diff --git a/STATUS.md b/STATUS.md index 83831a1f..65bf9f8f 100644 --- a/STATUS.md +++ b/STATUS.md @@ -6,7 +6,8 @@ Here are the features of the Open ROMs not found in the original ROMs from the 8 * improved keyboard scanning, supports multi-key roll-over and rejection of spurious joystick input * joystick (port 1) can be used to move text cursor * uses RAM under ROM and I/O: 61436 bytes free -* cold/warm start silences 4 SID chips - assumes addresses $D400, $D420, $D440, $D460 +* cold/warm start silences multiple SID chips - all $D4xx and $D5xx addresses +* wark start due to BRK prints out the instruction address * extended `LOAD` command * start/end addresses are displayed, in the Final cartridge style * command with just the file name tries to use the last device if it's number seems sane; otherwise uses 8 @@ -15,6 +16,7 @@ Here are the features of the Open ROMs not found in the original ROMs from the 8 NOTE: extra features and their syntax can change in the future! + # Features missing @@ -27,11 +29,8 @@ The following ROM features are currently missing: * tape support * RS-232 support * breaking Kernal routines with RUN/STOP key -* BRK handling; NMI/IRQ handling is incomplete +* NMI andling is incomplete -Features currently being worked on: - -* IEC support needs more work; alternative drive ROMs (JiffyDOS, DolphinDOS, etc) usually don't work with current implementation, SAVE / VERIFY are not implemented, etc. # API status @@ -101,14 +100,14 @@ NOTE: Even the 'DONE' routines won't support features described as missing in on | `$FFD2` | `CHROUT` | PARTIAL | | | `$FFD5` | `LOAD` | PARTIAL | no VERIFY support yet, no STOP key support | | `$FFD8` | `SAVE` | NOT DONE | | -| `$FFDB` | `SETTIM` | NOT DONE | | -| `$FFDE` | `RDTIM` | NOT DONE | | +| `$FFDB` | `SETTIM` | DONE | | +| `$FFDE` | `RDTIM` | DONE | | | `$FFE1` | `STOP` | DONE | | | `$FFE4` | `GETIN` | PARTIAL | only some devices supported | | `$FFE7` | `CLALL` | DONE | | -| `$FFEA` | `UDTIM` | NOT DONE | checking for STOP key present in SCNKEY instead | +| `$FFEA` | `UDTIM` | DONE | | | `$FFED` | `SCREEN` | DONE | | -| `$FFF0` | `PLOT` | NOT DONE | | +| `$FFF0` | `PLOT` | DONE | | | `$FFF3` | `IOBASE` | DONE | |
diff --git a/bin/basic_generic.rom b/bin/basic_generic.rom index 82c768bf..51ee2980 100644 Binary files a/bin/basic_generic.rom and b/bin/basic_generic.rom differ diff --git a/bin/basic_mega65.rom b/bin/basic_mega65.rom index 911bacab..84c54593 100644 Binary files a/bin/basic_mega65.rom and b/bin/basic_mega65.rom differ diff --git a/bin/basic_ultimate64.rom b/bin/basic_ultimate64.rom index e54c732f..5df8a636 100644 Binary files a/bin/basic_ultimate64.rom and b/bin/basic_ultimate64.rom differ diff --git a/bin/kernal_generic.rom b/bin/kernal_generic.rom index 140ad023..67a92cbc 100644 Binary files a/bin/kernal_generic.rom and b/bin/kernal_generic.rom differ diff --git a/bin/kernal_mega65.rom b/bin/kernal_mega65.rom index 140ad023..67a92cbc 100644 Binary files a/bin/kernal_mega65.rom and b/bin/kernal_mega65.rom differ diff --git a/bin/kernal_ultimate64.rom b/bin/kernal_ultimate64.rom index 140ad023..67a92cbc 100644 Binary files a/bin/kernal_ultimate64.rom and b/bin/kernal_ultimate64.rom differ diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index 6108e28e..d72deec7 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -34,11 +34,7 @@ .alias IEC_TMP1 $A3 ; temporary variable for tape and IEC .alias IEC_TMP2 $A4 ; temporary variable for tape and IEC - ;; 2-byte location below seems to be a good place for temporary storage, - ;; it seems used for timing during tape reads only - see: - ;; - 'C64 Programmer's Reference Guide', page 314 - ;; - 'Compute's Mapping the Commodore 64', page 32 - .alias CMP0 $B0 ; $B0-$B1 + .alias CMP0 $B0 ; $B0-$B1, temporary tape storage, we use it too for BRK instruction address .alias FNLEN $B7 ; current file name length diff --git a/c64/basic/basic_execute_line.s b/c64/basic/basic_execute_line.s index 5ea0aafb..1ddd7b43 100644 --- a/c64/basic/basic_execute_line.s +++ b/c64/basic/basic_execute_line.s @@ -30,8 +30,9 @@ basic_execute_statement: ;; Check for RUN/STOP lda STKEY - bpl basic_do_break - + bmi + + jmp basic_do_break +* ;; Skip over any white space and : ldy #0 ldx # 312 rasterlines, PAL, VIC 6569 + ;; #$06 -> 263 rasterlines, NTSC, VIC 6567R8 + ;; #$05 -> 262 rasterlines, NTSC, VIC 6567R56A + + cmp #$07 + bcs cint_pal + +cint_ntsc: + + ;; NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), + ;; is clocked at 1.022727 MHz, so that 1/60s is 17045 CPU cycles + + ldy #<17045 + ldx #>17045 + + sty CIA1_TIMALO + stx CIA1_TIMAHI + + lda #$00 + beq + + +cint_pal: + + lda #$01 +* + sta PALNTSC cint_brk: ; entry for BRK and STOP+RESTORE - XXX, where should it start? jsr setup_vicii - ;; According to [CM64], this routine also checks for PAL/NTSC - this must be a mistake, - ;; it's too late (IOINIT already needs this information), besides - POKE something - ;; to address 678 on a real C64, press STOP+RESTORE - the value won't change - ;; Initialise cursor blink flags (Compute's Mapping the 64 p215) lda #$00 sta cursor_blink_disable diff --git a/c64/kernal/f34a.open.s b/c64/kernal/f34a.open.s index 8d494dfe..c1bbb282 100644 --- a/c64/kernal/f34a.open.s +++ b/c64/kernal/f34a.open.s @@ -76,7 +76,7 @@ open_iec: lda current_secondary_address jsr iec_cmd_open bcc + - jmp kernalerror_DEVICE_NOT_FOUND ; XXX find a better error message for wrong channel (create new one?) + jmp kernalerror_DEVICE_NOT_FOUND * ;; We need our helpers to get to filenames under ROMs or IO area diff --git a/c64/kernal/f4a5.load.s b/c64/kernal/f4a5.load.s index ece03816..0bc03517 100644 --- a/c64/kernal/f4a5.load.s +++ b/c64/kernal/f4a5.load.s @@ -41,8 +41,9 @@ load: ;; Check whether we support the requested device lda current_device_number and #$FC - beq lvs_illegal_device_number ; device number below 4, not an IEC device - + bne + + jmp lvs_illegal_device_number ; device number below 4, not an IEC device +* ;; Device numbers above 30 are also illegal (see https://www.pagetable.com/?p=1031), ;; as the protocol combines device number with command code int one byte, ;; above 30 it is no longer possible (UNLISTEN and UNTALK codes prevent using @@ -60,41 +61,51 @@ load: ;; Call device to LISTEN (p16) lda current_device_number jsr listen - bcs lvs_device_not_found_error - + bcc + + jmp lvs_device_not_found_error ; XXX deduplicate with other jumps in this routine +* ;; Open channel 0 (reserved for file reading) lda #$00 jsr iec_cmd_open - bcs lvs_load_verify_error - + bcc + + jmp lvs_device_not_found_error ; XXX deduplicate with other jumps in this routine +* ;; Send file name jsr lvs_send_file_name - bcs lvs_load_verify_error - + bcc + + jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine +* ;; Now command device to talk (p16) lda current_device_number jsr talk - bcs lvs_load_verify_error - + bcc + + jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine +* lda #$60 ; open channel / data (p3) , required according to p13 sta IEC_TMP2 jsr iec_tx_command - bcs lvs_load_verify_error - + bcc + + jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine +* ;; We are currently talker, so do the IEC turn around so that we ;; are the listener (p16) jsr iec_turnaround_to_listen - bcs lvs_load_verify_error - + bcc + + jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine +* ;; Get load address and store it if secondary address is zero jsr iec_rx_byte - bcs lvs_file_not_found_error + bcc + + jmp lvs_file_not_found_error ; XXX deduplicate with other jumps in this routine +* ldx current_secondary_address beq + sta STAL+0 * jsr iec_rx_byte - bcs lvs_file_not_found_error + bcc + + jmp lvs_file_not_found_error ; XXX deduplicate with other jumps in this routine +* ldx current_secondary_address beq + sta STAL+1 @@ -105,16 +116,19 @@ load: load_loop: ;; We are now ready to receive bytes jsr iec_rx_byte - bcs lvs_load_verify_error - + bcc + + jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine +* ;; Handle the byte (store in memory / verify) jsr lvs_handle_byte_load_verify - bcs lvs_load_verify_error - + bcc + + jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine +* ;; Advance pointer to data jsr lvs_advance_pointer - bcs lvs_wrap_around_error - + bcc + + jmp lvs_wrap_around_error +* ;; Check for EOI - if so, this was the last byte lda IOSTATUS and #K_STS_EOI diff --git a/c64/kernal/fd15.interop b/c64/kernal/fd15.interop new file mode 100644 index 00000000..1436a2f0 --- /dev/null +++ b/c64/kernal/fd15.interop @@ -0,0 +1,4 @@ +Original Kernal location of the RESTOR routine. + +Routine moved to original location due to game 'Duotris' calling it instead of using the Kernal jumptable. +Starting the game without this patch caused warm reset with 'BRK AT $FD15' message. diff --git a/c64/kernal/vector.s b/c64/kernal/fd15.vector.s similarity index 100% rename from c64/kernal/vector.s rename to c64/kernal/fd15.vector.s diff --git a/c64/kernal/fda3.ioinit.s b/c64/kernal/fda3.ioinit.s index 3f1a3ba9..961ffdae 100644 --- a/c64/kernal/fda3.ioinit.s +++ b/c64/kernal/fda3.ioinit.s @@ -20,47 +20,24 @@ ioinit: sta CPU_R6510 stx CPU_D6510 - ;; Silence the SID chips + ;; Silence the SID chips under common addresses ldy #$00 * + ;; SIDs under $D4xx lda SID_SIGVOL, Y and #$F0 sta SID_SIGVOL, Y + ;; SIDs under $D5xx + lda SID_SIGVOL + $100, Y + and #$F0 + sta SID_SIGVOL + $100, Y tya clc adc #$20 tay - cpy #$80 ; $20 * amount of chips to silence, $80 to silence 4 chips bne - - ;; Detect video system (PAL/NTSC), use Graham's method, as it's short and reliable - ;; see here: https://codebase64.org/doku.php?id=base:detect_pal_ntsc - -ioinit_w0: - lda VIC_RASTER -ioinit_w1: - cmp VIC_RASTER - beq ioinit_w1 - bmi ioinit_w0 - - ;; Result in A, if no interrupt happened during the test: - ;; #$37 -> 312 rasterlines, PAL, VIC 6569 - ;; #$06 -> 263 rasterlines, NTSC, VIC 6567R8 - ;; #$05 -> 262 rasterlines, NTSC, VIC 6567R56A - - cmp #$07 - bcs ioinit_pal - -ioinit_ntsc: - lda #$00 - beq + - -ioinit_pal: - lda #$01 -* - sta PALNTSC - ;; XXX: calibrate TOD for both CIA's, see here: https://codebase64.org/doku.php?id=base:efficient_tod_initialisation ;; Enable CIA1 IRQ and ~50Hz timer (https://csdb.dk/forums/?roomid=11&topicid=69037) @@ -81,17 +58,6 @@ ioinit_pal: ldy #<16421 ldx #>16421 - lda PALNTSC - bne + - - ;; NTSC C64 (https://codebase64.org/doku.php?id=base:cpu_clocking), - ;; is clocked at 1.022727 MHz, so that 1/60s is 17045 CPU cycles - - ldy #<17045 - ldx #>17045 - - ;; Store the IRQ timing constant to CIA chip -* sty CIA1_TIMALO stx CIA1_TIMAHI diff --git a/c64/kernal/ff5b.cint.jmp.s b/c64/kernal/ff5b.cint.jmp.s new file mode 100644 index 00000000..b5497eca --- /dev/null +++ b/c64/kernal/ff5b.cint.jmp.s @@ -0,0 +1,6 @@ + +;; Our implementation is longer than the original one, +;; placing it here would cause a collision with OPEN + +cint: + jmp cint_real diff --git a/c64/kernal/ff5b.interop b/c64/kernal/ff5b.interop new file mode 100644 index 00000000..d5ca7abe --- /dev/null +++ b/c64/kernal/ff5b.interop @@ -0,0 +1,4 @@ +Original Kernal location of the CINT routine. + +Routine moved to original location due to game 'Duotris' calling it instead of using the Kernal jumptable. +Starting the game without this patch caused warm reset with 'BRK AT $FF5B' message. diff --git a/c64/kernal/iec/iec_pull_clk_release_data_oneshot.s b/c64/kernal/iec/iec_pull_clk_release_data_oneshot.s new file mode 100644 index 00000000..78d40472 --- /dev/null +++ b/c64/kernal/iec/iec_pull_clk_release_data_oneshot.s @@ -0,0 +1,8 @@ + +iec_pull_clk_release_data_oneshot: + + lda CIA2_PRA + ora #BIT_CIA2_PRA_CLK_OUT ; pull + and #$FF - BIT_CIA2_PRA_DAT_OUT ; release + sta CIA2_PRA + rts diff --git a/c64/kernal/iec/iec_tx_byte.s b/c64/kernal/iec/iec_tx_byte.s index 767dce76..6a978848 100644 --- a/c64/kernal/iec/iec_tx_byte.s +++ b/c64/kernal/iec/iec_tx_byte.s @@ -19,11 +19,66 @@ iec_tx_byte: ;; and it is going to be a data byte (released ATN) jsr iec_release_atn_clk_data - ;; Common part of iec_txbyte and iec_tx_common - waits for devices - ;; and transmits a byte + ;; Common part of iec_tx_byte and iec_tx_command + ;; 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 - jsr iec_tx_common +iec_tx_common: + + ;; Timing is critical here - execute on disabled IRQs + php + sei + + ;; Wait till all receivers are ready, they should all release DATA + jsr iec_wait_for_data_release + + ;; At this point a delay 256 usec or more is considered EOI, + ;; receiver should now acknowledge it by pulling data for at least 60 usec + ;; Keep the implementation as simple as possible: data should be released now + ;; so wait until it's pushed and released again + jsr iec_wait_for_data_pull + jsr iec_wait_for_data_release +* + ;; Pull CLK back to indicate that DATA is not valid, keep it for 60us + ;; We can use this routine as we don't hold DATA anyway (and its state doesn't even matter) + + jsr iec_pull_clk_release_data_oneshot + jsr iec_wait60us + + ;; Now, we can start transmission of 8 bits of data + ldx #7 + +iec_tx_common_sendbit: + ;; Is next bit 0 or 1? + lda IEC_TMP2 + lsr + sta IEC_TMP2 + bcs + + + ;; Bit is 0 + jsr iec_release_clk_pull_data + jmp iec_tx_common_bit_is_sent +* + ;; Bit is 1 + jsr iec_release_clk_data + +iec_tx_common_bit_is_sent: + + ;; Wait 20us, so that device(s) can pick DATA + jsr iec_wait20us + + ;; Pull CLK for 20us again, before sending the next bit + ;; or performing any other action + jsr iec_pull_clk_release_data_oneshot + jsr iec_wait20us + + ;; More bits to send? + dex + bpl iec_tx_common_sendbit + + plp + ;; Give device time to tell if they are busy by pulling DATA ;; They should do it within 1ms ldx #$FF @@ -36,5 +91,3 @@ iec_tx_byte: bpl iec_return_DEVICE_NOT_FOUND * jmp iec_return_success - - diff --git a/c64/kernal/iec/iec_tx_command.s b/c64/kernal/iec/iec_tx_command.s index e2da97f2..2332be44 100644 --- a/c64/kernal/iec/iec_tx_command.s +++ b/c64/kernal/iec/iec_tx_command.s @@ -19,15 +19,10 @@ iec_tx_command: ;; and it is going to be a command (pulled ATN) jsr iec_pull_atn_clk_release_data - ;; Give devices time to respond (response is mandatory!) + ;; Give devices time to respond (response is mandatory!) by pulling DATA jsr iec_wait1ms - - ;; Did at least one device respond by pulling DATA? - lda CIA2_PRA - 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 + lda CIA2_PRA ; pulled DATA = highest bit 0 = 'plus' + bpl + jmp iec_return_DEVICE_NOT_FOUND * ;; At least one device responded, but they are still allowed to stall @@ -41,22 +36,5 @@ iec_tx_command: ;; and transmits a byte clc ; Carry flag set is used for EOI mark - jsr iec_tx_common + jmp iec_tx_common - ;; According to https://www.pagetable.com/?p=1135 there is some complicated and dangerous - ;; flow here, but http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf (page 6) - ;; advices to just wait 1ms and check the DATA status - jsr iec_wait1ms - lda CIA2_PRA - and #BIT_CIA2_PRA_DAT_IN ; XXX try to optimize this, move to separate routine - beq + - - ;; XXX possible optimization of the flow above: for many commands it is enough - ;; 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 - - jmp iec_return_DEVICE_NOT_FOUND -* - ;; Done - - jmp iec_return_success diff --git a/c64/kernal/iec/iec_tx_common.s b/c64/kernal/iec/iec_tx_common.s deleted file mode 100644 index 8cc63e0f..00000000 --- a/c64/kernal/iec/iec_tx_common.s +++ /dev/null @@ -1,72 +0,0 @@ - -;; This is a common part of iec_tx_byte and iec_tx_command -;; 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 IEC_TMP2 ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html) -;; Carry flag set = signal EOI - -iec_tx_common: - - ;; Timing is critical here - execute on disabled IRQs - php - sei - - ;; Wait till all receivers are ready, they should all release DATA - jsr iec_wait_for_data_release - - ;; At this point a delay 256 usec or more is considered EOI - add waits if necessary - bcc + - jsr iec_wait100us - jsr iec_wait100us - jsr iec_wait60us - - ;; XXX waits above should be enough - why do we need more waits??? - jsr iec_wait100us - jsr iec_wait100us - jsr iec_wait100us - - ;; Receiver should now acknowledge EOI by pulling data for at least 60 usec - jsr iec_wait60us - jsr iec_wait_for_data_release -* - ;; Pull CLK back to indicate that DATA is not valid, keep it for 60us - ;; We can use this routine as we don't hold DATA anyway (and its state doesn't even matter) - - jsr iec_pull_clk_release_data - jsr iec_wait60us - - ;; Now, we can start transmission of 8 bits of data - ldx #7 - -iec_tx_common_sendbit: - ;; Is next bit 0 or 1? - lda IEC_TMP2 - lsr - sta IEC_TMP2 - bcs + - - ;; Bit is 0 - jsr iec_release_clk_pull_data - jmp iec_tx_common_bit_is_sent -* - ;; Bit is 1 - jsr iec_release_clk_data - -iec_tx_common_bit_is_sent: - - ;; Wait 20us, so that device(s) can pick DATA - jsr iec_wait20us - - ;; Pull CLK for 20us again, before sending the next bit - ;; or performing any other action - jsr iec_pull_clk_release_data - jsr iec_wait20us ; XXX this might be an overkill, there is a lot of code besides this wait here - few NOPs might be enough - - ;; More bits to send? - dex - bpl iec_tx_common_sendbit - - plp - rts ; Flow continues differently for data/command - diff --git a/c64/kernal/iec/iec_wait100us.s b/c64/kernal/iec/iec_wait100us.s deleted file mode 100644 index b3101685..00000000 --- a/c64/kernal/iec/iec_wait100us.s +++ /dev/null @@ -1,22 +0,0 @@ - -iec_wait100us: - - ;; Wait 100usec - - ;; PAL: - ;; - CPU frequency 0.985248 MHz, we need to waste at least 99 cycles - ;; NTSC: - ;; - CPU frequency 1.022727 MHZ, we need to waste at least 103 cycles - - ;; Waste cycles in a loop - - ldy #$12 ; 2 cycles -* dey ; 2 cycles * 18 - bpl - ; 3 cycles * 17 + 2 cycles - rts ; 6 cycles - - ;; 6 cycles JSR to routine, - ;; 97 cycles routine with RTS - ;; 1 cycle to fetch next instruction - ;; --- - ;; 104 cycles diff --git a/c64/kernal/iec/iec_wait1ms.s b/c64/kernal/iec/iec_wait1ms.s index a492df7f..3da125d8 100644 --- a/c64/kernal/iec/iec_wait1ms.s +++ b/c64/kernal/iec/iec_wait1ms.s @@ -17,4 +17,5 @@ iec_wait1ms: lda VIC_RASTER dex bne - + rts diff --git a/c64/kernal/interrupts/fe47.default_nmi_handler.s b/c64/kernal/interrupts/fe47.default_nmi_handler.s index 8814ac2c..1a1c915f 100644 --- a/c64/kernal/interrupts/fe47.default_nmi_handler.s +++ b/c64/kernal/interrupts/fe47.default_nmi_handler.s @@ -26,5 +26,9 @@ default_nmi_handler: bcs + jmp return_from_interrupt ; no STOP pressed * - jmp (CBINV) ; STOP + RESTORE + ;; STOP + RESTORE - clean the address of the BRK instruction (it's not BRK) first + lda #$00 + sta CMP0+0 + sta CMP0+1 + jmp (CBINV) diff --git a/c64/kernal/interrupts/irq_handler.s b/c64/kernal/interrupts/irq_handler.s index 99733333..292f88e0 100644 --- a/c64/kernal/interrupts/irq_handler.s +++ b/c64/kernal/interrupts/irq_handler.s @@ -16,12 +16,10 @@ irq_handler: pha ;; Check if caused by BRK - - ;; XXX disabled for now - resets Duotris game, unknown why - ; tsx - ; lda $0104, x ; get the pre-interrupt processor state - ; and #$10 - ; bne irq_handler_brk + tsx + lda $0104, x ; get the pre-interrupt processor state + and #$10 + bne irq_handler_brk ;; Not caused by BRK - call interrupt routine (only if initialised) lda CINV @@ -34,6 +32,15 @@ irq_handler: irq_handler_brk: + ;; Store BRK adddress, to be displayed + sec + lda $0105, x + sbc #$02 + sta CMP0+0 + lda $0106, x + sbc #$00 + sta CMP0+1 + ;; Interrupt caused by BRK jmp (CBINV) diff --git a/c64/kernal/lvs_helpers.s b/c64/kernal/lvs_helpers.s index 646a9bbd..d52c1bcf 100644 --- a/c64/kernal/lvs_helpers.s +++ b/c64/kernal/lvs_helpers.s @@ -51,10 +51,13 @@ lvs_handle_byte_load_verify: lvs_advance_pointer: ;; Advance pointer inc STAL - bne lvs_success_end + beq + + jmp lvs_success_end +* inc STAL+1 ;; If we wrap around to $0000, then this is bad. - beq lvs_error_end + bne + + jmp lvs_error_end * clc rts @@ -146,7 +149,7 @@ lvs_illegal_device_number: lvs_load_verify_error: ;; XXX should we really return BASIC error code here? lda VERCK - beq lvs_verify_error + bne lvs_verify_error lda #B_ERR_LOAD bne lvs_error_end ;; FALLTHROUGH diff --git a/c64/kernal/plot.s b/c64/kernal/plot.s index 439b1828..3739b362 100644 --- a/c64/kernal/plot.s +++ b/c64/kernal/plot.s @@ -9,4 +9,19 @@ ;; plot: + bcs plot_get + +plot_set: + sty current_screen_y + stx current_screen_x + + ;; Our implementation has different screen editor, updating any + ;; other variables (see [CM64]) seems to be unnecessary + + ;; FALLTROUGH to save one byte on RTS + +plot_get: + ldy current_screen_y + ldx current_screen_x rts + diff --git a/c64/kernal/rdtim.s b/c64/kernal/rdtim.s index a9e40a16..41ad0b94 100644 --- a/c64/kernal/rdtim.s +++ b/c64/kernal/rdtim.s @@ -9,4 +9,19 @@ ;; rdtim: + + ;; Disable interrupts for the duration of the routine, to prevent + ;; jiffy clock update while reeading it's values + sei + + ;; Store the jiffy clock state + ldy TIME + 0 + ldx TIME + 1 + lda TIME + 2 + + ;; Enable interrupts. More elegant solution would be pha + sei + ... + pla, + ;; but (checked by running a test program) original ROM routine always + ;; leaves IRQs enabled. + cli rts + diff --git a/c64/kernal/reset_entry.s b/c64/kernal/reset_entry.s index 8a6ccabc..7fb0b6a7 100644 --- a/c64/kernal/reset_entry.s +++ b/c64/kernal/reset_entry.s @@ -13,14 +13,8 @@ reset_entry: ; The following routine is based on reading the public KERNAL jumptable routine ; list, and making unimaginative assumptions about what should be done on reset. - - ; According to example here: https://codebase64.org/doku.php?id=base:assembling_your_own_cart_rom_image - ; the cartridge does not call RAMTAS - despite it's obviously required. So, call RAMTAS - ; before the cartridge check/takeover - - ; Setting up the screen and testing ram is obviously required - ; also affirmed by p269 of c64 prg - jsr RAMTAS + ; Also, https://codebase64.org/doku.php?id=base:assembling_your_own_cart_rom_image was used + ; as it shows example startup sequence, to be followe by cartridge creators ; C64 PRG p269 jsr cartridge_check @@ -28,16 +22,18 @@ reset_entry: jmp (ICART_COLD_START) * ; Initialising IO is obviously required. Also indicated by c64 prg p269. - ; Has to be after ther RAMTAS, as it clears memory, including the PAL/NTSC flag, - ; which is set by IOINIT - jsr IOINIT + jsr JIOINIT + + ; Setting up the screen and testing ram is obviously required + ; also affirmed by p269 of c64 prg + jsr JRAMTAS ; called RANTAM on Codebase64 wiki ; Resetting IO vectors is obviously required, if we want interrupts to run ; also affirmed by c64 prg p269 - jsr RESTOR + jsr JRESTOR ;; "Compute's Mapping the 64" p236 - jsr CINT + jsr JCINT ; What do we do when finished? A C64 jumps into the BASIC ROM cli ; Allow interrupts to happen diff --git a/c64/kernal/scnkey.s b/c64/kernal/scnkey.s index d5a6bb1b..87e52bfc 100644 --- a/c64/kernal/scnkey.s +++ b/c64/kernal/scnkey.s @@ -204,10 +204,6 @@ ReturnNoKeys: NoActivityDetected: - ;; Cancel STKEY status - lda #$FF - sta STKEY ; XXX this variable should be set by UDTIM - ;; So cancel all bucky keys lda key_bucky_state sta key_last_bucky_state @@ -326,20 +322,15 @@ next_row: stx $dc00 ;// Disconnect all Keyboard Rows cpx $dc01 ;// Only Control Port activity will be detected - bne ReturnNoKeys - + beq + + jmp ReturnNoKeys +* ;; Make X = $00, assumed below inx ;; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;; // Check and flag Non Alphanumeric Keys - ;; Store last row of keyboard scan result, - ;; so that RUN/STOP etc can be checked easily - ;; (Compute's Mapping the 64, p27) - lda ScanResult+0 - sta STKEY ; XXX this variable should be set by UDTIM - ;; Store de-bounce data for bucky keys ;; (Compute's Mapping the 64, p58-59) lda key_bucky_state @@ -472,7 +463,9 @@ RecordKeypress: ;; // New Key Detected ldy BufferQuantity cpy #MaxKeyRollover - bcs TooManyNewKeys + bcc + + jmp TooManyNewKeys +* AcceptKeyEvent: sta Buffer,y iny diff --git a/c64/kernal/settim.s b/c64/kernal/settim.s index 804538c1..7cfb3f11 100644 --- a/c64/kernal/settim.s +++ b/c64/kernal/settim.s @@ -9,4 +9,19 @@ ;; settim: + + ;; Disable interrupts for the duration of the routine, to prevent + ;; jiffy clock update while changing it's values + sei + + ;; Store the jiffy clock state + sty TIME + 0 + stx TIME + 1 + sta TIME + 2 + + ;; Enable interrupts. More elegant solution would be pha + sei + ... + pla, + ;; but (checked by running a test program) original ROM routine always + ;; leaves IRQs enabled. + cli rts + diff --git a/c64/kernal/udtim.s b/c64/kernal/udtim.s index b502112f..28af8cc4 100644 --- a/c64/kernal/udtim.s +++ b/c64/kernal/udtim.s @@ -9,4 +9,46 @@ ;; udtim: + + ;; Update jiffy clock. The whole day is $4F1A00 jiffies (24 hours * 60 minutes * 60 seconds * 60 jiffies), + ;; after this time we have to reset the clock. + + inc TIME+0 + bne udtim_clock_done + inc TIME+1 + bne udtim_clock_rollover + inc TIME+2 + + ;; FALLTROUGH + +udtim_clock_done: +udtim_update_stkey: ; entry to be used when interrupts are disabled + + ;; Another action we have to perform is to copy the last row of keyboard to RAM, + ;; so that various routines can detect the STOP key press + ;; XXX scnkey contains similar sequence - deduplicate this! + lda #$FF + sta CIA1_DDRA ; output + lda #$00 + sta CIA1_DDRB ; input + + lda #$7F + sta CIA1_PRA ; select the last row (bit to 0) + + lda CIA1_PRB ; read the row + sta STKEY rts + +udtim_clock_rollover: + + ;; At this point TIME+0 has to contain 0, + lda TIME+1 + cmp #$1A + bne udtim_clock_done + lda TIME+2 + cmp #$4F + bne udtim_clock_done + lda #$00 + sta TIME+2 + sta TIME+1 + beq udtim_clock_done ; will always jump diff --git a/src/compress_text.c b/src/compress_text.c index 57c02f19..576d4d09 100644 --- a/src/compress_text.c +++ b/src/compress_text.c @@ -161,7 +161,7 @@ char *error_list[]={ "READY.\r", // #29 // https://www.ibm.com/support/knowledgecenter/zosbasics/com.ibm.zos.zconcepts/zconc_whatistsonative.htm https://github.com/stefanhaustein/expressionparser "NTSC, ", // #30 "PAL, ", // #31 - "", // unused for now + "BRK AT $", // #32 "ERROR", // #33 // Simply the word error that is attached to the other parts of messages https://fjkraan.home.xs4all.nl/comp/apple2faq/app2asoftfaq.html "BYTES FREE\r\r", // #34 // https://github.com/stefanhaustein/expressionparser "MEMORY CORRUPT", // #35 diff --git a/strings/00DD29DF b/strings/00DD29DF new file mode 100644 index 00000000..fd7ade84 --- /dev/null +++ b/strings/00DD29DF @@ -0,0 +1,3 @@ +$DD00 + AND #$DF + +Instruction and a half (well known hardware register address) - not copyrightable. diff --git a/strings/00DD29DF8D00DD60 b/strings/00DD29DF8D00DD60 new file mode 100644 index 00000000..e8fcd0b0 --- /dev/null +++ b/strings/00DD29DF8D00DD60 @@ -0,0 +1,5 @@ +$DD00 + AND #$DF + STA $DD00 + RTS + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. diff --git a/strings/2006EEA5 b/strings/2006EEA5 new file mode 100644 index 00000000..4b53a2e3 --- /dev/null +++ b/strings/2006EEA5 @@ -0,0 +1,3 @@ +JSR $EE06 + LDA (argument does not match) + +Instruction and a half - not copyrightable. diff --git a/strings/4C15FD4C1AFD4C b/strings/4C15FD4C1AFD4C new file mode 100644 index 00000000..93764d3f --- /dev/null +++ b/strings/4C15FD4C1AFD4C @@ -0,0 +1 @@ +This is a part of Kernal jumptable - series of jumps, sometimes to the well known addreses (or through documented vectors). No business logic, part of the Kernal API itself (has to be as it is to maintain compatibility) - not copyrightable. diff --git a/strings/4C5BFF4CA3FD4C b/strings/4C5BFF4CA3FD4C new file mode 100644 index 00000000..93764d3f --- /dev/null +++ b/strings/4C5BFF4CA3FD4C @@ -0,0 +1 @@ +This is a part of Kernal jumptable - series of jumps, sometimes to the well known addreses (or through documented vectors). No business logic, part of the Kernal API itself (has to be as it is to maintain compatibility) - not copyrightable. diff --git a/strings/6031EA66FE47FE4AF391F20EF250F233F357F1CAF1EDF63EF12FF366FEA5F4EDF5 b/strings/6031EA66FE47FE4AF391F20EF250F233F357F1CAF1EDF63EF12FF366FEA5F4EDF5A900 similarity index 93% rename from strings/6031EA66FE47FE4AF391F20EF250F233F357F1CAF1EDF63EF12FF366FEA5F4EDF5 rename to strings/6031EA66FE47FE4AF391F20EF250F233F357F1CAF1EDF63EF12FF366FEA5F4EDF5A900 index b12c656e..8cd90eb1 100644 --- a/strings/6031EA66FE47FE4AF391F20EF250F233F357F1CAF1EDF63EF12FF366FEA5F4EDF5 +++ b/strings/6031EA66FE47FE4AF391F20EF250F233F357F1CAF1EDF63EF12FF366FEA5F4EDF5A900 @@ -1,4 +1,4 @@ -RTS (from previous routine) + a list of vectors to be copied starting from $0314 +RTS (from previous routine) + a list of vectors to be copied starting from $0314 + LDA #$00 Values of the vectors are already present in many autostart software - as it often overrides them, sometimes changing one to trigger autostart (one of the possible techniques). We have to use the same diff --git a/strings/6C28036C2A036C2C034C b/strings/6C28036C2A036C2C034C index fcfe7208..93764d3f 100644 --- a/strings/6C28036C2A036C2C034C +++ b/strings/6C28036C2A036C2C034C @@ -1 +1 @@ -This is a part of Kernal jumptable - series of jumps, sometimes to the well known addreses (or through documented vectors). No business logic, part of the Kernal API itself - not copyrightable. +This is a part of Kernal jumptable - series of jumps, sometimes to the well known addreses (or through documented vectors). No business logic, part of the Kernal API itself (has to be as it is to maintain compatibility) - not copyrightable. diff --git a/strings/7F8D0DDC b/strings/7F8D0DDC new file mode 100644 index 00000000..d0c43352 --- /dev/null +++ b/strings/7F8D0DDC @@ -0,0 +1,3 @@ +$7F + STA $DC0D + +Instruction (access to a docummented hardware register) and some part - not copyrightable. diff --git a/strings/9848BABD04012910 b/strings/9848BABD04012910 new file mode 100644 index 00000000..d0775e65 --- /dev/null +++ b/strings/9848BABD04012910 @@ -0,0 +1,3 @@ +TYA + PHA + TSX + LDA $0104,X + AND #$10 + +Beginning of IRQ handler - checks whether it is caused by BRK instruction or some other reason. Since IRQ handling for BRK/non-BRK caused interrupts are totally different, there is no other way but to start with such a check. Not creative - not copyrightable. diff --git a/strings/A59D10FB b/strings/A59D10FB new file mode 100644 index 00000000..90699c4e --- /dev/null +++ b/strings/A59D10FB @@ -0,0 +1,3 @@ +LDA $9D + BPL (address match) + +Checking a well-known zeropage flag - not creative, not copyrightable. diff --git a/strings/A97F8D00DCAD01DC b/strings/A97F8D00DCAD01DC new file mode 100644 index 00000000..9a2265bf --- /dev/null +++ b/strings/A97F8D00DCAD01DC @@ -0,0 +1,3 @@ +LDA #$7F + STA $DC00 + LDA $DC01 + +Part of keyboard scanning code in UDTIM routine - to get the last row (not even complete code, as there is also some code to set the port directions). This is probably the only sane way to read the rom. Not creative - not copyrightable. diff --git a/strings/D006E6A1D0 b/strings/D006E6A1D0 new file mode 100644 index 00000000..9856932f --- /dev/null +++ b/strings/D006E6A1D0 @@ -0,0 +1,3 @@ +BNE (offset match) + INC $A1 + BNE (offset does not match) + +Part of the routine to increment a well-known 24-bit counter. There are not many ways to do this in a sane way, some similarity is unavoidable, 2 instructions and a half is not much in this case. Not copyrightable. diff --git a/strings/DD09088D00DD b/strings/DD09088D00DD new file mode 100644 index 00000000..33ed075b --- /dev/null +++ b/strings/DD09088D00DD @@ -0,0 +1,5 @@ +$DD + ORA #$08 + STA $DD00 + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. diff --git a/strings/DD60AD00DD0910 b/strings/DD60AD00DD0910 new file mode 100644 index 00000000..5167b1a0 --- /dev/null +++ b/strings/DD60AD00DD0910 @@ -0,0 +1,5 @@ +$DD + RTS + LDA $DD00 + ORA #$10 + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. diff --git a/strings/DF8D00DD60AD00DD09 b/strings/DF8D00DD60AD00DD09 new file mode 100644 index 00000000..077c308b --- /dev/null +++ b/strings/DF8D00DD60AD00DD09 @@ -0,0 +1,5 @@ +$DF + STA $DD00 + RTS + LDA $DD00 + ORA (argument does not match) + +$DD00 is a hardware register, where one typically set/unset/read individual bits. +Having a set of trivial helper subroutines to set/clear individual bits (or groups of bits) is an obvious solution (thus not copyrightable), some similarities are unevitable. +Besides, in this case (since the similarity does not even cover a single subroutine from start to end) it is clear that the similar code actually performs slightly different actions. diff --git a/strings/EEAD00DD b/strings/EEAD00DD new file mode 100644 index 00000000..14560bce --- /dev/null +++ b/strings/EEAD00DD @@ -0,0 +1,3 @@ +$EE + LDA $DD00 + +Instruction (access to a well known hardware register address) and a half - not copyrightable. diff --git a/strings/F66C28036C2A036C2C034C b/strings/F66C28036C2A036C2C034C new file mode 100644 index 00000000..93764d3f --- /dev/null +++ b/strings/F66C28036C2A036C2C034C @@ -0,0 +1 @@ +This is a part of Kernal jumptable - series of jumps, sometimes to the well known addreses (or through documented vectors). No business logic, part of the Kernal API itself (has to be as it is to maintain compatibility) - not copyrightable. diff --git a/strings/FF586C00A0 b/strings/FF586C00A0 new file mode 100644 index 00000000..e69471c4 --- /dev/null +++ b/strings/FF586C00A0 @@ -0,0 +1,3 @@ +$FF + CLI + JMP ($A000) + +Part of the address, reenabling interrupts, jump through a documented vector - part of the initialization/reset sequence. Not creative - not copyrightable.