1443 lines
42 KiB
ArmAsm
Executable file
1443 lines
42 KiB
ArmAsm
Executable file
|
|
.fileopt comment, "Loader install code portion"
|
|
.fileopt compiler, "CA65"
|
|
.fileopt author, "Gunnar Ruthenberg"
|
|
|
|
__NO_LOADER_SYMBOLS_IMPORT = 1
|
|
.include "loader.inc"
|
|
.include "../version.inc"
|
|
|
|
.include "cpu.inc"
|
|
.include "cia.inc"
|
|
.include "vdc.inc"
|
|
|
|
.include "basic.inc"; for PETSCII_RETURN
|
|
.include "kernal.inc"
|
|
|
|
CBM1581_8 = $a6e9; the '8' in the 1581's ID string
|
|
FD_F_HD_H = $fea4; the 'f' in the CMD FD 2000/4000's ID string or the 'h' in the CMD HD's ID string
|
|
|
|
|
|
.include "hal/hal.inc"
|
|
|
|
.include "drives/drivecode-common.inc"
|
|
|
|
.importzp loadaddrlo
|
|
|
|
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
.import cmdfdfix0
|
|
.import cmdfdfix1
|
|
.import cmdfdfix2
|
|
.if !DISABLE_WATCHDOG
|
|
.import cmdfdfix3
|
|
.import cmdfdfix4
|
|
.if ::PLATFORM = diskio::platform::COMMODORE_128
|
|
.import cmdfdfix5
|
|
.import cmdfdfix6
|
|
.endif ; ::PLATFORM = diskio::platform::COMMODORE_128
|
|
.endif; !DISABLE_WATCHDOG
|
|
.endif; ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
|
|
USE_GENERIC_DRIVE = 0
|
|
|
|
|
|
.macro itoa4 value
|
|
.if (value & $0f > 9)
|
|
.byte (value & $0f) + 'a' - 10
|
|
.else
|
|
.byte (value & $0f) + '0'
|
|
.endif
|
|
.endmacro
|
|
|
|
.macro itoa1 value
|
|
itoa4 value <> 0
|
|
.endmacro
|
|
|
|
.macro itoa8 value
|
|
itoa4 value >> 4
|
|
itoa4 value & $0f
|
|
.endmacro
|
|
|
|
.macro itoa16 value
|
|
itoa8 value >> 8
|
|
itoa8 value & $ff
|
|
.endmacro
|
|
|
|
|
|
.segment "DISKIO_INSTALL"
|
|
|
|
.ifdef INSTADDR
|
|
.org INSTADDR - 2
|
|
.word * + 2; load address
|
|
.endif
|
|
|
|
.export install
|
|
|
|
; Install the loader
|
|
|
|
; in: nothing
|
|
; out: c - set on error
|
|
; a - status
|
|
; x - drive type (one of diskio::drivetype)
|
|
; y - if status is diskio::status::OK, zp address of version string address
|
|
install: jmp doinstall
|
|
|
|
; unfortunately, scopes must be defined before using them,
|
|
; this is why the actual install code is moved to after the drive code
|
|
.scope cbm1541
|
|
drivecode41:
|
|
.include "drives/drivecode1541.s"
|
|
|
|
.exportzp ID041
|
|
.exportzp CURRTRACK41
|
|
.exportzp NUMFILES41
|
|
.exportzp SECTORLINKTABLE41
|
|
|
|
.export topofstack41
|
|
.export idleloop41
|
|
.export getbytecmp41
|
|
.export BLOCKBUFFER41
|
|
|
|
; symbols used by the saver
|
|
.exportzp V1B41
|
|
.exportzp V2B41
|
|
.exportzp LEDSTATE41
|
|
.exportzp FILESECTOR41
|
|
.exportzp FILENAME41
|
|
.exportzp LINKTRACK41
|
|
.exportzp LINKSECTOR41
|
|
.exportzp REQUESTEDSECTOR41
|
|
|
|
.export trkseek41
|
|
.export initlink41
|
|
.export sertoraw41
|
|
.export getbytewdog41
|
|
.export getbyte41
|
|
.export getbyterts41
|
|
.export setbv2b41
|
|
.export getblock41
|
|
.export idxloop41
|
|
.export wdogentr41
|
|
.export findfile41
|
|
.export loadfile41
|
|
.endscope
|
|
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
.scope cbm1571
|
|
drivecode71:
|
|
.include "drives/drivecode1571.s"
|
|
|
|
.exportzp SECTORLINKTABLE71
|
|
.exportzp CUSTOMZPBUFFER71
|
|
.exportzp CUSTOMUPLOADSIZE71
|
|
|
|
.export topofstack71
|
|
.export idleloop71
|
|
.export BLOCKBUFFER71
|
|
|
|
; symbols used by the saver
|
|
.exportzp CURRTRACK71
|
|
.exportzp LEDSTATE71
|
|
.exportzp CLEARSECTORLINKTABLE71
|
|
.exportzp FILENAME71
|
|
.exportzp LINKTRACK71
|
|
.exportzp LINKSECTOR71
|
|
.exportzp DIRSECTORS71
|
|
|
|
.export bsetv2b71
|
|
.export trkseek71
|
|
.export initlink71
|
|
.export onemhz71
|
|
.export getblock71
|
|
.export findfile71
|
|
.export loadfile71
|
|
.export idxloop71
|
|
.endscope
|
|
|
|
.scope cbm1581
|
|
drivecode81:
|
|
.include "drives/drivecode1581.s"
|
|
|
|
.exportzp CUSTOMPARAM81
|
|
|
|
.export dcodinit81
|
|
.export BLOCKBUFFER81
|
|
.export CUSTOMRECEIVE81
|
|
.export loadfile81
|
|
|
|
; symbols used by the saver
|
|
.export filename81
|
|
.export swapzp81
|
|
.export getblock81
|
|
.export initwdog81
|
|
.export enablwdg81
|
|
.export initcntr81
|
|
.export bsyledon81
|
|
.export findfile81
|
|
.export DIRTRACKS81
|
|
.endscope
|
|
|
|
.endif; ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
doinstall: lda #.lobyte(version)
|
|
sta loadaddrlo
|
|
lda #.hibyte(version)
|
|
sta loadaddrlo + 1
|
|
|
|
BRANCH_IF_NOT_INSTALLED :+
|
|
jmp isinstalld
|
|
|
|
: php; I flag buffer
|
|
|
|
jsr CLALL
|
|
|
|
.if PLATFORM = diskio::platform::COMMODORE_128
|
|
|
|
; set data and filename banks to current program bank
|
|
lda MMU_CR
|
|
asl
|
|
rol
|
|
rol
|
|
and #$03; BA
|
|
tax ; FNBANK
|
|
jsr SETBANK
|
|
|
|
.endif; PLATFORM = diskio::platform::COMMODORE_128
|
|
|
|
; try the drive as denoted by FA (current drive) first
|
|
lda FA
|
|
cmp #MIN_DEVICE_NO
|
|
bcc :+
|
|
cmp #MAX_DEVICE_NO + 1
|
|
bcc :++
|
|
: lda #MIN_DEVICE_NO; FA does not contain a drive address (MIN_DEVICE_NO..MAX_DEVICE_NO), try MIN_DEVICE_NO first
|
|
:
|
|
; find first available drive,
|
|
; this is done via the high-level open/read/close routines,
|
|
; so non-serial bus devices will also respond
|
|
sta FA
|
|
|
|
find1stdrv: pha; buffer active drive device number
|
|
|
|
lda #0
|
|
tax
|
|
tay
|
|
jsr SETNAM
|
|
lda #COMMAND_ERROR_CHANNEL
|
|
ldx FA
|
|
tay
|
|
jsr SETLFS
|
|
jsr OPEN
|
|
bcc openokay
|
|
|
|
cmp #OPEN_DEVICENOTPRESENT
|
|
beq trynextdev
|
|
tax
|
|
pla; buffered active drive device number
|
|
lda #diskio::status::GENERIC_KERNAL_ERROR
|
|
bne installerr; jmp
|
|
|
|
trynextdev: ; device not present, try next address
|
|
lda #COMMAND_ERROR_CHANNEL
|
|
jsr CLOSE
|
|
jsr CLRCH
|
|
ldx FA
|
|
inx
|
|
cpx #MAX_DEVICE_NO + 1
|
|
bne :+
|
|
ldx #MIN_DEVICE_NO
|
|
: stx FA
|
|
pla; buffered active drive device number
|
|
cmp FA
|
|
bne find1stdrv
|
|
|
|
lda #diskio::status::DEVICE_NOT_PRESENT
|
|
ldx #diskio::drivetype::DEVICE_NONE
|
|
installerr: ldy #loadaddrlo
|
|
plp; I flag restore
|
|
sec
|
|
rts
|
|
|
|
openokay: ldx #COMMAND_ERROR_CHANNEL
|
|
jsr CKOUT
|
|
jsr READSS
|
|
bne trynextdev
|
|
jsr CLRCH
|
|
; read error channel, this also stops potentially blinking error LED
|
|
ldx #COMMAND_ERROR_CHANNEL
|
|
jsr CHKIN
|
|
: jsr READSS
|
|
bne :+
|
|
jsr BASIN
|
|
jmp :-
|
|
: lda #COMMAND_ERROR_CHANNEL
|
|
jsr CLOSE
|
|
jsr CLRCH
|
|
|
|
pla; buffered active drive device number, leave FA at first detected present device
|
|
|
|
.if USE_GENERIC_DRIVE
|
|
jmp usegeneric
|
|
.endif
|
|
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
; check if drive allows code upload and execution
|
|
jsr chkdrvcode
|
|
beq notgeneric
|
|
|
|
usegeneric: ; no compatible drive found
|
|
lda #diskio::status::DEVICE_INCOMPATIBLE
|
|
jmp nodrvcode
|
|
|
|
notgeneric: ; check which model the drive is and upload corresponding drive code
|
|
jsr getmodel
|
|
|
|
sty drivetype
|
|
tya
|
|
bmi usegeneric
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
tax
|
|
tya
|
|
and #diskio::drivetype::DRIVES_MASK
|
|
cmp #diskio::drivetype::DRIVES_1581_CMD
|
|
bne not1581cmd
|
|
|
|
cpy #diskio::drivetype::DRIVE_CMD_HD
|
|
beq usegeneric
|
|
cpy #diskio::drivetype::DRIVE_1581
|
|
beq is1581
|
|
|
|
lda #OPC_BIT_ABS
|
|
sta cmdfdfix0 - cbm1581::drvcodebeg81 + cbm1581::drivecode81
|
|
lda #.lobyte($54); DIRTRACKFD
|
|
sta cmdfdfix1 - cbm1581::drvcodebeg81 + cbm1581::drivecode81
|
|
lda #.hibyte($54); DIRTRACKFD
|
|
sta cmdfdfix2 - cbm1581::drvcodebeg81 + cbm1581::drivecode81
|
|
.if (::PLATFORM <> diskio::platform::COMMODORE_128) & (!DISABLE_WATCHDOG)
|
|
lda #$ff
|
|
ldy #.lobyte($1c05)
|
|
.endif
|
|
jmp iscmdfd
|
|
|
|
is1581: lda #OPC_JMP_ABS
|
|
sta cmdfdfix0 - cbm1581::drvcodebeg81 + cbm1581::drivecode81
|
|
lda #.lobyte($022b); DIRTRACK81
|
|
sta cmdfdfix1 - cbm1581::drvcodebeg81 + cbm1581::drivecode81
|
|
lda #.hibyte($022b); DIRTRACK81
|
|
sta cmdfdfix2 - cbm1581::drvcodebeg81 + cbm1581::drivecode81
|
|
.if (::PLATFORM <> diskio::platform::COMMODORE_128) & (!DISABLE_WATCHDOG)
|
|
lda #COUNT_TA_UNDF | FORCE_LOAD | ONE_SHOT | TIMER_START
|
|
ldy #.lobyte(CIA_CRB)
|
|
iscmdfd: sta cmdfdfix3 - cbm1581::drvcodebeg81 + cbm1581::drivecode81
|
|
sty cmdfdfix4 - cbm1581::drvcodebeg81 + cbm1581::drivecode81
|
|
.else
|
|
iscmdfd:
|
|
.endif
|
|
not1581cmd:
|
|
lda dcodeselt0,x
|
|
sta dcodesel0
|
|
lda dcodeselt1,x
|
|
sta dcodesel1
|
|
lda dcodeselt2,x
|
|
sta dcodesel2
|
|
lda dcodeselt3,x
|
|
sta dcodesel3
|
|
lda dcodeselt4,x
|
|
sta dcodesel4
|
|
lda dcodeselt5,x
|
|
sta dcodesel5
|
|
lda dcodeselt6,x
|
|
sta dcodesel6
|
|
lda dcodeselt7,x
|
|
sta dcodesel7
|
|
lda dcodeselt8,x
|
|
sta dcodesel8
|
|
lda dcodeselt9,x
|
|
sta family
|
|
lda dcodeselta,x
|
|
sta dirtrack
|
|
|
|
.else; ONLY_1541_AND_COMPATIBLE
|
|
|
|
jsr chkdrvcode
|
|
beq :+
|
|
; no compatible drive found
|
|
lda #diskio::status::DEVICE_INCOMPATIBLE
|
|
jmp nodrvcode
|
|
|
|
; check if 1541U
|
|
: jsr drvlistn
|
|
ldx #0
|
|
: lda drvch1541u,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #drvchkued - drvch1541u
|
|
bne :-
|
|
jsr UNLSN
|
|
lda #.lobyte($0300)
|
|
ldx #.hibyte($0300)
|
|
jsr memreadbyt
|
|
bmi :+; branch if 1541U
|
|
lda #diskio::drivetype::DRIVE_1541
|
|
SKIPWORD
|
|
: lda #diskio::drivetype::DRIVE_1541U
|
|
sta drivetype
|
|
|
|
lda #.lobyte(cbm1541::drvcodeend41 - cbm1541::drvcodebeg41 + cbm1541::drivecode41)
|
|
sta dcodesel0
|
|
lda #.hibyte(cbm1541::drvcodeend41 - cbm1541::drvcodebeg41 + cbm1541::drivecode41)
|
|
sta dcodesel1
|
|
lda #.lobyte(cbm1541::drvprgend41 - cbm1541::drvcodeend41 + cbm1541::TRAMPOLINEOFFSET)
|
|
sta dcodesel2
|
|
lda #.lobyte(cbm1541::drivecode41)
|
|
sta dcodesel3
|
|
lda #.hibyte(cbm1541::drivecode41)
|
|
sta dcodesel4
|
|
lda #.hibyte(cbm1541::drvcodeend41 - cbm1541::TRAMPOLINEOFFSET)
|
|
sta dcodesel5
|
|
lda #.lobyte(cbm1541::drvcodeend41 - cbm1541::TRAMPOLINEOFFSET)
|
|
sta dcodesel6
|
|
lda #.hibyte(cbm1541::dinstall)
|
|
sta dcodesel7
|
|
lda #.lobyte(cbm1541::dinstall)
|
|
sta dcodesel8
|
|
|
|
.endif; ONLY_1541_AND_COMPATIBLE
|
|
|
|
; check if there is more than 1 drive on the serial bus,
|
|
; upload silencing routines to the passive drives in order
|
|
; to make sure the 2bit+ATN protocol can work alright,
|
|
; detection is done via the low-level serial bus routines,
|
|
; so non-serial bus devices won't respond
|
|
; (1551 on Plus/4 does respond, though, so a little extra
|
|
; treatment is done through the drive disturbance HAL macros)
|
|
|
|
lda FA; active drive
|
|
pha
|
|
ldx #MIN_DEVICE_NO
|
|
checkbus: stx FA
|
|
pla
|
|
pha
|
|
cmp FA
|
|
beq jmpnodrive
|
|
|
|
lda #0
|
|
sta STATUS
|
|
PREPARE_DRIVE_DISTURBANCE_VALIDATION
|
|
jsr drvlistn
|
|
BRANCH_IF_DRIVE_DOES_NOT_DISTURB_SERIAL_BUS jmpnodrive
|
|
jsr READSS
|
|
bpl :+
|
|
jmpnodrive: jmp nodrive
|
|
|
|
; more than 1 drive on the bus or generic serial devices present
|
|
: jsr UNLSN
|
|
|
|
; upload and execute silencing routine
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
jsr chkdrvcode
|
|
beq mute
|
|
|
|
mutefail: lda FA
|
|
ldx #'0' - 1
|
|
sec
|
|
: inx
|
|
tay
|
|
sbc #10
|
|
bcs :-
|
|
stx mutedevice
|
|
tya
|
|
adc #'0'
|
|
sta mutedevice + 1
|
|
ldx #errormute - messages
|
|
jsr message
|
|
pla
|
|
sta FA
|
|
lda #diskio::status::TOO_MANY_DEVICES
|
|
jmp nodrvcode
|
|
|
|
mute: jsr getmodel
|
|
tya
|
|
bmi mutefail
|
|
|
|
tya
|
|
and #diskio::drivetype::DRIVES_MASK
|
|
cmp #diskio::drivetype::DRIVES_1581_CMD
|
|
beq mute81cmd
|
|
|
|
pha
|
|
.endif; ONLY_1541_AND_COMPATIBLE = 0
|
|
jsr drvlistn
|
|
ldx #0
|
|
: lda drvsilencc,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #atnfallbck - drvsilencc
|
|
bne :-
|
|
jsr drvrelistn
|
|
ldx #0
|
|
: lda atnfallbck,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #atnlo - atnfallbck
|
|
bne :-
|
|
jsr drvrelistn
|
|
ldx #0
|
|
: lda atnlo,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #atnhi - atnlo
|
|
bne :-
|
|
jsr drvrelistn
|
|
ldx #0
|
|
: lda atnhi,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #atnhiend - atnhi
|
|
bne :-
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
jsr UNLSN
|
|
pla
|
|
cmp #diskio::drivetype::DRIVES_157X
|
|
bne :++
|
|
jsr drvlistn
|
|
ldx #0
|
|
: lda drvslnc71,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #drvslnc71e - drvslnc71
|
|
bne :-
|
|
beq mutexecute; jmp
|
|
: jsr drvlistn
|
|
.else; ONLY_1541_AND_COMPATIBLE = 0
|
|
jsr drvrelistn
|
|
.endif; ONLY_1541_AND_COMPATIBLE = 0
|
|
ldx #0
|
|
: lda drvsilence,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #drvsilnced - drvsilence
|
|
bne :-
|
|
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
beq mutexecute; jmp
|
|
|
|
mute81cmd: cpy #diskio::drivetype::DRIVE_1581
|
|
bne mutecmd
|
|
|
|
jsr drvlistn
|
|
ldx #0
|
|
: lda drvslnc81,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #drvslnc81e - drvslnc81
|
|
bne :-
|
|
beq mutexecute; jmp
|
|
|
|
mutecmd: cpy #diskio::drivetype::DRIVE_CMD_HD
|
|
beq mutecmdhd
|
|
|
|
jsr drvlistn
|
|
ldx #0
|
|
: lda drvslncfd,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #drvslncfde - drvslncfd
|
|
bne :-
|
|
beq mutexecute; jmp
|
|
|
|
mutecmdhd: jsr drvlistn
|
|
ldx #0
|
|
: lda drvslnchd,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #drvslnchde - drvslnchd
|
|
bne :-
|
|
.endif; ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
mutexecute: jsr drvrelistn
|
|
ldx #0
|
|
: lda drvmuteme,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #drvmutemed - drvmuteme
|
|
bne :-
|
|
beq nodrive; jmp
|
|
|
|
nodrvcode: pha; error code
|
|
|
|
.if LOAD_VIA_KERNAL_FALLBACK
|
|
; quicker head stepping
|
|
jsr drvlistn
|
|
ldx #6
|
|
: lda drvfaststp,x
|
|
jsr CIOUT
|
|
dex
|
|
bpl :-
|
|
jsr UNLSN
|
|
|
|
lda #.lobyte($e5c6)
|
|
ldx #.hibyte($e5c6)
|
|
jsr memreadbyt
|
|
cpx #'1' | $80; 71
|
|
bne :++
|
|
jsr drvlistn
|
|
ldx #4
|
|
: lda twosided,x
|
|
jsr CIOUT
|
|
dex
|
|
bpl :-
|
|
jsr drvrelistn; make sure the drive is done
|
|
jsr UNLSN ; when leaving the init routine
|
|
:
|
|
.endif; LOAD_VIA_KERNAL_FALLBACK
|
|
|
|
CHECK_AND_BRANCH_IF_DRIVE_PARALLEL drivepar
|
|
|
|
.if PLATFORM = diskio::platform::COMMODORE_128
|
|
lda burstflag
|
|
beq :+
|
|
ldx #diskio::drivetype::DRIVE_GENERIC_BURST
|
|
SKIPWORD
|
|
:
|
|
.endif
|
|
ldx #diskio::drivetype::DRIVE_GENERIC_SERIAL
|
|
SKIPWORD
|
|
drivepar: ldx #diskio::drivetype::DRIVE_GENERIC_PARALLEL
|
|
pla; error code
|
|
plp; I flag restore
|
|
ldy #loadaddrlo
|
|
.if LOAD_VIA_KERNAL_FALLBACK
|
|
clc; this is not to be regarded as an error
|
|
.else
|
|
sec
|
|
.endif
|
|
rts
|
|
|
|
nodrive: jsr UNLSN
|
|
ldx FA
|
|
inx
|
|
cpx #MAX_DEVICE_NO + 1
|
|
beq :+
|
|
jmp checkbus
|
|
: pla
|
|
sta FA; active drive
|
|
|
|
; install drive-side loader code
|
|
.if PLATFORM = diskio::platform::COMMODORE_128
|
|
lda #0
|
|
sta SERIAL
|
|
.endif
|
|
jsr drvlistn
|
|
ldx #0
|
|
upload: sec
|
|
stx :+ + 1
|
|
dcodesel2 = * + 1
|
|
lda #0
|
|
: sbc #0
|
|
cmp #35
|
|
bcc :+
|
|
lda #35
|
|
: sta drvrutmw
|
|
|
|
ldy #6
|
|
: lda drvrutmw - 1,y
|
|
jsr CIOUT
|
|
dey
|
|
bne :-
|
|
|
|
dcodesel0 = * + 1
|
|
dcodesel1 = * + 2
|
|
: lda $c001,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx dcodesel2
|
|
beq :+
|
|
iny
|
|
cpy #35
|
|
bne :-
|
|
jsr drvrelistn
|
|
clc
|
|
lda #35
|
|
adc drvrutmw + 2
|
|
sta drvrutmw + 2
|
|
bcc upload
|
|
inc drvrutmw + 1
|
|
bne upload
|
|
|
|
: jsr drvrelistn
|
|
ldx #0
|
|
: lda droutrun,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #droutruned - droutrun
|
|
bne :-
|
|
jsr UNLSN
|
|
|
|
INIT_CLEAR_ATN_OUT_CLEAR_CLK_OUT_CLEAR_DATA_OUT
|
|
|
|
: SET_FLAGS_N_DATA_V_CLK
|
|
bvs :-
|
|
|
|
CLEAR
|
|
|
|
: SET_FLAGS_N_DATA_V_CLK
|
|
bvc :-
|
|
|
|
dcodesel3 = * + 1
|
|
ldy #0
|
|
dcodesel4 = * + 2
|
|
fastinst: lda $00,y
|
|
SENDBYTE
|
|
iny
|
|
bne :+
|
|
inc fastinst + 2
|
|
: cpy dcodesel0
|
|
bne fastinst
|
|
lda fastinst + 2
|
|
cmp dcodesel1
|
|
bne fastinst
|
|
|
|
INSTALL_IDLE
|
|
|
|
.if PLATFORM = diskio::platform::COMMODORE_128
|
|
burstflag = * + 1
|
|
lda #0
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
bne burst
|
|
.endif
|
|
DISABLE_BURST_MODE
|
|
burst:
|
|
.endif; PLATFORM = diskio::platform::COMMODORE_128
|
|
|
|
; if 1541U is detected, it runs on buggy firmware
|
|
lda drivetype
|
|
cmp #diskio::drivetype::DRIVE_1541U
|
|
bne :+
|
|
ldx #warnemubug - messages
|
|
jsr message
|
|
|
|
: plp; I flag restore
|
|
|
|
isinstalld: lda #diskio::status::OK
|
|
drivetype = * + 1
|
|
ldx #0
|
|
ldy #loadaddrlo
|
|
clc
|
|
rts
|
|
|
|
message: lda BORDERCOLOUR
|
|
pha
|
|
lda BGCOLOUR
|
|
pha
|
|
lda #COLOUR_RED
|
|
sta BORDERCOLOUR
|
|
sta BGCOLOUR
|
|
.if PLATFORM = diskio::platform::COMMODORE_16
|
|
lda TED_CTRL1
|
|
pha
|
|
lda #TEXT_MODE | DISPLAY_ENABLE | LINES_25 | SCROLLY_3; $1b
|
|
sta TED_CTRL1
|
|
lda TED_CTRL2
|
|
pha
|
|
and #.lobyte(~MULTICOLOUR_MODE)
|
|
ora #COLUMNS_40
|
|
sta TED_CTRL2
|
|
lda TED_BITMAP_ADDR
|
|
pha
|
|
ora #CHARSET_BITMAP_IN_ROM
|
|
sta TED_BITMAP_ADDR
|
|
lda TED_CHARGEN_ADDR
|
|
pha
|
|
and #.lobyte(~CHARGEN_ADDR_MASK)
|
|
ora #MAKE_CHARGEN_ADDR(CHARSET_ADDR_UPPERLOWER)
|
|
sta TED_CHARGEN_ADDR
|
|
lda TED_SCREEN_ADDR
|
|
pha
|
|
and #.lobyte(~SCREEN_ADDR_MASK)
|
|
ora #MAKE_SCREEN_ADDR($0c00)
|
|
sta TED_SCREEN_ADDR
|
|
lda PALETTE
|
|
pha
|
|
lda #PALETTE_DEFAULT
|
|
sta PALETTE
|
|
.else; PLATFORM <> diskio::platform::COMMODORE_16
|
|
.if PLATFORM = diskio::platform::COMMODORE_128
|
|
lda #FG_BG
|
|
sta VDC_CR
|
|
: bit VDC_SR; wait until update ready
|
|
bpl :-
|
|
lda VDC_DR
|
|
pha
|
|
lda #RED
|
|
sta VDC_DR
|
|
.endif ; PLATFORM = diskio::platform::COMMODORE_128
|
|
lda VIC2_CTRL1
|
|
and #.lobyte(~RASTERLINE_BIT8)
|
|
pha
|
|
lda VIC2_CTRL2
|
|
pha
|
|
lda VIC2_ADDR
|
|
pha
|
|
lda CIA2_PRA
|
|
and #VIC2_BANK
|
|
pha
|
|
lda #TEXT_MODE | DISPLAY_ENABLE | LINES_25 | SCROLLY_3; $1b
|
|
sta VIC2_CTRL1
|
|
lda #SINGLECOLOUR_MODE | COLUMNS_40 | SCROLLX_0; $08
|
|
sta VIC2_CTRL2
|
|
lda #VIC2_MAKE_ADDR($0400, CHARSET_ADDR_UPPERLOWER)
|
|
sta VIC2_ADDR
|
|
lda #(VIC2_MAKE_BANK $0400) & VIC2_BANK
|
|
sta CIA2_PRA
|
|
.endif; PLATFORM <> diskio::platform::COMMODORE_16
|
|
lda DFLTO
|
|
pha
|
|
lda COLOR
|
|
pha
|
|
lda #DEVICE_SCREEN
|
|
sta DFLTO
|
|
: lda messages,x
|
|
beq :+
|
|
jsr BSOUT
|
|
.if PLATFORM = diskio::platform::COMMODORE_16
|
|
lda #BLINK
|
|
ora COLOR
|
|
sta COLOR
|
|
.endif; PLATFORM = diskio::platform::COMMODORE_16
|
|
inx
|
|
bne :-
|
|
: pla
|
|
sta COLOR
|
|
pla
|
|
sta DFLTO
|
|
lda #8
|
|
: dex
|
|
bne :-
|
|
dey
|
|
bne :-
|
|
sbc #1
|
|
bne :-
|
|
.if PLATFORM = diskio::platform::COMMODORE_16
|
|
pla
|
|
sta PALETTE
|
|
pla
|
|
sta TED_SCREEN_ADDR
|
|
pla
|
|
sta TED_CHARGEN_ADDR
|
|
pla
|
|
sta TED_BITMAP_ADDR
|
|
pla
|
|
sta TED_CTRL2
|
|
pla
|
|
sta TED_CTRL1
|
|
.else; PLATFORM <> diskio::platform::COMMODORE_16
|
|
pla
|
|
sta CIA2_PRA
|
|
pla
|
|
.if PLATFORM = diskio::platform::COMMODORE_128
|
|
sta VM1
|
|
.endif ; PLATFORM = diskio::platform::COMMODORE_128
|
|
sta VIC2_ADDR
|
|
pla
|
|
sta VIC2_CTRL2
|
|
pla
|
|
sta VIC2_CTRL1
|
|
.if PLATFORM = diskio::platform::COMMODORE_128
|
|
lda #FG_BG
|
|
sta VDC_CR
|
|
: bit VDC_SR; wait until update ready
|
|
bpl :-
|
|
pla
|
|
sta VDC_DR
|
|
.endif ; PLATFORM = diskio::platform::COMMODORE_128
|
|
.endif; PLATFORM <> diskio::platform::COMMODORE_16
|
|
pla
|
|
sta BGCOLOUR
|
|
pla
|
|
sta BORDERCOLOUR
|
|
rts
|
|
|
|
drvrelistn: jsr UNLSN
|
|
drvlistn: lda FA
|
|
jsr LISTN
|
|
.if PLATFORM = diskio::platform::COMMODORE_128
|
|
lda SERIAL
|
|
sta burstflag
|
|
.endif
|
|
lda #SA_OPENCHANNEL | COMMAND_ERROR_CHANNEL
|
|
jmp SECND
|
|
|
|
memreadbyt: sta drvchkmr + 3
|
|
stx drvchkmr + 4
|
|
lda #drvchkmred - drvchkmr
|
|
ldx #.lobyte(drvchkmr)
|
|
ldy #.hibyte(drvchkmr)
|
|
jsr SETNAM
|
|
lda #COMMAND_ERROR_CHANNEL
|
|
ldx FA
|
|
tay
|
|
jsr SETLFS
|
|
jsr OPEN
|
|
bcc :+
|
|
lda #0
|
|
tax
|
|
rts
|
|
|
|
: ldx #COMMAND_ERROR_CHANNEL
|
|
jsr CHKIN
|
|
jsr BASIN
|
|
pha
|
|
jsr BASIN
|
|
pha
|
|
lda #COMMAND_ERROR_CHANNEL
|
|
jsr CLOSE
|
|
jsr CLRCH
|
|
pla
|
|
tax
|
|
pla
|
|
clc
|
|
rts
|
|
|
|
drvchkmr: .byte "m-r", $00, $00, 2
|
|
drvchkmred:
|
|
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
getmodel: ; check if running on a 1541/70/71 compatible drive
|
|
lda #.lobyte($e5c6)
|
|
ldx #.hibyte($e5c6)
|
|
jsr memreadbyt
|
|
cmp #'4'
|
|
bne not1541
|
|
|
|
; find out if 1541, 1541-C or 1541-II
|
|
lda #.lobyte($c002)
|
|
ldx #.hibyte($c002)
|
|
jsr memreadbyt
|
|
cmp #'c'
|
|
beq chk1541ii; branch if 'c' at $c002 (from 'COPYRIGHT' etc.)
|
|
; find out if 1541 or 1541-C
|
|
lda #.lobyte($eaa3)
|
|
ldx #.hibyte($eaa3)
|
|
jsr memreadbyt
|
|
ldy #diskio::drivetype::DRIVE_1541
|
|
cmp #$ff
|
|
beq check1541u
|
|
; 1541-C: no $ff at $eaa3 (but likely $fe, data direction for track 0 sensor bit)
|
|
ldy #diskio::drivetype::DRIVE_1541_C
|
|
beq check1541u
|
|
chk1541ii: lda #.lobyte($e5b7)
|
|
ldx #.hibyte($e5b7)
|
|
jsr memreadbyt
|
|
tax
|
|
lda #$ff
|
|
cpx #'c' | $80; 'CBM DOS' etc.
|
|
bne :+; treat as 1541-II if no match, so as not to detect JiffyDOS, SpeedDOS etc. as 1541-C but 1541-II instead
|
|
; find out if 1541-C or 1541-II
|
|
lda #.lobyte($eaa3)
|
|
ldx #.hibyte($eaa3)
|
|
jsr memreadbyt
|
|
: ldy #diskio::drivetype::DRIVE_1541_C
|
|
cmp #$ff
|
|
bne check1541u; 1541-C: no $ff at $eaa3 (but likely $fe, data direction for track 0 sensor bit)
|
|
iny; diskio::drivetype::DRIVE_1541_II: $ff at $eaa3
|
|
; check for discrete drive logics vs gate array
|
|
sty model1541
|
|
jsr drvlistn
|
|
ldx #0
|
|
: lda dchk1541ii,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #dch1541iie - dchk1541ii
|
|
bne :-
|
|
jsr UNLSN
|
|
lda #.lobyte($0300)
|
|
ldx #.hibyte($0300)
|
|
jsr memreadbyt
|
|
beq :+; branch if 1541-II
|
|
ldy #diskio::drivetype::DRIVE_1541
|
|
check1541u: sty model1541
|
|
: jsr drvlistn
|
|
ldx #0
|
|
: lda drvch1541u,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #drvchkued - drvch1541u
|
|
bne :-
|
|
jsr UNLSN
|
|
lda #.lobyte($0300)
|
|
ldx #.hibyte($0300)
|
|
jsr memreadbyt
|
|
bmi :+; branch if 1541U
|
|
model1541 = * + 1
|
|
ldy #0
|
|
SKIPWORD
|
|
: ldy #diskio::drivetype::DRIVE_1541U
|
|
rts
|
|
|
|
not1541: cmp #'7'
|
|
bne not157x
|
|
|
|
; find out if 1570 or 1571
|
|
cpx #'1' | $80; 71
|
|
ldy #diskio::drivetype::DRIVE_1570
|
|
bcc is1570
|
|
; 1571 or 1571CR
|
|
|
|
lda #.lobyte($e5c2)
|
|
ldx #.hibyte($e5c2)
|
|
jsr memreadbyt
|
|
cmp #'1'; 3.1
|
|
ldy #diskio::drivetype::DRIVE_1571
|
|
bcc :+
|
|
iny; diskio::drivetype::DRIVE_1571CR
|
|
:
|
|
is1570: rts
|
|
|
|
not157x: ; neither 1541 nor 157x
|
|
|
|
; try FD2000/FD4000
|
|
lda #.lobyte(FD_F_HD_H)
|
|
ldx #.hibyte(FD_F_HD_H)
|
|
jsr memreadbyt
|
|
cmp #'f'
|
|
beq :+
|
|
cmp #'h'
|
|
bne check1581
|
|
ldy #diskio::drivetype::DRIVE_CMD_HD
|
|
rts
|
|
|
|
: lda #.lobyte($fef0)
|
|
ldx #.hibyte($fef0)
|
|
jsr memreadbyt
|
|
ldy #diskio::drivetype::DRIVE_CMD_FD_2000
|
|
cmp #'4'
|
|
bne isfd2000
|
|
iny; diskio::drivetype::DRIVE_CMD_FD_4000
|
|
isfd2000: rts
|
|
|
|
; check if 1581
|
|
check1581: lda #.lobyte(CBM1581_8)
|
|
ldx #.hibyte(CBM1581_8)
|
|
jsr memreadbyt
|
|
ldy #diskio::drivetype::DRIVE_1581
|
|
cmp #'8'
|
|
bne :+
|
|
lda #diskio::status::DEVICE_INCOMPATIBLE
|
|
: rts
|
|
|
|
dchk1541ii: .byte "m-e", .lobyte($0205), .hibyte($0205)
|
|
sei
|
|
lda $1c0c
|
|
ldx #$ec; disable byte sync: clear SOE
|
|
stx $1c0c
|
|
ldy #$01
|
|
bit $1c01
|
|
ldx $1c01
|
|
: cpx $1c01; with disabled byte sync, $1c01 does not change on a 1541-II
|
|
bne :+
|
|
iny
|
|
bne :-
|
|
: sty $0300; if not 0, not a 1541-II (discrete drive logics rather than gate array)
|
|
sta $1c0c
|
|
cli
|
|
rts
|
|
dch1541iie:
|
|
.assert (* - dchk1541ii) <= 41, error, "dchk1541ii too big"
|
|
|
|
.endif ; ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
; may be executed on 1570/71 with ONLY_1541_AND_COMPATIBLE
|
|
drvch1541u: .byte "m-e", .lobyte($0205), .hibyte($0205)
|
|
sei
|
|
;ldy #0
|
|
dey
|
|
sty $0300
|
|
sty $1803; set all port pins as outputs
|
|
lda #$a4; bit 0 may be forced to GND (1541-II) or connected to track 0 sensor (1541-C, normally 0 = not on track 0)
|
|
sta $1801
|
|
cmp $1801
|
|
bne is1541u
|
|
anc #$8a; and #imm, but no asl/rol, bit 7 of result goes to carry
|
|
beq is1541u
|
|
bcc is1541u
|
|
tya
|
|
arr #$7f; bit 6 of result goes to carry
|
|
ror $0300
|
|
is1541u: lda #$66; 1570/71 data directions
|
|
sta $1803
|
|
; no cli
|
|
rts
|
|
drvchkued:
|
|
.assert (* - drvch1541u) <= 41, error, "drvch1541u too big"
|
|
|
|
drvmuteme: .byte "m-e", .lobyte($020b), .hibyte($020b), "krill."
|
|
sei
|
|
jmp $0300
|
|
drvmutemed:
|
|
drvsilence: .byte "m-w", .lobyte($0300), .hibyte($0300), drvsilnced - (* + 1)
|
|
cli
|
|
ldy #$7f
|
|
sty $180e; no IRQs from VIA1
|
|
sty $1c0e; no IRQs from VIA2
|
|
sty $400d; no IRQs from CIA/MOS5710
|
|
sei
|
|
sty $1802; set only ATN_IN as input
|
|
lda #$ff
|
|
sta $1803; set all $1801 port pins as outputs
|
|
ldx #.hibyte($0400); CLK_IN, ATNA_OUT cleared, CLK_OUT low, DATA_OUT low
|
|
stx $1801
|
|
ldy #$d0 ; JOBCODE_EXECUTE
|
|
jmp $043b; waitactive
|
|
drvsilnced:
|
|
.assert (* - drvsilence) <= 41, error, "drvsilence too big"
|
|
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
drvslnc71: .byte "m-w", .lobyte($0300), .hibyte($0300), drvslnc71e - (* + 1)
|
|
cli
|
|
ldy #$7f
|
|
sty $180e; no IRQs from VIA1
|
|
sty $1c0e; no IRQs from VIA2
|
|
sty $400d; no IRQs from CIA/MOS5710
|
|
sei
|
|
sty $1802; set only ATN_IN as input
|
|
lda #$20 ; 2 MHz mode
|
|
ora $1801
|
|
sta $1801
|
|
lda #$ff
|
|
ldx #.hibyte($0400); CLK_IN, ATNA_OUT cleared, CLK_OUT low, DATA_OUT low
|
|
ldy #$d0 ; JOBCODE_EXECUTE
|
|
jmp $043b; waitactive
|
|
drvslnc71e:
|
|
.assert (* - drvslnc71) <= 41, error, "drvslnc71 too big"
|
|
|
|
.endif ; ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
drvsilencc: .byte "m-w", .lobyte($043b), .hibyte($043b), atnfallbck - (* + 1)
|
|
waitactive:;lda #$ff
|
|
sta $1c06; VIA2 timer 1 latch lo
|
|
jsr $0407; waitactpr
|
|
ldy #$90 ; ATNA_OUT set, CLK_OUT low, DATA_OUT low
|
|
: ;ldx #.hibyte($0400); CLK_IN, ATNA_OUT cleared, CLK_OUT low, DATA_OUT low
|
|
stx $1800; clear ATNA_OUT, set CLK_IN
|
|
: bit $1800
|
|
bpl :-
|
|
;ldy #$90 ; ATNA_OUT set, CLK_OUT low, DATA_OUT low
|
|
sty $1800; set ATNA_OUT, clear CLK_IN
|
|
;lda #$ff
|
|
sta $1c05; timer 1 hi
|
|
: bit $1800
|
|
bpl :---
|
|
bit $1c05; timer 1 hi
|
|
bne :-
|
|
cmp $1803
|
|
|
|
.assert (* - drvsilencc) <= 41, error, "waitactive too big"
|
|
|
|
atnfallbck: .byte "m-w", .lobyte($043b + atnfallbck - waitactive), .hibyte($043b + atnfallbck - waitactive), atnlo - (* + 1)
|
|
bne atnloop
|
|
cpx $1801; check if fast silencing using jmp ($1800) is possible
|
|
bne :+
|
|
cpy $1800
|
|
beq * + 32; silncentry: jmp ($1800)
|
|
; slower fallback silence routine, this is required on older 1541U firmware revisions at least, which do not implement VIA1 port A correctly,
|
|
; it may also be required for drives modded with a parallel connection,
|
|
; this is executed unconditionally on 1570/71/CR at 2 MHz
|
|
: inc $1803; set all $1801 port pins to input
|
|
atnloop: bit $1800
|
|
bmi atnloop
|
|
stx $1800; clear ATNA_OUT
|
|
;lda #$ff
|
|
sta $1c05; timer 1 hi
|
|
ENABLE_WATCHDOG
|
|
: bit $1800
|
|
bpl :-
|
|
sty $1800; set ATNA_OUT
|
|
|
|
.assert (* - atnfallbck) <= 41, error, "atnfallbck too big"
|
|
|
|
atnlo: .byte "m-w", .lobyte($0400), .hibyte($0400), atnhi - (* + 1)
|
|
jmp ($fffc)
|
|
.byte 0
|
|
jmp ($1800); $0404, $04 = CLK_IN, jump to $0404 or $0484
|
|
waitactpr: ;ldy #$d0 ; JOBCODE_EXECUTE
|
|
sty $01 ; JOBCODE0400
|
|
ldy #$c0 ; timer 1 IRQs from VIA2
|
|
sty $1c0e
|
|
bne :+; jmp
|
|
; $0410, $10 = ATNA_OUT
|
|
; ATN_IN is clear, but ATNA_OUT is set: clear ATNA_OUT and reset timer
|
|
stx $1800; x = $04 = CLK_IN
|
|
sta $1c05; timer 1 hi
|
|
ENABLE_WATCHDOG
|
|
jmp ($1800); jump to $0404 or $0484
|
|
: ldy #1
|
|
sty $3f; JOBN, required on 1571 so code in the correct buffer ($0400) is executed upon interrupt
|
|
rts
|
|
|
|
.assert (* - atnlo) <= 41, error, "atnlo too big"
|
|
|
|
atnhi: .byte "m-w", .lobyte($0481), .hibyte($0481), atnhiend - (* + 1)
|
|
sei
|
|
bmi * - 21; jmp, atnloop
|
|
; $0484, $84 = ATN_IN | CLK_IN
|
|
; ATN_IN is set, but ATNA_OUT is cleared: set ATNA_OUT
|
|
sty $1800; y = $90 = ATN_IN | ATNA_OUT
|
|
sei
|
|
silncentry: jmp ($1800); jump to $0410 or $0490
|
|
.byte 0, 0, 0, 0, 0
|
|
jmp ($1800); $0490, $90 = ATN_IN | ATNA_OUT, jump to $0410 or $0490
|
|
atnhiend:
|
|
.assert (* - atnhi) <= 41, error, "atnhi too big"
|
|
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
drvslnc81: .byte "m-w", .lobyte($0300), .hibyte($0300), drvslnc81e - drvmute81
|
|
drvmute81: ;ldy #0
|
|
sty $4001
|
|
dey
|
|
sty $4007
|
|
lda #$19
|
|
slnc81loop: sta $400f
|
|
: bit $4001
|
|
slnc81sens: bpl slnc81loop; first, wait for a long period of ATN_IN set
|
|
ldx $4007
|
|
bne :-
|
|
ldx #OPC_BMI
|
|
cpx slnc81sens - drvmute81 + $0300
|
|
stx slnc81sens - drvmute81 + $0300
|
|
.if DISABLE_WATCHDOG
|
|
jmp slnc81loop
|
|
.else
|
|
bne slnc81loop
|
|
jmp ($fffc)
|
|
.endif
|
|
drvslnc81e:
|
|
.assert (* - drvslnc81) <= 41, error, "drvslnc81 too big"
|
|
|
|
drvslncfd: .byte "m-w", .lobyte($0300), .hibyte($0300), drvslncfde - drvmutefd
|
|
drvmutefd: ldx #0
|
|
stx $4001
|
|
dex
|
|
slncfdloop: stx $4005
|
|
: bit $4001
|
|
slncfdsens: bpl slncfdloop
|
|
lda $4005
|
|
bne :-
|
|
lda #OPC_BMI
|
|
cmp slncfdsens - drvmutefd + $0300
|
|
sta slncfdsens - drvmutefd + $0300
|
|
.if DISABLE_WATCHDOG
|
|
jmp slncfdloop
|
|
.else
|
|
bne slncfdloop
|
|
jmp ($fffc)
|
|
.endif
|
|
drvslncfde:
|
|
.assert (* - drvslncfd) <= 41, error, "drvslncfd too big"
|
|
|
|
drvslnchd: .byte "m-w", .lobyte($0300), .hibyte($0300), drvslnchde - drvmutehd
|
|
drvmutehd: ldx #0
|
|
stx $8000
|
|
dex
|
|
slnchdloop: stx $8005
|
|
: bit $8000
|
|
slnchdsens: bpl slnchdloop
|
|
lda $8005
|
|
bne :-
|
|
lda #OPC_BMI
|
|
cmp slnchdsens - drvmutehd + $0300
|
|
sta slnchdsens - drvmutehd + $0300
|
|
.if DISABLE_WATCHDOG
|
|
jmp slnchdloop
|
|
.else
|
|
bne slnchdloop
|
|
jmp ($fffc)
|
|
.endif
|
|
drvslnchde:
|
|
.assert (* - drvslnchd) <= 41, error, "drvslnchd too big"
|
|
|
|
dcodeselt0: .byte .lobyte(cbm1541::drvcodeend41 - cbm1541::drvcodebeg41 + cbm1541::drivecode41)
|
|
.byte .lobyte(cbm1571::drvcodeend71 - cbm1571::drvcodebeg71 + cbm1571::drivecode71)
|
|
.byte .lobyte(cbm1581::drvcodeend81 - cbm1581::drvcodebeg81 + cbm1581::drivecode81)
|
|
dcodeselt1: .byte .hibyte(cbm1541::drvcodeend41 - cbm1541::drvcodebeg41 + cbm1541::drivecode41)
|
|
.byte .hibyte(cbm1571::drvcodeend71 - cbm1571::drvcodebeg71 + cbm1571::drivecode71)
|
|
.byte .hibyte(cbm1581::drvcodeend81 - cbm1581::drvcodebeg81 + cbm1581::drivecode81)
|
|
dcodeselt2: .byte .lobyte(cbm1541::drvprgend41 - cbm1541::drvcodeend41 + cbm1541::TRAMPOLINEOFFSET)
|
|
.byte .lobyte(cbm1571::drvprgend71 - cbm1571::drvcodeend71 + cbm1571::TRAMPOLINEOFFSET)
|
|
.byte .lobyte(cbm1581::drvprgend81 - cbm1581::drvcodeend81)
|
|
dcodeselt3: .byte .lobyte(cbm1541::drivecode41)
|
|
.byte .lobyte(cbm1571::drivecode71)
|
|
.byte .lobyte(cbm1581::drivecode81)
|
|
dcodeselt4: .byte .hibyte(cbm1541::drivecode41)
|
|
.byte .hibyte(cbm1571::drivecode71)
|
|
.byte .hibyte(cbm1581::drivecode81)
|
|
dcodeselt5: .byte .hibyte(cbm1541::drvcodeend41 - cbm1541::TRAMPOLINEOFFSET)
|
|
.byte .hibyte(cbm1571::drvcodeend71 - cbm1571::TRAMPOLINEOFFSET)
|
|
.byte .hibyte(cbm1581::drvcodeend81)
|
|
dcodeselt6: .byte .lobyte(cbm1541::drvcodeend41 - cbm1541::TRAMPOLINEOFFSET)
|
|
.byte .lobyte(cbm1571::drvcodeend71 - cbm1571::TRAMPOLINEOFFSET)
|
|
.byte .lobyte(cbm1581::drvcodeend81)
|
|
dcodeselt7: .byte .hibyte(cbm1541::dinstall)
|
|
.byte .hibyte(cbm1571::dinstall)
|
|
.byte .hibyte(cbm1581::dinstall)
|
|
dcodeselt8: .byte .lobyte(cbm1541::dinstall)
|
|
.byte .lobyte(cbm1571::dinstall)
|
|
.byte .lobyte(cbm1581::dinstall)
|
|
dcodeselt9: .byte 41
|
|
.byte 71
|
|
.byte 81
|
|
dcodeselta: .byte DIRTRACK
|
|
.byte DIRTRACK
|
|
.byte DIRTRACK81
|
|
|
|
.endif; ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
; check if drive allows code upload and execution
|
|
chkdrvcode: lda #.lobyte($0300)
|
|
ldx #.hibyte($0300)
|
|
jsr memreadbyt
|
|
bcc :+
|
|
lda #$ff
|
|
rts
|
|
: eor #$ff
|
|
sta drvchkval + 1
|
|
jsr drvlistn
|
|
ldx #0
|
|
: lda drvchkme,x
|
|
jsr CIOUT
|
|
inx
|
|
cpx #drvchkmed - drvchkme
|
|
bne :-
|
|
jsr UNLSN
|
|
lda #.lobyte($0300)
|
|
ldx #.hibyte($0300)
|
|
jsr memreadbyt
|
|
drvchkval: cmp #0
|
|
rts
|
|
|
|
drvchkme: .byte "m-e", .lobyte($020a), .hibyte($020a), "krill"
|
|
lda #$ff
|
|
eor $0300
|
|
sta $0300
|
|
rts
|
|
drvchkmed:
|
|
.assert (* - drvchkme) <= 41, error, "drvchkme too big"
|
|
|
|
.if LOAD_VIA_KERNAL_FALLBACK
|
|
drvfaststp: .byte MINSTEPSPEED, $01, .hibyte($1c07), .lobyte($1c07), "w-m"; read backward
|
|
twosided: .byte "1m>0u"; read backward, enable 1571 mode to read two-sided disks
|
|
.endif; LOAD_VIA_KERNAL_FALLBACK
|
|
|
|
dcodesel5 = * + 1
|
|
dcodesel6 = * + 2
|
|
drvrutmw: .byte 35, 0, 0, "w-m"; read backward
|
|
droutrun: .byte "m-e", .lobyte($0209), .hibyte($0209), "krill"
|
|
dcodesel7 = * + 1
|
|
dcodesel8 = *
|
|
.byte $00, $00, .lobyte(REPOSITORY_VERSION), .hibyte(REPOSITORY_VERSION), PLATFORM
|
|
family: .byte 41
|
|
dirtrack: .byte DIRTRACK, FILENAME_MAXLENGTH, CONFIG_INTERNAL
|
|
droutruned:
|
|
|
|
messages:
|
|
.if ONLY_1541_AND_COMPATIBLE = 0
|
|
errormute: .byte PETSCII_LO_UP_CASE
|
|
.if PLATFORM = diskio::platform::COMMODORE_128
|
|
.byte PETSCII_BLINK
|
|
.endif
|
|
.if PLATFORM = diskio::platform::COMMODORE_16
|
|
.byte PETSCII_ORANGE
|
|
.else
|
|
.byte PETSCII_WHITE
|
|
.endif
|
|
.byte "ERROR: Failed to mute device #"
|
|
mutedevice: .byte "00.", 0
|
|
.endif; ONLY_1541_AND_COMPATIBLE = 0
|
|
|
|
warnemubug: .byte PETSCII_LO_UP_CASE
|
|
.if PLATFORM = diskio::platform::COMMODORE_128
|
|
.byte PETSCII_BLINK
|
|
.endif
|
|
.if PLATFORM = diskio::platform::COMMODORE_16
|
|
.byte PETSCII_ORANGE
|
|
.else
|
|
.byte PETSCII_WHITE
|
|
.endif
|
|
.byte "WARNING: Buggy "
|
|
.if PLATFORM = diskio::platform::COMMODORE_64
|
|
.byte "1541U firmware"
|
|
.else
|
|
.byte "emulator"
|
|
.endif
|
|
.byte " detected. Please update.", 0
|
|
|
|
version: .byte "Krill's Loader, revision ", REPOSITORY_VERSION_STRING, PETSCII_RETURN, "cfg "
|
|
itoa4 MIN_DEVICE_NO
|
|
itoa8 MAX_DEVICE_NO
|
|
itoa1 ONLY_1541_AND_COMPATIBLE
|
|
.byte '.'
|
|
itoa8 DIRTRACK
|
|
itoa8 DIRTRACK81
|
|
itoa8 FILENAME_MAXLENGTH
|
|
.byte '.'
|
|
itoa8 MINSTEPSPEED
|
|
itoa8 MAXSTEPSPEED
|
|
itoa4 STEPPERACC
|
|
itoa4 SINGLESTEPSPEED
|
|
.byte '.'
|
|
itoa4 (2 * LOAD_COMPD_API) + LOAD_RAW_API
|
|
itoa1 NTSC_COMPATIBILITY
|
|
itoa1 PREFER_SPEED_OVER_SIZE
|
|
itoa1 UNINSTALL_API
|
|
itoa1 FILE_EXISTS_API
|
|
itoa1 LOAD_UNDER_D000_DFFF
|
|
itoa1 ALLOW_2_MHZ_ON_C128
|
|
itoa4 (2 * MEM_DECOMP_TO_API) + MEM_DECOMP_API
|
|
itoa1 (2 * LOAD_TO_API) + END_ADDRESS_API
|
|
itoa1 LOAD_VIA_KERNAL_FALLBACK
|
|
itoa1 CLOSE_FILE_API
|
|
itoa8 CONFIG_INTERNAL
|
|
.byte '.'
|
|
itoa4 DECOMPRESSOR
|
|
.byte 0
|
|
|
|
CHECK_INSTALL_END_ADDRESS
|
|
|
|
.exportzp status_OK = diskio::status::OK
|
|
.exportzp status_DEVICE_INCOMPATIBLE = diskio::status::DEVICE_INCOMPATIBLE
|
|
.exportzp status_TOO_MANY_DEVICES = diskio::status::TOO_MANY_DEVICES
|
|
.exportzp status_GENERIC_KERNAL_ERROR = diskio::status::GENERIC_KERNAL_ERROR
|
|
.exportzp status_DEVICE_NOT_PRESENT = diskio::status::DEVICE_NOT_PRESENT
|
|
.exportzp status_FILE_NOT_FOUND = diskio::status::FILE_NOT_FOUND
|
|
|
|
.if PLATFORM <> diskio::platform::COMMODORE_16
|
|
.exportzp config_ALLOW_2_MHZ_ON_C128 = ALLOW_2_MHZ_ON_C128
|
|
.endif
|
|
.exportzp config_DECOMPRESSOR = DECOMPRESSOR
|
|
.exportzp config_DIRTRACK = DIRTRACK
|
|
.exportzp config_DIRTRACK81 = DIRTRACK81
|
|
.exportzp config_END_ADDRESS_API = END_ADDRESS_API
|
|
.exportzp config_FILENAME_MAXLENGTH = FILENAME_MAXLENGTH
|
|
.exportzp config_FILE_EXISTS_API = FILE_EXISTS_API
|
|
.exportzp config_INTERNAL = CONFIG_INTERNAL
|
|
.exportzp config_LOAD_COMPD_API = LOAD_COMPD_API
|
|
.exportzp config_LOAD_RAW_API = LOAD_RAW_API
|
|
.exportzp config_LOAD_TO_API = LOAD_TO_API
|
|
.exportzp config_LOAD_UNDER_D000_DFFF = LOAD_UNDER_D000_DFFF
|
|
.exportzp config_LOAD_VIA_KERNAL_FALLBACK = LOAD_VIA_KERNAL_FALLBACK
|
|
.exportzp config_MEM_DECOMP_API = MEM_DECOMP_API
|
|
.exportzp config_MEM_DECOMP_TO_API = MEM_DECOMP_TO_API
|
|
.exportzp config_NTSC_COMPATIBILITY = NTSC_COMPATIBILITY
|
|
.exportzp config_ONLY_1541_AND_COMPATIBLE = ONLY_1541_AND_COMPATIBLE
|
|
.exportzp config_PREFER_SPEED_OVER_SIZE = PREFER_SPEED_OVER_SIZE
|
|
.exportzp config_UNINSTALL_API = UNINSTALL_API
|