diff --git a/asminc/accelerator.inc b/asminc/accelerator.inc index 0c687b2ad..a92b65ff9 100644 --- a/asminc/accelerator.inc +++ b/asminc/accelerator.inc @@ -60,3 +60,12 @@ CHAMELEON_DISABLE_REGS = $FF CHAMELEON_CFGTUR_LIMIT_1MHZ = %00001100 CHAMELEON_CFGTUR_LIMIT_NONE = %10000000 + +; --------------------------------------------------------------------------- +; C65/C64DX in C64 mode + +C65_VICIII_KEY := $D02F +C65_VICIII_CTRL_B := $D031 + +C65_VICIII_UNLOCK_1 = $A5 +C65_VICIII_UNLOCK_2 = $96 diff --git a/doc/c64.sgml b/doc/c64.sgml index c037b1e0e..800314fec 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -177,14 +177,17 @@ url="funcref.html" name="function reference"> for declaration and usage. detect_c128 detect_c64dtv +detect_c65 detect_chameleon detect_scpu get_c128_speed get_c64dtv_speed +get_c65_speed get_chameleon_speed get_scpu_speed set_c128_speed set_c64dtv_speed +set_c65_speed set_chameleon_speed set_scpu_speed diff --git a/doc/funcref.sgml b/doc/funcref.sgml index 09ee27e4a..edca7745e 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -70,14 +70,17 @@ function. + + + @@ -2969,6 +2972,26 @@ used in presence of a prototype. +detect_c65 + + + +/ + +The function is specific to the C64. + +, +, + + + + detect_chameleon @@ -3592,6 +3615,28 @@ header files define constants that can be used to check the return code. +get_c65_speed + + + +/ + +The function is specific to the C64. +The function does not check for the presence of a C65/C64DX in C64 mode. +See the accelerator.h header for the speed definitions. + +, +, + + + + get_chameleon_speed @@ -6231,6 +6276,28 @@ clean-up when exitting the program. +set_c65_speed + + + +/ + +The function is specific to the C64. +The function does not check for the presence of a C65/C64DX in C64 mode. +See the accelerator.h header for the speed definitions. + +, +, + + + + set_chameleon_speed diff --git a/include/accelerator.h b/include/accelerator.h index d29b73467..a5e6dbb28 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -226,6 +226,43 @@ unsigned char detect_chameleon (void); * 0x01 : C64 Chameleon cartridge present */ + +/* C65/C64DX in C64 mode */ + +unsigned char __fastcall__ set_c65_speed (unsigned char speed); + +/* Set the speed of the C65/C64DX CPU, using SPEED_SLOW will switch to + * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. + * + * Note that any value higher or equal to SPEED_3X will switch to fast mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, to my knowledge the switching should not fail. + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char get_c65_speed (void); + +/* Get the speed of the C65/C64DX CPU. + * + * Possible return values: + * SPEED_SLOW : Slow mode + * SPEED_3X : Fast mode + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char detect_c65 (void); + +/* Check for the presence of a C65/C64DX in C64 mode. + * + * Possible return values: + * 0x00 : C65/C64DX in C64 mode not present + * 0x01 : C65/C64DX in C64 mode present + */ /* End of accelerator.h */ #endif diff --git a/libsrc/c64/acc_c65_speed.s b/libsrc/c64/acc_c65_speed.s new file mode 100755 index 000000000..94fa50e91 --- /dev/null +++ b/libsrc/c64/acc_c65_speed.s @@ -0,0 +1,70 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char __fastcall__ set_c65_speed (unsigned char speed); +; +;/* Set the speed of the C65 CPU, using SPEED_SLOW will switch to +; * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. +; * +; * Note that any value higher or equal to SPEED_3X will switch to fast mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, to my knowledge the switching should not fail. +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + +; unsigned char get_c65_speed (void); +; +;/* Get the speed of the C65 CPU. +; * +; * Possible return values: +; * SPEED_SLOW : 1 Mhz mode +; * SPEED_3X : 3.5 Mhz mode +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + + .export _set_c65_speed + .export _get_c65_speed + + .include "accelerator.inc" + +_set_c65_speed: + tay + jsr activate_new_vic_mode + cpy #SPEED_3X + bcs high_speed +low_speed: + and #$BF +store_speed: + sta C65_VICIII_CTRL_B + lda C65_VICIII_CTRL_B + jmp return_c65_speed + +high_speed: + ora #$40 + bne store_speed + +_get_c65_speed: + jsr activate_new_vic_mode +return_c65_speed: + sta C65_VICIII_KEY + and #$40 + beq speed_is_slow + lda #SPEED_3X + .byte $2C +speed_is_slow: + ldx #$00 + rts + +activate_new_vic_mode: + lda #C65_VICIII_UNLOCK_1 + sta C65_VICIII_KEY + lda #C65_VICIII_UNLOCK_2 + sta C65_VICIII_KEY + lda C65_VICIII_CTRL_B + rts diff --git a/libsrc/c64/acc_detect_c65.s b/libsrc/c64/acc_detect_c65.s new file mode 100755 index 000000000..8e9f9b9ec --- /dev/null +++ b/libsrc/c64/acc_detect_c65.s @@ -0,0 +1,55 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char detect_c65 (void); +; +;/* Check for the presence of a C65/C64DX in C64 mode. +; * +; * Possible return values: +; * 0x00 : C65/C64DX in C64 mode not present +; * 0x01 : C65/C64DX in C64 mode present +; */ + + .export _detect_c65 + + .include "accelerator.inc" + +_detect_c65: + ldy $D000 + +; Make sure the CPU is not a 65816 + clc + .byte $E2,$01 ; NOP #$01 on 6510 and 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816 + lda #$00 + tax + bcs not_found ; carry will be set on 65816 + +; Make sure the CPU is not a 6510 + .byte $1A ; NOP on 6510, INA on 65(S)C(E)02 + beq not_found + txa + +; Make sure the CPU is a 65CE02/4510 + .byte $A3,$A3 ; NOP NOP on 65(S)C02, LDZ #$A3 on 65CE02 and 4510 + .byte $6B ; NOP on 65(S)C02, TZA on 65CE02 and 4510 + cmp #$A3 + bne not_found + +; Switch to VICIII mode and check if $D040 is a mirror of $D000 + ldy #C65_VICIII_UNLOCK_1 + sty C65_VICIII_KEY + ldy #C65_VICIII_UNLOCK_2 + sty C65_VICIII_KEY + cpy $D040 + bne found + inc $D000 + cpy $D040 + beq not_found + +found: + lda #$01 +not_found: + sty $D000 + sta C65_VICIII_KEY + rts diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index e9bd61881..9ff4d96b4 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,7 +1,8 @@ CL ?= cl65 all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg \ - c64-c128-test.prg c128-test.prg chameleon-test.prg + c64-c128-test.prg c128-test.prg chameleon-test.prg \ + c65-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg @@ -20,3 +21,6 @@ c128-test.prg: c64-c128-test.c chameleon-test.prg: chameleon-test.c $(CL) -t c64 chameleon-test.c -o chameleon-test.prg + +c65-test.prg: c65-test.c + $(CL) -t c64 c65-test.c -o c65-test.prg diff --git a/testcode/lib/accelerator/c65-test.c b/testcode/lib/accelerator/c65-test.c new file mode 100644 index 000000000..02e322625 --- /dev/null +++ b/testcode/lib/accelerator/c65-test.c @@ -0,0 +1,8 @@ +/* C65/C64DX in C64 mode accelerator test code. */ + +#define ACC_DETECT detect_c65 +#define ACC_GET_SPEED get_c65_speed +#define ACC_SET_SPEED set_c65_speed +#define ACC_NAME "C65" + +#include "turbo-test.c"
+ + + +/ + +The function is specific to the C64. + +, +, + + + + detect_chameleon @@ -3592,6 +3615,28 @@ header files define constants that can be used to check the return code. +get_c65_speed + + + +/ + +The function is specific to the C64. +The function does not check for the presence of a C65/C64DX in C64 mode. +See the accelerator.h header for the speed definitions. + +, +, + + + + get_chameleon_speed @@ -6231,6 +6276,28 @@ clean-up when exitting the program. +set_c65_speed + + + +/ + +The function is specific to the C64. +The function does not check for the presence of a C65/C64DX in C64 mode. +See the accelerator.h header for the speed definitions. + +, +, + + + + set_chameleon_speed diff --git a/include/accelerator.h b/include/accelerator.h index d29b73467..a5e6dbb28 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -226,6 +226,43 @@ unsigned char detect_chameleon (void); * 0x01 : C64 Chameleon cartridge present */ + +/* C65/C64DX in C64 mode */ + +unsigned char __fastcall__ set_c65_speed (unsigned char speed); + +/* Set the speed of the C65/C64DX CPU, using SPEED_SLOW will switch to + * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. + * + * Note that any value higher or equal to SPEED_3X will switch to fast mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, to my knowledge the switching should not fail. + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char get_c65_speed (void); + +/* Get the speed of the C65/C64DX CPU. + * + * Possible return values: + * SPEED_SLOW : Slow mode + * SPEED_3X : Fast mode + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char detect_c65 (void); + +/* Check for the presence of a C65/C64DX in C64 mode. + * + * Possible return values: + * 0x00 : C65/C64DX in C64 mode not present + * 0x01 : C65/C64DX in C64 mode present + */ /* End of accelerator.h */ #endif diff --git a/libsrc/c64/acc_c65_speed.s b/libsrc/c64/acc_c65_speed.s new file mode 100755 index 000000000..94fa50e91 --- /dev/null +++ b/libsrc/c64/acc_c65_speed.s @@ -0,0 +1,70 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char __fastcall__ set_c65_speed (unsigned char speed); +; +;/* Set the speed of the C65 CPU, using SPEED_SLOW will switch to +; * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. +; * +; * Note that any value higher or equal to SPEED_3X will switch to fast mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, to my knowledge the switching should not fail. +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + +; unsigned char get_c65_speed (void); +; +;/* Get the speed of the C65 CPU. +; * +; * Possible return values: +; * SPEED_SLOW : 1 Mhz mode +; * SPEED_3X : 3.5 Mhz mode +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + + .export _set_c65_speed + .export _get_c65_speed + + .include "accelerator.inc" + +_set_c65_speed: + tay + jsr activate_new_vic_mode + cpy #SPEED_3X + bcs high_speed +low_speed: + and #$BF +store_speed: + sta C65_VICIII_CTRL_B + lda C65_VICIII_CTRL_B + jmp return_c65_speed + +high_speed: + ora #$40 + bne store_speed + +_get_c65_speed: + jsr activate_new_vic_mode +return_c65_speed: + sta C65_VICIII_KEY + and #$40 + beq speed_is_slow + lda #SPEED_3X + .byte $2C +speed_is_slow: + ldx #$00 + rts + +activate_new_vic_mode: + lda #C65_VICIII_UNLOCK_1 + sta C65_VICIII_KEY + lda #C65_VICIII_UNLOCK_2 + sta C65_VICIII_KEY + lda C65_VICIII_CTRL_B + rts diff --git a/libsrc/c64/acc_detect_c65.s b/libsrc/c64/acc_detect_c65.s new file mode 100755 index 000000000..8e9f9b9ec --- /dev/null +++ b/libsrc/c64/acc_detect_c65.s @@ -0,0 +1,55 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char detect_c65 (void); +; +;/* Check for the presence of a C65/C64DX in C64 mode. +; * +; * Possible return values: +; * 0x00 : C65/C64DX in C64 mode not present +; * 0x01 : C65/C64DX in C64 mode present +; */ + + .export _detect_c65 + + .include "accelerator.inc" + +_detect_c65: + ldy $D000 + +; Make sure the CPU is not a 65816 + clc + .byte $E2,$01 ; NOP #$01 on 6510 and 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816 + lda #$00 + tax + bcs not_found ; carry will be set on 65816 + +; Make sure the CPU is not a 6510 + .byte $1A ; NOP on 6510, INA on 65(S)C(E)02 + beq not_found + txa + +; Make sure the CPU is a 65CE02/4510 + .byte $A3,$A3 ; NOP NOP on 65(S)C02, LDZ #$A3 on 65CE02 and 4510 + .byte $6B ; NOP on 65(S)C02, TZA on 65CE02 and 4510 + cmp #$A3 + bne not_found + +; Switch to VICIII mode and check if $D040 is a mirror of $D000 + ldy #C65_VICIII_UNLOCK_1 + sty C65_VICIII_KEY + ldy #C65_VICIII_UNLOCK_2 + sty C65_VICIII_KEY + cpy $D040 + bne found + inc $D000 + cpy $D040 + beq not_found + +found: + lda #$01 +not_found: + sty $D000 + sta C65_VICIII_KEY + rts diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index e9bd61881..9ff4d96b4 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,7 +1,8 @@ CL ?= cl65 all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg \ - c64-c128-test.prg c128-test.prg chameleon-test.prg + c64-c128-test.prg c128-test.prg chameleon-test.prg \ + c65-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg @@ -20,3 +21,6 @@ c128-test.prg: c64-c128-test.c chameleon-test.prg: chameleon-test.c $(CL) -t c64 chameleon-test.c -o chameleon-test.prg + +c65-test.prg: c65-test.c + $(CL) -t c64 c65-test.c -o c65-test.prg diff --git a/testcode/lib/accelerator/c65-test.c b/testcode/lib/accelerator/c65-test.c new file mode 100644 index 000000000..02e322625 --- /dev/null +++ b/testcode/lib/accelerator/c65-test.c @@ -0,0 +1,8 @@ +/* C65/C64DX in C64 mode accelerator test code. */ + +#define ACC_DETECT detect_c65 +#define ACC_GET_SPEED get_c65_speed +#define ACC_SET_SPEED set_c65_speed +#define ACC_NAME "C65" + +#include "turbo-test.c"
+ +/ + +The function is specific to the C64. + +, +, + +
@@ -3592,6 +3615,28 @@ header files define constants that can be used to check the return code. +get_c65_speed + + + +/ + +The function is specific to the C64. +The function does not check for the presence of a C65/C64DX in C64 mode. +See the accelerator.h header for the speed definitions. + +, +, + + + + get_chameleon_speed @@ -6231,6 +6276,28 @@ clean-up when exitting the program. +set_c65_speed + + + +/ + +The function is specific to the C64. +The function does not check for the presence of a C65/C64DX in C64 mode. +See the accelerator.h header for the speed definitions. + +, +, + + + + set_chameleon_speed diff --git a/include/accelerator.h b/include/accelerator.h index d29b73467..a5e6dbb28 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -226,6 +226,43 @@ unsigned char detect_chameleon (void); * 0x01 : C64 Chameleon cartridge present */ + +/* C65/C64DX in C64 mode */ + +unsigned char __fastcall__ set_c65_speed (unsigned char speed); + +/* Set the speed of the C65/C64DX CPU, using SPEED_SLOW will switch to + * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. + * + * Note that any value higher or equal to SPEED_3X will switch to fast mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, to my knowledge the switching should not fail. + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char get_c65_speed (void); + +/* Get the speed of the C65/C64DX CPU. + * + * Possible return values: + * SPEED_SLOW : Slow mode + * SPEED_3X : Fast mode + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char detect_c65 (void); + +/* Check for the presence of a C65/C64DX in C64 mode. + * + * Possible return values: + * 0x00 : C65/C64DX in C64 mode not present + * 0x01 : C65/C64DX in C64 mode present + */ /* End of accelerator.h */ #endif diff --git a/libsrc/c64/acc_c65_speed.s b/libsrc/c64/acc_c65_speed.s new file mode 100755 index 000000000..94fa50e91 --- /dev/null +++ b/libsrc/c64/acc_c65_speed.s @@ -0,0 +1,70 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char __fastcall__ set_c65_speed (unsigned char speed); +; +;/* Set the speed of the C65 CPU, using SPEED_SLOW will switch to +; * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. +; * +; * Note that any value higher or equal to SPEED_3X will switch to fast mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, to my knowledge the switching should not fail. +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + +; unsigned char get_c65_speed (void); +; +;/* Get the speed of the C65 CPU. +; * +; * Possible return values: +; * SPEED_SLOW : 1 Mhz mode +; * SPEED_3X : 3.5 Mhz mode +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + + .export _set_c65_speed + .export _get_c65_speed + + .include "accelerator.inc" + +_set_c65_speed: + tay + jsr activate_new_vic_mode + cpy #SPEED_3X + bcs high_speed +low_speed: + and #$BF +store_speed: + sta C65_VICIII_CTRL_B + lda C65_VICIII_CTRL_B + jmp return_c65_speed + +high_speed: + ora #$40 + bne store_speed + +_get_c65_speed: + jsr activate_new_vic_mode +return_c65_speed: + sta C65_VICIII_KEY + and #$40 + beq speed_is_slow + lda #SPEED_3X + .byte $2C +speed_is_slow: + ldx #$00 + rts + +activate_new_vic_mode: + lda #C65_VICIII_UNLOCK_1 + sta C65_VICIII_KEY + lda #C65_VICIII_UNLOCK_2 + sta C65_VICIII_KEY + lda C65_VICIII_CTRL_B + rts diff --git a/libsrc/c64/acc_detect_c65.s b/libsrc/c64/acc_detect_c65.s new file mode 100755 index 000000000..8e9f9b9ec --- /dev/null +++ b/libsrc/c64/acc_detect_c65.s @@ -0,0 +1,55 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char detect_c65 (void); +; +;/* Check for the presence of a C65/C64DX in C64 mode. +; * +; * Possible return values: +; * 0x00 : C65/C64DX in C64 mode not present +; * 0x01 : C65/C64DX in C64 mode present +; */ + + .export _detect_c65 + + .include "accelerator.inc" + +_detect_c65: + ldy $D000 + +; Make sure the CPU is not a 65816 + clc + .byte $E2,$01 ; NOP #$01 on 6510 and 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816 + lda #$00 + tax + bcs not_found ; carry will be set on 65816 + +; Make sure the CPU is not a 6510 + .byte $1A ; NOP on 6510, INA on 65(S)C(E)02 + beq not_found + txa + +; Make sure the CPU is a 65CE02/4510 + .byte $A3,$A3 ; NOP NOP on 65(S)C02, LDZ #$A3 on 65CE02 and 4510 + .byte $6B ; NOP on 65(S)C02, TZA on 65CE02 and 4510 + cmp #$A3 + bne not_found + +; Switch to VICIII mode and check if $D040 is a mirror of $D000 + ldy #C65_VICIII_UNLOCK_1 + sty C65_VICIII_KEY + ldy #C65_VICIII_UNLOCK_2 + sty C65_VICIII_KEY + cpy $D040 + bne found + inc $D000 + cpy $D040 + beq not_found + +found: + lda #$01 +not_found: + sty $D000 + sta C65_VICIII_KEY + rts diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index e9bd61881..9ff4d96b4 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,7 +1,8 @@ CL ?= cl65 all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg \ - c64-c128-test.prg c128-test.prg chameleon-test.prg + c64-c128-test.prg c128-test.prg chameleon-test.prg \ + c65-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg @@ -20,3 +21,6 @@ c128-test.prg: c64-c128-test.c chameleon-test.prg: chameleon-test.c $(CL) -t c64 chameleon-test.c -o chameleon-test.prg + +c65-test.prg: c65-test.c + $(CL) -t c64 c65-test.c -o c65-test.prg diff --git a/testcode/lib/accelerator/c65-test.c b/testcode/lib/accelerator/c65-test.c new file mode 100644 index 000000000..02e322625 --- /dev/null +++ b/testcode/lib/accelerator/c65-test.c @@ -0,0 +1,8 @@ +/* C65/C64DX in C64 mode accelerator test code. */ + +#define ACC_DETECT detect_c65 +#define ACC_GET_SPEED get_c65_speed +#define ACC_SET_SPEED set_c65_speed +#define ACC_NAME "C65" + +#include "turbo-test.c"
@@ -3592,6 +3615,28 @@ header files define constants that can be used to check the return code.
+ + + +/ + +The function is specific to the C64. +The function does not check for the presence of a C65/C64DX in C64 mode. +See the accelerator.h header for the speed definitions. + +, +, + + + + get_chameleon_speed @@ -6231,6 +6276,28 @@ clean-up when exitting the program. +set_c65_speed + + + +/ + +The function is specific to the C64. +The function does not check for the presence of a C65/C64DX in C64 mode. +See the accelerator.h header for the speed definitions. + +, +, + + + + set_chameleon_speed diff --git a/include/accelerator.h b/include/accelerator.h index d29b73467..a5e6dbb28 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -226,6 +226,43 @@ unsigned char detect_chameleon (void); * 0x01 : C64 Chameleon cartridge present */ + +/* C65/C64DX in C64 mode */ + +unsigned char __fastcall__ set_c65_speed (unsigned char speed); + +/* Set the speed of the C65/C64DX CPU, using SPEED_SLOW will switch to + * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. + * + * Note that any value higher or equal to SPEED_3X will switch to fast mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, to my knowledge the switching should not fail. + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char get_c65_speed (void); + +/* Get the speed of the C65/C64DX CPU. + * + * Possible return values: + * SPEED_SLOW : Slow mode + * SPEED_3X : Fast mode + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char detect_c65 (void); + +/* Check for the presence of a C65/C64DX in C64 mode. + * + * Possible return values: + * 0x00 : C65/C64DX in C64 mode not present + * 0x01 : C65/C64DX in C64 mode present + */ /* End of accelerator.h */ #endif diff --git a/libsrc/c64/acc_c65_speed.s b/libsrc/c64/acc_c65_speed.s new file mode 100755 index 000000000..94fa50e91 --- /dev/null +++ b/libsrc/c64/acc_c65_speed.s @@ -0,0 +1,70 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char __fastcall__ set_c65_speed (unsigned char speed); +; +;/* Set the speed of the C65 CPU, using SPEED_SLOW will switch to +; * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. +; * +; * Note that any value higher or equal to SPEED_3X will switch to fast mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, to my knowledge the switching should not fail. +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + +; unsigned char get_c65_speed (void); +; +;/* Get the speed of the C65 CPU. +; * +; * Possible return values: +; * SPEED_SLOW : 1 Mhz mode +; * SPEED_3X : 3.5 Mhz mode +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + + .export _set_c65_speed + .export _get_c65_speed + + .include "accelerator.inc" + +_set_c65_speed: + tay + jsr activate_new_vic_mode + cpy #SPEED_3X + bcs high_speed +low_speed: + and #$BF +store_speed: + sta C65_VICIII_CTRL_B + lda C65_VICIII_CTRL_B + jmp return_c65_speed + +high_speed: + ora #$40 + bne store_speed + +_get_c65_speed: + jsr activate_new_vic_mode +return_c65_speed: + sta C65_VICIII_KEY + and #$40 + beq speed_is_slow + lda #SPEED_3X + .byte $2C +speed_is_slow: + ldx #$00 + rts + +activate_new_vic_mode: + lda #C65_VICIII_UNLOCK_1 + sta C65_VICIII_KEY + lda #C65_VICIII_UNLOCK_2 + sta C65_VICIII_KEY + lda C65_VICIII_CTRL_B + rts diff --git a/libsrc/c64/acc_detect_c65.s b/libsrc/c64/acc_detect_c65.s new file mode 100755 index 000000000..8e9f9b9ec --- /dev/null +++ b/libsrc/c64/acc_detect_c65.s @@ -0,0 +1,55 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char detect_c65 (void); +; +;/* Check for the presence of a C65/C64DX in C64 mode. +; * +; * Possible return values: +; * 0x00 : C65/C64DX in C64 mode not present +; * 0x01 : C65/C64DX in C64 mode present +; */ + + .export _detect_c65 + + .include "accelerator.inc" + +_detect_c65: + ldy $D000 + +; Make sure the CPU is not a 65816 + clc + .byte $E2,$01 ; NOP #$01 on 6510 and 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816 + lda #$00 + tax + bcs not_found ; carry will be set on 65816 + +; Make sure the CPU is not a 6510 + .byte $1A ; NOP on 6510, INA on 65(S)C(E)02 + beq not_found + txa + +; Make sure the CPU is a 65CE02/4510 + .byte $A3,$A3 ; NOP NOP on 65(S)C02, LDZ #$A3 on 65CE02 and 4510 + .byte $6B ; NOP on 65(S)C02, TZA on 65CE02 and 4510 + cmp #$A3 + bne not_found + +; Switch to VICIII mode and check if $D040 is a mirror of $D000 + ldy #C65_VICIII_UNLOCK_1 + sty C65_VICIII_KEY + ldy #C65_VICIII_UNLOCK_2 + sty C65_VICIII_KEY + cpy $D040 + bne found + inc $D000 + cpy $D040 + beq not_found + +found: + lda #$01 +not_found: + sty $D000 + sta C65_VICIII_KEY + rts diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index e9bd61881..9ff4d96b4 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,7 +1,8 @@ CL ?= cl65 all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg \ - c64-c128-test.prg c128-test.prg chameleon-test.prg + c64-c128-test.prg c128-test.prg chameleon-test.prg \ + c65-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg @@ -20,3 +21,6 @@ c128-test.prg: c64-c128-test.c chameleon-test.prg: chameleon-test.c $(CL) -t c64 chameleon-test.c -o chameleon-test.prg + +c65-test.prg: c65-test.c + $(CL) -t c64 c65-test.c -o c65-test.prg diff --git a/testcode/lib/accelerator/c65-test.c b/testcode/lib/accelerator/c65-test.c new file mode 100644 index 000000000..02e322625 --- /dev/null +++ b/testcode/lib/accelerator/c65-test.c @@ -0,0 +1,8 @@ +/* C65/C64DX in C64 mode accelerator test code. */ + +#define ACC_DETECT detect_c65 +#define ACC_GET_SPEED get_c65_speed +#define ACC_SET_SPEED set_c65_speed +#define ACC_NAME "C65" + +#include "turbo-test.c"
+ +/ + +The function is specific to the C64. +The function does not check for the presence of a C65/C64DX in C64 mode. +See the accelerator.h header for the speed definitions. + +, +, + +
@@ -6231,6 +6276,28 @@ clean-up when exitting the program. +set_c65_speed + + + +/ + +The function is specific to the C64. +The function does not check for the presence of a C65/C64DX in C64 mode. +See the accelerator.h header for the speed definitions. + +, +, + + + + set_chameleon_speed diff --git a/include/accelerator.h b/include/accelerator.h index d29b73467..a5e6dbb28 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -226,6 +226,43 @@ unsigned char detect_chameleon (void); * 0x01 : C64 Chameleon cartridge present */ + +/* C65/C64DX in C64 mode */ + +unsigned char __fastcall__ set_c65_speed (unsigned char speed); + +/* Set the speed of the C65/C64DX CPU, using SPEED_SLOW will switch to + * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. + * + * Note that any value higher or equal to SPEED_3X will switch to fast mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, to my knowledge the switching should not fail. + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char get_c65_speed (void); + +/* Get the speed of the C65/C64DX CPU. + * + * Possible return values: + * SPEED_SLOW : Slow mode + * SPEED_3X : Fast mode + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char detect_c65 (void); + +/* Check for the presence of a C65/C64DX in C64 mode. + * + * Possible return values: + * 0x00 : C65/C64DX in C64 mode not present + * 0x01 : C65/C64DX in C64 mode present + */ /* End of accelerator.h */ #endif diff --git a/libsrc/c64/acc_c65_speed.s b/libsrc/c64/acc_c65_speed.s new file mode 100755 index 000000000..94fa50e91 --- /dev/null +++ b/libsrc/c64/acc_c65_speed.s @@ -0,0 +1,70 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char __fastcall__ set_c65_speed (unsigned char speed); +; +;/* Set the speed of the C65 CPU, using SPEED_SLOW will switch to +; * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. +; * +; * Note that any value higher or equal to SPEED_3X will switch to fast mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, to my knowledge the switching should not fail. +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + +; unsigned char get_c65_speed (void); +; +;/* Get the speed of the C65 CPU. +; * +; * Possible return values: +; * SPEED_SLOW : 1 Mhz mode +; * SPEED_3X : 3.5 Mhz mode +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + + .export _set_c65_speed + .export _get_c65_speed + + .include "accelerator.inc" + +_set_c65_speed: + tay + jsr activate_new_vic_mode + cpy #SPEED_3X + bcs high_speed +low_speed: + and #$BF +store_speed: + sta C65_VICIII_CTRL_B + lda C65_VICIII_CTRL_B + jmp return_c65_speed + +high_speed: + ora #$40 + bne store_speed + +_get_c65_speed: + jsr activate_new_vic_mode +return_c65_speed: + sta C65_VICIII_KEY + and #$40 + beq speed_is_slow + lda #SPEED_3X + .byte $2C +speed_is_slow: + ldx #$00 + rts + +activate_new_vic_mode: + lda #C65_VICIII_UNLOCK_1 + sta C65_VICIII_KEY + lda #C65_VICIII_UNLOCK_2 + sta C65_VICIII_KEY + lda C65_VICIII_CTRL_B + rts diff --git a/libsrc/c64/acc_detect_c65.s b/libsrc/c64/acc_detect_c65.s new file mode 100755 index 000000000..8e9f9b9ec --- /dev/null +++ b/libsrc/c64/acc_detect_c65.s @@ -0,0 +1,55 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char detect_c65 (void); +; +;/* Check for the presence of a C65/C64DX in C64 mode. +; * +; * Possible return values: +; * 0x00 : C65/C64DX in C64 mode not present +; * 0x01 : C65/C64DX in C64 mode present +; */ + + .export _detect_c65 + + .include "accelerator.inc" + +_detect_c65: + ldy $D000 + +; Make sure the CPU is not a 65816 + clc + .byte $E2,$01 ; NOP #$01 on 6510 and 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816 + lda #$00 + tax + bcs not_found ; carry will be set on 65816 + +; Make sure the CPU is not a 6510 + .byte $1A ; NOP on 6510, INA on 65(S)C(E)02 + beq not_found + txa + +; Make sure the CPU is a 65CE02/4510 + .byte $A3,$A3 ; NOP NOP on 65(S)C02, LDZ #$A3 on 65CE02 and 4510 + .byte $6B ; NOP on 65(S)C02, TZA on 65CE02 and 4510 + cmp #$A3 + bne not_found + +; Switch to VICIII mode and check if $D040 is a mirror of $D000 + ldy #C65_VICIII_UNLOCK_1 + sty C65_VICIII_KEY + ldy #C65_VICIII_UNLOCK_2 + sty C65_VICIII_KEY + cpy $D040 + bne found + inc $D000 + cpy $D040 + beq not_found + +found: + lda #$01 +not_found: + sty $D000 + sta C65_VICIII_KEY + rts diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index e9bd61881..9ff4d96b4 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,7 +1,8 @@ CL ?= cl65 all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg \ - c64-c128-test.prg c128-test.prg chameleon-test.prg + c64-c128-test.prg c128-test.prg chameleon-test.prg \ + c65-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg @@ -20,3 +21,6 @@ c128-test.prg: c64-c128-test.c chameleon-test.prg: chameleon-test.c $(CL) -t c64 chameleon-test.c -o chameleon-test.prg + +c65-test.prg: c65-test.c + $(CL) -t c64 c65-test.c -o c65-test.prg diff --git a/testcode/lib/accelerator/c65-test.c b/testcode/lib/accelerator/c65-test.c new file mode 100644 index 000000000..02e322625 --- /dev/null +++ b/testcode/lib/accelerator/c65-test.c @@ -0,0 +1,8 @@ +/* C65/C64DX in C64 mode accelerator test code. */ + +#define ACC_DETECT detect_c65 +#define ACC_GET_SPEED get_c65_speed +#define ACC_SET_SPEED set_c65_speed +#define ACC_NAME "C65" + +#include "turbo-test.c"
@@ -6231,6 +6276,28 @@ clean-up when exitting the program.
+ + + +/ + +The function is specific to the C64. +The function does not check for the presence of a C65/C64DX in C64 mode. +See the accelerator.h header for the speed definitions. + +, +, + + + + set_chameleon_speed diff --git a/include/accelerator.h b/include/accelerator.h index d29b73467..a5e6dbb28 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -226,6 +226,43 @@ unsigned char detect_chameleon (void); * 0x01 : C64 Chameleon cartridge present */ + +/* C65/C64DX in C64 mode */ + +unsigned char __fastcall__ set_c65_speed (unsigned char speed); + +/* Set the speed of the C65/C64DX CPU, using SPEED_SLOW will switch to + * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. + * + * Note that any value higher or equal to SPEED_3X will switch to fast mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, to my knowledge the switching should not fail. + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char get_c65_speed (void); + +/* Get the speed of the C65/C64DX CPU. + * + * Possible return values: + * SPEED_SLOW : Slow mode + * SPEED_3X : Fast mode + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char detect_c65 (void); + +/* Check for the presence of a C65/C64DX in C64 mode. + * + * Possible return values: + * 0x00 : C65/C64DX in C64 mode not present + * 0x01 : C65/C64DX in C64 mode present + */ /* End of accelerator.h */ #endif diff --git a/libsrc/c64/acc_c65_speed.s b/libsrc/c64/acc_c65_speed.s new file mode 100755 index 000000000..94fa50e91 --- /dev/null +++ b/libsrc/c64/acc_c65_speed.s @@ -0,0 +1,70 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char __fastcall__ set_c65_speed (unsigned char speed); +; +;/* Set the speed of the C65 CPU, using SPEED_SLOW will switch to +; * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. +; * +; * Note that any value higher or equal to SPEED_3X will switch to fast mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, to my knowledge the switching should not fail. +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + +; unsigned char get_c65_speed (void); +; +;/* Get the speed of the C65 CPU. +; * +; * Possible return values: +; * SPEED_SLOW : 1 Mhz mode +; * SPEED_3X : 3.5 Mhz mode +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + + .export _set_c65_speed + .export _get_c65_speed + + .include "accelerator.inc" + +_set_c65_speed: + tay + jsr activate_new_vic_mode + cpy #SPEED_3X + bcs high_speed +low_speed: + and #$BF +store_speed: + sta C65_VICIII_CTRL_B + lda C65_VICIII_CTRL_B + jmp return_c65_speed + +high_speed: + ora #$40 + bne store_speed + +_get_c65_speed: + jsr activate_new_vic_mode +return_c65_speed: + sta C65_VICIII_KEY + and #$40 + beq speed_is_slow + lda #SPEED_3X + .byte $2C +speed_is_slow: + ldx #$00 + rts + +activate_new_vic_mode: + lda #C65_VICIII_UNLOCK_1 + sta C65_VICIII_KEY + lda #C65_VICIII_UNLOCK_2 + sta C65_VICIII_KEY + lda C65_VICIII_CTRL_B + rts diff --git a/libsrc/c64/acc_detect_c65.s b/libsrc/c64/acc_detect_c65.s new file mode 100755 index 000000000..8e9f9b9ec --- /dev/null +++ b/libsrc/c64/acc_detect_c65.s @@ -0,0 +1,55 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char detect_c65 (void); +; +;/* Check for the presence of a C65/C64DX in C64 mode. +; * +; * Possible return values: +; * 0x00 : C65/C64DX in C64 mode not present +; * 0x01 : C65/C64DX in C64 mode present +; */ + + .export _detect_c65 + + .include "accelerator.inc" + +_detect_c65: + ldy $D000 + +; Make sure the CPU is not a 65816 + clc + .byte $E2,$01 ; NOP #$01 on 6510 and 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816 + lda #$00 + tax + bcs not_found ; carry will be set on 65816 + +; Make sure the CPU is not a 6510 + .byte $1A ; NOP on 6510, INA on 65(S)C(E)02 + beq not_found + txa + +; Make sure the CPU is a 65CE02/4510 + .byte $A3,$A3 ; NOP NOP on 65(S)C02, LDZ #$A3 on 65CE02 and 4510 + .byte $6B ; NOP on 65(S)C02, TZA on 65CE02 and 4510 + cmp #$A3 + bne not_found + +; Switch to VICIII mode and check if $D040 is a mirror of $D000 + ldy #C65_VICIII_UNLOCK_1 + sty C65_VICIII_KEY + ldy #C65_VICIII_UNLOCK_2 + sty C65_VICIII_KEY + cpy $D040 + bne found + inc $D000 + cpy $D040 + beq not_found + +found: + lda #$01 +not_found: + sty $D000 + sta C65_VICIII_KEY + rts diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index e9bd61881..9ff4d96b4 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,7 +1,8 @@ CL ?= cl65 all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg \ - c64-c128-test.prg c128-test.prg chameleon-test.prg + c64-c128-test.prg c128-test.prg chameleon-test.prg \ + c65-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg @@ -20,3 +21,6 @@ c128-test.prg: c64-c128-test.c chameleon-test.prg: chameleon-test.c $(CL) -t c64 chameleon-test.c -o chameleon-test.prg + +c65-test.prg: c65-test.c + $(CL) -t c64 c65-test.c -o c65-test.prg diff --git a/testcode/lib/accelerator/c65-test.c b/testcode/lib/accelerator/c65-test.c new file mode 100644 index 000000000..02e322625 --- /dev/null +++ b/testcode/lib/accelerator/c65-test.c @@ -0,0 +1,8 @@ +/* C65/C64DX in C64 mode accelerator test code. */ + +#define ACC_DETECT detect_c65 +#define ACC_GET_SPEED get_c65_speed +#define ACC_SET_SPEED set_c65_speed +#define ACC_NAME "C65" + +#include "turbo-test.c"
diff --git a/include/accelerator.h b/include/accelerator.h index d29b73467..a5e6dbb28 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -226,6 +226,43 @@ unsigned char detect_chameleon (void); * 0x01 : C64 Chameleon cartridge present */ + +/* C65/C64DX in C64 mode */ + +unsigned char __fastcall__ set_c65_speed (unsigned char speed); + +/* Set the speed of the C65/C64DX CPU, using SPEED_SLOW will switch to + * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. + * + * Note that any value higher or equal to SPEED_3X will switch to fast mode. + * + * This function will return the actual speed the CPU is at after trying + * to set the requested speed, to my knowledge the switching should not fail. + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char get_c65_speed (void); + +/* Get the speed of the C65/C64DX CPU. + * + * Possible return values: + * SPEED_SLOW : Slow mode + * SPEED_3X : Fast mode + * + * This function does not check for the presence of a C65/C64DX in C64 mode, + * make sure you use 'detect_c65();' before using. + */ + +unsigned char detect_c65 (void); + +/* Check for the presence of a C65/C64DX in C64 mode. + * + * Possible return values: + * 0x00 : C65/C64DX in C64 mode not present + * 0x01 : C65/C64DX in C64 mode present + */ /* End of accelerator.h */ #endif diff --git a/libsrc/c64/acc_c65_speed.s b/libsrc/c64/acc_c65_speed.s new file mode 100755 index 000000000..94fa50e91 --- /dev/null +++ b/libsrc/c64/acc_c65_speed.s @@ -0,0 +1,70 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char __fastcall__ set_c65_speed (unsigned char speed); +; +;/* Set the speed of the C65 CPU, using SPEED_SLOW will switch to +; * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode. +; * +; * Note that any value higher or equal to SPEED_3X will switch to fast mode. +; * +; * This function will return the actual speed the CPU is at after trying +; * to set the requested speed, to my knowledge the switching should not fail. +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + +; unsigned char get_c65_speed (void); +; +;/* Get the speed of the C65 CPU. +; * +; * Possible return values: +; * SPEED_SLOW : 1 Mhz mode +; * SPEED_3X : 3.5 Mhz mode +; * +; * This function does not check for the presence of a C65/C64DX in C64 mode, +; * make sure you use 'detect_c65();' before using. +; */ + + .export _set_c65_speed + .export _get_c65_speed + + .include "accelerator.inc" + +_set_c65_speed: + tay + jsr activate_new_vic_mode + cpy #SPEED_3X + bcs high_speed +low_speed: + and #$BF +store_speed: + sta C65_VICIII_CTRL_B + lda C65_VICIII_CTRL_B + jmp return_c65_speed + +high_speed: + ora #$40 + bne store_speed + +_get_c65_speed: + jsr activate_new_vic_mode +return_c65_speed: + sta C65_VICIII_KEY + and #$40 + beq speed_is_slow + lda #SPEED_3X + .byte $2C +speed_is_slow: + ldx #$00 + rts + +activate_new_vic_mode: + lda #C65_VICIII_UNLOCK_1 + sta C65_VICIII_KEY + lda #C65_VICIII_UNLOCK_2 + sta C65_VICIII_KEY + lda C65_VICIII_CTRL_B + rts diff --git a/libsrc/c64/acc_detect_c65.s b/libsrc/c64/acc_detect_c65.s new file mode 100755 index 000000000..8e9f9b9ec --- /dev/null +++ b/libsrc/c64/acc_detect_c65.s @@ -0,0 +1,55 @@ +; +; Marco van den Heuvel, 2018-04-27 +; + +; unsigned char detect_c65 (void); +; +;/* Check for the presence of a C65/C64DX in C64 mode. +; * +; * Possible return values: +; * 0x00 : C65/C64DX in C64 mode not present +; * 0x01 : C65/C64DX in C64 mode present +; */ + + .export _detect_c65 + + .include "accelerator.inc" + +_detect_c65: + ldy $D000 + +; Make sure the CPU is not a 65816 + clc + .byte $E2,$01 ; NOP #$01 on 6510 and 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816 + lda #$00 + tax + bcs not_found ; carry will be set on 65816 + +; Make sure the CPU is not a 6510 + .byte $1A ; NOP on 6510, INA on 65(S)C(E)02 + beq not_found + txa + +; Make sure the CPU is a 65CE02/4510 + .byte $A3,$A3 ; NOP NOP on 65(S)C02, LDZ #$A3 on 65CE02 and 4510 + .byte $6B ; NOP on 65(S)C02, TZA on 65CE02 and 4510 + cmp #$A3 + bne not_found + +; Switch to VICIII mode and check if $D040 is a mirror of $D000 + ldy #C65_VICIII_UNLOCK_1 + sty C65_VICIII_KEY + ldy #C65_VICIII_UNLOCK_2 + sty C65_VICIII_KEY + cpy $D040 + bne found + inc $D000 + cpy $D040 + beq not_found + +found: + lda #$01 +not_found: + sty $D000 + sta C65_VICIII_KEY + rts diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index e9bd61881..9ff4d96b4 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,7 +1,8 @@ CL ?= cl65 all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg \ - c64-c128-test.prg c128-test.prg chameleon-test.prg + c64-c128-test.prg c128-test.prg chameleon-test.prg \ + c65-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg @@ -20,3 +21,6 @@ c128-test.prg: c64-c128-test.c chameleon-test.prg: chameleon-test.c $(CL) -t c64 chameleon-test.c -o chameleon-test.prg + +c65-test.prg: c65-test.c + $(CL) -t c64 c65-test.c -o c65-test.prg diff --git a/testcode/lib/accelerator/c65-test.c b/testcode/lib/accelerator/c65-test.c new file mode 100644 index 000000000..02e322625 --- /dev/null +++ b/testcode/lib/accelerator/c65-test.c @@ -0,0 +1,8 @@ +/* C65/C64DX in C64 mode accelerator test code. */ + +#define ACC_DETECT detect_c65 +#define ACC_GET_SPEED get_c65_speed +#define ACC_SET_SPEED set_c65_speed +#define ACC_NAME "C65" + +#include "turbo-test.c"