more sane directory name, updated binaries
This commit is contained in:
1 parent
d4d32095d1
commit
76aaf298b8
697 files changed
+56
-56
No files matched your search
@@ -0,0 +1,55 @@
|
||||
|
||||
// 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
|
||||
.label U64_CONTROL_STATUS = $DF1C // write = CONTROL, read = STATUS
|
||||
.label U64_COMMAND_DATA_IDENTIFY = $DF1D // write = COMMAND_DATA, read = IDENTIFICATION
|
||||
.label U64_RESPONSE_DATA = $DF1E // read only
|
||||
.label U64_STATUS_DATA = $DF1F // read only
|
||||
|
||||
// Constant for U64_IDENTIFICATION register
|
||||
.const U64_MAGIC_ID = $C9
|
||||
|
||||
// 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
|
||||
.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
|
||||
.const U64_TARGET_DOS1 = $01
|
||||
.const U64_TARGET_DOS2 = $02
|
||||
|
||||
// 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
|
||||
.const U64_FA_READ = $01
|
||||
.const U64_FA_WRITE = $02
|
||||
.const U64_FA_CREATE_NEW = $03
|
||||
.const U64_FA_CREATE_ALWAYS = $04
|
||||
@@ -0,0 +1,134 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// LOAD routine hook for fast loading via UltiDOS
|
||||
//
|
||||
|
||||
|
||||
u64_load:
|
||||
|
||||
// First check whether the command interface is enabled
|
||||
lda U64_IDENTIFICATION
|
||||
cmp #U64_MAGIC_ID
|
||||
beq !+
|
||||
|
||||
u64_load_skip:
|
||||
rts
|
||||
!:
|
||||
// XXX find out which device number softIEC is mapped to
|
||||
lda current_device_number
|
||||
cmp #$20 // for now use device number 32
|
||||
bne u64_load_skip
|
||||
|
||||
// Takeover the flow completely
|
||||
pla
|
||||
pla
|
||||
|
||||
// Display SEARCHING FOR + filename
|
||||
jsr lvs_display_searching_for
|
||||
|
||||
// Whatever the interface was doing - ask to abort it
|
||||
jsr u64_load_abort
|
||||
|
||||
// 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
|
||||
jsr u64_load_check_status
|
||||
bcs lvs_file_not_found_error
|
||||
|
||||
// Load first two bytes to determine start address
|
||||
|
||||
// XXX
|
||||
|
||||
jsr printf
|
||||
.text "DBG: NOT IMPLEMENTED"
|
||||
.byte $0D,0
|
||||
|
||||
jmp lvs_wrap_around_error
|
||||
rts
|
||||
|
||||
u64_load_abort:
|
||||
lda #U64_CTRL_BIT_ABORT
|
||||
sta U64_CONTROL
|
||||
!:
|
||||
lda U64_STATUS
|
||||
bne !-
|
||||
rts
|
||||
|
||||
u64_load_send_cmd:
|
||||
|
||||
ldx #U64_TARGET_DOS2
|
||||
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 !+
|
||||
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
|
||||
lda #U64_CTRL_BIT_PUSH_CMD
|
||||
sta U64_CONTROL
|
||||
// Wait till it is complete
|
||||
!:
|
||||
lda U64_STATUS
|
||||
and #U64_STAT_BIT_CMD_BUSY
|
||||
bne !-
|
||||
rts
|
||||
|
||||
u64_load_check_status:
|
||||
// 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
|
||||
lda U64_STATUS_DATA
|
||||
jsr JCHROUT // XXX for test only
|
||||
cmp #$30 // '0'
|
||||
bne u64_load_check_status_wrong
|
||||
|
||||
// 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'
|
||||
beq u64_load_check_status_ok
|
||||
|
||||
// FALLTROUGH
|
||||
u64_load_check_status_wrong:
|
||||
sec
|
||||
bcs !+
|
||||
u64_load_check_status_ok:
|
||||
clc
|
||||
!:
|
||||
// Now empty the status queue
|
||||
lda U64_STATUS
|
||||
and #U64_STAT_BIT_STAT_AV
|
||||
beq !+
|
||||
lda U64_STATUS_DATA
|
||||
jsr JCHROUT // XXX for test only
|
||||
jmp !-
|
||||
!:
|
||||
rts
|
||||
@@ -0,0 +1,8 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
// XXX provide documentation and implementation
|
||||
|
||||
STUB_IMPLEMENTATION()
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
This is a well-known address, needed even for some BASIC programming - it's a common target for a SYS command. See for example here:
|
||||
|
||||
- http://ready64.org/articoli/_files/043_pokesc64.txt
|
||||
sys 59062 - Advance Cursor
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
This is a well-known address, needed even for some BASIC programming - it's a common target for a SYS command. See for example here:
|
||||
|
||||
- http://ready64.org/articoli/_files/043_pokesc64.txt
|
||||
sys 59137 - Previous Line
|
||||
@@ -0,0 +1,8 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
// XXX provide documentation and implementation
|
||||
|
||||
STUB_IMPLEMENTATION()
|
||||
@@ -0,0 +1,8 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
// Screen CHROUT
|
||||
|
||||
STUB_IMPLEMENTATION()
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
This routine is called at least by the Final Cartridge III. See:
|
||||
- https://github.com/mist64/final_cartridge/blob/master/core/kernal_c64.i
|
||||
@@ -0,0 +1,8 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
// Insert line at top of screen
|
||||
|
||||
STUB_IMPLEMENTATION()
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
This routine is called at least by the Final Cartridge III. See:
|
||||
- https://github.com/mist64/final_cartridge/blob/master/core/kernal_c64.i
|
||||
@@ -0,0 +1 @@
|
||||
Routine is called by Lemmings game, purpose unknown so far
|
||||
@@ -0,0 +1,8 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
// XXX provide documentation and implementation
|
||||
|
||||
STUB_IMPLEMENTATION()
|
||||
@@ -0,0 +1,8 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
// IEC close
|
||||
|
||||
STUB_IMPLEMENTATION()
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
This routine is called at least by the Final Cartridge III. See:
|
||||
- https://github.com/mist64/final_cartridge/blob/master/core/kernal_c64.i
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
This routine is probably used by many cartridges and other software to initialize parts of the system. At least the UCart uses it - see here:
|
||||
|
||||
- https://www.elektroda.pl/rtvforum/topic3293027.html
|
||||
@@ -0,0 +1,8 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
// XXX provide documentation and implementation
|
||||
|
||||
STUB_IMPLEMENTATION()
|
||||
@@ -0,0 +1,9 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# X16 * #IGNORE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
cartridge_signature:
|
||||
|
||||
.byte $C3,$C2,$CD,$38,$30
|
||||
@@ -0,0 +1,10 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
// CHR$ codes for the 16 colours
|
||||
|
||||
colour_codes:
|
||||
.byte 144,5,28,159,156,30,31,158
|
||||
.byte 129,149,150,151,152,153,154,155
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
A color code table, see here:
|
||||
- https://csdb.dk/forums/index.php?roomid=7&topicid=487
|
||||
|
||||
CCGMS termina program expects it to be under original location, see here:
|
||||
- https://raw.githubusercontent.com/spathiwa/ccgmsterm/master/original/5a.gs
|
||||
@@ -0,0 +1,3 @@
|
||||
Location of the default Kernal vector values, described in Compute's Mapping the Commodore 64, page 237
|
||||
|
||||
It is referenced by GEOS - see https://github.com/mist64/geos/blob/master/inc/c64.inc
|
||||
@@ -0,0 +1,29 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Default values for Kernal vectors - described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 293 (RESTOR), 304 (VECTOR)
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 237
|
||||
//
|
||||
|
||||
vector_defaults:
|
||||
.word default_irq_handler // CINV
|
||||
.word default_brk_handler // CBINV
|
||||
.word default_nmi_handler // NMINV
|
||||
|
||||
.word OPEN // IOPEN
|
||||
.word CLOSE // ICLOSE
|
||||
.word CHKIN // ICHKIN
|
||||
.word CKOUT // ICKOUT
|
||||
.word CLRCHN // ICLRCH
|
||||
.word CHRIN // IBASIN
|
||||
.word CHROUT // IBSOUT
|
||||
.word STOP // ISTOP
|
||||
.word GETIN // IGETIN
|
||||
.word CLALL // ICLALL
|
||||
.word default_brk_handler // USRCMD
|
||||
.word LOAD // ILOAD
|
||||
.word SAVE // ISAVE
|
||||
@@ -0,0 +1,8 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
filename_any:
|
||||
|
||||
.text "*"
|
||||
@@ -0,0 +1,26 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Values for IRQ generation timer - original idea was:
|
||||
//
|
||||
// (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
|
||||
|
||||
// Current values selected on the following assumptions:
|
||||
//
|
||||
// PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
|
||||
// is clocked at 0.985248 MHz, so that 1/60s is 16421 ($4025) 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 ($4295) CPU cycles
|
||||
|
||||
|
||||
irq_timing_hi: // high bytes
|
||||
|
||||
.byte >17045 // NTSC
|
||||
.byte >16421 // PAL
|
||||
@@ -0,0 +1,26 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Values for IRQ generation timer - original idea was:
|
||||
//
|
||||
// (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
|
||||
|
||||
// Current values selected on the following assumptions:
|
||||
//
|
||||
// PAL C64 (https://codebase64.org/doku.php?id=base:cpu_clocking),
|
||||
// is clocked at 0.985248 MHz, so that 1/60s is 16421 ($4025) 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 ($4295) CPU cycles
|
||||
|
||||
|
||||
irq_timing_lo: // low bytes
|
||||
|
||||
.byte <17045 // NTSC
|
||||
.byte <16421 // PAL
|
||||
@@ -0,0 +1,98 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Messages to be prined out by Kernal
|
||||
//
|
||||
|
||||
.encoding "petscii_upper"
|
||||
|
||||
|
||||
// Double underscore prevents labels from being passed to VICE (would confuse monitor)
|
||||
|
||||
.label __MSG_KERNAL_SEARCHING_FOR = __msg_kernalsearching_for - __msg_kernal_first
|
||||
.label __MSG_KERNAL_LOADING = __msg_kernalloading - __msg_kernal_first
|
||||
.label __MSG_KERNAL_VERIFYING = __msg_kernalverifying - __msg_kernal_first
|
||||
.label __MSG_KERNAL_SAVING = __msg_kernalsaving - __msg_kernal_first
|
||||
.label __MSG_KERNAL_FROM_HEX = __msg_kernalfrom_hex - __msg_kernal_first
|
||||
.label __MSG_KERNAL_TO_HEX = __msg_kernalto_hex - __msg_kernal_first
|
||||
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
.label __MSG_KERNAL_PRESS_PLAY = __msg_kernalplay - __msg_kernal_first
|
||||
.label __MSG_KERNAL_FOUND = __msg_kernalfound - __msg_kernal_first
|
||||
#if CONFIG_MB_MEGA_65
|
||||
.label __MSG_KERNAL_OK_SEARCHING = __msg_kernaloksearching - __msg_kernal_first
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_PANIC_SCREEN
|
||||
.label __MSG_KERNAL_PANIC = __msg_kernalpanic - __msg_kernal_first
|
||||
.label __MSG_KERNAL_PANIC_ROM_MISMATCH = __msg_kernalpanic_rom_mismatch - __msg_kernal_first
|
||||
#endif
|
||||
|
||||
|
||||
__msg_kernal_first:
|
||||
|
||||
__msg_kernalsearching_for:
|
||||
.byte $0D
|
||||
.text "SEARCHING FOR"
|
||||
.byte $80 + $20 // end of string mark + space
|
||||
|
||||
__msg_kernalloading:
|
||||
.byte $0D
|
||||
.text "LOADIN"
|
||||
.byte $80 + $47 // end of string mark + 'G'
|
||||
|
||||
__msg_kernalverifying:
|
||||
.byte $0D
|
||||
.text "VERIFYIN"
|
||||
.byte $80 + $47 // end of string mark + 'G'
|
||||
|
||||
__msg_kernalsaving:
|
||||
.byte $0D
|
||||
.text "SAVING"
|
||||
.byte $80 + $20 // end of string mark + space
|
||||
|
||||
__msg_kernalfrom_hex:
|
||||
.text " FROM "
|
||||
.byte $80 + $24 // end of string mark + '$'
|
||||
|
||||
__msg_kernalto_hex:
|
||||
.text " TO "
|
||||
.byte $80 + $24 // end of string mark + '$'
|
||||
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
|
||||
__msg_kernalplay:
|
||||
.byte $0D
|
||||
.text "PRESS PLAY ON TAPE"
|
||||
.byte $80 + $0D // end of string mark + return
|
||||
|
||||
__msg_kernalfound:
|
||||
.text "FOUND"
|
||||
.byte $80 + $20 // end of string mark + space
|
||||
|
||||
#if CONFIG_MB_MEGA_65
|
||||
|
||||
__msg_kernaloksearching:
|
||||
.text "OK"
|
||||
.byte $0D, $0D
|
||||
.text "SEARCHIN"
|
||||
.byte $80 + $47 // end of string mark + 'G'
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if CONFIG_PANIC_SCREEN
|
||||
|
||||
__msg_kernalpanic:
|
||||
.text "KERNAL PANI"
|
||||
.byte $80 + $43 // end of string mark + 'C'
|
||||
|
||||
__msg_kernalpanic_rom_mismatch:
|
||||
.text " - ROM MISMATC"
|
||||
.byte $80 + $48 // end of string mark + 'H'
|
||||
|
||||
#endif // CONFIG_PANIC_SCREEN
|
||||
@@ -0,0 +1,128 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Command string definitions for programmable keys
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_PROGRAMMABLE_KEYS
|
||||
|
||||
|
||||
.macro PROGRAMMABLE_KEY_CODE(STR, CODE)
|
||||
{
|
||||
.if (STR.size() > 0)
|
||||
{
|
||||
.byte CODE
|
||||
}
|
||||
}
|
||||
|
||||
.macro PROGRAMMABLE_KEY_STRING(STR)
|
||||
{
|
||||
.if (STR.size() > 0)
|
||||
{
|
||||
.text STR
|
||||
.byte $00
|
||||
}
|
||||
}
|
||||
|
||||
.macro PROGRAMMABLE_KEY_OFFSET(STR, LABEL)
|
||||
{
|
||||
.if (STR.size() > 0)
|
||||
{
|
||||
.byte LABEL - programmable_keys_strings
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
programmable_keys_codes:
|
||||
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_RUN, KEY_RUN)
|
||||
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F1, KEY_F1)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F2, KEY_F2)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F3, KEY_F3)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F4, KEY_F4)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F5, KEY_F5)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F6, KEY_F6)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F7, KEY_F7)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F8, KEY_F8)
|
||||
|
||||
#if !CONFIG_LEGACY_SCNKEY && (CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C65)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_HELP, KEY_HELP)
|
||||
#endif
|
||||
|
||||
#if !CONFIG_LEGACY_SCNKEY && CONFIG_KEYBOARD_C65
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F9, KEY_F9)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F10, KEY_F10)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F11, KEY_F11)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F12, KEY_F12)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F13, KEY_F13)
|
||||
PROGRAMMABLE_KEY_CODE(CONFIG_KEYCMD_F14, KEY_F14)
|
||||
#endif
|
||||
|
||||
__programmable_keys_codes_end:
|
||||
|
||||
|
||||
programmable_keys_strings:
|
||||
|
||||
__str_offset_RUN: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_RUN)
|
||||
|
||||
__str_offset_F1: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F1)
|
||||
__str_offset_F2: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F2)
|
||||
__str_offset_F3: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F3)
|
||||
__str_offset_F4: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F4)
|
||||
__str_offset_F5: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F5)
|
||||
__str_offset_F6: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F6)
|
||||
__str_offset_F7: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F7)
|
||||
__str_offset_F8: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F8)
|
||||
|
||||
#if !CONFIG_LEGACY_SCNKEY && (CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C65)
|
||||
__str_offset_HELP: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_HELP)
|
||||
#endif
|
||||
|
||||
#if !CONFIG_LEGACY_SCNKEY && CONFIG_KEYBOARD_C65
|
||||
__str_offset_F9: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F9)
|
||||
__str_offset_F10: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F10)
|
||||
__str_offset_F11: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F11)
|
||||
__str_offset_F12: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F12)
|
||||
__str_offset_F13: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F13)
|
||||
__str_offset_F14: PROGRAMMABLE_KEY_STRING(CONFIG_KEYCMD_F14)
|
||||
#endif
|
||||
|
||||
__programmable_keys_strings_end:
|
||||
{
|
||||
.var offset = __programmable_keys_strings_end - programmable_keys_strings
|
||||
.if (offset >= 255) .error "Programmable keys took too much space"
|
||||
}
|
||||
|
||||
|
||||
programmable_keys_offsets:
|
||||
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_RUN, __str_offset_RUN)
|
||||
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F1, __str_offset_F1)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F2, __str_offset_F2)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F3, __str_offset_F3)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F4, __str_offset_F4)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F5, __str_offset_F5)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F6, __str_offset_F6)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F7, __str_offset_F7)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F8, __str_offset_F8)
|
||||
|
||||
#if !CONFIG_LEGACY_SCNKEY && (CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C65)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_HELP, __str_offset_HELP)
|
||||
#endif
|
||||
|
||||
#if !CONFIG_LEGACY_SCNKEY && CONFIG_KEYBOARD_C65
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F9, __str_offset_F9)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F10, __str_offset_F10)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F11, __str_offset_F11)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F12, __str_offset_F12)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F13, __str_offset_F13)
|
||||
PROGRAMMABLE_KEY_OFFSET(CONFIG_KEYCMD_F14, __str_offset_F14)
|
||||
#endif
|
||||
|
||||
|
||||
#endif // CONFIG_PROGRAMMABLE_KEYS
|
||||
@@ -0,0 +1 @@
|
||||
This particular address is not for interoperability - we had to choose some fixed location foor the extended ROM jumptable, beginning of the mapped memory block is just sane.
|
||||
@@ -0,0 +1,54 @@
|
||||
// #LAYOUT# M65 KERNAL_0 #TAKE-FLOAT
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Definitions for communication with Mega65 segment KERNAL_1 from KERNAL_0
|
||||
//
|
||||
|
||||
|
||||
#if SEGMENT_KERNAL_0
|
||||
|
||||
// Label definitions
|
||||
|
||||
.label VK1__IOINIT = $4000 + 2 * 0
|
||||
.label VK1__RAMTAS = $4000 + 2 * 1
|
||||
.label VK1__setup_vicii = $4000 + 2 * 2
|
||||
.label VK1__load_tape_normal = $4000 + 2 * 3
|
||||
.label VK1__load_tape_turbo = $4000 + 2 * 4
|
||||
.label VK1__load_tape_auto = $4000 + 2 * 5
|
||||
.label VK1__tape_head_align = $4000 + 2 * 6
|
||||
|
||||
#else
|
||||
|
||||
// Vector table (OpenROMs private!)
|
||||
|
||||
.word IOINIT
|
||||
.word RAMTAS
|
||||
.word setup_vicii
|
||||
|
||||
#if CONFIG_TAPE_NORMAL && !CONFIG_TAPE_AUTODETECT
|
||||
.word load_tape_normal
|
||||
#else
|
||||
.word $0000
|
||||
#endif
|
||||
|
||||
#if CONFIG_TAPE_TURBO && !CONFIG_TAPE_AUTODETECT
|
||||
.word load_tape_turbo
|
||||
#else
|
||||
.word $0000
|
||||
#endif
|
||||
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
.word load_tape_auto
|
||||
#else
|
||||
.word $0000
|
||||
#endif
|
||||
|
||||
#if CONFIG_TAPE_HEAD_ALIGN
|
||||
.word tape_head_align
|
||||
#else
|
||||
.word $0000
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,68 @@
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Definitions for calling Mega65 segment KERNAL_0 routines from KERNAL_1
|
||||
//
|
||||
|
||||
#import "KERNAL_0_combined.sym"
|
||||
|
||||
|
||||
.label STOP = KERNAL_0.STOP
|
||||
|
||||
.label hw_entry_reset = KERNAL_0.hw_entry_reset
|
||||
.label return_from_interrupt = KERNAL_0.return_from_interrupt
|
||||
.label clrchn_reset = KERNAL_0.clrchn_reset
|
||||
.label udtim_keyboard = KERNAL_0.udtim_keyboard
|
||||
|
||||
.label setup_irq_timer = KERNAL_0.setup_irq_timer
|
||||
.label wait_x_bars = KERNAL_0.wait_x_bars
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
.label iec_set_idle = KERNAL_0.iec_set_idle
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
|
||||
.label mega65_unhide = KERNAL_0.mega65_unhide
|
||||
.label tape_motor_on = KERNAL_0.tape_motor_on
|
||||
.label tape_motor_off = KERNAL_0.tape_motor_off
|
||||
|
||||
.label lvs_display_loading_verifying = KERNAL_0.proxy_K1_lvs_display_loading_verifying
|
||||
.label lvs_display_done = KERNAL_0.proxy_K1_lvs_display_done
|
||||
.label lvs_return_last_address = KERNAL_0.proxy_K1_lvs_return_last_address
|
||||
.label lvs_device_not_found_error = KERNAL_0.proxy_K1_lvs_device_not_found_error
|
||||
.label lvs_load_verify_error = KERNAL_0.proxy_K1_lvs_load_verify_error
|
||||
|
||||
.label lvs_check_EAL = KERNAL_0.lvs_check_EAL
|
||||
.label lvs_STAL_to_MEMUSS = KERNAL_0.lvs_STAL_to_MEMUSS
|
||||
|
||||
.label kernalerror_ROUTINE_TERMINATED = KERNAL_0.proxy_K1_kernalerror_ROUTINE_TERMINATED
|
||||
|
||||
.label print_kernal_message = KERNAL_0.proxy_K1_print_kernal_message
|
||||
.label print_return = KERNAL_0.proxy_K1_print_return
|
||||
|
||||
.label __MSG_KERNAL_PRESS_PLAY = KERNAL_0.__MSG_KERNAL_PRESS_PLAY
|
||||
.label __MSG_KERNAL_OK_SEARCHING = KERNAL_0.__MSG_KERNAL_OK_SEARCHING
|
||||
.label __MSG_KERNAL_FOUND = KERNAL_0.__MSG_KERNAL_FOUND
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
|
||||
.label tape_normal_byte_store = KERNAL_0.tape_normal_byte_store
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_TAPE_HEAD_ALIGN
|
||||
|
||||
.label CLALL = KERNAL_0.proxy_K1_CLALL
|
||||
.label nmi_lock = KERNAL_0.nmi_lock
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
// #LAYOUT# M65 KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// ROM mapping routines for Mega65
|
||||
//
|
||||
|
||||
// Available memory maps:
|
||||
// - NORMAL - nothing mapped in
|
||||
// - KERNAL_1 - for calling KERNAL_1 segment code
|
||||
|
||||
|
||||
map_NORMAL:
|
||||
|
||||
php
|
||||
pha
|
||||
phx
|
||||
phy
|
||||
phz
|
||||
|
||||
lda #$00
|
||||
tax
|
||||
tay
|
||||
taz
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
map_end:
|
||||
|
||||
map
|
||||
eom
|
||||
|
||||
plz
|
||||
ply
|
||||
plx
|
||||
pla
|
||||
plp
|
||||
|
||||
rts
|
||||
|
||||
|
||||
map_KERNAL_1:
|
||||
|
||||
php
|
||||
pha
|
||||
phx
|
||||
phy
|
||||
phz
|
||||
|
||||
lda #$00
|
||||
tay
|
||||
taz
|
||||
|
||||
ldx #$42 // 0x4000 <- map 8KB from 0x20000
|
||||
|
||||
bne map_end
|
||||
@@ -0,0 +1,69 @@
|
||||
// #LAYOUT# M65 KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Proxies for calling Mega65 segment KERNAL_0 routines from KERNAL_1
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO
|
||||
|
||||
|
||||
proxy_K1_kernalerror_ROUTINE_TERMINATED:
|
||||
|
||||
jsr map_NORMAL
|
||||
jmp kernalerror_ROUTINE_TERMINATED
|
||||
|
||||
|
||||
proxy_K1_lvs_display_loading_verifying:
|
||||
|
||||
jsr map_NORMAL
|
||||
jsr lvs_display_loading_verifying
|
||||
jmp map_KERNAL_1
|
||||
|
||||
proxy_K1_lvs_display_done:
|
||||
|
||||
jsr map_NORMAL
|
||||
jsr lvs_display_done
|
||||
jmp map_KERNAL_1
|
||||
|
||||
proxy_K1_lvs_return_last_address:
|
||||
|
||||
jsr map_NORMAL
|
||||
jmp lvs_return_last_address
|
||||
|
||||
proxy_K1_lvs_device_not_found_error:
|
||||
|
||||
jsr map_NORMAL
|
||||
jmp lvs_device_not_found_error
|
||||
|
||||
proxy_K1_lvs_load_verify_error:
|
||||
|
||||
jsr map_NORMAL
|
||||
jmp lvs_load_verify_error
|
||||
|
||||
|
||||
proxy_K1_print_kernal_message:
|
||||
|
||||
jsr map_NORMAL
|
||||
jsr print_kernal_message
|
||||
jmp map_KERNAL_1
|
||||
|
||||
proxy_K1_print_return:
|
||||
|
||||
jsr map_NORMAL
|
||||
jsr print_return
|
||||
jmp map_KERNAL_1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_TAPE_HEAD_ALIGN
|
||||
|
||||
proxy_K1_CLALL:
|
||||
|
||||
jsr map_NORMAL
|
||||
jsr CLALL
|
||||
jmp map_KERNAL_1
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
// #LAYOUT# M65 KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// ROM routine call redirect for tape routines
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL && !CONFIG_TAPE_AUTODETECT
|
||||
|
||||
load_tape_normal:
|
||||
|
||||
jsr map_KERNAL_1
|
||||
jsr_ind VK1__load_tape_normal
|
||||
jmp map_NORMAL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_TAPE_TURBO && !CONFIG_TAPE_AUTODETECT
|
||||
|
||||
load_tape_turbo:
|
||||
|
||||
jsr map_KERNAL_1
|
||||
jsr_ind VK1__load_tape_turbo
|
||||
jmp map_NORMAL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_TAPE_AUTODETECT
|
||||
|
||||
load_tape_auto:
|
||||
|
||||
jsr map_KERNAL_1
|
||||
jsr_ind VK1__load_tape_auto
|
||||
jmp map_NORMAL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if CONFIG_TAPE_HEAD_ALIGN
|
||||
|
||||
tape_head_align:
|
||||
|
||||
jsr map_KERNAL_1
|
||||
jsr_ind VK1__tape_head_align
|
||||
jmp map_NORMAL
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
// #LAYOUT# M65 KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Tape (normal) helper routine - byte storage when banking change is needed
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_TAPE_NORMAL
|
||||
|
||||
|
||||
tape_normal_byte_store:
|
||||
|
||||
jsr map_NORMAL
|
||||
sta (MEMUSS), y
|
||||
jmp map_KERNAL_1
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# X16 * #IGNORE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Routine to unhide Mega65 extra registers
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_KEYBOARD_C65 || (CONFIG_MB_MEGA_65 && (CONFIG_TAPE_NORMAL || CONFIG_TAPE_TURBO))
|
||||
|
||||
|
||||
mega65_unhide:
|
||||
|
||||
lda #$A5
|
||||
sta VIC_KEY
|
||||
lda #$96
|
||||
sta VIC_KEY
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
// #LAYOUT# X16 KERNAL_1 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
// Dummy, just to have anything in segment 1
|
||||
|
||||
brk
|
||||
@@ -0,0 +1,44 @@
|
||||
// #LAYOUT# X16 KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
// Stubs for Commander X16 support
|
||||
|
||||
|
||||
scnkey_set_keytab:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
clear_screen:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
setup_vicii:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
cursor_blink:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
chrin_keyboard:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
chrout_screen:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
IOINIT:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
SCNKEY:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
SCREEN:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
screen_calculate_pointers:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
setup_pal_ntsc:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
wait_x_bars:
|
||||
STUB_IMPLEMENTATION()
|
||||
|
||||
udtim_keyboard:
|
||||
STUB_IMPLEMENTATION()
|
||||
@@ -0,0 +1,94 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
// Kernal error codes are described in 'Commodore 64 Programmers Reference Guide', page 306
|
||||
|
||||
kernalerror_ROUTINE_TERMINATED: // by a STOP key
|
||||
|
||||
lda #K_ERR_ROUTINE_TERMINATED
|
||||
skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
kernalerror_TOO_MANY_OPEN_FILES:
|
||||
|
||||
lda #K_ERR_TOO_MANY_OPEN_FILES
|
||||
skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
kernalerror_FILE_ALREADY_OPEN:
|
||||
|
||||
lda #K_ERR_FILE_ALREADY_OPEN
|
||||
skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
kernalerror_FILE_NOT_OPEN:
|
||||
|
||||
lda #K_ERR_FILE_NOT_OPEN
|
||||
skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
kernalerror_FILE_NOT_FOUND:
|
||||
|
||||
lda #K_ERR_FILE_NOT_FOUND
|
||||
skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
kernalerror_DEVICE_NOT_FOUND:
|
||||
|
||||
lda #K_ERR_DEVICE_NOT_FOUND
|
||||
skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
kernalerror_FILE_NOT_INPUT:
|
||||
|
||||
lda #K_ERR_FILE_NOT_INPUT
|
||||
skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
kernalerror_FILE_NOT_OUTPUT:
|
||||
|
||||
lda #K_ERR_FILE_NOT_OUTPUT
|
||||
skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
kernalerror_FILE_NAME_MISSING:
|
||||
|
||||
lda #K_ERR_FILE_NAME_MISSING
|
||||
skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
kernalerror_ILLEGAL_DEVICE_NUMBER:
|
||||
|
||||
lda #K_ERR_ILLEGAL_DEVICE_NUMBER
|
||||
skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
kernalerror_IEC_TIMEOUT_READ:
|
||||
|
||||
lda #K_STS_TIMEOUT_READ
|
||||
skip_2_bytes_trash_nvz
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
#endif // CONFIG_IEC_JIFFYDOS
|
||||
|
||||
kernalerror_TOP_MEM_RS232:
|
||||
|
||||
lda #K_ERR_TOP_MEM_RS232
|
||||
|
||||
sec
|
||||
rts
|
||||
@@ -0,0 +1,33 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 274
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 224/225
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): .Y
|
||||
//
|
||||
|
||||
|
||||
ACPTR:
|
||||
|
||||
lda IOSTATUS
|
||||
beq !+
|
||||
|
||||
clc
|
||||
lda #$0D // tested on real ROMs
|
||||
rts
|
||||
!:
|
||||
|
||||
#if CONFIG_IEC
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
jmp iec_rx_dispatch
|
||||
#else
|
||||
jmp iec_rx_byte
|
||||
#endif
|
||||
#else
|
||||
jmp kernalerror_ILLEGAL_DEVICE_NUMBER
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// IEC part of the CHKIN routine
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
chkin_iec:
|
||||
|
||||
// Fail if the file is open for writing (secondary address 1)
|
||||
|
||||
lda LAT, Y
|
||||
cmp #$01
|
||||
beq_16 chkin_file_not_input
|
||||
|
||||
// Send TALK + TKSA first
|
||||
lda FAT,Y
|
||||
|
||||
jsr TALK
|
||||
bcs_16 chkinout_device_not_present
|
||||
|
||||
lda LAT, Y
|
||||
ora #$60
|
||||
jsr TKSA
|
||||
bcs_16 chkinout_device_not_present
|
||||
|
||||
jmp chkin_set_device
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,13 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// IEC part of the CHRIN routine
|
||||
//
|
||||
|
||||
|
||||
chrin_iec:
|
||||
|
||||
// XXX is this really all?
|
||||
jmp JACPTR
|
||||
@@ -0,0 +1,15 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// IEC part of the CHROUT routine
|
||||
//
|
||||
|
||||
|
||||
chrout_iec:
|
||||
|
||||
lda SCHAR
|
||||
jsr JCIOUT
|
||||
bcc_16 chrout_done_success
|
||||
jmp chrout_done_fail
|
||||
@@ -0,0 +1,52 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 279/280
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 224
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): .X, .Y
|
||||
//
|
||||
|
||||
|
||||
CIOUT:
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
pha
|
||||
lda C3PO
|
||||
bne ciout_send_byte
|
||||
|
||||
// Nothing to send - set buffer as valid, store byte there
|
||||
inc C3PO
|
||||
|
||||
// Clear carry flag to indicate success
|
||||
clc
|
||||
|
||||
ciout_store_in_buffer:
|
||||
|
||||
// Store in the buffer data to be sent next, return
|
||||
pla
|
||||
sta BSOUR
|
||||
rts
|
||||
|
||||
ciout_send_byte:
|
||||
|
||||
clc // send without EOI
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
jsr iec_tx_dispatch
|
||||
#else
|
||||
jsr iec_tx_byte
|
||||
#endif
|
||||
inc C3PO // tx byte routine sets to 0, but we still have something to send
|
||||
jmp ciout_store_in_buffer
|
||||
|
||||
#else
|
||||
|
||||
sec // indicate failure
|
||||
rts
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// IEC part of the CKOUT routine
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
ckout_iec:
|
||||
|
||||
// Fail if the file is open for reading (secondary address 0)
|
||||
|
||||
lda LAT, Y
|
||||
beq_16 ckout_file_not_output
|
||||
|
||||
// Send LISTEN + SECOND first
|
||||
lda FAT,Y
|
||||
|
||||
jsr LISTEN
|
||||
bcs_16 chkinout_device_not_present
|
||||
|
||||
lda LAT, Y
|
||||
ora #$60
|
||||
jsr SECOND
|
||||
bcs_16 chkinout_device_not_present
|
||||
|
||||
jmp ckout_set_device
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,38 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// IEC part of the CLOSE routine
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
// .Y contains LAT/FAT/SAT table index, it should stay this way
|
||||
|
||||
close_iec:
|
||||
|
||||
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?
|
||||
jsr iec_close_load
|
||||
jmp close_remove_from_table
|
||||
|
||||
!:
|
||||
ora $E0 // CLOSE command
|
||||
sta TBTCNT
|
||||
jsr iec_tx_command
|
||||
bcs close_iec_end
|
||||
jsr iec_tx_command_finalize
|
||||
|
||||
close_iec_end:
|
||||
|
||||
jmp close_remove_from_table
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,33 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// IEC part of the CLRCHN routine
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
clrchn_iec:
|
||||
|
||||
// Check input device
|
||||
lda DFLTN
|
||||
jsr iec_check_devnum_oc
|
||||
bcs !+
|
||||
|
||||
// It was IEC device - send UNTALK first
|
||||
jsr UNTLK
|
||||
!:
|
||||
// Check output device
|
||||
lda DFLTO
|
||||
jsr iec_check_devnum_oc
|
||||
|
||||
// If it was IEC device - send UNLSN first
|
||||
bcc_16 UNLSN
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,36 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Checks whether device number (in .A) is a correct IEC device number
|
||||
//
|
||||
// Preserves .A, .X and .Y
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
iec_check_devnum_lvs: // for load/verify/save
|
||||
|
||||
cmp #$08 // below 8 are illegal for load/save
|
||||
bcc iec_check_devnum_failed
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
iec_check_devnum_oc: // for open/close
|
||||
|
||||
cmp #$04 // below 4 are illegal, reserved for non-IEC devices on Commodore
|
||||
bcc iec_check_devnum_failed
|
||||
|
||||
// 31 and above are illegal too, due to IEC command encoding scheme,
|
||||
// see https://www.pagetable.com/?p=1031
|
||||
cmp #$1F // sets carry for 31 or above
|
||||
rts
|
||||
|
||||
iec_check_devnum_failed:
|
||||
|
||||
sec // indicate non-IEC device
|
||||
rts
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,34 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Common part of CLOSE and LOAD/SAVE routines for IEC
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_close_load:
|
||||
|
||||
tax
|
||||
|
||||
// Command drive to stop talking before closing the file
|
||||
jsr UNTLK
|
||||
|
||||
txa
|
||||
jsr LISTEN
|
||||
|
||||
lda #$E0 // CLOSE command
|
||||
sta TBTCNT
|
||||
jsr iec_tx_command
|
||||
jsr iec_tx_command_finalize
|
||||
|
||||
// Tell drive to unlisten
|
||||
jsr UNLSN
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,26 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Kernal internal IEC routine
|
||||
//
|
||||
// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_cmd_close:
|
||||
|
||||
jsr iec_check_channel_openclose
|
||||
bcc !+
|
||||
jmp kernalerror_FILE_NOT_INPUT
|
||||
!:
|
||||
ora #$E0
|
||||
|
||||
jmp common_open_close_unlsn_second
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,71 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Kernal internal IEC routine
|
||||
//
|
||||
// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_cmd_open: // similar to TKSA, but without turnaround
|
||||
|
||||
jsr iec_check_channel_openclose
|
||||
bcc !+
|
||||
jmp kernalerror_FILE_NOT_INPUT
|
||||
!:
|
||||
ora #$F0
|
||||
|
||||
#if CONFIG_IEC_BURST_CIA1 || CONFIG_IEC_BURST_CIA2 || CONFIG_IEC_BURST_MEGA_65
|
||||
pha
|
||||
jsr burst_advertise
|
||||
pla
|
||||
#endif
|
||||
|
||||
#if CONFIG_IEC_DOLPHINDOS
|
||||
|
||||
sta TBTCNT
|
||||
jsr iec_tx_command
|
||||
bcs !+ // branch if error
|
||||
|
||||
jsr dolphindos_detect
|
||||
|
||||
jmp iec_tx_command_finalize
|
||||
|
||||
#else
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
#endif
|
||||
|
||||
common_open_close_unlsn_second: // common part of several commands
|
||||
|
||||
sta TBTCNT
|
||||
jsr iec_tx_command
|
||||
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
|
||||
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
|
||||
cmp #$60
|
||||
beq !+
|
||||
sec // mark unsuitable channel number
|
||||
rts
|
||||
!:
|
||||
clc // mark suitable channel number
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,88 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Helper IEC routines to pull/release certain lines
|
||||
//
|
||||
// Order of operation is set for extra robustness, on non-emulated hardware
|
||||
// lines might need few cycles to stabilize (released CLK = DATA considered valid),
|
||||
// see page 10 of http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
//
|
||||
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_pull_atn_clk_release_data:
|
||||
|
||||
lda CIA2_PRA
|
||||
ora #BIT_CIA2_PRA_ATN_OUT // pull
|
||||
sta CIA2_PRA
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
iec_pull_clk_release_data:
|
||||
|
||||
lda CIA2_PRA
|
||||
ora #BIT_CIA2_PRA_CLK_OUT // pull
|
||||
sta CIA2_PRA
|
||||
!:
|
||||
and #$FF - BIT_CIA2_PRA_DAT_OUT // release
|
||||
bne iec_pull_release_end // branch always
|
||||
|
||||
iec_pull_clk_release_data_oneshot:
|
||||
|
||||
lda CIA2_PRA
|
||||
ora #BIT_CIA2_PRA_CLK_OUT // pull
|
||||
bne !- // branch always
|
||||
|
||||
iec_release_atn_clk_data:
|
||||
|
||||
lda CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_ATN_OUT // release
|
||||
sta CIA2_PRA
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
iec_release_clk_data:
|
||||
|
||||
lda CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_DAT_OUT // release
|
||||
sta CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_CLK_OUT // release
|
||||
jmp iec_pull_release_end
|
||||
|
||||
iec_release_clk_pull_data:
|
||||
|
||||
lda CIA2_PRA
|
||||
ora #BIT_CIA2_PRA_DAT_OUT // pull
|
||||
sta CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_CLK_OUT // release
|
||||
bne iec_pull_release_end // branch always
|
||||
|
||||
iec_pull_data_release_atn_clk:
|
||||
|
||||
lda CIA2_PRA
|
||||
ora #BIT_CIA2_PRA_DAT_OUT // pull
|
||||
sta CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_CLK_OUT // release
|
||||
sta CIA2_PRA
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
iec_release_atn:
|
||||
|
||||
lda CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_ATN_OUT // release
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
iec_pull_release_end:
|
||||
|
||||
sta CIA2_PRA
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,44 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_return_success:
|
||||
|
||||
// BSOUR is certainly not valid anymore
|
||||
lda #$00
|
||||
sta C3PO
|
||||
// Restore registers
|
||||
ply_trash_a
|
||||
plx_trash_a
|
||||
// Report success
|
||||
clc
|
||||
rts
|
||||
|
||||
iec_return_DEVICE_NOT_FOUND:
|
||||
|
||||
// Set IEC line to normal idle state
|
||||
jsr iec_set_idle
|
||||
// BSOUR is certainly not valid anymore
|
||||
lda #$00
|
||||
sta C3PO
|
||||
// Restore registers
|
||||
ply_trash_a
|
||||
plx_trash_a
|
||||
// Report error
|
||||
jmp kernalerror_DEVICE_NOT_FOUND
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,161 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
iec_rx_dispatch:
|
||||
|
||||
lda IECPROTO
|
||||
cmp #$01
|
||||
beq_16 jiffydos_rx_byte
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
#endif // CONFIG_IEC_JIFFYDOS
|
||||
|
||||
|
||||
iec_rx_byte:
|
||||
|
||||
// Store .X and .Y on the stack - preserve them
|
||||
phx_trash_a
|
||||
phy_trash_a
|
||||
|
||||
// Timing is critical here - execute on disabled IRQs
|
||||
// The best practice would be to do PHP first, but it seems this is not
|
||||
// what the original ROM does; furthermore, pushing additional bytes to
|
||||
// stack can wreck autostart softwaree loading at $0100
|
||||
sei
|
||||
|
||||
// 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 were not pulling CLK anyway
|
||||
jsr iec_release_clk_data
|
||||
|
||||
// Wait till data line is released (someone else might be holding it)
|
||||
jsr iec_wait_for_data_release
|
||||
|
||||
// Check if EOI
|
||||
jsr iec_rx_check_eoi
|
||||
|
||||
#if CONFIG_IEC_DOLPHINDOS
|
||||
|
||||
// Check if DolphinDOS was detected
|
||||
lda IECPROTO
|
||||
cmp #$02
|
||||
bne iec_rx_no_dolphindos
|
||||
|
||||
// For DolphinDOS just fetch the byte from parallel port
|
||||
lda CIA2_PRB
|
||||
pha
|
||||
jmp iec_rx_acknowledge
|
||||
|
||||
iec_rx_no_dolphindos:
|
||||
|
||||
#endif // CONFIG_IEC_DOLPHINDOS
|
||||
|
||||
// Latch input bits in on rising edge of CLK, eight times for eight bits.
|
||||
ldx #7
|
||||
|
||||
// Get empty byte to load into.
|
||||
lda #$00
|
||||
pha
|
||||
|
||||
iec_rx_bit_loop:
|
||||
|
||||
// Wait for CLK to release
|
||||
jsr iec_wait_for_clk_release
|
||||
|
||||
// (we do this implicitly below, with a tighter routine,
|
||||
// so that we do not 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.
|
||||
|
||||
// Move data bit into C flag, and loop until bit 6 clears
|
||||
// i.e., the clock has been released.
|
||||
|
||||
!: lda CIA2_PRA
|
||||
rol
|
||||
bpl !-
|
||||
|
||||
// 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
|
||||
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
|
||||
|
||||
// Timeout
|
||||
jsr kernalstatus_EOI
|
||||
pla
|
||||
|
||||
jmp iec_rx_end
|
||||
!:
|
||||
// More bits?
|
||||
dex
|
||||
bpl iec_rx_bit_loop
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
iec_rx_acknowledge:
|
||||
|
||||
// Then we must within 1000 usec acknowledge the byte 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
|
||||
|
||||
// Retrieve the received byte
|
||||
pla
|
||||
|
||||
// Restore registers
|
||||
sta TBTCNT // $A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
iec_rx_end:
|
||||
|
||||
ply_trash_a
|
||||
plx_trash_a
|
||||
lda TBTCNT
|
||||
|
||||
clc
|
||||
cli
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,44 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Helper routine to check for EOI while receiving byte from IEC
|
||||
//
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_rx_check_eoi:
|
||||
|
||||
// Wait for talker to pull CLK.
|
||||
// If over 200 usec (205 cycles on NTSC machine) , then it is EOI.
|
||||
// Loop iteraction takes 11 cycles, 19 full iterations are enough
|
||||
|
||||
ldx #$13 // 2 cycles
|
||||
|
||||
!:
|
||||
bit CIA2_PRA // 4 cycles
|
||||
bvc iec_rx_check_eoi_done // 2 cycles if not jumped
|
||||
dex // 2 cycles
|
||||
bne !- // 3 cycles if jumped
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
iec_rx_check_eoi_confirm:
|
||||
|
||||
// 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
|
||||
|
||||
// Pull data for 60 usec to confirm it
|
||||
jsr iec_release_clk_pull_data
|
||||
jsr iec_wait60us
|
||||
jsr iec_release_clk_data
|
||||
|
||||
iec_rx_check_eoi_done:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,49 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Sends file (stream) name to IEC device
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_send_file_name:
|
||||
ldy #0
|
||||
|
||||
iec_send_file_name_loop:
|
||||
cpy FNLEN
|
||||
beq iec_send_file_name_done
|
||||
|
||||
#if CONFIG_MEMORY_MODEL_60K
|
||||
ldx #<FNADDR+0
|
||||
jsr peek_under_roms
|
||||
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
|
||||
jsr peek_under_roms_via_FNADDR
|
||||
#else // CONFIG_MEMORY_MODEL_38K
|
||||
lda (FNADDR),y
|
||||
#endif
|
||||
|
||||
iny
|
||||
// Set Carry flag on the last file name character, to mark EOI
|
||||
cpy FNLEN
|
||||
clc
|
||||
bne !+
|
||||
sec
|
||||
!:
|
||||
// Transmit one character
|
||||
sta TBTCNT
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
jsr iec_tx_dispatch
|
||||
#else
|
||||
jsr iec_tx_byte
|
||||
#endif
|
||||
jmp iec_send_file_name_loop
|
||||
|
||||
iec_send_file_name_done:
|
||||
jmp UNLSN
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,17 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
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
|
||||
sta CIA2_PRA
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,45 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_turnaround_to_listen:
|
||||
|
||||
// Store .X and .Y on the stack - preserve them
|
||||
phx_trash_a
|
||||
phy_trash_a
|
||||
|
||||
// Timing is critical here - execute on disabled IRQs
|
||||
php
|
||||
sei
|
||||
|
||||
// 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?
|
||||
!:
|
||||
lda CIA2_PRA
|
||||
rol // to put BIT_CIA2_PRA_CLK_IN as the last (sign) bit
|
||||
bpl !+
|
||||
dex
|
||||
bne !-
|
||||
|
||||
// Timeout - XXX what errors do original Kernal report?
|
||||
plp
|
||||
jmp iec_return_DEVICE_NOT_FOUND
|
||||
|
||||
// CLK is pulled by the device, OK
|
||||
!:
|
||||
plp
|
||||
jmp iec_return_success
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,37 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_turnaround_to_talk:
|
||||
|
||||
// Store .X and .Y on the stack - preserve them
|
||||
phx_trash_a
|
||||
phy_trash_a
|
||||
|
||||
// Timing is critical here - execute on disabled IRQs
|
||||
php
|
||||
sei
|
||||
|
||||
// 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
|
||||
jsr iec_wait_for_clk_release
|
||||
|
||||
// Pull CLK line, it should be held by talker
|
||||
jsr iec_pull_clk_release_data
|
||||
|
||||
plp
|
||||
jmp iec_return_success
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,166 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
// Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
|
||||
|
||||
// Expects byte to send in TBTCNT ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html)
|
||||
// Carry flag set = signal EOI
|
||||
//
|
||||
// Preserves .X and .Y registers
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
iec_tx_dispatch:
|
||||
|
||||
php // preserve C flag for EOI indication
|
||||
lda IECPROTO
|
||||
cmp #$01
|
||||
bne !+
|
||||
|
||||
plp
|
||||
jmp jiffydos_tx_byte
|
||||
!:
|
||||
plp
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
#endif // CONFIG_IEC_JIFFYDOS
|
||||
|
||||
|
||||
iec_tx_byte:
|
||||
|
||||
// Store .X and .Y on the stack - preserve them
|
||||
phx_trash_a
|
||||
phy_trash_a
|
||||
|
||||
// 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
|
||||
|
||||
iec_tx_common:
|
||||
|
||||
// Timing is critical here - execute on disabled IRQs
|
||||
// The best practice would be to do PHP first, but it seems this is not
|
||||
// what the original ROM does; furthermore, pushing additional bytes to
|
||||
// stack can wreck autostart software loading at $0100
|
||||
sei
|
||||
|
||||
// Wait till all receivers are ready, they should all release DATA
|
||||
jsr iec_wait_for_data_release
|
||||
|
||||
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 is pushed and released again
|
||||
|
||||
jsr iec_wait_for_data_pull
|
||||
jsr iec_wait_for_data_release
|
||||
!:
|
||||
#if CONFIG_IEC_DOLPHINDOS
|
||||
|
||||
// Check if DolphinDOS was detected
|
||||
lda IECPROTO
|
||||
cmp #$02
|
||||
bne iec_tx_no_dolphindos
|
||||
|
||||
// For DolphinDOS just push the byte to parallel port (set it to output first)
|
||||
lda #$FF
|
||||
sta CIA2_DDRB
|
||||
lda TBTCNT
|
||||
sta CIA2_PRB
|
||||
|
||||
// Pull CLK to indicate data is now valid (we should not hold DATA nevertheless)
|
||||
jsr iec_pull_clk_release_data_oneshot
|
||||
|
||||
// Finish the flow
|
||||
jmp iec_tx_common_finalize
|
||||
|
||||
iec_tx_no_dolphindos:
|
||||
|
||||
#endif // CONFIG_IEC_DOLPHINDOS
|
||||
|
||||
// Pull CLK back to indicate that DATA is not valid, keep it for 60us
|
||||
// We can use this routine as we don't hold DATA anyway (and its state doesn't even matter)
|
||||
|
||||
jsr iec_pull_clk_release_data_oneshot
|
||||
jsr iec_wait60us
|
||||
|
||||
// Now, we can start transmission of 8 bits of data
|
||||
ldx #7
|
||||
|
||||
iec_tx_common_sendbit:
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
bne !+ // branch if not sending the last bit
|
||||
lda IECPROTO
|
||||
beq !+ // branch if standard protocol
|
||||
|
||||
// JiffyDOS ROM performs detection loop on every command; it seems we have to
|
||||
// replicate this behaviour for compatibility with at least 1541 JiffyDOS ROM
|
||||
|
||||
jsr jiffydos_detect
|
||||
!:
|
||||
#endif // CONFIG_IEC_JIFFYDOS
|
||||
|
||||
// Is next bit 0 or 1?
|
||||
lda TBTCNT
|
||||
lsr
|
||||
sta TBTCNT
|
||||
bcs !+
|
||||
|
||||
// Bit is 0
|
||||
jsr iec_release_clk_pull_data
|
||||
jmp iec_tx_common_bit_is_sent
|
||||
!:
|
||||
// Bit is 1
|
||||
jsr iec_release_clk_data
|
||||
|
||||
iec_tx_common_bit_is_sent:
|
||||
|
||||
// Wait 20us, so that device(s) can pick DATA
|
||||
jsr iec_wait20us
|
||||
|
||||
// Pull CLK for 20us again, before sending the next bit
|
||||
// or performing any other action
|
||||
jsr iec_pull_clk_release_data_oneshot
|
||||
jsr iec_wait20us
|
||||
|
||||
// More bits to send?
|
||||
dex
|
||||
bpl iec_tx_common_sendbit
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
iec_tx_common_finalize:
|
||||
|
||||
cli
|
||||
|
||||
// Give devices 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 !+
|
||||
dex
|
||||
bne !-
|
||||
bmi !+
|
||||
jmp iec_return_DEVICE_NOT_FOUND
|
||||
!:
|
||||
jmp iec_return_success
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,46 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
// Implemented based on https://www.pagetable.com/?p=1135, https://github.com/mist64/cbmbus_doc
|
||||
|
||||
// Expects byte to send in TBTCNT ($A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html)
|
||||
// Carry flag set = signal EOI
|
||||
//
|
||||
// Preserves .X and .Y registers
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_tx_command:
|
||||
|
||||
// Store .X and .Y on the stack - preserve them
|
||||
phx_trash_a
|
||||
phy_trash_a
|
||||
|
||||
// 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
|
||||
jsr iec_wait1ms
|
||||
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.
|
||||
|
||||
jsr iec_release_clk_data
|
||||
|
||||
// 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
|
||||
jmp iec_tx_common
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,27 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_tx_command_finalize:
|
||||
|
||||
// Store .X and .Y on the stack - preserve them
|
||||
phx_trash_a
|
||||
phy_trash_a
|
||||
|
||||
// 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
|
||||
|
||||
jmp iec_return_success
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,25 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
// Flush the IEC output buffer (if not empty) - send byte with EOI
|
||||
//
|
||||
// Preserves .X, .Y and .A registers
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_tx_flush:
|
||||
|
||||
pha
|
||||
lda C3PO
|
||||
beq !+
|
||||
sec // send it with EOI
|
||||
jsr iec_tx_byte // send the command regardless of the status
|
||||
!:
|
||||
pla
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,24 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Common EAL update routine
|
||||
//
|
||||
|
||||
|
||||
#if (CONFIG_IEC_JIFFYDOS || CONFIG_IEC_DOLPHINDOS) && !CONFIG_MEMORY_MODEL_60K
|
||||
|
||||
|
||||
iec_update_EAL_by_Y: // note: Carry has to be set by caller!
|
||||
|
||||
tya
|
||||
adc EAL+0
|
||||
sta EAL+0
|
||||
bcc !+
|
||||
inc EAL+1
|
||||
!:
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# X16 * #IGNORE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Wait 1 ms (1000 usec)
|
||||
//
|
||||
// On NTSC this means 1023 cycles (slightly less on PAL, but we have to be sure).
|
||||
// We cant count on badlines, as the screen might be disabled.
|
||||
// Delay here is implemented 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
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_wait1ms:
|
||||
|
||||
ldx #18 // we probably won't start with the beginning of raster
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
|
||||
wait_x_bars: // additional entry point for delayy in screen and tape support
|
||||
// has to preserve .Y and put .X to 0
|
||||
|
||||
lda VIC_RASTER
|
||||
!:
|
||||
cmp VIC_RASTER
|
||||
beq !-
|
||||
lda VIC_RASTER
|
||||
dex
|
||||
bne !-
|
||||
|
||||
iec_wait_rts: // dummy RTS, for very short waits
|
||||
|
||||
rts
|
||||
@@ -0,0 +1,31 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_wait20us:
|
||||
|
||||
// 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
|
||||
|
||||
// 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
|
||||
|
||||
// 6 cycles JSR to routine,
|
||||
// 14 cycles routine with RTS
|
||||
// 1 cycle to fetch next instruction
|
||||
// ---
|
||||
// 21 cycles
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,36 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Note: damages .X
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_wait60us:
|
||||
|
||||
// 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
|
||||
|
||||
// Waste cycles in a loop
|
||||
|
||||
ldx #$0A // 2 cycles
|
||||
!: dex // 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
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,16 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_wait_for_clk_release:
|
||||
|
||||
bit CIA2_PRA
|
||||
bvc iec_wait_for_clk_release
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,18 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_wait_for_data_pull:
|
||||
|
||||
lda CIA2_PRA
|
||||
// Check the highest bit, which is DATA IN,
|
||||
// (highest bit set = negative value)
|
||||
bmi iec_wait_for_data_pull
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,17 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
iec_wait_for_data_release:
|
||||
|
||||
lda CIA2_PRA
|
||||
// Check the highest bit, which is DATA IN,
|
||||
// (highest bit set = negative value)
|
||||
bpl iec_wait_for_data_release
|
||||
rts
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,38 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 285
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 223
|
||||
// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
|
||||
// - http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): .X, .Y
|
||||
//
|
||||
|
||||
|
||||
LISTEN:
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
// According to serial-bus.pdf (page 15) this routine flushes the IEC out buffer
|
||||
jsr iec_tx_flush
|
||||
|
||||
// Check whether device number is correct
|
||||
jsr iec_check_devnum_oc
|
||||
bcc !+
|
||||
jmp kernalerror_DEVICE_NOT_FOUND
|
||||
!:
|
||||
// Encode and execute the command
|
||||
ora #$20
|
||||
|
||||
jmp common_talk_listen
|
||||
|
||||
#else
|
||||
|
||||
jmp kernalerror_ILLEGAL_DEVICE_NUMBER
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,197 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// IEC part of the LOAD routine
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
load_iec_dev_not_found:
|
||||
jmp lvs_device_not_found_error
|
||||
|
||||
load_iec_file_not_found:
|
||||
jmp kernalerror_FILE_NOT_FOUND
|
||||
|
||||
load_iec_error:
|
||||
lda FA
|
||||
jsr iec_close_load
|
||||
jmp lvs_load_verify_error
|
||||
|
||||
load_break_error:
|
||||
pla
|
||||
lda FA
|
||||
jsr iec_close_load
|
||||
jmp kernalerror_ROUTINE_TERMINATED
|
||||
|
||||
|
||||
load_iec:
|
||||
|
||||
// Check file name
|
||||
lda FNLEN
|
||||
beq_16 kernalerror_FILE_NAME_MISSING
|
||||
|
||||
// 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 does not mess with the file
|
||||
// table in the C64, only in the drive.
|
||||
|
||||
// Call device to LISTEN (p16)
|
||||
lda FA
|
||||
jsr LISTEN
|
||||
bcs load_iec_dev_not_found
|
||||
|
||||
// Open channel 0 (reserved for file reading)
|
||||
lda #$00
|
||||
jsr iec_cmd_open
|
||||
bcs load_iec_dev_not_found
|
||||
|
||||
// Send file name
|
||||
jsr iec_send_file_name
|
||||
bcs load_iec_error
|
||||
|
||||
// Now command device to talk (p16)
|
||||
lda FA
|
||||
jsr TALK
|
||||
bcs load_iec_error
|
||||
|
||||
#if CONFIG_IEC_BURST_CIA1 || CONFIG_IEC_BURST_CIA2 || CONFIG_IEC_BURST_MEGA_65
|
||||
jsr burst_advertise
|
||||
#endif
|
||||
|
||||
lda #$60 // open channel / data (p3) , required according to p13
|
||||
sta TBTCNT
|
||||
jsr iec_tx_command
|
||||
bcs load_iec_error
|
||||
|
||||
#if CONFIG_IEC_DOLPHINDOS
|
||||
jsr dolphindos_detect
|
||||
#endif
|
||||
|
||||
// We are currently talker, so do the IEC turn around so that we
|
||||
// are the listener (p16)
|
||||
jsr iec_turnaround_to_listen
|
||||
bcs load_iec_error
|
||||
|
||||
// Get load address
|
||||
|
||||
jsr load_iec_get_addr_byte
|
||||
sta EAL+0
|
||||
|
||||
jsr load_iec_get_addr_byte
|
||||
sta EAL+1
|
||||
|
||||
// If secondary address is 0, override EAL with STAL
|
||||
|
||||
lda SA
|
||||
bne !+
|
||||
lda STAL+0
|
||||
sta EAL+0
|
||||
lda STAL+1
|
||||
sta EAL+1
|
||||
!:
|
||||
// Display start address
|
||||
jsr lvs_display_loading_verifying
|
||||
|
||||
#if (CONFIG_IEC_JIFFYDOS || CONFIG_IEC_DOLPHINDOS) && !CONFIG_MEMORY_MODEL_60K
|
||||
|
||||
// If feasible, use protocol-specific optimized LOAD loop
|
||||
|
||||
lda VERCKK
|
||||
bne load_iec_loop // branch if VERIFY
|
||||
lda IECPROTO
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
cmp #$01
|
||||
beq_16 jiffydos_load // branch if JiffyDOS
|
||||
#endif
|
||||
|
||||
#if CONFIG_IEC_DOLPHINDOS
|
||||
cmp #$02
|
||||
beq_16 dolphindos_load // branch if DolphinDOS
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
load_iec_loop:
|
||||
|
||||
// We are now ready to receive bytes
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
jsr iec_rx_dispatch
|
||||
#else
|
||||
jsr iec_rx_byte
|
||||
#endif
|
||||
bcs load_iec_error
|
||||
|
||||
// Handle the byte (store in memory / verify)
|
||||
jsr lvs_handle_byte_load_verify
|
||||
bcs load_iec_error
|
||||
|
||||
// Advance pointer to data; it is OK if it advances past $FFFF,
|
||||
// one autostart technique does exactly this
|
||||
#if !HAS_OPCODES_65CE02
|
||||
inc EAL+0
|
||||
bne !+
|
||||
inc EAL+1
|
||||
!:
|
||||
#else
|
||||
inw EAL+0
|
||||
#endif
|
||||
|
||||
// Handle STOP key; it is probably an overkill to do it
|
||||
// with every byte, once per 32 bytes should be enough
|
||||
lda EAL
|
||||
and #$1F
|
||||
bne !+
|
||||
phx_trash_a
|
||||
jsr udtim_keyboard
|
||||
jsr STOP
|
||||
bcs_16 load_break_error
|
||||
plx_trash_a
|
||||
!:
|
||||
// Check for EOI - if so, this was the last byte
|
||||
bit IOSTATUS
|
||||
bvc load_iec_loop
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
load_iec_loop_end:
|
||||
|
||||
// Display end address
|
||||
jsr lvs_display_done
|
||||
|
||||
// Close file on drive
|
||||
|
||||
lda FA
|
||||
jsr iec_close_load
|
||||
|
||||
// Return last address
|
||||
jmp lvs_return_last_address
|
||||
|
||||
|
||||
load_iec_get_addr_byte:
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
jsr iec_rx_dispatch
|
||||
#else // no turbo supported
|
||||
jsr iec_rx_byte
|
||||
#endif
|
||||
|
||||
bcs !+
|
||||
lda IOSTATUS
|
||||
and #K_STS_EOI
|
||||
bne !+
|
||||
lda TBTCNT
|
||||
rts
|
||||
!:
|
||||
pla
|
||||
pla
|
||||
jmp load_iec_file_not_found
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,43 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// IEC part of the OPEN routine
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
open_iec:
|
||||
|
||||
// Check for command to send
|
||||
ldy FNLEN
|
||||
beq open_iec_done
|
||||
|
||||
// We have a command to send to IEC device
|
||||
jsr LISTEN
|
||||
bcc !+
|
||||
jmp kernalerror_DEVICE_NOT_FOUND
|
||||
!:
|
||||
lda SA
|
||||
jsr iec_cmd_open
|
||||
bcc !+
|
||||
jmp kernalerror_DEVICE_NOT_FOUND
|
||||
!:
|
||||
|
||||
#if CONFIG_MEMORY_MODEL_60K
|
||||
// We need our helpers to get to filenames under ROMs or IO area
|
||||
jsr install_ram_routines
|
||||
#endif
|
||||
|
||||
// Send command ('file name')
|
||||
jsr iec_send_file_name
|
||||
|
||||
open_iec_done:
|
||||
|
||||
jmp open_done_success
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,132 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// IEC part of the SAVE routine
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
|
||||
save_iec_dev_not_found:
|
||||
jmp lvs_device_not_found_error
|
||||
|
||||
|
||||
save_iec:
|
||||
|
||||
// Check file name
|
||||
lda FNLEN
|
||||
beq_16 kernalerror_FILE_NAME_MISSING
|
||||
|
||||
// Display SAVING
|
||||
jsr lvs_display_saving
|
||||
|
||||
// Call device to LISTEN
|
||||
lda FA
|
||||
jsr LISTEN
|
||||
bcs save_iec_dev_not_found
|
||||
|
||||
// Open channel 1 (reserved for file writing)
|
||||
lda #$01
|
||||
jsr iec_cmd_open
|
||||
bcs save_iec_dev_not_found
|
||||
|
||||
// Send file name
|
||||
jsr iec_send_file_name
|
||||
bcs save_iec_dev_not_found
|
||||
|
||||
// Call device to LISTEN once again
|
||||
lda FA
|
||||
jsr LISTEN
|
||||
bcs save_iec_dev_not_found
|
||||
|
||||
#if CONFIG_IEC_BURST_CIA1 || CONFIG_IEC_BURST_CIA2 || CONFIG_IEC_BURST_MEGA_65
|
||||
jsr burst_advertise
|
||||
#endif
|
||||
|
||||
lda #$61 // open channel / data (p3) , required according to p13
|
||||
sta TBTCNT
|
||||
jsr iec_tx_command
|
||||
bcs save_iec_dev_not_found
|
||||
|
||||
#if CONFIG_IEC_DOLPHINDOS
|
||||
jsr dolphindos_detect
|
||||
#endif
|
||||
|
||||
// Save start address
|
||||
lda STAL+0
|
||||
sta TBTCNT
|
||||
clc
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
jsr iec_tx_dispatch
|
||||
#else
|
||||
jsr iec_tx_byte
|
||||
#endif
|
||||
|
||||
lda STAL+1
|
||||
sta TBTCNT
|
||||
clc
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
jsr iec_tx_dispatch
|
||||
#else
|
||||
jsr iec_tx_byte
|
||||
#endif
|
||||
|
||||
jsr lvs_STAL_to_MEMUSS
|
||||
ldy #$00
|
||||
iec_save_loop:
|
||||
|
||||
// Retrieve byte to send
|
||||
#if CONFIG_MEMORY_MODEL_60K
|
||||
ldx #<MEMUSS+0
|
||||
jsr peek_under_roms
|
||||
#elif CONFIG_MEMORY_MODEL_46K || CONFIG_MEMORY_MODEL_50K
|
||||
jsr peek_under_roms_via_MEMUSS
|
||||
#else // CONFIG_MEMORY_MODEL_38K
|
||||
lda (MEMUSS),y
|
||||
#endif
|
||||
|
||||
// Send the byte
|
||||
sta TBTCNT
|
||||
clc
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
jsr iec_tx_dispatch
|
||||
#else
|
||||
jsr iec_tx_byte
|
||||
#endif
|
||||
|
||||
// Next iteration
|
||||
#if !HAS_OPCODES_65CE02
|
||||
jsr lvs_advance_MEMUSS
|
||||
#else
|
||||
inw MEMUSS+0
|
||||
#endif
|
||||
jsr lvs_check_EAL
|
||||
bne iec_save_loop
|
||||
|
||||
iec_save_loop_end:
|
||||
|
||||
// Close file on drive
|
||||
lda FA
|
||||
jsr UNLSN
|
||||
|
||||
lda FA
|
||||
jsr LISTEN
|
||||
|
||||
lda #$E1 // CLOSE command
|
||||
sta TBTCNT
|
||||
jsr iec_tx_command
|
||||
jsr iec_tx_command_finalize
|
||||
|
||||
// Tell drive to unlisten
|
||||
lda FA
|
||||
jsr UNLSN
|
||||
|
||||
// Return success
|
||||
clc
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC
|
||||
@@ -0,0 +1,33 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 296
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 223/224
|
||||
// - https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): .X, .Y
|
||||
//
|
||||
|
||||
|
||||
SECOND:
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
// Due to OPEN/CLOSE/TKSA/SECOND command encoding, allowed channels are 0-15; it is the caller
|
||||
// responsibility, hovewer, to provide value ORed with $60
|
||||
// - https://www.lemon64.com/forum/viewtopic.php?t=57694&sid=531ba3592bcffadef2ac8b9162f2e529
|
||||
// - https://www.pagetable.com/?p=1031 (Kernal API description)
|
||||
|
||||
// XXX consider checking whether value is in range (contrary to original ROM implementation)
|
||||
|
||||
jmp common_open_close_unlsn_second
|
||||
|
||||
#else
|
||||
|
||||
jmp kernalerror_ILLEGAL_DEVICE_NUMBER
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 301/302
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 223
|
||||
// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
|
||||
// - http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): .X, .Y
|
||||
//
|
||||
|
||||
|
||||
TALK:
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
// According to serial-bus.pdf (page 15) this routine flushes the IEC out buffer
|
||||
jsr iec_tx_flush
|
||||
|
||||
// Check whether device number is correct
|
||||
jsr iec_check_devnum_oc
|
||||
bcc !+
|
||||
jmp kernalerror_DEVICE_NOT_FOUND
|
||||
!:
|
||||
// Encode and execute the command
|
||||
ora #$40
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
common_talk_listen: // common part of TALK and LISTEN
|
||||
|
||||
sta TBTCNT
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS || CONFIG_IEC_DOLPHINDOS
|
||||
|
||||
lda #$FF // force JiffyDOS detection, clear DolphinDOS mark
|
||||
sta IECPROTO
|
||||
|
||||
#endif
|
||||
|
||||
jmp iec_tx_command
|
||||
|
||||
#else
|
||||
|
||||
jmp kernalerror_ILLEGAL_DEVICE_NUMBER
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 302
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 224
|
||||
// - https://www.pagetable.com/?p=1031, https://github.com/mist64/cbmbus_doc
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): .X, .Y
|
||||
//
|
||||
|
||||
|
||||
TKSA:
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
// Due to OPEN/CLOSE/TKSA/SECOND command encoding, allowed channels are 0-15; it is the caller
|
||||
// responsibility, hovewer, to provide value ORed with $60
|
||||
// - https://www.lemon64.com/forum/viewtopic.php?t=57694&sid=531ba3592bcffadef2ac8b9162f2e529
|
||||
// - https://www.pagetable.com/?p=1031 (Kernal API description)
|
||||
|
||||
ora #$90
|
||||
|
||||
jmp common_untlk_tksa
|
||||
|
||||
#else
|
||||
|
||||
jmp kernalerror_ILLEGAL_DEVICE_NUMBER
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 303
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 224
|
||||
// - https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc
|
||||
// - http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): .X, .Y
|
||||
//
|
||||
|
||||
|
||||
UNLSN:
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
// According to serial-bus.pdf (page 15) this routine flushes the IEC out buffer
|
||||
jsr iec_tx_flush
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS || CONFIG_IEC_DOLPHINDOS
|
||||
|
||||
lda #$FF // do not use JiffyDOS / DolphinDOS anymore, trigger JiffyDOS detection
|
||||
sta IECPROTO
|
||||
|
||||
#endif
|
||||
|
||||
// Buffer empty, send the command
|
||||
lda #$3F
|
||||
|
||||
jmp common_open_close_unlsn_second
|
||||
|
||||
#else
|
||||
|
||||
jmp kernalerror_ILLEGAL_DEVICE_NUMBER
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 304
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 224
|
||||
// - https://www.pagetable.com/?p=1031, , https://github.com/mist64/cbmbus_doc
|
||||
// - http://www.zimmers.net/anonftp/pub/cbm/programming/serial-bus.pdf
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): .X, .Y
|
||||
//
|
||||
|
||||
|
||||
UNTLK:
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
// According to serial-bus.pdf (page 15) this routine flushes the IEC out buffer
|
||||
jsr iec_tx_flush
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS || CONFIG_IEC_DOLPHINDOS
|
||||
|
||||
lda #$FF // do not use JiffyDOS / DolphinDOS anymore, trigger JiffyDOS detection
|
||||
sta IECPROTO
|
||||
|
||||
#endif
|
||||
|
||||
// Buffer empty, send the command
|
||||
lda #$5F
|
||||
|
||||
common_untlk_tksa: // common part of UNTLK and TKSA
|
||||
|
||||
sta TBTCNT
|
||||
jsr iec_tx_command
|
||||
bcs !+ // branch if error
|
||||
// XXX - for TKSA, is it really the right place to do a turnaround? I have some doubts
|
||||
// (it forces us to send the TKSA command 'manually' sometimes), but
|
||||
// Luigi Di Fraia (https://luigidifraia.wordpress.com/2017/06/27/codebase64-on-the-kernal-behaviour/)
|
||||
// claims TKSA Kernal routine actually does the turnaround
|
||||
jmp iec_turnaround_to_listen
|
||||
!:
|
||||
rts
|
||||
|
||||
#else
|
||||
|
||||
jmp kernalerror_ILLEGAL_DEVICE_NUMBER
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Advertise burst IEC protocol support to the receiver
|
||||
//
|
||||
|
||||
//
|
||||
// Based on idea by Pasi 'Albert' Ojala and description from
|
||||
// https://sites.google.com/site/h2obsession/CBM/C128/fast-serial-for-uiec
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC_BURST_CIA1
|
||||
|
||||
|
||||
burst_advertise:
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
// Skip if other protocol (only JiffyDOS is possible at this moment) already detected
|
||||
lda IECPROTO
|
||||
bmi !+
|
||||
bne burst_advertise_done
|
||||
!:
|
||||
#endif
|
||||
|
||||
panic #$FF // XXX implement this
|
||||
|
||||
burst_advertise_done:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Advertise burst IEC protocol support to the receiver
|
||||
//
|
||||
|
||||
//
|
||||
// Based on idea by Pasi 'Albert' Ojala and description from
|
||||
// https://sites.google.com/site/h2obsession/CBM/C128/fast-serial-for-uiec
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC_BURST_CIA2
|
||||
|
||||
|
||||
burst_advertise:
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
// Skip if other protocol (only JiffyDOS is possible at this moment) already detected
|
||||
lda IECPROTO
|
||||
bmi !+
|
||||
bne burst_advertise_done
|
||||
!:
|
||||
#endif
|
||||
|
||||
// Make sure this is not done under ATN
|
||||
jst iec_release_atn
|
||||
|
||||
// Set the clock rate to the fastest possible
|
||||
ldy #$01
|
||||
sty CIA2_TIMALO
|
||||
dey
|
||||
sty CIA2_TIMAHI
|
||||
|
||||
// Prepare registers for transfer
|
||||
lda #$C1
|
||||
sta CIA2_CRA // start timer A, serial out, TOD 50Hz
|
||||
bit CIA2_ICR // clear interrupt register
|
||||
|
||||
// Send test byte
|
||||
lda #$FF // $FF keeps DATA released, see https://www.c64-wiki.com/wiki/Fast_serial_bus_protocol
|
||||
sta CIA2_SDR
|
||||
|
||||
// Wait until byte sent
|
||||
lda #$08 // interrupt mask
|
||||
!:
|
||||
bit CIA2_ICR
|
||||
beq !-
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
burst_advertise_done:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Advertise burst IEC protocol support to the receiver
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC_BURST_MEGA_65
|
||||
|
||||
|
||||
burst_advertise:
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
// Skip if other protocol (only JiffyDOS is possible at this moment) already detected
|
||||
lda IECPROTO
|
||||
bmi !+
|
||||
bne burst_advertise_done:
|
||||
!:
|
||||
#endif
|
||||
|
||||
panic #$FF // XXX implement this
|
||||
|
||||
burst_advertise_done:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Helper routine for JiffyDOS detection
|
||||
//
|
||||
|
||||
// The standard parallel cable (used by SpeedDOS, DolphinDOS 2, etc.) connects the following UserPort lines:
|
||||
// - PB0-PB7 - CIA2_PRB ($DD01), CIA #2 port B
|
||||
// - PC2, FLAG2 - CIA2_ICR ($DD0D), CIA #2 handshaking line
|
||||
//
|
||||
// See:
|
||||
// - http://sta.c64.org/cbmpar41c.html
|
||||
// - http://sta.c64.org/cbmpar71c.html
|
||||
// - Commodore 64 Programers Referencee Guide, pages 360-361, 429
|
||||
// - Computes Mapping the C64, page 183
|
||||
|
||||
|
||||
|
||||
#if CONFIG_IEC_DOLPHINDOS
|
||||
|
||||
|
||||
dolphindos_detect:
|
||||
|
||||
// Make sure the port settings are correct
|
||||
|
||||
lda #$7F
|
||||
sta CIA2_ICR // disable interrupt generation
|
||||
lda #$00
|
||||
sta CIA2_DDRB // set all port B lines as input
|
||||
|
||||
// According to logs collected from modified VICE emulator, original DolphinDOS ROM
|
||||
// constantly reads $DD0D and $DD01 until handshake bit of $DD0D is set, or some kind
|
||||
// of timeout occurs
|
||||
|
||||
ldx #$20
|
||||
|
||||
dolphindos_detect_loop:
|
||||
|
||||
lda CIA2_ICR
|
||||
cmp #$10
|
||||
beq dolphindos_detect_success
|
||||
lda CIA2_PRB // XXX do we need this read?
|
||||
|
||||
dex
|
||||
bne dolphindos_detect_loop
|
||||
|
||||
// FALLTROUGH - protocol not detected
|
||||
|
||||
dolphindos_detect_fail:
|
||||
|
||||
rts
|
||||
|
||||
dolphindos_detect_success:
|
||||
|
||||
// Protocol detected
|
||||
|
||||
lda #$02
|
||||
sta IECPROTO
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC_DOLPHINDOS
|
||||
@@ -0,0 +1,122 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// DolphinDOS protocol support for IEC - optimized load loop
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC_DOLPHINDOS && !CONFIG_MEMORY_MODEL_60K
|
||||
|
||||
|
||||
dolphindos_load:
|
||||
|
||||
// Timing is critical for some parts, do not allow interrupts
|
||||
sei
|
||||
|
||||
// A trick to shorten EAL update time
|
||||
ldy #$00
|
||||
|
||||
#if CONFIG_IEC_DOLPHINDOS_FAST
|
||||
// Another trick: prepare values for quickly setting/releasing DATA
|
||||
lda CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_DAT_OUT - BIT_CIA2_PRA_CLK_OUT - BIT_CIA2_PRA_ATN_OUT
|
||||
sta IECPROTO // release DATA
|
||||
ora #BIT_CIA2_PRA_DAT_OUT
|
||||
sta TBTCNT // pull DATA
|
||||
#endif
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
dolphindos_load_loop:
|
||||
|
||||
#if !CONFIG_IEC_DOLPHINDOS_FAST
|
||||
// Check if this was EOI
|
||||
bit IOSTATUS
|
||||
bvs dolphindos_load_end
|
||||
#endif
|
||||
|
||||
// Wait for the talker to release the CLK line
|
||||
!:
|
||||
bit CIA2_PRA
|
||||
bvc !-
|
||||
|
||||
// Release the DATA to signal we are ready
|
||||
#if !CONFIG_IEC_DOLPHINDOS_FAST
|
||||
lda CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_DAT_OUT // release
|
||||
#else
|
||||
lda IECPROTO
|
||||
#endif
|
||||
sta CIA2_PRA
|
||||
|
||||
#if !CONFIG_IEC_DOLPHINDOS_FAST
|
||||
|
||||
// Check if EOI
|
||||
jsr iec_rx_check_eoi // can damage .X, but this is safe
|
||||
|
||||
#else
|
||||
|
||||
// Check if EOI - inlined code to avoid wasting cycles on RTS
|
||||
ldx #$13
|
||||
!:
|
||||
bit CIA2_PRA
|
||||
bvc dolphindos_load_no_eoi
|
||||
dex
|
||||
bne !-
|
||||
|
||||
// EOI - mark it and retrieve the last byte
|
||||
jsr iec_rx_check_eoi_confirm
|
||||
lda CIA2_PRB
|
||||
sta (EAL),y
|
||||
|
||||
// Update EAL for the last time
|
||||
sec
|
||||
jsr iec_update_EAL_by_Y
|
||||
|
||||
// Restore proper IECPROTO value
|
||||
lda #$02
|
||||
sta IECPROTO
|
||||
|
||||
// End of load loop
|
||||
jmp load_iec_loop_end
|
||||
|
||||
dolphindos_load_no_eoi:
|
||||
|
||||
#endif
|
||||
|
||||
// Retrieve and store byte
|
||||
lda CIA2_PRB
|
||||
sta (EAL),y
|
||||
|
||||
// Pull DATA to acknowledge
|
||||
#if !CONFIG_IEC_DOLPHINDOS_FAST
|
||||
lda CIA2_PRA
|
||||
ora #BIT_CIA2_PRA_DAT_OUT
|
||||
#else
|
||||
lda TBTCNT
|
||||
#endif
|
||||
sta CIA2_PRA
|
||||
|
||||
// Handle EAL
|
||||
iny
|
||||
bne dolphindos_load_loop
|
||||
inc EAL+1
|
||||
jmp dolphindos_load_loop
|
||||
|
||||
#if !CONFIG_IEC_DOLPHINDOS_FAST
|
||||
|
||||
dolphindos_load_end:
|
||||
|
||||
// Update EAL
|
||||
clc
|
||||
jsr iec_update_EAL_by_Y
|
||||
|
||||
// End of load loop
|
||||
jmp load_iec_loop_end
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // CONFIG_IEC_DOLPHINDOS and not CONFIG_MEMORY_MODEL_60K
|
||||
@@ -0,0 +1,42 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Helper table for encoding lower nibble for JiffyDOS,
|
||||
// values found by observing the actual transfer using
|
||||
// original ROMs
|
||||
//
|
||||
|
||||
// Similar tables are probably used by nearly all the disk turbo loaders,
|
||||
// either on the C64 or drive side, soometimes generated in RAM on the fly;
|
||||
// example disk turbo presented below has a very similar table - but the
|
||||
// values are in reversed order:
|
||||
// - https://www.pagetable.com/?p=568
|
||||
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
|
||||
jiffydos_bittable:
|
||||
|
||||
.byte $00
|
||||
.byte $80 // $10 + $70
|
||||
.byte $20
|
||||
.byte $A0 // $30 + $70
|
||||
.byte $40
|
||||
.byte $C0 // $50 + $70
|
||||
.byte $60
|
||||
.byte $E0 // $70 + $70
|
||||
|
||||
.byte $10 // $80 - $70
|
||||
.byte $90
|
||||
.byte $30 // $A0 - $70
|
||||
.byte $B0
|
||||
.byte $50 // $C0 - $70
|
||||
.byte $D0
|
||||
.byte $70 // $E0 - $70
|
||||
.byte $F0
|
||||
|
||||
|
||||
#endif // CONFIG_IEC_JIFFYDOS
|
||||
@@ -0,0 +1,54 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Helper routine for JiffyDOS detection
|
||||
//
|
||||
|
||||
// Detection is done by inserting a long delay (above 400us?) during sending command last bit, see:
|
||||
// - https://sites.google.com/site/h2obsession/CBM/C128/JiffySoft128
|
||||
// - https://github.com/rkrajnc/sd2iec/blob/master/src/iec.c
|
||||
// The 'iec.s' suggests, that the drive should respond by pulling data
|
||||
|
||||
// The original JiffyDOS ROM seems to perform detection with every command
|
||||
// (even though for many of them it always fails) and we have to replicate
|
||||
// this behaviour for compatibility with at least 1541 JiffyDOS ROM
|
||||
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
|
||||
jiffydos_detect:
|
||||
|
||||
ldy #$25 // 400us is nearly 410 cycles on NTSC
|
||||
// loop iteration below is 11 cycles,
|
||||
// and several cycles were already used
|
||||
jiffydos_detect_loop:
|
||||
lda CIA2_PRA // 4 cycles
|
||||
bpl jiffydos_detected // 2 cycles
|
||||
dey // 2 cycles
|
||||
bne jiffydos_detect_loop // 3 cycles if branch
|
||||
|
||||
lda IECPROTO
|
||||
bpl jiffydos_detect_end // no detection requested, preserve existing protocol
|
||||
|
||||
lda #$00 // normal protocol
|
||||
beq jiffydos_store_proto // branch always
|
||||
|
||||
jiffydos_detected:
|
||||
jsr iec_wait_for_data_release // guessed from VICE logs
|
||||
lda #$01 // JiffyDOS protocol
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
jiffydos_store_proto:
|
||||
sta IECPROTO
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
jiffydos_detect_end:
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC_JIFFYDOS
|
||||
@@ -0,0 +1,175 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// JiffyDOS protocol support for IEC - optimized load loop
|
||||
//
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS && !CONFIG_MEMORY_MODEL_60K
|
||||
|
||||
|
||||
// Note: original JiffyDOS LOAD loop checks for RUN/STOP key every time a sector is read,
|
||||
// see description at https://sites.google.com/site/h2obsession/CBM/C128/JiffySoft128
|
||||
//
|
||||
// For simplicity and some space savings, our routine does not check the RUN/STOP key at all;
|
||||
// the protocol is fast enough (especially with modern flash mediums) that probably nobody
|
||||
// will want to terminate the loading.
|
||||
|
||||
|
||||
jiffydos_load:
|
||||
|
||||
// XXX implement JiffyDOS optimized LOAD protocol, this one is ineffective
|
||||
|
||||
|
||||
// Timing is critical, do not allow interrupts
|
||||
sei
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS_BLANK
|
||||
|
||||
// Preserve register with screen status (blank/visible)
|
||||
lda VIC_SCROLY
|
||||
sta TBTCNT
|
||||
|
||||
// Blank screen to make sure no sprite/badline will interrupt
|
||||
jsr screen_off
|
||||
|
||||
// Preserve 3 lowest bits of CIA2_PRA XXX deduplicate this
|
||||
|
||||
lda CIA2_PRA
|
||||
and #%00000111
|
||||
sta C3PO
|
||||
|
||||
#else
|
||||
|
||||
// Store previous sprite status in temporary variable
|
||||
jsr jiffydos_prepare
|
||||
sta TBTCNT
|
||||
|
||||
#endif
|
||||
|
||||
// A trick to shorten EAL update time
|
||||
ldy #$FF
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
jiffydos_load_loop:
|
||||
|
||||
// Wait until device is ready to send (releases CLK)
|
||||
jsr iec_wait_for_clk_release
|
||||
|
||||
// Prepare 'start sending' message
|
||||
lda CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_DAT_OUT // release
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS_BLANK
|
||||
|
||||
// It seems JiffyDOS needs some time here; waste few cycles
|
||||
nop
|
||||
jsr iec_wait_rts
|
||||
|
||||
// Ask device to start sending bits
|
||||
sta CIA2_PRA
|
||||
|
||||
#else
|
||||
|
||||
// Wait for appropriate moment, ask device to start sending bits
|
||||
tax
|
||||
jsr jiffydos_wait_line
|
||||
stx CIA2_PRA // cycles: 4
|
||||
|
||||
#endif
|
||||
|
||||
// Prepare 'data pull' byte, cycles: 3 + 2 + 2 = 7
|
||||
lda C3PO
|
||||
ora #BIT_CIA2_PRA_DAT_OUT // pull
|
||||
tax
|
||||
|
||||
// Delay, JiffyDOS needs some time, 4 cycles
|
||||
nop
|
||||
nop
|
||||
|
||||
// Get bits, cycles: 4 + 2 + 2 = 8
|
||||
lda CIA2_PRA // bits 0 and 1 on CLK/DATA
|
||||
lsr
|
||||
lsr
|
||||
|
||||
// Delay, JiffyDOS needs some time, 2 cycles
|
||||
nop
|
||||
|
||||
// Get bits, cycles: 4 + 2 + 2 = 8
|
||||
ora CIA2_PRA // bits 2 and 3 on CLK/DATA
|
||||
lsr
|
||||
lsr
|
||||
|
||||
// Get bits, cycles: 3 + 4 + 2 + 2 = 11
|
||||
eor C3PO
|
||||
eor CIA2_PRA // bits 4 and 5 on CLK/DATA
|
||||
lsr
|
||||
lsr
|
||||
|
||||
// Get bits, cycles: 3 + 4 = 7
|
||||
eor C3PO
|
||||
eor CIA2_PRA // bits 6 and 7 on CLK/DATA
|
||||
|
||||
// Store retrieved byte, cycles: 2 + 6 = 8
|
||||
iny // NTSC needs this delay
|
||||
sta (EAL),y // not compatible with CONFIG_MEMORY_MODEL_60K
|
||||
|
||||
// Retrieve status bits, cycles: 4
|
||||
bit CIA2_PRA
|
||||
|
||||
// Pull DATA at the end, cycles: 4
|
||||
stx CIA2_PRA
|
||||
|
||||
// If CLK line not active - this was the last byte
|
||||
bvs jiffydos_load_end
|
||||
|
||||
// Handle EAL
|
||||
cpy #$FF
|
||||
bne jiffydos_load_loop
|
||||
inc EAL+1
|
||||
jmp jiffydos_load_loop
|
||||
|
||||
jiffydos_load_end:
|
||||
|
||||
// Save last byte
|
||||
tax
|
||||
|
||||
// Update EAL
|
||||
sec
|
||||
jsr iec_update_EAL_by_Y
|
||||
|
||||
// Indicate that no byte waits in output buffer
|
||||
lda #$00
|
||||
sta C3PO
|
||||
|
||||
// Restore proper IECPROTO value
|
||||
lda #$01
|
||||
sta IECPROTO
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS_BLANK
|
||||
|
||||
// Restore screen state
|
||||
lda TBTCNT
|
||||
sta VIC_SCROLY
|
||||
|
||||
#else
|
||||
|
||||
// Re-enable sprites
|
||||
lda TBTCNT
|
||||
sta VIC_SPENA
|
||||
|
||||
#endif
|
||||
|
||||
// Store last byte as unoptimized LOAD routine would
|
||||
stx TBTCNT
|
||||
|
||||
// No need to re-enable interrupts; other IEC routines
|
||||
// called by LOAD will do this nevertheless
|
||||
|
||||
// End of load loop
|
||||
jmp load_iec_loop_end
|
||||
|
||||
|
||||
#endif // CONFIG_IEC_JIFFYDOS and not CONFIG_MEMORY_MODEL_60K
|
||||
@@ -0,0 +1,32 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// JiffyDOS transfer preparation routine
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
|
||||
jiffydos_prepare:
|
||||
|
||||
// We need to preserve 3 lowest bits of CIA2_PRA, they contain important
|
||||
// data - fortunately, the bits are never changed by external devices
|
||||
// Use C3PO for this, as afterwards we have to set there 0 nevertheless
|
||||
lda CIA2_PRA
|
||||
and #%00000111
|
||||
sta C3PO
|
||||
|
||||
// Hide sprites; JiffyDOS timing regime is very strict, before transmitting
|
||||
// anything we need to make sure nothing will steal the cycles
|
||||
|
||||
lda VIC_SPENA
|
||||
ldx #$00
|
||||
stx VIC_SPENA
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC_JIFFYDOS
|
||||
@@ -0,0 +1,121 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// JiffyDOS protocol support for IEC - byte reception
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
|
||||
jiffydos_rx_byte:
|
||||
|
||||
// Timing is critical, do not allow interrupts
|
||||
sei
|
||||
|
||||
// Store .X and .Y on the stack - preserve them
|
||||
phx_trash_a
|
||||
phy_trash_a
|
||||
|
||||
// Store previous sprite status on stack
|
||||
jsr jiffydos_prepare
|
||||
pha
|
||||
|
||||
// Wait until device is ready to send (releases CLK)
|
||||
jsr iec_wait_for_clk_release
|
||||
|
||||
// Prepare 'start sending' message
|
||||
lda CIA2_PRA
|
||||
and #$FF - BIT_CIA2_PRA_DAT_OUT // release
|
||||
tax
|
||||
|
||||
// Wait for appropriate moment
|
||||
jsr jiffydos_wait_line
|
||||
|
||||
// Ask device to start sending bits
|
||||
stx CIA2_PRA // cycles: 4
|
||||
|
||||
// Prepare 'data pull' byte, cycles: 3 + 2 + 2 = 7
|
||||
lda C3PO
|
||||
ora #BIT_CIA2_PRA_DAT_OUT // pull
|
||||
tax
|
||||
|
||||
// Delay, JiffyDOS needs some time, 4 cycles
|
||||
nop
|
||||
nop
|
||||
|
||||
// Get bits, cycles: 4 + 2 + 2 = 8
|
||||
lda CIA2_PRA // bits 0 and 1 on CLK/DATA
|
||||
lsr
|
||||
lsr
|
||||
|
||||
// Wait for the drive, cycles: 2
|
||||
nop
|
||||
|
||||
// Get bits, cycles: 4 + 2 + 2 = 8
|
||||
ora CIA2_PRA // bits 2 and 3 on CLK/DATA
|
||||
lsr
|
||||
lsr
|
||||
|
||||
// Get bits, cycles: 3 + 4 + 2 + 2 = 11
|
||||
eor C3PO
|
||||
eor CIA2_PRA // bits 4 and 5 on CLK/DATA
|
||||
lsr
|
||||
lsr
|
||||
|
||||
// Get bits, cycles: 3 + 4 = 7
|
||||
eor C3PO
|
||||
eor CIA2_PRA // bits 6 and 7 on CLK/DATA
|
||||
|
||||
// Preserve read byte, cycles: 3
|
||||
sta TBTCNT // $A4 is a byte buffer according to http://sta.c64.org/cbm64mem.html
|
||||
|
||||
// Delay, JiffyDOS needs some time; for PAL one NOP would be enough,
|
||||
// but NTSC machines are clocked slightly faster; cycles: 4
|
||||
nop
|
||||
nop
|
||||
|
||||
// Retrieve status bits, cycles: 4
|
||||
bit CIA2_PRA
|
||||
|
||||
// Pull DATA at the end, cycles: 4
|
||||
stx CIA2_PRA
|
||||
|
||||
// If CLK line active - success
|
||||
bvc jiffydos_rx_byte_end
|
||||
|
||||
// EOI or error, released DATA (highest byte set to 1) means error - see protocol analysis by Michael Steil, step R7a
|
||||
lda CIA2_PRA
|
||||
bmi jiffydos_rx_byte_error
|
||||
|
||||
// EOI - no error
|
||||
jsr kernalstatus_EOI
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
jiffydos_rx_byte_end:
|
||||
|
||||
// Indicate that no byte waits in output buffer
|
||||
lda #$00
|
||||
sta C3PO
|
||||
|
||||
// Restore proper IECPROTO value
|
||||
lda #$01
|
||||
sta IECPROTO
|
||||
|
||||
// Re-enable sprites
|
||||
pla
|
||||
sta VIC_SPENA
|
||||
|
||||
// End byte reception
|
||||
jmp iec_rx_end
|
||||
|
||||
jiffydos_rx_byte_error:
|
||||
|
||||
jsr kernalerror_IEC_TIMEOUT_READ
|
||||
bcs jiffydos_rx_byte_end // branch always
|
||||
|
||||
|
||||
#endif // CONFIG_IEC_JIFFYDOS
|
||||
@@ -0,0 +1,111 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// JiffyDOS protocol support for IEC - byte transfer
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
|
||||
jiffydos_tx_byte:
|
||||
|
||||
// Timing is critical, do not allow interrupts
|
||||
sei
|
||||
|
||||
// If EOI requested (carry flag set), mark this in IECPROTO as 0
|
||||
bcc !+
|
||||
dec IECPROTO // turns 1 into 0
|
||||
!:
|
||||
// Store .X and .Y on the stack - preserve them
|
||||
phx_trash_a
|
||||
phy_trash_a
|
||||
|
||||
// Make sure we are not sending data on ATN
|
||||
jsr iec_release_atn
|
||||
|
||||
// Store previous sprite status on stack
|
||||
jsr jiffydos_prepare
|
||||
pha
|
||||
|
||||
// Prepare nibbles to send
|
||||
lda TBTCNT
|
||||
and #$0F
|
||||
tax
|
||||
lda jiffydos_bittable, X // low nibble has to be encoded
|
||||
pha
|
||||
lda TBTCNT
|
||||
and #$F0
|
||||
pha
|
||||
|
||||
// Prepare value for device notification
|
||||
ldx C3PO
|
||||
|
||||
// Wait till receiver is ready
|
||||
jsr iec_wait_for_data_release
|
||||
|
||||
// Wait till it is safe to send data
|
||||
jsr jiffydos_wait_line
|
||||
|
||||
// Notify device that we are going to send byte by releasing everything
|
||||
stx CIA2_PRA // cycles: 4
|
||||
// Send high nibble; cycles: 4 + 3 + 4 + 2 + 2 + 2 + 3 + 4 = 24
|
||||
pla // retrieve high nibble from stack
|
||||
ora C3PO // restore VIC-II and RS-232 bits
|
||||
sta CIA2_PRA // bits 4 and 5 on CLK/DATA
|
||||
lsr // move bits 6 and 7 to positions 4 and 5
|
||||
lsr
|
||||
and #%00110000 // clear everything but CLK/DATA
|
||||
ora C3PO
|
||||
sta CIA2_PRA // bits 6 and 7 on CLK/DATA
|
||||
|
||||
// Send low nibble; cycles: 4 + 3 + 4 + 2 + 2 + 2 + 4 = 21
|
||||
pla // retrieve low nibble from stack
|
||||
ora C3PO // restore VIC-II and RS-232 bits
|
||||
sta CIA2_PRA
|
||||
lsr
|
||||
lsr
|
||||
and #%00110000 // clear everything but CLK/DATA
|
||||
sta CIA2_PRA
|
||||
|
||||
// Signal EOI if needed; cycles till no EOI: 3 + 3 + 2 + 2 + 4 = 14
|
||||
lda C3PO
|
||||
ldx IECPROTO
|
||||
beq jiffydos_tx_byte_wait_eoi
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
jiffydos_tx_byte_finalize:
|
||||
|
||||
ora #BIT_CIA2_PRA_CLK_OUT // pull CLK
|
||||
sta CIA2_PRA
|
||||
|
||||
// Restore proper IECPROTO value
|
||||
lda #$01
|
||||
sta IECPROTO
|
||||
|
||||
// Re-enable sprites and interrupts
|
||||
pla
|
||||
sta VIC_SPENA
|
||||
cli
|
||||
|
||||
// Return success
|
||||
jmp iec_return_success
|
||||
|
||||
|
||||
jiffydos_tx_byte_wait_eoi:
|
||||
|
||||
sta CIA2_PRA
|
||||
jsr iec_wait20us
|
||||
lda C3PO
|
||||
|
||||
// According to protocol analysis by Michael Steil (step S8) we should pull the DATA here
|
||||
// to signal there was no error; but DATA pulled by the controller is a normal state
|
||||
// (which should be stored in C3PO), so there is nothing to do here.
|
||||
|
||||
jmp jiffydos_tx_byte_finalize
|
||||
|
||||
|
||||
#endif // CONFIG_IEC_JIFFYDOS
|
||||
@@ -0,0 +1,37 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// JiffyDOS helper routine to wait for appropriate moment,
|
||||
// where no badline will interrupt the transmission
|
||||
//
|
||||
|
||||
|
||||
#if CONFIG_IEC_JIFFYDOS
|
||||
|
||||
|
||||
jiffydos_wait_line:
|
||||
|
||||
// One might try to optimize the code by checking for disabled screen
|
||||
// (bit 4 of VIC_SCROLY); problem: VIC checks this bit only once per frame:
|
||||
// - https://www.lemon64.com/forum/viewtopic.php?t=56582
|
||||
// so it would complicated the code
|
||||
|
||||
// Avoid 2 lines before the badline, otherwise VIC will ruin the synchronization
|
||||
lda VIC_RASTER
|
||||
cmp #$2E
|
||||
bcc jiffydos_wait_line_done // we are safe, border - lot of time till badline
|
||||
!:
|
||||
lda VIC_RASTER // carry+ is definitely set here!
|
||||
sbc VIC_SCROLY
|
||||
and #$07 // we want 8 lowest bits
|
||||
cmp #$06
|
||||
bcs !-
|
||||
|
||||
jiffydos_wait_line_done:
|
||||
|
||||
rts
|
||||
|
||||
|
||||
#endif // CONFIG_IEC_JIFFYDOS
|
||||
@@ -0,0 +1,23 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# X16 * #IGNORE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
|
||||
// c64 prg p263
|
||||
|
||||
cartridge_check:
|
||||
|
||||
ldx #$05
|
||||
!:
|
||||
lda CART_SIG-1,x
|
||||
cmp cartridge_signature-1,x
|
||||
bne cartridge_check_end
|
||||
dex
|
||||
bne !-
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
cartridge_check_end:
|
||||
|
||||
rts
|
||||
@@ -0,0 +1,76 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// This is a part CINT which initializes screen and keyboard
|
||||
//
|
||||
// For more details see:
|
||||
// - [RG64] C64 Programmers Reference Guide - page 280
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 242
|
||||
//
|
||||
|
||||
|
||||
cint_screen_keyboard:
|
||||
|
||||
// Setup KEYLOG vector
|
||||
|
||||
lda #<scnkey_set_keytab
|
||||
sta KEYLOG+0
|
||||
lda #>scnkey_set_keytab
|
||||
sta KEYLOG+1
|
||||
|
||||
// Initialise cursor blink flags (Computes Mapping the 64 p215)
|
||||
|
||||
lda #$01
|
||||
sta BLNCT
|
||||
sta BLNSW
|
||||
|
||||
// Enable cursor repeat - XXX make it configurable
|
||||
|
||||
#if CONFIG_KEY_REPEAT_DEFAULT && !CONFIG_KEY_REPEAT_ALWAYS
|
||||
|
||||
lda #$80
|
||||
sta RPTFLG
|
||||
|
||||
#endif
|
||||
|
||||
// Set keyboard decode vector (Computes Mapping the 64 p215)
|
||||
|
||||
#if CONFIG_LEGACY_SCNKEY
|
||||
|
||||
// Set initial variables for our improved keyboard scan routine
|
||||
lda #$FF
|
||||
ldx #6
|
||||
!: sta BufferOld,x
|
||||
dex
|
||||
bpl !-
|
||||
sta BufferQuantity
|
||||
|
||||
// Set key repeat delay (Computes 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 (Computes Mapping the 64 p58)
|
||||
|
||||
// Not needed for default keyboard scanning code
|
||||
|
||||
ldx #22-2 // Fudge factor to match speed
|
||||
stx DELAY
|
||||
|
||||
#endif
|
||||
|
||||
// Set current colour for text (Computes Mapping the 64 p215)
|
||||
ldx #CONFIG_COLOR_TXT
|
||||
stx COLOR
|
||||
|
||||
// Set maximum keyboard buffer size (Computes Mapping the 64 p215)
|
||||
ldx #10
|
||||
stx XMAX
|
||||
|
||||
// Put non-zero value in MODE to enable case switch
|
||||
ldx #$00
|
||||
stx MODE
|
||||
|
||||
// Fallthrough/jump to screen clear routine (Computes Mapping the 64 p215)
|
||||
|
||||
jmp clear_screen
|
||||
@@ -0,0 +1,25 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Part of the official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 280
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 242
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): none
|
||||
//
|
||||
|
||||
|
||||
cint_legacy: // $E518
|
||||
|
||||
// Setup video and I/O
|
||||
// See here: https://csdb.dk/forums/index.php?roomid=11&topicid=17048&firstpost=22
|
||||
jsr setup_vicii
|
||||
|
||||
// Code below must be placed under $E51B, or some code will break - see here:
|
||||
// - https://csdb.dk/forums/index.php?roomid=11&topicid=17048&firstpost=2
|
||||
// Game 'Operacja Proboszcz' is one example.
|
||||
|
||||
jmp cint_screen_keyboard // XXX try to fit the code here
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
Game 'Operacja Proboszcz' explicitly calls $E51B - thus, it is sane
|
||||
to place old CINT routine in it's original place
|
||||
@@ -0,0 +1,71 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_0 #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE-FLOAT
|
||||
// #LAYOUT# X16 * #IGNORE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Well-known Kernal routine, described in:
|
||||
//
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 215
|
||||
//
|
||||
|
||||
|
||||
setup_vicii:
|
||||
|
||||
#if (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0)
|
||||
|
||||
jsr map_KERNAL_1
|
||||
jsr_ind VK1__setup_vicii
|
||||
jmp map_NORMAL
|
||||
|
||||
#else
|
||||
|
||||
// Clear everything - turn off sprites (observed hanging around after
|
||||
// running programs and resetting), etc.
|
||||
|
||||
lda #$00
|
||||
ldx #$2E
|
||||
!:
|
||||
sta __VIC_BASE, x
|
||||
dex
|
||||
bpl !-
|
||||
|
||||
#if !CONFIG_MB_MEGA_65 && !CONFIG_MB_ULTIMATE_64
|
||||
|
||||
// Disable C128 extra keys - just to be sure they will not interfere with anything
|
||||
|
||||
stx VIC_XSCAN
|
||||
|
||||
// Disable the C128 2MHz mode, it prevents VIC-II display from working correctly
|
||||
|
||||
stx VIC_CLKRATE
|
||||
|
||||
#endif
|
||||
|
||||
// Set up default IO values
|
||||
// - [CM64] page 129 - VIC_SCROLY
|
||||
// - [CM64] pages 140-144 - VIC_SCROLX
|
||||
// - [CM64] pages 145-146 - VIC_YMCSB
|
||||
|
||||
lda #$1B // according to [CM64] page 137 some software assumes oldest bit is 0
|
||||
sta VIC_SCROLY
|
||||
lda #$C8
|
||||
sta VIC_SCROLX // 40 column etc
|
||||
lda #$14
|
||||
sta VIC_YMCSB
|
||||
lda #$0F
|
||||
sta VIC_IRQ // clear all interrupts
|
||||
|
||||
// We use a different colour scheme of white text on all blue by default,
|
||||
// but brand-specific color scheme can also be enabled
|
||||
|
||||
lda #CONFIG_COLOR_BG
|
||||
sta VIC_EXTCOL
|
||||
sta VIC_BGCOL0
|
||||
|
||||
// Setup default I/O devices
|
||||
|
||||
jmp clrchn_reset
|
||||
|
||||
#endif // ROM layout
|
||||
@@ -0,0 +1,71 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
// Resources describing the C64 reset sequence:
|
||||
// https://www.c64-wiki.com/wiki/Reset_(Process)
|
||||
|
||||
|
||||
hw_entry_reset:
|
||||
|
||||
// The GPL program at https://github.com/Klaus2m5/6502_65C02_functional_tests/blob/master/6502_functional_test.a65
|
||||
// uses the similar initial reset sequence, affirmed by c64 PRG p269
|
||||
|
||||
sei // disable the interrupts, as fast as possible - they are disabled in case of HW reset,
|
||||
// but this routine can be also called manually
|
||||
|
||||
cld // required for all CPUs - due to possibility of manual call
|
||||
|
||||
#if HAS_OPCODES_65CE02
|
||||
|
||||
see // disable extended stack
|
||||
|
||||
#endif
|
||||
|
||||
ldx #$FF
|
||||
txs
|
||||
|
||||
#if ROM_LAYOUT_M65
|
||||
|
||||
jsr map_NORMAL // we want normal memory mapping
|
||||
|
||||
#endif
|
||||
|
||||
#if CONFIG_PLATFORM_COMMODORE_64
|
||||
|
||||
// The following routine is based on reading the public KERNAL jumptable routine
|
||||
// list, and making unimaginative assumptions about what should be done on reset.
|
||||
// Also, https://codebase64.org/doku.php?id=base:assembling_your_own_cart_rom_image was used
|
||||
// as it shows example startup sequence, to be followe by cartridge creators
|
||||
|
||||
// C64 PRG p269
|
||||
jsr cartridge_check
|
||||
bne !+
|
||||
jmp (ICART_COLD_START)
|
||||
!:
|
||||
|
||||
// Disable the screen (and set 40 columns) to prevent visual glitches later
|
||||
ldx #$28
|
||||
stx VIC_SCROLX
|
||||
|
||||
#endif
|
||||
|
||||
// Initialising IO is obviously required. Also indicated by c64 prg p269.
|
||||
jsr JIOINIT
|
||||
|
||||
// Setting up the screen and testing ram is obviously required
|
||||
// also affirmed by p269 of c64 prg
|
||||
jsr JRAMTAS // called RANTAM on Codebase64 wiki
|
||||
|
||||
// Resetting IO vectors is obviously required, if we want interrupts to run
|
||||
// also affirmed by c64 prg p269
|
||||
jsr JRESTOR
|
||||
|
||||
// "Compute's Mapping the 64" p236
|
||||
jsr JCINT
|
||||
|
||||
// What do we do when finished? A C64 jumps into the BASIC ROM
|
||||
cli // allow interrupts to happen
|
||||
|
||||
// c64 prg p269
|
||||
jmp (IBASIC_COLD_START)
|
||||
@@ -0,0 +1,5 @@
|
||||
System reset routine has to be placed under it's original location due to 'SYS 64738' being extremaly popular to reset the C64,
|
||||
to the point it went into popular culture.
|
||||
|
||||
https://twitter.com/hashtag/SYS64738?src=hash
|
||||
https://www.computerhope.com/jargon/s/sys64738.htm
|
||||
@@ -0,0 +1,3 @@
|
||||
RRAMTAS is an important startup routine, frequentl called b cartridges - unfortunately, we can't count on them calling it
|
||||
via the jumptable, as even some tutorials on the web advise to call it directly - see for example here:
|
||||
https://codebase64.org/doku.php?id=base:assembling_your_own_cart_rom_image
|
||||
@@ -0,0 +1,115 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_0 #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE-FLOAT
|
||||
// #LAYOUT# X16 KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 291
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 237
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): none
|
||||
//
|
||||
|
||||
RAMTAS:
|
||||
|
||||
#if (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0)
|
||||
|
||||
jsr map_KERNAL_1
|
||||
jsr_ind VK1__RAMTAS
|
||||
jmp map_NORMAL
|
||||
|
||||
#else
|
||||
|
||||
// C64 Programmers Reference guide p291:
|
||||
// Clear $0000-$0101, $0200-$03ff
|
||||
// PGS: $0000, $0001 are CPU IO ports, so should not get written to
|
||||
|
||||
// How many ways are there to efficiently erase these two pages
|
||||
// of RAM? We would like to avoid any unnecessary byte similarity
|
||||
// with the C64 KERNAL. Thus we do $0300 before $0200, even though
|
||||
// with the longer sequence of identicale bytes we see no basis for
|
||||
// it being copyrightable. Again, we just want to redue the attack
|
||||
// surface for any misguided suit.
|
||||
|
||||
ldy #$00
|
||||
lda #$00
|
||||
!:
|
||||
sta $0300,Y
|
||||
sta $0200,Y
|
||||
sta $0002,Y // that is why we do not use .X for index, we do not want zeropage addressing here!
|
||||
iny
|
||||
bne !-
|
||||
|
||||
// Allocate cassette buffer
|
||||
ldx #<$033C
|
||||
stx TAPE1+0
|
||||
ldx #>$033C
|
||||
stx TAPE1+1
|
||||
|
||||
#if CONFIG_PLATFORM_COMMODORE_64
|
||||
|
||||
// Set screen address pointer ("Compute's Mapping the 64" p238)
|
||||
// This is obvious boiler plate containing no creative input, but to avoid
|
||||
// unnecessarily similarity to the C64 KERNAL, we use X instead of A to do this,
|
||||
// and several following
|
||||
ldx #>$0400
|
||||
stx HIBASE
|
||||
|
||||
// Set BASIC start text pointer
|
||||
// (remember, that low memory is 0 initialized at this moment)
|
||||
|
||||
ldx #>$0800
|
||||
stx MEMSTR+1
|
||||
|
||||
// Work out RAM size and put in MEMSIZK
|
||||
// Try to modify $8000, if it fails then RAM ends at $7FFF, else $9FFF
|
||||
|
||||
ldx $8000
|
||||
inx
|
||||
stx $8000
|
||||
cpx $8000
|
||||
bne ramtas_32k
|
||||
|
||||
// FALLTROUGH
|
||||
|
||||
ramtas_40k:
|
||||
|
||||
// 40K RAM - restore memory content, set MEMSIZK
|
||||
|
||||
ldy #$A0
|
||||
!:
|
||||
sty MEMSIZK+1
|
||||
|
||||
// Always restore memory, cartridge might have RAM under ROM
|
||||
|
||||
dex
|
||||
stx $8000
|
||||
|
||||
rts
|
||||
|
||||
ramtas_32k:
|
||||
|
||||
// 32K RAM - restore memory content, set MEMSIZK
|
||||
|
||||
ldy #$80
|
||||
bne !- // branch always
|
||||
|
||||
#elif CONFIG_PLATFORM_COMMANDER_X16
|
||||
|
||||
ldx #>$0800
|
||||
stx MEMSTR+1
|
||||
|
||||
ldy #$9F
|
||||
sty MEMSIZK+1
|
||||
|
||||
#else
|
||||
|
||||
.error "Please fill-in RAMTAS"
|
||||
|
||||
#endif // platform
|
||||
|
||||
|
||||
#endif // ROM layout
|
||||
@@ -0,0 +1,174 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# M65 KERNAL_0 #TAKE
|
||||
// #LAYOUT# M65 KERNAL_1 #TAKE-FLOAT
|
||||
// #LAYOUT# X16 * #IGNORE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 285
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 238
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): none
|
||||
//
|
||||
|
||||
|
||||
IOINIT:
|
||||
|
||||
#if (ROM_LAYOUT_M65 && SEGMENT_KERNAL_0)
|
||||
|
||||
jsr map_KERNAL_1
|
||||
jsr_ind VK1__IOINIT
|
||||
jmp map_NORMAL
|
||||
|
||||
#else
|
||||
|
||||
//
|
||||
// First initialize the CPU port, to make sure we have correct memory map
|
||||
//
|
||||
|
||||
// We want BASIC and KERNAL ROMs mapped, and datasette motor off
|
||||
// (https://www.c64-wiki.com/wiki/Zeropage)
|
||||
// Work around for VICE bug: Writing $00 before $01 results in rubbish in $01
|
||||
// after. https://sourceforge.net/p/vice-emu/bugs/1057/
|
||||
|
||||
ldx #$27
|
||||
stx CPU_R6510
|
||||
ldx #$2F // checked real ROM value
|
||||
stx CPU_D6510
|
||||
|
||||
//
|
||||
// Now prevent the CIAs from generating interrupts, who knows what damage they can do
|
||||
//
|
||||
|
||||
// Disable IRQ generation for both CIAs - see [CM64], page 149
|
||||
|
||||
ldx #$7F
|
||||
stx CIA1_ICR // $DC0D
|
||||
stx CIA2_ICR // $DD0D
|
||||
|
||||
// See discussion here:
|
||||
// https://www.lemon64.com/forum/viewtopic.php?t=41744&sid=e294c254db2ba671cde643f100aae341
|
||||
// It seems that initializing this register to $7F is the best idea - UDTIM key scanning
|
||||
// also leaves this at $7F
|
||||
|
||||
stx CIA1_PRA // $DC00
|
||||
|
||||
//
|
||||
// Now silence the SID chip(s), depending on the configuration - we want them silent ASAP
|
||||
//
|
||||
|
||||
lda #$00
|
||||
|
||||
#if !CONFIG_MB_MEGA_65
|
||||
|
||||
// First the standard chip (skip if it is covered by whole $D4XX range)
|
||||
|
||||
#if !CONFIG_SID_D4XX
|
||||
sta SID_SIGVOL
|
||||
#endif // !CONFIG_SID_D4XX
|
||||
|
||||
// Silence manually configured 2nd and 3rd SIDs
|
||||
|
||||
#if CONFIG_SID_2ND
|
||||
sta SID_SIGVOL - __SID_BASE + CONFIG_SID_2ND_ADDRESS
|
||||
#endif // CONFIG_SID_2ND
|
||||
|
||||
#if CONFIG_SID_3RD
|
||||
sta SID_SIGVOL - __SID_BASE + CONFIG_SID_3RD_ADDRESS
|
||||
#endif // CONFIG_SID_3RD
|
||||
|
||||
// Silence whole D4XX and D5XX ranges (if configured)
|
||||
|
||||
#if CONFIG_SID_D4XX || CONFIG_SID_D5XX
|
||||
|
||||
ldy #$00
|
||||
!:
|
||||
|
||||
#if CONFIG_SID_D4XX
|
||||
sta SID_SIGVOL + $000, Y
|
||||
#endif // CONFIG_SID_D4XX
|
||||
|
||||
#if CONFIG_SID_D5XX
|
||||
sta SID_SIGVOL + $100, Y
|
||||
#endif // CONFIG_SID_D4XX
|
||||
|
||||
tya
|
||||
clc
|
||||
adc #$20
|
||||
tay
|
||||
bne !-
|
||||
|
||||
#endif // CONFIG_SID_D4XX || CONFIG_SID_D5XX
|
||||
|
||||
#else
|
||||
|
||||
// Mega65 specific handling - it contains 4 SIDs
|
||||
|
||||
sta SID_SIGVOL + __SID_R1_OFFSET
|
||||
sta SID_SIGVOL + __SID_R2_OFFSET
|
||||
sta SID_SIGVOL + __SID_L1_OFFSET
|
||||
sta SID_SIGVOL + __SID_L2_OFFSET
|
||||
|
||||
#endif // CONFIG_MB_MEGA_65
|
||||
|
||||
//
|
||||
// Now continue the CIAs initialization
|
||||
//
|
||||
|
||||
// For CIA #1 we need port A as output and port B as input to scan the keyboard
|
||||
|
||||
ldx #$FF
|
||||
stx CIA1_DDRA // $DC02
|
||||
inx
|
||||
stx CIA1_DDRB // $DC03
|
||||
stx CIA2_DDRB // $DD03 // XXX this port is used for RS-232, value here is most likely wrong!
|
||||
|
||||
#if CONFIG_KEYBOARD_C65 || CONFIG_KEYBOARD_C65_CAPS_LOCK
|
||||
|
||||
lda #$02
|
||||
sta C65_EXTKEYS_DDR // output for most keys, input for CAPS LOCK bit
|
||||
|
||||
#endif
|
||||
|
||||
// Set DDR on CIA2 for IEC bus, VIC-II banking (see [CM64], $DDOO description on page 193)
|
||||
lda #$3F
|
||||
sta CIA2_DDRA // $DD02
|
||||
|
||||
// Checked using VICE that original ROM initializes timers this way
|
||||
ldx #$08
|
||||
stx CIA1_CRB // $DC0F
|
||||
stx CIA2_CRA // $DD0E
|
||||
stx CIA2_CRB // $DD0F
|
||||
|
||||
// Set VIC-II bank - at least the 'Operacja Proboszcz' game needs this within IOINIT
|
||||
// Checked on original ROMs, that it sets bit #2 (RS-232 output) high
|
||||
|
||||
ldx #%00000111 // XXX adapt this to IEC idle state, JMP at the end won't be needed
|
||||
stx CIA2_PRA // $DD00
|
||||
|
||||
// Put something sane in the IRQ timer
|
||||
jsr setup_irq_timer
|
||||
|
||||
// Enable timer A to run continuously (http://codebase64.org/doku.php?id=base:timerinterrupts)
|
||||
ldx #$11
|
||||
stx CIA1_CRA // $DC0E
|
||||
|
||||
// Enable timer interrupt
|
||||
ldx #$81
|
||||
stx CIA1_ICR // $DC0D
|
||||
|
||||
#if CONFIG_IEC
|
||||
|
||||
// Set IEC bus to its initial idle state
|
||||
jmp iec_set_idle
|
||||
|
||||
#else
|
||||
|
||||
rts
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // ROM layout
|
||||
@@ -0,0 +1,17 @@
|
||||
// #LAYOUT# STD * #TAKE
|
||||
// #LAYOUT# * KERNAL_0 #TAKE
|
||||
// #LAYOUT# * * #IGNORE
|
||||
|
||||
//
|
||||
// Official Kernal routine, described in:
|
||||
//
|
||||
// - [RG64] C64 Programmers Reference Guide - page 280
|
||||
// - [CM64] Computes Mapping the Commodore 64 - page 242
|
||||
//
|
||||
// CPU registers that has to be preserved (see [RG64]): none
|
||||
//
|
||||
|
||||
CINT:
|
||||
|
||||
jsr cint_legacy
|
||||
jmp setup_pal_ntsc
|
||||
Loaded 100 of 697 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user