write image to hard disk

This commit is contained in:
Peter Ferrie 2021-04-13 18:09:55 -07:00
parent 2a8a10bc1e
commit 91f8de836b
11 changed files with 280 additions and 73 deletions

View File

@ -36,6 +36,15 @@
;gDisplayBytes
!fill 10 ; array of ten bytes for use as
; substitution strings
;gHardDiskRef
!byte 00 ; handle of hard disk file
; 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
; non-zero if open

View File

@ -116,7 +116,10 @@ gMECCFastloadType = gIs13Sector-$01 ; byte
gOnAClearDayYouCanReadForever = gMECCFastloadType-$01 ; byte
gUsingRAMDisk = gOnAClearDayYouCanReadForever-$01 ; byte
gRAMDiskRef = gUsingRAMDisk-$01 ; byte
gDisplayBytes = gRAMDiskRef-$0A ; 10 bytes
gHardDiskExists = gRAMDiskRef-1 ; byte
gUsingHardDisk = gHardDiskExists-1 ; byte
gHardDiskRef = gUsingHardDisk-$01 ; byte
gDisplayBytes = gHardDiskRef-$0A ; 10 bytes
jcompare = gDisplayBytes-$03 ; 3-byte
jmodify = jcompare-$03 ; 3-byte
jPrintByID = jmodify-$03 ; 3-byte
@ -191,6 +194,9 @@ ConstructStandardDelivery = jConstructStandardDelivery
!warn "gOnAClearDayYouCanReadForever=",gOnAClearDayYouCanReadForever
!warn "gUsingRAMDisk=",gUsingRAMDisk
!warn "gRAMDiskRef=",gRAMDiskRef
!warn "gHardDiskExists=",gHardDiskExists
!warn "gUsingHardDisk=",gUsingHardDisk
!warn "gHardDiskRef=",gHardDiskRef
!warn "gDisplayBytes=",gDisplayBytes
!warn "jcompare=",jcompare
!warn "jmodify=",jmodify

View File

@ -227,6 +227,7 @@ no_hi_decr:
dey
jsr get_crunched_byte
sta (zp_dest_lo),y
sta $400
} else {
literal_start1:
jsr get_crunched_byte

View File

@ -39,7 +39,7 @@ ScanForDiskII
}
!zone {
ScanForRAMDisk
ScanForRAMAndHardDisks
lda #$00
sta iunit
- lda iunit
@ -65,27 +65,18 @@ ScanForRAMDisk
beq -
jsr GetVolumeInfo
;watch for RAM disk type
;watch for ProDOS volume type
lda filetype
and #$0F
cmp #$0F
bne -
;check for RAM[x] by name
;ensure writable
ldy OnlineReturn
cpy #4
beq +
cpy #5
bne -
dey
+
-- lda SlashRAM-1,y
cmp VolumeName-1,y
bne -
dey
bne --
lda filetype-1 ;;access
and #$02
beq -
;check free space
;need at least $118 blocks
@ -101,11 +92,40 @@ ScanForRAMDisk
bne +
cpx #$18
bcc -
+ lda #TRUE
sta gUsingRAMDisk
+ ldx #TRUE
;check for RAM[x] by name
ldy OnlineReturn
cpy #4
beq +
cpy #5
bne ++
dey
+
-- lda SlashRAM-1,y
cmp VolumeName-1,y
bne ++
dey
bne --
stx gUsingRAMDisk
.done
rts
++ lda iunit
pha
lsr
lsr
lsr
lsr
tay
pla
sta DiskIIArray+7-1,y ;;HardDiskArray-1,y
stx gHardDiskExists
bne - ;continue search, always taken
SlashRAM !byte $2F, $52, $41, $4D
}

215
src/mli.a
View File

