refactor RAM disk and hard disk support

This commit is contained in:
4am 2021-04-18 00:12:05 -04:00
parent 4aa11ebfcb
commit b3a75e8748
13 changed files with 767 additions and 644 deletions

View File

@ -34,6 +34,7 @@ asm:
grep "SaveProDOS=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 > build/vars.a
grep "kForceLower=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a
grep "DiskIIArray=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a
grep "HardDiskArray=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a
grep "PrintByID=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a
grep "WaitForKey=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a
grep "CleanExit=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a
@ -43,6 +44,7 @@ asm:
grep "filetype=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a
grep "access=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a
grep "VolumeName=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a
grep "RAMDiskImagePath=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a
grep "auxtype=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a
grep "blocks=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a
grep "PREFSVER=" build/vars.log | cut -d":" -f3 | cut -d"(" -f1 >> build/vars.a

View File

@ -37,19 +37,14 @@
!fill 10 ; array of ten bytes for use as
; substitution strings
;gHardDiskRef
!byte 00 ; handle of hard disk file
!byte 00 ; ProDOS file reference number of target file on hard disk
; non-zero if open
;gUsingHardDisk
!byte FALSE ; 0=true, 1=false
;gHardDiskExists
; !byte FALSE ; 0=true, 1=false
;gRAMDiskRef
!byte 00 ; handle of RAM disk
!byte 00 ; ProDOS file reference number of temporary file on RAM disk
; non-zero if open
;gUsingRAMDisk
!byte FALSE ; 0=true, 1=false
;gTargetType
!byte FALSE ; target type (disk drive, CFFA virtual drive, file on hard disk)
; see apidefs.a for values
;gOnAClearDayYouCanReadForever
!byte FALSE ; 0=true, 1=false

View File

@ -22,6 +22,14 @@ ID_MECC3 = $03
ID_MECC4 = $04
ID_MECC_UNK = $FF
;-------------------------------
;target types (for gTargetType)
;-------------------------------
ID_DISK_II = %00000000 ; BIT + BPL + BVC -> target is Disk II drive
ID_CFFA_VIRTUAL_DISK = %01000000 ; BIT + BPL + BVS -> target is a CFFA3000-managed virtual disk drive
ID_FILE_ON_HARD_DISK = %10000000 ; BIT + BMI -> target is a file on a hard disk
; Zero-page addresses we use for variables
nibsrcindex = $EC ; byte
nibdestindex = $ED ; byte
@ -116,10 +124,9 @@ gIs13Sector = gIsInfocom18-$01 ; byte
gMECCFastloadType = gIs13Sector-$01 ; byte
gOnAClearDayYouCanReadForever = gMECCFastloadType-$01 ; byte
gUsingRAMDisk = gOnAClearDayYouCanReadForever-$01 ; byte
gRAMDiskRef = gUsingRAMDisk-$01 ; byte
gUsingHardDisk = gRAMDiskRef-1 ; byte
gHardDiskRef = gUsingHardDisk-$01 ; byte
gTargetType = gOnAClearDayYouCanReadForever-$01 ; byte
gRAMDiskRef = gTargetType-$01 ; byte
gHardDiskRef = gRAMDiskRef-$01 ; byte
gDisplayBytes = gHardDiskRef-$0A ; 10 bytes
jcompare = gDisplayBytes-$03 ; 3-byte
jmodify = jcompare-$03 ; 3-byte
@ -193,9 +200,8 @@ ConstructStandardDelivery = jConstructStandardDelivery
!warn "gIsInfocom18=",gIsInfocom18
!warn "gIs13Sector=",gIs13Sector
!warn "gOnAClearDayYouCanReadForever=",gOnAClearDayYouCanReadForever
!warn "gUsingRAMDisk=",gUsingRAMDisk
!warn "gTargetType=",gTargetType
!warn "gRAMDiskRef=",gRAMDiskRef
!warn "gUsingHardDisk=",gUsingHardDisk
!warn "gHardDiskRef=",gHardDiskRef
!warn "gDisplayBytes=",gDisplayBytes
!warn "jcompare=",jcompare

145
src/harddisk.a Normal file
View File

