; 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 0x5000 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 RSTA SWI osExit different: SETD.0 DifferentText SWI osPrintString INIA 0d1 SWI osExit usage: SETD.0 Usage SWI osPrintString INIA 0d2 SWI osExit firstFailed: SETD.0 FirstError SWI osPrintString INIA 0d2 SWI osExit secondFailed: SETD.0 SecondError SWI osPrintString INIA 0d2 SWI osExit firstReadFailed: SETD.0 FirstReadError SWI osPrintString INIA 0d2 SWI osExit secondReadFailed: SETD.0 SecondReadError SWI osPrintString INIA 0d2 SWI osExit #Data #Base 0x3000 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