From 459672812194c8722312da8a7e997a75663b7946 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Thu, 28 Nov 2019 22:19:37 +0100 Subject: [PATCH] separate directory for fast IEC routines --- Makefile | 1 + c64/kernal/iec/iec_jiffydos.s | 238 ------------------ c64/kernal/iec_fast/iec_rx_byte_jiffydos.s | 97 +++++++ .../{iec => iec_fast}/iec_rx_dispatch.s | 0 c64/kernal/iec_fast/iec_tx_byte_jiffydos.s | 102 ++++++++ .../{iec => iec_fast}/iec_tx_dispatch.s | 0 .../jiffydos_bittable.s} | 2 +- c64/kernal/iec_fast/jiffydos_prepare.s | 29 +++ c64/kernal/iec_fast/jiffydos_wait_line.s | 33 +++ 9 files changed, 263 insertions(+), 239 deletions(-) delete mode 100644 c64/kernal/iec/iec_jiffydos.s create mode 100644 c64/kernal/iec_fast/iec_rx_byte_jiffydos.s rename c64/kernal/{iec => iec_fast}/iec_rx_dispatch.s (100%) create mode 100644 c64/kernal/iec_fast/iec_tx_byte_jiffydos.s rename c64/kernal/{iec => iec_fast}/iec_tx_dispatch.s (100%) rename c64/kernal/{iec/iec_jiffydos_bittable.s => iec_fast/jiffydos_bittable.s} (97%) create mode 100644 c64/kernal/iec_fast/jiffydos_prepare.s create mode 100644 c64/kernal/iec_fast/jiffydos_wait_line.s diff --git a/Makefile b/Makefile index 02266937..338def52 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,7 @@ SRCDIR_KERNAL = $(SRCDIR_COMMON) \ c64/kernal/,stubs \ c64/kernal/assets \ c64/kernal/iec \ + c64/kernal/iec_fast \ c64/kernal/init \ c64/kernal/interrupts \ c64/kernal/iostack \ diff --git a/c64/kernal/iec/iec_jiffydos.s b/c64/kernal/iec/iec_jiffydos.s deleted file mode 100644 index e19795f8..00000000 --- a/c64/kernal/iec/iec_jiffydos.s +++ /dev/null @@ -1,238 +0,0 @@ - -// -// JiffyDOS protocol support for IEC -// - -// XXX make it work -// XXX split into multiple files - - - -#if CONFIG_IEC_JIFFYDOS - - -// JiffyDOS timing regime is very strict - before transmitting anything -// we need to disable sprites and (if screen is not disabled) wait for -// appropriate moment, so that no badline interruption can happen - - -iec_tx_byte_jiffydos: - - // Timing is critical, do not allow interrupts - sei - - // If EOI requested (carry flag set), mark this in IECPROTO as 0 - bcc !+ - dec IECPROTO // turns 1 into 0 -!: - // Store .X and .Y on the stack - preserve them - phx_trash_a - phy_trash_a - - // Store previous sprite status on stack - jsr jiffydos_prepare_for_transfer - pha - - // Prepare nibbles to send - lda TBTCNT - and #$0F - tax - lda iec_jiffydos_bittable, X // low nibble has to be encoded - pha - lda TBTCNT - and #$F0 - pha - - // Prepare value for device notification - ldx C3PO - - // Wait till receiver is ready - jsr iec_wait_for_data_release - - // Wait till it is safe to send data - jsr jiffydos_wait_line - - // Notify device that we are going to send byte by releasing everything - stx CIA2_PRA // cycles: 4 - - // Send high nibble; cycles: 4 + 3 + 4 + 2 + 2 + 2 + 3 + 4 = 24 - pla // retrieve high nibble from stack - ora C3PO // restore VIC-II and RS-232 bits - sta CIA2_PRA // bits 4 and 5 on CLK/DATA - lsr // move bits 6 and 7 to positions 4 and 5 - lsr - and #%00110000 // clear everything but CLK/DATA - ora C3PO - sta CIA2_PRA // bits 6 and 7 on CLK/DATA - - // Send low nibble; cycles: 4 + 3 + 4 + 2 + 2 + 2 + 4 = 21 - pla // retrieve low nibble from stack - ora C3PO // restore VIC-II and RS-232 bits - sta CIA2_PRA - lsr - lsr - and #%00110000 // clear everything but CLK/DATA - sta CIA2_PRA - - // Signal EOI if needed; cycles till no EOI: 3 + 3 + 2 + 2 + 4 = 14 - lda C3PO - ldx IECPROTO - beq iec_tx_byte_jiffydos_wait_eoi - - // FALLTROUGH - -iec_tx_byte_jiffydos_finalize: - - ora #BIT_CIA2_PRA_CLK_OUT // pull CLK - sta CIA2_PRA - - // Restore proper IECPROTO value - lda #$01 - sta IECPROTO - - // Re-enable sprites and interrupts - pla - sta VIC_SPENA - cli - - // Return success - jmp iec_return_success - - -iec_tx_byte_jiffydos_wait_eoi: - - jsr iec_wait20us // XXX is it enough? - lda C3PO - jmp iec_tx_byte_jiffydos_finalize - - - -iec_rx_byte_jiffydos: - - // Timing is critical, do not allow interrupts - sei - - // Store .X and .Y on the stack - preserve them - phx_trash_a - phy_trash_a - - // Store previous sprite status on stack - jsr jiffydos_prepare_for_transfer - pha - - // Wait until device is ready to send - jsr iec_wait_for_clk_release - - // Prepare 'start sending' message - lda CIA2_PRA - and #$FF - BIT_CIA2_PRA_DAT_OUT // release - tax - - // Wait for appropriate moment - jsr jiffydos_wait_line - - // Ask device to start sending bits - stx CIA2_PRA // cycles: 4 - - // XXX we have to wait 20 cycles??? seriously??? what the hell shall we do here??? - pla // 4 cycles - pha // 3 cycles - pla // 4 cycles - pha // 3 cycles - nop // 2 cycles - nop // 2 cycles - nop // 2 cycles - - // Get bits, cycles: 4 + 2 + 2 = 8 - lda CIA2_PRA // bits 0 and 1 on CLK/DATA - lsr - lsr - - // Wait for the drive, cycles: 2 - nop - - // Get bits, cycles: 4 + 2 + 2 = 8 - ora CIA2_PRA // bits 2 and 3 on CLK/DATA - lsr - lsr - - // Get bits, cycles: 3 + 4 + 2 + 2 = 11 - eor C3PO - eor CIA2_PRA // bits 4 and 5 on CLK/DATA - lsr - lsr - - // Get bits, cycles: 3 + 4 = 7 - eor C3PO - eor CIA2_PRA // bits 6 and 7 on CLK/DATA - - // Preserve read byte - sta TBTCNT // $A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html - - // Retrieve status bits - lda CIA2_PRA - tax - - // Pull DATA at the end - ora #BIT_CIA2_PRA_DAT_OUT - sta CIA2_PRA - - // Check for EOI - txa - bmi !+ - jsr kernalstatus_EOI -!: - // Restore proper IECPROTO value - lda #$01 - sta IECPROTO - - // Re-enable sprites - pla - sta VIC_SPENA - - // End byte reception - jmp iec_rx_end - - - -jiffydos_wait_line: - - lda VIC_SCROLY - and #$10 - beq jiffydos_wait_line_done // screen is disabled, no need to watch for badlines - - // Avoid 2 lines before the badline, otherwise VIC will ruin the synchronization - lda VIC_RASTER - cmp #$2E - bcc jiffydos_wait_line_done // we are safe, border - lot of time till badline -!: - lda VIC_RASTER // carry+ is definitely set here! - sbc VIC_SCROLY - and #$07 // we want 8 lowest bits - cmp #$06 - bcs !- - -jiffydos_wait_line_done: - - rts - - - -jiffydos_prepare_for_transfer: - - // We need to preserve 3 lowest bits of CIA2_PRA, they contain important - // data - fortunately, the bits are never changed by external devices - // Use C3PO for this, as afterwards we have to set there 0 nevertheless - lda CIA2_PRA - and #%00000111 - sta C3PO - - // Hide sprites - lda VIC_SPENA - ldx #$00 - stx VIC_SPENA - - rts - - -#endif // CONFIG_IEC_JIFFYDOS diff --git a/c64/kernal/iec_fast/iec_rx_byte_jiffydos.s b/c64/kernal/iec_fast/iec_rx_byte_jiffydos.s new file mode 100644 index 00000000..ffe072bf --- /dev/null +++ b/c64/kernal/iec_fast/iec_rx_byte_jiffydos.s @@ -0,0 +1,97 @@ + +// +// JiffyDOS protocol support for IEC - byte reception +// + + +#if CONFIG_IEC_JIFFYDOS + + +iec_rx_byte_jiffydos: + + // Timing is critical, do not allow interrupts + sei + + // Store .X and .Y on the stack - preserve them + phx_trash_a + phy_trash_a + + // Store previous sprite status on stack + jsr jiffydos_prepare + pha + + // Wait until device is ready to send + jsr iec_wait_for_clk_release + + // Prepare 'start sending' message + lda CIA2_PRA + and #$FF - BIT_CIA2_PRA_DAT_OUT // release + tax + + // Wait for appropriate moment + jsr jiffydos_wait_line + + // Ask device to start sending bits + stx CIA2_PRA // cycles: 4 + + // XXX we have to wait 20 cycles??? seriously??? what the hell shall we do here??? + pla // 4 cycles + pha // 3 cycles + pla // 4 cycles + pha // 3 cycles + nop // 2 cycles + nop // 2 cycles + nop // 2 cycles + + // Get bits, cycles: 4 + 2 + 2 = 8 + lda CIA2_PRA // bits 0 and 1 on CLK/DATA + lsr + lsr + + // Wait for the drive, cycles: 2 + nop + + // Get bits, cycles: 4 + 2 + 2 = 8 + ora CIA2_PRA // bits 2 and 3 on CLK/DATA + lsr + lsr + + // Get bits, cycles: 3 + 4 + 2 + 2 = 11 + eor C3PO + eor CIA2_PRA // bits 4 and 5 on CLK/DATA + lsr + lsr + + // Get bits, cycles: 3 + 4 = 7 + eor C3PO + eor CIA2_PRA // bits 6 and 7 on CLK/DATA + + // Preserve read byte + sta TBTCNT // $A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html + + // Retrieve status bits + lda CIA2_PRA + tax + + // Pull DATA at the end + ora #BIT_CIA2_PRA_DAT_OUT + sta CIA2_PRA + + // Check for EOI + txa + bmi !+ + jsr kernalstatus_EOI +!: + // Restore proper IECPROTO value + lda #$01 + sta IECPROTO + + // Re-enable sprites + pla + sta VIC_SPENA + + // End byte reception + jmp iec_rx_end + + +#endif // CONFIG_IEC_JIFFYDOS diff --git a/c64/kernal/iec/iec_rx_dispatch.s b/c64/kernal/iec_fast/iec_rx_dispatch.s similarity index 100% rename from c64/kernal/iec/iec_rx_dispatch.s rename to c64/kernal/iec_fast/iec_rx_dispatch.s diff --git a/c64/kernal/iec_fast/iec_tx_byte_jiffydos.s b/c64/kernal/iec_fast/iec_tx_byte_jiffydos.s new file mode 100644 index 00000000..c50adb5d --- /dev/null +++ b/c64/kernal/iec_fast/iec_tx_byte_jiffydos.s @@ -0,0 +1,102 @@ + +// +// JiffyDOS protocol support for IEC - byte transfer +// + +// XXX make it work + + +#if CONFIG_IEC_JIFFYDOS + + +iec_tx_byte_jiffydos: + + // Timing is critical, do not allow interrupts + sei + + // If EOI requested (carry flag set), mark this in IECPROTO as 0 + bcc !+ + dec IECPROTO // turns 1 into 0 +!: + // Store .X and .Y on the stack - preserve them + phx_trash_a + phy_trash_a + + // Store previous sprite status on stack + jsr jiffydos_prepare + pha + + // Prepare nibbles to send + lda TBTCNT + and #$0F + tax + lda jiffydos_bittable, X // low nibble has to be encoded + pha + lda TBTCNT + and #$F0 + pha + + // Prepare value for device notification + ldx C3PO + + // Wait till receiver is ready + jsr iec_wait_for_data_release + + // Wait till it is safe to send data + jsr jiffydos_wait_line + + // Notify device that we are going to send byte by releasing everything + stx CIA2_PRA // cycles: 4 + + // Send high nibble; cycles: 4 + 3 + 4 + 2 + 2 + 2 + 3 + 4 = 24 + pla // retrieve high nibble from stack + ora C3PO // restore VIC-II and RS-232 bits + sta CIA2_PRA // bits 4 and 5 on CLK/DATA + lsr // move bits 6 and 7 to positions 4 and 5 + lsr + and #%00110000 // clear everything but CLK/DATA + ora C3PO + sta CIA2_PRA // bits 6 and 7 on CLK/DATA + + // Send low nibble; cycles: 4 + 3 + 4 + 2 + 2 + 2 + 4 = 21 + pla // retrieve low nibble from stack + ora C3PO // restore VIC-II and RS-232 bits + sta CIA2_PRA + lsr + lsr + and #%00110000 // clear everything but CLK/DATA + sta CIA2_PRA + + // Signal EOI if needed; cycles till no EOI: 3 + 3 + 2 + 2 + 4 = 14 + lda C3PO + ldx IECPROTO + beq iec_tx_byte_jiffydos_wait_eoi + + // FALLTROUGH + +iec_tx_byte_jiffydos_finalize: + + ora #BIT_CIA2_PRA_CLK_OUT // pull CLK + sta CIA2_PRA + + // Restore proper IECPROTO value + lda #$01 + sta IECPROTO + + // Re-enable sprites and interrupts + pla + sta VIC_SPENA + cli + + // Return success + jmp iec_return_success + + +iec_tx_byte_jiffydos_wait_eoi: + + jsr iec_wait20us // XXX is it enough? + lda C3PO + jmp iec_tx_byte_jiffydos_finalize + + +#endif // CONFIG_IEC_JIFFYDOS diff --git a/c64/kernal/iec/iec_tx_dispatch.s b/c64/kernal/iec_fast/iec_tx_dispatch.s similarity index 100% rename from c64/kernal/iec/iec_tx_dispatch.s rename to c64/kernal/iec_fast/iec_tx_dispatch.s diff --git a/c64/kernal/iec/iec_jiffydos_bittable.s b/c64/kernal/iec_fast/jiffydos_bittable.s similarity index 97% rename from c64/kernal/iec/iec_jiffydos_bittable.s rename to c64/kernal/iec_fast/jiffydos_bittable.s index 80376c25..b8c6220b 100644 --- a/c64/kernal/iec/iec_jiffydos_bittable.s +++ b/c64/kernal/iec_fast/jiffydos_bittable.s @@ -15,7 +15,7 @@ #if CONFIG_IEC_JIFFYDOS -iec_jiffydos_bittable: +jiffydos_bittable: .byte $00 .byte $80 // $10 + $70 diff --git a/c64/kernal/iec_fast/jiffydos_prepare.s b/c64/kernal/iec_fast/jiffydos_prepare.s new file mode 100644 index 00000000..1dc8f29b --- /dev/null +++ b/c64/kernal/iec_fast/jiffydos_prepare.s @@ -0,0 +1,29 @@ + +// +// JiffyDOS transfer preparation routine +// + + +#if CONFIG_IEC_JIFFYDOS + + +jiffydos_prepare: + + // We need to preserve 3 lowest bits of CIA2_PRA, they contain important + // data - fortunately, the bits are never changed by external devices + // Use C3PO for this, as afterwards we have to set there 0 nevertheless + lda CIA2_PRA + and #%00000111 + sta C3PO + + // Hide sprites; JiffyDOS timing regime is very strict, before transmitting + // anything we need to make sure nothing will steal the cycles + + lda VIC_SPENA + ldx #$00 + stx VIC_SPENA + + rts + + +#endif // CONFIG_IEC_JIFFYDOS diff --git a/c64/kernal/iec_fast/jiffydos_wait_line.s b/c64/kernal/iec_fast/jiffydos_wait_line.s new file mode 100644 index 00000000..7bb85d1b --- /dev/null +++ b/c64/kernal/iec_fast/jiffydos_wait_line.s @@ -0,0 +1,33 @@ + +// +// JiffyDOS helper routine to wait for appropriate moment, +// where no badline will interrupt the transmission +// + + +#if CONFIG_IEC_JIFFYDOS + + +jiffydos_wait_line: + + lda VIC_SCROLY + and #$10 + beq jiffydos_wait_line_done // screen is disabled, no need to watch for badlines + + // Avoid 2 lines before the badline, otherwise VIC will ruin the synchronization + lda VIC_RASTER + cmp #$2E + bcc jiffydos_wait_line_done // we are safe, border - lot of time till badline +!: + lda VIC_RASTER // carry+ is definitely set here! + sbc VIC_SCROLY + and #$07 // we want 8 lowest bits + cmp #$06 + bcs !- + +jiffydos_wait_line_done: + + rts + + +#endif // CONFIG_IEC_JIFFYDOS