@ -0,0 +1,145 @@
HardDirName !raw "PASSPORT"
HardDirName_e
HardDiskName !raw "/IMG0000.DSK"
HardDiskName_e
HardDiskImagePath
!byte 0 ; length byte
!fill 1 ; / character
!fill 15 ; longest possible volume name
!fill 1 ; / character
!fill HardDirName_e-HardDirName ; directory name (constant, see above)
!fill HardDiskName_e-HardDiskName ; filename with leading slash
; (modified at runtime but always the same length)
;-------------------------------
; CreateFileOnHardDisk
; create a new autonumbered image file on the user's selected target,
; which should be a hard disk
;
; in: HardDiskArray populated
; user's select target is a hard disk
; ProDOS is in memory
; out: if C set, create or open failed (A contains MLI error code)
; if C clear, everything succeeded (A is clobbered)
; all other registers and flags clobbered
;-------------------------------
CreateFileOnHardDisk
jsr LookupUnitNumberOfSelectedHardDisk
jsr GetVolumeName
lda OnlineReturn
and #$0F ; A=volume name length
tay
clc
adc #(HardDirName_e-HardDirName)+2
sta HardDiskImagePath
tax
lda #$2F
sta HardDiskImagePath+1
sta HardDiskImagePath+2, y
- lda OnlineReturn, y
sta HardDiskImagePath+1, y
dey
bne -
ldy #(HardDirName_e-HardDirName)
- lda HardDirName-1, y
sta HardDiskImagePath, x
dex
dey
bne -
; @HardDiskImagePath = fully qualified pathname of target volume +
; our hardcoded directory
lda #<HardDiskImagePath
sta mliparam+1
lda #>HardDiskImagePath
sta mliparam+2
jsr CreateDir ; create hardcoded directory
; (don't care if this fails)
lda HardDiskImagePath
clc
adc #(HardDiskName_e-HardDiskName)
sta HardDiskImagePath
tax
ldy #(HardDiskName_e-HardDiskName)
- lda HardDiskName-1, y
sta HardDiskImagePath, x
dex
dey
bne -
; @HardDiskImagePath = fully qualified pathname of target volume +
; our hardcoded directory + our default filename
; This file might already exist, in which case we will repeatedly
; construct sequentially numbered filenames until we find one that
; doesn't exist.
@findSpare
jsr GetFileInfo
bcs @tryCreate ; branch if file does not exist (good)
; construct next filename
; (filename starts as IMG0000.DSK so we ignore the last 4 characters
; and increment the digits as base 10)
ldx HardDiskImagePath
@nextDigit
inc HardDiskImagePath-4, x
lda HardDiskImagePath-4, x
cmp #'9'+1
bcc @findSpare ; loop back to check if new filename exists
lda #'0'
sta HardDiskImagePath-4, x
dex
bne @nextDigit
@tryCreate
; @mliparam+1 still points to @HardDiskImagePath, which now contains
; the full pathname of the file we want to create
jsr Create140KFile
bcs +
sta gHardDiskRef
+ rts
;-------------------------------
; CloseFileOnHardDisk
; close the previously open file on a hard disk, if any
;
; always safe to call (gracefully returns if no file is open)
; does not return any error status because no one cares
;
; in: ProDOS is in memory
; out: ProDOS is in memory
; all registers and flags clobbered
;-------------------------------
CloseFileOnHardDisk
lda gHardDiskRef
beq +
jsr CloseFile
lda #0
sta gHardDiskRef
+ rts
;-------------------------------
; PrintHardDiskImagePath
; print full path of file on hard disk
;
; in: @HardDiskImagePath must be populated and have non-zero length
; out: all registers and flags clobbered
;-------------------------------
PrintHardDiskImagePath
lda HardDiskImagePath
sta @volumelen
ldx #0
- lda HardDiskImagePath+1, x
ora #$80
jsr PrintA
inx
@volumelen=*+1
cpx #$FD ; SMC
bcc -
lda #$8D
jmp PrintA

View File

@ -1,54 +1,65 @@
SlashRAM !raw "/RAM"
SlashRAM_e
RAMFileName !raw "PASSPORTTMP.DSK"
RAMFileName_e
;-------------------------------
; ScanForDiskII
; scan all slots for things that
; look like Disk II cards
; scan all slots for things that look like Disk II cards
;
; out: all registers clobbered
; all flags clobbered
; DiskIIArray filled with 00 or FF
; in: none
; out: DiskIIArray populated
; all registers and flags clobbered
;-------------------------------
!zone {
ScanForDiskII
lda #$00
sta cmp1
ldx #$07
.fingerprint
txa
- txa
ora #$C0
sta cmp1+1
ldy #$01
lda (cmp1),y
lda (cmp1), y
cmp #$20
bne .next
bne +
ldy #$03
lda (cmp1),y
bne .next
lda (cmp1), y
bne +
ldy #$05
lda (cmp1),y
lda (cmp1), y
cmp #$03
bne .next
bne +
ldy #$FF
lda (cmp1),y
bne .next
lda (cmp1), y
bne +
tya
sta DiskIIArray-1,x
.next
dex
bne .fingerprint
sta DiskIIArray-1, x
+ dex
bne -
rts
}
!zone {
;-------------------------------
; ScanForRAMAndHardDisks
; scan all slots for things that look like RAM disks or hard drives
;
; in: none
; out: HardDriveArray populated
; RAMDiskImagePath possibly populated (if a suitable RAM disk was found)
; all registers and flags clobbered
;-------------------------------
ScanForRAMAndHardDisks
lda #$00
sta iunit
- lda iunit
@nextunit
lda iunit
clc
adc #$10
sta iunit
beq .done
cmp #$80
beq -
bne +
rts
+ cmp #$80
beq @nextunit
pha
and #$70
lsr
@ -57,60 +68,52 @@ ScanForRAMAndHardDisks
lsr
tay
pla
ldx DiskIIArray-1,y
bne - ; ScanForDiskII already detected that this slot is a floppy drive, so skip it
ldx DiskIIArray-1, y
bne @nextunit ; ScanForDiskII already detected that this slot is a floppy drive, so skip it
jsr GetVolumeName
bcs - ; can't get a volume name, so skip it
bcs @nextunit ; can't get a volume name, so skip it
lda OnlineReturn
and #$0F
beq - ; volume name length=0 means an error occurred, so skip it
beq @nextunit ; volume name length=0 means an error occurred, so skip it
jsr GetVolumeInfo
lda filetype
and #$0F
cmp #$0F
bne - ; ProDOS volume type says this isn't a directory, so skip it
bne @nextunit ; ProDOS volume type says this isn't a directory, so skip it
lda access
and #$02
beq - ; volume is not writeable, so skip it
beq @nextunit ; volume is not writeable, so skip it
;check free space
;need at least $118 blocks
sec
; check free space on volume (need at least $118 blocks)
lda auxtype
sec
sbc blocks
tax
lda auxtype+1
sbc blocks+1
cmp #1
bcc - ; not enough free space, so skip it
bcc @nextunit ; not enough free space, so skip it
bne +
cpx #$18
bcc - ; not enough free space, so skip it
+ ldx #TRUE
;check for RAM[x] by name
ldy OnlineReturn
cpy #4
beq +
cpy #5
bne ++
dey
bcc @nextunit ; not enough free space, so skip it
+
-- lda SlashRAM-1,y
cmp VolumeName-1,y
bne ++
dey
bne --
; check if this volume is a RAM disk
; if so, we will use it as temporary storage when writing to a disk in a disk drive
; (writing to a file on the RAM disk, then writing that to the target disk all at once)
jsr .IsRAMDisk
bne @foundHardDrive
stx gUsingRAMDisk
beq - ;continue search, always taken
lda RAMDiskImagePath
bne @nextunit ; we already found a suitable RAM disk, so skip this one
.done
rts
; now that we've found the first suitable RAM disk, construct
; the full path of the RAM disk image file and store it in
; RAMDiskImagePath
jsr .ConstructRAMDiskImagePath
beq @nextunit ; always branches
++ lda iunit
@foundHardDrive
lda iunit
pha
lsr
lsr
@ -118,12 +121,58 @@ ScanForRAMAndHardDisks
lsr
tay
pla
sta DiskIIArray+7-1,y ;;HardDiskArray-1,y
; stx gHardDiskExists
bne - ;continue search, always taken
sta HardDiskArray-1, y
bne @nextunit ; always branches
SlashRAM !byte $2F, $52, $41, $4D
}
.IsRAMDisk
; in: @OnlineReturn+@VolumeName contains length+name of a ProDOS volume
; out: Z=1 if volume is a suitable RAM disk
; Z=0 otherwise
; all other registers and flags clobbered
lda OnlineReturn
and #$0F
cmp #4
beq +
cmp #5
bne @exit ; volume name isn't the right length for a supported RAM disk
+
; due to limitations of the ProDOS API, we settle for checking if the volume name =
; 'RAM' or 'RAMn' where n is a slot number, which covers the common cases ('RAM3' for
; third-party memory cards, 'RAM5' on a IIgs)
ldy #(SlashRAM_e-SlashRAM)
- lda SlashRAM-1, y
cmp VolumeName-1, y
bne @exit ; volume name does not match 'RAM' or 'RAMn' pattern
dey
bne -
@exit rts
.ConstructRAMDiskImagePath
; in: @OnlineReturn+@VolumeName contains length+name of RAM disk
; out: Z=1
; Y=0
; all other registers and flags clobbered
lda OnlineReturn
and #$0F
tay
clc
adc #(RAMFileName_e-RAMFileName)+1
sta RAMDiskImagePath
tax
lda #$2F
sta RAMDiskImagePath+1, y
- lda OnlineReturn, y
sta RAMDiskImagePath, y
dey
bne -
ldy #(RAMFileName_e-RAMFileName)
- lda RAMFileName-1, y
sta RAMDiskImagePath, x
dex
dey
bne -
rts
;-------------------------------
; LoadPrefs
@ -140,11 +189,9 @@ LoadPrefs
!word PREFSREADLEN
!word PREFSBUFFER
jsr ValidatePrefs
bcc .goodprefs
bcc +
jmp SavePrefs
.goodprefs
rts
+ rts
;-------------------------------
; LoadFile1Shot
@ -164,7 +211,6 @@ LoadPrefs
; all registers clobbered
; stack set to next instruction after parameters
;-------------------------------
!zone {
LoadFile1Shot
clc
pla
@ -179,33 +225,33 @@ LoadFile1Shot
pha
ldy #$01
lda ($00),y ; lo byte of pathname
lda ($00), y ; lo byte of pathname
sta mliparam+1
iny
lda ($00),y ; hi byte of pathname
lda ($00), y ; hi byte of pathname
sta mliparam+2
ldy #$07
lda ($00),y ; lo byte of ProDOS file buffer
lda ($00), y ; lo byte of ProDOS file buffer
sta mliparam+3
iny
lda ($00),y ; hi byte of ProDOS file buffer
lda ($00), y ; hi byte of ProDOS file buffer
sta mliparam+4
jsr OpenFile
bcs .loadfile1s ; C set on error
bcs @exit ; C set on error
pha ; push file reference number
ldy #$03
lda ($00),y ; lo address of data buffer
lda ($00), y ; lo address of data buffer
sta mliparam+2
iny
lda ($00),y ; hi address of data buffer
lda ($00), y ; hi address of data buffer
sta mliparam+3
iny
lda ($00),y ; lo data length
lda ($00), y ; lo data length
sta mliparam+4
iny
lda ($00),y ; hi data length
lda ($00), y ; hi data length
sta mliparam+5
pla ; pull file reference number
jsr ReadFile
@ -216,6 +262,4 @@ LoadFile1Shot
plp ; restore flags from readfile
; (so caller gets codes from read attempt,
; not close)
.loadfile1s
rts
}
@exit rts

613
src/mli.a
View File

@ -26,17 +26,11 @@ PC_CLOSE = $01
PC_SETMARK = $02
PC_SETEOF = $02
; MLI addresses
PRODOSMLI = $BF00 ; [callable] MLI entry point
;!ct "lcase.ct"
RAMFileName !raw "PASSPORTTMP.DSK"
RAMFileName_e
HardDirName !raw "PASSPORT"
HardDirName_e
HardDiskName !raw "/IMG0000.DSK"
HardDiskName_e
; MLI constants
FULL_ACCESS = $C3
; MLI error codes
ERR_FNF = $46
@ -44,33 +38,37 @@ ERR_EOF = $4C
ERR_EXIST = $47
;-------------------------------
; WriteTrackMLI - write the contents of
; BASEPAGE data buffer to disk
; in: @SLOT contains (slot x 16) + $30
; @DRIVE contains drive + $30
; @gTrack contains track number
; @BASEPAGE contains data to write ($1000 bytes)
; out: if C set, write failed (A contains MLI error code)
; if C clear, write succeeded (A is clobbered)
; all other flags clobbered
; all registers clobbered
; WriteTrackFirstPass
;
; write the contents of BASEPAGE data buffer to the selected target
; (or possibly an intermediate target, such as a RAM disk)
;
; in: @SLOT contains (slot x 16) + $30
; @DRIVE contains drive + $30
; @gTrack contains track number
; @BASEPAGE contains data to write ($1000 bytes)
; ProDOS is in memory
; out: if C set, write failed (A contains MLI error code)
; if C clear, write succeeded (A is clobbered)
; all other registers and flags clobbered
; ProDOS is in memory
;-------------------------------
!zone {
WriteTrackMLI
jsr SwapProDOS
lda gUsingHardDisk
and gUsingRAMDisk
beq +
WriteTrackFirstPass
lda gHardDiskRef
ora gRAMDiskRef
bne +
; we're writing directly to a disk drive, so we
; reorder the data buffer so we can write the
; logical sectors as ProDOS blocks
jsr ReorderBuffer
+
; ProDOS 'unit number' is DSSS0000, where
; D is the drive number (0=drive 1, 1=drive 2) and
; SSS is the slot number (1-7)
; c.f. 'Beneath Apple ProDOS' page 6-19
;
lda DRIVE ; drive number is stored as ASCII text
; ProDOS 'unit number' is DSSS0000, where
; D is the drive number (0=drive 1, 1=drive 2) and
; SSS is the slot number (1-7)
; c.f. 'Beneath Apple ProDOS' page 6-19
lda DRIVE
sec
sbc #$31
sbc #$31 ; drive number is stored as ASCII text
lsr
lda #0
ror
@ -81,76 +79,101 @@ WriteTrackMLI
asl
asl
ora mliparam+1
sta mliparam+1 ; ProDOS unit number
sta mliparam+1 ; ProDOS unit number
lda #$00
sta mliparam+2 ; lo byte of data buffer
sta mliparam+2 ; lo byte of data buffer
lda #$08
sta .blockcount
sta @blockcount ; 8 blocks = 16 sectors
lda gTrack
asl
asl
asl
sta mliparam+4 ; lo byte of block number
sta mliparam+4 ; lo byte of block number
rol
and #$01
sta mliparam+5 ; hi byte of block number
lda #BASEPAGE ; hi byte of data buffer
sta mliparam+5 ; hi byte of block number
lda #BASEPAGE ; hi byte of data buffer
sta mliparam+3
.writeloop
lda gUsingHardDisk
and gUsingRAMDisk
beq +
lda #$81 ; 'write block' command
ldy #$03 ; parameter count
@writeloop
lda gHardDiskRef
ora gRAMDiskRef
bne +
lda #$81 ; 'write block' command
ldy #$03 ; parameter count
jsr mli
bcs .writeerr
- inc mliparam+3 ; 2 pages per block
bcs @writeerr
- inc mliparam+3 ; 2 pages per block
inc mliparam+3
inc mliparam+4
dec .blockcount
bne .writeloop
dec @blockcount
bne @writeloop
clc
bcc .writedone
bcc @writedone ; always branches
+ jsr WriteToFile
bcc -
.writeerr
.writedone
@writeerr
@writedone
php
pha
lda gUsingHardDisk
and gUsingRAMDisk
beq +
lda gHardDiskRef
ora gRAMDiskRef
bne +
jsr ReorderBuffer
+ jsr SwapProDOS
pla
+ pla
plp
rts
.blockcount !byte $FF
}
@blockcount !byte $FF
;-------------------------------
; WriteTrackSecondPass
;
; write the contents of BASEPAGE data buffer
; from a file on a RAM disk
; to the final destination drive
;
; in: gRAMDiskRef contains file reference number of open file on RAM disk
; ProDOS is in memory
; out: if C set, write failed (A contains MLI error code)
; if C clear, write succeeded (A is clobbered)
; all other registers and flags clobbered
; ProDOS is in memory
;-------------------------------
WriteTrackSecondPass
lda gRAMDiskRef
pha
lda #0
sta gRAMDiskRef
jsr WriteTrackFirstPass
tax
pla
sta gRAMDiskRef
txa
rts
;-------------------------------
; SaveFile1Shot
; save a file to disk all at once,
; using ProDOS MLI calls
;
; in: stack contains 11 ($0B) bytes of parameters:
; +1 address of pathname
; +3 [byte] file type
; +4 [word] aux file type
; +6 address of data buffer
; +8 [word] length of data buffer
; +A address of ProDOS file buffer
; out: if C set, save failed and A contains error code
; from open or write
; if C clear, save succeeded
; all other flags clobbered
; all registers clobbered
; stack set to next instruction after parameters
; in: ProDOS is in memory
; stack contains 11 ($0B) bytes of parameters:
; +1 address of pathname
; +3 [byte] file type
; +4 [word] aux file type
; +6 address of data buffer
; +8 [word] length of data buffer
; +A address of ProDOS file buffer
; out: ProDOS is in memory
; if C set, save failed and A contains error code
; from open or write
; if C clear, save succeeded
; all other flags clobbered
; all registers clobbered
; stack set to next instruction after parameters
;-------------------------------
!zone {
SaveFile1Shot
clc
pla
@ -181,7 +204,7 @@ SaveFile1Shot
lda ($00),y ; hi byte of aux file type
sta mliparam+6
jsr CreateFile
bcs .savefile1s
bcs +
ldy #$0A
lda ($00),y ; lo byte of ProDOS file buffer
@ -190,7 +213,7 @@ SaveFile1Shot
lda ($00),y ; hi byte of ProDOS file buffer
sta mliparam+4
jsr OpenFile
bcs .savefile1s
bcs +
pha ; push file reference number
ldy #$06
@ -215,32 +238,29 @@ SaveFile1Shot
; (so caller gets codes from write attempt,
; not close)
.savefile1s
rts
}
+ rts
;-------------------------------
; open file via ProDOS MLI
;
; in: caller has filled @mliparam with address of
; pathname, address of data buffer, and maximum
; data length
; out: if C set, open failed and A contains error code
; if C clear, open succeeded and A contains
; file reference number
; in: ProDOS is in memory
; caller has filled @mliparam with address of
; pathname, address of data buffer, and maximum
; data length
; out: if C set, open failed and A contains error code
; if C clear, open succeeded and A contains
; file reference number
; ProDOS is in memory
;-------------------------------
!zone {
OpenFile
lda #CMD_OPEN ; MLI command
ldy #PC_OPEN ; number of parameters for 'open' command
jsr mli
bcs .openfile
bcs +
lda refnum ; caller should save file reference number
; as this memory location may be
; overwritten by later MLI calls
.openfile
rts
}
+ rts
;-------------------------------
; read an open file via ProDOS MLI
@ -252,17 +272,14 @@ OpenFile
; if C clear, read succeeded and A contains the same
; file reference number that was passed in
;-------------------------------
!zone {
ReadFile
sta mliparam+1 ; store file reference number
lda #CMD_READ ; MLI read command
ldy #PC_READ ; number of parameters for 'read' command
jsr mli
bcs .readfile
bcs +
lda mliparam+1 ; if no error, return file reference number
.readfile
rts
}
+ rts
;-------------------------------
; change file position in an open file via ProDOS MLI
@ -274,16 +291,14 @@ ReadFile
; if C clear, set_mark call succeeded and A contains
; the same file reference number that was passed in
;-------------------------------
!zone {
SetMark
sta mliparam+1 ; store file reference number
lda #CMD_SETMARK ; MLI set_mark command
ldy #PC_SETMARK ; number of params for 'set_mark' cmd
jsr mli
bcs .exit
bcs +
lda mliparam+1 ; if no error, return file refnum
.exit rts
}
+ rts
;-------------------------------
; write to an open file via ProDOS MLI
@ -295,17 +310,14 @@ SetMark
; if C clear, write succeeded and A contains the same
; file reference number that was passed in
;-------------------------------
!zone {
WriteFile
sta mliparam+1 ; store file reference number
lda #CMD_WRITE ; MLI write command
ldy #PC_WRITE ; number of parameters for 'write' command
jsr mli
bcs .writefile
bcs +
lda mliparam+1 ; if no error, return file reference number
.writefile
rts
}
+ rts
;-------------------------------
; set file size in an open file via ProDOS MLI
@ -317,71 +329,108 @@ WriteFile
; if C clear, set_eof call succeeded and A contains
; the same file reference number that was passed in
;-------------------------------
!zone {
SetEOF
sta mliparam+1 ; store file reference number
lda #CMD_SETEOF ; MLI set_eof command
ldy #PC_SETEOF ; number of params for 'set_eof' cmd
jsr mli
bcs .exit
bcs +
lda mliparam+1 ; if no error, return file refnum
.exit rts
}
+ rts
;-------------------------------
; close an open file
; in: A = file reference number
; out: if error, C set and A contains error code
; if success, C clear
; in: ProDOS is in memory
; A = file reference number
; out: if error, C set and A contains error code
; if success, C clear
; ProDOS is in memory
;-------------------------------
CloseFile
sta mliparam+1 ; store file reference number
lda #CMD_CLOSE ; MLI close command
ldy #PC_CLOSE ; number of parameters for 'close' command
jsr mli
rts
sta mliparam+1 ; store file reference number
lda #CMD_CLOSE ; MLI close command
ldy #PC_CLOSE ; number of parameters for 'close' command
jmp mli
;-------------------------------
; Create140KFile
;
; in: @mliparam+1 points to pathname
; out: C clear if file create+open succeeded, and A = file reference number
; C set on error, and A = MLI error code
;-------------------------------
Create140KFile
jsr CreateFile
bcs @exit
lda #$00
sta mliparam+3 ; io_buffer at address $0800
lda #$08
sta mliparam+4
jsr OpenFile
bcs @deleteAndReturn
ldx #$00
stx mliparam+2
ldx #$30
stx mliparam+3
ldx #$02
stx mliparam+4 ; set file size (140KB)
jsr SetEOF
bcc @exit
pha
jsr CloseFile
pla
@deleteAndReturn
pha ; save error code
jsr DeleteFile ; delete file
pla ; restore error code
sec
@exit rts
;-------------------------------
; CreateDir/CreateFile
;
; create a directory or file via ProDOS MLI
; always sets access bits to $C3 (full access)
; always sets creation to 0 (current date/time)
; always sets storage type to $0D (directory) or 1 (file)
; in: caller has filled @mliparam
; with address of pathname,
; file type, aux file type
; out: if error, C set and A contains error code
; if success, C clear
; always sets file type to $0F (directory) or 6 (BIN file)
; in: caller has filled @mliparam+1 with address of pathname
; out: if error, C set and A contains error code
; if success, C clear and A clobbered
;-------------------------------
accessbits = $C3 ; full access
CreateDir
lda #$0D
ldy #$0F
bne .createFile
bne +
CreateFile
lda #1
ldy #6
.createFile
sta mliparam+7 ; storage type (directory or file)
sty mliparam+4 ; file type (directory or binary)
lda #accessbits
sta mliparam+3 ; access bits (full access)
+ sta mliparam+7 ; storage type (directory or file)
sty mliparam+4 ; file type (directory or binary)
lda #FULL_ACCESS
sta mliparam+3 ; access bits (full access)
lda #0
sta mliparam+8 ; creation date (current)
sta mliparam+8 ; creation date (current)
sta mliparam+9
sta mliparam+10 ; creation time (current)
sta mliparam+10 ; creation time (current)
sta mliparam+11
lda #CMD_CREATE ; MLI create command
ldy #PC_CREATE ; number of parameters for 'create' command
lda #CMD_CREATE ; MLI create command
ldy #PC_CREATE ; number of parameters for 'create' command
jsr mli
rts
;-------------------------------
; DeleteFile
; delete a file using ProDOS MLI
; in: caller has filled @mliparam
; with address of pathname
; out: if error, C set and A contains error code
; if success, C clear
;
; in: ProDOS is in memory
; caller has filled @mliparam+1 with address of pathname
; out: if error, C set and A contains error code
; if success, C clear
; ProDOS is in memory
;-------------------------------
DeleteFile
lda #CMD_DESTROY ; MLI destroy command
@ -389,187 +438,6 @@ DeleteFile
jsr mli
rts
;-------------------------------
; CreateRAMOrHardFile - create image file on RAM or hard disk
; if RAM or hard disk is in use
; in: nothing (assumes that prefix is set already)
; out: if C set, write failed (A contains MLI error code)
; if C clear, write succeeded (A is clobbered)
; all other flags clobbered
; all registers clobbered
;-------------------------------
!zone {
CreateRAMOrHardFile
lda gUsingHardDisk
lsr ; TRUE/FALSE in C instead of Z
bcc .createHardFile
lda gUsingRAMDisk
beq .createRAMFile
.gotRAM
rts
.createRAMFile
;existing file being reused?
lda gRAMDiskRef
bne .gotRAM
;no, create a new one
.createHardFile
php
jsr SwapProDOS
lda OnlineReturn
and #$0F
tay
plp
php
bcs .prefRAM
clc
adc #(HardDirName_e-HardDirName)+2
sta DiskImgPath
tax
lda #$2F
sta DiskImgPath+1
sta DiskImgPath+2,y
- lda OnlineReturn,y
sta DiskImgPath+1,y
dey
bne -
ldy #(HardDirName_e-HardDirName)
- lda HardDirName-1,y
sta DiskImgPath,x
dex
dey
bne -
lda #<DiskImgPath
sta mliparam+1
lda #>DiskImgPath
sta mliparam+2
jsr CreateDir
clc
lda DiskImgPath
adc #(HardDiskName_e-HardDiskName)
sta DiskImgPath
tax
ldy #(HardDiskName_e-HardDiskName)
- lda HardDiskName-1,y
sta DiskImgPath,x
dex
dey
bne -
.findSpare
jsr GetFileInfo
bcs .foundSpare
ldx DiskImgPath
.nextDigit
inc DiskImgPath-4,x
lda DiskImgPath-4,x
cmp #'9'+1
bcc .findSpare
lda #'0'
sta DiskImgPath-4,x
dex
bne .nextDigit
.prefRAM
clc
adc #(RAMFileName_e-RAMFileName)+1
sta DiskImgPath
tax
lda #$2F
sta DiskImgPath+1,y
- lda OnlineReturn,y
sta DiskImgPath,y
dey
bne -
ldy #(RAMFileName_e-RAMFileName)
- lda RAMFileName-1,y
sta DiskImgPath,x
dex
dey
bne -
jsr DeleteRAMFile
.foundSpare
jsr CreateFile
bcs .createfail
lda #0
sta mliparam+3
lda #8
sta mliparam+4
jsr OpenFile
bcs .openfail
plp
php
bcc .storeHardRef
sta gRAMDiskRef
bcs .setSize
.storeHardRef
sta gHardDiskRef
.setSize
;140kb
ldx #0
stx mliparam+2
ldx #$30
stx mliparam+3
ldx #2
stx mliparam+4
jsr SetEOF
lda #0
rol
;update file buffer array
plp
jsr SaveProDOS
beq .restore
php
lda gRAMDiskRef
bcs .closeRef
lda gHardDiskRef
ldx #0
stx gHardDiskRef
.closeRef
jsr CloseFile
.openfail
plp
php
pha
jsr DeleteFile
pla
.createfail
plp
bcs .failRAM
jsr SwapProDOS
jmp FatalWriteError
.failRAM
ldx #FALSE
stx gUsingRAMDisk
.restore
jmp SwapProDOS
DiskImgPath
!byte $d1
!fill 17
!fill HardDirName_e-HardDirName
!fill HardDiskName_e-HardDiskName
}
;-------------------------------
; WriteToFile - write memory to image file on RAM or hard disk
; if RAM or hard disk is in use
@ -580,7 +448,6 @@ DiskImgPath
; all other flags clobbered
; all registers clobbered
;-------------------------------
!zone {
WriteToFile
lda mliparam+2
pha
@ -588,11 +455,11 @@ WriteToFile
pha
lda mliparam+4
sta .tmpparm4
sta @tmpparm4
asl
sta mliparam+3
lda mliparam+5
sta .tmpparm5
sta @tmpparm5
rol
sta mliparam+4
lda #0
@ -607,7 +474,7 @@ WriteToFile
pla
sta mliparam+2
txa
bcs .done
bcs @done
lda #0
sta mliparam+4
lda #2
@ -617,100 +484,15 @@ WriteToFile
lda gRAMDiskRef
+ jsr WriteFile
.done
ldx .tmpparm4
@done
ldx @tmpparm4
stx mliparam+4
ldx .tmpparm5
ldx @tmpparm5
stx mliparam+5
rts
.tmpparm4 !byte 0
.tmpparm5 !byte 0
}
;-------------------------------
; WriteRAMToDisk - write image file in RAM to physical disk
; if RAM disk is in use
; in: nothing
; out: if error, C set and A contains error code
; if success, C clear
; all other flags clobbered
; all registers clobbered
;-------------------------------
!zone {
WriteRAMToDisk
lda #0
sta mliparam+2
sta mliparam+3
sta mliparam+4
sta gTrack
jsr SwapProDOS
lda gRAMDiskRef
jsr SetMark
jsr SwapProDOS
jsr RestartProgress ; restart progress bar
lda #FALSE
sta gUsingRAMDisk ; prevent track write from calling RAM again
- lda #0
sta mliparam+2
sta mliparam+4
lda #$10
sta mliparam+3
sta mliparam+5
jsr SwapProDOS
lda gRAMDiskRef
jsr ReadFile
jsr SwapProDOS
jsr IncProgress
jsr WriteTrackMLI
bcs .exit
lda KEY
bmi .cancel
inc gTrack
lda gTrack
cmp #$23
bne -
jsr IncProgress
clc
.exit
ldx #TRUE
stx gUsingRAMDisk
rts
.cancel
jsr .exit
jmp Cancel
}
;-------------------------------
; (Close)DeleteRAMFile - (close and) remove image file on RAM disk
; if RAM disk is in use
; in: nothing
; out: if error, C set and A contains error code
; if success, C clear
; all other flags clobbered
; all registers clobbered
;-------------------------------
!zone {
CloseDeleteRAMFile
lda gRAMDiskRef
beq +
jsr CloseFile
lda #0
sta gRAMDiskRef
DeleteRAMFile
lda #<DiskImgPath
sta mliparam+1
lda #>DiskImgPath
sta mliparam+2
jsr DeleteFile
+ rts
}
@tmpparm4 !byte 0
@tmpparm5 !byte 0
;-------------------------------
; get volume name of disk in specific slot+drive
@ -720,7 +502,6 @@ DeleteRAMFile
; (up to 15 character name, no leading slash)
; note: lower 4 bits of @OnlineReturn contain length of @VolumeName
;-------------------------------
!zone {
GetVolumeName
sta mliparam+1
lda #<OnlineReturn
@ -733,7 +514,6 @@ OnlineReturn
VolumeName
!byte $FF,$FF,$FF,$FF,$FF,$FF,$FF
!byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
}
;-------------------------------
; check if volume is online
@ -752,10 +532,11 @@ Online
;-------------------------------
; query volume information
; using ProDOS MLI
; in: nothing (queries last fetched volume)
; out: if error, C set and A contains error code
; if success, C clear and MLI buffer is filled
; (access, file type, block count, dates and times)
; in: @OnlineReturn+@VolumeName contain the length+name of the volume to query
; (this will be true if you just called GetVolumeName)
; out: if error, C set and A contains error code
; if success, C clear and MLI buffer is filled
; (access, file type, block count, dates and times)
;-------------------------------
GetVolumeInfo
lda OnlineReturn

View File

@ -153,6 +153,8 @@ FirstMover
!source "memory.a"
!source "sectormap.a"
!source "mli.a"
!source "ramdisk.a"
!source "harddisk.a"
!source "slots.a"
!source "prefs.a"
!source "keys.a"
@ -169,6 +171,9 @@ ResetVector
sta $C004
sta $C00C
sta $C00E
jsr ThisSlot
; /!\ execution falls through here
MainMenu
lda #<ResetVector
sta $03F2
@ -183,24 +188,15 @@ MainMenu
jsr PrintByID
lda #s_mainmenu
jsr PrintByID
ldx gUsingHardDisk
beq .usingharddisk
lda SLOT
and #$0F
ora #$C0
ldx #$28
ldy #$06
jsr CompareMemory
!byte $20,$33,$CD
!byte $18
!byte $90,$2E
bcc .usingcffa
bit gTargetType
bmi @usingHardDisk
bvs @usingCFFA
lda #s_targetdisk
!byte $2C
.usingcffa
@usingCFFA
lda #s_targetcffa
!byte $2C
.usingharddisk
@usingHardDisk
lda #s_targetfile
jsr PrintByID
.getkey
@ -218,30 +214,23 @@ MainMenu
bne +
.jmptoexit
jmp CleanExit
+
cmp #k_slot
+ cmp #k_slot
bne +
jsr NextSlot
lda #TRUE
sta gChangedPrefs
jmp MainMenu
+
cmp #k_verify
beq MainMenu ; always branches
+ cmp #k_verify
bne +
lda #%00000000
beq Action ; unconditional branch
+
cmp #k_crack
+ cmp #k_crack
bne .getkey
lda #%11000000
; note: execution falls through here
; /!\ execution falls through here
Action
sta gMode
bpl +
jsr CreateRAMOrHardFile
+ jsr ResetProgress
jsr ResetProgress
jsr InitSectorMap
Reaction
lda #FALSE
@ -264,6 +253,29 @@ Reaction
jsr PrintByID
lda VPOS
sta TEXTTOP
lda gMode
bpl @printReading ; don't create RAM disk or hard disk file in verify mode
jsr LookupUnitNumberOfSelectedHardDisk
beq @notHardDrive
jsr SwapProDOS ; ProDOS out -> in
jsr CreateFileOnHardDisk
jsr SwapProDOS ; ProDOS in -> out (preserves flags)
bcc @printReading
jmp FatalWriteError ; failed to create target file on hard disk
; this is fatal
@notHardDrive
lda RAMDiskImagePath
beq @printReading ; no RAM disk available
jsr SwapProDOS ; ProDOS out -> in
jsr CreateFileOnRAMDisk
jsr SwapProDOS ; ProDOS in -> out (preserves flags)
bcc @printReading
lda #0 ; failed to create temporary file on RAM disk
sta RAMDiskImagePath ; this is not fatal, but we'll mark the RAM
; disk as unavailable so we don't bother with it
; /!\ execution falls through here
@printReading
lda #s_reading
jsr PrintByID
lda #$B2
@ -551,26 +563,32 @@ nextsector
bcs .linkread
Pass
bit gMode
bpl .passverify
lda gUsingHardDisk
beq +
lda gUsingRAMDisk
bne +
bpl @passVerify
lda gRAMDiskRef
beq @printFinalMessage ; not using RAM disk, so we're done
; we've written the entire cracked disk as a file on the RAM disk,
; now a second pass to write that file out to the target disk drive
lda #s_writingto
jsr PrintByID
lda #s_slotanddrive
jsr PrintByID
jsr SwapProDOS ; ProDOS out -> in
jsr WriteRAMToDisk
bcc +
jsr SwapProDOS ; ProDOS in -> out (preserves flags)
bcc @printFinalMessage
jmp FatalWriteError
+ lda #s_passcrack0
ldx gPatchCount
beq .passprint
lda #s_passcrack
!byte $2C ; hide next 2 bytes
.passverify
lda #s_pass
.passprint
@printFinalMessage
lda gPatchCount
beq @passWithZeroPatches
lda #s_passcrack ; 'crack complete'
!byte $2C
@passWithZeroPatches
lda #s_passcrack0 ; 'crack complete but no patches'
!byte $2C
@passVerify
lda #s_pass ; 'verification complete'
jsr PrintByID
jmp TheEnd
@ -638,15 +656,11 @@ FatalError
TheEnd
lda $C0E8
lda gHardDiskRef
ora gRAMDiskRef
beq +
jsr SwapProDOS
jsr CloseDeleteRAMFile ; does nothing if RAM disk was not used
lda gHardDiskRef
jsr CloseFile
jsr SwapProDOS
+ lda #s_done
jsr SwapProDOS ; ProDOS out -> in
jsr DeleteFileOnRAMDisk ; always safe to call
jsr CloseFileOnHardDisk ; always safe to call
jsr SwapProDOS ; ProDOS in -> out
lda #s_done
jsr PrintByID
jsr WaitForKey
cmp #$9B
@ -679,7 +693,7 @@ CleanExit
lda gChangedPrefs
bne +
jsr SavePrefs
+ jsr CloseDeleteRAMFile
+ jsr DeleteFileOnRAMDisk ; always safe to call
jsr MLI ; does not return
!byte $65
!word .quitparm
@ -697,46 +711,49 @@ MLI_WRITEPROT = $2B
WriteTrack
jsr AnalyzeTrack
WriteTrackNA ; entry point used by Special Delivery tracer
; to write track with "N"o "A"nalysis
WriteTrackNA ; entry point used by Special Delivery tracer
; to write track with 'N'o 'A'nalysis
bit gMode
bpl .exit ; verify mode -> no write
bpl @exit ; don't write anything in verify mode
lda gSaidWriting
beq .write ; only print 'writing to' message once
beq @doTheWriteThing ; only print 'writing to' message once
; we haven't yet printed any 'writing to...' message in the log, so
; figure out what that should look like and do it now
lda #s_writingto
jsr PrintByID
ldx gUsingHardDisk
bne +
lda DiskImgPath
sta .volumelen
ldx #0
- lda DiskImgPath+1, x
ora #$80
jsr PrintA
inx
.volumelen=*+1
cpx #$FD ; SMC
bcc -
lda #$8D
jsr PrintA
bvc ++ ; always branches
+ lda #s_ramdisk
ldx gUsingRAMDisk
beq +
lda #s_slotanddrive
+ jsr PrintByID
++ lda #TRUE
lda gHardDiskRef
beq @maybeWritingToRAMDisk
; we are writing to a file on a hard disk, so print the
; full pathname of that file
jsr PrintHardDiskImagePath
bvc @doneSaidWriting ; always branches
@maybeWritingToRAMDisk
lda gRAMDiskRef
beq @notWritingToRAMDisk
lda #s_ramdisk ; writing to (a file on) a RAM disk
!byte $2C
@notWritingToRAMDisk
lda #s_slotanddrive ; writing to a slot and drive
jsr PrintByID
@doneSaidWriting
lda #TRUE
sta gSaidWriting
.write
jsr WriteTrackMLI
@doTheWriteThing
jsr SwapProDOS ; ProDOS out -> in
jsr WriteTrackFirstPass
jsr SwapProDOS ; ProDOS in -> out
bcs FatalWriteError
.exit
rts
@exit rts
;-------------------------------
; FatalWriteError
; in: A has MLI code (from WriteTrackMLI)
; out: exits via TheEnd
; in: A has MLI code (from WriteTrackFirstPass or WriteTrackSecondPass)
; out: does not return, exits via TheEnd
;-------------------------------
FatalWriteError
sta gDisplayBytes ; for use in error messages, if any
@ -950,6 +967,7 @@ LastMover
!warn "GetVolumeName=",GetVolumeName
!warn "OnlineReturn=",OnlineReturn
!warn "VolumeName=",VolumeName
!warn "RAMDiskImagePath=",RAMDiskImagePath
!warn "GetVolumeInfo=",GetVolumeInfo
!warn "mliparam=",mliparam
!warn "access=",access
@ -965,4 +983,5 @@ LastMover
!warn "kForceLower=",kForceLower
!warn "PrintByID=",PrintByID
!warn "DiskIIArray=",DiskIIArray
!warn "HardDiskArray=",HardDiskArray
}

