Add Copy and Compare, which stream in both directions at once
Copy joins the read and write streaming services: source and destination are both larger than Data Memory while the program owns one block. Compare reads two files through separate blocks and ignores the bytes past a short final block, which belong to neither file. Between them they exercise empty, exact-block, part-block and 84,000 byte files, and the host extracts the copy afterwards so that two native programs agreeing with each other is not the only oracle. Written by ChatGPT, as their headers record, along with the agree.sh section and the manifest entry that drive them. THIS SHOULD HAVE COME FIRST. The commit before it staged whole files rather than the hunks it meant, so its manifest already names these two programs while their source was still untracked - that commit will not build on its own. Left in place rather than rewritten, since the pair is right and only their order is wrong. NOTES.md is their review of the streaming work. The first item in it is fixed by the commit before this one; the rest are still open. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
a7d3e09d94
commit
54f5cfe8a4
@@ -0,0 +1,277 @@
|
||||
; Compare two files without asking either one to fit in Data Memory.
|
||||
;
|
||||
; Each occupied block is read into its own 256-byte buffer. The byte count returned for
|
||||
; the block is compared before its contents, and only those bytes are examined: bytes
|
||||
; after the end of a short final block belong to neither file and are allowed to differ.
|
||||
;
|
||||
; Written by ChatGPT for Anachronaut's SplitBit
|
||||
|
||||
#Include services.asm
|
||||
|
||||
#Program
|
||||
#Base 0x4000
|
||||
|
||||
start:
|
||||
SETD.0 Arguments
|
||||
INIB 0xFF
|
||||
SWI osArgument
|
||||
SETD.0 Arguments
|
||||
LDA.0
|
||||
BRA usage
|
||||
CALL textSplit
|
||||
SETD.0 TextRest
|
||||
LDD.0.0
|
||||
LDA.0
|
||||
BRA usage
|
||||
|
||||
SETD.0 Arguments
|
||||
SWI osFileInfo
|
||||
BNQ firstFailed
|
||||
SETD.0 FirstBlocks
|
||||
STD.3.0
|
||||
|
||||
SETD.0 TextRest
|
||||
LDD.0.0
|
||||
SWI osFileInfo
|
||||
BNQ secondFailed
|
||||
SETD.0 SecondBlocks
|
||||
STD.3.0
|
||||
|
||||
; A different number of occupied blocks is immediately a different file.
|
||||
SETD.0 FirstBlocks
|
||||
LDA.0
|
||||
SETD.1 SecondBlocks
|
||||
LDB.1
|
||||
CCF
|
||||
SUB
|
||||
BNQ different
|
||||
INCD.0
|
||||
INCD.1
|
||||
LDA.0
|
||||
LDB.1
|
||||
CCF
|
||||
SUB
|
||||
BNQ different
|
||||
|
||||
SETD.0 FirstBlocks
|
||||
SETD.1 RemainingBlocks
|
||||
CALL copyWord
|
||||
RSTA
|
||||
SETD.0 Index
|
||||
STA.0
|
||||
INCD.0
|
||||
STA.0
|
||||
|
||||
nextBlock:
|
||||
SETD.0 RemainingBlocks
|
||||
LDA.0
|
||||
INCD.0
|
||||
LDB.0
|
||||
OR
|
||||
BRQ alike
|
||||
|
||||
SETD.0 Arguments
|
||||
SETD.1 FirstBlock
|
||||
CALL readAtIndex
|
||||
BNQ firstReadFailed
|
||||
SETD.0 FirstCount
|
||||
STD.3.0
|
||||
|
||||
SETD.0 TextRest
|
||||
LDD.0.0
|
||||
SETD.1 SecondBlock
|
||||
CALL readAtIndex
|
||||
BNQ secondReadFailed
|
||||
SETD.0 SecondCount
|
||||
STD.3.0
|
||||
|
||||
; Equal occupied-block counts do not imply equal tails, so compare the valid byte count
|
||||
; returned for this block as well.
|
||||
SETD.0 FirstCount
|
||||
LDA.0
|
||||
SETD.1 SecondCount
|
||||
LDB.1
|
||||
CCF
|
||||
SUB
|
||||
BNQ different
|
||||
INCD.0
|
||||
INCD.1
|
||||
LDA.0
|
||||
LDB.1
|
||||
CCF
|
||||
SUB
|
||||
BNQ different
|
||||
|
||||
SETD.0 FirstCount
|
||||
SETD.1 BytesLeft
|
||||
CALL copyWord
|
||||
SETD.0 FirstBlock
|
||||
SETD.1 SecondBlock
|
||||
|
||||
compareByte:
|
||||
SETD.2 BytesLeft
|
||||
LDA.2
|
||||
INCD.2
|
||||
LDB.2
|
||||
OR
|
||||
BRQ blockSame
|
||||
LDA.0
|
||||
LDB.1
|
||||
CCF
|
||||
SUB
|
||||
BNQ different
|
||||
INCD.0
|
||||
INCD.1
|
||||
SETD.2 BytesLeft
|
||||
CALL takeByte
|
||||
BRI compareByte
|
||||
|
||||
blockSame:
|
||||
CALL stepIndex
|
||||
CALL takeBlock
|
||||
BRI nextBlock
|
||||
|
||||
; DP0 is the path and DP1 the destination buffer. Q and DP3 are the service answers.
|
||||
readAtIndex:
|
||||
SETD.2 Index
|
||||
LDA.2
|
||||
INCD.2
|
||||
LDB.2
|
||||
SWI osFileBlock
|
||||
RET
|
||||
|
||||
; DP0 names the source word and DP1 the destination word.
|
||||
copyWord:
|
||||
LDA.0
|
||||
STA.1
|
||||
INCD.0
|
||||
INCD.1
|
||||
LDA.0
|
||||
STA.1
|
||||
RET
|
||||
|
||||
stepIndex:
|
||||
SETD.0 Index
|
||||
INCD.0
|
||||
LDA.0
|
||||
INCA
|
||||
STA.0
|
||||
BNC stepDone
|
||||
DECD.0
|
||||
LDA.0
|
||||
INCA
|
||||
STA.0
|
||||
stepDone:
|
||||
RET
|
||||
|
||||
takeBlock:
|
||||
SETD.0 RemainingBlocks
|
||||
INCD.0
|
||||
LDA.0
|
||||
BRA blockBorrow
|
||||
DECA
|
||||
STA.0
|
||||
RET
|
||||
blockBorrow:
|
||||
INIA 0xFF
|
||||
STA.0
|
||||
DECD.0
|
||||
LDA.0
|
||||
DECA
|
||||
STA.0
|
||||
RET
|
||||
|
||||
; Decrement the big-endian sixteen-bit BytesLeft. A full block arrives as 0x0100, so an
|
||||
; eight-bit counter would compare none of it and call many different files equal.
|
||||
takeByte:
|
||||
INCD.2
|
||||
LDA.2
|
||||
BRA byteBorrow
|
||||
DECA
|
||||
STA.2
|
||||
RET
|
||||
byteBorrow:
|
||||
INIA 0xFF
|
||||
STA.2
|
||||
DECD.2
|
||||
LDA.2
|
||||
DECA
|
||||
STA.2
|
||||
RET
|
||||
|
||||
alike:
|
||||
SETD.0 SameText
|
||||
SWI osPrintString
|
||||
SWI osExit
|
||||
different:
|
||||
SETD.0 DifferentText
|
||||
SWI osPrintString
|
||||
SWI osExit
|
||||
usage:
|
||||
SETD.0 Usage
|
||||
SWI osPrintString
|
||||
SWI osExit
|
||||
firstFailed:
|
||||
SETD.0 FirstError
|
||||
SWI osPrintString
|
||||
SWI osExit
|
||||
secondFailed:
|
||||
SETD.0 SecondError
|
||||
SWI osPrintString
|
||||
SWI osExit
|
||||
firstReadFailed:
|
||||
SETD.0 FirstReadError
|
||||
SWI osPrintString
|
||||
SWI osExit
|
||||
secondReadFailed:
|
||||
SETD.0 SecondReadError
|
||||
SWI osPrintString
|
||||
SWI osExit
|
||||
|
||||
#Data
|
||||
#Base 0x2000
|
||||
|
||||
Arguments:
|
||||
#Reserve 0d256
|
||||
FirstBlocks:
|
||||
0x00 0x00
|
||||
SecondBlocks:
|
||||
0x00 0x00
|
||||
RemainingBlocks:
|
||||
0x00 0x00
|
||||
Index:
|
||||
0x00 0x00
|
||||
FirstCount:
|
||||
0x00 0x00
|
||||
SecondCount:
|
||||
0x00 0x00
|
||||
BytesLeft:
|
||||
0x00 0x00
|
||||
FirstBlock:
|
||||
#Reserve 0d256
|
||||
SecondBlock:
|
||||
#Reserve 0d256
|
||||
|
||||
Usage:
|
||||
"compare: give me two files
|
||||
"
|
||||
FirstError:
|
||||
"compare: cannot find the first file
|
||||
"
|
||||
SecondError:
|
||||
"compare: cannot find the second file
|
||||
"
|
||||
FirstReadError:
|
||||
"compare: cannot read the first file
|
||||
"
|
||||
SecondReadError:
|
||||
"compare: cannot read the second file
|
||||
"
|
||||
SameText:
|
||||
"the same
|
||||
"
|
||||
DifferentText:
|
||||
"different
|
||||
"
|
||||
|
||||
#Include text.asm
|
||||
Reference in New Issue
Block a user