Skip to content

Commit

Permalink
v2.1.0: the "copy/paste my beloved" update
Browse files Browse the repository at this point in the history
  • Loading branch information
Korbo committed Jun 29, 2024
1 parent 60ea705 commit 2699471
Show file tree
Hide file tree
Showing 8 changed files with 307 additions and 77 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.o
*.kate-swp
*.prg
main
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LD = ld65
SP = sp65

all: main.c
$(CL) -t c64 -O -o 64fetch.prg main.c detect.s
$(CL) -t c64 -O -o 64fetch.prg main.c detect.c detectasm.s

clean:
rm *.o
219 changes: 219 additions & 0 deletions detect.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
#include <6502.h>
#include <peekpoke.h>

#include "detect.h"
// shoutouts to chironb on github, who i """"borrowed"""" this code from, because i sure as hell wouldn't have been able to do this wizardry, especially not the device section
unsigned char detect_sid(void) {

// **********
// DETECT SID
// **********

// Taken from the work published here:

// https://codebase64.org/doku.php?id=base:detecting_sid_type_-_safe_method

// ;SID DETECTION ROUTINE

// ;By SounDemon - Based on a tip from Dag Lem.
// ;Put together by FTC after SounDemons instructions
// ;...and tested by Rambones and Jeff.

// ; - Don't run this routine on a badline
// ; - Won't work in VICE (always detects 6581) unless resid-fp emulation is enabled

// sei ;No disturbing interrupts
// lda #$ff
// cmp $d012 ;Don't run it on a badline.
// bne *-3

// ;Detection itself starts here
// lda #$ff ;Set frequency in voice 3 to $ffff
// sta $d412 ;...and set testbit (other bits doesn't matter) in $d012 to disable oscillator
// sta $d40e
// sta $d40f
// lda #$20 ;Sawtooth wave and gatebit OFF to start oscillator again.
// sta $d412
// lda $d41b ;Accu now has different value depending on sid model (6581=3/8580=2)
// lsr ;...that is: Carry flag is set for 6581, and clear for 8580.
// bcc model_8580
// model_6581:
// [...]

// model_8580:
// [...]

unsigned char i = 0; // For looping

unsigned char D41B_before = 0;
unsigned char D41B_after = 0;

unsigned char one_D41B_after_value = 0;
unsigned char one_D41B_after_frequency = 0;
unsigned char two_D41B_after_value = 0;
unsigned char two_D41B_after_frequency = 0;
unsigned char three_D41B_after_value = 0;
unsigned char three_D41B_after_frequency = 0;

unsigned char likely_8580 = 0;
unsigned char likely_6581 = 0;

D41B_before = PEEK(0xD41B); // Record iniital value

for (i = 0 ; i < 255 ; ++i) {

POKE(0xD011, 0x0B); // Load 0x0B into 0xD011(53265) - Disable VIC-II
POKE(0xD412, 0xFF); // Load 0xFF into 0xD412 - Set frequency in voice 3 to $ffff
POKE(0xD40E, 0xFF); // Load 0xFF into 0xD40E - ...and set testbit (other bits doesn't matter) in $d012 to disable oscillator
POKE(0xD40F, 0xFF); // Load 0xFF into 0xD40F
POKE(0xD412, 0x20); // Load 0x20 into 0xD412 - Sawtooth wave and gatebit OFF to start oscillator again.
POKE(0xD011, 0x1B); // Load 0x1B into 0xD011(53265) - Enable VIC-II
D41B_after = PEEK(0xD41B); // Record current value

// check curent value to see if it's sotred
if ( D41B_after == one_D41B_after_value ) { // does the current value equal slot one's value
++one_D41B_after_frequency; // if so, update the count for this slot

} else if ( D41B_after == two_D41B_after_value ) { // does the current value equal slot two's value
++two_D41B_after_frequency; // if so, update the count for this slot

} else if ( D41B_after == three_D41B_after_value ) { // does the current value equal slot three's value
++three_D41B_after_frequency; // if so, update the count for this slot

// if it doesn't match any slots, try to allocate one
} else if ( one_D41B_after_frequency == 0 ) { // if this slot one empty?
one_D41B_after_value = D41B_after; // if so, update the value for this slot and...
++one_D41B_after_frequency; // ...update the count for this slot

} else if ( two_D41B_after_frequency == 0 ) { // if this slot one empty?
two_D41B_after_value = D41B_after; // if so, update the value for this slot and...
++two_D41B_after_frequency; // ...update the count for this slot

} else if ( three_D41B_after_frequency == 0 ) { // if this slot one empty?
three_D41B_after_value = D41B_after; // if so, update the value for this slot and...
++three_D41B_after_frequency; // ...update the count for this slot

} else {
D41B_after = 0;
one_D41B_after_value = 0;
one_D41B_after_frequency = 0;
two_D41B_after_value = 0;
two_D41B_after_frequency = 0;
three_D41B_after_value = 0;
three_D41B_after_frequency = 0;

};

};

// Scan for 8580 --> 0x08 & any of 0x33 0x32
if (one_D41B_after_value == 0x08 || two_D41B_after_value == 0x08 || three_D41B_after_value == 0x08) {
++likely_8580;
};

if (one_D41B_after_value == 0x32 || two_D41B_after_value == 0x32 || three_D41B_after_value == 0x32) {
++likely_8580;
};

// Scan for 6581 --> 0x09 & any of 0x34 0x33
if (one_D41B_after_value == 0x09 || two_D41B_after_value == 0x09 || three_D41B_after_value == 0x09) {
++likely_6581;
};

if (one_D41B_after_value == 0x34 || two_D41B_after_value == 0x34 || three_D41B_after_value == 0x34) {
++likely_6581;
};

// Codes:
// 1 - 6581
// 2 - 8580
// 0 - Undetermined
if (likely_6581 > likely_8580) {
return(1);
} else if (likely_8580 > likely_6581) {
return(2);
} else {
return(0);
};

};//end func