View File

@ -323,9 +323,9 @@
ldx #1
stx gTrack
lda gUsingHardDisk
and gUsingRAMDisk
bne +
lda gHardDiskRef
ora gRAMDiskRef
beq +
ldx #$0E
+ stx gSector
dec gAddress+1 ; and $2000-20FF
@ -336,10 +336,10 @@
lda #$20 ; $2000-21FF
sta mliparam+3 ; hi byte of data buffer
dec mliparam+4 ; lo byte of block number
jsr SwapProDOS
lda gUsingHardDisk
and gUsingRAMDisk
beq +
jsr SwapProDOS ; ProDOS out -> in
lda gHardDiskRef
ora gRAMDiskRef
bne +
lda #$81 ; 'write block' command
ldy #$03 ; parameter count
jsr mli
@ -349,7 +349,7 @@
.writeerr
.writedone
jsr SwapProDOS
jsr SwapProDOS ; ProDOS in -> out
;restore original disk location

View File

@ -17,8 +17,7 @@ RestartProgress
pla
sta VPOS
jsr $FC22
; note: execution falls through here
; /!\ execution falls through here
ResetProgress
lda #$82 ; reset progress indicator

107
src/ramdisk.a Normal file
View File

@ -0,0 +1,107 @@
RAMDiskImagePath
!byte 0 ; length byte (0 means no suitable RAM disk is available)
!fill 1 ; / character
!fill 4 ; longest possible volume name for supported RAM disks
; (code only matches 'RAM' or 'RAMn' where n is usually a slot number)
!fill 1 ; / character
!fill 15 ; filename without leading slash (constant, see initscan.a)
;-------------------------------
; CreateFileOnRAMDisk
; create 140KB file on RAM disk (filename is hardcoded)
;
; in: ProDOS is in memory
; RAMDiskImagePath populated
; out: if C set, creation failed (A contains MLI error code)
; if C clear, creation succeeded (A clobbered, gRAMDiskRef contains file refnum)
; all other flags clobbered
; all registers clobbered
; ProDOS is in memory
;-------------------------------
CreateFileOnRAMDisk
jsr DeleteFileOnRAMDisk ; always safe to call
lda #<RAMDiskImagePath
sta mliparam+1
lda #>RAMDiskImagePath
sta mliparam+2
jsr Create140KFile
bcs +
sta gRAMDiskRef
+ rts
;-------------------------------
; DeleteFileOnRAMDisk
; delete our temporary image file on RAM disk
;
; always safe to call
; gracefully returns if no RAM disk was detected
; gracefully closes file before deleting, if it was open
; does not return any error status because no one cares
;
; in: ProDOS is in memory
; out: all registers and flags clobbered
; gRAMDiskRef=0
; ProDOS is in memory
;-------------------------------
DeleteFileOnRAMDisk
lda RAMDiskImagePath
beq @exit ; no RAM disk available
lda gRAMDiskRef
beq +
jsr CloseFile ; close existing file
lda #0
sta gRAMDiskRef
+
lda #<RAMDiskImagePath
sta mliparam+1
lda #>RAMDiskImagePath
sta mliparam+2
jsr DeleteFile ; delete file, ignore error
@exit rts
;-------------------------------
; WriteRAMToDisk - write image file in RAM to physical disk
; if RAM disk is in use
; in: ProDOS is in memory
; out: if error, C set and A contains error code
; if success, C clear
; all other flags clobbered
; all registers clobbered
; ProDOS is in memory
;-------------------------------
WriteRAMToDisk
lda #0
sta mliparam+2
sta mliparam+3
sta mliparam+4
sta gTrack
lda gRAMDiskRef
jsr SetMark
jsr RestartProgress ; restart progress bar
@writeRAMToDiskLoop
lda #$00
sta mliparam+2
sta mliparam+4
lda #$10
sta mliparam+3
sta mliparam+5
lda gRAMDiskRef
jsr ReadFile
jsr IncProgress
jsr WriteTrackSecondPass
bcs @exit
lda KEY
bmi @cancel
inc gTrack
lda gTrack
cmp #$23
bne @writeRAMToDiskLoop
jsr IncProgress
clc
@exit rts
@cancel
jmp Cancel