@ -32,9 +32,16 @@ PRODOSMLI = $BF00 ; [callable] MLI entry point
RAMFileName !text "PASSPORTTMP.DSK"
RAMFileName_e
HardDirName !text "PASSPORT.IMG"
HardDirName_e
HardDiskName !text "/IMG0000.DSK"
HardDiskName_e
; MLI error codes
ERR_FNF = $46
ERR_EOF = $4C
ERR_EXIST = $47
;-------------------------------
; WriteTrackMLI - write the contents of
@ -51,7 +58,8 @@ ERR_EOF = $4C
!zone {
WriteTrackMLI
jsr SwapProDOS
lda gUsingRAMDisk
lda gUsingHardDisk
and gUsingRAMDisk
beq +
jsr ReorderBuffer
+ lda DRIVE ; ProDOS "unit number" is
@ -86,7 +94,8 @@ WriteTrackMLI
lda #BASEPAGE ; hi byte of data buffer
sta mliparam+3
.writeloop
lda gUsingRAMDisk
lda gUsingHardDisk
and gUsingRAMDisk
beq +
lda #$81 ; 'write block' command
ldy #$03 ; parameter count
@ -100,14 +109,15 @@ WriteTrackMLI
clc
bcc .writedone
+ jsr WriteToRAMFile
+ jsr WriteToFile
bcc -
.writeerr
.writedone
php
pha
lda gUsingRAMDisk
lda gUsingHardDisk
and gUsingRAMDisk
beq +
jsr ReorderBuffer
+ jsr SwapProDOS
@ -329,10 +339,10 @@ CloseFile
rts
;-------------------------------
; create a file via ProDOS MLI
; 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 1 (file)
; always sets storage type to $0D (directory) or 1 (file)
; in: caller has filled @mliparam
; with address of pathname,
; file type, aux file type
@ -341,16 +351,23 @@ CloseFile
;-------------------------------
accessbits = $C3 ; full access
CreateDir
lda #$0D
ldy #$0F
bne .createFile
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)
ldy #1
sty mliparam+7 ; storage type (file)
dey
sty mliparam+8 ; creation date (current)
sty mliparam+9
sty mliparam+10 ; creation time (current)
sty mliparam+11
lda #0
sta mliparam+8 ; creation date (current)
sta mliparam+9
sta mliparam+10 ; creation time (current)
sta mliparam+11
lda #CMD_CREATE ; MLI create command
ldy #PC_CREATE ; number of parameters for 'create' command
jsr mli
@ -370,46 +387,109 @@ DeleteFile
rts
;-------------------------------
; CreateRAMFile - create image file on RAM disk
; if RAM disk is in use
; in: nothing (assumes that prefix is set to /RAM)
; 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 {
CreateRAMFile
CreateRAMOrHardFile
lda gUsingHardDisk
lsr ; TRUE/FALSE in C instead of Z
bcc .createHardFile
lda gUsingRAMDisk
bne .done
beq .createRAMFile
.gotRAM
rts
.createRAMFile
;existing file being reused?
lda gRAMDiskRef
bne .done
bne .gotRAM
;no, create a new one
.createHardFile
php
jsr SwapProDOS
lda OnlineReturn
and #$0F
tay
plp
php
bcs .prefRAM
clc
adc #(RAMFileName_e-RAMFileName)+1
sta RAMPath
adc #(HardDirName_e-HardDirName)+2
sta DiskImgPath
tax
lda #$2F
sta RAMPath+1,y
sta DiskImgPath+1
sta DiskImgPath+2,y
- lda OnlineReturn,y
sta RAMPath,y
sta DiskImgPath+1,y
dey
bne -
ldy #(HardDirName_e-HardDirName)
- lda HardDirName-1,y
sta DiskImgPath,x
dex
dey
bne -
jsr CreateHardDir
clc
lda DiskImgPath
adc #(HardDiskName_e-HardDiskName)
sta DiskImgPath
pha
tax
ldy #(HardDiskName_e-HardDiskName)
- lda HardDiskName-1,y
sta DiskImgPath,x
dex
dey
bne -
pla
tax
.findSpare
jsr GetFileInfo
bcs .foundSpare
.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 RAMPath,x
sta DiskImgPath,x
dex
dey
bne -
jsr DeleteRAMFile
.foundSpare
jsr CreateFile
bcs .createfail
lda #0
@ -419,8 +499,16 @@ CreateRAMFile
jsr OpenFile
bcs .openfail
plp
php
bcc .storeHardRef
sta gRAMDiskRef
bcs .setSize
.storeHardRef
sta gHardDiskRef
.setSize
;140kb
ldx #0
@ -430,24 +518,43 @@ CreateRAMFile
ldx #2
stx mliparam+4
jsr SetEOF
lda #0
rol
;update file buffer array
plp
pha
php
jsr SaveGlobal
plp
bcc .restore
pla
beq .restore
php
lda gRAMDiskRef
bcs .closeRef
lda gHardDiskRef
ldx #0
stx gHardDiskRef
.closeRef
jsr CloseFile
.openfail
plp
php
pha
jsr DeleteRAMFile
jsr DeleteFile
pla
sec
.createfail
plp
bcs .failRAM
jsr SwapProDOS
jmp FatalWriteError
.failRAM
ldx #FALSE
stx gUsingRAMDisk
@ -461,15 +568,17 @@ CreateRAMFile
.done
rts
RAMPath !byte $d1
DiskImgPath
!byte $d1
!fill 17
!fill RAMFileName_e-RAMFileName
!fill HardDirName_e-HardDirName
!fill HardDiskName_e-HardDiskName
}
;-------------------------------
; WriteToRAMFile - write memory to image file on RAM disk
; if RAM disk is in use
; WriteToFile - write memory to image file on RAM or hard disk
; if RAM or hard disk is in use
; in: called has filled @mliparam
; with block number and write address
; out: if error, C set and A contains error code
@ -478,7 +587,7 @@ RAMPath !byte $d1
; all registers clobbered
;-------------------------------
!zone {
WriteToRAMFile
WriteToFile
lda mliparam+2
pha
lda mliparam+3
@ -494,8 +603,10 @@ WriteToRAMFile
sta mliparam+4
lda #0
sta mliparam+2
lda gHardDiskRef
bne +
lda gRAMDiskRef
jsr SetMark
+ jsr SetMark
tax
pla
sta mliparam+3
@ -507,8 +618,10 @@ WriteToRAMFile
sta mliparam+4
lda #2
sta mliparam+5
lda gHardDiskRef
bne +
lda gRAMDiskRef
jsr WriteFile
+ jsr WriteFile
.done
pha
@ -599,14 +712,30 @@ CloseDeleteRAMFile
lda #0
sta gRAMDiskRef
DeleteRAMFile
lda #<RAMPath
lda #<DiskImgPath
sta mliparam+1
lda #>RAMPath
lda #>DiskImgPath
sta mliparam+2
jsr DeleteFile
jmp DeleteFile
}
.done
rts
;-------------------------------
; CreateHardDir - create images directory on hard disk
; if hard 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 {
CreateHardDir
lda #<DiskImgPath
sta mliparam+1
lda #>DiskImgPath
sta mliparam+2
jmp CreateDir
}
@ -624,8 +753,7 @@ GetVolumeName
sta mliparam+2
lda #>OnlineReturn
sta mliparam+3
jsr Online
rts
bne Online
OnlineReturn
!byte $FF
VolumeName
@ -672,6 +800,8 @@ GetVolumeInfo
sta mliparam+1
lda #>OnlineReturn
sta mliparam+2
GetFileInfo
lda #CMD_GETFILEINFO
ldy #PC_GETFILEINFO
jsr mli
@ -695,7 +825,8 @@ mli sta mlicmd ; store command code
mlicmd !byte 00 ; command number
!word mliparam ; address of parameter table
rts
mliparam !byte $FE,$FE,$FE,$FE
mliparam !byte $FE,$FE,$FE
access !byte $FE ; access privileges (set by MLI get_file_info)
filetype !byte $FE ; file type (set by MLI get_file_info)
auxtype ; auxiliary file type (2 bytes, set by MLI get_file_info)
refnum !byte $FE ; file refnum (set by MLI open)

