Fix the return address stack so it can handle 16-bit addresses, remove an unused library from the disassembler code, and tidy up the disassembler code and the readme a bit
This commit is contained in:
parent
ddce9abba1
commit
bbb2a1a695
|
@ -1,6 +1,6 @@
|
|||
program Disassembler;
|
||||
|
||||
uses Crt, Sysutils;
|
||||
uses Sysutils;
|
||||
|
||||
var
|
||||
Op, Regs: 0 .. $f; //Opcode, and register arguments in a single variable
|
||||
|
@ -90,16 +90,13 @@ begin
|
|||
write (Opcodes [Op]);
|
||||
if Op = $b then writeln (IntToHex (Addr, 1), ', R', X)
|
||||
else begin
|
||||
if Op >= 2 then if Op <> $b then write ('R', X);
|
||||
if Op >= 2 then write ('R', X);
|
||||
if Op >= 6 then if Op <= 9 then write (', R', Y);
|
||||
if OP >= $c then write (', R', Y);
|
||||
if Op >= $a then write (', ', IntToHex (Addr, 1));
|
||||
writeln ();
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
until (BP >= EP);
|
||||
|
||||
end.
|
||||
|
|
24
emulator.pas
24
emulator.pas
|
@ -56,10 +56,12 @@ begin
|
|||
if IP > $ffef then break;
|
||||
//Address argument
|
||||
if Op >= $a then begin
|
||||
//High byte
|
||||
Addr := Mem [IP];
|
||||
Addr := Addr shl 8;
|
||||
IP := IP + 1;
|
||||
if IP > $ffef then break;
|
||||
//Low byte
|
||||
Addr := Addr + Mem [IP];
|
||||
IP := IP + 1;
|
||||
if IP > $ffef then break;
|
||||
|
@ -70,7 +72,13 @@ begin
|
|||
if Op = 0 then Halt := true
|
||||
//Ret
|
||||
else if Op = 1 then begin
|
||||
//High byte of the return address
|
||||
IP := Mem [RP];
|
||||
IP := IP shl 8;
|
||||
RP := RP + 1;
|
||||
if RP > $fff0 then break;
|
||||
//Low byte of the return address
|
||||
IP := IP + Mem [RP];
|
||||
RP := RP + 1;
|
||||
if RP > $fff0 then break;
|
||||
end
|
||||
|
@ -122,9 +130,15 @@ begin
|
|||
//Cleq
|
||||
else if Op = $e then begin
|
||||
if R [X] = R [Y] then begin
|
||||
//Low byte of the return address
|
||||
RP := RP - 1;
|
||||
if RP > $fff0 then break;
|
||||
Mem [RP] := IP;
|
||||
Mem [RP] := IP and $ff;
|
||||
//High byte of the return address
|
||||
RP := RP - 1;
|
||||
if RP > $fff0 then break;
|
||||
Mem [RP] := IP shr 8;
|
||||
//Call
|
||||
IP := Addr;
|
||||
if IP > $ffef then break;
|
||||
end;
|
||||
|
@ -132,9 +146,15 @@ begin
|
|||
//Clneq
|
||||
else if Op = $f then begin
|
||||
if R [X] <> R [Y] then begin
|
||||
//Low byte of the return address
|
||||
RP := RP - 1;
|
||||
if RP > $fff0 then break;
|
||||
Mem [RP] := IP;
|
||||
Mem [RP] := IP and $ff;
|
||||
//High byte of the return address
|
||||
RP := RP - 1;
|
||||
if RP > $fff0 then break;
|
||||
Mem [RP] := IP shr 8;
|
||||
//Call
|
||||
IP := Addr;
|
||||
if IP > $ffef then break;
|
||||
end;
|
||||
|
|
23
readme.md
23
readme.md
|
@ -1,7 +1,7 @@
|
|||
Thingamajig
|
||||
===========
|
||||
|
||||
Thingamajig is a RISC-y and MISC-y hobbyist computer architecture. Its
|
||||
Thingamajig is a RISC-y and MISC-y homebrew computer architecture. Its
|
||||
git repository can be found at
|
||||
https://ahti.space/git/crazyettin/Thingamajig.
|
||||
|
||||
|
@ -14,10 +14,10 @@ Registers and Memory
|
|||
* 8-bit memory addresses 0-FFFF
|
||||
|
||||
Multi-byte values are big-endian. Memory addresses FFF0-FFFF are
|
||||
reserved for memory mapped devices. The instruction and return pointers
|
||||
cannot have values higher than FFEF and FFF0 respectively to avoid the
|
||||
reserved addresses. The instruction and return pointers are initialised
|
||||
as 0 and FFF0 respectively; other registers and memory are unitialised.
|
||||
reserved for memory mapped devices; the instruction and return pointers
|
||||
cannot have values higher than FFEF and FFF0 respectively to avoid them.
|
||||
The instruction and return pointers are initialised as 0 and FFF0
|
||||
respectively, while other registers and memory are unitialised.
|
||||
|
||||
Instructions
|
||||
------------
|
||||
|
@ -27,7 +27,7 @@ Instructions without an address argument are 8-bit and those with one
|
|||
modified.
|
||||
|
||||
0 HALT
|
||||
1 RET IP = *RP; RP += 1
|
||||
1 RET IP = *RP; RP += 2
|
||||
|
||||
2 SHL RX RX <<= 1 Logical shifts
|
||||
3 SHR RX RX >>= 1
|
||||
|
@ -46,15 +46,14 @@ B STORE RX, ADDR *ADDR = RX Written as "STORE ADDR, RX" in
|
|||
|
||||
C BREQ RX, RY, ADDR if (RX == RY) IP = ADDR
|
||||
D BRNEQ RX, RY, ADDR if (RX != RY) IP = ADDR
|
||||
E CLEQ RX, RY, ADDR if (RX == RY) {RP -= 1; *RP = IP; IP = ADDR}
|
||||
F CLNEQ RX, RY, ADDR if (RX != RY) {RP -= 1; *RP = IP; IP = ADDR}
|
||||
E CLEQ RX, RY, ADDR if (RX == RY) {RP -= 2; *RP = IP; IP = ADDR}
|
||||
F CLNEQ RX, RY, ADDR if (RX != RY) {RP -= 2; *RP = IP; IP = ADDR}
|
||||
|
||||
Memory-Mapped Devices
|
||||
---------------------
|
||||
|
||||
Input (when read from) and output (when written to) are mapped to
|
||||
address FFFF. The emulator implements this by emulating a dumb serial
|
||||
terminal.
|
||||
address FFFF. The emulator emulates a dumb terminal for this.
|
||||
|
||||
Arbitrary devices can be mapped to the other reserved addresses.
|
||||
|
||||
|
@ -62,5 +61,5 @@ Initial Program Loader
|
|||
----------------------
|
||||
|
||||
At boot the initial program loader loads a program to the memory
|
||||
starting from address 0 after which is cedes control to the processor.
|
||||
The emulator loads the program from a file.
|
||||
starting from address 0 after which is cedes control to the CPU. The
|
||||
emulator loads the program from a file.
|
||||
|
|
Loading…
Reference in New Issue