From f05ddef5fdcb3e98cf7c0a520a91cc8f3f5b5d10 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 30 Dec 2019 20:28:52 +0100 Subject: [PATCH] initial work towards burst IEC protocol support --- CONFIG.md | 8 +-- c64/,,config_custom.s | 11 ++-- c64/,,config_generic.s | 2 +- c64/,,config_mega65.s | 2 +- c64/,,config_testing.s | 2 +- c64/,,config_ultimate64.s | 2 +- c64/aliases/,aliases_config.s | 54 +++++++++++++-- c64/aliases/,aliases_ram_lowmem.s | 2 +- c64/kernal/assets/irq_timing_hi.s | 23 +++++++ c64/kernal/assets/irq_timing_lo.s | 23 +++++++ c64/kernal/iec/iec_cmd_open.s | 8 ++- .../iec_update_eal_by_y.s} | 2 +- c64/kernal/iec/load_iec.s | 5 +- c64/kernal/iec/save_iec.s | 5 +- c64/kernal/iec_fast/burst_cia1_detect.s | 31 +++++++++ c64/kernal/iec_fast/burst_cia2_detect.s | 66 +++++++++++++++++++ c64/kernal/iec_fast/burst_soft_detect.s | 27 ++++++++ c64/kernal/iec_fast/jiffydos_load.s | 6 +- c64/kernal/init/fda3.ioinit.s | 11 +--- c64/kernal/init/setup_pal_ntsc.s | 58 ++++++++-------- 20 files changed, 280 insertions(+), 68 deletions(-) create mode 100644 c64/kernal/assets/irq_timing_hi.s create mode 100644 c64/kernal/assets/irq_timing_lo.s rename c64/kernal/{iec_fast/iec_fast_common.s => iec/iec_update_eal_by_y.s} (80%) create mode 100644 c64/kernal/iec_fast/burst_cia1_detect.s create mode 100644 c64/kernal/iec_fast/burst_cia2_detect.s create mode 100644 c64/kernal/iec_fast/burst_soft_detect.s diff --git a/CONFIG.md b/CONFIG.md index 39dec2bd..df65d62a 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -109,10 +109,6 @@ Adds support for the IEEC bus - for serial printers, disk drives, etc. Needs over 1000 bytes in KERNAL segment. If unsure - enable. -### `CONFIG_IEC_BLANK_SCREEN` - -Causes screen blanking during some IEC operations (currently only JiffyDOS file loading) to increase the data transfer performance. - ### `CONFIG_IEC_DOLPHINDOS` Adds support for DolphinDOS fast protocol to the IEC bus, using UserPort cable. @@ -131,6 +127,10 @@ Adds support for JiffyDOS fast protocol to the IEC bus. Needs about 430 bytes in KERNAL segment. If unsure - enable. +### `CONFIG_IEC_JIFFYDOS_BLANK` + +Causes screen blanking during iffyDOS file loading to increase performance. + ### `CONFIG_TAPE_NORMAL` Adds a minimal normal (standard Commodore format) tape support - just LOAD command. diff --git a/c64/,,config_custom.s b/c64/,,config_custom.s index 2e6799c1..2911e68c 100644 --- a/c64/,,config_custom.s +++ b/c64/,,config_custom.s @@ -45,16 +45,19 @@ // I/O devices #define CONFIG_IEC -#define CONFIG_IEC_BLANK_SCREEN -#define CONFIG_IEC_DOLPHINDOS // not finished yet, but LOAD works +#define CONFIG_IEC_DOLPHINDOS #define CONFIG_IEC_DOLPHINDOS_FAST #define CONFIG_IEC_JIFFYDOS +#define CONFIG_IEC_JIFFYDOS_BLANK +// #define CONFIG_IEC_BURST_CIA1 // please keep disabled for now +// #define CONFIG_IEC_BURST_CIA2 // please keep disabled for now +// #define CONFIG_IEC_BURST_SOFT // please keep disabled for now #define CONFIG_TAPE_NORMAL #define CONFIG_TAPE_TURBO -// #define CONFIG_RS232_UP2400 // please keep disabled for now -// #define CONFIG_RS232_UP9600 // please keep disabled for now +// #define CONFIG_RS232_UP2400 // please keep disabled for now +// #define CONFIG_RS232_UP9600 // please keep disabled for now // Multiple SID support diff --git a/c64/,,config_generic.s b/c64/,,config_generic.s index 258caf5a..362566a3 100644 --- a/c64/,,config_generic.s +++ b/c64/,,config_generic.s @@ -42,10 +42,10 @@ // I/O devices #define CONFIG_IEC -#define CONFIG_IEC_BLANK_SCREEN #define CONFIG_IEC_DOLPHINDOS #define CONFIG_IEC_DOLPHINDOS_FAST #define CONFIG_IEC_JIFFYDOS +#define CONFIG_IEC_JIFFYDOS_BLANK #define CONFIG_TAPE_NORMAL #define CONFIG_TAPE_TURBO diff --git a/c64/,,config_mega65.s b/c64/,,config_mega65.s index eebb62e4..4c243094 100644 --- a/c64/,,config_mega65.s +++ b/c64/,,config_mega65.s @@ -42,10 +42,10 @@ // I/O devices #define CONFIG_IEC -#define CONFIG_IEC_BLANK_SCREEN // #define CONFIG_IEC_DOLPHINDOS // #define CONFIG_IEC_DOLPHINDOS_FAST #define CONFIG_IEC_JIFFYDOS +#define CONFIG_IEC_JIFFYDOS_BLANK // #define CONFIG_TAPE_NORMAL // #define CONFIG_TAPE_TURBO diff --git a/c64/,,config_testing.s b/c64/,,config_testing.s index 317eeed9..4e910880 100644 --- a/c64/,,config_testing.s +++ b/c64/,,config_testing.s @@ -42,10 +42,10 @@ // I/O devices #define CONFIG_IEC -// #define CONFIG_IEC_BLANK_SCREEN #define CONFIG_IEC_DOLPHINDOS // #define CONFIG_IEC_DOLPHINDOS_FAST #define CONFIG_IEC_JIFFYDOS +// #define CONFIG_IEC_JIFFYDOS_BLANK // #define CONFIG_TAPE_NORMAL #define CONFIG_TAPE_TURBO diff --git a/c64/,,config_ultimate64.s b/c64/,,config_ultimate64.s index 3d4cce51..2f2a2206 100644 --- a/c64/,,config_ultimate64.s +++ b/c64/,,config_ultimate64.s @@ -42,10 +42,10 @@ // I/O devices #define CONFIG_IEC -#define CONFIG_IEC_BLANK_SCREEN #define CONFIG_IEC_DOLPHINDOS #define CONFIG_IEC_DOLPHINDOS_FAST #define CONFIG_IEC_JIFFYDOS +#define CONFIG_IEC_JIFFYDOS_BLANK #define CONFIG_TAPE_NORMAL #define CONFIG_TAPE_TURBO diff --git a/c64/aliases/,aliases_config.s b/c64/aliases/,aliases_config.s index c9a096d9..4a375175 100644 --- a/c64/aliases/,aliases_config.s +++ b/c64/aliases/,aliases_config.s @@ -112,10 +112,15 @@ } -// Check that I/O configuration is correct + +// Check that IEC configuration is correct { -#if CONFIG_RS232_UP9600 && (CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO) - .error "CONFIG_RS232_UP9600 is not compatible with CONFIG_TAPE_*" +#if CONFIG_IEC_JIFFYDOS && !CONFIG_IEC + .error "CONFIG_IEC_JIFFYDOS requires CONFIG_IEC" +#endif + +#if CONFIG_IEC_JIFFYDOS_BLANK && !CONFIG_IEC_JIFFYDOS + .error "CONFIG_IEC_JIFFYDOS_BLANK requires CONFIG_IEC_JIFFYDOS" #endif #if CONFIG_IEC_DOLPHINDOS && !CONFIG_IEC @@ -126,8 +131,35 @@ .error "CONFIG_IEC_DOLPHINDOS_FAST requires CONFIG_IEC_DOLPHINDOS" #endif -#if CONFIG_IEC_JIFFYDOS && !CONFIG_IEC - .error "CONFIG_IEC_JIFFYDOS requires CONFIG_IEC" +#if (CONFIG_IEC_BURST_CIA1 || CONFIG_IEC_BURST_CIA1 || CONFIG_IEC_BURST_SOFT) && !CONFIG_IEC + .error "CONFIG_IEC_BURST_* requires CONFIG_IEC" +#endif + +#if CONFIG_IEC_BURST_SOFT && !CONFIG_MB_MEGA_65 + .error "CONFIG_IEC_BURST_SOFT requires CONFIG_MB_MEGA_65" +#endif + + .var selected_iec_burst = 0; + +#if CONFIG_IEC_BURST_CIA1 + .eval selected_iec_burst++ +#endif +#if CONFIG_IEC_BURST_CIA2 + .eval selected_iec_burst++ +#endif +#if CONFIG_IEC_BURST_SOFT + .eval selected_iec_burst++ +#endif + + .if (selected_iec_burst > 1) .error "Please select at most one CONFIG_IEC_BURST_* option" +} + + + +// Check that RS-232 configuration is correct +{ +#if CONFIG_RS232_UP9600 && (CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO) + .error "CONFIG_RS232_UP9600 is not compatible with CONFIG_TAPE_*" #endif .var selected_rs232 = 0; @@ -143,6 +175,7 @@ } + // Check that startup banner configuration is correct { .var selected = 0; @@ -322,13 +355,22 @@ #if CONFIG_IEC .var iec_features_str = "IEC" +#if CONFIG_IEC_BURST_CIA1 + .eval iec_features_str = iec_features_str + " BURST1" +#endif +#if CONFIG_IEC_BURST_CIA2 + .eval iec_features_str = iec_features_str + " BURST2" +#endif +#if CONFIG_IEC_BURST_SOFT + .eval iec_features_str = iec_features_str + " BURST" +#endif #if CONFIG_IEC_DOLPHINDOS .eval iec_features_str = iec_features_str + " DOLPHIN" #endif #if CONFIG_IEC_JIFFYDOS .eval iec_features_str = iec_features_str + " JIFFY" #endif -#if !CONFIG_IEC_DOLPHINDOS && !CONFIG_IEC_JIFFYDOS +#if !CONFIG_IEC_BURST_CIA1 && !CONFIG_IEC_BURST_CIA2 && !CONFIG_IEC_BURST_SOFT && !CONFIG_IEC_DOLPHINDOS && !CONFIG_IEC_JIFFYDOS .eval iec_features_str = iec_features_str + " NORMAL" #endif .eval features_str = ADD_FEATURE(features_str, iec_features_str) diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index c554e0de..cf1f4ee8 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -103,7 +103,7 @@ .label PTR1 = $9E // -- NOT IMPLEMENTED -- .label PTR2 = $9F // -- NOT IMPLEMENTED -- .label TIME = $A0 // $A0-$A2 jiffy clock -#if !CONFIG_IEC_JIFFYDOS && !CONFIG_IEC_DOLPHINDOS +#if !CONFIG_IEC_JIFFYDOS && !CONFIG_IEC_DOLPHINDOS && !CONFIG_IEC_BURST_CIA1 && !CONFIG_IEC_BURST_CIA2 && !CONFIG_IEC_BURST_SOFT .label TSFCNT = $A3 // temporary variable for tape and IEC, [!] our usage differs #else .label IECPROTO = $A3 // -- WIP -- [!] 0 = normal, 1 = JiffyDOS, >= $80 for unknown diff --git a/c64/kernal/assets/irq_timing_hi.s b/c64/kernal/assets/irq_timing_hi.s new file mode 100644 index 00000000..86cd851c --- /dev/null +++ b/c64/kernal/assets/irq_timing_hi.s @@ -0,0 +1,23 @@ + +// +// Values for IRQ generation timer - original idea was: +// +// (This value was calculated by running a custom IRQ handler on a C64 +// with original KERNAL, and writing the values of $DC04/5 to the screen +// in the IRQ handler to see roughly what value the timers must be set to) +// ldy #<16380 +// ldx #>16380 + +// Current values selected on the following assumptions: +// +// PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), +// is clocked at 0.985248 MHz, so that 1/60s is 16421 ($4025) CPU cycles +// +// NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), +// is clocked at 1.022727 MHz, so that 1/60s is 17045 ($4295) CPU cycles + + +irq_timing_hi: // high bytes + + .byte >17045 // NTSC + .byte >16421 // PAL diff --git a/c64/kernal/assets/irq_timing_lo.s b/c64/kernal/assets/irq_timing_lo.s new file mode 100644 index 00000000..6f6872aa --- /dev/null +++ b/c64/kernal/assets/irq_timing_lo.s @@ -0,0 +1,23 @@ + +// +// Values for IRQ generation timer - original idea was: +// +// (This value was calculated by running a custom IRQ handler on a C64 +// with original KERNAL, and writing the values of $DC04/5 to the screen +// in the IRQ handler to see roughly what value the timers must be set to) +// ldy #<16380 +// ldx #>16380 + +// Current values selected on the following assumptions: +// +// PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), +// is clocked at 0.985248 MHz, so that 1/60s is 16421 ($4025) CPU cycles +// +// NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), +// is clocked at 1.022727 MHz, so that 1/60s is 17045 ($4295) CPU cycles + + +irq_timing_lo: // low bytes + + .byte <17045 // NTSC + .byte <16421 // PAL diff --git a/c64/kernal/iec/iec_cmd_open.s b/c64/kernal/iec/iec_cmd_open.s index 54159d78..835ed317 100644 --- a/c64/kernal/iec/iec_cmd_open.s +++ b/c64/kernal/iec/iec_cmd_open.s @@ -17,13 +17,19 @@ iec_cmd_open: // similar to TKSA, but without turnaround !: ora #$F0 -#if CONFIG_IEC_DOLPHINDOS +#if CONFIG_IEC_DOLPHINDOS || CONFIG_IEC_BURST_CIA1 || CONFIG_IEC_BURST_CIA2 || CONFIG_IEC_BURST_SOFT sta TBTCNT jsr iec_tx_command bcs !+ // branch if error +#if CONFIG_IEC_DOLPHINDOS jsr dolphindos_detect +#endif +#if CONFIG_IEC_BURST_CIA1 || CONFIG_IEC_BURST_CIA2 || CONFIG_IEC_BURST_SOFT + jsr burst_detect +#endif + jmp iec_tx_command_finalize #else diff --git a/c64/kernal/iec_fast/iec_fast_common.s b/c64/kernal/iec/iec_update_eal_by_y.s similarity index 80% rename from c64/kernal/iec_fast/iec_fast_common.s rename to c64/kernal/iec/iec_update_eal_by_y.s index a7ce0bb6..a41a6106 100644 --- a/c64/kernal/iec_fast/iec_fast_common.s +++ b/c64/kernal/iec/iec_update_eal_by_y.s @@ -1,6 +1,6 @@ // -// Common routines for multiple IEC fact protocols +// Common EAL update routine // diff --git a/c64/kernal/iec/load_iec.s b/c64/kernal/iec/load_iec.s index d901e6a7..fabe54be 100644 --- a/c64/kernal/iec/load_iec.s +++ b/c64/kernal/iec/load_iec.s @@ -63,9 +63,10 @@ load_iec: bcs load_iec_error #if CONFIG_IEC_DOLPHINDOS - jsr dolphindos_detect - +#endif +#if CONFIG_IEC_BURST_CIA1 || CONFIG_IEC_BURST_CIA2 || CONFIG_IEC_BURST_SOFT + jsr burst_detect #endif // We are currently talker, so do the IEC turn around so that we diff --git a/c64/kernal/iec/save_iec.s b/c64/kernal/iec/save_iec.s index bd6aade5..d09e08a7 100644 --- a/c64/kernal/iec/save_iec.s +++ b/c64/kernal/iec/save_iec.s @@ -45,9 +45,10 @@ save_iec: bcs save_iec_dev_not_found #if CONFIG_IEC_DOLPHINDOS - jsr dolphindos_detect - +#endif +#if CONFIG_IEC_BURST_CIA1 || CONFIG_IEC_BURST_CIA2 || CONFIG_IEC_BURST_SOFT + jsr burst_detect #endif // Save start address diff --git a/c64/kernal/iec_fast/burst_cia1_detect.s b/c64/kernal/iec_fast/burst_cia1_detect.s new file mode 100644 index 00000000..cf36e58b --- /dev/null +++ b/c64/kernal/iec_fast/burst_cia1_detect.s @@ -0,0 +1,31 @@ + +// +// Helper routine for burst IEC protocol support +// + +// +// Based on idea by Pasi 'Albert' Ojala +// + + +#if CONFIG_IEC_BURST_CIA1 + + +burst_detect: + +#if CONFIG_IEC_JIFFYDOS || CONFIG_IEC_DOLPHINDOS + + lda IECPROTO + bmi !+ + bne burst_detect_fail // skip if other protocol already detected +!: +#endif + + panic #$FF // XXX implement this + +burst_detect_fail: + + rts + + +#endif diff --git a/c64/kernal/iec_fast/burst_cia2_detect.s b/c64/kernal/iec_fast/burst_cia2_detect.s new file mode 100644 index 00000000..19fba610 --- /dev/null +++ b/c64/kernal/iec_fast/burst_cia2_detect.s @@ -0,0 +1,66 @@ + +// +// Helper routine for burst IEC protocol support +// + +// +// Based on idea by Pasi 'Albert' Ojala +// + + +#if CONFIG_IEC_BURST_CIA2 + + +burst_detect: + +#if CONFIG_IEC_JIFFYDOS || CONFIG_IEC_DOLPHINDOS + + lda IECPROTO + bmi !+ + bne burst_detect_fail // skip if other protocol already detected +!: +#endif + + // For extra safety, do it on disabled interupts + php + sei + + // Set the clock rate to the fastest possible + ldy #$01 + sty CIA2_TIMALO + dey + sty CIA2_TIMAHI + + // Prepare registers for transfer + lda #$C1 + sta CIA2_CRA // start timer A, serial out, TOD 50Hz + bit CIA2_ICR // clear interrupt register + + // Send test byte + lda #$FF // $FF keeps DATA released, see https://www.c64-wiki.com/wiki/Fast_serial_bus_protocol + sta CIA2_SDR + + // Wait until byte sent + lda #$08 // interrupt mask +!: + bit CIA2_ICR + beq !- + + // Now see if we get any byte back + + lda CIA2_SDR // XXX we do not need a value, we need to know if it was received + + + panic #$00 // XXX finish this routine + + + plp + + // FALLTROUGH + +burst_detect_fail: + + rts + + +#endif diff --git a/c64/kernal/iec_fast/burst_soft_detect.s b/c64/kernal/iec_fast/burst_soft_detect.s new file mode 100644 index 00000000..cd31a19e --- /dev/null +++ b/c64/kernal/iec_fast/burst_soft_detect.s @@ -0,0 +1,27 @@ + +// +// Helper routine for burst IEC protocol support +// + + +#if CONFIG_IEC_BURST_SOFT + + +burst_detect: + +#if CONFIG_IEC_JIFFYDOS || CONFIG_IEC_DOLPHINDOS + + lda IECPROTO + bmi !+ + bne burst_detect_fail // skip if other protocol already detected +!: +#endif + + panic #$FF // XXX implement this + +burst_detect_fail: + + rts + + +#endif diff --git a/c64/kernal/iec_fast/jiffydos_load.s b/c64/kernal/iec_fast/jiffydos_load.s index 5b6ca0c4..bd83e271 100644 --- a/c64/kernal/iec_fast/jiffydos_load.s +++ b/c64/kernal/iec_fast/jiffydos_load.s @@ -20,7 +20,7 @@ jiffydos_load: // Timing is critical, do not allow interrupts sei -#if CONFIG_IEC_BLANK_SCREEN +#if CONFIG_IEC_JIFFYDOS_BLANK // Preserve register with screen status (blank/visibe) lda VIC_SCROLY @@ -57,7 +57,7 @@ jiffydos_load_loop: lda CIA2_PRA and #$FF - BIT_CIA2_PRA_DAT_OUT // release -#if CONFIG_IEC_BLANK_SCREEN +#if CONFIG_IEC_JIFFYDOS_BLANK // It seems JiffyDOS needs some time here; waste few cycles nop @@ -143,7 +143,7 @@ jiffydos_load_end: lda #$01 sta IECPROTO -#if CONFIG_IEC_BLANK_SCREEN +#if CONFIG_IEC_JIFFYDOS_BLANK // Restore screen state lda TBTCNT diff --git a/c64/kernal/init/fda3.ioinit.s b/c64/kernal/init/fda3.ioinit.s index 59fa824d..0ca661f9 100644 --- a/c64/kernal/init/fda3.ioinit.s +++ b/c64/kernal/init/fda3.ioinit.s @@ -110,8 +110,6 @@ IOINIT: lda #$3F sta CIA2_DDRA // $DD02 - // XXX detect TOD clock, see https://codebase64.org/doku.php?id=base:efficient_tod_initialisation - // XXX how to initialize these timers??? // stx CIA1_CRB // $DC0F // stx CIA2_CRA // $DD0E @@ -123,13 +121,8 @@ IOINIT: ldx #%00000111 // XXX adapt this to IEC idle state, JMP at the end won't be needed stx CIA2_PRA // $DD00 - // - - ldy #<16421 - ldx #>16421 - - sty CIA1_TIMALO // $DC04 - stx CIA1_TIMAHI // $DC05 + // Put something sane in the IRQ timer + jsr setup_irq_timer // Enable timer A to run continuously (http://codebase64.org/doku.php?id=base:timerinterrupts) ldx #$11 diff --git a/c64/kernal/init/setup_pal_ntsc.s b/c64/kernal/init/setup_pal_ntsc.s index 99668527..101cf716 100644 --- a/c64/kernal/init/setup_pal_ntsc.s +++ b/c64/kernal/init/setup_pal_ntsc.s @@ -23,43 +23,39 @@ setup_pal_ntsc: setup_pal: - // Set timer interval to ~1/60th of a second - - // (This value was calculated by running a custom IRQ handler on a C64 - // with original KERNAL, and writing the values of $DC04/5 to the screen - // in the IRQ handler to see roughly what value the timers must be set to) - // ldy #<16380 - // ldx #>16380 - - // PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), - // is clocked at 0.985248 MHz, so that 1/60s is 16421 ($4025) CPU cycles - - ldy #<16421 - ldx #>16421 - lda #$01 + skip_2_bytes_trash_nvz + + // FALLTROUGH + +setup_ntsc: + + lda #$00 // FALLTROUGH setup_pal_ntsc_end: - sty CIA1_TIMALO // $DC04 - stx CIA1_TIMAHI // $DC05 - sta TVSFLG + // FALLTROUGH + +setup_irq_timer: // entry point needed by UP9600 and CIA1 burst mod support + + // Sets up IRQ timer in CIA1 to ~1/60th of a second, + // depending on the detected video system + + // Retrieve video system (0 - NTSC, 1 - PAL), assume PAL for unknown values + + ldx TVSFLG + beq !+ + ldx #$01 +!: + // Setup interval for timer A in CIA1 + + lda irq_timing_lo, x + sta CIA1_TIMALO // $DC04 + lda irq_timing_hi, x + sta CIA1_TIMAHI // $DC05 + rts - -setup_ntsc: - - // Set timer interval to ~1/60th of a second - - // NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), - // is clocked at 1.022727 MHz, so that 1/60s is 17045 ($4295) CPU cycles - - ldy #<17045 - ldx #>17045 - - lda #$00 - - beq setup_pal_ntsc_end // branch always