CIOUT kept the byte to send next in BSOUR ($95), but iec_tx_byte, which CIOUT and iec_tx_flush (called by UNLSN, UNTLK, LISTEN, TALK) use to send it, transmits TBTCNT ($A4). So every byte CHROUT sent to a serial device was whatever TBTCNT held, and a file written with CHKOUT and CHROUT held the wrong bytes. The contract (C64 Programmer's Reference Guide, CIOUT): CIOUT sends a byte to the listening device, always holding one back so that the last byte goes with EOI when UNLSN ends the transfer. CIOUT now buffers the byte in TBTCNT, the one-line fix of upstream PR #113; changing the send path to read BSOUR would also move LOAD's and SAVE's bytes. Upstream: https://github.com/MEGA65/open-roms/pull/113
58 lines
1.1 KiB
ArmAsm
58 lines
1.1 KiB
ArmAsm
;; #LAYOUT# STD * #TAKE
|
|
;; #LAYOUT# * KERNAL_0 #TAKE
|
|
;; #LAYOUT# * * #IGNORE
|
|
|
|
;
|
|
; Official Kernal routine, described in:
|
|
;
|
|
; - [RG64] C64 Programmers Reference Guide - page 279/280
|
|
; - [CM64] Computes Mapping the Commodore 64 - page 224
|
|
;
|
|
; CPU registers that has to be preserved (see [RG64]): .X, .Y
|
|
;
|
|
|
|
|
|
CIOUT:
|
|
|
|
!ifdef CONFIG_IEC {
|
|
|
|
pha
|
|
lda C3PO
|
|
bne ciout_send_byte
|
|
|
|
; Nothing to send - set buffer as valid, store byte there
|
|
inc C3PO
|
|
|
|
; Clear carry flag to indicate success
|
|
clc
|
|
|
|
ciout_store_in_buffer:
|
|
|
|
; Store in the buffer data to be sent next, return; iec_tx_byte
|
|
; sends the byte from TBTCNT, so that is our buffer, not BSOUR
|
|
pla
|
|
sta TBTCNT
|
|
rts
|
|
|
|
ciout_send_byte:
|
|
|
|
!ifdef CONFIG_MB_M65 {
|
|
jsr m65dos_check
|
|
+bcc m65dos_ciout ; branch if device is handeld by internal DOS
|
|
}
|
|
|
|
clc ; send without EOI
|
|
!ifdef CONFIG_IEC_JIFFYDOS {
|
|
jsr iec_tx_dispatch
|
|
} else {
|
|
jsr iec_tx_byte
|
|
}
|
|
inc C3PO ; tx byte routine sets to 0, but we still have something to send
|
|
jmp ciout_store_in_buffer
|
|
|
|
} else {
|
|
|
|
sec ; indicate failure
|
|
rts
|
|
}
|