diff --git a/asminc/accelerator.inc b/asminc/accelerator.inc index f86ce8b2d..1008b49c1 100644 --- a/asminc/accelerator.inc +++ b/asminc/accelerator.inc @@ -32,3 +32,11 @@ SuperCPU_Fast := $D07B SuperCPU_Speed_Mode := $D0B8 SuperCPU_Detect := $D0BC + +; --------------------------------------------------------------------------- +; C64DTV + +C64DTV_Extended_Regs := $D03F + +C64DTV_Slow = $00 +C64DTV_Fast = $03 diff --git a/doc/c64.sgml b/doc/c64.sgml index 05b87a22b..f1e678c72 100644 --- a/doc/c64.sgml +++ b/doc/c64.sgml @@ -175,9 +175,12 @@ The functions listed below are accelerator functions for the C64. See the for declaration and usage. +detect_c64dtv detect_scpu -scpu_get_speed -scpu_set_speed +get_c64dtv_speed +get_scpu_speed +set_c64dtv_speed +set_scpu_speed diff --git a/doc/funcref.sgml b/doc/funcref.sgml index e47a0c0a9..268c210fe 100644 --- a/doc/funcref.sgml +++ b/doc/funcref.sgml @@ -68,8 +68,11 @@ function.

+ + + @@ -2920,6 +2923,26 @@ used in presence of a prototype. +detect_c64dtv

+ + + +/ + +The function is specific to the C64. + +, +, + + + + detect_scpu

@@ -3479,6 +3502,28 @@ header files define constants that can be used to check the return code. +get_c64dtv_speed

+ + + +/ + +The function is specific to the C64. +The function does not check for the presence of the C64DTV. +See the accelerator.h header for the speed definitions. + +, +, + + + + get_scpu_speed

@@ -6052,13 +6097,35 @@ clean-up when exitting the program. +set_c64dtv_speed

+ + + +/ + +The function is specific to the C64. +The function does not check for the presence of the C64DTV. +See the accelerator.h header for the speed definitions. + +, +, + + + + set_scpu_speed

