Move the opcode map: nothing in 0x0X, and room for a return variant
Three blocks move and nothing else changes. Branches take 0x60, subroutines take 0x70, and the ALU moves up into the 0x10 block the two of them used to share. Order within each block is preserved exactly - this relocates them, it does not rethink them. WHAT IT BUYS IS AN EMPTY 0x00 TO 0x0F. Program Memory that was never written, or a load that stopped part way and left zeroes in its tail, used to read as a long run of ADDs: the machine carried on through them, arrived somewhere unpredictable, and whatever broke there was a long way from the byte that caused it. Now it faults where it is met: Fault: 0x00 at Program Address 0x0004 is not an instruction. That is the address of the byte after the last real instruction, which is the difference between a diagnosis and a search. Reserving the whole nibble rather than just 0x00 means a run into blank memory faults wherever it starts rather than only when it lands on the right byte. runOffTest records it, and the block is left empty for whatever turns out to want it. The other half is room: branches and subroutines had filled 0x10 to 0x1F between them, so a service return that keeps Q and DP3 had nowhere to sit next to its family. It has 0x76 waiting now. Five places wrote an opcode down that the scripted remap did not reach, and four of them were found by tests rather than by looking: - secondPass.c lists which opcodes take an address, and firstPass.c knows SWI by number. Missing those made XOR read as a branch. - Asm.asm knows SWI by number too, being the other assembler. Missing it made the native and host assemblers disagree byte for byte, which is exactly the check that exists to catch a thing known in two places. - loaderTest.asm carries a hand written payload, and its RETI was 0x19. To the assembler those are numbers and to the program they are data, so nothing but running it could notice. It says so in a comment now. - The Assembler Manual prints the bytes hello.asm assembles to, and two of them were branches. The monitor's recorded disassembly moved by exactly the bytes it should: 18 became 72 wherever SWI appears, with SETD and INIB untouched and every disassembled line still reading the same.
This commit is contained in:
@@ -5,16 +5,16 @@ CosmOS
|
||||
* loaded, starting at 4000
|
||||
* bank 00
|
||||
* 4000 47 00 20 00 SETD.0 2000
|
||||
4004 18 10 SWI 10
|
||||
4004 72 10 SWI 10
|
||||
4006 47 00 20 44 SETD.0 2044
|
||||
400A 18 10 SWI 10
|
||||
400A 72 10 SWI 10
|
||||
400C 47 00 20 7A SETD.0 207A
|
||||
4010 27 1F INIB 1F
|
||||
4012 18 11 SWI 11
|
||||
4012 72 11 SWI 11
|
||||
4014 47 00 20 5D SETD.0 205D
|
||||
* 4000 47 00 20 00 18 10 47 00 20 44 18 10 47 00 20 7A G. ...G. D..G. z
|
||||
4010 27 1F 18 11 47 00 20 5D 18 10 47 00 20 7A 18 10 '...G. ]..G. z..
|
||||
4020 47 00 20 65 18 10 18 12 00 00 00 00 00 00 00 00 G. e............
|
||||
* 4000 47 00 20 00 72 10 47 00 20 44 72 10 47 00 20 7A G. .r.G. Dr.G. z
|
||||
4010 27 1F 72 11 47 00 20 5D 72 10 47 00 20 7A 72 10 '.r.G. ]r.G. zr.
|
||||
4020 47 00 20 65 72 10 72 12 00 00 00 00 00 00 00 00 G. er.r.........
|
||||
4030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
||||
* bank 01
|
||||
* 2000 61 20 70 72 6F 67 72 61 6D 2C 20 6C 6F 61 64 65 a program, loade
|
||||
@@ -32,43 +32,11 @@ CosmOS
|
||||
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
|
||||
* bank 01
|
||||
* * bank 00
|
||||
* 8200: 8204: 8206: 8208: 820B: no such instruction
|
||||
820B: that one needs a value after it
|
||||
820B: 820D: * 8200 47 00 81 00 SETD.0 8100
|
||||
8204 18 10 SWI 10
|
||||
8206 42 02 LDA.2
|
||||
8208 4A 00 01 LDD.0.1
|
||||
820B 18 12 SWI 12
|
||||
820D 00 ADD
|
||||
820E 00 ADD
|
||||
820F 00 ADD
|
||||
* hello, typed
|
||||
finished
|
||||
* > greet.sbx 210
|
||||
hello.sbx 52
|
||||
Life.sbx 1409
|
||||
Snake.sbx 2167
|
||||
Keys.sbx 663
|
||||
Say.sbx 155
|
||||
Break.sbx 148
|
||||
notes.txt 21
|
||||
8 files
|
||||
> halted
|
||||
8008 18 SHR
|
||||
8009 12 AND
|
||||
800A 00 ?
|
||||
800B 00 ?
|
||||
* Fault: 0x00 at Program Address 0x800A is not an instruction.
|
||||
H
|
||||
Execution halted.
|
||||
[exit 0]
|
||||
[exit 1]
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
Fault: 0x00 at Program Address 0x0004 is not an instruction.
|
||||
.Execution halted.
|
||||
[exit 1]
|
||||
@@ -14,10 +14,11 @@ Shapes are what follows the opcode:
|
||||
import re
|
||||
import sys
|
||||
|
||||
ADDRESS = {0x10, 0x11, 0x12, 0x13, 0x14, 0x16, 0x17, 0x1A, 0x1B, 0x1C, 0x1D}
|
||||
ONE_BYTE = {0x18, 0x26, 0x27}
|
||||
# Branches and the two calls that carry an address: the ten in 0x6X, plus RCAL and CALL.
|
||||
ADDRESS = {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x70, 0x71}
|
||||
ONE_BYTE = {0x72, 0x26, 0x27}
|
||||
TWO_SELECTORS = {0x4A, 0x4B}
|
||||
SELECTOR = {0x15, 0x33, 0x36, 0x40, 0x41, 0x42, 0x43, 0x44,
|
||||
SELECTOR = {0x65, 0x33, 0x36, 0x40, 0x41, 0x42, 0x43, 0x44,
|
||||
0x45, 0x46, 0x47, 0x48, 0x49, 0x4C, 0x4D,
|
||||
0x4E, 0x4F, 0x50, 0x51}
|
||||
|
||||
|
||||
@@ -656,6 +656,10 @@ stringKeyword | testPrograms/stringKeyword.asm | run | -
|
||||
# version of RCAL that quietly did what CALL does would pass a test that only checked it
|
||||
# returned to the right place.
|
||||
rawCallAndOffsets | testPrograms/rawCallAndOffsets.asm | run | - | -
|
||||
# Falling off the end of a program into Program Memory nobody wrote. It faults on the byte
|
||||
# after the last instruction rather than executing a run of additions and going wrong
|
||||
# somewhere else, which is what 0x00 through 0x0F being empty buys.
|
||||
runOffTest | testPrograms/runOffTest.asm | run | - | -
|
||||
|
||||
# WAIT, the seventy first instruction, on a disk given ten thousand cycles of latency. Two
|
||||
# reads with interrupts masked and no handler anywhere: the machine sleeps through both and
|
||||
|
||||
Reference in New Issue
Block a user