more JiffyDOS code - low nibble TX, general turbo dispatcher

This commit is contained in:
FeralChild64 committed 2019-11-18 19:03:05 +01:00
1 parent 28bc07ea23
commit d0fd34e79f
10 files changed
+422 -293

No files matched your search

+4
View File
@@ -14,7 +14,11 @@ ACPTR:
jsr kernalstatus_reset jsr kernalstatus_reset
#if CONFIG_IEC #if CONFIG_IEC
#if CONFIG_IEC_JIFFYDOS
jmp iec_rx_dispatch
#else // no turbo supported
jmp iec_rx_byte jmp iec_rx_byte
#endif
#else #else
jmp kernalerror_ILLEGAL_DEVICE_NUMBER jmp kernalerror_ILLEGAL_DEVICE_NUMBER
#endif #endif
+4
View File
@@ -33,7 +33,11 @@ ciout_store_in_buffer:
ciout_send_byte: ciout_send_byte:
clc // don't send with EOI clc // don't send with EOI
#if CONFIG_IEC_JIFFYDOS
jsr iec_tx_dispatch
#else // no turbo supported
jsr iec_tx_byte jsr iec_tx_byte
#endif
inc C3PO // iec_tx_byte sets it to 0, but we still have something to send inc C3PO // iec_tx_byte sets it to 0, but we still have something to send
jmp ciout_store_in_buffer jmp ciout_store_in_buffer
+173 -184
View File
@@ -1,184 +1,173 @@
// //
// JiffyDOS protocol support for IEC // JiffyDOS protocol support for IEC
// //
// XXX finish this // XXX finish this
#if CONFIG_IEC_JIFFYDOS #if CONFIG_IEC_JIFFYDOS
// JiffyDOS timing regime is very strict - before transmitting anything // JiffyDOS timing regime is very strict - before transmitting anything
// we need to disable sprites and (if screen is not disabled) wait for // we need to disable sprites and (if screen is not disabled) wait for
// appropriate moment, so that no badline interruption can happen // appropriate moment, so that no badline interruption can happen
iec_tx_byte_jiffydos: iec_tx_byte_jiffydos:
// We need to preserve 3 lowest bits of CIA2_PRA - as they encode // We need to preserve 3 lowest bits of CIA2_PRA - as they encode
// Use C3PO for this, as afterwards we have to set there 0 nevertheless // Use C3PO for this, as afterwards we have to set there 0 nevertheless
lda CIA2_PRA lda CIA2_PRA
and #%00000111 and #%00000111
sta C3PO sta C3PO
// Hide sprites, store their previous status on stack // Hide sprites, store their previous status on stack
jsr jiffydos_hide_sprites jsr jiffydos_hide_sprites
pha pha
// Prepare nibbles to send // Prepare nibbles to send
lda TBTCNT lda TBTCNT
and #$0F and #$0F
pha tax
lda TBTCNT lda iec_jiffydos_bittable, X // low nibble has to be encoded
and #$F0 pha
pha lda TBTCNT
and #$F0
// Wait till receiver is ready pha
jsr iec_wait_for_data_release
// Wait till receiver is ready
__jd_check1: jsr iec_wait_for_data_release
// Wait till it is safe to send data __jd_check1:
jsr jiffydos_wait_line
// Wait till it is safe to send data
// Notify device that we are going to send byte by releasing everything jsr jiffydos_wait_line
// Cycles: 3 + 4 = 7
lda C3PO // Notify device that we are going to send byte by releasing everything
sta CIA2_PRA // Cycles: 3 + 4 = 7
lda C3PO
// Send high nibble; cycles: 4 + 3 + 4 + 2 + 2 + 2 + 4 = 21 sta CIA2_PRA
pla // retrieve high nibble from stack
ora C3PO // restore VIC-II and RS-232 bits // Send high nibble; cycles: 4 + 3 + 4 + 2 + 2 + 2 + 4 = 21
sta CIA2_PRA // bits 4 and 5 on CLK/DATA pla // retrieve high nibble from stack
ror // move bits 6 and 7 to positions 4 and 5 ora C3PO // restore VIC-II and RS-232 bits
ror sta CIA2_PRA // bits 4 and 5 on CLK/DATA
and #%00110000 // clear everything but CLK/DATA ror // move bits 6 and 7 to positions 4 and 5
sta CIA2_PRA // bits 6 and 7 on CLK/DATA ror
and #%00110000 // clear everything but CLK/DATA
// Send low nibble; cycles: XXX sta CIA2_PRA // bits 6 and 7 on CLK/DATA
// XXX something strange seems to happen with low nibble: // Send low nibble; cycles: 4 + 3 + 4 + 2 + 2 + 2 + 4 = 21
pla // retrieve low nibble from stack
// $0 -> $00 ora C3PO // restore VIC-II and RS-232 bits
// $1 -> $80 = $10 + $70 sta CIA2_PRA
// $2 -> $20 ror
// $3 -> $A0 = $30 + $70 ror
// $4 -> $40 and #%00110000 // clear everything but CLK/DATA
// $5 -> $C0 = $50 + $70 sta CIA2_PRA
// $6 -> $60
// $7 -> $E0 = $70 + $70
// $8 -> $10 = $80 - $70 // XXX EOI signalled by early CLK (20us delay for non-CLK?)
// $9 -> $90
// $A -> $30 = $A0 - $70
// $B -> $B0 // Re-enable sprites
// $C -> $50 = $C0 - $70 pla
// $D -> $D0 lda VIC_SPENA
// $E -> $70 = $E0 - $70
// $F -> $F0 // Mark TX buffer as empty
lda #$00
// XXX why??? how this is calculated??? sta C3PO
// XXX EOI signalled by early CLK (20us delay for non-CLK?) rts
// Re-enable sprites iec_rx_byte_jiffydos:
pla
lda VIC_SPENA // Hide sprites, store their previous status on stack
jsr jiffydos_hide_sprites
// Mark TX buffer as empty pha
lda #$00
sta C3PO // Wait until device is ready to send
jsr iec_wait_for_clk_release
rts
// Prepare 'start sending' message
lda CIA2_PRA
iec_rx_byte_jiffydos: and #$FF - BIT_CIA2_PRA_DAT_OUT // release
pha
// Hide sprites, store their previous status on stack
jsr jiffydos_hide_sprites // Wait for appropriate moment
pha jsr jiffydos_wait_line
// Wait until device is ready to send // Ask device to start sending bits
jsr iec_wait_for_clk_release pla
sta CIA2_PRA
// Prepare 'start sending' message
lda CIA2_PRA
and #$FF - BIT_CIA2_PRA_DAT_OUT // release // XXX retrieve byte
pha
// Wait for appropriate moment // Re-enable sprites
jsr jiffydos_wait_line pla
lda VIC_SPENA
// Ask device to start sending bits
pla rts
sta CIA2_PRA
jiffydos_wait_line:
// XXX retrieve byte
lda VIC_SCROLY
and #$10
// Re-enable sprites beq jiffydos_wait_line_done // screen is disabled, no need to watch for badlines
pla
lda VIC_SPENA // To give the transfer routine as much time as possible,
// wait till a badline
rts
// XXX this is probably overkill, most likely it is enough to avoid 2 (3?) lines
// before badline - to be adjusted in the future
jiffydos_wait_line: !:
sec
lda VIC_SCROLY lda VIC_SCROLY
and #$10 sbc VIC_RASTER
beq jiffydos_wait_line_done // screen is disabled, no need to watch for badlines and #$07 // we want 8 lowest bits
bne !-
// To give the transfer routine as much time as possible,
// wait till a badline jiffydos_wait_line_done:
rts
// XXX this is probably overkill, most likely it is enough to avoid 2 (3?) lines
// before badline - to be adjusted in the future
!: __jd_check2:
sec
lda VIC_SCROLY
sbc VIC_RASTER jiffydos_hide_sprites:
and #$07 // we want 8 lowest bits
bne !- lda VIC_SPENA
ldx #$00
jiffydos_wait_line_done: stx VIC_SPENA
rts
rts
__jd_check2:
.function SAME_PAGE_CHECK(label_1, label_2)
{
jiffydos_hide_sprites: #if PASS_SIZETEST
.return (label_1 - label_1 % 256) == (label_2 - label_2 % 256)
lda VIC_SPENA #else
ldx #$00 .return true
stx VIC_SPENA #endif
}
rts
.if (!SAME_PAGE_CHECK(__jd_check1, __jd_check2))
{
.function SAME_PAGE_CHECK(label_1, label_2) // To meet the strict JiffyDOS timing, we need to make sure
{ // it does not span across multiple pages, as this would add
#if PASS_SIZETEST // 1 cycle to some jump instructions - maybe this wont cause
.return (label_1 - label_1 % 256) == (label_2 - label_2 % 256) // problems, but better safe than sorry.
#else
.return true .error "JiffyDOS code can't span across multiple pages"
#endif }
}
.if (!SAME_PAGE_CHECK(__jd_check1, __jd_check2)) #endif // CONFIG_IEC_JIFFYDOS
{
// To meet the strict JiffyDOS timing, we need to make sure
// it does not span across multiple pages, as this would add
// 1 cycle to some jump instructions - maybe this wont cause
// problems, but better safe than sorry.
.error "JiffyDOS code can't span across multiple pages"
}
#endif // CONFIG_IEC_JIFFYDOS
+33
View File
@@ -0,0 +1,33 @@
//
// Helper table for encoding lower nibble for JiffyyDOS,
// values found by observing the actual transfer
//
#if CONFIG_IEC_JIFFYDOS
// XXX consider calculating the values on-the-fly
iec_jiffydos_bittable:
.byte $00
.byte $80 // $10 + $70
.byte $20
.byte $A0 // $30 + $70
.byte $40
.byte $C0 // $50 + $70
.byte $60
.byte $E0 // $70 + $70
.byte $10 // $80 - $70
.byte $90
.byte $30 // $A0 - $70
.byte $B0
.byte $50 // $C0 - $70
.byte $D0
.byte $70 // $E0 - $70
.byte $F0
#endif // CONFIG_IEC_JIFFYDOS
+32
View File
@@ -0,0 +1,32 @@
//
// Arbitration code for normal/turbo transfer
//
#if CONFIG_IEC_JIFFYDOS
iec_rx_dispatch:
lda IECPROTO
#if CONFIG_IEC_JIFFYDOS
cmp #$01
beq iec_rx_dispatch_jiffydos
#endif // CONFIG_IEC_JIFFYDOS
// FALLTROUGH
iec_rx_dispatch_normal:
plp
jmp iec_rx_byte
#if CONFIG_IEC_JIFFYDOS
iec_rx_dispatch_jiffydos:
plp
jmp iec_rx_byte_jiffydos
#endif // CONFIG_IEC_JIFFYDOS
#endif // any turbo supported
+7 -7
View File
@@ -68,21 +68,21 @@ iec_tx_common_sendbit:
cpx #$00 cpx #$00
bne !+ // branch if not sending the last bit bne !+ // branch if not sending the last bit
ldy #$1B // 400us is nearly 410 cycles on NTSC ldy #$25 // 400us is nearly 410 cycles on NTSC
// loop iteration below is 15 cycles, // loop iteration below is 11 cycles,
// and several cycles were already used // and several cycles were already used
iec_jiffydos_detect_loop: iec_jiffydos_detect_loop:
lda CIA2_PRA // 4 cycles lda CIA2_PRA // 4 cycles
bpl iec_jiffydos_detected // 2 cycles bpl iec_jiffydos_detected // 2 cycles
dey // 2 cycles dey // 2 cycles
bne iec_jiffydos_detect_loop // 2 cycles bne iec_jiffydos_detect_loop // 3 cycles if branch
lda #$00 // 2 cycles lda #$00 // normal protocol
beq iec_jiffydos_store_proto // 3 cycles, branch always skip_2_bytes_trash_nvz
iec_jiffydos_detected: iec_jiffydos_detected:
panic #$FF // WHOAAAA! He wants to speak jiffy, but I do not know this language yet! lda #$01 // JiffyDOS protocol
iec_jiffydos_store_proto: iec_jiffydos_store_proto:
sta IECPROTO sta IECPROTO
+33
View File
@@ -0,0 +1,33 @@
//
// Arbitration code for normal/turbo transfer
//
#if CONFIG_IEC_JIFFYDOS
iec_tx_dispatch:
php // preserve C flag for EOI indication
lda IECPROTO
#if CONFIG_IEC_JIFFYDOS
cmp #$01
beq iec_tx_dispatch_jiffydos
#endif // CONFIG_IEC_JIFFYDOS
// FALLTROUGH
iec_tx_dispatch_normal:
plp
jmp iec_tx_byte
#if CONFIG_IEC_JIFFYDOS
iec_tx_dispatch_jiffydos:
plp
jmp iec_tx_byte_jiffydos
#endif // CONFIG_IEC_JIFFYDOS
#endif // any turbo supported
+12
View File
@@ -71,10 +71,18 @@ load_iec:
// Get load address // Get load address
#if CONFIG_IEC_JIFFYDOS
jsr iec_rx_dispatch
#else // no turbo supported
jsr iec_rx_byte jsr iec_rx_byte
#endif
bcs load_iec_file_not_found bcs load_iec_file_not_found
sta EAL+0 sta EAL+0
#if CONFIG_IEC_JIFFYDOS
jsr iec_rx_dispatch
#else // no turbo supported
jsr iec_rx_byte jsr iec_rx_byte
#endif
bcs load_iec_file_not_found bcs load_iec_file_not_found
sta EAL+1 sta EAL+1
@@ -92,7 +100,11 @@ load_iec:
iec_load_loop: iec_load_loop:
// We are now ready to receive bytes // We are now ready to receive bytes
#if CONFIG_IEC_JIFFYDOS
jsr iec_rx_dispatch
#else // no turbo supported
jsr iec_rx_byte jsr iec_rx_byte
#endif
bcs load_iec_error bcs load_iec_error
// Handle the byte (store in memory / verify) // Handle the byte (store in memory / verify)
+114 -102
View File
@@ -1,102 +1,114 @@
// //
// IEC part of the SAVE routine // IEC part of the SAVE routine
// //
#if CONFIG_IEC #if CONFIG_IEC
save_iec_dev_not_found: save_iec_dev_not_found:
jmp lvs_device_not_found_error jmp lvs_device_not_found_error
save_iec: save_iec:
// Check file name // Check file name
lda FNLEN lda FNLEN
beq_far kernalerror_FILE_NAME_MISSING beq_far kernalerror_FILE_NAME_MISSING
// Display SAVING // Display SAVING
jsr lvs_display_saving jsr lvs_display_saving
// Call device to LISTEN // Call device to LISTEN
lda FA lda FA
jsr LISTEN jsr LISTEN
bcs save_iec_dev_not_found bcs save_iec_dev_not_found
// Open channel 1 (reserved for file writing) // Open channel 1 (reserved for file writing)
lda #$01 lda #$01
jsr iec_cmd_open jsr iec_cmd_open
bcs save_iec_dev_not_found bcs save_iec_dev_not_found
// Send file name // Send file name
jsr iec_send_file_name jsr iec_send_file_name
bcs save_iec_dev_not_found bcs save_iec_dev_not_found
// Call device to LISTEN once again // Call device to LISTEN once again
lda FA lda FA
jsr LISTEN jsr LISTEN
bcs save_iec_dev_not_found bcs save_iec_dev_not_found
lda #$61 // open channel / data (p3) , required according to p13 lda #$61 // open channel / data (p3) , required according to p13
sta TBTCNT sta TBTCNT
jsr iec_tx_command jsr iec_tx_command
bcs save_iec_dev_not_found bcs save_iec_dev_not_found
// Save start address // Save start address
lda STAL+0 lda STAL+0
sta TBTCNT sta TBTCNT
clc clc
jsr iec_tx_byte #if CONFIG_IEC_JIFFYDOS
jsr iec_tx_dispatch
lda STAL+1 #else // no turbo supported
sta TBTCNT jsr iec_tx_byte
clc #endif
jsr iec_tx_byte
lda STAL+1
jsr lvs_setup_MEMUSS sta TBTCNT
ldy #$00 clc
iec_save_loop: #if CONFIG_IEC_JIFFYDOS
jsr iec_tx_dispatch
// Retrieve byte to send #else // no turbo supported
#if CONFIG_MEMORY_MODEL_60K jsr iec_tx_byte
ldx #<MEMUSS+0 #endif
jsr peek_under_roms
#else // CONFIG_MEMORY_MODEL_38K jsr lvs_setup_MEMUSS
lda (MEMUSS),y ldy #$00
#endif iec_save_loop:
// Send the byte // Retrieve byte to send
sta TBTCNT #if CONFIG_MEMORY_MODEL_60K
clc ldx #<MEMUSS+0
jsr iec_tx_byte jsr peek_under_roms
#else // CONFIG_MEMORY_MODEL_38K
// Next iteration lda (MEMUSS),y
jsr lvs_advance_MEMUSS_check_EAL #endif
bne iec_save_loop
// Send the byte
iec_save_loop_end: sta TBTCNT
clc
// Close file on drive #if CONFIG_IEC_JIFFYDOS
lda FA jsr iec_tx_dispatch
jsr UNLSN #else // no turbo supported
jsr iec_tx_byte
lda FA #endif
jsr LISTEN
// Next iteration
lda #$E1 // CLOSE command jsr lvs_advance_MEMUSS_check_EAL
sta TBTCNT bne iec_save_loop
jsr iec_tx_command
jsr iec_tx_command_finalize iec_save_loop_end:
// Tell drive to unlisten // Close file on drive
lda FA lda FA
jsr UNLSN jsr UNLSN
// Return success lda FA
clc jsr LISTEN
rts
lda #$E1 // CLOSE command
sta TBTCNT
#endif // CONFIG_IEC jsr iec_tx_command
jsr iec_tx_command_finalize
// Tell drive to unlisten
lda FA
jsr UNLSN
// Return success
clc
rts
#endif // CONFIG_IEC
+10
View File
@@ -26,6 +26,16 @@ TALK:
// Encode and execute the command // Encode and execute the command
ora #$40 ora #$40
#if CONFIG_IEC_JIFFYDOS
// XXX temporary, until receiving is implemented too
sta TBTCNT
lda #$00 // standard protocol
sta IECPROTO
jmp iec_tx_command
#endif // CONFIG_IEC_JIFFYDOS
common_talk_listen: // common part of TALK and LISTEN common_talk_listen: // common part of TALK and LISTEN
sta TBTCNT sta TBTCNT