115 lines
2.8 KiB
ArmAsm
115 lines
2.8 KiB
ArmAsm
;; Receive a byte from the IEC bus.
|
|
;; reference 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_clock_release
|
|
|
|
;; We then release the data line
|
|
;; (We can use this routine, since we weren't holding CLK, anyway)
|
|
jsr iec_release_clk_and_data
|
|
|
|
;; 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
|
|
|
|
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.
|
|
|
|
;; 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.
|
|
|
|
;; Move data bit into C flag, and loop until bit 6 clears
|
|
;; i.e., the clock has been released.
|
|
* LDA $DD00
|
|
ROL
|
|
bpl -
|
|
|
|
;; Pull it into the data byte
|
|
pla
|
|
ROR
|
|
pha
|
|
|
|
;; Wait for CLK to re-assert
|
|
jsr iec_wait_for_clock_assert
|
|
|
|
;; More bits?
|
|
dex
|
|
bpl iec_rx_bit_loop
|
|
|
|
;; 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
|
|
|
|
;; Retreive the received byte
|
|
PLA
|
|
|
|
;; Return no-error
|
|
CLC
|
|
RTS
|
|
|