fixes for IEC
This commit is contained in:
1 parent
28ce7e69bf
commit
5f57f58163
13 files changed
+167
-151
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
@@ -1,118 +1,103 @@
|
||||
;; Receive a byte from the IEC bus.
|
||||
;; reference http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
;; page 11.
|
||||
|
||||
|
||||
;; XXX rework this, according to pagetable.com
|
||||
;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc,
|
||||
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf (page 11)
|
||||
|
||||
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
|
||||
|
||||
; ;; First, we wait for the talker to release the CLK line.
|
||||
; ;; XXX jsr iec_wait_for_clock_release
|
||||
iec_rx_not_eoi:
|
||||
|
||||
; ;; We then release the data line
|
||||
; ;; (We can use this routine, since we weren't holding CLK, anyway)
|
||||
; jsr iec_release_clk_and_data
|
||||
;; Latch input bits in on rising edge of CLK, eight times for eight bits.
|
||||
ldx #7
|
||||
|
||||
; ;; Wait for talker to assert CLK.
|
||||
; ;; If >200usec, then it is EOI and we have to assert the
|
||||
; ;; DATA line for 60 usec to tell the TALKER that we have
|
||||
; ;; 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
|
||||
;; Get empty byte to load into.
|
||||
lda #$00
|
||||
pha
|
||||
|
||||
iec_rx_bit_loop:
|
||||
|
||||
; ;; Wait for CLK to release
|
||||
; ;; jsr iec_wait_for_clock_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.
|
||||
;; Wait for CLK to release
|
||||
jsr iec_wait_for_clk_release
|
||||
|
||||
; ;; DATA now has the next bit, but inverted (well, except that it turns out not to be).
|
||||
; ;; DATA is in bit7, which is a bit annoying.
|
||||
; ;; But we can clock it out with a ROL instruction
|
||||
; ;; so that it is in C. We can then ROR it into the
|
||||
; ;; 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.
|
||||
;; (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.
|
||||
|
||||
; ;; Move data bit into C flag, and loop until bit 6 clears
|
||||
; ;; i.e., the clock has been released.
|
||||
;* LDA $DD00
|
||||
; ROL
|
||||
; bpl -
|
||||
;; DATA now has the next bit, but inverted (well, except that it turns out not to be).
|
||||
;; DATA is in bit 7, which is a bit annoying.
|
||||
;; But we can clock it out with a ROL instruction
|
||||
;; so that it is in C. We can then ROR it into the
|
||||
;; 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
|
||||
;; pla
|
||||
; ROR
|
||||
; pha
|
||||
;; Move data bit into C flag, and loop until bit 6 clears
|
||||
;; i.e., the clock has been released.
|
||||
* lda CI2PRA
|
||||
rol
|
||||
bpl -
|
||||
|
||||
; ;; Wait for CLK to re-assert
|
||||
; jsr iec_wait_for_clock_assert
|
||||
;; Pull it into the data byte
|
||||
pla
|
||||
ror
|
||||
pha
|
||||
|
||||
; ;; More bits?
|
||||
; dex
|
||||
; bpl iec_rx_bit_loop
|
||||
;; Wait for CLK to be pulled again
|
||||
jsr iec_wait_for_clk_pull
|
||||
|
||||
; ;; Then we must within 1000usec acknowledge the frame by
|
||||
; ;; asserting DATA. At this point, CLK is asserted by the
|
||||
; ;; talker and DATA by us, i.e., we are ready to receive
|
||||
; ;; the next byte. (p11).
|
||||
; jsr iec_assert_data
|
||||
;; More bits?
|
||||
dex
|
||||
bpl iec_rx_bit_loop
|
||||
|
||||
; ;; Retreive the received byte
|
||||
; PLA
|
||||
;; Then we must within 1000 usec acknowledge the frame by
|
||||
;; 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
|
||||
; CLC
|
||||
; RTS
|
||||
;; Retreive the received byte
|
||||
pla
|
||||
|
||||
;; Return no-error
|
||||
clc
|
||||
rts
|
||||
|
||||
@@ -1,39 +1,29 @@
|
||||
;; According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
;; pages 7--8.
|
||||
|
||||
;; See also https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
|
||||
|
||||
iec_turnaround_to_listen:
|
||||
|
||||
;; Assert data and release clock
|
||||
lda $dd00
|
||||
and #$ef ; release clock (bit 4)
|
||||
ora #$20 ; assert data (bit 5)
|
||||
sta $dd00
|
||||
|
||||
;; Wait for clock line to be asserted by the drive
|
||||
* lda $dd00
|
||||
and #$40
|
||||
;; Pull DATA, release CLK and ATN (we are not sending commands)
|
||||
jsr iec_pull_data_release_atn_clock
|
||||
|
||||
;; Wait for clock line to be pulled by the drive
|
||||
ldx #$FF ; XXX should we really use that high number?
|
||||
*
|
||||
lda CI2PRA
|
||||
rol ; to put BIT_CI2PRA_CLK_IN as the last (sign) bit
|
||||
bpl +
|
||||
dex
|
||||
bne -
|
||||
|
||||
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
;; page 8 tells us we should not do anything here after waiting for
|
||||
;; the clock line to assert.
|
||||
|
||||
ldx #$ff
|
||||
* lda $dd00
|
||||
and #$40
|
||||
bne +
|
||||
dex
|
||||
bne -
|
||||
;; Timeout
|
||||
jsr printf
|
||||
.byte "DBG: TURNAROUND FAILED",$0d,$00
|
||||
sec
|
||||
rts
|
||||
|
||||
;; 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
|
||||
;; CLK is pulled by the device, OK
|
||||
*
|
||||
clc
|
||||
rts
|
||||
|
||||
@@ -35,7 +35,7 @@ iec_tx_command:
|
||||
|
||||
;; Common part of iec_txbyte and iec_tx_common - waits for devices
|
||||
;; and transmits a byte
|
||||
|
||||
|
||||
pla
|
||||
jsr iec_tx_common
|
||||
|
||||
|
||||
@@ -6,11 +6,12 @@ iec_tx_common:
|
||||
|
||||
;; Store the bye to send on a stack
|
||||
pha
|
||||
|
||||
|
||||
;; Wait till all receivers are ready, they should all release DATA
|
||||
jsr iec_wait_for_data_release
|
||||
|
||||
|
||||
;; 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
|
||||
|
||||
jsr iec_pull_clk_release_data
|
||||
@@ -42,11 +43,14 @@ iec_tx_common_bit_is_sent:
|
||||
pla
|
||||
dex
|
||||
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,
|
||||
;; one can signal that it's busy much earlier (more than 100ms) than the other.
|
||||
;; Can we do something about it?
|
||||
|
||||
|
||||
;; All done - give devices time to tell if they are busy by pulling DATA
|
||||
;; They should do it within 1ms
|
||||
ldx #$FF
|
||||
@@ -62,7 +66,9 @@ iec_tx_common_bit_is_sent:
|
||||
jsr iec_wait100us
|
||||
|
||||
iec_tx_common_done:
|
||||
|
||||
;; Byte sent, return
|
||||
clc
|
||||
rts
|
||||
|
||||
iec_tx_common_nextbit:
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
|
||||
iec_tx_eoi:
|
||||
|
||||
;; Wait at least 200us
|
||||
;; Wait at least 256 usec
|
||||
jsr iec_wait100us
|
||||
jsr iec_wait100us
|
||||
jsr iec_wait60us
|
||||
|
||||
;; Restore the bus to idle state
|
||||
jsr iec_set_idle
|
||||
|
||||
@@ -4,9 +4,9 @@ iec_wait100us:
|
||||
;; Wait 100usec
|
||||
|
||||
;; 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:
|
||||
;; - 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
|
||||
;; (in a loop) in order not to clutter VICE debug logs
|
||||
|
||||
@@ -4,9 +4,9 @@ iec_wait20us:
|
||||
;; Wait 20usec
|
||||
|
||||
;; 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:
|
||||
;; - 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
|
||||
;; in order not to clutter VICE debug logs
|
||||
|
||||
@@ -4,9 +4,9 @@ iec_wait60us:
|
||||
;; Wait 60usec
|
||||
|
||||
;; 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:
|
||||
;; - 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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
iec_wait_for_clk_release:
|
||||
lda CI2PRA
|
||||
and #BIT_CI2PRA_CLK_IN
|
||||
beq iec_wait_for_clk_release
|
||||
rts
|
||||
+17
-11
@@ -15,9 +15,6 @@ open:
|
||||
bcs +
|
||||
bmi open_has_space
|
||||
*
|
||||
jsr printf
|
||||
.byte "FULL", $0D, 0
|
||||
|
||||
;; Table is full - according to https://codebase64.org/doku.php?id=base:kernalreference
|
||||
;; C flag set means error occured
|
||||
sec
|
||||
@@ -74,11 +71,9 @@ open_rs232:
|
||||
|
||||
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:
|
||||
;; 1. Call current device to attention as LISTENER = $20 + device
|
||||
;; 2.
|
||||
;; XXX for now for channel 15 only!
|
||||
|
||||
;; Disable IRQs, since timing matters!
|
||||
sei
|
||||
@@ -86,14 +81,25 @@ open_iec:
|
||||
;; Begin sending under attention
|
||||
;; 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
|
||||
jsr listen
|
||||
bcs open_iec_error
|
||||
jsr talk
|
||||
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
|
||||
lda #$00
|
||||
clc
|
||||
clc
|
||||
|
||||
open_iec_error:
|
||||
;; Re-enable interrupts and return
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
; Function defined on pp272-273 of C64 Programmers Reference Guide
|
||||
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
|
||||
Reference in new issue
Block a user