View File

@ -220,7 +220,7 @@ MainMenu
Action
sta gMode
bpl +
jsr CreateRAMFile
jsr CreateRAMOrHardFile
+ jsr ResetProgress
jsr InitSectorMap
Reaction
@ -532,6 +532,8 @@ nextsector
Pass
bit gMode
bpl .passverify
lda gUsingHardDisk
beq +
lda gUsingRAMDisk
bne +
lda #s_writing
@ -614,7 +616,14 @@ FatalError
TheEnd
lda $C0E8
lda #s_done
lda gHardDiskRef
beq +
pha
jsr SwapProDOS
pla
jsr CloseFile
jsr SwapProDOS
+ lda #s_done
jsr PrintByID
jsr WaitForKey
cmp #$9B
@ -649,7 +658,6 @@ CleanExit
jsr SavePrefs
.checkRAM
lda gRAMDiskRef
beq .doquit
jsr CloseFile ; leave it behind in case it's wanted
.doquit
jsr MLI
@ -675,6 +683,9 @@ WriteTrackNA ; entry point used by Special Delivery tracer
bpl .exit ; verify mode -> no write
lda gSaidWriting
beq .write
lda #s_writehard ; only print "writing to hard disk" message once
ldx gUsingHardDisk
beq +
lda #s_writeram ; only print "writing to RAM disk" message once
ldx gUsingRAMDisk
beq +
@ -907,6 +918,7 @@ LastMover
!warn "VolumeName=",VolumeName
!warn "GetVolumeInfo=",GetVolumeInfo
!warn "mliparam=",mliparam
!warn "access=",access
!warn "filetype=",filetype
!warn "auxtype=",auxtype
!warn "blocks=",blocks

