Two applications that read a file too big for Data Memory: Type prints one, More pages it. Both sit on fileStream.asm, which wraps osFileInfo and osFileBlock into open-and-next so an application walks a file's blocks without repeating the service calls. The disk fixture is deliberately awkward: readable.txt crosses several blocks and carries no zero byte to be mistaken for an end marker, and empty.txt says that zero blocks is a valid file rather than an error. These three files were written by ChatGPT, as their headers record. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
142 lines
2.6 KiB
NASM
142 lines
2.6 KiB
NASM
; Read a named file from beginning to end, one block at a time.
|
|
;
|
|
; DP0 = filename
|
|
; CALL fileStreamOpen Q = 0, or the osFileInfo error
|
|
; CALL fileStreamNext Q = 0, or the osFileBlock error
|
|
; DP3 = bytes in FileStreamBlock; zero means EOF
|
|
;
|
|
; This is application-side machinery built on CosmOS services, not a filesystem and not
|
|
; yet an OS stream. Open remembers the address of the caller's filename, which must remain
|
|
; valid until the one stream is finished.
|
|
;
|
|
; Written by ChatGPT for Anachronaut's SplitBit
|
|
|
|
#Program
|
|
fileStreamOpen:
|
|
SETD.3 FileStreamName
|
|
STD.0.3
|
|
SWI osFileInfo
|
|
BNQ fileStreamReturn
|
|
PSHD.3
|
|
POPB
|
|
POPA
|
|
SETD.3 FileStreamBlocks
|
|
STA.3
|
|
INCD.3
|
|
STB.3
|
|
SETD.3 FileStreamIndex
|
|
RSTA
|
|
STA.3
|
|
INCD.3
|
|
STA.3
|
|
fileStreamReturn:
|
|
RET
|
|
|
|
fileStreamNext:
|
|
SETD.3 FileStreamBlocks
|
|
LDA.3
|
|
INCD.3
|
|
LDB.3
|
|
OR
|
|
BRQ fileStreamEnd
|
|
SETD.3 FileStreamName
|
|
LDD.0.3
|
|
SETD.1 FileStreamBlock
|
|
SETD.3 FileStreamIndex
|
|
LDA.3
|
|
INCD.3
|
|
LDB.3
|
|
SWI osFileBlock
|
|
BNQ fileStreamReturn
|
|
|
|
; DP3 is the service's return value and also the pointer this routine uses for all of
|
|
; its bookkeeping. Keep the value before touching the pointer, then restore it at the
|
|
; one successful return below.
|
|
PSHD.3
|
|
POPB
|
|
POPA
|
|
SETD.3 FileStreamCount
|
|
STA.3
|
|
INCD.3
|
|
STB.3
|
|
|
|
; Index++.
|
|
SETD.3 FileStreamIndex
|
|
INCD.3
|
|
LDA.3
|
|
INCA
|
|
STA.3
|
|
BNC fileStreamTakeBlock
|
|
DECD.3
|
|
LDA.3
|
|
INCA
|
|
STA.3
|
|
fileStreamTakeBlock:
|
|
; Blocks--.
|
|
SETD.3 FileStreamBlocks
|
|
INCD.3
|
|
LDA.3
|
|
BRA fileStreamBlocksBorrow
|
|
DECA
|
|
STA.3
|
|
BRI fileStreamReadReturn
|
|
fileStreamBlocksBorrow:
|
|
INIA 0xFF
|
|
STA.3
|
|
DECD.3
|
|
LDA.3
|
|
DECA
|
|
STA.3
|
|
fileStreamReadReturn:
|
|
SETD.3 FileStreamCount
|
|
LDD.3.3
|
|
RET
|
|
fileStreamEnd:
|
|
; There is no reset-pointer instruction. Two zero bytes through the Stack are the
|
|
; literal construction of a zero Data Pointer.
|
|
RSTA
|
|
PSHA
|
|
PSHA
|
|
POPD.3
|
|
RET
|
|
|
|
; DP2 names a big-endian sixteen-bit byte count. Decrement it, returning Q = 0 when it
|
|
; reached zero and nonzero while bytes remain. This is shared because correctly counting
|
|
; a full 0x0100-byte block is the least interesting part of both applications to duplicate.
|
|
fileStreamTakeRemaining:
|
|
INCD.2
|
|
LDA.2
|
|
BRA fileStreamRemainingBorrow
|
|
DECA
|
|
STA.2
|
|
DECD.2
|
|
LDB.2
|
|
INCD.2
|
|
LDA.2
|
|
OR
|
|
RET
|
|
fileStreamRemainingBorrow:
|
|
INIA 0xFF
|
|
STA.2
|
|
DECD.2
|
|
LDA.2
|
|
DECA
|
|
STA.2
|
|
LDB.2
|
|
INCD.2
|
|
LDA.2
|
|
OR
|
|
RET
|
|
|
|
#Data
|
|
FileStreamName:
|
|
0x00 0x00
|
|
FileStreamBlocks:
|
|
0x00 0x00
|
|
FileStreamIndex:
|
|
0x00 0x00
|
|
FileStreamCount:
|
|
0x00 0x00
|
|
FileStreamBlock:
|
|
#Reserve 0d256
|