Breakpoints: SWI osBreak, and s refuses a read only bank
A breakpoint that shows every register as the program had them, waits for a key, and carries on. NOTHING IS OVERWRITTEN, and that is the design rather than a shortcut. A breakpoint poked into a running program has to replace an instruction, and putting that instruction back in order to continue is the same act as disarming the breakpoint; firing a second time would mean stepping over the restored instruction and putting the breakpoint back behind it, and this machine cannot step a single instruction. SWI is two bytes, dispatches through a vector, and its frame already holds the address after it, so RETI resumes at the next instruction with nothing to restore and nothing to re-arm. It fires every time it is reached. The price is that a breakpoint is part of the program: a build with them in has different addresses from a build without. That is the bargain every machine with a break instruction makes. Every value shown comes out of the frame rather than the registers, because by the time the handler runs the registers are the handler's. Apps/Break.asm stops twice so that the second stop is checked as well as the first. Also here, found by the test that came with it: the monitor's s wrote into whichever bank was selected, and bank 2 is the controller's own table, published read only. Writing to it was refused, and a refusal nobody catches stops the machine - so selecting the bank table to look at it and then typing s killed the session. bankPresent now keeps the whole flags byte and s declines. The recorded output of cosmosMonitor had contained that crash, having been blessed without being read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
b36d438132
commit
5fd995aa62
@@ -0,0 +1,56 @@
|
|||||||
|
; Stopping a program to look at it.
|
||||||
|
;
|
||||||
|
; SWI osBreak shows every register as this program had them, waits for a key, and carries
|
||||||
|
; on. It is two bytes and it fires every time it is reached.
|
||||||
|
;
|
||||||
|
; WHY IT IS AN INSTRUCTION RATHER THAN SOMETHING SET FROM OUTSIDE. A breakpoint that was
|
||||||
|
; poked into a running program would have to overwrite an instruction, and then putting that
|
||||||
|
; instruction back in order to continue is the same act as disarming the breakpoint. Firing
|
||||||
|
; a second time would mean stepping over the restored instruction and putting the breakpoint
|
||||||
|
; back behind it, and this machine cannot step one instruction. Nothing is overwritten here,
|
||||||
|
; so there is nothing to restore and nothing to re-arm.
|
||||||
|
;
|
||||||
|
; The price is that it is part of the program. A build with breakpoints in it has different
|
||||||
|
; addresses from a build without, which is the same bargain every machine makes that has a
|
||||||
|
; break instruction.
|
||||||
|
;
|
||||||
|
; Correct output is two stops, showing A and B changing between them, and the addresses of
|
||||||
|
; the two SWIs.
|
||||||
|
|
||||||
|
#Include services.asm
|
||||||
|
|
||||||
|
#Program
|
||||||
|
|
||||||
|
#Base 0x2000
|
||||||
|
|
||||||
|
start:
|
||||||
|
SETD.0 Banner
|
||||||
|
SWI osPrintString
|
||||||
|
|
||||||
|
INIA 0d17
|
||||||
|
INIB 0d34
|
||||||
|
SETD.0 Marker
|
||||||
|
SWI osBreak
|
||||||
|
|
||||||
|
; Something for the second stop to show as different.
|
||||||
|
INIA 0d68
|
||||||
|
INIB 0d85
|
||||||
|
SETD.0 Banner
|
||||||
|
SWI osBreak
|
||||||
|
|
||||||
|
SETD.0 DoneText
|
||||||
|
SWI osPrintString
|
||||||
|
SWI osExit
|
||||||
|
|
||||||
|
#Data
|
||||||
|
|
||||||
|
#Base 0x1000
|
||||||
|
|
||||||
|
Banner:
|
||||||
|
"two stops, and what the registers were at each
|
||||||
|
"
|
||||||
|
Marker:
|
||||||
|
"marker"
|
||||||
|
DoneText:
|
||||||
|
"carried on to the end
|
||||||
|
"
|
||||||
@@ -985,6 +985,127 @@ serviceNoDisk:
|
|||||||
STA.2
|
STA.2
|
||||||
RETI
|
RETI
|
||||||
|
|
||||||
|
; A breakpoint. Shows every register as the interrupted program had them, waits for a key,
|
||||||
|
; and returns as though nothing happened.
|
||||||
|
;
|
||||||
|
; EVERY VALUE COMES OUT OF THE FRAME, not out of the registers, because by the time this
|
||||||
|
; runs the registers belong to the handler. The frame is what the program had, and RETI is
|
||||||
|
; going to give it all back, so what is shown is what will be resumed with.
|
||||||
|
;
|
||||||
|
; DP3 holds the frame throughout. It survives a CALL, and console.asm promises not to
|
||||||
|
; disturb it, which is what lets the printing routines be used between one field and the
|
||||||
|
; next. The Stack Pointer comes back to the same place after a balanced call, so the frame
|
||||||
|
; stays where it was found.
|
||||||
|
;
|
||||||
|
; +1 Status +2 Q +3 A +4 B +5 DP3 +7 DP2 +9 DP1 +11 DP0 +13 where it resumes
|
||||||
|
handleBreak:
|
||||||
|
MVSD.3
|
||||||
|
|
||||||
|
; Where it broke, which is two before where it resumes: the SWI and the vector it names.
|
||||||
|
SETD.0 BreakText
|
||||||
|
CALL printString
|
||||||
|
PSHD.3
|
||||||
|
POPD.0
|
||||||
|
DPUP.0 0d13
|
||||||
|
LDA.0
|
||||||
|
PSHA ; The high half, while the low one is worked on.
|
||||||
|
INCD.0
|
||||||
|
LDA.0
|
||||||
|
INIB 0d2
|
||||||
|
CCF
|
||||||
|
SUB ; Two back from where it resumes: the SWI and the vector it names.
|
||||||
|
MVQA
|
||||||
|
POPB
|
||||||
|
BRC breakBorrowed ; It borrowed, so the high half comes down by one.
|
||||||
|
BRI breakAddress
|
||||||
|
breakBorrowed:
|
||||||
|
DECB
|
||||||
|
breakAddress:
|
||||||
|
PSHA ; low
|
||||||
|
PSHB ; high
|
||||||
|
POPA
|
||||||
|
CALL printByteHex
|
||||||
|
POPA
|
||||||
|
CALL printByteHex
|
||||||
|
CALL newLine
|
||||||
|
|
||||||
|
SETD.0 ARegText
|
||||||
|
PSHD.3
|
||||||
|
POPD.1
|
||||||
|
DPUP.1 0d3
|
||||||
|
CALL breakByte
|
||||||
|
SETD.0 BRegText
|
||||||
|
PSHD.3
|
||||||
|
POPD.1
|
||||||
|
DPUP.1 0d4
|
||||||
|
CALL breakByte
|
||||||
|
SETD.0 QRegText
|
||||||
|
PSHD.3
|
||||||
|
POPD.1
|
||||||
|
DPUP.1 0d2
|
||||||
|
CALL breakByte
|
||||||
|
SETD.0 SRegText
|
||||||
|
PSHD.3
|
||||||
|
POPD.1
|
||||||
|
DPUP.1 0d1
|
||||||
|
CALL breakByte
|
||||||
|
CALL newLine
|
||||||
|
|
||||||
|
SETD.0 DP0Text
|
||||||
|
PSHD.3
|
||||||
|
POPD.1
|
||||||
|
DPUP.1 0d11
|
||||||
|
CALL breakWord
|
||||||
|
SETD.0 DP1Text
|
||||||
|
PSHD.3
|
||||||
|
POPD.1
|
||||||
|
DPUP.1 0d9
|
||||||
|
CALL breakWord
|
||||||
|
SETD.0 DP2Text
|
||||||
|
PSHD.3
|
||||||
|
POPD.1
|
||||||
|
DPUP.1 0d7
|
||||||
|
CALL breakWord
|
||||||
|
SETD.0 DP3Text
|
||||||
|
PSHD.3
|
||||||
|
POPD.1
|
||||||
|
DPUP.1 0d5
|
||||||
|
CALL breakWord
|
||||||
|
CALL newLine
|
||||||
|
|
||||||
|
; Anything typed carries on. Reading the data port waits however the console is set, which
|
||||||
|
; is one key if the program asked for key mode and a whole line if it did not - and either
|
||||||
|
; way it is the program's own console being borrowed for a moment.
|
||||||
|
SETD.0 ResumeText
|
||||||
|
CALL printString
|
||||||
|
INA 0x00
|
||||||
|
CALL newLine
|
||||||
|
RETI
|
||||||
|
|
||||||
|
; DP0 names a field and DP1 points at it in the frame. The caller does the stepping, with
|
||||||
|
; DPUP and a number written into the program, because a routine cannot hand a pointer back:
|
||||||
|
; CALL saves DP0 to DP2 and RET puts them back, so a walk done in here would be undone on
|
||||||
|
; the way out. Written that way first, and every field showed the frame's first byte.
|
||||||
|
breakByte:
|
||||||
|
CALL printString
|
||||||
|
LDA.1
|
||||||
|
CALL printByteHex
|
||||||
|
INIA 0x20
|
||||||
|
OUTA 0x00
|
||||||
|
RET
|
||||||
|
|
||||||
|
; The same for the two byte fields, most significant first the way the frame holds them.
|
||||||
|
breakWord:
|
||||||
|
CALL printString
|
||||||
|
LDA.1
|
||||||
|
CALL printByteHex
|
||||||
|
INCD.1
|
||||||
|
LDA.1
|
||||||
|
CALL printByteHex
|
||||||
|
INIA 0x20
|
||||||
|
OUTA 0x00
|
||||||
|
RET
|
||||||
|
|
||||||
; A and B together are a number. Prints it in decimal without leading zeroes, which covers
|
; A and B together are a number. Prints it in decimal without leading zeroes, which covers
|
||||||
; a line number and a byte count both, so there is no need for one service each.
|
; a line number and a byte count both, so there is no need for one service each.
|
||||||
handlePrintNumber:
|
handlePrintNumber:
|
||||||
@@ -1279,6 +1400,16 @@ dumpNoBank:
|
|||||||
; The cursor is left alone. Somebody poking a byte is usually looking at something else, and
|
; The cursor is left alone. Somebody poking a byte is usually looking at something else, and
|
||||||
; having the address they were reading move underneath them would be a poor reward.
|
; having the address they were reading move underneath them would be a poor reward.
|
||||||
doSet:
|
doSet:
|
||||||
|
; A bank can be present and still refuse to be written: the controller's own table is
|
||||||
|
; published read only, and writing to it is refused. A refusal nobody catches stops the
|
||||||
|
; machine, which is a poor answer to somebody looking around with b and then typing s.
|
||||||
|
CALL bankPresent
|
||||||
|
SETD.0 BankFlags
|
||||||
|
LDA.0
|
||||||
|
INIB 0x02 ; The read only bit of that bank's record.
|
||||||
|
AND
|
||||||
|
BNQ setReadOnly
|
||||||
|
|
||||||
SETD.1 TextRest
|
SETD.1 TextRest
|
||||||
LDD.0.1
|
LDD.0.1
|
||||||
CALL textHexWord
|
CALL textHexWord
|
||||||
@@ -1309,6 +1440,12 @@ setByte:
|
|||||||
POPD.0
|
POPD.0
|
||||||
BRI setByte
|
BRI setByte
|
||||||
|
|
||||||
|
setReadOnly:
|
||||||
|
SETD.0 ReadOnlyText
|
||||||
|
CALL printString
|
||||||
|
CALL newLine
|
||||||
|
BRI prompt
|
||||||
|
|
||||||
setWhat:
|
setWhat:
|
||||||
SETD.0 SetUsage
|
SETD.0 SetUsage
|
||||||
CALL printString
|
CALL printString
|
||||||
@@ -1694,6 +1831,8 @@ bankPresent:
|
|||||||
LDA.0
|
LDA.0
|
||||||
OUTA 0xE2
|
OUTA 0xE2
|
||||||
INA 0xE9 ; The flags byte of that bank's record.
|
INA 0xE9 ; The flags byte of that bank's record.
|
||||||
|
SETD.0 BankFlags
|
||||||
|
STA.0 ; Kept whole, since present is not the only thing it says.
|
||||||
INIB 0x01
|
INIB 0x01
|
||||||
AND
|
AND
|
||||||
RET
|
RET
|
||||||
@@ -1788,6 +1927,26 @@ NothingLoaded:
|
|||||||
Finished:
|
Finished:
|
||||||
"finished"
|
"finished"
|
||||||
|
|
||||||
|
BreakText:
|
||||||
|
"break at "
|
||||||
|
ARegText:
|
||||||
|
"A "
|
||||||
|
BRegText:
|
||||||
|
"B "
|
||||||
|
QRegText:
|
||||||
|
"Q "
|
||||||
|
SRegText:
|
||||||
|
"S "
|
||||||
|
DP0Text:
|
||||||
|
"DP0 "
|
||||||
|
DP1Text:
|
||||||
|
"DP1 "
|
||||||
|
DP2Text:
|
||||||
|
"DP2 "
|
||||||
|
DP3Text:
|
||||||
|
"DP3 "
|
||||||
|
ResumeText:
|
||||||
|
"press a key "
|
||||||
MonitorPrompt:
|
MonitorPrompt:
|
||||||
"* "
|
"* "
|
||||||
UnknownText:
|
UnknownText:
|
||||||
@@ -1813,6 +1972,8 @@ BankIs:
|
|||||||
"bank "
|
"bank "
|
||||||
SetUsage:
|
SetUsage:
|
||||||
"s <address> <byte> <byte> ..."
|
"s <address> <byte> <byte> ..."
|
||||||
|
ReadOnlyText:
|
||||||
|
"that bank will not be written"
|
||||||
GoUsage:
|
GoUsage:
|
||||||
"g <address>"
|
"g <address>"
|
||||||
DirName:
|
DirName:
|
||||||
@@ -1886,6 +2047,8 @@ DumpCount:
|
|||||||
0x00
|
0x00
|
||||||
BankWas:
|
BankWas:
|
||||||
0x00
|
0x00
|
||||||
|
BankFlags:
|
||||||
|
0x00
|
||||||
ShowAsCode:
|
ShowAsCode:
|
||||||
0x00
|
0x00
|
||||||
DumpRecord:
|
DumpRecord:
|
||||||
@@ -2006,4 +2169,5 @@ CommandLine:
|
|||||||
osFileDelete handleFileDelete
|
osFileDelete handleFileDelete
|
||||||
osFileRename handleFileRename
|
osFileRename handleFileRename
|
||||||
osPrintNumber handlePrintNumber
|
osPrintNumber handlePrintNumber
|
||||||
|
osBreak handleBreak
|
||||||
Device 0x20 diskDone
|
Device 0x20 diskDone
|
||||||
|
|||||||
@@ -51,3 +51,17 @@
|
|||||||
; number, in decimal, without leading zeroes. A and B together, so one service covers both
|
; number, in decimal, without leading zeroes. A and B together, so one service covers both
|
||||||
; a line number and a byte count and there is no need for two.
|
; a line number and a byte count and there is no need for two.
|
||||||
osPrintNumber 0d24
|
osPrintNumber 0d24
|
||||||
|
|
||||||
|
; ---- Stopping to look ----
|
||||||
|
;
|
||||||
|
; A breakpoint. Put SWI osBreak anywhere in a program and the system shows every register as
|
||||||
|
; the program had them, waits for a key, and carries on.
|
||||||
|
;
|
||||||
|
; NOTHING IS OVERWRITTEN, which is what makes this simple. A breakpoint that replaced an
|
||||||
|
; instruction would have to put it back to continue, and putting it back disarms the
|
||||||
|
; breakpoint - so firing twice would need the instruction to be stepped over and the
|
||||||
|
; breakpoint replaced behind it, and this machine has no way to step one instruction. An SWI
|
||||||
|
; costs two bytes of the program and fires for ever, because there was never anything to
|
||||||
|
; restore. The price is that it is part of the program: a build with breakpoints in it has
|
||||||
|
; different addresses from one without.
|
||||||
|
osBreak 0d25
|
||||||
|
|||||||
@@ -560,6 +560,7 @@ Those numbers are written down once, in `Programs/CosmOS/Source/services.asm`, w
|
|||||||
| osFileDelete | DP0 names a file. Q is zero if it went. |
|
| osFileDelete | DP0 names a file. Q is zero if it went. |
|
||||||
| osFileRename | DP0 is the name a file has, DP1 the name it should have. Q is zero if it moved. |
|
| osFileRename | DP0 is the name a file has, DP1 the name it should have. Q is zero if it moved. |
|
||||||
| osPrintNumber | A and B together are a number. Prints it in decimal, without leading zeroes. |
|
| 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. |
|
||||||
|
|
||||||
```
|
```
|
||||||
#Include services.asm
|
#Include services.asm
|
||||||
@@ -568,6 +569,23 @@ Those numbers are written down once, in `Programs/CosmOS/Source/services.asm`, w
|
|||||||
SWI osPrintString
|
SWI osPrintString
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Stopping To Look:
|
||||||
|
|
||||||
|
`SWI osBreak` is a breakpoint. It shows every register as the program had them, waits for a key, and returns as though nothing happened.
|
||||||
|
|
||||||
|
```
|
||||||
|
break at 200E
|
||||||
|
A 11 B 22 Q 00 S 00
|
||||||
|
DP0 1030 DP1 05AE DP2 039A DP3 2000
|
||||||
|
press a key
|
||||||
|
```
|
||||||
|
|
||||||
|
Every value comes out of the interrupt frame rather than out of the registers, because by the time the handler runs the registers belong to the handler. The frame is what the program had and what RETI is about to give back, so what is shown is what will be resumed with. The address is two before where it resumes: the `SWI` and the vector it names.
|
||||||
|
|
||||||
|
**Nothing is overwritten, and that is the whole of why it is simple.** A breakpoint poked into a running program has to replace an instruction, and putting that instruction back in order to continue is the same act as disarming the breakpoint. Firing a second time would mean stepping over the restored instruction and putting the breakpoint back behind it, and this machine has no way to step a single instruction. Two bytes of `SWI` cost a little space and fire for ever, because there was never anything to restore.
|
||||||
|
|
||||||
|
The price is that a breakpoint is part of the program. A build with breakpoints in it has different addresses from a build without — the same bargain every machine makes that has a break instruction.
|
||||||
|
|
||||||
### The Disk Without A Filesystem:
|
### The Disk Without A Filesystem:
|
||||||
|
|
||||||
A program that wants a file does not need to know what a filesystem is. Before these existed it had to include the whole of `sbfs.asm` — two and a half kilobytes of a private copy of code the system already had running — and then mount a disk that was already mounted.
|
A program that wants a file does not need to know what a filesystem is. Before these existed it had to include the whole of `sbfs.asm` — two and a half kilobytes of a private copy of code the system already had running — and then mount a disk that was already mounted.
|
||||||
@@ -668,6 +686,7 @@ Whoever does the loading keeps its own code and data below the addresses the loa
|
|||||||
| Keys | The console interrupting rather than being asked. The only one that brings a vector of its own, which is what the version two format exists for. |
|
| Keys | The console interrupting rather than being asked. The only one that brings a vector of its own, which is what the version two format exists for. |
|
||||||
| Say | Prints whatever it was told, which is the shortest thing that shows osArgument working. |
|
| Say | Prints whatever it was told, which is the shortest thing that shows osArgument working. |
|
||||||
| Files | Writes a file, reads it back, renames it and deletes it, in 645 bytes, including nothing but the service names. It is what says a program does not need a filesystem inside it. |
|
| Files | Writes a file, reads it back, renames it and deletes it, in 645 bytes, including nothing but the service names. It is what says a program does not need a filesystem inside it. |
|
||||||
|
| Break | Stops itself twice with SWI osBreak, so that the registers can be seen changing between one stop and the next. |
|
||||||
| Edit | A line editor. |
|
| Edit | A line editor. |
|
||||||
|
|
||||||
### The Monitor:
|
### The Monitor:
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
CosmOS
|
||||||
|
> loaded, starting at 2000
|
||||||
|
> two stops, and what the registers were at each
|
||||||
|
break at 200E
|
||||||
|
A 11 B 22 Q 00 S 00
|
||||||
|
DP0 1030 DP1 05CC DP2 039A DP3 2000
|
||||||
|
press a key
|
||||||
|
break at 2018
|
||||||
|
A 44 B 55 Q 00 S 00
|
||||||
|
DP0 1000 DP1 05CC DP2 039A DP3 2000
|
||||||
|
press a key
|
||||||
|
carried on to the end
|
||||||
|
finished
|
||||||
|
> halted
|
||||||
|
Execution halted.
|
||||||
|
[exit 0]
|
||||||
@@ -26,6 +26,35 @@ CosmOS
|
|||||||
0010 03 FF 08 00 00 00 00 00 01 20 01 00 00 00 00 00 ......... ......
|
0010 03 FF 08 00 00 00 00 00 01 20 01 00 00 00 00 00 ......... ......
|
||||||
0020 00 FF 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 ................
|
0020 00 FF 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 ................
|
||||||
0030 00 FF 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 ................
|
0030 00 FF 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 ................
|
||||||
* Fault: The device on port 233 refused the access at Program Address 0x1359, and nothing is installed to deal with it.
|
* that bank will not be written
|
||||||
|
* bank 00
|
||||||
|
* * 8000 26 48 INIA 48
|
||||||
|
8002 D1 00 OUTA 00
|
||||||
|
8004 26 0A INIA 0A
|
||||||
|
8006 D1 00 OUTA 00
|
||||||
|
8008 18 12 SWI 12
|
||||||
|
800A 00 ADD
|
||||||
|
800B 00 ADD
|
||||||
|
800C 00 ADD
|
||||||
|
* H
|
||||||
|
finished
|
||||||
|
* 8000 26 48 INIA 48
|
||||||
|
8002 D1 00 OUTA 00
|
||||||
|
8004 26 0A INIA 0A
|
||||||
|
8006 D1 00 OUTA 00
|
||||||
|
8008 18 12 SWI 12
|
||||||
|
800A 00 ADD
|
||||||
|
800B 00 ADD
|
||||||
|
800C 00 ADD
|
||||||
|
* > greet.sbx 210
|
||||||
|
hello.sbx 52
|
||||||
|
Life.sbx 1411
|
||||||
|
Snake.sbx 2175
|
||||||
|
Keys.sbx 663
|
||||||
|
Say.sbx 155
|
||||||
|
Break.sbx 128
|
||||||
|
notes.txt 21
|
||||||
|
8 files
|
||||||
|
> halted
|
||||||
Execution halted.
|
Execution halted.
|
||||||
[exit 1]
|
[exit 0]
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ Life.sbx 1411
|
|||||||
Snake.sbx 2175
|
Snake.sbx 2175
|
||||||
Keys.sbx 663
|
Keys.sbx 663
|
||||||
Say.sbx 155
|
Say.sbx 155
|
||||||
|
Break.sbx 128
|
||||||
notes.txt 21
|
notes.txt 21
|
||||||
7 files
|
8 files
|
||||||
> load what?
|
> load what?
|
||||||
> no such file
|
> no such file
|
||||||
> not a program
|
> not a program
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
load Break.sbx
|
||||||
|
run
|
||||||
|
|
||||||
|
|
||||||
|
exit
|
||||||
@@ -9,6 +9,8 @@ b data
|
|||||||
x 1000
|
x 1000
|
||||||
b 2
|
b 2
|
||||||
x 0
|
x 0
|
||||||
|
s 0 FF
|
||||||
|
b program
|
||||||
s 8000 26 48 D1 00 26 0A D1 00 18 12
|
s 8000 26 48 D1 00 26 0A D1 00 18 12
|
||||||
d 8000
|
d 8000
|
||||||
g 8000
|
g 8000
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ for i in 1 2 3 4 5 6 7 8; do "$TOOL" put "$DISKS/sbfs.img" "filler$i.txt" >/dev/
|
|||||||
"$ROOT/Assembler" -I "$ROOT/Programs/CosmOS/Source" \
|
"$ROOT/Assembler" -I "$ROOT/Programs/CosmOS/Source" \
|
||||||
"$ROOT/Programs/CosmOS/Apps/Say.asm" -o "$WORK/Say.sbx" >/dev/null
|
"$ROOT/Programs/CosmOS/Apps/Say.asm" -o "$WORK/Say.sbx" >/dev/null
|
||||||
"$TOOL" put "$DISKS/cosmos.img" "$WORK/Say.sbx" >/dev/null
|
"$TOOL" put "$DISKS/cosmos.img" "$WORK/Say.sbx" >/dev/null
|
||||||
|
# Break.sbx stops itself twice and shows what the registers were each time. It needs no disk
|
||||||
|
# of its own: it only prints.
|
||||||
|
"$ROOT/Assembler" -I "$ROOT/Programs/CosmOS/Source" \
|
||||||
|
"$ROOT/Programs/CosmOS/Apps/Break.asm" -o "$WORK/Break.sbx" >/dev/null
|
||||||
|
"$TOOL" put "$DISKS/cosmos.img" "$WORK/Break.sbx" >/dev/null
|
||||||
printf 'this is not a program' > notes.txt
|
printf 'this is not a program' > notes.txt
|
||||||
"$TOOL" put "$DISKS/cosmos.img" notes.txt >/dev/null
|
"$TOOL" put "$DISKS/cosmos.img" notes.txt >/dev/null
|
||||||
|
|
||||||
|
|||||||
@@ -221,6 +221,10 @@ cosmosRun | CosmOS/Source/cosmos.asm | run | cosmosRun
|
|||||||
# The last part is what the mode is FOR: a program typed in as bytes, run with g, and the
|
# The last part is what the mode is FOR: a program typed in as bytes, run with g, and the
|
||||||
# prompt that comes back is the monitor's own. A program giving the machine back lands where
|
# prompt that comes back is the monitor's own. A program giving the machine back lands where
|
||||||
# it was started from, so looking at something and running it do not interrupt each other.
|
# it was started from, so looking at something and running it do not interrupt each other.
|
||||||
|
#
|
||||||
|
# It also asks to write into bank 2, the controller's own table, which is published read
|
||||||
|
# only. That used to stop the machine, and the recorded output of this test contained the
|
||||||
|
# crash without anybody noticing, which is what blessing a result without reading it buys.
|
||||||
cosmosMonitor | CosmOS/Source/cosmos.asm | run | cosmosMonitor.in | - | disks/cosmos.img
|
cosmosMonitor | CosmOS/Source/cosmos.asm | run | cosmosMonitor.in | - | disks/cosmos.img
|
||||||
# The original hello.asm, brought over as an application. It is not much of a program,
|
# The original hello.asm, brought over as an application. It is not much of a program,
|
||||||
# but it is the one that talks to the hardware directly: it writes to port 0x00 instead
|
# but it is the one that talks to the hardware directly: it writes to port 0x00 instead
|
||||||
@@ -270,6 +274,13 @@ cosmosFiles | CosmOS/Source/cosmos.asm | run | cosmosFil
|
|||||||
# name, and with several words, since what arrives is the rest of the line rather than a
|
# name, and with several words, since what arrives is the rest of the line rather than a
|
||||||
# list and it is the program's business what to make of it.
|
# list and it is the program's business what to make of it.
|
||||||
cosmosSay | CosmOS/Source/cosmos.asm | run | cosmosSay.in | - | disks/cosmos.img
|
cosmosSay | CosmOS/Source/cosmos.asm | run | cosmosSay.in | - | disks/cosmos.img
|
||||||
|
# A program stopping itself to be looked at. Two breakpoints, so what is checked is not only
|
||||||
|
# that one fires but that the SECOND one does - which is the whole difference between this
|
||||||
|
# design and one that overwrites an instruction, since an overwritten instruction has to be
|
||||||
|
# put back to continue and putting it back is the same act as disarming the breakpoint.
|
||||||
|
# Every value shown comes out of the interrupt frame rather than the registers, because by
|
||||||
|
# the time the handler runs the registers are the handler's.
|
||||||
|
cosmosBreak | CosmOS/Source/cosmos.asm | run | cosmosBreak.in | - | disks/cosmos.img
|
||||||
# The editor, which is the first program on this machine that makes a file a person typed:
|
# The editor, which is the first program on this machine that makes a file a person typed:
|
||||||
# every byte on every other image here was put there by the host tool. It is run twice in
|
# every byte on every other image here was put there by the host tool. It is run twice in
|
||||||
# one session, and that is the test rather than a flourish - the second run reads back what
|
# one session, and that is the test rather than a flourish - the second run reads back what
|
||||||
@@ -291,6 +302,7 @@ app-Life | CosmOS/Apps/Life.asm | assemble | -
|
|||||||
app-Snake | CosmOS/Apps/Snake.asm | assemble | - | -
|
app-Snake | CosmOS/Apps/Snake.asm | assemble | - | -
|
||||||
app-Keys | CosmOS/Apps/Keys.asm | assemble | - | -
|
app-Keys | CosmOS/Apps/Keys.asm | assemble | - | -
|
||||||
app-Say | CosmOS/Apps/Say.asm | assemble | - | -
|
app-Say | CosmOS/Apps/Say.asm | assemble | - | -
|
||||||
|
app-Break | CosmOS/Apps/Break.asm | assemble | - | -
|
||||||
app-Edit | CosmOS/Apps/Edit.asm | assemble | - | -
|
app-Edit | CosmOS/Apps/Edit.asm | assemble | - | -
|
||||||
app-Files | CosmOS/Apps/Files.asm | assemble | - | -
|
app-Files | CosmOS/Apps/Files.asm | assemble | - | -
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user