diff --git a/Programs/CosmOS/Apps/Pour.asm b/Programs/CosmOS/Apps/Pour.asm index c5734b1..197a0d2 100644 --- a/Programs/CosmOS/Apps/Pour.asm +++ b/Programs/CosmOS/Apps/Pour.asm @@ -98,6 +98,16 @@ theTail: SWI osFileWrite BNQ writeFailed + ; And how big it turned out to be, which here is what was asked for: this one knows its + ; size from the start. Something that did not - an assembler, say - would ask for more + ; than it needed and say the truth here. + RSTA + PSHA + SETD.0 Blocks + LDA.0 + PSHA + POPD.3 + INIA 0d40 SWI osFileDone BNQ doneFailed diff --git a/Programs/CosmOS/Assembler/Asm.asm b/Programs/CosmOS/Assembler/Asm.asm index 9111902..dade95b 100644 --- a/Programs/CosmOS/Assembler/Asm.asm +++ b/Programs/CosmOS/Assembler/Asm.asm @@ -57,6 +57,7 @@ start: CALL settleFormat CALL deriveName ; After the first pass: what it is called depends on whether a ; #Base turned up, and that is not known until then. + CALL layOutImage BNQ stopped CALL passTwo @@ -1360,8 +1361,7 @@ layOutImage: BNQ layOutNo SETD.0 ImgWalk - SETD.2 ScratchImage - CALL numSet + CALL numZero ; The front of the file, not the front of a buffer. SETD.0 MagicSPBT INIA 0d4 CALL putBytes @@ -1414,8 +1414,7 @@ layOutLoadable: BNQ layOutNo SETD.0 ImgWalk - SETD.2 ScratchImage - CALL numSet + CALL numZero ; The front of the file, not the front of a buffer. SETD.0 MagicSBEX INIA 0d4 CALL putBytes @@ -1460,17 +1459,104 @@ layOutNo: ADD RET +; ---- Room for the file ---- +; +; Nothing is held in memory any more, so what is checked here is not a buffer. It is that +; the SIZE CAN STILL BE DESCRIBED: every number in this assembler is two bytes, so a file +; of more than 65,535 would have wrapped round while it was being added up and come out +; smaller than one of its own segments. A wrapped total would allocate a short file and +; write off the end of it. +; +; Then the file is started, which is where running out of DISK is found - and that happens +; before a single byte is written, so a refusal costs nothing that was already there. checkImageRoom: - SETD.0 ImgRoom - SETD.2 ImgTotal + SETD.0 ImgTotal + SETD.2 ImgProgLen + CALL numCompare + BRC imageTooBig ; The total is smaller than a part of it: it went round. + SETD.0 ImgTotal + SETD.2 ImgDataLen CALL numCompare BRC imageTooBig + + ; ---- How much room to ask for ---- + ; + ; MORE THAN THE FILE WILL COME TO, on purpose. How many vectors are actually installed is + ; not known until the second pass has resolved every handler, and by then the file has to + ; exist to be written into. What IS known now is how many vectors were DECLARED, and no + ; more than that can be installed - so the room asked for is the whole file plus four + ; bytes for each of them and five for a marker. + ; + ; Asking for too much costs nothing but a moment: osFileDone is told what it really came + ; to and the difference goes back. Asking for too little would have meant writing off the + ; end of the file, and the first sign of it was Keys coming out four bytes short. + SETD.0 ImgAsk + SETD.2 ImgTotal + CALL numSet + SETD.0 ImgVecMost + SETD.2 VecCount + CALL numSet + SETD.0 ImgVecMost + SETD.2 ImgVecMost + CALL numAdd + SETD.0 ImgVecMost + SETD.2 ImgVecMost + CALL numAdd ; Four bytes an entry. + SETD.0 ImgAsk + SETD.2 ImgVecMost + CALL numAdd + INIA 0d5 + SETD.0 ImgAsk + CALL numAddByte + + ; Blocks are the high half of the size and the tail is the low half, which is how an + ; entry holds one and why nothing here has to divide. + SETD.1 ImgAsk + LDA.1 + SETD.0 ImgOutBlocks + STA.0 ; The high half is whole blocks. + SETD.1 ImgAsk + INCD.1 + LDA.1 + SETD.0 ImgOutTail + STA.0 ; And the low half is what is left over. + + ; DP3 wants the block count and A the tail. The Stack takes the high byte first, which is + ; the way every reader in the system takes a count back out of DP3. + RSTA + PSHA + SETD.0 ImgOutBlocks + LDA.0 + PSHA + POPD.3 + SETD.0 ImgOutTail + LDA.0 + SETD.0 OutName + SWI osFileStart + BNQ imageNoRoom + + ; Nothing in the window yet. + RSTA + SETD.0 OutHeld + STA.0 + SETD.0 OutDirty + STA.0 + RSTA RSTB CCF ADD RET +imageNoRoom: + SETD.0 NoRoomText + SWI osPrintString + RSTA + INIB 0d1 + CCF + ADD + RET + imageTooBig: SETD.0 TooBigText SWI osPrintString @@ -1481,16 +1567,171 @@ imageTooBig: RET ; Puts A down at ImgWalk and steps it. -putByte: +; ---- Putting a byte into the file ---- +; +; THE FILE IS WRITTEN AS IT IS MADE, through one block of window, rather than being built +; whole in memory and handed over at the end. Everything below works in FILE OFFSETS: a +; cursor is a two byte number counting from the front of the file, and because a block is +; two hundred and fifty six bytes, the block it lands in is the offset's HIGH byte and the +; place within that block is its LOW one. No division anywhere, which is just as well. +; +; There are two cursors and they move independently, because #Program and #Data alternate +; in source and the two segments are consecutive in the file. Whenever a byte lands in a +; block other than the one in hand, the one in hand goes back to the disk and the new one +; is fetched - so a run of bytes in one segment costs nothing extra, and a switch between +; segments costs two block operations. There are a few dozen switches in a source file and +; several thousand bytes. +; +; The block is FETCHED rather than assumed blank, and that is what makes the whole thing +; work with one window instead of three. The header is patched after every byte is out; the +; block where the program ends is the same block the data begins in; both are simply +; revisits, and a revisit is what fetching handles. + +; A at the file offset in the two byte number DP2 names, which is then stepped on. +putAt: SETD.0 ImgHold STA.0 - SETD.1 ImgWalk - LDD.0.1 - SETD.2 ImgHold - LDA.2 - STA.0 + + ; WHICH CURSOR THIS IS, KEPT IN MEMORY. It arrives in DP2 and everything below wants DP2 + ; for something of its own - and a call puts DP2 back the way it was AT THE CALL, not the + ; way it was on the way in. Leaving it there meant the step at the end moved whatever the + ; last call had left in DP2, which was the address of the window, and the window walked + ; off across memory while the cursor stood still. + SETD.0 ImgCursor + STD.2.0 + + ; Which block, and where in it: a block is two hundred and fifty six bytes, so the two + ; halves of the offset are exactly those two things. + PSHD.2 + POPD.0 + LDA.0 + SETD.1 ImgBlockWant + STA.1 INCD.0 - STD.0.1 + LDA.0 + SETD.1 ImgSlot + STA.1 + + CALL outHold + BNQ putAtFailed + + SETD.0 OutAt + SETD.2 ScratchWindow + CALL numSet + SETD.0 OutAt + SETD.1 ImgSlot + LDA.1 + CALL numAddByte + SETD.1 OutAt + LDD.0.1 + SETD.1 ImgHold + LDA.1 + STA.0 + + INIA 0x01 + SETD.0 OutDirty + STA.0 + + SETD.1 ImgCursor + LDD.0.1 + CALL numStep + RSTA + RSTB + CCF + ADD + RET + +putAtFailed: + RSTA + INIB 0d1 + CCF + ADD + RET + +; Makes sure the block ImgBlockWant names is the one in the window, writing back whatever +; was there and fetching the new one. +outHold: + SETD.0 OutHeld + LDA.0 + BRA outFetch ; Nothing in hand at all. + SETD.0 OutBlock + LDA.0 + SETD.2 ImgBlockWant + LDB.2 + CCF + SUB + BRQ outHeldAlready + + CALL outFlush + BNQ outHoldNo + +outFetch: + SETD.0 ImgBlockWant + LDA.0 + SETD.1 OutBlock + STA.1 + + SETD.1 ScratchWindow + LDD.1.1 + SETD.0 OutBlock + LDB.0 + RSTA + SWI osFileFetch + BNQ outHoldNo + + INIA 0x01 + SETD.0 OutHeld + STA.0 + RSTA + SETD.0 OutDirty + STA.0 + +outHeldAlready: + RSTA + RSTB + CCF + ADD + RET + +outHoldNo: + RSTA + INIB 0d1 + CCF + ADD + RET + +; Whatever is in the window goes back to the file, if anything has been put in it. +outFlush: + SETD.0 OutHeld + LDA.0 + BRA outFlushNothing + SETD.0 OutDirty + LDA.0 + BRA outFlushNothing + + SETD.1 ScratchWindow + LDD.1.1 + SETD.0 OutBlock + LDB.0 + RSTA + SWI osFileWrite + BNQ outHoldNo + + RSTA + SETD.0 OutDirty + STA.0 + +outFlushNothing: + RSTA + RSTB + CCF + ADD + RET + +; The header and everything else that is written in order goes through ImgWalk. +putByte: + SETD.2 ImgWalk + CALL putAt RET ; Puts A bytes from DP0 down at ImgWalk. @@ -1543,12 +1784,11 @@ emitByte: emitToProgram: SETD.1 ProgPut emitPut: - LDD.0.1 - SETD.2 EmitHold - LDA.2 - STA.0 - INCD.0 - STD.0.1 + PSHD.1 + POPD.2 ; ProgPut or DataPut, whichever this byte belongs to. + SETD.0 EmitHold + LDA.0 + CALL putAt RET ; The byte at DP0 offset by A, into ClsByte. The classifier has one of these; this is the @@ -1676,8 +1916,8 @@ writeVectorsHeader: LDA.0 BRA writeVectorsNone SETD.0 ImgWalk - SETD.2 ScratchImage - CALL numSet + CALL numZero ; Back to the front of the file, which is a revisit like + ; any other: the window fetches block nought again. SETD.0 ImgWalk INIA 0d4 CALL numAddByte @@ -1695,8 +1935,8 @@ writeVectorsNone: LDA.0 BRA writeVectorsOut SETD.0 ImgWalk - SETD.2 ScratchImage - CALL numSet + CALL numZero ; Back to the front of the file, which is a revisit like + ; any other: the window fetches block nought again. SETD.0 ImgWalk INIA 0d8 CALL numAddByte @@ -1772,15 +2012,33 @@ vectorNotEntry: ADD RET +; Whatever is still in the window, and then the file takes its name. Nothing that was +; already on the disk has been touched until this last step. writeImage: - SETD.0 OutName - SETD.1 ScratchImage - LDD.1.1 - SETD.2 ImgTotal - LDA.2 - INCD.2 - LDB.2 - SWI osFileSave + CALL outFlush + BNQ writeFailed + + ; What it really came to, which is what the room was asked for less whatever the vectors + ; did not need. + SETD.1 ImgTotal + LDA.1 + SETD.0 ImgOutBlocks + STA.0 + SETD.1 ImgTotal + INCD.1 + LDA.1 + SETD.0 ImgOutTail + STA.0 + + RSTA + PSHA + SETD.0 ImgOutBlocks + LDA.0 + PSHA + POPD.3 + SETD.0 ImgOutTail + LDA.0 + SWI osFileDone BNQ writeFailed RSTA RSTB @@ -2054,8 +2312,35 @@ DropWalk: ; actually is. Three numbers in three files describe these buffers - this one, LabLimit and ; LabRoom in labels.asm, and the map itself - and each of the three has now been the one ; that was left behind while the other two moved. -ImgRoom: - 0x48 0x00 +; Which block of the file is in the window, and whether anything has been put in it. The +; window itself is in scratch, like every other buffer here: a #Reserve is written into the +; file as zeroes and copied at load, and a program that carries its own scratch pays for it +; twice. +OutAt: + 0x00 0x00 +OutBlock: + 0x00 +OutHeld: + 0x00 +OutDirty: + 0x00 +ImgBlockWant: + 0x00 +ImgSlot: + 0x00 +ImgOutBlocks: + 0x00 +ImgOutTail: + 0x00 +ImgCursor: + 0x00 0x00 +ImgAsk: + 0x00 0x00 +ImgVecMost: + 0x00 0x00 +NoRoomText: +"no room on the disk for the output +" MagicSPBT: "SPBT" diff --git a/Programs/CosmOS/Assembler/scratch.asm b/Programs/CosmOS/Assembler/scratch.asm index 6840db1..6e8bbd7 100644 --- a/Programs/CosmOS/Assembler/scratch.asm +++ b/Programs/CosmOS/Assembler/scratch.asm @@ -17,7 +17,8 @@ ; ; 0x4000 6144 the label index, 1536 entries of four ; 0x5800 16384 the label names, packed end to end -; 0x9800 18432 the output file being built +; 0x9800 256 one block of the output file, on its way to the disk +; 0x9900 18176 free ; 0xE000 1792 the vector names, 64 entries of twenty eight ; 0xE700 2048 the reader's stack, six levels of 301 ; 0xEF00 368 which files have been included, sixteen names of 23 @@ -43,10 +44,16 @@ ; index doubled, and the output given what is left, which is still four and a half thousand ; bytes more than CosmOS needs today. ; -; The output's share is temporary. It exists only because the assembler holds a whole -; finished file in memory before writing it, and that is the next thing to go - the file is -; produced in order and could be written as it is made, which would leave this needing three -; blocks rather than eighteen kilobytes. +; THE OUTPUT IS NO LONGER HELD AT ALL. It used to be built whole in memory and handed over +; at the end, which is what made a buffer of eighteen kilobytes the largest thing this +; machine could assemble. The file is produced in order, so it is written as it is made, +; through one block of window - and the eighteen kilobytes that were its share are free. +; +; What to do with them is not obvious and does not have to be decided today. Nothing here +; is close to full: the names are at half, the index at a third, and the output has no +; ceiling of its own any more. Leaving the room unclaimed is better than sharing it out +; among buffers that do not need it, because an unclaimed page is available to whichever +; one turns out to want it. ; ; That ends at 0xF070, with the Stack coming down from 0xFFFF above it - nearly four ; kilobytes, against the tens of bytes of CALL frames this ever nests. @@ -65,7 +72,7 @@ ScratchLabIndex: 0x40 0x00 ScratchLabArena: 0x58 0x00 -ScratchImage: +ScratchWindow: 0x98 0x00 ScratchVecNames: 0xE0 0x00 diff --git a/Programs/CosmOS/README.md b/Programs/CosmOS/README.md index 7498230..8724f5c 100644 --- a/Programs/CosmOS/README.md +++ b/Programs/CosmOS/README.md @@ -512,7 +512,8 @@ Those numbers are written down once, in `Programs/CosmOS/Source/services.asm`, w | osChangeDir | DP0 names a directory. Q is zero if the machine is now in it. What a program changes here, the shell puts back when the program stops. | | osFileStart | DP0 names a file, DP3 is how many whole blocks and A is the bytes left over in the last one. Q is zero if a write is now open. Nothing already on the disk is touched. | | osFileWrite | DP1 is a block, A and B together are which block of the file it is, counting from zero. Q is zero if it was written. An index past the end of the file is refused. | -| osFileDone | No arguments. The old file goes and what was written takes its name. Q is zero if it was committed. | +| osFileDone | DP3 is how many whole blocks it came to and A the bytes left over. The old file goes and what was written takes its name, at that size. Q is zero if it was committed. | +| osFileFetch | DP1 is where a block should go, A and B together are which block. Reads back a block of the file being written. | | osPrintNumber | A and B together are a number. Prints it in decimal, without leading zeroes. | | osBreak | Stops the program, shows every register as it had them, waits for a key, and carries on. | @@ -664,6 +665,8 @@ file a block at a time; `osFileStart`, `osFileWrite` and `osFileDone` write one. ...for each block: DP1 the bytes, A and B which block... SWI osFileWrite + SETD.3 0x00 0x06 ; and what it came to, which need not be + INIA 0d40 ; what was asked for SWI osFileDone ``` @@ -678,6 +681,17 @@ is taken at the start, so a disk that cannot hold it says so while the old one i there. That is stronger than `osFileSave` can manage, where the size is only known once the caller already has every byte in hand. +**The size asked for need not be the size it comes to.** Some sizes are not knowable until +the last byte is out - the assembler cannot say how many vectors a program installs until +it has resolved them, and by then the file it is writing into has to exist. So the room is +taken generously at the start, where running out costs nothing, and `osFileDone` is told +the truth. The blocks that were asked for and not used go back. + +`osFileFetch` reads a block of the file back, which is what lets a program keep only one +block of it in hand. Anything producing two parts of a file at once - source that says +`#Program` and `#Data` in whatever order it likes - has to be able to put a block down, go +and write somewhere else, and pick it up again where it left off. + Two limits differ between the two. `osFileSave` is handed a byte count in two registers and so cannot write more than 65,535 bytes; `osFileStart` is told blocks and a tail, the way an entry holds a size, and reaches the whole disk. And `osFileWrite` refuses an index past the diff --git a/Programs/CosmOS/Source/cosmos.asm b/Programs/CosmOS/Source/cosmos.asm index d4b4c9d..d649f41 100644 --- a/Programs/CosmOS/Source/cosmos.asm +++ b/Programs/CosmOS/Source/cosmos.asm @@ -987,9 +987,36 @@ handleFileWrite: STA.2 RETI -; Nothing to be told. The old file goes and the temporary takes its name, which is the only -; step that can lose anything and the last one. +; DP1 is where the block goes, and A and B together say which one, the same way writing is +; told. Reads back a block of the file being written. +handleFileFetch: + SETD.2 SbfsIndex + STA.2 + INCD.2 + STB.2 + CALL sbfsStreamFetch + MVQA + MVSD.2 + DPUP.2 0d02 + STA.2 + RETI + +; DP3 is how many whole blocks it came to and A is what is left over, told the same way +; osFileStart is told. It need not be what was asked for: a writer that cannot know its +; size until the last byte asks for enough at the start, where running out costs nothing, +; and says the truth here. The blocks it did not use go back. +; +; This is the only step that can lose anything, and the last one. handleFileDone: + SETD.2 SbfsFileTail + STA.2 + PSHD.3 + POPB + POPA + SETD.2 SbfsFileBlocks + STA.2 + INCD.2 + STB.2 CALL fileForget CALL sbfsStreamDone MVQA @@ -3744,6 +3771,7 @@ CommandLine: osFileStart handleFileStart osFileWrite handleFileWrite osFileDone handleFileDone + osFileFetch handleFileFetch osPrintNumber handlePrintNumber osBreak handleBreak Device 0x20 diskDone diff --git a/Programs/CosmOS/Source/sbfs.asm b/Programs/CosmOS/Source/sbfs.asm index c4fe59f..5d57985 100644 --- a/Programs/CosmOS/Source/sbfs.asm +++ b/Programs/CosmOS/Source/sbfs.asm @@ -2420,11 +2420,60 @@ sbfsStreamWrite: CALL sbfsWriteOne RET +; DP1 is where the block should go and SbfsIndex says which one. The other direction of +; sbfsStreamWrite, and the thing that lets a writer keep only ONE block of a file in hand: +; anything writing two parts of a file at once has to be able to put a block down, go +; somewhere else, and pick it up again where it left off. +sbfsStreamFetch: + SETD.0 SbfsStreamOpen + LDA.0 + BRA sbfsStreamNo + + SETD.0 SbfsStreamTo + STD.1.0 + + SETD.0 SbfsFileStart + SETD.2 SbfsStreamAt + CALL sbfsSetWord + SETD.0 SbfsFileBlocks + SETD.2 SbfsStreamBlocks + CALL sbfsSetWord + SETD.0 SbfsStreamTail + LDA.0 + SETD.2 SbfsFileTail + STA.2 + + SETD.0 SbfsStreamTo + LDD.1.0 + CALL sbfsReadOne + RET + +; SbfsFileBlocks and SbfsFileTail say how big it turned out to be, which need not be how +; big it was started at. +; +; A WRITER MAY ASK FOR MORE ROOM THAN IT ENDS UP USING, and that is not laziness on its +; part. Some sizes are not knowable until the last byte is out: the assembler cannot say +; how many vectors a program installs until it has resolved them, and by then the file it +; is writing into must already exist. So the room is taken generously at the start, where +; running out costs nothing, and the size is told the truth here. +; +; The blocks that were asked for and not used go back to the free count. It is a note +; rather than the authority - the directory is - but a note worth keeping right, and two +; disks holding the same files must hold the same bytes. sbfsStreamDone: SETD.0 SbfsStreamOpen LDA.0 BRA sbfsStreamNo + ; What it really came to, put aside before anything walks the disk. + SETD.0 SbfsStreamNewBlocks + SETD.2 SbfsFileBlocks + CALL sbfsSetWord + SETD.0 SbfsFileTail + LDA.0 + SETD.1 SbfsStreamNewTail + STA.1 + ; Now, and not before, the old one goes. It may not be there at all, which is what ; writing something for the first time looks like from here. CALL sbfsStreamWhere @@ -2433,15 +2482,67 @@ sbfsStreamDone: CALL sbfsWipeFound sbfsStreamNoOld: - ; And the temporary takes its name, which is the whole of what committing is. + ; And the temporary takes its name and its true size, which together are the whole of + ; what committing is. CALL sbfsStreamTemp CALL sbfsScanFor BNQ sbfsStreamNo + + ; How much room it was given, before the entry that says so is changed. + CALL sbfsFileExtent + SETD.0 SbfsStreamSpare + SETD.2 SbfsWantBlocks + CALL sbfsSetWord + PSHD.3 POPD.1 DPUP.1 0d06 SETD.0 SbfsStreamLeaf CALL sbfsCopyName + + PSHD.3 + POPD.1 + DPUP.1 0d03 + SETD.0 SbfsStreamNewBlocks + CALL sbfsCopyWord + PSHD.3 + POPD.1 + DPUP.1 0d05 + SETD.0 SbfsStreamNewTail + LDA.0 + STA.1 + + SETD.1 SbfsBuffer + CALL sbfsBufferIn + CALL sbfsWriteBlock + BNQ sbfsStreamNo + + ; And the difference goes back, which is what it was given less what it kept. + SETD.0 SbfsFileBlocks + SETD.2 SbfsStreamNewBlocks + CALL sbfsSetWord + SETD.0 SbfsStreamNewTail + LDA.0 + SETD.1 SbfsFileTail + STA.1 + CALL sbfsFileExtent + SETD.0 SbfsStreamSpare + SETD.2 SbfsWantBlocks + CALL sbfsSubWord + + RSTA + SETD.0 SbfsBlock + STA.0 + INCD.0 + STA.0 + CALL sbfsReadBlock + BNQ sbfsStreamNo + SETD.1 SbfsBuffer + CALL sbfsBufferOut + SETD.0 SbfsBuffer + DPUP.0 0d12 + SETD.2 SbfsStreamSpare + CALL sbfsAddWord SETD.1 SbfsBuffer CALL sbfsBufferIn CALL sbfsWriteBlock @@ -2771,6 +2872,14 @@ SbfsStreamPath: 0x00 0x00 SbfsStreamFrom: 0x00 0x00 +SbfsStreamTo: + 0x00 0x00 +SbfsStreamNewBlocks: + 0x00 0x00 +SbfsStreamNewTail: + 0x00 +SbfsStreamSpare: + 0x00 0x00 SbfsStreamAt: 0x00 0x00 SbfsStreamParent: diff --git a/Programs/CosmOS/Source/services.asm b/Programs/CosmOS/Source/services.asm index 2462d9b..0690bfc 100644 --- a/Programs/CosmOS/Source/services.asm +++ b/Programs/CosmOS/Source/services.asm @@ -102,7 +102,13 @@ ; registers and cannot write more than 65,535. osFileStart 0d29 ; DP0 names it, DP3 is whole blocks, A is bytes in the tail. osFileWrite 0d30 ; DP1 is the block, A and B together are which one, from zero. - osFileDone 0d31 ; No arguments. The temporary takes the name. + osFileDone 0d31 ; DP3 is whole blocks and A the tail: how big it turned out to be. + osFileFetch 0d32 ; DP1 is where it goes, A and B are which block. Reads one back. + +; osFileFetch is what lets a program keep only ONE block of a file in hand while writing +; it. Anything producing two parts of a file at once - an assembler, whose source says +; #Program and #Data in whatever order it likes - has to be able to put a block down, go +; and write somewhere else, and pick it up again where it left off. ; Q is zero if it read, DP3 is how many of its bytes are the file's: ; a whole 0d256 except in a last block that is short. That count is ; why DP3 answers and not a register - 0d256 does not fit in a byte, diff --git a/Tests/expected/cosmosBreak.out b/Tests/expected/cosmosBreak.out index 2c39770..6dce33c 100644 --- a/Tests/expected/cosmosBreak.out +++ b/Tests/expected/cosmosBreak.out @@ -3,11 +3,11 @@ CosmOS > two stops, and what the registers were at each break at 400E A 11 B 22 Q 00 status 00 -DP0 2030 DP1 09F0 DP2 0000 DP3 4000 SP FFFF +DP0 2030 DP1 09F7 DP2 0000 DP3 4000 SP FFFF press a key break at 4023 A 44 B 55 Q 00 status 00 -DP0 2000 DP1 09F0 DP2 0000 DP3 4000 SP FFF5 +DP0 2000 DP1 09F7 DP2 0000 DP3 4000 SP FFF5 press a key carried on to the end finished