;; 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 iec_rx_byte: rts ; ;; First, we wait for the talker to release the CLK line. ; ;; XXX 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