708 lines
21 KiB
PHP
Executable file
708 lines
21 KiB
PHP
Executable file
|
|
.ifndef _LOADER_INC_
|
|
_LOADER_INC_ = 1
|
|
|
|
DISABLE_WATCHDOG = 0 ; disable the drive-side watchdog - the watchdog will reset the drive safely when the host resets at any point,
|
|
; however, the drive hardware (1541 and 1571) only allows for a maximum time-out period of 65536 cycles: this means
|
|
; that letting the loader starve for a few video frames (about 1.5 frames with a 1571 running at 2 MHz) will reset
|
|
; the drive, which can be prevented using this option.
|
|
|
|
; C-128 only: for burst transfers, use the CLK line for the incoming data-sent signal rather than the
|
|
; SERIAL_IRQ flag in CIA1_ICR ($dc0d) in order to avoid interference by CIA1 interrupt handlers,
|
|
; note that this slows down transfer speed
|
|
ASYNCHRONOUS_BURST_HANDSHAKE = 0
|
|
|
|
; set to 0 if loading via KERNAL fallback is problematic with non-standard KERNALs, VICE virtual drives, IEEE-488 interfaces or devices like IDE64
|
|
KERNAL_FALLBACK_SEI_WORKAROUNDS = 1
|
|
KERNAL_FALLBACK_OPEN_SEI_WORKAROUNDS = 0; this does not work with VICE virtual device traps
|
|
|
|
CONFIG_INTERNAL = ((KERNAL_FALLBACK_SEI_WORKAROUNDS = 0) << 3) | (KERNAL_FALLBACK_OPEN_SEI_WORKAROUNDS << 2) | (ASYNCHRONOUS_BURST_HANDSHAKE << 1) | DISABLE_WATCHDOG
|
|
|
|
.pushseg
|
|
|
|
.segment "CODE"; import symbols as absolute by default
|
|
|
|
.scope diskio
|
|
|
|
.scope platform
|
|
COMMODORE_64 = 64
|
|
COMMODORE_128 = 128
|
|
COMMODORE_16 = 16
|
|
.endscope; platform
|
|
|
|
.scope drivetype
|
|
DRIVES_1541 = $00
|
|
DRIVES_157X = $10
|
|
DRIVES_1581_CMD = $20
|
|
DRIVES_MASK = $f0
|
|
|
|
DRIVE_1541 = $01
|
|
DRIVE_1541_C = $02
|
|
DRIVE_1541_II = $03
|
|
DRIVE_1541U = $04
|
|
DRIVE_1570 = $15
|
|
DRIVE_1571 = $16
|
|
DRIVE_1571CR = $17
|
|
DRIVE_1581 = $28
|
|
DRIVE_CMD_FD_2000 = $29
|
|
DRIVE_CMD_FD_4000 = $2a
|
|
DRIVE_CMD_HD = $2b
|
|
|
|
DRIVE_GENERIC_SERIAL = $fc ; -4
|
|
DRIVE_GENERIC_BURST = $fd ; -3
|
|
DRIVE_GENERIC_PARALLEL = $fe ; -2
|
|
DEVICE_NONE = $ff ; -1
|
|
.endscope; drivetype
|
|
|
|
.scope status
|
|
OK = 0
|
|
|
|
FILE_TOO_LARGE = $f7 ; -9
|
|
FILE_ON_DISK_TOO_SMALL = $f8 ; -8
|
|
FILE_ON_DISK_TOO_LARGE = $f9 ; -7
|
|
WRITE_PROTECT_ON = $fa ; -6
|
|
|
|
DEVICE_INCOMPATIBLE = $fb ; -5, cannot upload loader drive code to active device, if LOAD_VIA_KERNAL_FALLBACK != 0, do not regard this as an error
|
|
TOO_MANY_DEVICES = $fc ; -4, a device on the bus other than the active device is not compatible, if LOAD_VIA_KERNAL_FALLBACK != 0, do not regard this as an error
|
|
GENERIC_KERNAL_ERROR = $fd ; -3, an error occured during installation or while loading without installed drive code via KERNAL fallback, check the x register for further information
|
|
DEVICE_NOT_PRESENT = $fe ; -2
|
|
FILE_NOT_FOUND = $ff ; -1
|
|
.endscope; status
|
|
|
|
.endscope; diskio
|
|
|
|
.enum DECOMPRESSORS
|
|
|
|
BITNAX = 1 ; Doynax and Bitbreaker's Bitnax
|
|
BYTEBOOZER2 = 2 ; HCL/Booze Design's ByteBoozer2
|
|
DOYNAX_LZ = 3 ; Doynax LZ, aka Doynamite
|
|
EXOMIZER = 4 ; Magnus Lind's Exomizer
|
|
LEVELCRUSH = 5 ; Taboo Levelcrush
|
|
LZSA2 = 6 ; Emmanuel Marty's LZSA2 with modifications by Bitbreaker
|
|
NUCRUNCH = 7 ; ChristopherJam aka Shrydar's NuCrunch
|
|
PUCRUNCH = 8 ; Pasi Ojala's Pucrunch
|
|
SUBSIZER = 9 ; tlr's Subsizer
|
|
TINYCRUNCH = 10 ; ChristopherJam aka Shrydar's tinycrunch
|
|
TSCRUNCH = 11 ; Antonio Savona's TSCrunch
|
|
ZX0 = 12 ; Einar Saukas' ZX0/Salvador with Dali modifications by Bitbreaker
|
|
|
|
NONE = 0
|
|
|
|
.endenum
|
|
|
|
|
|
.ifdef EXTCONFIGPATH
|
|
.include "loaderconfig.inc"
|
|
.else
|
|
.include "config.inc"
|
|
.endif; !EXTCONFIGPATH
|
|
|
|
.if .defined(FORCE_ASYNCHRONOUS_BURST_HANDSHAKE)
|
|
USE_ASYNCHRONOUS_BURST_HANDSHAKE = 1
|
|
.else
|
|
USE_ASYNCHRONOUS_BURST_HANDSHAKE = ASYNCHRONOUS_BURST_HANDSHAKE
|
|
.endif
|
|
|
|
|
|
.ifndef __NO_LOADER_SYMBOLS_IMPORT
|
|
.ifndef install
|
|
|
|
.if PLATFORM <> diskio::platform::COMMODORE_16
|
|
; Set the VIC bank
|
|
; in: a - VIC bank (0..3)
|
|
; out: undefined
|
|
.macro SET_VIC_BANK bank
|
|
lda #bank & 3
|
|
sta CIA2_PRA
|
|
.endmacro
|
|
|
|
; allow for arbitrary $DD00 writes ($00-$FF) when the loader is idle,
|
|
; good for raster routines with LDA #value:STA $D018:STA $DD00, e.g.
|
|
|
|
; call after load
|
|
.macro ENTER_BUS_LOCK
|
|
; nothing to do
|
|
.endmacro
|
|
|
|
; call before load
|
|
.macro LEAVE_BUS_LOCK
|
|
; when the loader is idle, the user is
|
|
; allowed to write anything to CIA2_DDRA ($DD00) -
|
|
; set it to a known and valid state here.
|
|
;php; without these, there's a race condition and thus a small
|
|
;sei; chance for video glitches, but with these, there's a
|
|
INIT_CLEAR_ATN_OUT_CLEAR_CLK_OUT_CLEAR_DATA_OUT
|
|
;plp; chance for actual crashes with stable raster routines
|
|
.endmacro
|
|
|
|
.if ALLOW_2_MHZ_ON_C128 | (PLATFORM = diskio::platform::COMMODORE_128)
|
|
; For 2 MHz in interrupt handlers during loading,
|
|
; to be run at the start of every IRQ handler
|
|
.macro LOADER_IRQ_HANDLER_PROLOGUE
|
|
; buffer clock setting and continue at 2 MHz
|
|
lda VIC2_C128_CLOCK
|
|
pha
|
|
lda #C128_TWO_MHZ
|
|
sta VIC2_C128_CLOCK
|
|
.endmacro
|
|
|
|
; For 2 MHz in interrupt handlers during loading,
|
|
; to be run at the end of every IRQ handler
|
|
.macro LOADER_IRQ_HANDLER_EPILOGUE
|
|
pla
|
|
sta VIC2_C128_CLOCK
|
|
.endmacro
|
|
.endif
|
|
.else
|
|
; To be run at the start of every IRQ handler
|
|
.macro LOADER_IRQ_HANDLER_PROLOGUE
|
|
; buffer force single clock flag
|
|
; and allow double clock
|
|
lda TED_CHARGEN_ADDR
|
|
pha
|
|
and #255 - FORCE_SINGLE_CLOCK
|
|
sta TED_CHARGEN_ADDR
|
|
.endmacro
|
|
|
|
; To be run at the end of every IRQ handler
|
|
.macro LOADER_IRQ_HANDLER_EPILOGUE
|
|
; restore force single clock flag
|
|
.local fast
|
|
|
|
pla
|
|
lsr
|
|
lsr
|
|
lda TED_CHARGEN_ADDR
|
|
and #255 - FORCE_SINGLE_CLOCK
|
|
bcc fast
|
|
ora #FORCE_SINGLE_CLOCK
|
|
fast: sta TED_CHARGEN_ADDR
|
|
.endmacro
|
|
.endif
|
|
|
|
|
|
; Install the loader
|
|
; note: KERNAL ROM must be enabled, and the I flag will be cleared (CLI)
|
|
; in: nothing
|
|
; out: c - set on error
|
|
; a - status
|
|
; x - drive type (one of diskio::drivetypes)
|
|
; y - if status is diskio::status::OK, zeropage address of version string address
|
|
.import install
|
|
.macro LOADER_INSTALL
|
|
jsr install
|
|
.endmacro
|
|
|
|
.if LOAD_RAW_API
|
|
; Load a file without decompression
|
|
; in: x/y - x: lo, y: hi to 0-terminated filename string,
|
|
; zero-length file name will load next file
|
|
; c - if LOAD_TO_API != 0, c = 0: load to address as stored in the file
|
|
; c = 1: load to caller-specified address (loadaddrlo/hi)
|
|
; out: c - set on error
|
|
; a - status
|
|
.import loadraw
|
|
.macro LOADRAW name
|
|
.if LOAD_TO_API
|
|
clc
|
|
.endif
|
|
ldx #<(name)
|
|
ldy #>(name)
|
|
jsr loadraw
|
|
.endmacro
|
|
|
|
.macro LOADNEXTRAW
|
|
lda #0
|
|
LOADRAW * - 1
|
|
.endmacro
|
|
|
|
.if LOAD_TO_API
|
|
.macro LOADRAW_LOADTO name, dest
|
|
sec
|
|
lda #<(dest)
|
|
sta loadaddrlo
|
|
lda #>(dest)
|
|
sta loadaddrhi
|
|
ldx #<(name)
|
|
ldy #>(name)
|
|
jsr loadraw
|
|
.endmacro
|
|
|
|
.macro LOADNEXTRAW_LOADTO dest
|
|
lda #0
|
|
LOADRAW_LOADTO * - 1, dest
|
|
.endmacro
|
|
.endif; LOAD_TO_API
|
|
.endif; LOAD_RAW_API
|
|
|
|
.if LOAD_COMPD_API
|
|
; Load a compressed file
|
|
; in: x/y - x: lo, y: hi to 0-terminated filename string,
|
|
; zero-length file name will load next file
|
|
; c - if DECOMPLOAD_TO_API != 0, c = 0: load to address as stored in the file
|
|
; c = 1: load with caller-specified address offset (loadaddroffslo/hi)*
|
|
; out: c - set on error
|
|
; a - status
|
|
; x/y - if DECOMPRESSOR = DECOMPRESSORS::PUCRUNCH, x: lo, y: hi of the loaded file's execution address
|
|
|
|
; * this is an offset rather than an absolute destination, as the original destination address required for calculating this offset is
|
|
; stored in the file, but to retrieve it, the first file block would have to be loaded first to the original load address or to an extra buffer
|
|
|
|
.import loadcompd
|
|
.import loadcompdopen
|
|
.import loadcompdexecute
|
|
.macro LOADCOMPD name
|
|
ldx #<(name)
|
|
ldy #>(name)
|
|
jsr loadcompd
|
|
.endmacro
|
|
|
|
.macro LOADNEXTCOMPD
|
|
lda #0
|
|
LOADCOMPD * - 1
|
|
.endmacro
|
|
|
|
.if LOAD_TO_API
|
|
.macro LOADCOMPD_RELTO name, load_address_offset
|
|
sec
|
|
lda #<(load_address_offset)
|
|
sta loadaddroffslo
|
|
lda #>(load_address_offset)
|
|
sta loadaddroffshi
|
|
ldx #<(name)
|
|
ldy #>(name)
|
|
jsr loadcompd
|
|
.endmacro
|
|
|
|
.macro LOADNEXTCOMPD_RELTO dest_lo, dest_hi
|
|
lda #0
|
|
LOADCOMPD_RELTO #<(* - 1), #>(* - 1), dest_lo, dest_hi
|
|
.endmacro
|
|
.endif; LOAD_TO_API
|
|
.endif; LOAD_COMPD_API
|
|
|
|
.if FILE_EXISTS_API
|
|
; Check if file exists
|
|
; in: x/y - x: lo, y: hi to 0-terminated filename string
|
|
; out: c - set on file not found or error
|
|
; a - status
|
|
.import fileexists
|
|
.macro FILEEXISTS name
|
|
ldx #<(name)
|
|
ldy #>(name)
|
|
jsr fileexists
|
|
.endmacro
|
|
.endif; FILE_EXISTS_API
|
|
|
|
.if MEM_DECOMP_API
|
|
; Decompress a compressed file from memory
|
|
; in: x/y - x: lo, y: hi of compressed file in memory
|
|
; c - if MEMDECOMP_TO_API != 0, c = 0: decompress to address as stored in the file
|
|
; c = 1: decompress to caller-specified address (loadaddrlo/hi)
|
|
; out: x/y - if DECOMPRESSOR = DECOMPRESSORS::PUCRUNCH, x: lo, y: hi of the file's execution address
|
|
.import memdecomp
|
|
.macro MEMDECOMP source_lo, source_hi
|
|
.if MEM_DECOMP_TO_API
|
|
clc
|
|
.endif
|
|
ldx source_lo
|
|
ldy source_hi
|
|
jsr memdecomp
|
|
.endmacro
|
|
|
|
.if MEM_DECOMP_TO_API
|
|
.macro MEMDECOMP_TO source_lo, source_hi, dest
|
|
sec
|
|
lda #<(dest)
|
|
sta decdestlo
|
|
lda #>(dest)
|
|
sta decdesthi
|
|
ldx source_lo
|
|
ldy source_hi
|
|
jsr memdecomp
|
|
.endmacro
|
|
.endif; MEM_DECOMP_TO_API
|
|
.endif; MEM_DECOMP_API
|
|
|
|
.endif; !install
|
|
.endif; !__NO_LOADER_SYMBOLS_IMPORT
|
|
|
|
.struct drivecode
|
|
entry .word; drive
|
|
to .word; drive
|
|
length .word; bytes
|
|
from .word; host
|
|
.endstruct
|
|
|
|
.struct swapparams
|
|
buffer .word; $0800 bytes for swapped loader drive code
|
|
|
|
drivecode41 .tag drivecode
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
drivecode71 .tag drivecode
|
|
drivecode81 .tag drivecode
|
|
.endif; ONLY_1541_AND_COMPATIBLE = 0
|
|
.endstruct
|
|
|
|
.ifndef __NO_CUSTOMDRIVECODE_SYMBOLS_IMPORT
|
|
.ifndef swapdrvcod
|
|
.import swapdrvcod
|
|
.import restoreldr
|
|
.endif; !swapdrvcod
|
|
|
|
; Execute custom code in the drive, buffer loader code on host side before
|
|
; in: x/y - x: lo, y: hi of swapparams structure
|
|
; out: c - set on error
|
|
; a - status
|
|
.macro SWAP_DRIVECODE params
|
|
ldx #<(params)
|
|
ldy #>(params)
|
|
jsr swapdrvcod
|
|
.endmacro
|
|
|
|
; Restore drive-side loader code
|
|
; in: nothing
|
|
; out: undefined
|
|
.macro RESTORE_LOADER
|
|
jsr restoreldr
|
|
.endmacro
|
|
.endif; !__NO_CUSTOMDRIVECODE_SYMBOLS_IMPORT
|
|
|
|
.struct saveparams
|
|
filename .word; existing file to overwrite, pointer to 0-terminated filename string
|
|
from .word; pointer to file data
|
|
length .word; length of file data in bytes
|
|
loadaddress .word; usually same as from
|
|
buffer .word; pointer to $0800 bytes for swapped loader drive code
|
|
.endstruct
|
|
|
|
.ifndef __NO_SAVE_SYMBOLS_IMPORT
|
|
.ifndef save
|
|
|
|
.import save
|
|
; Save a file by overwriting an existing file of the same block-size
|
|
; in: x/y - x: lo, y: hi of saveparams structure
|
|
; out: c - set on error
|
|
; a - status
|
|
.macro SAVE_OVERWRITE params
|
|
ldx #<(params)
|
|
ldy #>(params)
|
|
jsr save
|
|
.endmacro
|
|
|
|
.endif; !save
|
|
.endif; !__NO_SAVE_SYMBOLS_IMPORT
|
|
|
|
.ifndef __NO_LOADER_SYMBOLS_IMPORT
|
|
|
|
.if UNINSTALL_API
|
|
; Uninstall the loader
|
|
; in: nothing
|
|
; out: undefined
|
|
.import uninstall
|
|
.macro LOADER_UNINSTALL
|
|
jsr uninstall
|
|
.endmacro
|
|
.endif; UNINSTALL_API
|
|
|
|
.if CLOSE_FILE_API
|
|
; Close an open file
|
|
; in: nothing
|
|
; out: undefined
|
|
.import closefile
|
|
.endif; CLOSE_FILE_API
|
|
|
|
|
|
; linker-generated loader segments symbols
|
|
|
|
.import __DISKIO_ZP_START__
|
|
.import __DISKIO_ZP_END__
|
|
.import __DISKIO_ZP_LOAD__
|
|
.import __DISKIO_ZP_RUN__
|
|
.import __DISKIO_ZP_SIZE__
|
|
|
|
.import __DISKIO_INSTALL_START__
|
|
.import __DISKIO_INSTALL_END__
|
|
.import __DISKIO_INSTALL_LOAD__
|
|
.import __DISKIO_INSTALL_RUN__
|
|
.import __DISKIO_INSTALL_SIZE__
|
|
|
|
.import __DISKIO_START__
|
|
.import __DISKIO_END__
|
|
.import __DISKIO_LOAD__
|
|
.import __DISKIO_RUN__
|
|
.import __DISKIO_SIZE__
|
|
|
|
.endif; !__NO_LOADER_SYMBOLS_IMPORT
|
|
|
|
|
|
.ifndef __NOIMPORTVARS
|
|
.ifndef loadaddrlo
|
|
.importzp loadaddrlo
|
|
.importzp loadaddrhi
|
|
|
|
.importzp loadaddroffslo
|
|
.importzp loadaddroffshi
|
|
|
|
.importzp decdestlo
|
|
.importzp decdesthi
|
|
|
|
.importzp endaddrlo
|
|
.importzp endaddrhi
|
|
|
|
.importzp bytesloadedlo
|
|
.importzp bytesloadedhi
|
|
.endif; !loadaddrlo
|
|
.endif; !__NOIMPORTVARS
|
|
|
|
.if PLATFORM <> diskio::platform::COMMODORE_16
|
|
.macro INIT_CLEAR_ATN_OUT_CLEAR_CLK_OUT_CLEAR_DATA_OUT
|
|
; this is executed during install and LEAVE_BUS_LOCK,
|
|
; hence it accesses the port register rather than the data direction register
|
|
lda #3
|
|
and CIA2_PRA
|
|
sta CIA2_PRA
|
|
.endmacro
|
|
.endif
|
|
|
|
; custom drive code API
|
|
|
|
.ifndef ID041
|
|
|
|
.importzp ID041
|
|
.importzp CURRTRACK41
|
|
.importzp NUMFILES41
|
|
.importzp SECTORLINKTABLE41
|
|
|
|
.import topofstack41
|
|
.import idleloop41
|
|
.import getbytecmp41
|
|
.import BLOCKBUFFER41
|
|
|
|
.importzp V1B41
|
|
.importzp V2B41
|
|
.importzp LEDSTATE41
|
|
.importzp FILESECTOR41
|
|
.importzp FILENAME41
|
|
.importzp LINKTRACK41
|
|
.importzp LINKSECTOR41
|
|
.importzp REQUESTEDSECTOR41
|
|
.import trkseek41
|
|
.import initlink41
|
|
.import sertoraw41
|
|
.import getbytewdog41
|
|
.import getbyte41
|
|
.import getbyterts41
|
|
.import setbv2b41
|
|
.import getblock41
|
|
.import idxloop41
|
|
.import wdogentr41
|
|
.import findfile41
|
|
.import loadfile41
|
|
|
|
.endif
|
|
|
|
; Return-to-loader macros
|
|
; upon execution, i-flag must be set, ATN must be asserted, DATA and CLK must be cleared
|
|
|
|
.macro RETURNTOLOADER41 hook
|
|
.scope
|
|
.assert * >= $0100, error, "Return to 1541 loader code too low in memory"
|
|
|
|
lda #$1a; ATNA_OUT | CLK_OUT | DATA_OUT
|
|
sta $1800; VIA1_PRB
|
|
|
|
lda $1800; VIA1_PRB
|
|
and #$60; DEVICE_NUMBER
|
|
ora #$94; ATN_IN | ATNA_OUT | CLK_IN
|
|
sta compare + 1
|
|
ldx #0
|
|
|
|
lda #$10; ATNA_OUT
|
|
sta $1800; VIA1_PRB
|
|
|
|
ldy $1800; VIA1_PRB
|
|
getbyte: lda #$80
|
|
getbit: cpy $1800; VIA1_PRB
|
|
beq getbit
|
|
ldy $1800; VIA1_PRB
|
|
compare: cpy #0
|
|
ror
|
|
bcc getbit
|
|
sta $00,x
|
|
inx
|
|
bne getbyte
|
|
|
|
hook
|
|
|
|
jmp $00da
|
|
|
|
.assert * <= $0800, error, "Return to 1541 loader code too high in memory"
|
|
.endscope
|
|
.endmacro
|
|
|
|
.ifndef NUMFILES71
|
|
|
|
.importzp CURRTRACK71
|
|
.importzp LEDSTATE71
|
|
.importzp CLEARSECTORLINKTABLE71
|
|
.importzp FILENAME71
|
|
.importzp LINKTRACK71
|
|
.importzp LINKSECTOR71
|
|
.importzp SECTORLINKTABLE71
|
|
.importzp DIRSECTORS71
|
|
.importzp CUSTOMZPBUFFER71
|
|
.importzp CUSTOMUPLOADSIZE71
|
|
.importzp getbytrt71
|
|
.importzp CUSTOMPARAM71
|
|
|
|
.importzp bsetv2b71
|
|
.importzp trkseek71
|
|
.import initlink71
|
|
.import onemhz71
|
|
.import topofstack71
|
|
.import getblock71
|
|
.import idleloop71
|
|
.import findfile71
|
|
.import loadfile71
|
|
.import idxloop71
|
|
.import BLOCKBUFFER71
|
|
|
|
.endif
|
|
|
|
.macro RETURNTOLOADER71 hook
|
|
.scope
|
|
.assert * >= $0100, error, "Return to 1571 loader code too low in memory"
|
|
|
|
ldx #0
|
|
|
|
lda #$10; ATNA_OUT
|
|
sta $1800
|
|
|
|
ldy $1800; VIA1_PRB
|
|
getbyte: lda #$80
|
|
getbit: cpy $1800; VIA1_PRB
|
|
beq getbit
|
|
ldy $1800; VIA1_PRB
|
|
cpy #$94; ATN_IN | ATNA_OUT | CLK_IN
|
|
ror
|
|
bcc getbit
|
|
sta $00,x
|
|
inx
|
|
bne getbyte
|
|
|
|
hook
|
|
|
|
jmp $0037
|
|
|
|
.assert * <= $0800, error, "Return to 1571 loader code too high in memory"
|
|
.endscope
|
|
.endmacro
|
|
|
|
.ifndef dcodinit81
|
|
|
|
.importzp CUSTOMPARAM81
|
|
|
|
.import dcodinit81
|
|
.import DRVCODEND81
|
|
.import BLOCKBUFFER81
|
|
.import CUSTOMRECEIVE81
|
|
.import filename81
|
|
.import swapzp81
|
|
.import getblock81
|
|
.import initwdog81
|
|
.import enablwdg81
|
|
.import initcntr81
|
|
.import bsyledon81
|
|
.import findfile81
|
|
.import loadfile81
|
|
.import DIRTRACKS81
|
|
|
|
.endif
|
|
|
|
.macro RETURNTOLOADER81 hook
|
|
.scope
|
|
.assert * >= DRVCODEND81, error, "Return to 1581 loader code too low in memory"
|
|
|
|
ldy #0
|
|
sty $4001; CIA_PRB
|
|
getbyte: lda #$80
|
|
getbit: pha
|
|
lda $4001; CIA_PRB
|
|
waitbit: cmp $4001; CIA_PRB
|
|
beq waitbit
|
|
lda $4001; CIA_PRB
|
|
and #$04; CLK_IN
|
|
cmp #$04; CLK_IN
|
|
pla
|
|
ror
|
|
bcc getbit
|
|
restore: sta $0300 & $ff00,y
|
|
iny
|
|
bne :+
|
|
inc restore + 2
|
|
: cpy #<DRVCODEND81
|
|
bne getbyte
|
|
lda restore + 2
|
|
cmp #>DRVCODEND81
|
|
bne getbyte
|
|
|
|
hook
|
|
|
|
waitrun: lda $4001; CIA_PRB
|
|
lsr
|
|
bcc waitrun
|
|
jmp dcodinit81
|
|
|
|
.endscope
|
|
.endmacro
|
|
|
|
.popseg
|
|
|
|
.if (ALLOW_2_MHZ_ON_C128 & (PLATFORM = diskio::platform::COMMODORE_64)) | (PLATFORM = diskio::platform::COMMODORE_128)
|
|
USE_2_MHZ = 1
|
|
.else
|
|
USE_2_MHZ = 0
|
|
.endif
|
|
|
|
.if LOAD_VIA_KERNAL_FALLBACK
|
|
.if DIRTRACK <> 18
|
|
.error "***** Option LOAD_VIA_KERNAL_FALLBACK requires DIRTRACK to be 18 *****"
|
|
.endif
|
|
.if DIRTRACK81 <> 40
|
|
.error "***** Option LOAD_VIA_KERNAL_FALLBACK requires DIRTRACK81 to be 40 *****"
|
|
.endif
|
|
|
|
.if (PLATFORM = diskio::platform::COMMODORE_128) & ASYNCHRONOUS_BURST_HANDSHAKE
|
|
.error "***** Option LOAD_VIA_KERNAL_FALLBACK requires ASYNCHRONOUS_BURST_HANDSHAKE = 0 *****"
|
|
.endif
|
|
|
|
.macro CHECK_LOADER_ZP_ADDRESSES
|
|
.assert (loader_zp_first > STATUS) || (loader_zp_last < STATUS), error, "Loader zeropage variables cross KERNAL STATUS register at $90"
|
|
.assert (loader_zp_first > C3PO) || (loader_zp_last < C3PO), error, "Loader zeropage variables cross KERNAL serial buffer output char buffered flag C3PO at $94"
|
|
.assert (loader_zp_first > BSOUR) || (loader_zp_last < BSOUR), error, "Loader zeropage variables cross KERNAL serial buffer byte BSOUR at $95"
|
|
|
|
.if PLATFORM = diskio::platform::COMMODORE_16
|
|
.assert (loader_zp_first > LDTND) || (loader_zp_last < LDTND), error, "Loader zeropage variables cross KERNAL logical file index/open files count at $97"
|
|
.assert (loader_zp_first > DFLTN) || (loader_zp_last < DFLTN), error, "Loader zeropage variables cross KERNAL input device variable DFLTN at $98"
|
|
.assert (loader_zp_first > DFLTO) || (loader_zp_last < DFLTO), error, "Loader zeropage variables cross KERNAL output device variable DFLTO at $99"
|
|
.assert (loader_zp_first > R2D2) || (loader_zp_last < R2D2), error, "Loader zeropage variables cross KERNAL serial bus EOI flag R2D2 at $a6"
|
|
.assert (loader_zp_first > BSOUR1) || (loader_zp_last < BSOUR1), error, "Loader zeropage variables cross KERNAL serial bus shift counter BSOUR1 at $a8"
|
|
.assert (loader_zp_first > COUNT) || (loader_zp_last < COUNT), error, "Loader zeropage variables cross KERNAL serial bus counter COUNT at $aa"
|
|
.assert (loader_zp_first > USE4DY) || (loader_zp_last < USE4DY), error, "Loader zeropage variables cross KERNAL parallel drive state register USE4DY at $f9"
|
|
.else; PLATFORM <> diskio::platform::COMMODORE_16
|
|
.assert (loader_zp_first > LDTND) || (loader_zp_last < LDTND), error, "Loader zeropage variables cross KERNAL logical file index/open files count at $98"
|
|
.assert (loader_zp_first > DFLTN) || (loader_zp_last < DFLTN), error, "Loader zeropage variables cross KERNAL input device variable DFLTN at $99"
|
|
.assert (loader_zp_first > DFLTO) || (loader_zp_last < DFLTO), error, "Loader zeropage variables cross KERNAL output device variable DFLTO at $9a"
|
|
.assert (loader_zp_first > R2D2) || (loader_zp_last < R2D2), error, "Loader zeropage variables cross KERNAL serial bus EOI flag R2D2 at $a3"
|
|
.assert (loader_zp_first > BSOUR1) || (loader_zp_last < BSOUR1), error, "Loader zeropage variables cross KERNAL serial bus shift counter BSOUR1 at $a4"
|
|
.assert (loader_zp_first > COUNT) || (loader_zp_last < COUNT), error, "Loader zeropage variables cross KERNAL serial bus counter COUNT at $a5"
|
|
.endif; PLATFORM <> diskio::platform::COMMODORE_16
|
|
.endmacro
|
|
.else
|
|
.macro CHECK_LOADER_ZP_ADDRESSES
|
|
.endmacro
|
|
.endif
|
|
|
|
.endif; _LOADER_INC_
|