unsigned char detect_cpu(void) {

unsigned char gotten_cpu = 0;
unsigned char sid_detected = 0;

// cc65 has a getcpu() function that only tells you if it's a 6502 or others, but not the Commodore specific ones.
// The cc65 online documentation is super old. The GitHub has more up-to-date information.
// https://github.com/cc65/cc65/blob/master/include/6502.h
//
// /* Possible returns of getcpu() */
// #define CPU_6502 0
// #define CPU_65C02 1
// #define CPU_65816 2
// #define CPU_4510 3
// #define CPU_65SC02 4
// #define CPU_65CE02 5
// #define CPU_HUC6280 6
// #define CPU_2A0x 7
// #define CPU_45GS02 8

// Detect 6510/8500/8502 --> Address 0x00 should be 47, whereas regular 6502's seem to have 76 there.
// Detect SID to guess that it's a Commodore 64C or not.
// Detect a Commodore 128 --> Address 0xD030 (53296) is always 255 on a non-Commodore 128 6502 CPU.

gotten_cpu = getcpu();
sid_detected = detect_sid();

if ( getcpu() == 0 ) {
if (PEEK(0) == 47 && PEEK(0xD030) != 255) { return(9 ); // 9 MOS 8502 (Commodore 128)
} else if (PEEK(0) == 47 && sid_detected == 2 ) { return(10); // 10 MOS 8500 (Commodore 64C)
} else if (PEEK(0) == 47 && sid_detected == 1 ) { return(11); // 11 MOS 6510 (Commodore 64)
} else { return(0); // 0 MOS 6502 ???
};
} else { return(gotten_cpu); // 255 Unknown
};

};//end func

unsigned char detect_kernal(void) {
// I have discovered a *NEW* byte to look at in any kernal and figure out what it is. I need to re-write this to use this, becuase it'll save a bunch of code!

// REVIEW - E4AC (58540) - Each Kernal:
// - 901227-01 --> 0x2B
// - 901227-02 --> 0x5C
// - 901227-03 --> 0x81
// - 251104-01 --> 0x00
// - 251104-04 --> 0xB3
// - 901246-01 --> 0x63

// C64 R3 58497 _77_ && 58498 79 && 58677 14
// SX R3 58497 _83_ && 58498 88 && 58677 6
// J64 R3 58497 _68_ && 58498 79 && 58677 14
// JSX R3 58497 _68_ && 58498 79 && 58677 6

unsigned char kernal_value = 0;
kernal_value = PEEK(0xE4AC);

switch (kernal_value) {
case 0x2B : return(1); break; // 901227-01 - R1 C64 First Kernal
case 0x5C : return(2); break; // 901227-02 - R2 C64 Early Kernal
case 0x81 :
switch ( PEEK(58497L) ) {
case 68 :
switch (PEEK(58677L)) {
case 14 : return(10); break; // R3 C64 JiffyDOS
case 6 : return(11); break; // R3 SX-64 JiffyDOS
};//end-switch
break;
};//end-switch
return(3); // 901227-03 - R3 C64 Kernal
break;
case 0xB3 : return(4); break; // 251104-04 - R4 SX-64 Common Latest Kernal
case 0x00 : return(5); break; // 251104-01 - R1 SX-64 Rare First Kernal
case 0x63 : return(6); break; // 901246-01 - 4064 Educator 64 --> ? Fair to say this is most similar to a stock R3 901227-03 kernal. From here: "Note that some patches of 901227-03 are included." http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/revisions.txt
default : return(0); break; // Default Unknown Kernal
};//end switch

}; // end func

2 changes: 0 additions & 2 deletions detect.h
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
extern char detectregion();
extern char detectsid();
48 changes: 0 additions & 48 deletions detect.s

This file was deleted.

29 changes: 29 additions & 0 deletions detectasm.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
; TODO: Convert to C

.global _detect_region

.code

_detect_region:
SEI
LDX #$00
w0: LDA $D012
w1: CMP $D012
BEQ w1
BMI w0
AND #$03
CMP #$03
BNE detectionDone ; done for NTSC
TAY
countCycles:
INX
LDA $D012
BPL countCycles
CPX #$5E ; VICE values: PAL-N=$6C PAL=$50
; so choose middle value $5E for check
BCC isPAL
INY ; is PAL-N
isPAL:
TYA
detectionDone:
RTS
Loading

0 comments on commit 2699471

Please sign in to comment.