Merge pull request #30 from FeralChild64/master

IEC fixes, BRK handling, other small improvements
This commit is contained in:
gardners authored and GitHub committed 2019-09-03 07:50:17 +09:30
commit 2f2476f43e
55 files changed
+406 -262

No files matched your search

+8 -9
View File
@@ -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 | |
<br />
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -5
View File
@@ -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
+3 -2
View File
@@ -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 #<basic_current_statement_ptr
+18 -2
View File
@@ -2,6 +2,22 @@
basic_warm_start:
jsr install_ram_routines
;; If warm start caused by BRK, print it address
lda CMP0
ora CMP0+1
beq +
ldx #32
jsr print_packed_message
lda CMP0+1
jsr printf_printhexbyte
lda CMP0+0
jsr printf_printhexbyte
lda #$0D
jsr JCHROUT
*
jmp basic_main_loop
+3 -1
View File
@@ -66,7 +66,9 @@ got_filename:
jsr basic_parse_line_number
lda basic_line_number+1
bne do_ILLEGAL_QUANTITY_error
beq +
jmp do_ILLEGAL_QUANTITY_error
*
lda basic_line_number+0
sta current_device_number
+17 -9
View File
@@ -17,11 +17,13 @@ wedge_dos:
;; Check if user asked for a status
ldy #$00
lda (basic_current_statement_ptr), y
beq wedge_dos_status
bne +
jmp wedge_dos_status ; XXX try to optimize this, perhaps move 'wedge_dos_status' above?
*
;; Check if asked for a directory
cmp #$24
beq wedge_dos_directory
bne +
jmp wedge_dos_directory
*
;; Check if asked to change drive number, or if it is a regular command
cmp #$30
@@ -42,8 +44,9 @@ wedge_dos_command:
jsr JSETNAM
jsr JOPEN
bcs wedge_dos_basic_error
bcc +
jmp wedge_dos_basic_error ; XXX combine with other such jumps
*
;; Retrieve status, print it if not OK
jsr JCLALL
jsr wedge_dos_status_get
@@ -83,12 +86,16 @@ wedge_dos_status_get:
lda #$00 ; empty file name
jsr JSETNAM
jsr JOPEN
bcs wedge_dos_basic_error
bcc +
jmp wedge_dos_basic_error ; XXX combine with other such jumps
*
;; Set channel for input
ldx #$0F
jsr JCHKIN
bcs wedge_dos_basic_error
bcc +
jmp wedge_dos_basic_error ; XXX combine with other such jumps
*
ldy #$00
*
@@ -99,7 +106,9 @@ wedge_dos_status_get:
;; Print out everything retrieved from the drive
bne +
jsr JCHRIN
bcs wedge_dos_basic_error
bcc wedge_dos_x1
jmp wedge_dos_basic_error ; XXX try to optimize this
wedge_dos_x1:
sta BUF, y
iny
jmp -
@@ -129,7 +138,6 @@ wedge_dos_directory:
;; First change the secondary address to the one suitable for
;; directory loading
;; XXX
lda #$00 ; logical device number
ldx current_device_number
ldy #$60
+3 -2
View File
@@ -448,8 +448,9 @@ screen_grow_logical_line:
ldy current_screen_y
;; Don't grow line if it is already grown
lda screen_line_link_table,y
bmi done_grow_line
bpl +
jmp done_grow_line
*
lda #$80
sta screen_line_link_table,y
+46 -5
View File
@@ -9,16 +9,57 @@
;;
cint:
cint_real:
;; According to [CM64], this routine checks for PAL/NTSC. It's definitely not done
;; within the 'BRK' part, this can be easily checked - POKE something
;; to address 678 on a real C64, press STOP+RESTORE, the value won't change
;; 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
lda #$C8 ; preparation, as the VIC might be uninitialized
sta VIC_SCROLX
cint_w0:
lda VIC_RASTER
cint_w1:
cmp VIC_RASTER
beq cint_w1
bmi cint_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 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
+1 -1
View File
@@ -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
+36 -22
View File
@@ -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
+4
View File
@@ -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.
File renamed without changes.
+6 -40
View File
@@ -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
+6
View File
@@ -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
+4
View File
@@ -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.
@@ -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
+58 -5
View File
@@ -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
+4 -26
View File
@@ -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
-72
View File
@@ -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
-22
View File
@@ -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
+1
View File
@@ -17,4 +17,5 @@ iec_wait1ms:
lda VIC_RASTER
dex
bne -
rts
@@ -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)
+13 -6
View File
@@ -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)
+6 -3
View File
@@ -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
+15
View File
@@ -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
+15
View File
@@ -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
+9 -13
View File
@@ -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
+6 -13
View File
@@ -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
+15
View File
@@ -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
+42
View File
@@ -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
+1 -1
View File
@@ -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
+3
View File
@@ -0,0 +1,3 @@
$DD00 + AND #$DF
Instruction and a half (well known hardware register address) - not copyrightable.
+5
View File
@@ -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.
+3
View File
@@ -0,0 +1,3 @@
JSR $EE06 + LDA (argument does not match)
Instruction and a half - not copyrightable.
+1
View File
@@ -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.
+1
View File
@@ -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.
@@ -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
+1 -1
View File
@@ -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.
+3
View File
@@ -0,0 +1,3 @@
$7F + STA $DC0D
Instruction (access to a docummented hardware register) and some part - not copyrightable.
+3
View File
@@ -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.
+3
View File
@@ -0,0 +1,3 @@
LDA $9D + BPL (address match)
Checking a well-known zeropage flag - not creative, not copyrightable.
+3
View File
@@ -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.
+3
View File
@@ -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.
+5
View File
@@ -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.
+5
View File
@@ -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.
+5
View File
@@ -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.
+3
View File
@@ -0,0 +1,3 @@
$EE + LDA $DD00
Instruction (access to a well known hardware register address) and a half - not copyrightable.
+1
View File
@@ -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.
+3
View File
@@ -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.