diff --git a/STATUS.md b/STATUS.md index 56f5f4e9..ab419717 100644 --- a/STATUS.md +++ b/STATUS.md @@ -73,18 +73,18 @@ NOTE: Even the 'DONE' routines won't support features described as missing in on | $FF8A | RESTOR | PARTIAL | CBINV, NMINV, and USRCMD missing | | $FF8D | VECTOR | DONE | | | $FF90 | SETMSG | DONE | | -| $FF93 | SECOND | PARTIAL | * work in progress | -| $FF96 | TKSA | PARTIAL | should probably also do a turnaround | +| $FF93 | SECOND | DONE | | +| $FF96 | TKSA | PARTIAL | should it do a turnaround? | | $FF99 | MEMTOP | DONE | | | $FF9C | MEMBOT | DONE | | | $FF9F | SCNKEY | DONE | could be better integrated with ROM | | $FFA2 | SETTMO | NOT DONE | | | $FFA5 | ACPTR | NOT DONE | * work in progress | -| $FFA8 | CIOUT | PARITAL | * work in progress | +| $FFA8 | CIOUT | DONE | | | $FFAB | UNTLK | PARITAL | * work in progress | -| $FFAE | UNLSN | PARITAL | * work in progress | -| $FFB1 | LISTEN | PARTIAL | * work in progress | -| $FFB4 | TALK | PARTIAL | * work in progress | +| $FFAE | UNLSN | DONE | | +| $FFB1 | LISTEN | DONE | | +| $FFB4 | TALK | PARTIAL | should it do a turnaround? | | $FFB7 | READST | DONE | | | $FFBA | SETFLS | DONE | | | $FFBD | SETNAM | DONE | | diff --git a/c64/kernal/ciout.s b/c64/kernal/ciout.s index a1cf61f6..26095a85 100644 --- a/c64/kernal/ciout.s +++ b/c64/kernal/ciout.s @@ -8,7 +8,6 @@ ;; CPU registers that has to be preserved (see [RG64]): .X, .Y ;; -;; XXX currently does not preserve registers, to be fixed! ciout: @@ -31,9 +30,8 @@ ciout_store_in_buffer: ciout_send_byte: - ;; Send previous data - lda BSOUR clc ; don't send with EOI jsr iec_tx_byte + inc C3PO ; iec_tx_byte sets it to 0, but we still have something to send jmp ciout_store_in_buffer diff --git a/c64/kernal/iec_return.s b/c64/kernal/iec_return.s new file mode 100644 index 00000000..a89a1336 --- /dev/null +++ b/c64/kernal/iec_return.s @@ -0,0 +1,38 @@ + +;; +;; Helper routines to return with error/success +;; +;; All of them restore X/Y registers from stack, +;; they take care about Carry flag, +;; error return reeset IEC line to default state, +;; take care about .A and IOSTATUS +;; + +iec_return_success: + + ;; BSOUR is certainly not valid anymore + lda #$00 + sta C3PO + ;; Restore registers + pla + tay + pla + tax + ;; Report success + clc + rts + +iec_return_DEVICE_NOT_FOUND: + + ;; Set IEC line to normal idle state + jsr iec_set_idle + ;; BSOUR is certainly not valid anymore + lda #$00 + sta C3PO + ;; Restore registers + pla + tay + pla + tax + ;; Report error + jmp kernalerror_DEVICE_NOT_FOUND diff --git a/c64/kernal/iec_tx_byte.s b/c64/kernal/iec_tx_byte.s index b827d8c2..a1eac09b 100644 --- a/c64/kernal/iec_tx_byte.s +++ b/c64/kernal/iec_tx_byte.s @@ -1,11 +1,16 @@ ;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc -;; Carry flag set = signal EOI +;; Expects byte to send in BSOUR; Carry flag set = signal EOI +;; Preserves .X and .Y registers + iec_tx_byte: - ;; Store byte to send on the stack + ;; Store .X and .Y on the stack - preserve them + txa + pha + tya pha ;; Notify all devices that we are going to send a byte @@ -15,10 +20,9 @@ iec_tx_byte: ;; Common part of iec_txbyte and iec_tx_common - waits for devices ;; and transmits a byte - pla jsr iec_tx_common - ;; All done - give device time to tell if they are busy by pulling DATA + ;; Give device time to tell if they are busy by pulling DATA ;; They should do it within 1ms ldx #$FF * lda CIA2_PRA @@ -27,15 +31,8 @@ iec_tx_byte: bpl + dex bne - - bpl iec_tx_byte_error + bpl iec_return_DEVICE_NOT_FOUND * - ;; All done - clc - rts - -iec_tx_byte_error: - - jsr iec_set_idle - jmp kernalerror_DEVICE_NOT_FOUND + jmp iec_return_success diff --git a/c64/kernal/iec_tx_command.s b/c64/kernal/iec_tx_command.s index 0e92e2db..f785d736 100644 --- a/c64/kernal/iec_tx_command.s +++ b/c64/kernal/iec_tx_command.s @@ -1,9 +1,16 @@ ;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc +;; Expects command to send in BSOUR; Carry flag set = signal EOI +;; Preserves .X and .Y registers + + iec_tx_command: - ;; Store command to send on the stack + ;; Store .X and .Y on the stack - preserve them + txa + pha + tya pha ;; Notify all devices that we are going to send a byte @@ -18,11 +25,8 @@ iec_tx_command: and #BIT_CIA2_PRA_DAT_IN ; XXX try to optimize this, move to separate routine beq + - ;; No devices present on the bus, so we can immediately return with device not found - pla - - jsr iec_set_idle - jmp kernalerror_DEVICE_NOT_FOUND + ;; No devices present on the bus, so we can immediately return with device not found + jmp iec_return_DEVICE_NOT_FOUND * ;; At least one device responded, but they are still allowed to stall ;; (can be busy processing something), we have to wait till they are all @@ -35,7 +39,6 @@ iec_tx_command: ;; and transmits a byte clc ; Carry flag set is used for EOI mark - pla jsr iec_tx_common ;; According to https://www.pagetable.com/?p=1135 there is some complicated and dangerous @@ -50,8 +53,7 @@ iec_tx_command: ;; to wait for the DATA being pulled, as confirmation is expected from ;; a single device only - but not sure if it's worth the trouble - jsr iec_set_idle - jmp kernalerror_DEVICE_NOT_FOUND + jmp iec_return_DEVICE_NOT_FOUND * ;; All done @@ -60,5 +62,5 @@ iec_tx_command: ;; jsr iec_wait20us ;; jsr iec_set_idle - clc - rts + jmp iec_return_success + diff --git a/c64/kernal/iec_tx_common.s b/c64/kernal/iec_tx_common.s index ef9a5097..50d5edca 100644 --- a/c64/kernal/iec_tx_common.s +++ b/c64/kernal/iec_tx_common.s @@ -3,15 +3,15 @@ ;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc ;; and http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf +;; Expects byte to send in BSOUR; Carry flag set = signal EOI + + iec_tx_common: ;; Timing is critical here - execute on disabled IRQs php sei - ;; Store the byte to send on a stack - pha - ;; Wait till all receivers are ready, they should all release DATA jsr iec_wait_for_data_release @@ -38,13 +38,14 @@ iec_tx_common: ;; Now, we can start transmission of 8 bits of data ldx #7 - pla iec_tx_common_sendbit: ;; Is next bit 0 or 1? + lda BSOUR lsr - pha + sta BSOUR bcs + + ;; XXX we are actually destroying BSOUR here... is it allowed? ;; Bit is 0 jsr iec_release_clk_pull_data @@ -65,13 +66,8 @@ iec_tx_common_bit_is_sent: ;; More bits to send? dex - bpl iec_tx_common_nextbit - pla - + bpl iec_tx_common_sendbit + plp rts ; Flow continues differently for data/command - -iec_tx_common_nextbit: - pla - jmp iec_tx_common_sendbit diff --git a/c64/kernal/listen.s b/c64/kernal/listen.s index 92ad77fa..7f71c941 100644 --- a/c64/kernal/listen.s +++ b/c64/kernal/listen.s @@ -4,16 +4,15 @@ ;; ;; - [RG64] C64 Programmer's Reference Guide - page 285 ;; - [CM64] Compute's Mapping the Commodore 64 - page 223 +;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc ;; ;; CPU registers that has to be preserved (see [RG64]): .X, .Y ;; -;; XXX currently does not preserve registers, to be fixed! listen: - ;; This trivial routine is documented in 'Compute's Mapping the Commodore 64', page 223 and - ;; https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc and #$1F ; make sure bits encoding the command are cleared out ora #$20 + sta BSOUR jmp iec_tx_command diff --git a/c64/kernal/load.s b/c64/kernal/load.s index df29f688..131e987f 100644 --- a/c64/kernal/load.s +++ b/c64/kernal/load.s @@ -67,22 +67,16 @@ load_send_filename: jsr peek_under_roms iny - ;; Save Y because iec_tx_byte will corrupt it - tax - tya - pha - ;; Set Carry flag on the last file name character, to mark EOI - cmp FNLEN + cpy FNLEN clc bne + sec * - txa + ;; Transmit one character + sta BSOUR jsr iec_tx_byte - pla - tay jmp load_send_filename load_filename_sent: @@ -98,6 +92,7 @@ load_filename_sent: bcs lvs_load_verify_error lda #$60 ; open channel / data (p3) , required according to p13 + sta BSOUR jsr iec_tx_command bcs lvs_load_verify_error @@ -156,6 +151,7 @@ load_loop: jsr listen lda #$E0 + sta BSOUR jsr iec_tx_command ;; Tell drive to unlisten diff --git a/c64/kernal/open.s b/c64/kernal/open.s index d5f99aa7..6ae6ac7e 100644 --- a/c64/kernal/open.s +++ b/c64/kernal/open.s @@ -82,12 +82,6 @@ open_iec: ;; XXX note: this is only a temporary test implementation, real 'open' does not send anything to IEC, ;; see http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf - ;; Disable IRQs, since timing matters! - sei - - ;; Begin sending under attention - ;; XXX jsr iec_assert_atn - ;; Request device to talk lda current_device_number jsr talk @@ -107,8 +101,5 @@ open_iec: clc open_iec_error: - ;; Re-enable interrupts and return - ;; (iec_tx_byte will have set/cleared C flag and put result code - ;; in A if it was an error). - cli + ;; Carry flag will be set by low-level routines rts diff --git a/c64/kernal/second.s b/c64/kernal/second.s index d9024dff..53d1391e 100644 --- a/c64/kernal/second.s +++ b/c64/kernal/second.s @@ -4,16 +4,15 @@ ;; ;; - [RG64] C64 Programmer's Reference Guide - page 296 ;; - [CM64] Compute's Mapping the Commodore 64 - page 223/224 +;; - https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc ;; ;; CPU registers that has to be preserved (see [RG64]): .X, .Y ;; -;; XXX currently does not preserve registers, to be fixed! second: - ;; see also https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc - and #$1F ; make sure bits encoding the command are cleared out ora #$60 + sta BSOUR jmp iec_tx_command diff --git a/c64/kernal/talk.s b/c64/kernal/talk.s index 253cba33..67a87bd9 100644 --- a/c64/kernal/talk.s +++ b/c64/kernal/talk.s @@ -4,18 +4,17 @@ ;; ;; - [RG64] C64 Programmer's Reference Guide - page 301/302 ;; - [CM64] Compute's Mapping the Commodore 64 - page 223 +;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc ;; ;; CPU registers that has to be preserved (see [RG64]): .X, .Y ;; -;; XXX currently does not preserve registers, to be fixed! + ;; XXX shouldn't this do a turnaround? talk: - ;; See also https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc - and #$1F ; make sure bits encoding the command are cleared out ora #$40 + sta BSOUR jmp iec_tx_command - diff --git a/c64/kernal/tksa.s b/c64/kernal/tksa.s index 604ad2aa..d003cfbb 100644 --- a/c64/kernal/tksa.s +++ b/c64/kernal/tksa.s @@ -4,18 +4,18 @@ ;; ;; - [RG64] C64 Programmer's Reference Guide - page 302 ;; - [CM64] Compute's Mapping the Commodore 64 - page 224 +;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc ;; ;; CPU registers that has to be preserved (see [RG64]): .X, .Y ;; -;; XXX currently does not preserve registers, to be fixed! + ;; XXX shouldn't this do a turnaround? tksa: - ;; See also https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc - and #$1F ; make sure bits encoding the command are cleared out ora #$F0 + sta BSOUR jmp iec_tx_command diff --git a/c64/kernal/unlsn.s b/c64/kernal/unlsn.s index 05e73cf5..32f0b0f5 100644 --- a/c64/kernal/unlsn.s +++ b/c64/kernal/unlsn.s @@ -4,11 +4,11 @@ ;; ;; - [RG64] C64 Programmer's Reference Guide - page 303 ;; - [CM64] Compute's Mapping the Commodore 64 - page 224 +;; - https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc ;; ;; CPU registers that has to be preserved (see [RG64]): .X, .Y ;; -;; XXX currently does not preserve registers, to be fixed! unlsn: @@ -17,15 +17,12 @@ unlsn: ;; First check whether we have something to be sent in the buffer lda C3PO beq + - lda BSOUR sec ; send it with EOI jsr iec_tx_byte ; XXX what about the status of this operation? - ;; Mark the buffer as invalid - lda #$00 - sta C3PO * - ;; Buffer empty send the command + ;; Buffer empty, send the command lda #$3F + sta BSOUR jmp iec_tx_command diff --git a/c64/kernal/untlk.s b/c64/kernal/untlk.s index d7276361..7f421bb7 100644 --- a/c64/kernal/untlk.s +++ b/c64/kernal/untlk.s @@ -4,16 +4,17 @@ ;; ;; - [RG64] C64 Programmer's Reference Guide - page 304 ;; - [CM64] Compute's Mapping the Commodore 64 - page 224 +;; - https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc ;; ;; CPU registers that has to be preserved (see [RG64]): .X, .Y ;; -;; XXX currently does not preserve registers, to be fixed! + ;; XXX shouldn't this do a turnaround? untlk: - ;; This trivial routine is documented in 'Compute's Mapping the Commodore 64', page 224 lda #$5F + sta BSOUR jmp iec_tx_command