passport/src/initscan.a

266 lines
7.4 KiB
Plaintext

SlashRAM !raw "/RAM"
SlashRAM_e
RAMFileName !raw "PASSPORTTMP.DSK"
RAMFileName_e
;-------------------------------
; ScanForDiskII
; scan all slots for things that look like Disk II cards
;
; in: none
; out: DiskIIArray populated
; all registers and flags clobbered
;-------------------------------
ScanForDiskII
lda #$00
sta cmp1
ldx #$07
- txa
ora #$C0
sta cmp1+1
ldy #$01
lda (cmp1), y
cmp #$20
bne +
ldy #$03
lda (cmp1), y
bne +
ldy #$05
lda (cmp1), y
cmp #$03
bne +
ldy #$FF
lda (cmp1), y
bne +
tya
sta DiskIIArray-1, x
+ dex
bne -
rts
;-------------------------------
; 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
@nextunit
lda iunit
clc
adc #$10
sta iunit
bne +
rts
+ cmp #$80
beq @nextunit
pha
and #$70
lsr
lsr
lsr
lsr
tay
pla
ldx DiskIIArray-1, y
bne @nextunit ; ScanForDiskII already detected that this slot is a floppy drive, so skip it
jsr GetVolumeName
bcs @nextunit ; can't get a volume name, so skip it
lda OnlineReturn
and #$0F
beq @nextunit ; volume name length=0 means an error occurred, so skip it
jsr GetVolumeInfo
lda filetype
and #$0F
cmp #$0F
bne @nextunit ; ProDOS volume type says this isn't a directory, so skip it
lda access
and #$02
beq @nextunit ; volume is not writeable, so skip it
; 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 @nextunit ; not enough free space, so skip it
bne +
cpx #$18
bcc @nextunit ; not enough free space, so skip it
+
; 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
lda RAMDiskImagePath
bne @nextunit ; we already found a suitable RAM disk, so skip this one
; 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
@foundHardDrive
lda iunit
pha
lsr
lsr
lsr
lsr
tay
pla
sta HardDiskArray-1, y
bne @nextunit ; always branches
.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
; load preferences from file
;
; in: ProDOS must be in memory
;-------------------------------
LoadPrefs
lda #$FF
sta PREFSVER
jsr LoadFile1Shot
!word PREFSFILE
!word PREFSVER
!word PREFSREADLEN
!word PREFSBUFFER
jsr ValidatePrefs
bcc +
jmp SavePrefs
+ rts
;-------------------------------
; LoadFile1Shot
; load a file into memory all at once,
; using ProDOS MLI calls
;
; in: stack contains 8 bytes of parameters:
; +1 address of pathname
; +3 address of data buffer (to receive file contents)
; +5 [word] maximum length of data to read
; +7 address of ProDOS file buffer
; out: if C set, load failed and A contains error code
; from open or read
; if C clear, load succeeded and ($02) contains
; data loaded from file
; all other flags clobbered
; all registers clobbered
; stack set to next instruction after parameters
;-------------------------------
LoadFile1Shot
clc
pla
sta $00
adc #$08
tax
pla
sta $01
adc #$00
pha
txa
pha
ldy #$01
lda ($00), y ; lo byte of pathname
sta mliparam+1
iny
lda ($00), y ; hi byte of pathname
sta mliparam+2
ldy #$07
lda ($00), y ; lo byte of ProDOS file buffer
sta mliparam+3
iny
lda ($00), y ; hi byte of ProDOS file buffer
sta mliparam+4
jsr OpenFile
bcs @exit ; C set on error
pha ; push file reference number
ldy #$03
lda ($00), y ; lo address of data buffer
sta mliparam+2
iny
lda ($00), y ; hi address of data buffer
sta mliparam+3
iny
lda ($00), y ; lo data length
sta mliparam+4
iny
lda ($00), y ; hi data length
sta mliparam+5
pla ; pull file reference number
jsr ReadFile
php ; save flags from readfile
pha
jsr CloseFile ; always close whether read worked or not
pla
plp ; restore flags from readfile
; (so caller gets codes from read attempt,
; not close)
@exit rts