diff --git a/bin/basic b/bin/basic index ce99e4f6..5563b9cd 100644 Binary files a/bin/basic and b/bin/basic differ diff --git a/bin/kernal b/bin/kernal index d072f2e9..b992407f 100644 Binary files a/bin/kernal and b/bin/kernal differ diff --git a/c64/basic/,aliases.s b/c64/basic/,aliases.s index a9898755..bbee542e 100644 --- a/c64/basic/,aliases.s +++ b/c64/basic/,aliases.s @@ -210,7 +210,68 @@ .alias JSCREEN $FFED .alias JPLOT $FFF0 .alias JIOBASE $FFF3 - + + ;; Kernal error codes - returned in the A register + ;; Described in 'Commodore 64 Programmer's Reference Guide', page 306 + .alias K_ERR_ROUTINE_TERMINATED $00 + .alias K_ERR_TOO_MANY_OPEN_FILES $01 + .alias K_ERR_FILE_ALREADY_OPEN $02 + .alias K_ERR_FILE_NOT_OPEN $03 + .alias K_ERR_FILE_NOT_FOUND $04 + .alias K_ERR_DEVICE_NOT_FOUND $05 + .alias K_ERR_FILE_NOT_INPUT $06 + .alias K_ERR_FILE_NOT_OUTPUT $07 + .alias K_ERR_FILE_NAME_MISSING $08 + .alias K_ERR_ILLEGAL_DEVICE_NUMBER $09 + .alias K_ERR_TOP_MEM_RS232 $F0 + + ;; Kernal status codes for READST routine (IOSTATUS) + ;; Described in 'Commodore 64 Programmer's Reference Guide', page 292 + ;; For IEC devices + .alias K_STS_TIMEOUT_WRITE $01 + .alias K_STS_TIMEOUT_READ $02 + .alias K_STS_EOI $40 + .alias K_STS_DEVICE_NOT_FOUND $80 + ;; For tape deck + .alias K_STS_SHORT_BLOCK $04 + .alias K_STS_LONG_BLOCK $08 + .alias K_STS_READ_ERROR $10 + .alias K_STS_CHECKSUM_ERROR $20 + .alias K_STS_END_OF_FILE $40 + .alias K_STS_END_OF_TAPE $80 + + ;; BASIC error codes, taken from http://sta.c64.org/cbm64baserr.html + .alias B_ERR_TOO_MANY_FILES $01 + .alias B_ERR_FILE_OPEN $02 + .alias B_ERR_FILE_NOT_OPEN $03 + .alias B_ERR_FILE_NOT_FOUND $04 + .alias B_ERR_DEVICE_NOT_PRESENT $05 + .alias B_ERR_NOT_INPUT_FILE $06 + .alias B_ERR_NOT_OUTPUT_FILE $07 + .alias B_ERR_MISSING_FILENAME $08 + .alias B_ERR_ILLEGAL_DEVICE_NUMBER $09 + .alias B_ERR_NEXT_WITHOUT_FOR $0A + .alias B_ERR_SYNTAX $0B + .alias B_ERR_RETURN_WITHOUT_GOSUB $0C + .alias B_ERR_OUT_OF_DATA $0D + .alias B_ERR_ILLEGAL_QUANTITY $0E + .alias B_ERR_OVERFLOW $0F + .alias B_ERR_OUT_OF_MEMORY $10 + .alias B_ERR_UNDEFD_STATEMENT $11 + .alias B_ERR_BAD_SUBSCRIPT $12 + .alias B_ERR_REDIMD_ARRAY $13 + .alias B_ERR_DIVISION_BY_ZERO $14 + .alias B_ERR_ILLEGAL_DIRECT $15 + .alias B_ERR_TYPE_MISMATCH $16 + .alias B_ERR_STRING_TOO_LONG $17 + .alias B_ERR_FILE_DATA $18 + .alias B_ERR_FORMULA_TOO_COMPLEX $19 + .alias B_ERR_CANT_CONTINUE $1A + .alias B_ERR_UNDEFD_FUNCTION $1B + .alias B_ERR_VERIFY $1C + .alias B_ERR_LOAD $1D + .alias B_ERR_BREAK $1E + ;; BASIC uses some extra bytes for memory access under ROMs located at $2A7 onwards ;; IRQs are disabled when doing such accesses, and a default NMI handler only increments ;; a counter, so that if an NMI occurs, it doesn't crash the machine, but can be captured. diff --git a/c64/basic/cmd_load.s b/c64/basic/cmd_load.s index fa5748c6..5eb5b7f0 100644 --- a/c64/basic/cmd_load.s +++ b/c64/basic/cmd_load.s @@ -21,8 +21,9 @@ cmd_load: jsr JSETMSG ;; XXX handle device number from arguments, if not present, use the call below - jsr set_sane_devnum - + jsr select_device + stx current_device_number + ;; Set filename and length lda #$00 sta current_filename_length diff --git a/c64/basic/set_sane_devnum.s b/c64/basic/select_device.s similarity index 87% rename from c64/basic/set_sane_devnum.s rename to c64/basic/select_device.s index 501bc5d1..48061f8a 100644 --- a/c64/basic/set_sane_devnum.s +++ b/c64/basic/select_device.s @@ -1,5 +1,5 @@ -set_sane_devnum: +select_device: ;; Take last device number, make sure it's a drive ;; If not, set to 8 (first drive number) @@ -12,6 +12,5 @@ set_sane_devnum: bpl + bcs + ldx #$08 - stx current_device_number * rts diff --git a/c64/basic/wedge_dos.s b/c64/basic/wedge_dos.s index 167338f7..da0d3788 100644 --- a/c64/basic/wedge_dos.s +++ b/c64/basic/wedge_dos.s @@ -6,11 +6,8 @@ wedge_dos: ;; Close all the channels, so that wedge has full control jsr wedge_dos_CLALL - ;; Make sure current device number is sane - jsr set_sane_devnum - - ;; Set remaining file parameters (X already set by set_sane_devnum); - ;; channel 15 is a typical one for commands + ;; Set file parameters, channel 15 is a typical one for commands + jsr select_device ; sets X register lda #$0F ldy #$0F jsr JSETFLS diff --git a/c64/kernal/,aliases.s b/c64/kernal/,aliases.s index e5616ae3..b76ce732 100644 --- a/c64/kernal/,aliases.s +++ b/c64/kernal/,aliases.s @@ -151,6 +151,67 @@ .alias JPLOT $FFF0 .alias JIOBASE $FFF3 + ;; Kernal error codes - returned in the A register + ;; Described in 'Commodore 64 Programmer's Reference Guide', page 306 + .alias K_ERR_ROUTINE_TERMINATED $00 + .alias K_ERR_TOO_MANY_OPEN_FILES $01 + .alias K_ERR_FILE_ALREADY_OPEN $02 + .alias K_ERR_FILE_NOT_OPEN $03 + .alias K_ERR_FILE_NOT_FOUND $04 + .alias K_ERR_DEVICE_NOT_FOUND $05 + .alias K_ERR_FILE_NOT_INPUT $06 + .alias K_ERR_FILE_NOT_OUTPUT $07 + .alias K_ERR_FILE_NAME_MISSING $08 + .alias K_ERR_ILLEGAL_DEVICE_NUMBER $09 + .alias K_ERR_TOP_MEM_RS232 $F0 + + ;; Kernal status codes for READST routine (IOSTATUS) + ;; Described in 'Commodore 64 Programmer's Reference Guide', page 292 + ;; For IEC devices + .alias K_STS_TIMEOUT_WRITE $01 + .alias K_STS_TIMEOUT_READ $02 + .alias K_STS_EOI $40 + .alias K_STS_DEVICE_NOT_FOUND $80 + ;; For tape deck + .alias K_STS_SHORT_BLOCK $04 + .alias K_STS_LONG_BLOCK $08 + .alias K_STS_READ_ERROR $10 + .alias K_STS_CHECKSUM_ERROR $20 + .alias K_STS_END_OF_FILE $40 + .alias K_STS_END_OF_TAPE $80 + + ;; BASIC error codes, taken from http://sta.c64.org/cbm64baserr.html + .alias B_ERR_TOO_MANY_FILES $01 + .alias B_ERR_FILE_OPEN $02 + .alias B_ERR_FILE_NOT_OPEN $03 + .alias B_ERR_FILE_NOT_FOUND $04 + .alias B_ERR_DEVICE_NOT_PRESENT $05 + .alias B_ERR_NOT_INPUT_FILE $06 + .alias B_ERR_NOT_OUTPUT_FILE $07 + .alias B_ERR_MISSING_FILENAME $08 + .alias B_ERR_ILLEGAL_DEVICE_NUMBER $09 + .alias B_ERR_NEXT_WITHOUT_FOR $0A + .alias B_ERR_SYNTAX $0B + .alias B_ERR_RETURN_WITHOUT_GOSUB $0C + .alias B_ERR_OUT_OF_DATA $0D + .alias B_ERR_ILLEGAL_QUANTITY $0E + .alias B_ERR_OVERFLOW $0F + .alias B_ERR_OUT_OF_MEMORY $10 + .alias B_ERR_UNDEFD_STATEMENT $11 + .alias B_ERR_BAD_SUBSCRIPT $12 + .alias B_ERR_REDIMD_ARRAY $13 + .alias B_ERR_DIVISION_BY_ZERO $14 + .alias B_ERR_ILLEGAL_DIRECT $15 + .alias B_ERR_TYPE_MISMATCH $16 + .alias B_ERR_STRING_TOO_LONG $17 + .alias B_ERR_FILE_DATA $18 + .alias B_ERR_FORMULA_TOO_COMPLEX $19 + .alias B_ERR_CANT_CONTINUE $1A + .alias B_ERR_UNDEFD_FUNCTION $1B + .alias B_ERR_VERIFY $1C + .alias B_ERR_LOAD $1D + .alias B_ERR_BREAK $1E + ;; Under-ROM routines ;; (BASIC also includes them. XXX - We should de-duplicate them in a safe manner) .alias missed_nmi_flag $2A7 diff --git a/c64/kernal/errors.s b/c64/kernal/errors.s index 33666e62..1f18f5e1 100644 --- a/c64/kernal/errors.s +++ b/c64/kernal/errors.s @@ -1,53 +1,88 @@ ;; Kernal error codes are described in 'Commodore 64 Programmer's Reference Guide', page 306 -kernalerror_common: - sta DFLTN +kernalerror_ROUTINE_TERMINATED: ; by a STOP key + lda #K_ERR_ROUTINE_TERMINATED sec rts -kernalerror_ROUTINE_TERMINATED: ; by a STOP key - lda #$00 - jmp kernalerror_common - kernalerror_TOO_MANY_OPEN_FILES: - lda #$01 - jmp kernalerror_common - -kernalerror_FILE_ALREADY_OPEN: - lda #$02 - jmp kernalerror_common - -kernalerror_FILE_NOT_OPEN: - lda #$03 - jmp kernalerror_common - -kernalerror_FILE_NOT_FOUND: - lda #$04 - jmp kernalerror_common - -kernalerror_DEVICE_NOT_FOUND: - lda #$05 - jmp kernalerror_common - -kernalerror_FILE_NOT_INPUT: - lda #$06 - jmp kernalerror_common - -kernalerror_FILE_NOT_OUTPUT: - lda #$07 - jmp kernalerror_common - -kernalerror_FILE_NAME_MISSING: - lda #$08 - jmp kernalerror_common - -kernalerror_ILLEGAL_DEVICE_NUMBER: - lda #$09 - jmp kernalerror_common - -kernalerror_TOP_MEM_RS232: - lda #$F0 - sta RSSTAT + lda #K_ERR_TOO_MANY_OPEN_FILES sec rts + +kernalerror_FILE_ALREADY_OPEN: + lda #K_ERR_FILE_ALREADY_OPEN + sec + rts + +kernalerror_FILE_NOT_OPEN: + lda #K_ERR_FILE_NOT_OPEN + sec + rts + +kernalerror_FILE_NOT_FOUND: + lda #K_ERR_FILE_NOT_FOUND + sec + rts + +kernalerror_DEVICE_NOT_FOUND: + lda #K_ERR_DEVICE_NOT_FOUND + sec + rts + +kernalerror_FILE_NOT_INPUT: + lda #K_ERR_FILE_NOT_INPUT + sec + rts + +kernalerror_FILE_NOT_OUTPUT: + lda #K_ERR_FILE_NOT_OUTPUT + sec + rts + +kernalerror_FILE_NAME_MISSING: + lda #K_ERR_FILE_NAME_MISSING + sec + rts + +kernalerror_ILLEGAL_DEVICE_NUMBER: + lda #K_ERR_ILLEGAL_DEVICE_NUMBER + sec + rts + +kernalerror_TOP_MEM_RS232: + lda #K_ERR_TOP_MEM_RS232 + sec + rts + +;; Kernal status codes are described in 'Commodore 64 Programmer's Reference Guide', page 292 + +kernalstatus_reset: + lda #$00 + sta IOSTATUS + rts + +kernalstatus_TIMEOUT_WRITE: ;; XXX detect this! + lda IOSTATUS + ora #K_STS_TIMEOUT_WRITE + sta IOSTATUS + rts + +kernalstatus_TIMEOUT_READ: ;; XXX detect this! + lda IOSTATUS + ora #K_STS_TIMEOUT_READ + sta IOSTATUS + rts + +kernalstatus_EOI: + lda IOSTATUS + ora #K_STS_EOI + sta IOSTATUS + rts + +kernalstatus_DEVICE_NOT_FOUND: + lda IOSTATUS + ora #K_STS_DEVICE_NOT_FOUND + sta IOSTATUS + rts diff --git a/c64/kernal/iec_rx_byte.s b/c64/kernal/iec_rx_byte.s index 943ce880..d91a857d 100644 --- a/c64/kernal/iec_rx_byte.s +++ b/c64/kernal/iec_rx_byte.s @@ -28,7 +28,7 @@ iec_rx_clk_wait1: ;; Timeout - either this is the last byte of stream, or the stream is empty at all. ;; Mark end of stream in IOSTATUS - jsr iec_rx_set_eoi + jsr kernalstatus_EOI iec_rx_not_empty: @@ -93,7 +93,7 @@ iec_rx_clk_wait2: bne iec_rx_clk_wait2 ; 3 cycles if jumped ;; Timeout - jsr iec_rx_set_eoi + jsr kernalstatus_EOI pla sec ; XXX confirm that sec is really a way to report timeout here rts @@ -115,11 +115,3 @@ iec_rx_clk_wait2: clc rts -iec_rx_set_eoi: - - ;; Store EOI information in IOSTATUS - lda IOSTATUS - ora #$40 - sta IOSTATUS - - rts diff --git a/c64/kernal/load.s b/c64/kernal/load.s index bc6b3ac6..d9097d95 100644 --- a/c64/kernal/load.s +++ b/c64/kernal/load.s @@ -1,4 +1,4 @@ - ; Function defined on pp272-273 of C64 Programmers Reference Guide + ; Function defined on pp272-273 of C64 Programmers Reference Guide ;; IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf ;; Definition of function from Compute's Mapping the 64 p231 @@ -29,8 +29,7 @@ load: sty load_save_start_ptr+1 ;; Reset status - lda #$00 - sta IOSTATUS + jsr kernalstatus_reset ;; We need our helpers to get to filenames under ROMs or IO area jsr install_ram_routines @@ -54,16 +53,14 @@ print_filename_loop: iny jmp print_filename_loop * - ;; XXX - Use default device number ;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf - ;; p13, 16. - ;; also p16 tells us this routine doesn't mess with the file table in the C64, - ;; only in the drive. + ;; p13, 16; also p16 tells us this routine doesn't mess with the file table + ;; in the C64, only in the drive. ;; Call device to LISTEN (p16) lda current_device_number jsr listen - bcs load_error + bcs load_device_not_found_error ;; Open channel #0 (p16) lda #$00 @@ -105,7 +102,7 @@ sent_filename: ;; Command device to unlisten to indicate end of file name. (p16) jsr unlsn bcs load_error - jsr iec_set_idle + jsr iec_set_idle ;; XXX is it needed? ;; Now command device to talk (p16) lda current_device_number @@ -118,20 +115,18 @@ sent_filename: ;; We are currently talker, so do the IEC turn around so that we ;; are the listener (p16) - ;; An error here means FILE NOT FOUND ? jsr iec_turnaround_to_listen bcs load_error ;; Get load address and store it if secondary address is zero - ;; XXX add secondary address check jsr iec_rx_byte - bcs file_not_found_error + bcs load_file_not_found_error ldx current_secondary_address beq + sta load_save_start_ptr+0 * jsr iec_rx_byte - bcs file_not_found_error + bcs load_file_not_found_error ldx current_secondary_address beq + sta load_save_start_ptr+1 @@ -179,11 +174,11 @@ load_loop: bne + inc load_save_start_ptr+1 ;; If we wrap around to $0000, then this is bad. - beq load_error + beq load_wrap_around_error * - ;; Check for EOI -- if so, read one last byte + ;; Check for EOI - if so, this was the last byte lda IOSTATUS - and #$40 + and #K_STS_EOI beq load_loop load_done: @@ -221,7 +216,7 @@ load_done: jsr iec_set_idle ;; Return last address - Compute's Mapping the 64 says without the '+1', - ;; checked on original ROMs that this is really the case + ;; checked (short test program) on original ROMs that this is really the case ldx load_save_start_ptr+0 ldy load_save_start_ptr+1 @@ -229,27 +224,38 @@ load_done: cli rts +load_wrap_around_error: + + ;; This error is probably not even detected by C64 Kernal; + ;; report BASIC error code that looks the most sane + cli + lda #B_ERR_OVERFLOW + sec + rts + rts + +load_device_not_found_error: + + cli + jsr kernalstatus_DEVICE_NOT_FOUND + jmp kernalerror_DEVICE_NOT_FOUND + +load_file_not_found_error: + + cli + jmp kernalerror_FILE_NOT_FOUND + load_error: - ;; Advance cursor to next line, if needed - lda MSGFLG - bpl + - lda #$0D - jsr JCHROUT -* - ;; XXX - Indicate KERNAL (not BASIC) LOAD error condtion - sec - lda #28 - - ;; Re-enable interrupts and return + ;; XXX should we really return BASIC error code here? cli - ;; (iec_tx_byte will have set/cleared C flag and put result code - ;; in A if it was an error). + lda kernal_load_or_verify_flag + beq load_verify_error + lda #B_ERR_LOAD + bne + +load_verify_error: + lda #B_ERR_VERIFY +* + sec rts -file_not_found_error: - ;; Indicate KERNAL error condition for file not found - sec - lda #$04 - cli - rts