adapted to Kick Assembler, some documentation update
This commit is contained in:
1 parent
ae23dbae7b
commit
de27124b4f
198 files changed
+4181
-3976
No files matched your search
+70
-68
@@ -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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
;; Target-specific hooks
|
||||
// Target-specific hooks
|
||||
|
||||
|
||||
.macro TARGET_HOOK_LOAD
|
||||
.macend
|
||||
.macro TARGET_HOOK_LOAD() {
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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,4 +1,4 @@
|
||||
; c64 prg p263
|
||||
// c64 prg p263
|
||||
|
||||
cartridge_check:
|
||||
ldx #$04
|
||||
|
||||
+37
-37
@@ -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
@@ -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
File diff suppressed because it is too large.
Load diff
+40
-40
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
;; Home the cursor
|
||||
;; (Compute's Mapping the 64 p216)
|
||||
// Home the cursor
|
||||
// (Compute's Mapping the 64 p216)
|
||||
|
||||
home_cursor:
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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,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,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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,3 +1,4 @@
|
||||
; Scan keyboard
|
||||
; C64 Programmer's Reference Guide Page 273
|
||||
// Scan keyboard
|
||||
// C64 Programmer's Reference Guide Page 273
|
||||
|
||||
jmp SCNKEY
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
Reference in new issue
Block a user