adapted to Kick Assembler, some documentation update

This commit is contained in:
FeralChild64 committed 2019-09-07 12:35:21 +02:00
1 parent ae23dbae7b
commit de27124b4f
198 files changed
+4181 -3976

No files matched your search

+70 -68
View File
@@ -1,73 +1,75 @@
; Names of ZP and low memory locations
; (Only those of relevance for the KERNAL)
; (And only those for now that we feel the need to implement initially)
; (https://www.c64-wiki.com/wiki/Zeropage)
// Names of ZP and low memory locations
// (Only those of relevance for the KERNAL)
// (And only those for now that we feel the need to implement initially)
// (https://www.c64-wiki.com/wiki/Zeropage)
.alias kernal_load_or_verify_flag $93
.alias current_file_num $98
.alias input_device_number DFLTN
.alias cassette_buffer_bytes_used $A6
.alias load_or_scroll_temp_pointer $AC
;; We also use the following for temp colour pointer when scrolling
.alias load_save_verify_end_address $AE
.alias cassette_buffer_ptr $B2
.alias current_logical_filenum $B8
.alias current_secondary_address $B9
.alias current_device_number $BA
.alias current_filename_ptr $BB
.alias load_save_end_ptr $C3
.alias last_key_matrix_position $C5
.alias keys_in_key_buffer $C6
.alias reverse_video_flag $C7
.alias end_of_input_line $C8
.alias start_of_keyboard_input $C9
.alias current_key_index_entry $CB
.alias cursor_blink_disable $CC
.alias cursor_blink_countdown $CD
.alias cursor_saved_character $CE
.alias cursor_is_visible $CF
.alias keyboard_input_ready $D0
.alias current_screen_line_ptr $D1
.alias current_screen_x $D3
.alias quote_mode_flag $D4
.alias logical_line_length $D5
.alias current_screen_y $D6
.alias last_printed_character_ascii $D7
.alias insert_mode $D8
; Bits 0 -3 = bits 8-11 of screen line address
; Bit 7 = line spans multiple physical lines
.alias screen_line_link_table $D9
.alias current_screen_line_colour_ptr $F3
.alias keyboard_decoding_table_ptr $F5
.alias rs232_rx_buffer_ptr $F7
.alias rs232_tx_buffer_ptr $F9
// XXX get rid of this file, use ,aliases_ram_lowmem.s instead
.label kernal_load_or_verify_flag = $93
.label current_file_num = $98
.label input_device_number = DFLTN
.label cassette_buffer_bytes_used = $A6
.label load_or_scroll_temp_pointer = $AC
// We also use the following for temp colour pointer when scrolling
.label load_save_verify_end_address = $AE
.label cassette_buffer_ptr = $B2
.label current_logical_filenum = $B8
.label current_secondary_address = $B9
.label current_device_number = $BA
.label current_filename_ptr = $BB
.label load_save_end_ptr = $C3
.label last_key_matrix_position = $C5
.label keys_in_key_buffer = $C6
.label reverse_video_flag = $C7
.label end_of_input_line = $C8
.label start_of_keyboard_input = $C9
.label current_key_index_entry = $CB
.label cursor_blink_disable = $CC
.label cursor_blink_countdown = $CD
.label cursor_saved_character = $CE
.label cursor_is_visible = $CF
.label keyboard_input_ready = $D0
.label current_screen_line_ptr = $D1
.label current_screen_x = $D3
.label quote_mode_flag = $D4
.label logical_line_length = $D5
.label current_screen_y = $D6
.label last_printed_character_ascii = $D7
.label insert_mode = $D8
// Bits 0 -3 = bits 8-11 of screen line address
// Bit 7 = line spans multiple physical lines
.label screen_line_link_table = $D9
.label current_screen_line_colour_ptr = $F3
.label keyboard_decoding_table_ptr = $F5
.label rs232_rx_buffer_ptr = $F7
.label rs232_tx_buffer_ptr = $F9
; "Compute's Mapping the 64" book
.alias keyboard_buffer $0277
.alias text_colour $0286 ; p55
.alias colour_under_cursor $0287 ; p56
.alias key_buffer_size $0289 ; p57
// "Compute's Mapping the 64" book
.label keyboard_buffer = $0277
.label text_colour = $0286 // p55
.label colour_under_cursor = $0287 // p56
.label key_buffer_size = $0289 // p57
;; 0 = cursor keys, insert, delete and space repeat, but nothing else
;; 128 = all keys repeat
;; 64 = no keys repeat
.alias key_repeat_flags $028A ; p58
;; https://www.c64-wiki.com/wiki/Page_2
.alias key_repeat_counter $028B
.alias key_first_repeat_delay $028C
;; bit 0 = shift, 1 = Vendor Key, 2 = Control
.alias key_bucky_state $028D
.alias key_last_bucky_state $028E
.alias keyboard_decoding_ptr $028F
.alias enable_case_switch $0291
.alias screen_scroll_disable $0292
// 0 = cursor keys, insert, delete and space repeat, but nothing else
// 128 = all keys repeat
// 64 = no keys repeat
.label key_repeat_flags = $028A // p58
// https://www.c64-wiki.com/wiki/Page_2
.label key_repeat_counter = $028B
.label key_first_repeat_delay = $028C
// bit 0 = shift, 1 = Vendor Key, 2 = Control
.label key_bucky_state = $028D
.label key_last_bucky_state = $028E
.label keyboard_decoding_ptr = $028F
.label enable_case_switch = $0291
.label screen_scroll_disable = $0292
;; Under-ROM routines
;; (BASIC also includes them. XXX - We should de-duplicate them in a safe manner)
.alias missed_nmi_flag $2A7
.alias tiny_nmi_handler $2A8
.alias peek_under_roms tiny_nmi_handler+peek_under_roms_routine-tiny_nmi_handler_routine
.alias poke_under_roms tiny_nmi_handler+poke_under_roms_routine-tiny_nmi_handler_routine
.alias memmap_allram tiny_nmi_handler+memmap_allram_routine-tiny_nmi_handler_routine
.alias memmap_normal tiny_nmi_handler+memmap_normal_routine-tiny_nmi_handler_routine
// Under-ROM routines
// (BASIC also includes them. XXX - We should de-duplicate them in a safe manner)
.label missed_nmi_flag = $2A7
.label tiny_nmi_handler = $2A8
.label peek_under_roms = tiny_nmi_handler+peek_under_roms_routine-tiny_nmi_handler_routine
.label poke_under_roms = tiny_nmi_handler+poke_under_roms_routine-tiny_nmi_handler_routine
.label memmap_allram = tiny_nmi_handler+memmap_allram_routine-tiny_nmi_handler_routine
.label memmap_normal = tiny_nmi_handler+memmap_normal_routine-tiny_nmi_handler_routine
+3 -3
View File
@@ -1,6 +1,6 @@
;; Target-specific hooks
// Target-specific hooks
.macro TARGET_HOOK_LOAD
.macend
.macro TARGET_HOOK_LOAD() {
}
+3 -3
View File
@@ -1,6 +1,6 @@
;; Target-specific hooks
// Target-specific hooks
.macro TARGET_HOOK_LOAD
.macend
.macro TARGET_HOOK_LOAD() {
}
@@ -1,57 +1,57 @@
;; Registers according to Ultimate 64 Command Interface description,
;; https://1541u-documentation.readthedocs.io/en/latest/command%20interface.html
;; and ultimate_dos_v1.0.pdf and command_interface_v1.0.pdf by Gideon Zweijtzer
// Registers according to Ultimate 64 Command Interface description,
// https://1541u-documentation.readthedocs.io/en/latest/command%20interface.html
// and ultimate_dos_v1.0.pdf and command_interface_v1.0.pdf by Gideon Zweijtzer
;; Command interface registers
.alias U64_CONTROL $DF1C ; write
.alias U64_STATUS $DF1C ; read
.alias U64_COMMAND_DATA $DF1D ; write
.alias U64_IDENTIFICATION $DF1D ; read
.alias U64_RESPONSE_DATA $DF1E ; read only
.alias U64_STATUS_DATA $DF1F ; read only
// Command interface registers
.label U64_CONTROL = $DF1C // write
.label U64_STATUS = $DF1C // read
.label U64_COMMAND_DATA = $DF1D // write
.label U64_IDENTIFICATION = $DF1D // read
.label U64_RESPONSE_DATA = $DF1E // read only
.label U64_STATUS_DATA = $DF1F // read only
;; Constant for U64_IDENTIFICATION register
.alias U64_MAGIC_ID $C9
// Constant for U64_IDENTIFICATION register
.const U64_MAGIC_ID = $C9
;; Constants for U64_CONTROL register
.alias U64_CTRL_BIT_PUSH_CMD $01
.alias U64_CTRL_BIT_DATA_ACC $02
.alias U64_CTRL_BIT_ABORT $04
.alias U64_CTRL_BIT_CLR_ERR $08
// Constants for U64_CONTROL register
.const U64_CTRL_BIT_PUSH_CMD = $01
.const U64_CTRL_BIT_DATA_ACC = $02
.const U64_CTRL_BIT_ABORT = $04
.const U64_CTRL_BIT_CLR_ERR = $08
;; Constants for U64_STATUS register
.alias U64_STAT_BIT_CMD_BUSY $01
.alias U64_STAT_BIT_DATA_ACC $02
.alias U64_STAT_BIT_ABORT_P $04
.alias U64_STAT_BIT_ERROR $08
.alias U64_STAT_MASK_STATE $30 ; two bits!
.alias U64_STAT_BIT_STAT_AV $40
.alias U64_STAT_BIT_DATA_AV $80
// Constants for U64_STATUS register
.const U64_STAT_BIT_CMD_BUSY = $01
.const U64_STAT_BIT_DATA_ACC = $02
.const U64_STAT_BIT_ABORT_P = $04
.const U64_STAT_BIT_ERROR = $08
.const U64_STAT_MASK_STATE = $30 // two bits!
.const U64_STAT_BIT_STAT_AV = $40
.const U64_STAT_BIT_DATA_AV = $80
;; Interface targets
.alias U64_TARGET_DOS1 $01
.alias U64_TARGET_DOS2 $02
// Interface targets
.const U64_TARGET_DOS1 = $01
.const U64_TARGET_DOS2 = $02
;; DOS command codes
.alias U64_DOS_CMD_IDENTIFY $01
.alias U64_DOS_CMD_OPEN_FILE $02
.alias U64_DOS_CMD_CLOSE_FILE $03
.alias U64_DOS_CMD_READ_DATA $04
.alias U64_DOS_CMD_WRITE_DATA $05
.alias U64_DOS_CMD_FILE_SEEK $06
.alias U64_DOS_CMD_FILE_INFO $07
.alias U64_DOS_CMD_CHANGE_DIR $11
.alias U64_DOS_CMD_GET_PATH $12
.alias U64_DOS_CMD_OPEN_DIR $13
.alias U64_DOS_CMD_READ_DIR $14
.alias U64_DOS_CMD_COPY_UI_PATH $15
.alias U64_DOS_CMD_LOAD_REU $21
.alias U64_DOS_CMD_SAVE_REU $22
.alias U64_DOS_CMD_ECHO $F0
// DOS command codes
.const U64_DOS_CMD_IDENTIFY = $01
.const U64_DOS_CMD_OPEN_FILE = $02
.const U64_DOS_CMD_CLOSE_FILE = $03
.const U64_DOS_CMD_READ_DATA = $04
.const U64_DOS_CMD_WRITE_DATA = $05
.const U64_DOS_CMD_FILE_SEEK = $06
.const U64_DOS_CMD_FILE_INFO = $07
.const U64_DOS_CMD_CHANGE_DIR = $11
.const U64_DOS_CMD_GET_PATH = $12
.const U64_DOS_CMD_OPEN_DIR = $13
.const U64_DOS_CMD_READ_DIR = $14
.const U64_DOS_CMD_COPY_UI_PATH = $15
.const U64_DOS_CMD_LOAD_REU = $21
.const U64_DOS_CMD_SAVE_REU = $22
.const U64_DOS_CMD_ECHO = $F0
;; DOS file opening constants
.alias U64_FA_READ $01
.alias U64_FA_WRITE $02
.alias U64_FA_CREATE_NEW $03
.alias U64_FA_CREATE_ALWAYS $04
// DOS file opening constants
.const U64_FA_READ = $01
.const U64_FA_WRITE = $02
.const U64_FA_CREATE_NEW = $03
.const U64_FA_CREATE_ALWAYS = $04
@@ -1,9 +1,9 @@
;; Target-specific hooks
// Target-specific hooks
.macro TARGET_HOOK_LOAD
;; XXX disabled for now - the current file opening API is not
;; really suitable for easy usage from Kernal
;; jsr u64_load
.macend
.macro TARGET_HOOK_LOAD() {
// XXX disabled for now - the current file opening API is not
// really suitable for easy usage from Kernal
// jsr u64_load
}
@@ -1,52 +1,53 @@
;;
;; LOAD routine hook for fast loading via UltiDOS
;;
//
// LOAD routine hook for fast loading via UltiDOS
//
u64_load:
;; First check whether the command interface is enabled
// First check whether the command interface is enabled
lda U64_IDENTIFICATION
cmp #U64_MAGIC_ID
beq +
beq !+
u64_load_skip:
rts
*
;; XXX find out which device number softIEC is mapped to
!:
// XXX find out which device number softIEC is mapped to
lda current_device_number
cmp #$20 ; for now use device number 32
cmp #$20 // for now use device number 32
bne u64_load_skip
;; Takeover the flow completely
// Takeover the flow completely
pla
pla
;; Display SEARCHING FOR + filename
// Display SEARCHING FOR + filename
jsr lvs_display_searching_for
;; Whatever the interface was doing - ask to abort it
// Whatever the interface was doing - ask to abort it
jsr u64_load_abort
;; Send a command to open the file
// Send a command to open the file
lda #U64_DOS_CMD_OPEN_FILE
jsr u64_load_send_cmd
lda #U64_FA_READ
jsr u64_load_send_cmd
jsr u64_load_send_filename
jsr u64_load_finalize_cmd
;; Check status
// Check status
jsr u64_load_check_status
bcs lvs_file_not_found_error
;; Load first two bytes to determine start address
// Load first two bytes to determine start address
// XXX
;; XXX
jsr printf
.byte "DBG: NOT IMPLEMENTED",$0D,0
.text "DBG: NOT IMPLEMENTED"
.byte $0D,0
jmp lvs_wrap_around_error
rts
@@ -54,77 +55,77 @@ u64_load_skip:
u64_load_abort:
lda #U64_CTRL_BIT_ABORT
sta U64_CONTROL
*
!:
lda U64_STATUS
bne -
bne !-
rts
u64_load_send_cmd:
ldx #U64_TARGET_DOS2
stx U64_COMMAND_DATA ; target
sta U64_COMMAND_DATA ; command code
stx U64_COMMAND_DATA // target
sta U64_COMMAND_DATA // command code
rts
u64_load_send_filename:
ldy #0
u64_load_send_filename_loop:
cpy FNLEN
bne+
bne !+
rts
*
!:
ldx #<current_filename_ptr
jsr peek_under_roms
iny
sta U64_COMMAND_DATA
jmp u64_load_send_filename_loop
u64_load_finalize_cmd:
;; Push the command for execution
// Push the command for execution
lda #U64_CTRL_BIT_PUSH_CMD
sta U64_CONTROL
;; Wait till it is complete
*
// Wait till it is complete
!:
lda U64_STATUS
and #U64_STAT_BIT_CMD_BUSY
bne -
bne !-
rts
u64_load_check_status:
;; Wait till status is available
// Wait till status is available
lda U64_STATUS
and #U64_STAT_BIT_STAT_AV
beq u64_load_check_status
;; Status is ready - check the first character
// Status is ready - check the first character
lda U64_STATUS_DATA
jsr JCHROUT ; XXX for test only
cmp #$30 ; '0'
jsr JCHROUT // XXX for test only
cmp #$30 // '0'
bne u64_load_check_status_wrong
;; Check the second status character
// Check the second status character
lda U64_STATUS
and #U64_STAT_BIT_STAT_AV
beq u64_load_check_status_ok
lda U64_STATUS_DATA
jsr JCHROUT ; XXX for test only
cmp #$30 ; '0'
jsr JCHROUT // XXX for test only
cmp #$30 // '0'
beq u64_load_check_status_ok
;; FALLTROUGH
// FALLTROUGH
u64_load_check_status_wrong:
sec
bcs +
bcs !+
u64_load_check_status_ok:
clc
*
;; Now empty the status queue
!:
// Now empty the status queue
lda U64_STATUS
and #U64_STAT_BIT_STAT_AV
beq +
beq !+
lda U64_STATUS_DATA
jsr JCHROUT ; XXX for test only
jmp -
*
jsr JCHROUT // XXX for test only
jmp !-
!:
rts
+9 -10
View File
@@ -1,15 +1,14 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 274
;; - [CM64] Compute's Mapping the Commodore 64 - page 224/225
;;
;; CPU registers that has to be preserved (see [RG64]): .Y
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 274
// - [CM64] Compute's Mapping the Commodore 64 - page 224/225
//
// CPU registers that has to be preserved (see [RG64]): .Y
//
acptr:
ACPTR:
jsr kernalstatus_reset
jmp iec_rx_byte
+20 -20
View File
@@ -1,41 +1,41 @@
;; We have the following variables:
;; cursor_blink_disable
;; cursor_blink_countdown
;; cursor_saved_character
;; cursor_is_visible
;; colour_under_cursor
// We have the following variables:
// cursor_blink_disable
// cursor_blink_countdown
// cursor_saved_character
// cursor_is_visible
// colour_under_cursor
show_cursor_if_enabled:
lda cursor_blink_disable
beq +
beq !+
rts
* lda cursor_is_visible
!: lda cursor_is_visible
beq show_cursor
rts
show_cursor:
;; Set cursor as though it had just finished the off phase,
;; so that the call to blink_cursor paints it
// Set cursor as though it had just finished the off phase,
// so that the call to blink_cursor paints it
lda #$00
sta cursor_blink_countdown
sta cursor_is_visible
jsr blink_cursor
;; Then set the timeout to 1 frame, so that the cursor
;; blinks under key repeat conditions, like on the original KERNAL
// Then set the timeout to 1 frame, so that the cursor
// blinks under key repeat conditions, like on the original KERNAL
lda #$01
sta cursor_blink_countdown
rts
blink_cursor:
;; Is the cursor enabled?
// Is the cursor enabled?
lda cursor_blink_disable
bne no_blink_cursor
;; Do we need to redraw things?
// Do we need to redraw things?
dec cursor_blink_countdown
bpl no_blink_cursor
;; Check if cursor was visible or not, and toggle
// Check if cursor was visible or not, and toggle
lda cursor_is_visible
bne undraw_cursor
draw_cursor:
@@ -46,7 +46,7 @@ draw_cursor:
sta cursor_saved_character
eor #$80
sta (current_screen_line_ptr),y
;; Also set cursor colour
// Also set cursor colour
lda (current_screen_line_colour_ptr),y
sta colour_under_cursor
lda text_colour
@@ -68,10 +68,10 @@ undraw_cursor:
lda #0
sta cursor_is_visible
;; Fall through
// Fall through
reset_blink_timer:
;; Rest blink counter
;; (Compute's Mapping the 64, p39-40)
// Rest blink counter
// (Compute's Mapping the 64, p39-40)
lda #20
sta cursor_blink_countdown
no_blink_cursor:
@@ -80,7 +80,7 @@ no_blink_cursor:
disable_cursor:
lda #$80
sta cursor_blink_disable
;; FALL THROUGH
// FALL THROUGH
hide_cursor_if_visible:
lda cursor_is_visible
bne undraw_cursor
+1 -1
View File
@@ -1,4 +1,4 @@
; c64 prg p263
// c64 prg p263
cartridge_check:
ldx #$04
+37 -37
View File
@@ -1,64 +1,64 @@
;;
;; Official Kernal routines, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 275 (CHKIN) / 276 (CKOUT)
;; - [CM64] Compute's Mapping the Commodore 64 - page 229
;;
;; CPU registers that has to be preserved (see [RG64]): .Y
;;
//
// Official Kernal routines, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 275 (CHKIN) / 276 (CKOUT)
// - [CM64] Compute's Mapping the Commodore 64 - page 229
//
// CPU registers that has to be preserved (see [RG64]): .Y
//
;; CHKIN implementation
// CHKIN implementation
chkin_real:
;; Store Y for preservation
// Store Y for preservation
tya
pha
;; Reset status
// Reset status
jsr kernalstatus_reset
;; First retrieve the FAT/LAT/SAT table index (and check if file is open)
// First retrieve the FAT/LAT/SAT table index (and check if file is open)
txa
jsr find_fls
bcs chkinout_file_not_open
;; Now we have table index in Y - first filter out unsuitable devices
// Now we have table index in Y - first filter out unsuitable devices
lda FAT,Y
cmp #$01
beq chkinout_device_not_present ; tape not implemented
beq chkinout_device_not_present // tape not implemented
cmp #$02
beq chkinout_device_not_present ; RS-232 not implemented
beq chkinout_device_not_present // RS-232 not implemented
;; Fail if the file is open for writing (secondary address 1)
// Fail if the file is open for writing (secondary address 1)
lda LAT, Y
cmp #$01
beq chkinout_file_not_input
;; For IEC devices, send TALK + TKSA first
// For IEC devices, send TALK + TKSA first
lda FAT,Y
jsr iec_check_devnum
bcs chkin_set_device
jsr talk
bcs chkinout_device_not_present ; don't set DFLTN in case of failure
jsr TALK
bcs chkinout_device_not_present // don't set DFLTN in case of failure
lda LAT, Y
jsr tksa
jsr TKSA
bcs chkinout_device_not_present
chkin_set_device:
lda FAT,Y
sta DFLTN
clc ; for success
;; FALLTROUGH
clc // for success
// FALLTROUGH
;; Common part for booth CHKIN and CKOUT
// Common part for booth CHKIN and CKOUT
chkinout_end:
tax
@@ -88,54 +88,54 @@ chkinout_file_not_output:
tay
jmp kernalerror_FILE_NOT_OUTPUT
;; CKOUT implementation
// CKOUT implementation
ckout_real:
;; Store Y for preservation
// Store Y for preservation
tya
pha
;; Reset status
// Reset status
jsr kernalstatus_reset
;; First retrieve the FAT/LAT/SAT table index (and check if file is open)
// First retrieve the FAT/LAT/SAT table index (and check if file is open)
txa
jsr find_fls
bcs chkinout_file_not_open
;; Now we have table index in Y - first filter out unsuitable devices
// Now we have table index in Y - first filter out unsuitable devices
lda FAT,Y
cmp #$01
beq chkinout_device_not_present ; tape not implemented
beq chkinout_device_not_present // tape not implemented
cmp #$02
beq chkinout_device_not_present ; RS-232 not implemented
beq chkinout_device_not_present // RS-232 not implemented
cmp #$00
beq chkinout_file_not_output ; cannot output to keyboard - XXX check real ROM behaviour
beq chkinout_file_not_output // cannot output to keyboard - XXX check real ROM behaviour
;; Fail if the file is open for reading (secondary address 0)
// Fail if the file is open for reading (secondary address 0)
lda LAT, Y
beq chkinout_file_not_output
;; For IEC devices, send LISTEN + SECOND first
// For IEC devices, send LISTEN + SECOND first
lda FAT,Y
jsr iec_check_devnum
bcs chkout_set_device
jsr listen
bcs chkinout_device_not_present ; don't set DFLTO in case of failure
jsr LISTEN
bcs chkinout_device_not_present // don't set DFLTO in case of failure
lda LAT, Y
jsr second
jsr SECOND
bcs chkinout_device_not_present
chkout_set_device:
lda FAT,Y
sta DFLTO
clc ; for success
clc // for success
jmp chkinout_end
+60 -60
View File
@@ -1,67 +1,67 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 277/278
;; - [CM64] Compute's Mapping the Commodore 64 - page 228
;;
;; CPU registers that has to be preserved (see [RG64]): .Y
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 277/278
// - [CM64] Compute's Mapping the Commodore 64 - page 228
//
// CPU registers that has to be preserved (see [RG64]): .Y
//
;; XXX keyboard part currently does not preserve register Y, to be fixed!
// XXX keyboard part currently does not preserve register Y, to be fixed!
;; Reads a byte of input, unless from keyboard.
;; If from keyboard, then it gets a whole line of input, and returns the first char.
;; Repeated calls after that read out the successive bytes of the line of input.
// Reads a byte of input, unless from keyboard.
// If from keyboard, then it gets a whole line of input, and returns the first char.
// Repeated calls after that read out the successive bytes of the line of input.
chrin_real:
;; Determine the device number
// Determine the device number
lda DFLTN
beq chrin_keyboard ; #$00 - keyboard
;; XXX add screen support
beq chrin_keyboard // #$00 - keyboard
// XXX add screen support
jsr iec_check_devnum
bcc chrin_iec
jmp lvs_device_not_found_error ; not a supported device
jmp lvs_device_not_found_error // not a supported device
chrin_iec:
jsr JACPTR
bcs chrin_done_fail
;; FALLTROUGH
// FALLTROUGH
chrin_done:
clc ; indicate success
clc // indicate success
rts
chrin_done_fail:
sec ; indicate failure
sec // indicate failure
rts
chrin_keyboard:
;; Save X
// Save X
txa
pha
chrin_repeat:
;; Do we have a line of input we are currently returning?
;; If so, return the next byte, and clear the flag when we reach the end.
// Do we have a line of input we are currently returning?
// If so, return the next byte, and clear the flag when we reach the end.
;; Do we have a line of input waiting?
// Do we have a line of input waiting?
lda keyboard_input_ready
beq read_from_keyboard
;; Yes, we have input waiting at (start_of_keyboard_input)+keyboard_input_ready
;; When keyboard_input_ready = end_of_input_line, then we return a carriage return
;; and clear the flag
// Yes, we have input waiting at (start_of_keyboard_input)+keyboard_input_ready
// When keyboard_input_ready = end_of_input_line, then we return a carriage return
// and clear the flag
cmp end_of_input_line
bne not_end_of_input
;; Return carriage return and clear pending input flag
// Return carriage return and clear pending input flag
lda #$00
sta keyboard_input_ready
pla
@@ -71,7 +71,7 @@ chrin_repeat:
rts
not_end_of_input:
;; Return next byte of waiting input and advance index
// Return next byte of waiting input and advance index
tay
pla
tax
@@ -80,13 +80,13 @@ not_end_of_input:
inc keyboard_input_ready
clc
rts
read_from_keyboard:
read_from_keyboard:
jsr enable_cursor
;; Wait for a key
// Wait for a key
lda keys_in_key_buffer
beq chrin_repeat
@@ -100,31 +100,31 @@ read_from_keyboard:
jsr hide_cursor_if_visible
;; It was enter.
;; Note that we have a line of input to return, and return the first byte thereof
;; after computing and storing its length.
;; (Compute's Mapping the 64, p96)
// It was enter.
// Note that we have a line of input to return, and return the first byte thereof
// after computing and storing its length.
// (Compute's Mapping the 64, p96)
;; Set pointer to line of input
// Set pointer to line of input
lda current_screen_line_ptr+0
sta start_of_keyboard_input+0
lda current_screen_line_ptr+1
sta start_of_keyboard_input+1
;; Calculate length
// Calculate length
jsr get_current_line_logical_length
tay
iny
* dey
!: dey
bmi empty_line
lda (current_screen_line_ptr),y
cmp #$20
beq -
beq !-
iny
sty end_of_input_line
lda #$01
sta keyboard_input_ready
;; Return first char of line
// Return first char of line
ldy #$00
pla
tax
@@ -134,43 +134,43 @@ read_from_keyboard:
rts
empty_line:
;; For an empty line, just return the carriage return
;; (and don't forget to actually print the carriage return, so that
;; the cursor advances and screen scrolls as required)
// For an empty line, just return the carriage return
// (and don't forget to actually print the carriage return, so that
// the cursor advances and screen scrolls as required)
pla
tax
clc
lda #$0d
rts
not_enter:
;; Print character
not_enter:
// Print character
lda keyboard_buffer
jsr chrout
jsr CHROUT
jsr pop_keyboard_buffer
;; Keep looking for input from keyboard until carriage return
// Keep looking for input from keyboard until carriage return
jmp chrin_repeat
pop_keyboard_buffer:
;; Pop key out of keyboard buffer
;; Disable interrupts while reading from keyboard buffer
;; so that no race conditions can occur
pop_keyboard_buffer:
// Pop key out of keyboard buffer
// Disable interrupts while reading from keyboard buffer
// so that no race conditions can occur
sei
ldx #$00
ldy #$01
* lda keyboard_buffer,y
!: lda keyboard_buffer,y
sta keyboard_buffer,x
inx
iny
cpy key_buffer_size
bne -
bne !-
dec keys_in_key_buffer
cli
rts
screen_code_to_petscii:
cmp #$1b
bcs not_alpha
@@ -185,7 +185,7 @@ not_alpha:
rts
not_punctuation:
not_punctuation:
cmp #$5b
bcs not_shifted
@@ -193,18 +193,18 @@ not_punctuation:
adc #$80
rts
not_shifted:
not_shifted:
cmp #$80
bcs not_vendor
;; $60-$7F -> $A0-$BF
// $60-$7F -> $A0-$BF
clc
adc #$40
;; FALLTROUGH
// FALLTROUGH
not_vendor:
rts
+253 -253
View File
File diff suppressed because it is too large. Load diff
+40 -40
View File
@@ -1,24 +1,24 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 280
;; - [CM64] Compute's Mapping the Commodore 64 - page 242
;;
;; CPU registers that has to be preserved (see [RG64]): none
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 280
// - [CM64] Compute's Mapping the Commodore 64 - page 242
//
// CPU registers that has to be preserved (see [RG64]): none
//
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
// 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
// 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
lda #$C8 // preparation, as the VIC might be uninitialized
sta VIC_SCROLX
cint_w0:
@@ -28,18 +28,18 @@ cint_w1:
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
// 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
// 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
@@ -48,51 +48,51 @@ cint_ntsc:
stx CIA1_TIMAHI
lda #$00
beq +
beq !+
cint_pal:
lda #$01
*
!:
sta PALNTSC
cint_brk: ; entry for BRK and STOP+RESTORE - XXX, where should it start?
cint_brk: // entry for BRK and STOP+RESTORE - XXX, where should it start?
jsr setup_vicii
;; Initialise cursor blink flags (Compute's Mapping the 64 p215)
// Initialise cursor blink flags (Compute's Mapping the 64 p215)
lda #$00
sta cursor_blink_disable
;; Set keyboard decode vector (Compute's Mapping the 64 p215)
// Set keyboard decode vector (Compute's Mapping the 64 p215)
;; Set initial variables for our improved keyboard scan routine
lda #$ff
// Set initial variables for our improved keyboard scan routine
lda #$FF
ldx #6
* sta BufferOld,x
!: sta BufferOld,x
dex
bpl -
bpl !-
sta BufferQuantity
;; Set key repeat delay (Compute's Mapping the 64 p215)
;; Making some numbers up here: Repeat every ~1/10th sec
;; But require key to be held for ~1/3sec before
;; repeating (Compute's Mapping the 64 p58)
ldx #22-2 ; Fudge factor to match speed
// Set key repeat delay (Compute's Mapping the 64 p215)
// Making some numbers up here: Repeat every ~1/10th sec
// But require key to be held for ~1/3sec before
// repeating (Compute's Mapping the 64 p58)
ldx #22-2 // Fudge factor to match speed
stx key_first_repeat_delay
;; Set current colour for text (Compute's Mapping the 64 p215)
ldx #$01 ; default is light blue ($0E), but we use a different one
// Set current colour for text (Compute's Mapping the 64 p215)
ldx #$01 // default is light blue ($0E), but we use a different one
stx text_colour
;; Set maximum keyboard buffer size (Compute's Mapping the 64 p215)
// Set maximum keyboard buffer size (Compute's Mapping the 64 p215)
ldx #10
stx key_buffer_size
;; Put non-zero value in enable_case_switch
// Put non-zero value in enable_case_switch
stx enable_case_switch
;; Set default I/O devices (see SCINIT description at http://sta.c64.org/cbm64krnfunc.html)
// Set default I/O devices (see SCINIT description at http://sta.c64.org/cbm64krnfunc.html)
jsr clrchn_reset
;; Fallthrough/jump to screen clear routine (Compute's Mapping the 64 p215)
// Fallthrough/jump to screen clear routine (Compute's Mapping the 64 p215)
jmp clear_screen
+14 -14
View File
@@ -1,37 +1,37 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 279/280
;; - [CM64] Compute's Mapping the Commodore 64 - page 224
;;
;; CPU registers that has to be preserved (see [RG64]): .X, .Y
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 279/280
// - [CM64] Compute's Mapping the Commodore 64 - page 224
//
// CPU registers that has to be preserved (see [RG64]): .X, .Y
//
ciout:
CIOUT:
pha
lda C3PO
bne ciout_send_byte
;; Nothing to send - set buffer as valid, store byte there
// Nothing to send - set buffer as valid, store byte there
inc C3PO
;; Clear carry flag to indicate success
// Clear carry flag to indicate success
clc
ciout_store_in_buffer:
;; Store in the buffer data to be sent next, return
// Store in the buffer data to be sent next, return
pla
sta BSOUR
rts
ciout_send_byte:
clc ; don't send with EOI
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
inc C3PO // iec_tx_byte sets it to 0, but we still have something to send
jmp ciout_store_in_buffer
+20 -20
View File
@@ -1,38 +1,38 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 281
;; - [CM64] Compute's Mapping the Commodore 64 - page 230
;;
;; CPU registers that has to be preserved (see [RG64]): .Y
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 281
// - [CM64] Compute's Mapping the Commodore 64 - page 230
//
// CPU registers that has to be preserved (see [RG64]): .Y
//
clall_real:
;; Store .Y register
// Store .Y register
tya
pha
;; Original routine probably just sets LDTND to 0, but this is not really safe,
;; so we actually close all the channels; at least IDE64 does the same for
;; it's channels, see CLALL description in the IDE64 User's Guide
*
// Original routine probably just sets LDTND to 0, but this is not really safe,
// so we actually close all the channels; at least IDE64 does the same for
// it's channels, see CLALL description in the IDE64 User's Guide
!:
ldy LDTND
beq +
beq !+
dey
lda LAT, y
jsr JCLOSE
jmp -
*
;; Restore .Y register
jmp !-
!:
// Restore .Y register
pla
tay
;; 'C64 Programmers Reference Guide', page 281, claims it calls CLRCHN too
jsr clrchn
// 'C64 Programmers Reference Guide', page 281, claims it calls CLRCHN too
jsr CLRCHN
;; Not sure whether original Kernal does so, but it seems sane to also clear possible errors
// Not sure whether original Kernal does so, but it seems sane to also clear possible errors
jmp kernalstatus_reset
+7 -7
View File
@@ -1,23 +1,23 @@
;; Common ppart of CLOSE and LOAD routines
// Common ppart of CLOSE and LOAD routines
close_load:
tax
;; Command drive to stop talking and to close the file
jsr untlk
// Command drive to stop talking and to close the file
jsr UNTLK
txa
jsr listen
jsr LISTEN
lda #$E0 ; CLOSE command
lda #$E0 // CLOSE command
sta IEC_TMP2
jsr iec_tx_command
jsr iec_tx_command_finalize
;; Tell drive to unlisten
jsr unlsn
// Tell drive to unlisten
jsr UNLSN
rts
+21 -21
View File
@@ -1,35 +1,35 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 282
;; - [CM64] Compute's Mapping the Commodore 64 - page 230
;;
;; CPU registers that has to be preserved (see [RG64]): .Y
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 282
// - [CM64] Compute's Mapping the Commodore 64 - page 230
//
// CPU registers that has to be preserved (see [RG64]): .Y
//
clrchn_real:
;; Handle IEC input device
// Handle IEC input device
lda DFLTN
jsr iec_check_devnum
bcs +
;; Previous device was IEC one - send UNTALK first
jsr untlk
*
;; Restore output device to default
bcs !+
// Previous device was IEC one - send UNTALK first
jsr UNTLK
!:
// Restore output device to default
lda DFLTO
jsr iec_check_devnum
bcs +
;; Handle IEC output device
jsr unlsn
*
clrchn_reset: ;; entry needed by CHRIN
;; Set input device number to keyboard
bcs !+
// Handle IEC output device
jsr UNLSN
!:
clrchn_reset: // entry needed by CHRIN
// Set input device number to keyboard
lda #$00
sta DFLTN
;; Set output device number to screen
// Set output device number to screen
lda #$03
sta DFLTO
+23 -23
View File
@@ -1,10 +1,10 @@
;; Clear screen and initialise line link table
;; (Compute's Mapping the 64 p215-216)
// Clear screen and initialise line link table
// (Compute's Mapping the 64 p215-216)
clear_screen:
;; Clear line link table
;; (Compute's Mapping the 64 p215)
// Clear line link table
// (Compute's Mapping the 64 p215)
lda #$00
ldy #24
@@ -13,27 +13,27 @@ clearscreen_l1:
dey
bpl clearscreen_l1
;; Y now = #$FF
// Y now = #$FF
;; Clear screen RAM.
;; We should do this at HIBASE, which annoyingly
;; is no ZP, so we need to make a vector
;; (Compute's Mapping the 64 p216)
;; Get pointer to the screen into current_screen_line_ptr
;; as it is the first appropriate place for it found when
;; searching through the ZP allocations listed in
;; Compute's Mapping the 64
// Clear screen RAM.
// We should do this at HIBASE, which annoyingly
// is no ZP, so we need to make a vector
// (Compute's Mapping the 64 p216)
// Get pointer to the screen into current_screen_line_ptr
// as it is the first appropriate place for it found when
// searching through the ZP allocations listed in
// Compute's Mapping the 64
sta current_screen_line_ptr+0
lda hibase
lda HIBASE
sta current_screen_line_ptr+1
ldx #$03 ; countdown for pages to update
iny ; Y now = #$00
lda #$20 ; space character
ldx #$03 // countdown for pages to update
iny // Y now = #$00
lda #$20 // space character
clearscreen_l2:
sta (current_screen_line_ptr),y
iny
bne clearscreen_l2
;; To draw only 1000 bytes, add 250 to address each time
// To draw only 1000 bytes, add 250 to address each time
lda current_screen_line_ptr
clc
adc #<250
@@ -41,20 +41,20 @@ clearscreen_l2:
lda current_screen_line_ptr+1
adc #>250
sta current_screen_line_ptr+1
lda #$20 ; get space character again
lda #$20 // get space character again
dex
bpl clearscreen_l2
;; Clear colour RAM
;; (Compute's Mapping the 64 p216)
// Clear colour RAM
// (Compute's Mapping the 64 p216)
lda text_colour
clearscreen_l3:
sta $d800,y
sta $d900,y
sta $da00,y
sta $db00-24,y ; so we only erase 1000 bytes
sta $db00-24,y // so we only erase 1000 bytes
iny
bne clearscreen_l3
;; (Compute's Mapping the 64 p216)
// (Compute's Mapping the 64 p216)
jmp home_cursor
+7 -7
View File
@@ -1,20 +1,20 @@
setup_vicii:
;; Set up default IO values (Compute's Mapping the 64 p215)
lda #$1B ; Enable text mode
// Set up default IO values (Compute's Mapping the 64 p215)
lda #$1B // Enable text mode
sta VIC_SCROLY
lda #$C8 ; 40 column etc
lda #$C8 // 40 column etc
sta VIC_SCROLX
;; Compute's Mapping the 64, p156
;; We use a different colour scheme of white text on all blue
// Compute's Mapping the 64, p156
// We use a different colour scheme of white text on all blue
lda #$06
sta VIC_EXTCOL
sta VIC_BGCOL0
;; Turn off sprites (observed hanging around after running programs and resetting)
// Turn off sprites (observed hanging around after running programs and resetting)
lda #$00
sta VIC_SPENA
;;FALLTROUGH
// FALLTROUGH
+5 -5
View File
@@ -1,7 +1,7 @@
;; Kernal error codes are described in 'Commodore 64 Programmer's Reference Guide', page 306
// Kernal error codes are described in 'Commodore 64 Programmer's Reference Guide', page 306
kernalerror_ROUTINE_TERMINATED: ; by a STOP key
kernalerror_ROUTINE_TERMINATED: // by a STOP key
lda #K_ERR_ROUTINE_TERMINATED
sec
rts
@@ -56,20 +56,20 @@ kernalerror_TOP_MEM_RS232:
sec
rts
;; Kernal status codes are described in 'Commodore 64 Programmer's Reference Guide', page 292
// 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!
kernalstatus_TIMEOUT_WRITE: // XXX detect this!
lda IOSTATUS
ora #K_STS_TIMEOUT_WRITE
sta IOSTATUS
rts
kernalstatus_TIMEOUT_READ: ;; XXX detect this!
kernalstatus_TIMEOUT_READ: // XXX detect this!
lda IOSTATUS
ora #K_STS_TIMEOUT_READ
sta IOSTATUS
+14 -14
View File
@@ -1,27 +1,27 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 283
;; - [CM64] Compute's Mapping the Commodore 64 - page 227/228
;;
;; CPU registers that has to be preserved (see [RG64]): .X, .Y
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 283
// - [CM64] Compute's Mapping the Commodore 64 - page 227/228
//
// CPU registers that has to be preserved (see [RG64]): .X, .Y
//
;; XXX currently does not preserve registers, to be fixed!
// XXX currently does not preserve registers, to be fixed!
getin:
GETIN:
;; Wait for a key
// Wait for a key
lda keys_in_key_buffer
bne +
bne !+
;; Nothing in keyboard buffer to read
// Nothing in keyboard buffer to read
sec
lda #$00
rts
*
!:
lda keyboard_buffer
pha
+3 -3
View File
@@ -1,6 +1,6 @@
;; Our implementation is longer than the original one,
;; placing it here would cause a collision with CHROUT
// Our implementation is longer than the original one,
// placing it here would cause a collision with CHROUT
chrin:
CHRIN:
jmp chrin_real
+3 -3
View File
@@ -1,6 +1,6 @@
;; Our implementation is longer than the original one,
;; placing it here would cause a collision with CHKIN
// Our implementation is longer than the original one,
// placing it here would cause a collision with CHKIN
chrout:
CHROUT:
jmp chrout_real
+3 -3
View File
@@ -1,6 +1,6 @@
;; In our implementation CHKIN and CKOUT are closely tied,
;; placing it here would cause a collision
// In our implementation CHKIN and CKOUT are closely tied,
// placing it here would cause a collision
chkin:
CHKIN:
jmp chkin_real
+3 -3
View File
@@ -1,6 +1,6 @@
;; In our implementation CHKIN and CKOUT are closely tied,
;; placing it here would cause a collision
// In our implementation CHKIN and CKOUT are closely tied,
// placing it here would cause a collision
ckout:
CKOUT:
jmp ckout_real
+27 -27
View File
@@ -1,49 +1,49 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 281/282
;; - [CM64] Compute's Mapping the Commodore 64 - page 229/230
;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc (IEC command)
;;
;; CPU registers that has to be preserved (see [RG64]): none
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 281/282
// - [CM64] Compute's Mapping the Commodore 64 - page 229/230
// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc (IEC command)
//
// CPU registers that has to be preserved (see [RG64]): none
//
close:
CLOSE:
;; XXX this needs more testing (opening 10 files at once, closing in various orders, etc) once the code is more mature
// XXX this needs more testing (opening 10 files at once, closing in various orders, etc) once the code is more mature
;; Find the LAT / SAT / FAT entry which LAT corresponds to A
// Find the LAT / SAT / FAT entry which LAT corresponds to A
jsr find_fls
bcs close_error_not_found ;; XXX can we report error in IOSTATUS here?
bcs close_error_not_found // XXX can we report error in IOSTATUS here?
;; We have the entry index in Y - check whether this is IEC device
// We have the entry index in Y - check whether this is IEC device
lda FAT, y
jsr iec_check_devnum
bcs close_remove_from_table
;; IEC device
// IEC device
jsr iec_tx_flush ; make sure no byte is awaiting
lda SAT, y ; get secondary address
jsr iec_tx_flush // make sure no byte is awaiting
lda SAT, y // get secondary address
cmp #$60
bne +
;; workaround for using CLOSE on reading executable - XXX is this a proper way?
bne !+
// workaround for using CLOSE on reading executable - XXX is this a proper way?
jsr close_load
jmp close_remove_from_table
*
ora $E0 ; CLOSE command
!:
ora $E0 // CLOSE command
sta IEC_TMP2
jsr iec_tx_command
bcs close_remove_from_table
jsr iec_tx_command_finalize
close_remove_from_table:
;; Remove channel from the table
// Remove channel from the table
iny
cpy #$0A
bpl +
bpl !+
lda LAT, y
sta LAT-1, y
lda FAT, y
@@ -51,14 +51,14 @@ close_remove_from_table:
lda SAT, y
sta SAT-1, y
jmp close_remove_from_table
*
;; Decrement the list size variable
!:
// Decrement the list size variable
dec LDTND
clc ; report success - not sure if original CLOSE does this, but it's nevertheless a good practice
clc // report success - not sure if original CLOSE does this, but it's nevertheless a good practice
rts
close_error_not_found:
sec ; report success - not sure if original CLOSE does this, but it's nevertheless a good practice
sec // report success - not sure if original CLOSE does this, but it's nevertheless a good practice
rts
+3 -3
View File
@@ -1,6 +1,6 @@
;; Our implementation is longer than the original one,
;; placing it here would cause a collision with CLRCHN
// Our implementation is longer than the original one,
// placing it here would cause a collision with CLRCHN
clall:
CLALL:
jmp clall_real
+3 -3
View File
@@ -1,6 +1,6 @@
;; Our implementation is longer than the original one,
;; placing it here would cause a collision with OPEN
// Our implementation is longer than the original one,
// placing it here would cause a collision with OPEN
clrchn:
CLRCHN:
jmp clrchn_real
+32 -32
View File
@@ -1,23 +1,23 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 289
;; - [CM64] Compute's Mapping the Commodore 64 - page 230/231
;;
;; CPU registers that has to be preserved (see [RG64]): none
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 289
// - [CM64] Compute's Mapping the Commodore 64 - page 230/231
//
// CPU registers that has to be preserved (see [RG64]): none
//
open:
OPEN:
;; Reset status
// Reset status
jsr kernalstatus_reset
;; Check if the logical file number is unique
// Check if the logical file number is unique
ldy LDTND
*
beq +
!:
beq !+
dey
lda LAT, y
cmp current_logical_filenum
@@ -25,23 +25,23 @@ open:
jmp kernalerror_FILE_ALREADY_OPEN
open_not_yet_open:
cpy #$00
jmp -
*
;; Check if we have space in tables
jmp !-
!:
// Check if we have space in tables
ldy LDTND
cpy #$0A
bcc open_has_space
*
;; Table is full
!:
// Table is full
jmp kernalerror_TOO_MANY_OPEN_FILES
open_has_space:
;; Update the tables
// Update the tables
;; LAT / FAT / SAT support implemented according to
;; 'Compute's Mapping the Commodore 64', page 52
// LAT / FAT / SAT support implemented according to
// 'Compute's Mapping the Commodore 64', page 52
lda current_logical_filenum
sta LAT, y
@@ -53,16 +53,16 @@ open_has_space:
iny
sty LDTND
;; Check for command to send
// Check for command to send
lda FNLEN
beq open_done_success
;; Check for IEC device
// Check for IEC device
lda current_device_number
jsr iec_check_devnum
bcc open_iec
;; FALLTROUGH
// FALLTROUGH
open_done_success:
clc
@@ -70,21 +70,21 @@ open_done_success:
open_iec:
;; We have a command to send to IEC device
jsr listen
bcc +
// We have a command to send to IEC device
jsr LISTEN
bcc !+
jmp kernalerror_DEVICE_NOT_FOUND
*
!:
lda current_secondary_address
jsr iec_cmd_open
bcc +
bcc !+
jmp kernalerror_DEVICE_NOT_FOUND
*
!:
;; We need our helpers to get to filenames under ROMs or IO area
// We need our helpers to get to filenames under ROMs or IO area
jsr install_ram_routines
;; Send command ('file name')
// Send command ('file name')
jsr lvs_send_file_name
jmp open_done_success
+92 -92
View File
@@ -1,146 +1,146 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 286
;; - [CM64] Compute's Mapping the Commodore 64 - page 231
;; - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
;;
;; CPU registers that has to be preserved (see [RG64]): none
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 286
// - [CM64] Compute's Mapping the Commodore 64 - page 231
// - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
//
// CPU registers that has to be preserved (see [RG64]): none
//
;; Expects that SETLFS and SETNAM are called before hand.
;; $YYXX = load address.
;; (ignored if SETLFS channel = 1, i.e., like ,8,1)
;; If A=1 then VERIFY instead of LOAD.
;; On exit, $YYXX is the highest address into which data
;; will have been placed.
// Expects that SETLFS and SETNAM are called before hand.
// $YYXX = load address.
// (ignored if SETLFS channel = 1, i.e., like ,8,1)
// If A=1 then VERIFY instead of LOAD.
// On exit, $YYXX is the highest address into which data
// will have been placed.
;; XXX honor MSGFLG bit 6
;; XXX add VERIFY support
// XXX honor MSGFLG bit 6
// XXX add VERIFY support
load:
LOAD:
;; Are we loading or verifying?
// Are we loading or verifying?
sta VERCK
;; Store start address of LOAD
// Store start address of LOAD
stx STAL+0
sty STAL+1
;; Reset status
// Reset status
jsr kernalstatus_reset
;; We need our helpers to get to filenames under ROMs or IO area
// We need our helpers to get to filenames under ROMs or IO area
jsr install_ram_routines
;; Allow platform-specific routine to takeover the flow
`TARGET_HOOK_LOAD
// Allow platform-specific routine to takeover the flow
TARGET_HOOK_LOAD()
;; Check whether we support the requested device
// Check whether we support the requested device
lda current_device_number
and #$FC
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
;; number 31), yet original ROMs show ILLEGAL DEVICE NUMBER error only
;; for devices 0-3; in our implementation LISTEN / TALK will cause device
;; not present detected for numbers above 30
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
// number 31), yet original ROMs show ILLEGAL DEVICE NUMBER error only
// for devices 0-3; in our implementation LISTEN / TALK will cause device
// not present detected for numbers above 30
;; Display SEARCHING FOR + filename
// Display SEARCHING FOR + filename
jsr lvs_display_searching_for
;; 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.
// 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.
;; Call device to LISTEN (p16)
// Call device to LISTEN (p16)
lda current_device_number
jsr listen
bcc +
jmp lvs_device_not_found_error ; XXX deduplicate with other jumps in this routine
*
;; Open channel 0 (reserved for file reading)
jsr LISTEN
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
bcc +
jmp lvs_device_not_found_error ; XXX deduplicate with other jumps in this routine
*
;; Send file name
bcc !+
jmp lvs_device_not_found_error // XXX deduplicate with other jumps in this routine
!:
// Send file name
jsr lvs_send_file_name
bcc +
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
*
;; Now command device to talk (p16)
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
bcc +
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
*
lda #$60 ; open channel / data (p3) , required according to p13
jsr TALK
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
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)
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
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
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
bcc +
jmp lvs_file_not_found_error ; XXX deduplicate with other jumps in this routine
*
bcc !+
jmp lvs_file_not_found_error // XXX deduplicate with other jumps in this routine
!:
ldx current_secondary_address
beq +
beq !+
sta STAL+0
*
!:
jsr iec_rx_byte
bcc +
jmp lvs_file_not_found_error ; XXX deduplicate with other jumps in this routine
*
bcc !+
jmp lvs_file_not_found_error // XXX deduplicate with other jumps in this routine
!:
ldx current_secondary_address
beq +
beq !+
sta STAL+1
*
;; Display start address
!:
// Display start address
jsr lvs_display_loading_verifying
load_loop:
;; We are now ready to receive bytes
// We are now ready to receive bytes
jsr iec_rx_byte
bcc +
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
*
;; Handle the byte (store in memory / verify)
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
bcc +
jmp lvs_load_verify_error ; XXX deduplicate with other jumps in this routine
*
;; Advance pointer to data
bcc !+
jmp lvs_load_verify_error // XXX deduplicate with other jumps in this routine
!:
// Advance pointer to data
jsr lvs_advance_pointer
bcc +
bcc !+
jmp lvs_wrap_around_error
*
;; Check for EOI - if so, this was the last byte
!:
// Check for EOI - if so, this was the last byte
lda IOSTATUS
and #K_STS_EOI
beq load_loop
;; Display end address
// Display end address
jsr lvs_display_done
;; Close file on drive
// Close file on drive
lda current_device_number
jsr close_load
;; Return last address
// Return last address
jmp lvs_return_last_address
+10 -10
View File
@@ -1,13 +1,13 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 293/294
;; - [CM64] Compute's Mapping the Commodore 64 - page 231/232
;; - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
;;
;; CPU registers that has to be preserved (see [RG64]): none
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 293/294
// - [CM64] Compute's Mapping the Commodore 64 - page 231/232
// - IEC reference at http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
//
// CPU registers that has to be preserved (see [RG64]): none
//
save:
SAVE:
rts
+15 -15
View File
@@ -1,24 +1,24 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 301
;; - [CM64] Compute's Mapping the Commodore 64 - page 232
;;
;; CPU registers that has to be preserved (see [RG64]): .Y
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 301
// - [CM64] Compute's Mapping the Commodore 64 - page 232
//
// CPU registers that has to be preserved (see [RG64]): .Y
//
stop:
;; Bit 7 of STKEY contains the state of the STOP key
;; (Compute's Mapping the 64, p27)
STOP:
// Bit 7 of STKEY contains the state of the STOP key
// (Compute's Mapping the 64, p27)
;; BASIC checks carry flag to indicate STOP or not
// BASIC checks carry flag to indicate STOP or not
lda STKEY
bpl stop_pressed
;; By trial and error, we know that Z + C = BREAK
;; and that neither should be set otherwise
lda #$ff
// By trial and error, we know that Z + C = BREAK
// and that neither should be set otherwise
lda #$FF
clc
rts
+30 -36
View File
@@ -1,70 +1,64 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 293 (RESTOR), 304 (VECTOR)
;; - [CM64] Compute's Mapping the Commodore 64 - page 237
;;
;; CPU registers that has to be preserved (see [RG64]): none
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 293 (RESTOR), 304 (VECTOR)
// - [CM64] Compute's Mapping the Commodore 64 - page 237
//
// CPU registers that has to be preserved (see [RG64]): none
//
restor:
RESTOR:
clc ;; clear carry - for writing to system table
clc // clear carry - for writing to system table
ldx #<vector_defaults
ldy #>vector_defaults
;; FALLTHROUGH
// FALLTHROUGH
vector:
VECTOR:
.scope
// Temporary storage location - checked on real C64 that this is the
// address originally used; after calling VECTOR and checking zero page
// area afterwards, the address could be found there
.label _caller_arr_ptr = MEMUS
;; Temporary storage location - checked on real C64 that this is the
;; address originally used; after calling VECTOR and checking zero page
;; area afterwards, the address could be found there
.alias _caller_arr_ptr MEMUS
;; According to 'Compute's Mapping the Commodore 64' page 237,
;; the CBM implementation does not disable IRQs - yet, the
;; 'C64 Programmers Reference Guide' does not contain such
;; warning and does not mention any preparations needed, so...
;; better safe than sorry, disable the IRQ for the duration
;; of vector manipulation
// According to 'Compute's Mapping the Commodore 64' page 237,
// the CBM implementation does not disable IRQs - yet, the
// 'C64 Programmers Reference Guide' does not contain such
// warning and does not mention any preparations needed, so...
// better safe than sorry, disable the IRQ for the duration
// of vector manipulation
php
cli
;; Prepare the user data pointer - strange order to reduce risk
;; of potential similarity to the original routine
// Prepare the user data pointer - strange order to reduce risk
// of potential similarity to the original routine
sty _caller_arr_ptr + 1
stx _caller_arr_ptr + 0
;; Select routine variant - store or restore vectors
// Select routine variant - store or restore vectors
ldy #$1F
bcc vector_restore
;; FALLTHROUGH
// FALLTHROUGH
vector_store:
*
lda CINV, y
sta (_caller_arr_ptr), y
dey
bpl -
bpl vector_store
;; Restore status register (IRQ) before return
// Restore status register (IRQ) before return
plp
rts
vector_restore:
*
lda (_caller_arr_ptr), y
sta CINV, y
dey
bpl -
bpl vector_restore
;; Restore status register (IRQ) before return
// Restore status register (IRQ) before return
plp
rts
.scend
+34 -34
View File
@@ -1,34 +1,34 @@
;;
;; Official Kernal routine, described in:
;;
;; - [RG64] C64 Programmer's Reference Guide - page 285
;; - [CM64] Compute's Mapping the Commodore 64 - page 238
;;
;; CPU registers that has to be preserved (see [RG64]): none
;;
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmer's Reference Guide - page 285
// - [CM64] Compute's Mapping the Commodore 64 - page 238
//
// CPU registers that has to be preserved (see [RG64]): none
//
ioinit:
IOINIT:
; Set $00/$01 port mode and value
; We want BASIC and KERNAL ROMs mapped, and datasette motor off
; (https://www.c64-wiki.com/wiki/Zeropage)
;; XXX - Work around VICE bug: Writing $00 before $01 results in rubbish in $01
;; after. https://sourceforge.net/p/vice-emu/bugs/1057/
// Set $00/$01 port mode and value
// We want BASIC and KERNAL ROMs mapped, and datasette motor off
// (https://www.c64-wiki.com/wiki/Zeropage)
// XXX - Work around VICE bug: Writing $00 before $01 results in rubbish in $01
// after. https://sourceforge.net/p/vice-emu/bugs/1057/
lda #$27
ldx #$2F
sta CPU_R6510
stx CPU_D6510
;; Silence the SID chips under common addresses
// Silence the SID chips under common addresses
ldy #$00
*
;; SIDs under $D4xx
!:
// SIDs under $D4xx
lda SID_SIGVOL, Y
and #$F0
sta SID_SIGVOL, Y
;; SIDs under $D5xx
// SIDs under $D5xx
lda SID_SIGVOL + $100, Y
and #$F0
sta SID_SIGVOL + $100, Y
@@ -36,24 +36,24 @@ ioinit:
clc
adc #$20
tay
bne -
bne !-
;; XXX: calibrate TOD for both CIA's, see here: https://codebase64.org/doku.php?id=base:efficient_tod_initialisation
// 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)
// Enable CIA1 IRQ and ~50Hz timer (https://csdb.dk/forums/?roomid=11&topicid=69037)
lda #$7F
sta CIA1_ICR ; disable all
sta CIA1_ICR // disable all
;; Set timer interval to ~1/60th of a second
// Set timer interval to ~1/60th of a second
;; (This value was calculated by running a custom IRQ handler on a C64
;; with original KERNAL, and writing the values of $DC04/5 to the screen
;; in the IRQ handler to see roughly what value the timers must be set to)
;; ldy #<16380
;; ldx #>16380
// (This value was calculated by running a custom IRQ handler on a C64
// with original KERNAL, and writing the values of $DC04/5 to the screen
// in the IRQ handler to see roughly what value the timers must be set to)
// ldy #<16380
// ldx #>16380
;; PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
;; is clocked at 0.985248 MHz, so that 1/60s is 16421 CPU cycles
// PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
// is clocked at 0.985248 MHz, so that 1/60s is 16421 CPU cycles
ldy #<16421
ldx #>16421
@@ -61,19 +61,19 @@ ioinit:
sty CIA1_TIMALO
stx CIA1_TIMAHI
;; Enable timer interrupt
// Enable timer interrupt
lda #$81
sta CIA1_ICR
;; Enable timer A to run continuously (http://codebase64.org/doku.php?id=base:timerinterrupts)
// Enable timer A to run continuously (http://codebase64.org/doku.php?id=base:timerinterrupts)
lda #$11
sta CIA1_CRA
lda CIA1_ICR
;; Set DDR on CIA2 for IEC bus, VIC-II banking
// Set DDR on CIA2 for IEC bus, VIC-II banking
lda #$3B
sta CIA2_DDRA
;; Set IEC bus to its initial idle state
// Set IEC bus to its initial idle state
jmp iec_set_idle
+3 -3
View File
@@ -1,6 +1,6 @@
;; Our implementation is longer than the original one,
;; placing it here would cause a collision with OPEN
// Our implementation is longer than the original one,
// placing it here would cause a collision with OPEN
cint:
CINT:
jmp cint_real
+60 -28
View File
@@ -1,31 +1,63 @@
;;
;; This byte identifies Kernal revision. Sources:
;; - [CM64] Compute's Mapping the Commodore 64 (page 242/243)
;; - [MM] Marko Mäkelä article, http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/revisions.txt
;; - [VICE] Checked with ROMs included in VICE emulator
;;
;; IDEA: put here a value, that is different from any version currently known, as
;; a warning that this is not a Commodore Kernal. Currently known numbers for C64 are:
;;
;; - $00 - [CM64] then current number [MM] 901227-02 [VICE] C64 Revision 2
;; - $03 - [CM64] (not mentionned) [MM] 901227-02, 901227-03 [VICE] C64 Revision 3
;; - $43 - [CM64] (not mentionned) [MM] 251104-04 [VICE] SX-64
;; - $64 - [CM64] PET64 ROM [MM] (not mentionned) [VICE] PET64
;; - $AA - [CM64] first version of ROM [MM] 901227-01 [VICE] C64 Revision 1
;;
;; Values from unofficial ROMs:
;; - $03 - SuperCPU ROM 1.40, 2.04, also unofficial 0.7 ROM from [VICE]
;;
;; Values from other Commodore machines:
;; C128:
;; - $01 - see https://www.pagetable.com/?p=1058
;; - $02 - unreleased updated ROM, see https://www.pagetable.com/?p=1058
;;
;; XXX check more unofficial C64 ROMs (JiffyDOS, DolphinDOS, etc.) and other machines
;; VIC-20, PET, CBM II, 264 series, C65 prototypes, other sources for C128 ROMs
;;
//
// This byte (hex $FF80, dec 65408) identifies Kernal revision on several machines. Although not all
// of the, used it for versioning purpose, here is the list of all the values I could find. Sources:
// - [CM64] Compute's Mapping the Commodore 64 (page 242/243)
// - [MM] Marko Mäkelä article, http://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/revisions.txt
// - [VICE] Checked with ROMs included in VICE emulator
// - [XEMU] Checked with ROMs retrieved by XEMU emulator
//
// IDEA: put here a value, that is different from any version currently known, as
// a warning that this is not a Commodore Kernal or anything already known.
//
// C64 - values from the official ROMs:
// - $00 - [CM64] then current number [MM] 901227-02 [VICE] C64 Revision 2
// - $03 - [CM64] (not mentionned) [MM] 901227-02, 901227-03 [VICE] C64 Revision 3
// - $43 - [CM64] (not mentionned) [MM] 251104-04 [VICE] SX-64
// - $64 - [CM64] PET64 ROM [MM] (not mentionned) [VICE] PET64
// - $AA - [CM64] first version of ROM [MM] 901227-01 [VICE] C64 Revision 1
//
// C64 - values from unofficial 3rd party ROMs:
// - $00 - Turbo Trans, Turbo Access, Turbo Process
// - $03 - SuperCPU ROM 1.40, 2.04, also unofficial 0.7 ROM from [VICE],
// DolphinDOS 2.0, JiffyDOS 6.01, EXOS V3/4,
// Datel Mercury V3 US, Datel DOS-ROM V1.2, Datel Turbo ROM II V3.2+,
// Turbo Process US,
// burst CIA 1/2 Kernal by Albert, SD2IEC Kernal 1.0/2.0/2.1/2.2 by Claus
// - $4A - S-JiffyDOS
// - $53 - Professional DOS V1, SpeedDOS Plus 2.7
// - $C3 - Cockroach Turbo ROM V1
//
// PET:
// - $40 - [VICE] PET 2001-8N
// - $A7 - [VICE] PET 30XX
// - $AA - [VICE] PET 40XX, PET 80XX, SuperPET
//
// CBM II:
// - $E0 - [VICE] 5x0, 6x0, 7x0 models
//
// VIC-20:
// - $16 - [VICE] all models, also VIC-20 JiffyDOS PAL/NTSC
//
// 264 family:
// - $01 - [VICE] 364
// - $05 - [VICE] C16, C116, Plus/4
// - $06 - (unofficial) JiffyDOS NTSC
// - $81 - [VICE] 232
// - $86 - (unofficial) JiffyDOS PAL
//
// C128:
// - $01 - see https://www.pagetable.com/?p=1058
// - $02 - unreleased updated ROM, see https://www.pagetable.com/?p=1058
//
// Commodore prototypes:
// - $04 - [XEMU] 64 mode ROM of the C65 prototype, ROM 910111
// - $FF - [XEMU] C65 native mode, ROM 910111
// - $FF - [XEMU] Commodore LCD
//
// Non-Commodore machines:
// - $FF - Commander X16 (emulator r28)
//
kernal_revision:
.byte $FF
.byte $FF // XXX possibly change this value (current candidate: $F0), $FF conflicts with other machines
+2 -2
View File
@@ -1,4 +1,4 @@
; $FFFA - CPU NMI Hanlder
; Uncontrovertial as this is also a CPU requirement.
// $FFFA - CPU NMI Hanlder
// Uncontrovertial as this is also a CPU requirement.
.word nmi_handler
+2 -2
View File
@@ -1,4 +1,4 @@
; $FFFC - CPU Reset Vector
; Uncontrovertial, as it is a CPU requirement, and nothing else.
// $FFFC - CPU Reset Vector
// Uncontrovertial, as it is a CPU requirement, and nothing else.
.word reset_entry
+3 -3
View File
@@ -1,5 +1,5 @@
; $FFFE - CPU IRQ Vector.
; This is non-controvertial, as it is a 6502 CPU requirement, and we just have to point
; it to whatever IRQ routine we make.
// $FFFE - CPU IRQ Vector.
// This is non-controvertial, as it is a 6502 CPU requirement, and we just have to point
// it to whatever IRQ routine we make.
.word irq_handler
+7 -7
View File
@@ -1,18 +1,18 @@
;; Just a helper routines
// Just a helper routines
;; Find the LAT / SAT / FAT entry index where LAT corresponds to A, returns index in Y
;; Carry flag set means not found
// Find the LAT / SAT / FAT entry index where LAT corresponds to A, returns index in Y
// Carry flag set means not found
find_fls:
ldy LDTND
beq find_fls_not_found ; table empty
*
beq find_fls_not_found // table empty
!:
dey
bmi find_fls_not_found ; no more entries
bmi find_fls_not_found // no more entries
cmp LAT, y
bne - ; does not match, try the next one
bne !- // does not match, try the next one
clc
rts
+2 -2
View File
@@ -1,5 +1,5 @@
;; Home the cursor
;; (Compute's Mapping the 64 p216)
// Home the cursor
// (Compute's Mapping the 64 p216)
home_cursor:
+13 -13
View File
@@ -1,22 +1,22 @@
;;
;; Checks whether device number (in .A) is a correct IEC device number
;;
;; Preserves .A, .X and .Y
;;
//
// Checks whether device number (in .A) is a correct IEC device number
//
// Preserves .A, .X and .Y
//
iec_check_devnum:
;; 0, 1, 2, or 3 are illegal - reserved for non-IEC devices on Commodore
// 0, 1, 2, or 3 are illegal - reserved for non-IEC devices on Commodore
cmp #$04
bcs +
;; FALLTROUGH
bcs !+
// FALLTROUGH
iec_check_devnum_failed:
sec ; indicate non-IEC device
sec // indicate non-IEC device
rts
*
;; 31 and above are illegal too, due to IEC command encoding scheme,
;; see https://www.pagetable.com/?p=1031
!:
// 31 and above are illegal too, due to IEC command encoding scheme,
// see https://www.pagetable.com/?p=1031
cmp #$1F
bcs iec_check_devnum_failed
;; Carry is clear here - indicates IEC device
// Carry is clear here - indicates IEC device
rts
+7 -7
View File
@@ -1,16 +1,16 @@
;;
;; Kernal internal IEC routine
;;
;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
;;
//
// Kernal internal IEC routine
//
// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
//
iec_cmd_close:
jsr iec_check_channel_openclose
bcc +
bcc !+
jmp kernalerror_FILE_NOT_INPUT
*
!:
ora #$E0
jmp common_open_close_unlsn_second
+22 -22
View File
@@ -1,42 +1,42 @@
;;
;; Kernal internal IEC routine
;;
;; - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
;;
//
// Kernal internal IEC routine
//
// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
//
iec_cmd_open: ; similar to TKSA, but without turnaround
iec_cmd_open: // similar to TKSA, but without turnaround
jsr iec_check_channel_openclose
bcc +
bcc !+
jmp kernalerror_FILE_NOT_INPUT
*
!:
ora #$F0
;; FALLTROUGH
// FALLTROUGH
common_open_close_unlsn_second: ; common part of several commands
common_open_close_unlsn_second: // common part of several commands
sta IEC_TMP2
jsr iec_tx_command
bcs + ; branch if error
bcs !+ // branch if error
jmp iec_tx_command_finalize
*
!:
rts
iec_check_channel_openclose:
;; Due to OPEN/CLOSE/TKSA/SECOND command encoding (see https://www.pagetable.com/?p=1031),
;; allowed channels are 0-15; report error if out of range
// Due to OPEN/CLOSE/TKSA/SECOND command encoding (see https://www.pagetable.com/?p=1031),
// allowed channels are 0-15; report error if out of range
cmp #$10
bcc +
;; Workaround to allow reading executable files and disk directory
;; using OPEN routine - see https://www.pagetable.com/?p=273 for
;; example usage
bcc !+
// Workaround to allow reading executable files and disk directory
// using OPEN routine - see https://www.pagetable.com/?p=273 for
// example usage
cmp #$60
beq +
sec ; mark unsuitable channel number
beq !+
sec // mark unsuitable channel number
rts
*
clc ; mark suitable channel number
!:
clc // mark suitable channel number
rts
@@ -1,15 +1,15 @@
iec_pull_atn_clk_release_data:
;; Pulled CLK = DATA considered invalid; for extra robustness on non-emulated
;; hardware give some lines few more cycles to stabilize; see page 10 of
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
// Pulled CLK = DATA considered invalid; for extra robustness on non-emulated
// hardware give some lines few more cycles to stabilize; see page 10 of
// http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
lda CIA2_PRA
ora #BIT_CIA2_PRA_ATN_OUT ; pull
ora #BIT_CIA2_PRA_ATN_OUT // pull
sta CIA2_PRA
ora #BIT_CIA2_PRA_CLK_OUT ; pull
ora #BIT_CIA2_PRA_CLK_OUT // pull
sta CIA2_PRA
and #$FF - BIT_CIA2_PRA_DAT_OUT ; release
and #$FF - BIT_CIA2_PRA_DAT_OUT // release
sta CIA2_PRA
rts
+5 -5
View File
@@ -1,13 +1,13 @@
iec_pull_clk_release_data:
;; Pulled CLK = DATA considered invalid; for extra robustness on non-emulated
;; hardware give some lines few more cycles to stabilize; see page 10 of
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
// Pulled CLK = DATA considered invalid; for extra robustness on non-emulated
// hardware give some lines few more cycles to stabilize; see page 10 of
// http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
lda CIA2_PRA
ora #BIT_CIA2_PRA_CLK_OUT ; pull
ora #BIT_CIA2_PRA_CLK_OUT // pull
sta CIA2_PRA
and #$FF - BIT_CIA2_PRA_DAT_OUT ; release
and #$FF - BIT_CIA2_PRA_DAT_OUT // release
sta CIA2_PRA
rts
@@ -2,7 +2,7 @@
iec_pull_clk_release_data_oneshot:
lda CIA2_PRA
ora #BIT_CIA2_PRA_CLK_OUT ; pull
and #$FF - BIT_CIA2_PRA_DAT_OUT ; release
ora #BIT_CIA2_PRA_CLK_OUT // pull
and #$FF - BIT_CIA2_PRA_DAT_OUT // release
sta CIA2_PRA
rts
@@ -1,15 +1,15 @@
iec_pull_data_release_atn_clk:
;; Released CLK = DATA considered valid; for extra robustness on non-emulated
;; hardware give some lines few more cycles to stabilize; see page 10 of
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
// Released CLK = DATA considered valid; for extra robustness on non-emulated
// hardware give some lines few more cycles to stabilize; see page 10 of
// http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
lda CIA2_PRA
ora #BIT_CIA2_PRA_DAT_OUT ; pull
ora #BIT_CIA2_PRA_DAT_OUT // pull
sta CIA2_PRA
and #$FF - BIT_CIA2_PRA_CLK_OUT ; release
and #$FF - BIT_CIA2_PRA_CLK_OUT // release
sta CIA2_PRA
and #$FF - BIT_CIA2_PRA_ATN_OUT ; release
and #$FF - BIT_CIA2_PRA_ATN_OUT // release
sta CIA2_PRA
rts
+1 -1
View File
@@ -2,7 +2,7 @@
iec_release_atn:
lda CIA2_PRA
and #$FF - BIT_CIA2_PRA_ATN_OUT ; release
and #$FF - BIT_CIA2_PRA_ATN_OUT // release
sta CIA2_PRA
rts
+6 -6
View File
@@ -1,16 +1,16 @@
iec_release_atn_clk_data:
;; Released CLK = DATA considered valid; for extra robustness on non-emulated
;; hardware give some lines few more cycles to stabilize; see page 10 of
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
// Released CLK = DATA considered valid; for extra robustness on non-emulated
// hardware give some lines few more cycles to stabilize; see page 10 of
// http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
lda CIA2_PRA
and #$FF - BIT_CIA2_PRA_ATN_OUT ; release
and #$FF - BIT_CIA2_PRA_ATN_OUT // release
sta CIA2_PRA
and #$FF - BIT_CIA2_PRA_DAT_OUT ; release
and #$FF - BIT_CIA2_PRA_DAT_OUT // release
sta CIA2_PRA
and #$FF - BIT_CIA2_PRA_CLK_OUT ; release
and #$FF - BIT_CIA2_PRA_CLK_OUT // release
sta CIA2_PRA
rts
+5 -5
View File
@@ -1,13 +1,13 @@
iec_release_clk_data:
;; Released CLK = DATA considered valid; for extra robustness on non-emulated
;; hardware give some lines few more cycles to stabilize; see page 10 of
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
// Released CLK = DATA considered valid; for extra robustness on non-emulated
// hardware give some lines few more cycles to stabilize; see page 10 of
// http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
lda CIA2_PRA
and #$FF - BIT_CIA2_PRA_DAT_OUT ; release
and #$FF - BIT_CIA2_PRA_DAT_OUT // release
sta CIA2_PRA
and #$FF - BIT_CIA2_PRA_CLK_OUT ; release
and #$FF - BIT_CIA2_PRA_CLK_OUT // release
sta CIA2_PRA
rts
+5 -5
View File
@@ -1,13 +1,13 @@
iec_release_clk_pull_data:
;; Released CLK = DATA considered valid; for extra robustness on non-emulated
;; hardware give some lines few more cycles to stabilize; see page 10 of
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
// Released CLK = DATA considered valid; for extra robustness on non-emulated
// hardware give some lines few more cycles to stabilize; see page 10 of
// http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
lda CIA2_PRA
ora #BIT_CIA2_PRA_DAT_OUT ; pull
ora #BIT_CIA2_PRA_DAT_OUT // pull
sta CIA2_PRA
and #$FF - BIT_CIA2_PRA_CLK_OUT ; release
and #$FF - BIT_CIA2_PRA_CLK_OUT // release
sta CIA2_PRA
rts
+15 -15
View File
@@ -1,38 +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
;;
//
// 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
// BSOUR is certainly not valid anymore
lda #$00
sta C3PO
;; Restore registers
// Restore registers
pla
tay
pla
tax
;; Report success
// Report success
clc
rts
iec_return_DEVICE_NOT_FOUND:
;; Set IEC line to normal idle state
// Set IEC line to normal idle state
jsr iec_set_idle
;; BSOUR is certainly not valid anymore
// BSOUR is certainly not valid anymore
lda #$00
sta C3PO
;; Restore registers
// Restore registers
pla
tay
pla
tax
;; Report error
// Report error
jmp kernalerror_DEVICE_NOT_FOUND
+70 -70
View File
@@ -1,141 +1,141 @@
;; Receive a byte from the IEC bus.
;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc,
;; http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf (page 11)
;;
;; Preserves .X and .Y registers
// Receive a byte from the IEC bus.
// Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc,
// http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf (page 11)
//
// Preserves .X and .Y registers
iec_rx_byte:
;; Store .X and .Y on the stack - preserve them
// Store .X and .Y on the stack - preserve them
txa
pha
tya
pha
;; Timing is critical here - execute on disabled IRQs
// Timing is critical here - execute on disabled IRQs
php
sei
;; First, we wait for the talker to release the CLK line
// First, we wait for the talker to release the CLK line
jsr iec_wait_for_clk_release
;; We then release the DATA to signal we are ready
;; We can use this routine, since we weren't pulling CLK anyway
// We then release the DATA to signal we are ready
// We can use this routine, since we weren't pulling CLK anyway
jsr iec_release_clk_data
;; Wait till data line is released (someone else might be holding it)
// Wait till data line is released (someone else might be holding it)
jsr iec_wait_for_data_release
;; Wait for talker to pull CLK.
;; If over 200 usec (205 cycles on NTSC machine) , then it is EOI.
;; Loop iteraction takes 13 cycles, 17 full iterations are enough
// Wait for talker to pull CLK.
// If over 200 usec (205 cycles on NTSC machine) , then it is EOI.
// Loop iteraction takes 13 cycles, 17 full iterations are enough
ldx #$11 ; 2 cycles
ldx #$11 // 2 cycles
iec_rx_clk_wait1:
lda CIA2_PRA ; 4 cycles
rol ; 2 cycles, to put CLK in as the last bit
bpl iec_rx_not_eoi ; 2 cycles if not jumped
dex ; 2 cycles
bne iec_rx_clk_wait1 ; 3 cycles if jumped
lda CIA2_PRA // 4 cycles
rol // 2 cycles, to put CLK in as the last bit
bpl iec_rx_not_eoi // 2 cycles if not jumped
dex // 2 cycles
bne iec_rx_clk_wait1 // 3 cycles if jumped
;; Timeout - either this is the last byte of stream, or the stream is empty at all.
;; Mark end of stream in IOSTATUS
jsr kernalstatus_EOI
// Timeout - either this is the last byte of stream, or the stream is empty at all.
// Mark end of stream in IOSTATUS
jsr kernalstatus_EOI
iec_rx_not_empty:
;; Pull data for 60 usec to confirm it
// Pull data for 60 usec to confirm it
jsr iec_release_clk_pull_data
jsr iec_wait60us
jsr iec_release_clk_data
iec_rx_not_eoi:
;; Latch input bits in on rising edge of CLK, eight times for eight bits.
// Latch input bits in on rising edge of CLK, eight times for eight bits.
ldx #7
;; Get empty byte to load into.
// Get empty byte to load into.
lda #$00
pha
iec_rx_bit_loop:
;; Wait for CLK to release
// Wait for CLK to release
jsr iec_wait_for_clk_release
;; (we do this implicitly below, with a tighter routine,
;; so that we don't have timing problems, as the requirements
;; are quite tight. Basically we need to read the clock and data
;; bit from the same byte read.
// (we do this implicitly below, with a tighter routine,
// so that we don't have timing problems, as the requirements
// are quite tight. Basically we need to read the clock and data
// bit from the same byte read.
;; DATA now has the next bit, but inverted (well, except that it turns out not to be).
;; DATA is in bit 7, which is a bit annoying.
;; But we can clock it out with a ROL instruction
;; so that it is in C. We can then ROR it into the
;; partial data byte.
;; We use ROR so that we shift in from the top, so that
;; the first bit we shift in ends up in bit 0 after all
;; 8 bits have been read.
;; ODD: For some reason we don't need to invert the
;; received bits. This is weird, because we invert them
;; on the way out, and everything in the protocol seems
;; to indicate that we sould do so. But experimentation
;; has confirmed the bits don't need inversion on reception.
// DATA now has the next bit, but inverted (well, except that it turns out not to be).
// DATA is in bit 7, which is a bit annoying.
// But we can clock it out with a ROL instruction
// so that it is in C. We can then ROR it into the
// partial data byte.
// We use ROR so that we shift in from the top, so that
// the first bit we shift in ends up in bit 0 after all
// 8 bits have been read.
// ODD: For some reason we don't need to invert the
// received bits. This is weird, because we invert them
// on the way out, and everything in the protocol seems
// to indicate that we sould do so. But experimentation
// has confirmed the bits don't need inversion on reception.
;; Move data bit into C flag, and loop until bit 6 clears
;; i.e., the clock has been released.
// Move data bit into C flag, and loop until bit 6 clears
// i.e., the clock has been released.
* lda CIA2_PRA
!: lda CIA2_PRA
rol
bpl -
bpl !-
;; Pull it into the data byte
// Pull it into the data byte
pla
ror
pha
;; Wait for CLK to be pulled again, over 300 usec (307 cycles on NTSC)
;; consider this a timeout
ldy #$19 ; 2 cycles
// Wait for CLK to be pulled again, over 300 usec (307 cycles on NTSC)
// consider this a timeout
ldy #$19 // 2 cycles
iec_rx_clk_wait2:
lda CIA2_PRA ; 4 cycles
rol ; 2 cycles, to put CLK in as the last bit
bpl + ; 2 cycles if not jumped
dey ; 2 cycles
bne iec_rx_clk_wait2 ; 3 cycles if jumped
lda CIA2_PRA // 4 cycles
rol // 2 cycles, to put CLK in as the last bit
bpl !+ // 2 cycles if not jumped
dey // 2 cycles
bne iec_rx_clk_wait2 // 3 cycles if jumped
;; Timeout
// Timeout
jsr kernalstatus_EOI
pla
plp
;; Restore registers
// Restore registers
pla
tay
pla
tax
sec ; XXX confirm that sec is really a way to report timeout here
sec // XXX confirm that sec is really a way to report timeout here
rts
*
;; More bits?
!:
// More bits?
dex
bpl iec_rx_bit_loop
;; Then we must within 1000 usec acknowledge the frame by
;; pulling DATA. At this point, CLK is pulled by the
;; talker and DATA by us, i.e., we are ready to receive
;; the next byte. (p11).
// Then we must within 1000 usec acknowledge the frame by
// pulling DATA. At this point, CLK is pulled by the
// talker and DATA by us, i.e., we are ready to receive
// the next byte. (p11).
jsr iec_release_clk_pull_data
;; Retreive the received byte
// Retreive the received byte
pla
;; Return no-error
// Return no-error
plp
;; Restore registers
sta IEC_TMP2 ; $A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html
// Restore registers
sta IEC_TMP2 // $A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html
pla
tay
pla
+2 -2
View File
@@ -1,7 +1,7 @@
iec_set_idle:
lda CIA2_PRA
ora #BIT_CIA2_PRA_CLK_OUT ; pull
and #$FF - BIT_CIA2_PRA_DAT_OUT - BIT_CIA2_PRA_ATN_OUT ; release
ora #BIT_CIA2_PRA_CLK_OUT // pull
and #$FF - BIT_CIA2_PRA_DAT_OUT - BIT_CIA2_PRA_ATN_OUT // release
sta CIA2_PRA
rts
+15 -15
View File
@@ -1,37 +1,37 @@
;; According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
;; pages 7--8.
;; See also https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
// According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
// pages 7--8.
// See also https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
iec_turnaround_to_listen:
;; Store .X and .Y on the stack - preserve them
// Store .X and .Y on the stack - preserve them
txa
pha
tya
pha
;; Timing is critical here - execute on disabled IRQs
// Timing is critical here - execute on disabled IRQs
php
sei
;; Pull DATA, release CLK and ATN (we are not sending commands)
// Pull DATA, release CLK and ATN (we are not sending commands)
jsr iec_pull_data_release_atn_clk
;; Wait for clock line to be pulled by the drive
ldx #$FF ; XXX should we really use that high number?
*
// Wait for clock line to be pulled by the drive
ldx #$FF // XXX should we really use that high number?
!:
lda CIA2_PRA
rol ; to put BIT_CIA2_PRA_CLK_IN as the last (sign) bit
bpl +
rol // to put BIT_CIA2_PRA_CLK_IN as the last (sign) bit
bpl !+
dex
bne -
bne !-
;; Timeout - XXX what errors do original Kernal report?
// Timeout - XXX what errors do original Kernal report?
plp
jmp iec_return_DEVICE_NOT_FOUND
;; CLK is pulled by the device, OK
*
// CLK is pulled by the device, OK
!:
plp
jmp iec_return_success
+8 -8
View File
@@ -1,27 +1,27 @@
;; According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
;; pages 7--8.
;; See also https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
// According to http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
// pages 7--8.
// See also https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
iec_turnaround_to_talk:
;; Store .X and .Y on the stack - preserve them
// Store .X and .Y on the stack - preserve them
txa
pha
tya
pha
;; Timing is critical here - execute on disabled IRQs
// Timing is critical here - execute on disabled IRQs
php
sei
;; First make sure both CLK, DATA and ATN are released at our side
// First make sure both CLK, DATA and ATN are released at our side
jsr iec_release_atn
jsr iec_release_clk_data
;; Wait till device releases CLK line
// Wait till device releases CLK line
jsr iec_wait_for_clk_release
;; Pull CLK line, it should be held by talker
// Pull CLK line, it should be held by talker
jsr iec_pull_clk_release_data
plp
+40 -40
View File
@@ -1,96 +1,96 @@
;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
// Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
;; 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
;;
;; Preserves .X and .Y registers
// 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
//
// Preserves .X and .Y registers
iec_tx_byte:
;; Store .X and .Y on the stack - preserve them
// Store .X and .Y on the stack - preserve them
txa
pha
tya
pha
;; Notify all devices that we are going to send a byte
;; and it is going to be a data byte (released ATN)
// Notify all devices that we are going to send a byte
// and it is going to be a data byte (released ATN)
jsr iec_release_atn_clk_data
;; 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
// 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
iec_tx_common:
;; Timing is critical here - execute on disabled IRQs
// Timing is critical here - execute on disabled IRQs
php
sei
;; Wait till all receivers are ready, they should all release DATA
// Wait till all receivers are ready, they should all release DATA
jsr iec_wait_for_data_release
bcc +
bcc !+
;; 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
// 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)
!:
// 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
// Now, we can start transmission of 8 bits of data
ldx #7
iec_tx_common_sendbit:
;; Is next bit 0 or 1?
// Is next bit 0 or 1?
lda IEC_TMP2
lsr
sta IEC_TMP2
bcs +
bcs !+
;; Bit is 0
// Bit is 0
jsr iec_release_clk_pull_data
jmp iec_tx_common_bit_is_sent
*
;; Bit is 1
!:
// Bit is 1
jsr iec_release_clk_data
iec_tx_common_bit_is_sent:
;; Wait 20us, so that device(s) can pick DATA
// 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
// 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?
// 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
// Give device time to tell if they are busy by pulling DATA
// They should do it within 1ms
ldx #$FF
* lda CIA2_PRA
;; BPL here is checking that bit 7 clears,
;; i.e, that the DATA line is pulled by drive
bpl +
!: lda CIA2_PRA
// BPL here is checking that bit 7 clears,
// i.e, that the DATA line is pulled by drive
bpl !+
dex
bne -
bmi +
bne !-
bmi !+
jmp iec_return_DEVICE_NOT_FOUND
*
!:
jmp iec_return_success
+19 -19
View File
@@ -1,40 +1,40 @@
;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
// Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
;; 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
;;
;; Preserves .X and .Y registers
// 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
//
// Preserves .X and .Y registers
iec_tx_command:
;; Store .X and .Y on the stack - preserve them
// Store .X and .Y on the stack - preserve them
txa
pha
tya
pha
;; Notify all devices that we are going to send a byte
;; and it is going to be a command (pulled ATN)
// Notify all devices that we are going to send a byte
// 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!) by pulling DATA
// Give devices time to respond (response is mandatory!) by pulling DATA
jsr iec_wait1ms
lda CIA2_PRA ; pulled DATA = highest bit 0 = 'plus'
bpl +
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
;; (can be busy processing something), we have to wait till they are all
;; ready (or bored with DOS attack...)
;; Release back CLK, keep DATA released - to ask devices for status.
!:
// 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
// ready (or bored with DOS attack...)
// Release back CLK, keep DATA released - to ask devices for status.
jsr iec_release_clk_data
;; Common part of iec_txbyte and iec_tx_common - waits for devices
;; and transmits a byte
// Common part of iec_txbyte and iec_tx_common - waits for devices
// and transmits a byte
clc ; Carry flag set is used for EOI mark
clc // Carry flag set is used for EOI mark
jmp iec_tx_common
+5 -5
View File
@@ -1,18 +1,18 @@
;; Routine to finalize some IEC commands - which do not end in turnaround and are not followed by others
;; Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
// Routine to finalize some IEC commands - which do not end in turnaround and are not followed by others
// Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
iec_tx_command_finalize:
;; Store .X and .Y on the stack - preserve them
// Store .X and .Y on the stack - preserve them
txa
pha
tya
pha
;; Give device some time to complete command reception, release ATN,
;; give it some time again before (possible) next command
// Give device some time to complete command reception, release ATN,
// give it some time again before (possible) next command
jsr iec_wait20us
jsr iec_set_idle
jsr iec_wait20us
+7 -7
View File
@@ -1,15 +1,15 @@
;; Flush the IEC output buffer (if not empty) - send byte with EOI
;;
;; Preserves .X, .Y and .A registers
// Flush the IEC output buffer (if not empty) - send byte with EOI
//
// Preserves .X, .Y and .A registers
iec_tx_flush:
pha
lda C3PO
beq +
sec ; send it with EOI
jsr iec_tx_byte ; send the command regardless of the status
*
beq !+
sec // send it with EOI
jsr iec_tx_byte // send the command regardless of the status
!:
pla
rts
+11 -11
View File
@@ -1,21 +1,21 @@
;;
;; Wait 1 ms (1000 usec)
;;
;; On NTSC this means 1023 cycles (slightly less on PAL, but we have to be sure).
;; We can't count on badlines, as the screen might be disabled.
;; Delay here is implemeented using VIC-II raster register. Since one raster is
;; 63 cycles, we need at least 17 full rasters to be 100% sure we wait enough
//
// Wait 1 ms (1000 usec)
//
// On NTSC this means 1023 cycles (slightly less on PAL, but we have to be sure).
// We can't count on badlines, as the screen might be disabled.
// Delay here is implemeented using VIC-II raster register. Since one raster is
// 63 cycles, we need at least 17 full rasters to be 100% sure we wait enough
iec_wait1ms:
ldx #18 ; we probably won't start with the beginning of raster
ldx #18 // we probably won't start with the beginning of raster
lda VIC_RASTER
*
!:
cmp VIC_RASTER
beq -
beq !-
lda VIC_RASTER
dex
bne -
bne !-
rts
+15 -15
View File
@@ -1,22 +1,22 @@
iec_wait20us:
;; Wait 20usec
// Wait 20usec
;; PAL:
;; - CPU frequency 0.985248 MHz, we need to waste at least 20 cycles
;; NTSC:
;; - CPU frequency 1.022727 MHz, we need to waste at least 21 cycles
// PAL:
// - CPU frequency 0.985248 MHz, we need to waste at least 20 cycles
// NTSC:
// - CPU frequency 1.022727 MHz, we need to waste at least 21 cycles
;; Waste cycles by reading some unimportant memory location
;; in order not to clutter VICE debug logs
// Waste cycles by reading some unimportant memory location
// in order not to clutter VICE debug logs
ora $03FF ; 4 cycles
ora $03FF ; 4 cycles
rts ; 6 cycles
ora $03FF // 4 cycles
ora $03FF // 4 cycles
rts // 6 cycles
;; 6 cycles JSR to routine,
;; 14 cycles routine with RTS
;; 1 cycle to fetch next instruction
;; ---
;; 21 cycles
// 6 cycles JSR to routine,
// 14 cycles routine with RTS
// 1 cycle to fetch next instruction
// ---
// 21 cycles
+15 -15
View File
@@ -1,23 +1,23 @@
iec_wait60us:
;; Wait 60usec
// Wait 60usec
;; PAL:
;; - CPU frequency 0.985248 MHz, we need to waste at least 60 cycles
;; NTSC:
;; - CPU frequency 1.022727 MHz, we need to waste at least 62 cycles
// PAL:
// - CPU frequency 0.985248 MHz, we need to waste at least 60 cycles
// NTSC:
// - CPU frequency 1.022727 MHz, we need to waste at least 62 cycles
;; Waste cycles in a loop
// Waste cycles in a loop
ldy #$0A ; 2 cycles
* dey ; 2 cycles * 10
bpl - ; 3 cycles * 9 + 2 cycles
rts ; 6 cycles
ldy #$0A // 2 cycles
!: dey // 2 cycles * 10
bpl !- // 3 cycles * 9 + 2 cycles
rts // 6 cycles
;; 6 cycles JSR to routine,
;; 57 cycles routine with RTS
;; 1 cycle to fetch next instruction
;; ---
;; 64 cycles
// 6 cycles JSR to routine,
// 57 cycles routine with RTS
// 1 cycle to fetch next instruction
// ---
// 64 cycles
+2 -2
View File
@@ -2,7 +2,7 @@
iec_wait_for_data_pull:
lda CIA2_PRA
;; Check the highest bit, which is DATA IN,
;; (highest bit set = negative value)
// Check the highest bit, which is DATA IN,
// (highest bit set = negative value)
bmi iec_wait_for_data_pull
rts
+2 -2
View File
@@ -2,7 +2,7 @@
iec_wait_for_data_release:
lda CIA2_PRA
;; Check the highest bit, which is DATA IN,
;; (highest bit set = negative value)
// Check the highest bit, which is DATA IN,
// (highest bit set = negative value)
bpl iec_wait_for_data_release
rts
@@ -1,9 +1,10 @@
default_irq_handler:
default_irq_handler:
jsr blink_cursor
jsr JSCNKEY
jsr JUDTIM ; update jiffy clock
jsr JUDTIM // update jiffy clock
;; Acknowledge CIA interrupt and return
// Acknowledge CIA interrupt and return
jmp clear_cia1_interrupt_flag_and_return_from_interrupt
@@ -1,11 +1,11 @@
;; https://csdb.dk/forums/index.php?roomid=11&topicid=5776
;; Clear the CIA1 interrupt flag, and then fall through to
;; the return from interrupt routine
// https://csdb.dk/forums/index.php?roomid=11&topicid=5776
// Clear the CIA1 interrupt flag, and then fall through to
// the return from interrupt routine
clear_cia1_interrupt_flag_and_return_from_interrupt:
;; We have free choice of LDA, LDX or LDY to achieve this goal
;; in 3 bytes and minimum cycles. Thus we randomly choose LDY.
LDY $DC0D
// We have free choice of LDA, LDX or LDY to achieve this goal
// in 3 bytes and minimum cycles. Thus we randomly choose LDY.
ldy CIA1_ICR
;; FALL THROUGH to $EA81
// FALL THROUGH to $EA81
@@ -1,18 +1,20 @@
;; The IRQ is a commonly messed with thing on the C64,
;; so we need to handle entry points that are commonly
;; relied upon, including:
;; $EA31 - Standard IRQ routine
;; $EA61 - Check keyboard, but don't update timer? https://github.com/cc65/cc65/issues/324
;; $EA81 - https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb
;; Also the $0314 vector is widely used (e.g., https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb)
// The IRQ is a commonly messed with thing on the C64,
// so we need to handle entry points that are commonly
// relied upon, including:
// $EA31 - Standard IRQ routine
// $EA61 - Check keyboard, but don't update timer? https://github.com/cc65/cc65/issues/324
// $EA81 - https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb
// Also the $0314 vector is widely used (e.g., https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb)
return_from_interrupt:
;; Restore registers and return
;; Sequence according to Compute's Mapping the 64 p73
// Restore registers and return
// Sequence according to Compute's Mapping the 64 p73
pla
tay
pla
tax
pla
rti
@@ -1,34 +1,33 @@
default_nmi_handler:
;; Implemented according to Compute's Mapping the Commodore 64, page 74
;; and to https://www.c64-wiki.com/wiki/Interrupt
// Implemented according to Compute's Mapping the Commodore 64, page 74
// and to https://www.c64-wiki.com/wiki/Interrupt
;; Save registers, sequence according to Compute's Mapping the Commodore 64, page 73
// Save registers, sequence according to Compute's Mapping the Commodore 64, page 73
pha
txa
pha
tya
pha
;; XXX: RS-232 support is not implemented
// XXX: RS-232 support is not implemented
;; XXX confirm NMIs from CIA, or no other NMI will arrive!
// XXX confirm NMIs from CIA, or no other NMI will arrive!
jsr cartridge_check
bcc +
bcc !+
jmp (ICART_WARM_START)
*
!:
;; According to C64 Wiki, if STOP key is pressed, the routine assumes warm start request
// According to C64 Wiki, if STOP key is pressed, the routine assumes warm start request
jsr JSTOP
bcs +
jmp return_from_interrupt ; no STOP pressed
*
;; STOP + RESTORE - clean the address of the BRK instruction (it's not BRK) first
bcs !+
jmp return_from_interrupt // no STOP pressed
!:
// STOP + RESTORE - clean the address of the BRK instruction (it's not BRK) first
lda #$00
sta CMP0+0
sta CMP0+1
jmp (CBINV)
@@ -1,13 +1,13 @@
default_brk_handler:
;; Implemented according to Compute's Mapping the Commodore 64, pages 73-74
// Implemented according to Compute's Mapping the Commodore 64, pages 73-74
sei ; disable IRQs, to be sure they won't interfere
sei // disable IRQs, to be sure they won't interfere
jsr JRESTOR
jsr JIOINIT
jsr CINT_BRK
jsr cint_brk
cli
+16 -16
View File
@@ -1,38 +1,38 @@
irq_handler:
;; The IRQ is a commonly messed with thing on the C64,
;; so we need to handle entry points that are commonly
;; relied upon, including:
;; $EA31 - Standard IRQ routine
;; $EA61 - Check keyboard, but don't update timer? https://github.com/cc65/cc65/issues/324
;; $EA81 - https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb
;; Also the $0314 vector is widely used (e.g., https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb)
// The IRQ is a commonly messed with thing on the C64,
// so we need to handle entry points that are commonly
// relied upon, including:
// $EA31 - Standard IRQ routine
// $EA61 - Check keyboard, but don't update timer? https://github.com/cc65/cc65/issues/324
// $EA81 - https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb
// Also the $0314 vector is widely used (e.g., https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb)
;; Save registers, sequence according to Compute's Mapping the Commodore 64, page 73
// Save registers, sequence according to Compute's Mapping the Commodore 64, page 73
pha
txa
pha
tya
pha
;; Check if caused by BRK
// Check if caused by BRK
tsx
lda $0104, x ; get the pre-interrupt processor state
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)
// Not caused by BRK - call interrupt routine (only if initialised)
lda CINV
ora CINV+1
beq +
beq !+
jmp (CINV)
*
;; Vector not initialized - call default interrupt routine
!:
// Vector not initialized - call default interrupt routine
jmp default_irq_handler
irq_handler_brk:
;; Store BRK adddress, to be displayed
// Store BRK adddress, to be displayed
sec
lda $0105, x
sbc #$02
@@ -41,6 +41,6 @@ irq_handler_brk:
sbc #$00
sta CMP0+1
;; Interrupt caused by BRK
// Interrupt caused by BRK
jmp (CBINV)
+5 -5
View File
@@ -1,17 +1,17 @@
nmi_handler:
sei ;; don't allow IRQ to interfere, see https://www.c64-wiki.com/wiki/Interrupt
sei // don't allow IRQ to interfere, see https://www.c64-wiki.com/wiki/Interrupt
;; Call interrupt routine (only if initialised)
// Call interrupt routine (only if initialised)
pha
lda NMINV
ora NMINV+1
beq +
beq !+
pla
jmp (NMINV)
*
;; Vector not initialized - call default interrupt routine
!:
// Vector not initialized - call default interrupt routine
pla
jmp default_nmi_handler
+4 -3
View File
@@ -1,3 +1,4 @@
; Initialise screen editor
; C64 Programmer's Reference Guide Page 272
jmp cint
// Initialise screen editor
// C64 Programmer's Reference Guide Page 272
jmp CINT
+4 -3
View File
@@ -1,3 +1,4 @@
; Initialise input/output
; C64 Programmer's Reference Guide Page 272
jmp ioinit
// Initialise input/output
// C64 Programmer's Reference Guide Page 272
jmp IOINIT
+4 -3
View File
@@ -1,3 +1,4 @@
; Initialise RAM, allocate tape buffer, set screen to $0400
; C64 Programmer's Reference Guide Page 273
jmp ramtas
// Initialise RAM, allocate tape buffer, set screen to $0400
// C64 Programmer's Reference Guide Page 273
jmp RAMTAS
+4 -3
View File
@@ -1,3 +1,4 @@
; Restore default IO vectors
; C64 Programmer's Reference Guide Page 273
jmp restor
// Restore default IO vectors
// C64 Programmer's Reference Guide Page 273
jmp RESTOR
+4 -3
View File
@@ -1,3 +1,4 @@
; Read/set vectored I/O
; C64 Programmer's Reference Guide Page 273
jmp vector
// Read/set vectored I/O
// C64 Programmer's Reference Guide Page 273
jmp VECTOR
+4 -3
View File
@@ -1,3 +1,4 @@
; Control KERNAL messages
; C64 Programmer's Reference Guide Page 273
jmp setmsg
// Control KERNAL messages
// C64 Programmer's Reference Guide Page 273
jmp SETMSG
+4 -3
View File
@@ -1,3 +1,4 @@
; SEnd secondary address after LISTEN
; C64 Programmer's Reference Guide Page 273
jmp second
// Send secondary address after LISTEN
// C64 Programmer's Reference Guide Page 273
jmp SECOND
+4 -3
View File
@@ -1,3 +1,4 @@
; Send secondary address after talk
; C64 Programmer's Reference Guide Page 273
jmp tksa
// Send secondary address after talk
// C64 Programmer's Reference Guide Page 273
jmp TKSA
+4 -3
View File
@@ -1,3 +1,4 @@
; read/set the top of memory
; C64 Programmer's Reference Guide Page 272
jmp memtop
// read/set the top of memory
// C64 Programmer's Reference Guide Page 272
jmp MEMTOP
+4 -3
View File
@@ -1,3 +1,4 @@
; read/set the bottom of memory
; C64 Programmer's Reference Guide Page 272
jmp membot
// read/set the bottom of memory
// C64 Programmer's Reference Guide Page 272
jmp MEMBOT
+3 -2
View File
@@ -1,3 +1,4 @@
; Scan keyboard
; C64 Programmer's Reference Guide Page 273
// Scan keyboard
// C64 Programmer's Reference Guide Page 273
jmp SCNKEY
+4 -3
View File
@@ -1,3 +1,4 @@
; Set timeout on serial bus
; C64 Programmer's Reference Guide Page 273
jmp settmo
// Set timeout on serial bus
// C64 Programmer's Reference Guide Page 273
jmp SETTMO
+4 -3
View File
@@ -1,3 +1,4 @@
; Input byte from serial port
; C64 Programmer's Reference Guide Page 272
jmp acptr
// Input byte from serial port
// C64 Programmer's Reference Guide Page 272
jmp ACPTR
+4 -3
View File
@@ -1,3 +1,4 @@
; Output byte to serial port
; C64 Programmer's Reference Guide Page 272
jmp ciout
// Output byte to serial port
// C64 Programmer's Reference Guide Page 272
jmp CIOUT
+4 -3
View File
@@ -1,3 +1,4 @@
; Command serial bus to UNTALK
; C64 Programmer's Reference Guide Page 273
jmp untlk
// Command serial bus to UNTALK
// C64 Programmer's Reference Guide Page 273
jmp UNTLK
+4 -3
View File
@@ -1,3 +1,4 @@
; Command serial bus to UNLISTEN
; C64 Programmer's Reference Guide Page 273
jmp unlsn
// Command serial bus to UNLISTEN
// C64 Programmer's Reference Guide Page 273
jmp UNLSN
+4 -3
View File
@@ -1,3 +1,4 @@
; Command devices on the serial bus to listen
; C64 Programmer's Reference Guide Page 272
jmp listen
// Command devices on the serial bus to listen
// C64 Programmer's Reference Guide Page 272
jmp LISTEN
+4 -3
View File
@@ -1,3 +1,4 @@
; Command serial bus device to talk
; C64 Programmer's Reference Guide Page 273
jmp talk
// Command serial bus device to talk
// C64 Programmer's Reference Guide Page 273
jmp TALK
+4 -3
View File
@@ -1,3 +1,4 @@
; Read I/O statusjmp
; C64 Programmer's Reference Guide Page 273
jmp readst
// Read I/O statusjmp
// C64 Programmer's Reference Guide Page 273
jmp READST
+4 -3
View File
@@ -1,3 +1,4 @@
; Set logical, first and second addresses
; C64 Programmer's Reference Guide Page 273
jmp setfls
// Set logical, first and second addresses
// C64 Programmer's Reference Guide Page 273
jmp SETFLS
+4 -3
View File
@@ -1,3 +1,4 @@
; Set file name
; C64 Programmer's Reference Guide Page 273
jmp setnam
// Set file name
// C64 Programmer's Reference Guide Page 273
jmp SETNAM
+4 -3
View File
@@ -1,4 +1,5 @@
; open a logical file
; C64 Programmer's Reference Guide Page 272
; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect
// open a logical file
// C64 Programmer's Reference Guide Page 272
// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect
jmp (IOPEN)
+4 -3
View File
@@ -1,4 +1,5 @@
; close a specified logical file
; C64 Programmer's Reference Guide Page 272
; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect
// close a specified logical file
// C64 Programmer's Reference Guide Page 272
// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect
jmp (ICLOSE)
+4 -3
View File
@@ -1,4 +1,5 @@
; Open channel for input
; C64 Programmer's Reference Guide Page 272
; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect
// Open channel for input
// C64 Programmer's Reference Guide Page 272
// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect
jmp (ICHKIN)
+4 -3
View File
@@ -1,4 +1,5 @@
; Open channel for output
; C64 Programmer's Reference Guide Page 272
; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect
// Open channel for output
// C64 Programmer's Reference Guide Page 272
// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect
jmp (ICKOUT)
+4 -3
View File
@@ -1,4 +1,5 @@
; close input and output channels
; C64 Programmer's Reference Guide Page 272
; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect
// close input and output channels
// C64 Programmer's Reference Guide Page 272
// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect
jmp (ICLRCH)
+4 -3
View File
@@ -1,4 +1,5 @@
; Input character from channel
; C64 Programmer's Reference Guide Page 272
; According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect
// Input character from channel
// C64 Programmer's Reference Guide Page 272
// According to Compute's Mapping the Commodore 64 (pages 74/75), this jump is indirect
jmp (IBASIN)
Loaded 100 of 198 files, more files were not shown because too many files have changed in this diff. Show more