View File

@ -1,62 +1,85 @@
DiskIIArray
!byte 00,00,00,00,00,00,00
HardDiskArray ; must be immediately after DiskIIArray
!byte 00,00,00,00,00,00,00
!byte 00,00,00,00,00,00,00,00
!fill 7
HardDiskArray
!fill 15
;-------------------------------
; NextSlot
; in: DiskIIArray, HardDiskArray filled by calling
; ScanForDiskII and ScanForRAMAndHardDisks
; out: @SLOT, @DRIVE set to ASCII values of
; next available slot/drive
; @g
; in: DiskIIArray populated by calling ScanForDiskII
; HardDiskArray populated by calling ScanForRAMAndHardDisks
; out: @SLOT, @DRIVE set to ASCII values of next available slot/drive
; @gTargetType set based on type of target (see apidefs.a for values)
;-------------------------------
!zone {
NextSlot
ldy #FALSE
lda DRIVE
cmp #$31
bne .incslot
lda #$32
bne NextSlotLoop
lda #$32 ; cycle from drive 1 to drive 2 of the same slot
sta DRIVE
bne .getslot ; unconditional branch
.incslot
lda #$31
bne ThisSlot ; always branches
NextSlotLoop
lda #$31 ; cycle to drive 1 of the next slot
sta DRIVE
inc SLOT
.getslot
ThisSlot
lda SLOT
cmp #$38
bne .nowrap
lda #$31
bne +
lda #$31 ; cycle from slot 7 back to slot 1
sta SLOT
.nowrap
+ sec
sbc #$30
tax
lda DiskIIArray-1, x
beq @maybeHardDisk
lda SLOT
and #$0F
ora #$C0
ldx #$28
ldy #$06
jsr CompareMemory ; check for signature of CFFA3000 virtual drive in slot ROM
!byte $20,$33,$CD
!byte $18
!byte $90,$2E
bcc @foundCFFA
lda SLOT
cmp #$36
bne @foundDiskII
lda #$32 ; never return S6,D1
sta DRIVE
bne @foundDiskII ; always branches
@maybeHardDisk
jsr LookupUnitNumberOfSelectedHardDisk ; see if we found a hard disk
beq NextSlotLoop ; no hard disk at this location, keep cycling
lda #ID_FILE_ON_HARD_DISK
!byte $2C
@foundCFFA
lda #ID_CFFA_VIRTUAL_DISK
!byte $2C
@foundDiskII
lda #ID_DISK_II
sta gTargetType
rts
LookupUnitNumberOfSelectedHardDisk
; in: HardDiskArray populated
; out: if selected slot and drive contain a suitable hard disk
; then A=ProDOS unit number, Z=0
; otherwise A=0, Z=1
; X clobbered
lda SLOT
sec
sbc #$30
tax
lda DiskIIArray-1,x
bne .done
lda DRIVE
lsr
bcs .checkdrive
bcs +
txa
ora #8
tax
.checkdrive
lda HardDiskArray-1,x
beq .incslot
jsr SwapProDOS ; preserves A
jsr GetVolumeName
jsr SwapProDOS
ldy #TRUE
.done
sty gUsingHardDisk
lda SLOT
cmp #$36
bne .reallydone
lda #$32
sta DRIVE
.reallydone
+ lda HardDiskArray-1, x
rts
}

