Files
open-roms/src/kernal/iec/ciout.s
T
chris 264e9792a5 CIOUT: buffer the byte where iec_tx_byte sends it from
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
2026-10-15 02:15:38 +02:00

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
}