View File

@ -319,14 +319,15 @@
;read other page in block
;sector $01 pairs with $0F on disk, but
;sector $0E pairs with $0F in RAM disk
;sector $0E pairs with $0F in RAM disk or image
lda #1
sta gTrack
ldx gUsingRAMDisk
ldx #1
stx gTrack
lda gUsingHardDisk
and gUsingRAMDisk
bne +
lda #$0E
+ sta gSector
ldx #$0E
+ stx gSector
dec gAddress+1 ; and $2000-20FF
jsr ReadSector
@ -336,14 +337,15 @@
sta mliparam+3 ; hi byte of data buffer
dec mliparam+4 ; lo byte of block number
jsr SwapProDOS
lda gUsingRAMDisk
lda gUsingHardDisk
and gUsingRAMDisk
beq +
lda #$81 ; 'write block' command
ldy #$03 ; parameter count
jsr mli
bcs .writeerr
bcc .writedone
+ jsr WriteToRAMFile
+ jsr WriteToFile
.writeerr
.writedone

View File

@ -1,21 +1,26 @@
DiskIIArray
!byte 00,00,00,00,00,00,00
HardDiskArray
!byte 00,00,00,00,00,00,00
!byte 00,00,00,00,00,00,00,00
;-------------------------------
; NextSlot
;-------------------------------
!zone {
NextSlot
ldy #FALSE
lda DRIVE
cmp #$31
bne .incslot
lda #$32
sta DRIVE
bne .done ; unconditional branch
bne .getslot ; unconditional branch
.incslot
lda #$31
sta DRIVE
inc SLOT
.getslot
lda SLOT
cmp #$38
bne .nowrap
@ -26,8 +31,24 @@ NextSlot
sbc #$30
tax
lda DiskIIArray-1,x
bne .done
lda DRIVE
lsr
bcs .checkdrive
txa
ora #8
tax
.checkdrive
lda HardDiskArray-1,x
beq .incslot
pha
jsr SwapProDOS
pla
jsr GetVolumeName
jsr SwapProDOS
ldy #TRUE
.done
sty gUsingHardDisk
lda SLOT
cmp #$36
bne .reallydone

View File

@ -154,6 +154,7 @@ StringTableLow
!byte <.timingbits
!byte <.acceptsany
!byte <.addressepilogue
!byte <.writehard
StringTableHigh
!byte >.header
@ -295,6 +296,7 @@ StringTableHigh
!byte >.timingbits
!byte >.acceptsany
!byte >.addressepilogue
!byte >.writehard
;
; Text can contain substitution strings, which
@ -695,4 +697,6 @@ StringTableHigh
!text "T00,S01 Erasing site license information",$00
.badblock
!text "@",s_found,"bad block @",s_protectioncheck,$00
.writehard
!text "Writing to hard disk",$8D,$00
}

View File

@ -141,3 +141,4 @@ s_thedisk = $87
s_timingbits = $88
s_acceptsany = $89
s_addressepilogue = $8A
s_writehard = $8B

View File

@ -36,7 +36,7 @@ OneTimeSetup
jmp CleanExit
.founds6
jsr ScanForRAMDisk
jsr ScanForRAMAndHardDisks
jsr LoadPrefs ; load preferences (if available)
jmp ($fe) ;;zp_dest_lo