View File

@ -338,7 +338,7 @@ StringTableHigh
.passport
!text "Passport ",$00
.header
!text "@",s_passport,"by 4am@",s_space7,"@",s_space7," 2021-04-16",$00
!text "@",s_passport,"by 4am@",s_space7,"@",s_space7," 2021-04-17",$00
.bar9
!text "_________",$00
.bar18

View File

@ -26,6 +26,7 @@ for /f "tokens=2,3 delims=)" %%q in ('find "RELBASE =" ..\build\out.txt') do set
for /f "tokens=4,* delims=:(" %%q in ('find "SaveProDOS=" ..\build\out.txt') do echo %%q > ..\build\vars.a
for /f "tokens=4,* delims=:(" %%q in ('find "kForceLower=" ..\build\out.txt') do echo %%q >> ..\build\vars.a
for /f "tokens=4,* delims=:(" %%q in ('find "DiskIIArray=" ..\build\out.txt') do echo %%q >> ..\build\vars.a
for /f "tokens=4,* delims=:(" %%q in ('find "HardDiskArray=" ..\build\out.txt') do echo %%q >> ..\build\vars.a
for /f "tokens=4,* delims=:(" %%q in ('find "PrintByID=" ..\build\out.txt') do echo %%q >> ..\build\vars.a
for /f "tokens=4,* delims=:(" %%q in ('find "WaitForKey=" ..\build\out.txt') do echo %%q >> ..\build\vars.a
for /f "tokens=4,* delims=:(" %%q in ('find "CleanExit=" ..\build\out.txt') do echo %%q >> ..\build\vars.a
@ -35,6 +36,7 @@ for /f "tokens=4,* delims=:(" %%q in ('find "GetVolumeInfo=" ..\build\out.txt')
for /f "tokens=4,* delims=:(" %%q in ('find "filetype=" ..\build\out.txt') do echo %%q >> ..\build\vars.a
for /f "tokens=4,* delims=:(" %%q in ('find "access=" ..\build\out.txt') do echo %%q >> ..\build\vars.a
for /f "tokens=4,* delims=:(" %%q in ('find "VolumeName=" ..\build\out.txt') do echo %%q >> ..\build\vars.a
for /f "tokens=4,* delims=:(" %%q in ('find "RAMDiskImagePath=" ..\build\out.txt') do echo %%q >> ..\build\vars.a
for /f "tokens=4,* delims=:(" %%q in ('find "auxtype=" ..\build\out.txt') do echo %%q >> ..\build\vars.a
for /f "tokens=4,* delims=:(" %%q in ('find "blocks=" ..\build\out.txt') do echo %%q >> ..\build\vars.a
for /f "tokens=4,* delims=:(" %%q in ('find "PREFSVER=" ..\build\out.txt') do echo %%q >> ..\build\vars.a