/ - The function is specific to the C128 and C64. diff --git a/include/accelerator.h b/include/accelerator.h index 7d1244233..336bbb036 100644 --- a/include/accelerator.h +++ b/include/accelerator.h @@ -98,5 +98,43 @@ extern unsigned char detect_scpu (void); * 0x01 : SuperCPU cartridge present */ + +/* C64DTV */ + +extern unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed); + +/* Set the speed of the C64DTV, using SPEED_SLOW will switch to + * slow mode, SPEED_2X or SPEED_FAST will switch to fast mode. + * + * Note that any value higher or equal to SPEED_2X 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 switch should not fail. + * + * This function does not check for the presence of the C64DTV, + * make sure you use 'detect_c64dtv();' before using. + */ + +extern unsigned char get_c64dtv_speed (void); + +/* Get the speed of the C64DTV. + * + * Possible return values: + * SPEED_1X : slow mode + * SPEED_2X : fast mode + * + * This function does not check for the presence of the C64DTV, + * make sure you use 'detect_c64dtv();' before using. + */ + +extern unsigned char detect_c64dtv (void); + +/* Check for the presence of the C64DTV. + * + * Possible return values: + * 0x00 : C64DTV not present + * 0x01 : C64DTV present + */ + /* End of accelerator.h */ #endif diff --git a/libsrc/c64/acc_c64dtv_speed.s b/libsrc/c64/acc_c64dtv_speed.s new file mode 100755 index 000000000..6a8371a9c --- /dev/null +++ b/libsrc/c64/acc_c64dtv_speed.s @@ -0,0 +1,64 @@ +; +; Marco van den Heuvel, 2018-04-14 +; + +; extern unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed); +; +;/* Set the speed of the C64DTV, using SPEED_SLOW will switch to +; * slow mode, SPEED_2X or SPEED_FAST will switch to fast mode. +; * +; * Note that any value higher or equal to SPEED_2X 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 the C64DTV, +; * make sure you use 'detect_c64dtv();' before using. +; */ + +; extern unsigned char get_c64dtv_speed (void); +; +;/* Get the speed of the C64DTV. +; * +; * Possible return values: +; * SPEED_1X : slow mode +; * SPEED_2X : fast mode +; * +; * This function does not check for the presence of the C64DTV, +; * make sure you use 'detect_c64dtv();' before using. +; */ + + .export _set_c64dtv_speed + .export _get_c64dtv_speed + + .include "accelerator.inc" + +_set_c64dtv_speed: + cmp #SPEED_2X + bcs high_speed +low_speed: + ldx #C64DTV_Slow +set_speed: + .byte $32,$99 ; SAC #$99 set accumulator to reg 9 (cpu control) + txa ; (re)set skip and burst bits + .byte $32,$00 ; SAC #$00 set accumulator back to reg 0 + jmp _get_c64dtv_speed + +high_speed: + ldx #C64DTV_Fast + bne set_speed + + +_get_c64dtv_speed: + .byte $32,$99 ; SAC #$99 set accumulator to reg 9 (cpu control) + tax + .byte $32,$00 ; SAC #$00 set accumulator back to reg 0 + txa + and #C64DTV_Fast + bne in_fast_mode + lda #$00 + .byte $2C +in_fast_mode: + lda #$01 + ldx #$00 + rts diff --git a/libsrc/c64/acc_detect_c64dtv.s b/libsrc/c64/acc_detect_c64dtv.s new file mode 100755 index 000000000..1734095b1 --- /dev/null +++ b/libsrc/c64/acc_detect_c64dtv.s @@ -0,0 +1,44 @@ +; +; Marco van den Heuvel, 2018-04-14 +; + +; unsigned char detect_c64dtv (void); +; +;/* Check for the presence of the C64DTV. +; * +; * Possible return values: +; * 0x00 : C64DTV not present +; * 0x01 : C64DTV present +; */ + + .export _detect_c64dtv + + .include "accelerator.inc" + +_detect_c64dtv: + ldy C64DTV_Extended_Regs + lda #$00 + ldx $D000 + +; Make sure the CPU is a 6510 + .byte $1A ; NOP on 8502, INA on 65(S)C(E)02, 4510 and 65816 + bne not_found + lda #$01 + sta C64DTV_Extended_Regs + +; Check if $D000 is mirrored at $D040 + cpx $D040 + bne found + inc $D000 + cpx $D040 + bne not_found +found: + lda #$01 + .byte $2C +not_found: + lda #$00 + stx $D000 + ldx #$00 + sty C64DTV_Extended_Regs + rts + diff --git a/testcode/lib/accelerator/Makefile b/testcode/lib/accelerator/Makefile index ece54ec36..a9fe5f78d 100644 --- a/testcode/lib/accelerator/Makefile +++ b/testcode/lib/accelerator/Makefile @@ -1,9 +1,13 @@ CL ?= cl65 -all: c64-scpu-test.prg c128-scpu-test.prg +all: c64-scpu-test.prg c128-scpu-test.prg c64dtv-test.prg c64-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c64 c64-c128-scpu-test.c -o c64-scpu-test.prg c128-scpu-test.prg: c64-c128-scpu-test.c $(CL) -t c128 c64-c128-scpu-test.c -o c128-scpu-test.prg + +c64dtv-test.prg: c64dtv-test.c + $(CL) -t c64 c64dtv-test.c -o c64dtv-test.prg + diff --git a/testcode/lib/accelerator/c64dtv-test.c b/testcode/lib/accelerator/c64dtv-test.c new file mode 100755 index 000000000..34f0410d9 --- /dev/null +++ b/testcode/lib/accelerator/c64dtv-test.c @@ -0,0 +1,8 @@ +/* C64DTV accelerator test code. */ + +#define ACC_DETECT detect_c64dtv +#define ACC_GET_SPEED get_c64dtv_speed +#define ACC_SET_SPEED set_c64dtv_speed +#define ACC_NAME "C64DTV" + +#include "turbo-test.c"