fixes for IEC

This commit is contained in:
FeralChild64 committed 2019-06-20 16:49:35 +02:00
1 parent 28ce7e69bf
commit 5f57f58163
12 files changed
+158 -142

No files matched your search

@@ -0,0 +1,7 @@
iec_pull_data_release_atn_clock:
lda CI2PRA
ora #BIT_CI2PRA_DAT_OUT ; pull
and #$FF - BIT_CI2PRA_ATN_OUT - BIT_CI2PRA_CLK_OUT ; release
sta CI2PRA
rts
+83 -98
View File
@@ -1,118 +1,103 @@
;; Receive a byte from the IEC bus. ;; Receive a byte from the IEC bus.
;; reference http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf ;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc,
;; page 11. ;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf (page 11)
;; XXX rework this, according to pagetable.com
iec_rx_byte: iec_rx_byte:
;; First, we wait for the talker to release the CLK line
jsr iec_wait_for_clk_release
;; We then release the DATA to signal we are ready
;; We can use this routine, since we weren't pulling CLK anyway
jsr iec_release_clk_data
;; Wait for talker to pull CLK.
;; If over 200 usec (205 cycles on NTSC machine) , then it is EOI.
;; Loop iteraction takes 13 cycles, 17 full iterations are enough
ldx #$11 ; 2 cycles
iec_rx_clk_wait:
lda CI2PRA ; 4 cycles
rol ; 2 cycles, to put BIT_CI2PRA_CLK_IN as the last bit
bpl iec_rx_not_eoi ; 2 cycles if not jumped
dex ; 2 cycles
bne iec_rx_clk_wait ; 3 cycles if jumped
;; Timeout - wait for pulled CLK and pull data for 60 usec to confirm
jsr iec_wait_for_clk_pull
jsr iec_release_clk_pull_data
jsr iec_wait60us
jsr iec_release_clk_data
;; Store EOI information in IOSTATUS - XXX this should be done by the caller!
lda IOSTATUS
ora #$40
sta IOSTATUS
sec
rts rts
; ;; First, we wait for the talker to release the CLK line. iec_rx_not_eoi:
; ;; XXX jsr iec_wait_for_clock_release
; ;; We then release the data line ;; Latch input bits in on rising edge of CLK, eight times for eight bits.
; ;; (We can use this routine, since we weren't holding CLK, anyway) ldx #7
; jsr iec_release_clk_and_data
; ;; Wait for talker to assert CLK. ;; Get empty byte to load into.
; ;; If >200usec, then it is EOI and we have to assert the lda #$00
; ;; DATA line for 60 usec to tell the TALKER that we have pha
; ;; acknowledged the EOI.
; ldx #20
iec_rx_clk_wait:
; ;; Loop takes 11 usec, so ~20 iterations for 200usec timeout
; lda $dd00
; rol
; bpl not_eoi
; dex
; cpx #$21
; bne not_rx_timeout
; ;; Time out waiting for CLK to assert again.
; ;; = error
; sec
; rts
not_rx_timeout:
; cpx #$00
; bpl iec_rx_clk_wait
; ;; Remember EOI condition
; lda IOSTATUS
; ora #$40
; sta IOSTATUS
; ;; EOI timeout: So pulse DATA line for 60 usec
; jsr iec_assert_data
; jsr iec_wait60us
; jsr iec_release_clk_and_data
; ;; And still wait for CLK to be asserted
; ;; XXX - This will cause periodic EOI pulses if the sender takes too long.
; ;; That is probably ok.
; ldx #$7f
; jmp iec_rx_clk_wait
not_eoi:
; ;; CLK is now low. Latch input bits in on rising edge
; ;; of CLK, eight times for eight bits.
; ldx #7
; ;; Get empty byte to load into.
; lda #$00
; pha
iec_rx_bit_loop: iec_rx_bit_loop:
; ;; Wait for CLK to release ;; Wait for CLK to release
; ;; jsr iec_wait_for_clock_release jsr iec_wait_for_clk_release
; ;; (we do this implicitly below, with a tighter routine,
; ;; so that we don't have timing problems, as the requirements
; ;; are quite tight. Basically we need to read the clock and data
; ;; bit from the same byte read.
; ;; DATA now has the next bit, but inverted (well, except that it turns out not to be). ;; (we do this implicitly below, with a tighter routine,
; ;; DATA is in bit7, which is a bit annoying. ;; so that we don't have timing problems, as the requirements
; ;; But we can clock it out with a ROL instruction ;; are quite tight. Basically we need to read the clock and data
; ;; so that it is in C. We can then ROR it into the ;; bit from the same byte read.
; ;; partial data byte.
; ;; We use ROR so that we shift in from the top, so that
; ;; the first bit we shift in ends up in bit 0 after all
; ;; 8 bits have been read.
; ;; ODD: For some reason we don't need to invert the
; ;; received bits. This is weird, because we invert them
; ;; on the way out, and everything in the protocol seems
; ;; to indicate that we sould do so. But experimentation
; ;; has confirmed the bits don't need inversion on reception.
; ;; Move data bit into C flag, and loop until bit 6 clears ;; DATA now has the next bit, but inverted (well, except that it turns out not to be).
; ;; i.e., the clock has been released. ;; DATA is in bit 7, which is a bit annoying.
;* LDA $DD00 ;; But we can clock it out with a ROL instruction
; ROL ;; so that it is in C. We can then ROR it into the
; bpl - ;; partial data byte.
;; We use ROR so that we shift in from the top, so that
;; the first bit we shift in ends up in bit 0 after all
;; 8 bits have been read.
;; ODD: For some reason we don't need to invert the
;; received bits. This is weird, because we invert them
;; on the way out, and everything in the protocol seems
;; to indicate that we sould do so. But experimentation
;; has confirmed the bits don't need inversion on reception.
; ;; Pull it into the data byte ;; Move data bit into C flag, and loop until bit 6 clears
;; pla ;; i.e., the clock has been released.
; ROR * lda CI2PRA
; pha rol
bpl -
; ;; Wait for CLK to re-assert ;; Pull it into the data byte
; jsr iec_wait_for_clock_assert pla
ror
pha
; ;; More bits? ;; Wait for CLK to be pulled again
; dex jsr iec_wait_for_clk_pull
; bpl iec_rx_bit_loop
; ;; Then we must within 1000usec acknowledge the frame by ;; More bits?
; ;; asserting DATA. At this point, CLK is asserted by the dex
; ;; talker and DATA by us, i.e., we are ready to receive bpl iec_rx_bit_loop
; ;; the next byte. (p11).
; jsr iec_assert_data
; ;; Retreive the received byte ;; Then we must within 1000 usec acknowledge the frame by
; PLA ;; pulling DATA. At this point, CLK is pulled by the
;; talker and DATA by us, i.e., we are ready to receive
;; the next byte. (p11).
jsr iec_release_clk_pull_data
; ;; Return no-error ;; Retreive the received byte
; CLC pla
; RTS
;; Return no-error
clc
rts
+17 -27
View File
@@ -1,39 +1,29 @@
;; According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf ;; According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
;; pages 7--8. ;; pages 7--8.
;; See also https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
iec_turnaround_to_listen: iec_turnaround_to_listen:
;; Assert data and release clock ;; Pull DATA, release CLK and ATN (we are not sending commands)
lda $dd00 jsr iec_pull_data_release_atn_clock
and #$ef ; release clock (bit 4)
ora #$20 ; assert data (bit 5)
sta $dd00
;; Wait for clock line to be asserted by the drive ;; Wait for clock line to be pulled by the drive
* lda $dd00 ldx #$FF ; XXX should we really use that high number?
and #$40 *
lda CI2PRA
rol ; to put BIT_CI2PRA_CLK_IN as the last (sign) bit
bpl +
dex
bne - bne -
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf ;; Timeout
;; page 8 tells us we should not do anything here after waiting for jsr printf
;; the clock line to assert. .byte "DBG: TURNAROUND FAILED",$0d,$00
sec
rts
ldx #$ff ;; CLK is pulled by the device, OK
* lda $dd00
and #$40
bne +
dex
bne -
;; jsr printf
;; .byte "TURNAROUND FAILED - FILE NOT FOUND?",$0d,$00
;; ;; Timeout = file not found error
;; ;; (https://www.pagetable.com/?p=1023)
lda #4
sec
rts
* *
;; ATN turn around successful
clc clc
rts rts
+6
View File
@@ -11,6 +11,7 @@ iec_tx_common:
jsr iec_wait_for_data_release jsr iec_wait_for_data_release
;; Pull CLK back to indicate that DATA is not valid, keep it for 60us ;; Pull CLK back to indicate that DATA is not valid, keep it for 60us
;; We can use this routine as we don't hold DATA anyway (and its state doesn't even matter)
;; Don't wait too long, as 200us or more is considered EOI ;; Don't wait too long, as 200us or more is considered EOI
jsr iec_pull_clk_release_data jsr iec_pull_clk_release_data
@@ -43,6 +44,9 @@ iec_tx_common_bit_is_sent:
dex dex
bpl iec_tx_common_nextbit bpl iec_tx_common_nextbit
;; Whole byte send, make sure ATN is released
jsr iec_release_atn_clk_data
;; XXX the flow below is REALLY dangerous, as if there are multiple devices, ;; XXX the flow below is REALLY dangerous, as if there are multiple devices,
;; one can signal that it's busy much earlier (more than 100ms) than the other. ;; one can signal that it's busy much earlier (more than 100ms) than the other.
;; Can we do something about it? ;; Can we do something about it?
@@ -62,7 +66,9 @@ iec_tx_common_bit_is_sent:
jsr iec_wait100us jsr iec_wait100us
iec_tx_common_done: iec_tx_common_done:
;; Byte sent, return ;; Byte sent, return
clc
rts rts
iec_tx_common_nextbit: iec_tx_common_nextbit:
+2 -1
View File
@@ -1,9 +1,10 @@
iec_tx_eoi: iec_tx_eoi:
;; Wait at least 200us ;; Wait at least 256 usec
jsr iec_wait100us jsr iec_wait100us
jsr iec_wait100us jsr iec_wait100us
jsr iec_wait60us
;; Restore the bus to idle state ;; Restore the bus to idle state
jsr iec_set_idle jsr iec_set_idle
+2 -2
View File
@@ -4,9 +4,9 @@ iec_wait100us:
;; Wait 100usec ;; Wait 100usec
;; PAL: ;; PAL:
;; - CPU frequency 0.985248 MHz, we need to waste at least 102 cycles ;; - CPU frequency 0.985248 MHz, we need to waste at least 99 cycles
;; NTSC: ;; NTSC:
;; - CPU frequency 1.022727 MHZ, we need to waste at least 98 cycles ;; - CPU frequency 1.022727 MHZ, we need to waste at least 103 cycles
;; Waste cycles by reading some unimportant memory location ;; Waste cycles by reading some unimportant memory location
;; (in a loop) in order not to clutter VICE debug logs ;; (in a loop) in order not to clutter VICE debug logs
+2 -2
View File
@@ -4,9 +4,9 @@ iec_wait20us:
;; Wait 20usec ;; Wait 20usec
;; PAL: ;; PAL:
;; - CPU frequency 0.985248 MHz, we need to waste at least 21 cycles ;; - CPU frequency 0.985248 MHz, we need to waste at least 20 cycles
;; NTSC: ;; NTSC:
;; - CPU frequency 1.022727 MHZ, we need to waste at least 20 cycles ;; - CPU frequency 1.022727 MHZ, we need to waste at least 21 cycles
;; Waste cycles by reading some unimportant memory location ;; Waste cycles by reading some unimportant memory location
;; in order not to clutter VICE debug logs ;; in order not to clutter VICE debug logs
+2 -2
View File
@@ -4,9 +4,9 @@ iec_wait60us:
;; Wait 60usec ;; Wait 60usec
;; PAL: ;; PAL:
;; - CPU frequency 0.985248 MHz, we need to waste at least 61 cycles ;; - CPU frequency 0.985248 MHz, we need to waste at least 60 cycles
;; NTSC: ;; NTSC:
;; - CPU frequency 1.022727 MHZ, we need to waste at least 59 cycles ;; - CPU frequency 1.022727 MHZ, we need to waste at least 62 cycles
;; Waste cycles in a loop ;; Waste cycles in a loop
+6
View File
@@ -0,0 +1,6 @@
iec_wait_for_clk_pull:
lda CI2PRA
rol ; to put BIT_CI2PRA_CLK_IN as the last (sign) bit
bmi iec_wait_for_clk_pull
rts
+6
View File
@@ -0,0 +1,6 @@
iec_wait_for_clk_release:
lda CI2PRA
and #BIT_CI2PRA_CLK_IN
beq iec_wait_for_clk_release
rts
+16 -10
View File
@@ -15,9 +15,6 @@ open:
bcs + bcs +
bmi open_has_space bmi open_has_space
* *
jsr printf
.byte "FULL", $0D, 0
;; Table is full - according to https://codebase64.org/doku.php?id=base:kernalreference ;; Table is full - according to https://codebase64.org/doku.php?id=base:kernalreference
;; C flag set means error occured ;; C flag set means error occured
sec sec
@@ -74,11 +71,9 @@ open_rs232:
open_iec: open_iec:
;; XXX add FILENAM support, test it ;; Part implemented according to https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
;; Sequence is: ;; XXX for now for channel 15 only!
;; 1. Call current device to attention as LISTENER = $20 + device
;; 2.
;; Disable IRQs, since timing matters! ;; Disable IRQs, since timing matters!
sei sei
@@ -86,10 +81,21 @@ open_iec:
;; Begin sending under attention ;; Begin sending under attention
;; XXX jsr iec_assert_atn ;; XXX jsr iec_assert_atn
;; CLK is now asserted, and we are ready to transmit a byte ;; Request device to talk
lda current_device_number lda current_device_number
jsr listen jsr talk
bcs open_iec_error bcs open_iec_error ; XXX what about the accumulator?
jsr printf
.byte "DBG: OPEN 1", $0D, 0
;; Send secondary address
lda current_secondary_address
jsr tksa
bcs open_iec_error ; XXX what about the accumulator?
jsr printf
.byte "DBG: OPEN 2", $0D, 0
;; Indicate success ;; Indicate success
lda #$00 lda #$00
+9
View File
@@ -1,3 +1,12 @@
; Function defined on pp272-273 of C64 Programmers Reference Guide ; Function defined on pp272-273 of C64 Programmers Reference Guide
tksa: tksa:
;; This routine is documented in 'C64 Programmer's Reference Guide', page 302 and
;; https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc
ora #$F0
jsr iec_tx_command
bcs tksa_error
jmp iec_turnaround_to_listen
tksa_error:
rts rts