234 lines
4.2 KiB
NASM
234 lines
4.2 KiB
NASM
; Deleting, renaming, and saving over something that is already there.
|
|
;
|
|
; Reading and writing were built first because a program had to be got onto a disk and off
|
|
; it again. What a document needs is different and it is all about the second time: a file
|
|
; that is written once is easy, and a file that is written again having grown is where this
|
|
; format's bargain shows. Files are contiguous and do not grow, so saving a longer version
|
|
; means putting it somewhere else and letting go of where it was.
|
|
;
|
|
; THE ORDER MATTERS AND THE OBVIOUS ONE IS WRONG. Delete the old, create the new, write it:
|
|
; that loses the lot when the create is refused for want of a run long enough, which is a
|
|
; thing that happens on a disk with plenty of free blocks once it is in pieces. sbfsSaveFile
|
|
; does it the other way round, and the rename at the end of that is why renaming exists.
|
|
;
|
|
; Correct output is:
|
|
; here.txt 0002 already here
|
|
; doc.txt 0003 first draft
|
|
; doc.txt 0004 a second draft, which is longer than the first
|
|
; notes.txt 0004 a second draft, which is longer than the first
|
|
; doc.txt gone
|
|
; notes.txt gone
|
|
;
|
|
; The start block moving from 0003 to 0004 is the file being put somewhere else, which is
|
|
; what saving a longer one has to do. The last two lines are a rename and a delete having
|
|
; actually happened rather than having been reported.
|
|
|
|
#Include print.asm
|
|
#Include sbfs.asm
|
|
|
|
#Program
|
|
|
|
start:
|
|
CALL sbfsMount
|
|
BNQ failed
|
|
|
|
SETD.0 Existing
|
|
CALL report
|
|
BNQ failed
|
|
|
|
; Written once, the ordinary way.
|
|
SETD.0 DocName
|
|
SETD.1 ShortText
|
|
INIA 0d11
|
|
CALL makeAndWrite
|
|
BNQ failed
|
|
SETD.0 DocName
|
|
CALL report
|
|
BNQ failed
|
|
|
|
; And again, longer. Nothing here says where it goes; that is sbfsSaveFile's business.
|
|
SETD.0 SbfsFileBlocks
|
|
RSTA
|
|
STA.0
|
|
INCD.0
|
|
STA.0
|
|
SETD.0 SbfsFileTail
|
|
INIA 0d46
|
|
STA.0
|
|
SETD.0 DocName
|
|
SETD.1 LongText
|
|
CALL sbfsSaveFile
|
|
BNQ failed
|
|
SETD.0 DocName
|
|
CALL report
|
|
BNQ failed
|
|
|
|
; Renaming moves nothing: the same blocks answer to a different name.
|
|
SETD.0 DocName
|
|
SETD.1 NewName
|
|
CALL sbfsRename
|
|
BNQ failed
|
|
SETD.0 NewName
|
|
CALL report
|
|
BNQ failed
|
|
|
|
; And the old name is not there any more, which is the half of renaming that could have
|
|
; quietly not happened.
|
|
SETD.0 DocName
|
|
CALL expectGone
|
|
|
|
SETD.0 NewName
|
|
CALL sbfsDelete
|
|
BNQ failed
|
|
SETD.0 NewName
|
|
CALL expectGone
|
|
HALT
|
|
|
|
failed:
|
|
SETD.0 Failed
|
|
CALL printString
|
|
CALL lineFeed
|
|
HALT
|
|
|
|
; DP0 names the file, DP1 is its text, A is how long it is. Everything here fits in a
|
|
; block, so the whole length is the tail.
|
|
makeAndWrite:
|
|
PSHD.1
|
|
SETD.1 SbfsFileTail
|
|
STA.1
|
|
RSTA
|
|
SETD.1 SbfsFileBlocks
|
|
STA.1
|
|
INCD.1
|
|
STA.1
|
|
CALL sbfsCreate
|
|
POPD.1
|
|
BNQ makeFailed
|
|
CALL sbfsWriteFile
|
|
RET
|
|
makeFailed:
|
|
RET
|
|
|
|
; DP0 names a file that should not be there. Says so either way.
|
|
expectGone:
|
|
PSHD.0
|
|
POPD.3
|
|
CALL printString
|
|
CALL padName
|
|
PSHD.3
|
|
POPD.0
|
|
CALL sbfsFind
|
|
BRQ goneStillThere
|
|
SETD.0 GoneText
|
|
CALL printString
|
|
CALL lineFeed
|
|
RET
|
|
goneStillThere:
|
|
SETD.0 StillText
|
|
CALL printString
|
|
CALL lineFeed
|
|
RET
|
|
|
|
; Prints a file's name, where it begins, and what is in it.
|
|
report:
|
|
PSHD.0
|
|
POPD.3
|
|
CALL printString
|
|
CALL padName
|
|
PSHD.3
|
|
POPD.0
|
|
CALL sbfsFind
|
|
BNQ reportFailed
|
|
|
|
SETD.0 SbfsFileStart
|
|
LDA.0
|
|
CALL printByteHex
|
|
INCD.0
|
|
LDA.0
|
|
CALL printByteHex
|
|
CALL blankSpace
|
|
|
|
SETD.1 Landing
|
|
CALL sbfsRead
|
|
BNQ reportFailed
|
|
|
|
SETD.0 Landing
|
|
SETD.1 SbfsFileTail
|
|
LDA.1
|
|
SETD.1 LeftOver
|
|
STA.1
|
|
BRA reportEnd
|
|
reportLoop:
|
|
LDA.0
|
|
OUTA 0x00
|
|
INCD.0
|
|
SETD.1 LeftOver
|
|
LDA.1
|
|
DECA
|
|
STA.1
|
|
BNA reportLoop
|
|
reportEnd:
|
|
CALL lineFeed
|
|
RSTA
|
|
RSTB
|
|
CCF
|
|
ADD
|
|
RET
|
|
|
|
reportFailed:
|
|
RSTA
|
|
INIB 0d1
|
|
CCF
|
|
ADD
|
|
RET
|
|
|
|
; Names are different lengths and the columns should not be, so this pads out to eleven.
|
|
; DP3 holds the name, which is where the caller left it.
|
|
padName:
|
|
PSHD.3
|
|
POPD.0
|
|
INIB 0d11
|
|
padCount:
|
|
LDA.0
|
|
BRA padOut
|
|
INCD.0
|
|
DECB
|
|
BNB padCount
|
|
padOut:
|
|
RSTA
|
|
padLoop:
|
|
BRB padDone
|
|
INIA 0x20
|
|
OUTA 0x00
|
|
DECB
|
|
BRI padLoop
|
|
padDone:
|
|
RET
|
|
|
|
#Data
|
|
|
|
Existing:
|
|
"here.txt"
|
|
DocName:
|
|
"doc.txt"
|
|
NewName:
|
|
"notes.txt"
|
|
|
|
ShortText:
|
|
"first draft"
|
|
LongText:
|
|
"a second draft, which is longer than the first"
|
|
|
|
GoneText:
|
|
"gone"
|
|
StillText:
|
|
"STILL THERE"
|
|
Failed:
|
|
"failed"
|
|
|
|
LeftOver:
|
|
0x00
|
|
|
|
Landing:
|
|
#Reserve 0d256
|