Release 0.1.0

This commit is contained in:
Jeremiah Orians 2018-03-20 20:45:33 -04:00
parent 35d15cf61d
commit f513b3f6ac
No known key found for this signature in database
GPG Key ID: 7457821534D2ACCD
20 changed files with 1220 additions and 1666 deletions

View File

@ -25,6 +25,10 @@ Performance tuned hex1 to reduce both size and instruction count
Performance tuned hex0 to reduce both size and instruction count Performance tuned hex0 to reduce both size and instruction count
Performance tuned hex2 to reduce both size and isntruction count Performance tuned hex2 to reduce both size and isntruction count
The stage0 vm now halts on ALL invalid instructions The stage0 vm now halts on ALL invalid instructions
Displacements in the Stage0-vm no longer match that of the Knight hardware platform; instead of from the start of the instruction, from the end of the immediate to the target address.
The Stage0-vm has relocated the 2OPI and 1OPI instructions and adjusted their encodings accordingly to simplify instruction size logic.
The Skip class instructions now lookup the first byte of the instruction that follows them and skips the appropriate size instead of 4 bytes always.
The assembler, disassembler and definitions files were adjusted accordingly
** Fixed ** Fixed
Fixed behavior of R@ thanks to reepca Fixed behavior of R@ thanks to reepca

View File

@ -329,84 +329,84 @@ void assemble(struct Token* p)
setExpression(p, "POPPC", "0D02001", 4); setExpression(p, "POPPC", "0D02001", 4);
/* 2OPI Group */ /* 2OPI Group */
setExpression(p, "ADDI", "0E", 4); setExpression(p, "ADDI", "E1000E", 6);
setExpression(p, "ADDUI", "0F", 4); setExpression(p, "ADDUI", "E1000F", 6);
setExpression(p, "SUBI", "10", 4); setExpression(p, "SUBI", "E10010", 6);
setExpression(p, "SUBUI", "11", 4); setExpression(p, "SUBUI", "E10011", 6);
setExpression(p, "CMPI", "12", 4); setExpression(p, "CMPI", "E10012", 6);
setExpression(p, "LOAD", "13", 4); setExpression(p, "LOAD", "E10013", 6);
setExpression(p, "LOAD8", "14", 4); setExpression(p, "LOAD8", "E10014", 6);
setExpression(p, "LOADU8", "15", 4); setExpression(p, "LOADU8", "E10015", 6);
setExpression(p, "LOAD16", "16", 4); setExpression(p, "LOAD16", "E10016", 6);
setExpression(p, "LOADU16", "17", 4); setExpression(p, "LOADU16", "E10017", 6);
setExpression(p, "LOAD32", "18", 4); setExpression(p, "LOAD32", "E10018", 6);
setExpression(p, "LOADU32", "19", 4); setExpression(p, "LOADU32", "E10019", 6);
setExpression(p, "CMPUI", "1F", 4); setExpression(p, "CMPUI", "E1001F", 6);
setExpression(p, "STORE", "20", 4); setExpression(p, "STORE", "E10020", 6);
setExpression(p, "STORE8", "21", 4); setExpression(p, "STORE8", "E10021", 6);
setExpression(p, "STORE16", "22", 4); setExpression(p, "STORE16", "E10022", 6);
setExpression(p, "STORE32", "23", 4); setExpression(p, "STORE32", "E10023", 6);
setExpression(p, "ANDI", "B0", 4); setExpression(p, "ANDI", "E100B0", 6);
setExpression(p, "ORI", "B1", 4); setExpression(p, "ORI", "E100B1", 6);
setExpression(p, "XORI", "B2", 4); setExpression(p, "XORI", "E100B2", 6);
setExpression(p, "NANDI", "B3", 4); setExpression(p, "NANDI", "E100B3", 6);
setExpression(p, "NORI", "B4", 4); setExpression(p, "NORI", "E100B4", 6);
setExpression(p, "XNORI", "B5", 4); setExpression(p, "XNORI", "E100B5", 6);
setExpression(p, "CMPJUMPI.G", "C0", 4); setExpression(p, "CMPJUMPI.G", "E100C0", 6);
setExpression(p, "CMPJUMPI.GE", "C1", 4); setExpression(p, "CMPJUMPI.GE", "E100C1", 6);
setExpression(p, "CMPJUMPI.E", "C2", 4); setExpression(p, "CMPJUMPI.E", "E100C2", 6);
setExpression(p, "CMPJUMPI.NE", "C3", 4); setExpression(p, "CMPJUMPI.NE", "E100C3", 6);
setExpression(p, "CMPJUMPI.LE", "C4", 4); setExpression(p, "CMPJUMPI.LE", "E100C4", 6);
setExpression(p, "CMPJUMPI.L", "C5", 4); setExpression(p, "CMPJUMPI.L", "E100C5", 6);
setExpression(p, "CMPJUMPUI.G", "D0", 4); setExpression(p, "CMPJUMPUI.G", "E100D0", 6);
setExpression(p, "CMPJUMPUI.GE", "D1", 4); setExpression(p, "CMPJUMPUI.GE", "E100D1", 6);
setExpression(p, "CMPJUMPUI.LE", "D4", 4); setExpression(p, "CMPJUMPUI.LE", "E100D4", 6);
setExpression(p, "CMPJUMPUI.L", "D5", 4); setExpression(p, "CMPJUMPUI.L", "E100D5", 6);
/* 1OPI Group */ /* 1OPI Group */
setExpression(p, "JUMP.C", "2C0", 4); setExpression(p, "JUMP.C", "E0002C0", 6);
setExpression(p, "JUMP.B", "2C1", 4); setExpression(p, "JUMP.B", "E0002C1", 6);
setExpression(p, "JUMP.O", "2C2", 4); setExpression(p, "JUMP.O", "E0002C2", 6);
setExpression(p, "JUMP.G", "2C3", 4); setExpression(p, "JUMP.G", "E0002C3", 6);
setExpression(p, "JUMP.GE", "2C4", 4); setExpression(p, "JUMP.GE", "E0002C4", 6);
setExpression(p, "JUMP.E", "2C5", 4); setExpression(p, "JUMP.E", "E0002C5", 6);
setExpression(p, "JUMP.NE", "2C6", 4); setExpression(p, "JUMP.NE", "E0002C6", 6);
setExpression(p, "JUMP.LE", "2C7", 4); setExpression(p, "JUMP.LE", "E0002C7", 6);
setExpression(p, "JUMP.L", "2C8", 4); setExpression(p, "JUMP.L", "E0002C8", 6);
setExpression(p, "JUMP.Z", "2C9", 4); setExpression(p, "JUMP.Z", "E0002C9", 6);
setExpression(p, "JUMP.NZ", "2CA", 4); setExpression(p, "JUMP.NZ", "E0002CA", 6);
setExpression(p, "JUMP.P", "2CB", 4); setExpression(p, "JUMP.P", "E0002CB", 6);
setExpression(p, "JUMP.NP", "2CC", 4); setExpression(p, "JUMP.NP", "E0002CC", 6);
setExpression(p, "CALLI", "2D0", 4); setExpression(p, "CALLI", "E0002D0", 6);
setExpression(p, "LOADI", "2D1", 4); setExpression(p, "LOADI", "E0002D1", 6);
setExpression(p, "LOADUI", "2D2", 4); setExpression(p, "LOADUI", "E0002D2", 6);
setExpression(p, "SALI", "2D3", 4); setExpression(p, "SALI", "E0002D3", 6);
setExpression(p, "SARI", "2D4", 4); setExpression(p, "SARI", "E0002D4", 6);
setExpression(p, "SL0I", "2D5", 4); setExpression(p, "SL0I", "E0002D5", 6);
setExpression(p, "SR0I", "2D6", 4); setExpression(p, "SR0I", "E0002D6", 6);
setExpression(p, "SL1I", "2D7", 4); setExpression(p, "SL1I", "E0002D7", 6);
setExpression(p, "SR1I", "2D8", 4); setExpression(p, "SR1I", "E0002D8", 6);
setExpression(p, "LOADR", "2E0", 4); setExpression(p, "LOADR", "E0002E0", 6);
setExpression(p, "LOADR8", "2E1", 4); setExpression(p, "LOADR8", "E0002E1", 6);
setExpression(p, "LOADRU8", "2E2", 4); setExpression(p, "LOADRU8", "E0002E2", 6);
setExpression(p, "LOADR16", "2E3", 4); setExpression(p, "LOADR16", "E0002E3", 6);
setExpression(p, "LOADRU16", "2E4", 4); setExpression(p, "LOADRU16", "E0002E4", 6);
setExpression(p, "LOADR32", "2E5", 4); setExpression(p, "LOADR32", "E0002E5", 6);
setExpression(p, "LOADRU32", "2E6", 4); setExpression(p, "LOADRU32", "E0002E6", 6);
setExpression(p, "STORER", "2F0", 4); setExpression(p, "STORER", "E0002F0", 6);
setExpression(p, "STORER8", "2F1", 4); setExpression(p, "STORER8", "E0002F1", 6);
setExpression(p, "STORER16", "2F2", 4); setExpression(p, "STORER16", "E0002F2", 6);
setExpression(p, "STORER32", "2F3", 4); setExpression(p, "STORER32", "E0002F3", 6);
setExpression(p, "CMPSKIPI.G", "A00", 4); setExpression(p, "CMPSKIPI.G", "E000A00", 6);
setExpression(p, "CMPSKIPI.GE", "A01", 4); setExpression(p, "CMPSKIPI.GE", "E000A01", 6);
setExpression(p, "CMPSKIPI.E", "A02", 4); setExpression(p, "CMPSKIPI.E", "E000A02", 6);
setExpression(p, "CMPSKIPI.NE", "A03", 4); setExpression(p, "CMPSKIPI.NE", "E000A03", 6);
setExpression(p, "CMPSKIPI.LE", "A04", 4); setExpression(p, "CMPSKIPI.LE", "E000A04", 6);
setExpression(p, "CMPSKIPI.L", "A05", 4); setExpression(p, "CMPSKIPI.L", "E000A05", 6);
setExpression(p, "CMPSKIPUI.G", "A10", 4); setExpression(p, "CMPSKIPUI.G", "E000A10", 6);
setExpression(p, "CMPSKIPUI.GE", "A11", 4); setExpression(p, "CMPSKIPUI.GE", "E000A11", 6);
setExpression(p, "CMPSKIPUI.LE", "A14", 4); setExpression(p, "CMPSKIPUI.LE", "E000A14", 6);
setExpression(p, "CMPSKIPUI.L", "A15", 4); setExpression(p, "CMPSKIPUI.L", "E000A15", 6);
/* 0OPI Group */ /* 0OPI Group */
setExpression(p, "JUMP", "3C00", 4); setExpression(p, "JUMP", "3C00", 4);
@ -483,7 +483,7 @@ void update_jumps(struct Token* head, struct Token* p)
if('@' == p->Text[0]) if('@' == p->Text[0])
{ {
int16_t dist = 0; int16_t dist = 0;
dist = dest - p->address + 4; dist = dest - p->address;
sprintf(p->Expression, "%04x", (uint16_t)dist); sprintf(p->Expression, "%04x", (uint16_t)dist);
} }

View File

@ -156,84 +156,84 @@ DEFINE PUSHPC 0D02000
DEFINE POPPC 0D02001 DEFINE POPPC 0D02001
# 2OPI Group # 2OPI Group
DEFINE ADDI 0E DEFINE ADDI E1000E
DEFINE ADDUI 0F DEFINE ADDUI E1000F
DEFINE SUBI 10 DEFINE SUBI E10010
DEFINE SUBUI 11 DEFINE SUBUI E10011
DEFINE CMPI 12 DEFINE CMPI E10012
DEFINE LOAD 13 DEFINE LOAD E10013
DEFINE LOAD8 14 DEFINE LOAD8 E10014
DEFINE LOADU8 15 DEFINE LOADU8 E10015
DEFINE LOAD16 16 DEFINE LOAD16 E10016
DEFINE LOADU16 17 DEFINE LOADU16 E10017
DEFINE LOAD32 18 DEFINE LOAD32 E10018
DEFINE LOADU32 19 DEFINE LOADU32 E10019
DEFINE CMPUI 1F DEFINE CMPUI E1001F
DEFINE STORE 20 DEFINE STORE E10020
DEFINE STORE8 21 DEFINE STORE8 E10021
DEFINE STORE16 22 DEFINE STORE16 E10022
DEFINE STORE32 23 DEFINE STORE32 E10023
DEFINE ANDI B0 DEFINE ANDI E100B0
DEFINE ORI B1 DEFINE ORI E100B1
DEFINE XORI B2 DEFINE XORI E100B2
DEFINE NANDI B3 DEFINE NANDI E100B3
DEFINE NORI B4 DEFINE NORI E100B4
DEFINE XNORI B5 DEFINE XNORI E100B5
DEFINE CMPJUMPI.G C0 DEFINE CMPJUMPI.G E100C0
DEFINE CMPJUMPI.GE C1 DEFINE CMPJUMPI.GE E100C1
DEFINE CMPJUMPI.E C2 DEFINE CMPJUMPI.E E100C2
DEFINE CMPJUMPI.NE C3 DEFINE CMPJUMPI.NE E100C3
DEFINE CMPJUMPI.LE C4 DEFINE CMPJUMPI.LE E100C4
DEFINE CMPJUMPI.L C5 DEFINE CMPJUMPI.L E100C5
DEFINE CMPJUMPUI.G D0 DEFINE CMPJUMPUI.G E100D0
DEFINE CMPJUMPUI.GE D1 DEFINE CMPJUMPUI.GE E100D1
DEFINE CMPJUMPUI.LE D4 DEFINE CMPJUMPUI.LE E100D4
DEFINE CMPJUMPUI.L D5 DEFINE CMPJUMPUI.L E100D5
# 1OPI Group # 1OPI Group
DEFINE JUMP.C 2C0 DEFINE JUMP.C E0002C0
DEFINE JUMP.B 2C1 DEFINE JUMP.B E0002C1
DEFINE JUMP.O 2C2 DEFINE JUMP.O E0002C2
DEFINE JUMP.G 2C3 DEFINE JUMP.G E0002C3
DEFINE JUMP.GE 2C4 DEFINE JUMP.GE E0002C4
DEFINE JUMP.E 2C5 DEFINE JUMP.E E0002C5
DEFINE JUMP.NE 2C6 DEFINE JUMP.NE E0002C6
DEFINE JUMP.LE 2C7 DEFINE JUMP.LE E0002C7
DEFINE JUMP.L 2C8 DEFINE JUMP.L E0002C8
DEFINE JUMP.Z 2C9 DEFINE JUMP.Z E0002C9
DEFINE JUMP.NZ 2CA DEFINE JUMP.NZ E0002CA
DEFINE JUMP.P 2CB DEFINE JUMP.P E0002CB
DEFINE JUMP.NP 2CC DEFINE JUMP.NP E0002CC
DEFINE CALLI 2D0 DEFINE CALLI E0002D0
DEFINE LOADI 2D1 DEFINE LOADI E0002D1
DEFINE LOADUI 2D2 DEFINE LOADUI E0002D2
DEFINE SALI 2D3 DEFINE SALI E0002D3
DEFINE SARI 2D4 DEFINE SARI E0002D4
DEFINE SL0I 2D5 DEFINE SL0I E0002D5
DEFINE SR0I 2D6 DEFINE SR0I E0002D6
DEFINE SL1I 2D7 DEFINE SL1I E0002D7
DEFINE SR1I 2D8 DEFINE SR1I E0002D8
DEFINE LOADR 2E0 DEFINE LOADR E0002E0
DEFINE LOADR8 2E1 DEFINE LOADR8 E0002E1
DEFINE LOADRU8 2E2 DEFINE LOADRU8 E0002E2
DEFINE LOADR16 2E3 DEFINE LOADR16 E0002E3
DEFINE LOADRU16 2E4 DEFINE LOADRU16 E0002E4
DEFINE LOADR32 2E5 DEFINE LOADR32 E0002E5
DEFINE LOADRU32 2E6 DEFINE LOADRU32 E0002E6
DEFINE STORER 2F0 DEFINE STORER E0002F0
DEFINE STORER8 2F1 DEFINE STORER8 E0002F1
DEFINE STORER16 2F2 DEFINE STORER16 E0002F2
DEFINE STORER32 2F3 DEFINE STORER32 E0002F3
DEFINE CMPSKIPI.G A00 DEFINE CMPSKIPI.G E000A00
DEFINE CMPSKIPI.GE A01 DEFINE CMPSKIPI.GE E000A01
DEFINE CMPSKIPI.E A02 DEFINE CMPSKIPI.E E000A02
DEFINE CMPSKIPI.NE A03 DEFINE CMPSKIPI.NE E000A03
DEFINE CMPSKIPI.LE A04 DEFINE CMPSKIPI.LE E000A04
DEFINE CMPSKIPI.L A05 DEFINE CMPSKIPI.L E000A05
DEFINE CMPSKIPUI.G A10 DEFINE CMPSKIPUI.G E000A10
DEFINE CMPSKIPUI.GE A11 DEFINE CMPSKIPUI.GE E000A11
DEFINE CMPSKIPUI.LE A14 DEFINE CMPSKIPUI.LE E000A14
DEFINE CMPSKIPUI.L A15 DEFINE CMPSKIPUI.L E000A15
# 0OPI Group # 0OPI Group
DEFINE JUMP 3C00 DEFINE JUMP 3C00

View File

@ -31,7 +31,7 @@ struct Instruction
char opcode[3]; char opcode[3];
uint32_t raw_XOP; uint32_t raw_XOP;
char XOP[6]; char XOP[6];
char operation[9]; char operation[13];
int16_t raw_Immediate; int16_t raw_Immediate;
char Immediate[7]; char Immediate[7];
uint32_t HAL_CODE; uint32_t HAL_CODE;
@ -865,19 +865,25 @@ void decode_0OP(struct Instruction* c)
void decode_Integer_2OPI(struct Instruction* c) void decode_Integer_2OPI(struct Instruction* c)
{ {
/* Parse Raw Data */ /* Get Immediate pieces */
c->raw_Immediate = c->raw2*0x100 + c->raw3; c->raw_Immediate = fgetc(binary_file);
c->Immediate[0] = c->operation[4]; int a = fgetc(binary_file);
c->Immediate[1] = c->operation[5];
c->Immediate[2] = c->operation[6]; /* Unpack immediate */
c->Immediate[3] = c->operation[7]; unpack_byte(c->raw_Immediate, &(c->operation[8]));
c->reg0 = c->raw1/16; unpack_byte(a, &(c->operation[10]));
c->reg1 = c->raw1%16;
/* Process registers and immediate */
c->raw_Immediate = c->raw_Immediate * 0x100 + a;
c->reg0 = c->raw3/16;
c->reg1 = c->raw3%16;
char Name[20] = "ILLEGAL_2OPI"; char Name[20] = "ILLEGAL_2OPI";
if(c->raw1 != 0) goto broken_2OPI;
/* Convert to Human readable form */ /* Convert to Human readable form */
switch(c->raw0) switch(c->raw2)
{ {
case 0x0E: /* ADDI */ case 0x0E: /* ADDI */
{ {
@ -1046,6 +1052,7 @@ void decode_Integer_2OPI(struct Instruction* c)
} }
default: /* Unknown 2OPI*/ default: /* Unknown 2OPI*/
{ {
broken_2OPI:
string_values(c, true); string_values(c, true);
return; return;
} }
@ -1057,19 +1064,23 @@ void decode_Integer_2OPI(struct Instruction* c)
void decode_1OPI(struct Instruction* c) void decode_1OPI(struct Instruction* c)
{ {
/* Get Immediate pieces */
c->raw_Immediate = fgetc(binary_file);
int a = fgetc(binary_file);
/* Unpack immediate */
unpack_byte(c->raw_Immediate, &(c->operation[8]));
unpack_byte(a, &(c->operation[10]));
/* Parse Raw Data */ /* Parse Raw Data */
c->raw_Immediate = c->raw2*0x100 + c->raw3; c->raw_Immediate = c->raw_Immediate*0x100 + a;
c->Immediate[0] = c->operation[3]; c->raw_XOP = c->raw3/16;
c->Immediate[1] = c->operation[4]; c->reg0 = c->raw3%16;
c->Immediate[2] = c->operation[5];
c->Immediate[3] = c->operation[6];
c->Immediate[4] = c->operation[7];
c->HAL_CODE = 0;
c->raw_XOP = c->raw1/16;
c->reg0 = c->raw1%16;
char Name[20] = "ILLEGAL_1OPI"; char Name[20] = "ILLEGAL_1OPI";
uint32_t Opcode = (c->raw0 * 16) + c->raw_XOP; uint32_t Opcode = (c->raw2 * 16) + c->raw_XOP;
if(0 != c->raw1) goto Broken_1OPI;
/* Convert to Human readable form */ /* Convert to Human readable form */
switch(Opcode) switch(Opcode)
@ -1291,6 +1302,7 @@ void decode_1OPI(struct Instruction* c)
} }
default: /* Unknown 1OPI*/ default: /* Unknown 1OPI*/
{ {
Broken_1OPI:
string_values(c, true); string_values(c, true);
return; return;
} }
@ -1403,54 +1415,62 @@ void eval_instruction(struct Instruction* c)
case 0x01: /* Integer 4OP */ case 0x01: /* Integer 4OP */
{ {
decode_Integer_4OP(c); decode_Integer_4OP(c);
address = address + 4;
break; break;
} }
case 0x05: /* Integer 3OP */ case 0x05: /* Integer 3OP */
{ {
decode_Integer_3OP(c); decode_Integer_3OP(c);
address = address + 4;
break; break;
} }
case 0x09: /* Integer 2OP */ case 0x09: /* Integer 2OP */
{ {
decode_Integer_2OP(c); decode_Integer_2OP(c);
address = address + 4;
break; break;
} }
case 0x0D: /* 1OP */ case 0x0D: /* 1OP */
{ {
decode_1OP(c); decode_1OP(c);
break; address = address + 4;
}
case 0x0E ... 0x2B: /* 2OPI */
case 0xB0 ... 0xDF:
{
decode_Integer_2OPI(c);
break;
}
case 0x2C ... 0x2F: /* 1OPI */
case 0xA0 ... 0xA1:
{
decode_1OPI(c);
break; break;
} }
case 0x3C: /* Core 0OPI */ case 0x3C: /* Core 0OPI */
{ {
decode_0OPI(c); decode_0OPI(c);
address = address + 4;
break; break;
} }
case 0x42: /* HALCODE */ case 0x42: /* HALCODE */
{ {
decode_HALCODE(c); decode_HALCODE(c);
address = address + 4;
break;
}
case 0xE1: /* 2OPI */
{
decode_Integer_2OPI(c);
address = address + 6;
break;
}
case 0xE0: /* 1OPI */
{
decode_1OPI(c);
address = address + 6;
break; break;
} }
case 0x00: /* NOP */ case 0x00: /* NOP */
case 0xFF: /* HALT */ case 0xFF: /* HALT */
{ {
decode_0OP(c); decode_0OP(c);
address = address + 4;
break; break;
} }
default: /* Not supported by this disassembler */ default: /* Not supported by this disassembler */
{ {
string_values(c, true); string_values(c, true);
address = address + 4;
return; return;
} }
} }
@ -1479,7 +1499,6 @@ int main(int argc, char **argv)
{ {
read_instruction(current); read_instruction(current);
eval_instruction(current); eval_instruction(current);
address = address + 4;
byte = fgetc(binary_file); byte = fgetc(binary_file);
ungetc(byte, binary_file); ungetc(byte, binary_file);
} }

View File

@ -69,6 +69,8 @@ this is primarily used for pointer comparisons involving hand encoded objects.
For pointers starting with &, it is assumed that the user wants the 32bit absolute address of the label; For pointers starting with &, it is assumed that the user wants the 32bit absolute address of the label;
this is primarily for hand encoding objects or instructions that want 32bit absolute addresses this is primarily for hand encoding objects or instructions that want 32bit absolute addresses
Should one wish to manually calculate the displacement field of an instruction, simply subtract the address of the byte after the immediate from the address of the target.
*** More advanced? *** More advanced?
It is possible for a hex2 assembler to support more than just the minimal set as defined above and is frequently the case on complicated instruction sets. It is possible for a hex2 assembler to support more than just the minimal set as defined above and is frequently the case on complicated instruction sets.
However, to be considered hex2 compliant a program should not depend on those additions. However, to be considered hex2 compliant a program should not depend on those additions.
@ -429,135 +431,6 @@ The Opcodes will be preserved should we wish in the future to be binary compatab
| ... | Reserved | | ... | Reserved |
| 0D FF FF Fx | Reserved | | 0D FF FF Fx | Reserved |
** 2OPI Groups
2OPI ii ii is the Immediate, a = b OP ii ii
*** 2OPI Integer
| Hex | Name | Comment |
|-------------+-----------------+--------------------------|
| 0E ab ii ii | ADDI a b ii ii | a = b + ii ii [signed] |
| 0F ab ii ii | ADDUI a b ii ii | a = b + ii ii [unsigned] |
| 10 ab ii ii | SUBI a b ii ii | a = b - ii ii [signed] |
| 11 ab ii ii | SUBUI a b ii ii | a = b - ii ii [unsigned] |
*** 2OPI Integer signed compare
| Hex | Name | Comment |
|-------------+----------------+--------------------------|
| 12 ab ii ii | CMPI a b ii ii | a = b CMP ii ii [signed] |
*** 2OPI Integer Load
| Hex | Name | Comment |
|-------------+-------------------+--------------------------------------|
| 13 ab ii ii | LOAD a b ii ii | a = MEM[b + ii ii] |
| 14 ab ii ii | LOAD8 a b ii ii | a = MEM[b + ii ii] [signed 8bits] |
| 15 ab ii ii | LOADU8 a b ii ii | a = MEM[b + ii ii] [unsigned 8bits] |
| 16 ab ii ii | LOAD16 a b ii ii | a = MEM[b + ii ii] [signed 16bits] |
| 17 ab ii ii | LOADU16 a b ii ii | a = MEM[b + ii ii] [unsigned 16bits] |
| 18 ab ii ii | LOAD32 a b ii ii | a = MEM[b + ii ii] [signed 32bits] |
| 19 ab ii ii | LOADU32 a b ii ii | a = MEM[b + ii ii] [unsigned 32bits] |
| 1A ab ii ii | Reserved | |
| 1B ab ii ii | Reserved | |
| 1C ab ii ii | Reserved | |
| 1D ab ii ii | Reserved | |
| 1E ab ii ii | Reserved | |
*** 2OPI Integer unsigned compare
| Hex | Name | Comment |
|-------------+-----------------+----------------------------|
| 1F ab ii ii | CMPUI a b ii ii | a = b CMP ii ii [unsigned] |
*** 2OPI Integer store
| Hex | Name | Comment |
|-------------+----------------+------------------------------------|
| 20 ab ii ii | STORE a b ii | MEM[b + ii ii] = a |
| 21 ab ii ii | STORE8 a b ii | MEM[b + ii ii] = a [signed 8bits] |
| 22 ab ii ii | STORE16 a b ii | MEM[b + ii ii] = a [signed 16bits] |
| 23 ab ii ii | STORE32 a b ii | MEM[b + ii ii] = a [signed 32bits] |
| 24 ab ii ii | Reserved | |
| 25 ab ii ii | Reserved | |
| 26 ab ii ii | Reserved | |
| 27 ab ii ii | Reserved | |
| 28 ab ii ii | Reserved | |
| 29 ab ii ii | Reserved | |
| 2A ab ii ii | Reserved | |
| 2B ab ii ii | Reserved | |
** 1OPI Groups
1OPI i ii ii is the Immediate, a = a OP i ii ii
*** Conditional Integer Jumps
| Hex | Name | Comment |
|-------------+-----------------+--------------------------------------|
| 2C 0a ii ii | JUMP.C a ii ii | Carry? a; PC = PC + i ii ii |
| 2C 1a ii ii | JUMP.B a ii ii | Borrow? a; PC = PC + i ii ii |
| 2C 2a ii ii | JUMP.O a ii ii | Overflow? a; PC = PC + i ii ii |
| 2C 3a ii ii | JUMP.G a ii ii | GT? a; PC = PC + i ii ii |
| 2C 4a ii ii | JUMP.GE a ii ii | GT? a \vert EQ? a; PC = PC + i ii ii |
| 2C 5a ii ii | JUMP.E a ii ii | EQ? a; PC = PC + i ii ii |
| 2C 6a ii ii | JUMP.NE a ii ii | NEQ? a; PC = PC + i ii ii |
| 2C 7a ii ii | JUMP.LE a ii ii | LT? a \vert EQ? a; PC = PC + i ii ii |
| 2C 8a ii ii | JUMP.L a ii ii | LT? a; PC = PC + i ii ii |
| 2C 9a ii ii | JUMP.Z a ii ii | ZERO? a; PC = PC + i ii ii |
| 2C Aa ii ii | JUMP.NZ a ii ii | NZERO? a; PC = PC + i ii ii |
| 2C Ba ii ii | JUMP.P | POSITIVE? a; PC = PC + ii ii |
| 2C Ca ii ii | JUMP.NP | NEGATIVE? a; PC = PC + ii ii |
| 2C Dx xx xx | Reserved | |
| 2C Ex xx xx | Reserved | |
| 2C Fx xx xx | Reserved | |
*** Branch Immediates
| Hex | Name | Comment |
|-------------+----------------+----------------------------------------------------------------|
| 2D 0a ii ii | CALLI a ii ii | MEM[a] = PC; a = a + (register size in bytes); PC = PC + ii ii |
| 2D 1a ii ii | LOADI a ii ii | a = ii ii (signed) |
| 2D 2a ii ii | LOADUI a ii ii | a = ii ii (unsigned) |
| 2D 3a ii ii | SALI a ii ii | a = a << ii ii [arithmetically] |
| 2D 4a ii ii | SARI a ii ii | a = a >> ii ii [arithmetically] |
| 2D 5a ii ii | SL0I a ii ii | a = a << ii ii [Fill with zeros] |
| 2D 6a ii ii | SR0I a ii ii | a = a >> ii ii [Fill with zeros] |
| 2D 7a ii ii | SL1I a ii ii | a = a << ii ii [Fill with ones] |
| 2D 8a ii ii | SR1I a ii ii | a = a >> ii ii [Fill with ones] |
*** Relative Loads
| Hex | Name | Comment |
|-------------+------------------+----------------------------------------|
| 2E 0a ii ii | LOADR a ii ii | a = MEM[ip + ii ii] |
| 2E 1a ii ii | LOADR8 a ii ii | a = MEM[ip + ii ii] [signed 8 bits] |
| 2E 2a ii ii | LOADRU8 a ii ii | a = MEM[ip + ii ii] [unsigned 8 bits] |
| 2E 3a ii ii | LOADR16 a ii ii | a = MEM[ip + ii ii] [signed 16 bits] |
| 2E 4a ii ii | LOADRU16 a ii ii | a = MEM[ip + ii ii] [unsigned 16 bits] |
| 2E 5a ii ii | LOADR32 a ii ii | a = MEM[ip + ii ii] [signed 32 bits] |
| 2E 6a ii ii | LOADRU32 a ii ii | a = MEM[ip + ii ii] [unsigned 32 bits] |
| 2E 7a ii ii | Reserved | |
| 2E 8a ii ii | Reserved | |
| 2E 9a ii ii | Reserved | |
| 2E Aa ii ii | Reserved | |
| 2E Ba ii ii | Reserved | |
| 2E Ca ii ii | Reserved | |
| 2E Da ii ii | Reserved | |
| 2E Ea ii ii | Reserved | |
| 2E Fa ii ii | Reserved | |
*** Relative Stores
| Hex | Name | Comment |
|-------------+------------------+--------------------------------------|
| 2F 0a ii ii | STORER a ii ii | MEM[ip + ii ii] = a |
| 2F 1a ii ii | STORER8 a ii ii | MEM[ip + ii ii] = a [signed 8 bits] |
| 2F 2a ii ii | STORER16 a ii ii | MEM[ip + ii ii] = a [signed 16 bits] |
| 2F 3a ii ii | STORER32 a ii ii | MEM[ip + ii ii] = a [signed 32 bits] |
| 2F 4a ii ii | Reserved | |
| 2F 5a ii ii | Reserved | |
| 2F 6a ii ii | Reserved | |
| 2F 7a ii ii | Reserved | |
| 2F 8a ii ii | Reserved | |
| 2F 9a ii ii | Reserved | |
| 2F Aa ii ii | Reserved | |
| 2F Ba ii ii | Reserved | |
| 2F Ca ii ii | Reserved | |
| 2F Da ii ii | Reserved | |
| 2F Ea ii ii | Reserved | |
| 2F Fa ii ii | Reserved | |
** 0OPI group ** 0OPI group
0OPI ii ii is the Immediate, OP ii ii 0OPI ii ii is the Immediate, OP ii ii
@ -674,37 +547,6 @@ DO NOT USE.
|-------------+----------| |-------------+----------|
| 43 00 00 00 | Reserved | | 43 00 00 00 | Reserved |
| ... | Reserved | | ... | Reserved |
| 9F FF FF FF | Reserved |
** CMPSKIPI Group
| Hex | Name | Comment |
|-------------+----------------------+------------------------------------|
| A0 0a ii ii | CMPSKIPI.G a ii ii | a > ii ii ? Skip Next instruction |
| A0 1a ii ii | CMPSKIPI.GE a ii ii | a >= ii ii ? Skip Next instruction |
| A0 2a ii ii | CMPSKIPI.E a ii ii | a == ii ii ? Skip Next instruction |
| A0 3a ii ii | CMPSKIPI.NE a ii ii | a != ii ii ? Skip Next instruction |
| A0 4a ii ii | CMPSKIPI.LE a ii ii | a <= ii ii ? Skip Next instruction |
| A0 5a ii ii | CMPSKIPI.L a ii ii | a < ii ii ? Skip Next instruction |
| A0 6a ii ii | Reserved | |
| ... | Reserved | |
| A0 Fa ii ii | Reserved | |
| A1 0a ii ii | CMPSKIPUI.G a ii ii | a > ii ii ? Skip Next instruction |
| A1 1a ii ii | CMPSKIPUI.GE a ii ii | a >= ii ii ? Skip Next instruction |
| A1 2a ii ii | Reserved | |
| A1 3a ii ii | Reserved | |
| A1 4a ii ii | CMPSKIPUI.LE a ii ii | a <= ii ii ? Skip Next instruction |
| A1 5a ii ii | CMPSKIPUI.L a ii ii | a < ii ii ? Skip Next instruction |
| A1 6a ii ii | Reserved | |
| ... | Reserved | |
| A1 Fa ii ii | Reserved | |
** Reserved Block 2
At this time these instructions only produce a warning; but could do anything.
DO NOT USE.
| Hex | Name |
|-------------+----------|
| A2 00 00 00 | Reserved |
| ... | Reserved |
| AF FF FF FF | Reserved | | AF FF FF FF | Reserved |
** Bit optimization group ** Bit optimization group
@ -720,36 +562,198 @@ DO NOT USE.
| ... | Reserved | | | ... | Reserved | |
| BF FF FF FF | Reserved | | | BF FF FF FF | Reserved | |
** CMPJUMPI Group ** Extended instruction block
| Hex | Name | Comment | This block specified for instructions that require immediates
|-------------+------------------------+-------------------------------------| *** 1OPI Groups
| C0 ab ii ii | CMPJUMPI.G a b ii ii | a > b ? PC = PC + ii ii | 1OPI i ii ii is the Immediate, a = a OP i ii ii
| C1 ab ii ii | CMPJUMPI.GE a b ii ii | a >= b ? PC = PC + ii ii |
| C2 ab ii ii | CMPJUMPI.E a b ii ii | a == b ? PC = PC + ii ii |
| C3 ab ii ii | CMPJUMPI.NE a b ii ii | a != b ? PC = PC + ii ii |
| C4 ab ii ii | CMPJUMPI.LE a b ii ii | a <= b ? PC = PC + ii ii |
| C5 ab ii ii | CMPJUMPI.L a b ii ii | a < b ? PC = PC + ii ii |
| C6 ab ii ii | Reserved | |
| ... | Reserved | |
| CF ab ii ii | Reserved | |
| D0 ab ii ii | CMPJUMPUI.G a b ii ii | a > b ? PC = PC + ii ii (unsigned) |
| D1 ab ii ii | CMPJUMPUI.GE a b ii ii | a >= b ? PC = PC + ii ii (unsigned) |
| D2 ab ii ii | Reserved | |
| D3 ab ii ii | Reserved | |
| D4 ab ii ii | CMPJUMPUI.LE a b ii ii | a <= b ? PC = PC + ii ii (unsigned) |
| D5 ab ii ii | CMPJUMPUI.L a b ii ii | a < b ? PC = PC + ii ii (unsigned) |
| D6 ab ii ii | Reserved | |
| ... | Reserved | |
| DF ab ii ii | Reserved | |
** Reserved Block 3 **** Conditional Integer Jumps
| Hex | Name | Comment |
|-------------------+-----------------+--------------------------------------|
| E0 00 2C 0a ii ii | JUMP.C a ii ii | Carry? a; PC = PC + i ii ii |
| E0 00 2C 1a ii ii | JUMP.B a ii ii | Borrow? a; PC = PC + i ii ii |
| E0 00 2C 2a ii ii | JUMP.O a ii ii | Overflow? a; PC = PC + i ii ii |
| E0 00 2C 3a ii ii | JUMP.G a ii ii | GT? a; PC = PC + i ii ii |
| E0 00 2C 4a ii ii | JUMP.GE a ii ii | GT? a \vert EQ? a; PC = PC + i ii ii |
| E0 00 2C 5a ii ii | JUMP.E a ii ii | EQ? a; PC = PC + i ii ii |
| E0 00 2C 6a ii ii | JUMP.NE a ii ii | NEQ? a; PC = PC + i ii ii |
| E0 00 2C 7a ii ii | JUMP.LE a ii ii | LT? a \vert EQ? a; PC = PC + i ii ii |
| E0 00 2C 8a ii ii | JUMP.L a ii ii | LT? a; PC = PC + i ii ii |
| E0 00 2C 9a ii ii | JUMP.Z a ii ii | ZERO? a; PC = PC + i ii ii |
| E0 00 2C Aa ii ii | JUMP.NZ a ii ii | NZERO? a; PC = PC + i ii ii |
| E0 00 2C Ba ii ii | JUMP.P | POSITIVE? a; PC = PC + ii ii |
| E0 00 2C Ca ii ii | JUMP.NP | NEGATIVE? a; PC = PC + ii ii |
| E0 00 2C Dx xx xx | Reserved | |
| E0 00 2C Ex xx xx | Reserved | |
| E0 00 2C Fx xx xx | Reserved | |
**** Branch Immediates
| Hex | Name | Comment |
|-------------------+----------------+----------------------------------------------------------------|
| E0 00 2D 0a ii ii | CALLI a ii ii | MEM[a] = PC; a = a + (register size in bytes); PC = PC + ii ii |
**** Load Immediates
| Hex | Name | Comment |
|-------------------+----------------+----------------------------------------------------------------|
| E0 00 2D 1a ii ii | LOADI a ii ii | a = ii ii (signed) |
| E0 00 2D 2a ii ii | LOADUI a ii ii | a = ii ii (unsigned) |
**** Shift Immediates
| Hex | Name | Comment |
|-------------------+----------------+----------------------------------------------------------------|
| E0 00 2D 3a ii ii | SALI a ii ii | a = a << ii ii [arithmetically] |
| E0 00 2D 4a ii ii | SARI a ii ii | a = a >> ii ii [arithmetically] |
| E0 00 2D 5a ii ii | SL0I a ii ii | a = a << ii ii [Fill with zeros] |
| E0 00 2D 6a ii ii | SR0I a ii ii | a = a >> ii ii [Fill with zeros] |
| E0 00 2D 7a ii ii | SL1I a ii ii | a = a << ii ii [Fill with ones] |
| E0 00 2D 8a ii ii | SR1I a ii ii | a = a >> ii ii [Fill with ones] |
**** Relative Loads
| Hex | Name | Comment |
|-------------------+------------------+----------------------------------------|
| E0 00 2E 0a ii ii | LOADR a ii ii | a = MEM[ip + ii ii] |
| E0 00 2E 1a ii ii | LOADR8 a ii ii | a = MEM[ip + ii ii] [signed 8 bits] |
| E0 00 2E 2a ii ii | LOADRU8 a ii ii | a = MEM[ip + ii ii] [unsigned 8 bits] |
| E0 00 2E 3a ii ii | LOADR16 a ii ii | a = MEM[ip + ii ii] [signed 16 bits] |
| E0 00 2E 4a ii ii | LOADRU16 a ii ii | a = MEM[ip + ii ii] [unsigned 16 bits] |
| E0 00 2E 5a ii ii | LOADR32 a ii ii | a = MEM[ip + ii ii] [signed 32 bits] |
| E0 00 2E 6a ii ii | LOADRU32 a ii ii | a = MEM[ip + ii ii] [unsigned 32 bits] |
| E0 00 2E 7a ii ii | Reserved | |
| E0 00 2E 8a ii ii | Reserved | |
| E0 00 2E 9a ii ii | Reserved | |
| E0 00 2E Aa ii ii | Reserved | |
| E0 00 2E Ba ii ii | Reserved | |
| E0 00 2E Ca ii ii | Reserved | |
| E0 00 2E Da ii ii | Reserved | |
| E0 00 2E Ea ii ii | Reserved | |
| E0 00 2E Fa ii ii | Reserved | |
**** Relative Stores
| Hex | Name | Comment |
|-------------------+------------------+--------------------------------------|
| E0 00 2F 0a ii ii | STORER a ii ii | MEM[ip + ii ii] = a |
| E0 00 2F 1a ii ii | STORER8 a ii ii | MEM[ip + ii ii] = a [signed 8 bits] |
| E0 00 2F 2a ii ii | STORER16 a ii ii | MEM[ip + ii ii] = a [signed 16 bits] |
| E0 00 2F 3a ii ii | STORER32 a ii ii | MEM[ip + ii ii] = a [signed 32 bits] |
| E0 00 2F 4a ii ii | Reserved | |
| E0 00 2F 5a ii ii | Reserved | |
| E0 00 2F 6a ii ii | Reserved | |
| E0 00 2F 7a ii ii | Reserved | |
| E0 00 2F 8a ii ii | Reserved | |
| E0 00 2F 9a ii ii | Reserved | |
| E0 00 2F Aa ii ii | Reserved | |
| E0 00 2F Ba ii ii | Reserved | |
| E0 00 2F Ca ii ii | Reserved | |
| E0 00 2F Da ii ii | Reserved | |
| E0 00 2F Ea ii ii | Reserved | |
| E0 00 2F Fa ii ii | Reserved | |
**** CMPSKIPI Group
| Hex | Name | Comment |
|-------------------+----------------------+------------------------------------|
| E0 00 A0 0a ii ii | CMPSKIPI.G a ii ii | a > ii ii ? Skip Next instruction |
| E0 00 A0 1a ii ii | CMPSKIPI.GE a ii ii | a >= ii ii ? Skip Next instruction |
| E0 00 A0 2a ii ii | CMPSKIPI.E a ii ii | a == ii ii ? Skip Next instruction |
| E0 00 A0 3a ii ii | CMPSKIPI.NE a ii ii | a != ii ii ? Skip Next instruction |
| E0 00 A0 4a ii ii | CMPSKIPI.LE a ii ii | a <= ii ii ? Skip Next instruction |
| E0 00 A0 5a ii ii | CMPSKIPI.L a ii ii | a < ii ii ? Skip Next instruction |
| E0 00 A0 6a ii ii | Reserved | |
| ... | Reserved | |
| E0 00 A0 Fa ii ii | Reserved | |
| E0 00 A1 0a ii ii | CMPSKIPUI.G a ii ii | a > ii ii ? Skip Next instruction |
| E0 00 A1 1a ii ii | CMPSKIPUI.GE a ii ii | a >= ii ii ? Skip Next instruction |
| E0 00 A1 2a ii ii | Reserved | |
| E0 00 A1 3a ii ii | Reserved | |
| E0 00 A1 4a ii ii | CMPSKIPUI.LE a ii ii | a <= ii ii ? Skip Next instruction |
| E0 00 A1 5a ii ii | CMPSKIPUI.L a ii ii | a < ii ii ? Skip Next instruction |
| E0 00 A1 6a ii ii | Reserved | |
| ... | Reserved | |
| E0 00 A1 Fa ii ii | Reserved | |
*** 2OPI Groups
2OPI ii ii is the Immediate, a = b OP ii ii
**** 2OPI Integer
| Hex | Name | Comment |
|-------------------+-----------------+--------------------------|
| E1 00 0E ab ii ii | ADDI a b ii ii | a = b + ii ii [signed] |
| E1 00 0F ab ii ii | ADDUI a b ii ii | a = b + ii ii [unsigned] |
| E1 00 10 ab ii ii | SUBI a b ii ii | a = b - ii ii [signed] |
| E1 00 11 ab ii ii | SUBUI a b ii ii | a = b - ii ii [unsigned] |
**** 2OPI Integer signed compare
| Hex | Name | Comment |
|-------------------+----------------+--------------------------|
| E1 00 12 ab ii ii | CMPI a b ii ii | a = b CMP ii ii [signed] |
**** 2OPI Integer Load
| Hex | Name | Comment |
|-------------------+-------------------+--------------------------------------|
| E1 00 13 ab ii ii | LOAD a b ii ii | a = MEM[b + ii ii] |
| E1 00 14 ab ii ii | LOAD8 a b ii ii | a = MEM[b + ii ii] [signed 8bits] |
| E1 00 15 ab ii ii | LOADU8 a b ii ii | a = MEM[b + ii ii] [unsigned 8bits] |
| E1 00 16 ab ii ii | LOAD16 a b ii ii | a = MEM[b + ii ii] [signed 16bits] |
| E1 00 17 ab ii ii | LOADU16 a b ii ii | a = MEM[b + ii ii] [unsigned 16bits] |
| E1 00 18 ab ii ii | LOAD32 a b ii ii | a = MEM[b + ii ii] [signed 32bits] |
| E1 00 19 ab ii ii | LOADU32 a b ii ii | a = MEM[b + ii ii] [unsigned 32bits] |
| E1 00 1A ab ii ii | Reserved | |
| E1 00 1B ab ii ii | Reserved | |
| E1 00 1C ab ii ii | Reserved | |
| E1 00 1D ab ii ii | Reserved | |
| E1 00 1E ab ii ii | Reserved | |
**** 2OPI Integer unsigned compare
| Hex | Name | Comment |
|-------------------+-----------------+----------------------------|
| E1 00 1F ab ii ii | CMPUI a b ii ii | a = b CMP ii ii [unsigned] |
**** 2OPI Integer store
| Hex | Name | Comment |
|-------------------+----------------+------------------------------------|
| E1 00 20 ab ii ii | STORE a b ii | MEM[b + ii ii] = a |
| E1 00 21 ab ii ii | STORE8 a b ii | MEM[b + ii ii] = a [signed 8bits] |
| E1 00 22 ab ii ii | STORE16 a b ii | MEM[b + ii ii] = a [signed 16bits] |
| E1 00 23 ab ii ii | STORE32 a b ii | MEM[b + ii ii] = a [signed 32bits] |
| E1 00 24 ab ii ii | Reserved | |
| E1 00 25 ab ii ii | Reserved | |
| E1 00 26 ab ii ii | Reserved | |
| E1 00 27 ab ii ii | Reserved | |
| E1 00 28 ab ii ii | Reserved | |
| E1 00 29 ab ii ii | Reserved | |
| E1 00 2A ab ii ii | Reserved | |
| E1 00 2B ab ii ii | Reserved | |
**** CMPJUMPI Group
| Hex | Name | Comment |
|-------------------+------------------------+-------------------------------------|
| E1 00 C0 ab ii ii | CMPJUMPI.G a b ii ii | a > b ? PC = PC + ii ii |
| E1 00 C1 ab ii ii | CMPJUMPI.GE a b ii ii | a >= b ? PC = PC + ii ii |
| E1 00 C2 ab ii ii | CMPJUMPI.E a b ii ii | a == b ? PC = PC + ii ii |
| E1 00 C3 ab ii ii | CMPJUMPI.NE a b ii ii | a != b ? PC = PC + ii ii |
| E1 00 C4 ab ii ii | CMPJUMPI.LE a b ii ii | a <= b ? PC = PC + ii ii |
| E1 00 C5 ab ii ii | CMPJUMPI.L a b ii ii | a < b ? PC = PC + ii ii |
| E1 00 C6 ab ii ii | Reserved | |
| ... | Reserved | |
| E1 00 CF ab ii ii | Reserved | |
| E1 00 D0 ab ii ii | CMPJUMPUI.G a b ii ii | a > b ? PC = PC + ii ii (unsigned) |
| E1 00 D1 ab ii ii | CMPJUMPUI.GE a b ii ii | a >= b ? PC = PC + ii ii (unsigned) |
| E1 00 D2 ab ii ii | Reserved | |
| E1 00 D3 ab ii ii | Reserved | |
| E1 00 D4 ab ii ii | CMPJUMPUI.LE a b ii ii | a <= b ? PC = PC + ii ii (unsigned) |
| E1 00 D5 ab ii ii | CMPJUMPUI.L a b ii ii | a < b ? PC = PC + ii ii (unsigned) |
| E1 00 D6 ab ii ii | Reserved | |
| ... | Reserved | |
| E1 00 DF ab ii ii | Reserved | |
*** Reserved Block 2
At this time these instructions only produce a warning; but could do anything. At this time these instructions only produce a warning; but could do anything.
DO NOT USE. DO NOT USE.
| Hex | Name |
|-------------+----------| | Hex | Name |
| E0 00 00 00 | Reserved | |-------------------+----------|
| ... | Reserved | | E1 01 00 00 00 00 | Reserved |
| FE FF FF FF | Reserved | | ... | Reserved |
| EF FF FF FF FF FF | Reserved |
** 0OP ** 0OP
| Hex | Name | Comment | | Hex | Name | Comment |
@ -821,33 +825,23 @@ This ordering was selected simply because makes the starting IP address 0 and is
*** Class E 2OPI *** Class E 2OPI
This is a very rare and special group as each entry consumes a piece of the precious 256 entry opcode space. This is a very rare and special group as each entry consumes a piece of the precious 256 entry opcode space.
|--------------+------------+------------+------------------| |--------------+------------+------------+------------+------------------|
| opcode 8bits | Reg0 4bits | Reg1 4bits | Immediate 16bits | | opcode 8bits | XOP 16bits | Reg0 4bits | Reg1 4bits | Immediate 16bits |
|--------------+------------+------------+------------------| |--------------+------------+------------+------------+------------------|
| Opcode | Function group | Length in Bytes | | Opcode | Function group | Length in Bytes |
|---------+----------------+-----------------| |--------+----------------+-----------------|
| 0E - 19 | Integer group | 4 | | E1 | Integer group | 6 |
| 1A - 1E | Reserved | Undefined |
| 1F - 23 | Integer group | 4 |
| 24 - 2B | Reserved | Undefined |
| B0 - B5 | Integer group | 4 |
| B6 - BF | Reserved | Undefined |
| C0 - C5 | Integer group | 4 |
| C6 - CF | Reserved | Undefined |
| D0 - D1 | Integer group | 4 |
| D2 - D3 | Reserved | Undefined |
| D4 - D5 | Integer group | 4 |
*** Class F 1OPI *** Class F 1OPI
|--------------+-----------+------------+------------------| |--------------+------------+------------+------------------|
| opcode 8bits | XOP 4bits | Reg0 4bits | Immediate 16bits | | opcode 8bits | XOP 20bits | Reg0 4bits | Immediate 16bits |
|--------------+-----------+------------+------------------| |--------------+------------+------------+------------------|
| Opcode | Function group | Length in Bytes |
|--------+----------------+-----------------|
| E0 | Integer group | 6 |
| Opcode | Function group | Length in Bytes |
|---------+----------------+-----------------|
| 2C - 2F | Integer group | 4 |
| A0 - A1 | Integer group | 4 |
*** Class G 0OPI *** Class G 0OPI
|--------------+-----------+------------------| |--------------+-----------+------------------|
@ -878,13 +872,16 @@ This is a very rare and special group as each entry consumes a piece of the prec
| FF | HALT | 4 | | FF | HALT | 4 |
** Exotic behavior ** Exotic behavior
*** Illegal instructions
To ensure consistent behavior, all undefined opcodes are to be treated like illegal instructions and for hardware/operating system combinations that lack an illegal instruction handler, the result is that of HALT.
Should an illegal instruction handler be implemented, the implementor should if possible emulate the instruction via software and jump to instruction that follows.
*** Illegal encoding
Assemblers should throw an exception in the event that a register is compared to itself.
As such code is likely wrong and such sequences are reserved for future opcode harvesting in the event of opcode starvation.
*** compare and skip instructions *** compare and skip instructions
All compare and skip instructions lookup the first byte following themselves to determine the number of bytes to skip to allow the correct behavior to occur with shorter and longer instruction formats. All compare and skip instructions lookup the first byte following themselves to determine the number of bytes to skip to allow the correct behavior to occur with shorter and longer instruction formats.
To ensure consistent behavior, all undefined opcodes are to be treated like illegal instructions and for hardware/operating system combinations that lack an illegal instruction handler, the result is that of HALT.
Assemblers should throw an exception in the event that a register is compared to itself as jumps and nops are the preferred alternative in such cases and their encoding could be repurposed in the event of opcode starvation.
*** compare and jump instructions
Assemblers should throw an exception in the event that a register is compared to itself as jumps and nops are the preferred alternative in such cases and their encoding could be repurposed in the event of opcode starvation.
*** HALCODE *** HALCODE
On systems that support an IOMMU and Kernel mode, all HALCODES can be modified or replaced by the kernel. Those listed in this document are those that must be supported on bootup. On systems that support an IOMMU and Kernel mode, all HALCODES can be modified or replaced by the kernel. Those listed in this document are those that must be supported on bootup.

View File

@ -46,8 +46,8 @@ stage0_monitor: hex stage0/stage0_monitor.hex0 | roms
stage1_assembler-0: hex stage1/stage1_assembler-0.hex0 | roms stage1_assembler-0: hex stage1/stage1_assembler-0.hex0 | roms
./bin/hex < stage1/stage1_assembler-0.hex0 > roms/stage1_assembler-0 ./bin/hex < stage1/stage1_assembler-0.hex0 > roms/stage1_assembler-0
SET: stage1_assembler-0 vm stage1/SET.hex0 | roms SET: stage1_assembler-2 vm stage1/SET.hex2 | roms
./bin/vm --rom roms/stage1_assembler-0 --tape_01 stage1/SET.hex0 --tape_02 roms/SET ./bin/vm --rom roms/stage1_assembler-2 --tape_01 stage1/SET.hex2 --tape_02 roms/SET
DEHEX: stage1_assembler-0 vm stage1/dehex.hex0 | roms DEHEX: stage1_assembler-0 vm stage1/dehex.hex0 | roms
./bin/vm --rom roms/stage1_assembler-0 --tape_01 stage1/dehex.hex0 --tape_02 roms/DEHEX ./bin/vm --rom roms/stage1_assembler-0 --tape_01 stage1/dehex.hex0 --tape_02 roms/DEHEX

View File

@ -1,7 +1,7 @@
## Copyright (C) 2016 Jeremiah Orians ## Copyright (C) 2016 Jeremiah Orians
## This file is part of stage0. ## This file is part of stage0.
## ##
## stage0 is free software: you an redistribute it and/or modify ## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by ## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or ## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version. ## (at your option) any later version.
@ -14,122 +14,132 @@
## You should have received a copy of the GNU General Public License ## You should have received a copy of the GNU General Public License
## along with stage0. If not, see <http://www.gnu.org/licenses/>. ## along with stage0. If not, see <http://www.gnu.org/licenses/>.
# :start # :start 0
2D2B0001 # LOADUI R11 1 ; Our toggle E0002D2B0001 # LOADUI R11 1 ; Our toggle
2D2D0600 # LOADUI R13 0x600 ; Where we are starting our Stack E0002D2D0600 # LOADUI R13 0x600 ; Where we are starting our Stack
# ;; R14 will be storing our condition # ;; R14 will be storing our condition
0D00002F # FALSE R15 ; Our holder 0D00002F # FALSE R15 ; Our holder
# ;; Prep TAPE_01 # ;; Prep TAPE_01
2D201100 # LOADUI R0 0x1100 E0002D201100 # LOADUI R0 0x1100
42100001 # FOPEN_WRITE 42100001 # FOPEN_WRITE
# ;; Prep TAPE_02 # ;; Prep TAPE_02
2D201101 # LOADUI R0 0x1101 E0002D201101 # LOADUI R0 0x1101
42100001 # FOPEN_WRITE 42100001 # FOPEN_WRITE
# :loop # :loop 24
2D210000 # LOADUI R1 0 ; Read from tty E0002D210000 # LOADUI R1 0 ; Read from tty
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
A030000d # CMPSKIPI.NE R0 13 ; Replace all CR E000A030000d # CMPSKIPI.NE R0 13 ; Replace all CR
2D20000a # LOADUI R0 10 ; WIth LF E0002D20000a # LOADUI R0 10 ; WIth LF
42100200 # FPUTC ; Display the Char to User 42100200 # FPUTC ; Display the Char to User
# ;; Check for Ctrl-D # ;; Check for Ctrl-D
A0300004 # CMPSKIPI.NE R0 4
3C0000d0 # JUMP @finish E000A0300004 # CMPSKIPI.NE R0 4
3C000112 # JUMP @finish
# ;; Check for EOF # ;; Check for EOF
2CC000cc # JUMP.NP R0 @finish E0002CC0010c # JUMP.NP R0 @finish
# :.L1 # ;; Write out unprocessed byte
2D211101 # LOADUI R1 0x1101 ; Write to TAPE_02 E0002D211101 # LOADUI R1 0x1101 ; Write to TAPE_02
42100200 # FPUTC ; Print the Char 42100200 # FPUTC ; Print the Char
2D0D0034 # CALLI R13 @hex ; Convert it
2CC0ffd4 # JUMP.NP R0 @loop ; Don't use nonhex chars # ;; Convert byte to nybble
2C9B0010 # JUMP.Z R11 @.L99 ; Jump if toggled E0002D0D003e # CALLI R13 @hex ; Convert it
# ;; Get another byte if nonhex
E0002CC0ffc0 # JUMP.NP R0 @loop ; Don't use nonhex chars
# ;; Deal with the case of second nybble
E0002C9B000e # JUMP.Z R11 @second_nybble ; Jump if toggled
# ;; Process first byte of pair # ;; Process first byte of pair
B0F0000f # ANDI R15 R0 0x0F ; Store First nibble E100B0F0000f # ANDI R15 R0 0x0F ; Store First nibble
0D00002B # FALSE R11 ; Flip the toggle 0D00002B # FALSE R11 ; Flip the toggle
3C00ffc4 # JUMP @loop 3C00ffac # JUMP @loop
# :.L99 # ;; Combined second nybble in pair with first
2D5F0004 # SL0I R15 4 ; Shift our first nibble # :second_nybble 78
B000000f # ANDI R0 R0 0x0F ; Mask out top E0002D5F0004 # SL0I R15 4 ; Shift our first nibble
0500000F # ADD R0 R0 R15 ; Combine nibbles E100B000000f # ANDI R0 R0 0x0F ; Mask out top
2D1B0001 # LOADI R11 1 ; Flip the toggle 0500000F # ADD R0 R0 R15 ; Combine nibbles
2D211100 # LOADUI R1 0x1100 ; Write the combined byte
42100200 # FPUTC ; To TAPE_01
3C00ffa8 # JUMP @loop ; Try to get more bytes
# :hex # ;; Writeout and prepare for next cycle
E0002D1B0001 # LOADI R11 1 ; Flip the toggle
E0002D211100 # LOADUI R1 0x1100 ; Write the combined byte
42100200 # FPUTC ; To TAPE_01
3C00ff88 # JUMP @loop ; Try to get more bytes
# :hex 9c
# ;; Deal with line comments starting with # # ;; Deal with line comments starting with #
1FE00023 # CMPUI R14 R0 35 E1001FE00023 # CMPUI R14 R0 35
2C5E0060 # JUMP.E R14 @ascii_comment E0002C5E007e # JUMP.E R14 @ascii_comment
# ;; Deal with line comments starting with ; # ;; Deal with line comments starting with ;
1FE0003b # CMPUI R14 R0 59 E1001FE0003b # CMPUI R14 R0 59
2C5E0058 # JUMP.E R14 @ascii_comment E0002C5E0072 # JUMP.E R14 @ascii_comment
# ;; Deal with all ascii less than '0' # ;; Deal with all ascii less than '0'
1FE00030 # CMPUI R14 R0 48 E1001FE00030 # CMPUI R14 R0 48
2C8E0048 # JUMP.L R14 @ascii_other E0002C8E005e # JUMP.L R14 @ascii_other
# ;; Deal with '0'-'9' # ;; Deal with '0'-'9'
1FE00039 # CMPUI R14 R0 57 E1001FE00039 # CMPUI R14 R0 57
2C7E0028 # JUMP.LE R14 @ascii_num E0002C7E0034 # JUMP.LE R14 @ascii_num
# ;; Deal with all ascii less than 'A' # ;; Deal with all ascii less than 'A'
1FE00041 # CMPUI R14 R0 65 E1001FE00041 # CMPUI R14 R0 65
2C8E0038 # JUMP.L R14 @ascii_other E0002C8E0046 # JUMP.L R14 @ascii_other
# ;; Deal with 'A'-'F' # ;; Deal with 'A'-'F'
1FE00046 # CMPUI R14 R0 70 E1001FE00046 # CMPUI R14 R0 70
2C7E0028 # JUMP.LE R14 @ascii_high E0002C7E0030 # JUMP.LE R14 @ascii_high
# ;; Deal with all ascii less than 'a' # ;; Deal with all ascii less than 'a'
1FE00061 # CMPUI R14 R0 97 E1001FE00061 # CMPUI R14 R0 97
2C8E0028 # JUMP.L R14 @ascii_other E0002C8E002e # JUMP.L R14 @ascii_other
# ;; Deal with 'a'-'f' # ;; Deal with 'a'-'f'
1FE00066 # CMPUI R14 R0 102 E1001FE00066 # CMPUI R14 R0 102
2C7E0010 # JUMP.LE R14 @ascii_low E0002C7E000e # JUMP.LE R14 @ascii_low
# ;; Ignore the rest # ;; Ignore the rest
3C00001c # JUMP @ascii_other 3C00001e # JUMP @ascii_other
# :ascii_num # :ascii_num 100
11000030 # SUBUI R0 R0 48 E10011000030 # SUBUI R0 R0 48
0D01001D # RET R13 0D01001D # RET R13
# :ascii_low # :ascii_low 10a
11000057 # SUBUI R0 R0 87 E10011000057 # SUBUI R0 R0 87
0D01001D # RET R13 0D01001D # RET R13
# :ascii_high # :ascii_high 114
11000037 # SUBUI R0 R0 55 E10011000037 # SUBUI R0 R0 55
0D01001D # RET R13 0D01001D # RET R13
# :ascii_other # :ascii_other 11e
0D000030 # TRUE R0 0D000030 # TRUE R0
0D01001D # RET R13 0D01001D # RET R13
# :ascii_comment # :ascii_comment 126
2D210000 # LOADUI R1 0 ; Read from tty E0002D210000 # LOADUI R1 0 ; Read from tty
42100100 # FGETC ; Read another char 42100100 # FGETC ; Read another char
A030000d # CMPSKIPI.NE R0 13 ; Replace all CR E000A030000d # CMPSKIPI.NE R0 13 ; Replace all CR
2D20000a # LOADUI R0 10 ; WIth LF E0002D20000a # LOADUI R0 10 ; WIth LF
42100200 # FPUTC ; Let the user see it 42100200 # FPUTC ; Let the user see it
1FE0000a # CMPUI R14 R0 10 ; Stop at the end of line E1001FE0000a # CMPUI R14 R0 10 ; Stop at the end of line
2D211101 # LOADUI R1 0x1101 ; Write to TAPE_02 E0002D211101 # LOADUI R1 0x1101 ; Write to TAPE_02
42100200 # FPUTC ; The char we just read 42100200 # FPUTC ; The char we just read
2C6Effe0 # JUMP.NE R14 @ascii_comment ; Otherwise keep looping E0002C6Effd0 # JUMP.NE R14 @ascii_comment ; Otherwise keep looping
3C00ffd4 # JUMP @ascii_other 3C00ffc4 # JUMP @ascii_other
# :finish # :finish 15a
2D201100 # LOADUI R0 0x1100 ; Close TAPE_01 E0002D201100 # LOADUI R0 0x1100 ; Close TAPE_01
42100002 # FCLOSE 42100002 # FCLOSE
2D201101 # LOADUI R0 0x1101 ; Close TAPE_02 E0002D201101 # LOADUI R0 0x1101 ; Close TAPE_02
42100002 # FCLOSE 42100002 # FCLOSE
FFFFFFFF # HALT FFFFFFFF # HALT

View File

@ -16,22 +16,22 @@
:start :start
# ;; We will be using R13 for storage of Head # ;; We will be using R13 for storage of Head
2D2E 4000 # LOADUI R14 0x4000 ; Our malloc pointer (Initialized) E0002D2E 4000 # LOADUI R14 0x4000 ; Our malloc pointer (Initialized)
2D2F $stack # LOADUI R15 $stack ; Put stack at end of program E0002D2F $stack # LOADUI R15 $stack ; Put stack at end of program
# ;; Main program # ;; Main program
# ;; Reads contents of Tape_01 and applies all Definitions # ;; Reads contents of Tape_01 and applies all Definitions
# ;; Writes results to Tape_02 # ;; Writes results to Tape_02
# ;; Accepts no arguments and HALTS when done # ;; Accepts no arguments and HALTS when done
:main :main
2D0F @Tokenize_Line # CALLI R15 @Tokenize_Line ; Call Tokenize_Line E0002D0F @Tokenize_Line # CALLI R15 @Tokenize_Line ; Call Tokenize_Line
2D0F @reverse_list # CALLI R15 @reverse_list ; Reverse the list of tokens E0002D0F @reverse_list # CALLI R15 @reverse_list ; Reverse the list of tokens
2D0F @Identify_Macros # CALLI R15 @Identify_Macros ; Tag all nodes that are macros E0002D0F @Identify_Macros # CALLI R15 @Identify_Macros ; Tag all nodes that are macros
2D0F @Line_Macro # CALLI R15 @Line_Macro ; Apply macros down nodes E0002D0F @Line_Macro # CALLI R15 @Line_Macro ; Apply macros down nodes
2D0F @Process_String # CALLI R15 @Process_String ; Convert string values to Hex16 E0002D0F @Process_String # CALLI R15 @Process_String ; Convert string values to Hex16
2D0F @Eval_Immediates # CALLI R15 @Eval_Immediates ; Convert numbers to hex E0002D0F @Eval_Immediates # CALLI R15 @Eval_Immediates ; Convert numbers to hex
2D0F @Preserve_Other # CALLI R15 @Preserve_Other ; Ensure labels/Pointers aren't lost E0002D0F @Preserve_Other # CALLI R15 @Preserve_Other ; Ensure labels/Pointers aren't lost
2D0F @Print_Hex # CALLI R15 @Print_Hex ; Write Nodes to Tape_02 E0002D0F @Print_Hex # CALLI R15 @Print_Hex ; Write Nodes to Tape_02
FFFFFFFF # HALT ; We are Done FFFFFFFF # HALT ; We are Done
@ -40,7 +40,7 @@ FFFFFFFF # HALT ; We are Done
# ;; Returns to whatever called it # ;; Returns to whatever called it
:Tokenize_Line :Tokenize_Line
# ;; Prep TAPE_01 # ;; Prep TAPE_01
2D201100 # LOADUI R0 0x1100 E0002D201100 # LOADUI R0 0x1100
42100000 # FOPEN_READ 42100000 # FOPEN_READ
0D00002D # FALSE R13 ; Head is NULL 0D00002D # FALSE R13 ; Head is NULL
09000510 # MOVE R1 R0 ; Read Tape_01 09000510 # MOVE R1 R0 ; Read Tape_01
@ -48,53 +48,53 @@ FFFFFFFF # HALT ; We are Done
42100100 # FGETC ; Get a Char 42100100 # FGETC ; Get a Char
# ;; Deal with lines comments starting with # # ;; Deal with lines comments starting with #
A0300023 # CMPSKIPI.NE R0 35 E000A0300023 # CMPSKIPI.NE R0 35
3C00 @Purge_Line_Comment # JUMP @Purge_Line_Comment 3C00 @Purge_Line_Comment # JUMP @Purge_Line_Comment
# ;; Deal with Line comments starting with ; # ;; Deal with Line comments starting with ;
A030003b # CMPSKIPI.NE R0 59 E000A030003b # CMPSKIPI.NE R0 59
3C00 @Purge_Line_Comment # JUMP @Purge_Line_Comment 3C00 @Purge_Line_Comment # JUMP @Purge_Line_Comment
# ;; Deal with Tab # ;; Deal with Tab
A0300009 # CMPSKIPI.NE R0 9 E000A0300009 # CMPSKIPI.NE R0 9
3C00 @Tokenize_Line_0 # JUMP @Tokenize_Line_0 ; Throw away byte and try again 3C00 @Tokenize_Line_0 # JUMP @Tokenize_Line_0 ; Throw away byte and try again
# ;; Deal with New line # ;; Deal with New line
A030000a # CMPSKIPI.NE R0 10 E000A030000a # CMPSKIPI.NE R0 10
3C00 @Tokenize_Line_0 # JUMP @Tokenize_Line_0 ; Throw away byte and try again 3C00 @Tokenize_Line_0 # JUMP @Tokenize_Line_0 ; Throw away byte and try again
# ;; Deal with space characters # ;; Deal with space characters
A0300020 # CMPSKIPI.NE R0 32 E000A0300020 # CMPSKIPI.NE R0 32
3C00 @Tokenize_Line_0 # JUMP @Tokenize_Line_0 ; Throw away byte and try again 3C00 @Tokenize_Line_0 # JUMP @Tokenize_Line_0 ; Throw away byte and try again
# ;; Stop if EOF # ;; Stop if EOF
A0100000 # CMPSKIPI.GE R0 0 E000A0100000 # CMPSKIPI.GE R0 0
3C00 @Tokenize_Line_Done # JUMP @Tokenize_Line_Done 3C00 @Tokenize_Line_Done # JUMP @Tokenize_Line_Done
# ;; Allocate a new Node # ;; Allocate a new Node
0900042E # COPY R2 R14 ; Get address of new Node 0900042E # COPY R2 R14 ; Get address of new Node
0FEE0010 # ADDUI R14 R14 16 ; Allocate 16 Bytes E1000FEE0010 # ADDUI R14 R14 16 ; Allocate 16 Bytes
23E20008 # STORE32 R14 R2 8 ; Set Text pointer E10023E20008 # STORE32 R14 R2 8 ; Set Text pointer
# ;; Deal with Strings wrapped in \" # ;; Deal with Strings wrapped in \"
A0300022 # CMPSKIPI.NE R0 34 E000A0300022 # CMPSKIPI.NE R0 34
3C00 @Store_String # JUMP @Store_String 3C00 @Store_String # JUMP @Store_String
# ;; Deal with Strings wrapped in ' # ;; Deal with Strings wrapped in '
A0300027 # CMPSKIPI.NE R0 39 E000A0300027 # CMPSKIPI.NE R0 39
3C00 @Store_String # JUMP @Store_String 3C00 @Store_String # JUMP @Store_String
# ;; Everything else is an atom store it # ;; Everything else is an atom store it
2D0F @Store_Atom # CALLI R15 @Store_Atom E0002D0F @Store_Atom # CALLI R15 @Store_Atom
:Tokenize_Line_1 :Tokenize_Line_1
23D20000 # STORE32 R13 R2 0 ; Set p->next to head E10023D20000 # STORE32 R13 R2 0 ; Set p->next to head
090005D2 # MOVE R13 R2 ; Set head to p 090005D2 # MOVE R13 R2 ; Set head to p
3C00 @Tokenize_Line_0 # JUMP @Tokenize_Line_0 ; Keep getting tokens 3C00 @Tokenize_Line_0 # JUMP @Tokenize_Line_0 ; Keep getting tokens
:Tokenize_Line_Done :Tokenize_Line_Done
# ;; Done reading File # ;; Done reading File
2D201100 # LOADUI R0 0x1100 ; Close TAPE_01 E0002D201100 # LOADUI R0 0x1100 ; Close TAPE_01
42100002 # FCLOSE 42100002 # FCLOSE
0D01001F # RET R15 0D01001F # RET R15
@ -108,9 +108,9 @@ A0300027 # CMPSKIPI.NE R0 39
# ; Using R2 as next # ; Using R2 as next
:reverse_list_0 :reverse_list_0
2C90 @reverse_list_done # JUMP.Z R0 @reverse_list_done ; Stop if NULL == head E0002C90 @reverse_list_done # JUMP.Z R0 @reverse_list_done ; Stop if NULL == head
13200000 # LOAD R2 R0 0 ; next = head->next E10013200000 # LOAD R2 R0 0 ; next = head->next
20100000 # STORE R1 R0 0 ; head->next = root E10020100000 # STORE R1 R0 0 ; head->next = root
09000510 # MOVE R1 R0 ; root = head 09000510 # MOVE R1 R0 ; root = head
09000502 # MOVE R0 R2 ; head = next 09000502 # MOVE R0 R2 ; head = next
3C00 @reverse_list_0 # JUMP @reverse_list_0 ; Keep looping 3C00 @reverse_list_0 # JUMP @reverse_list_0 ; Keep looping
@ -128,7 +128,7 @@ A0300027 # CMPSKIPI.NE R0 39
# ;; Comment never existed # ;; Comment never existed
:Purge_Line_Comment :Purge_Line_Comment
42100100 # FGETC ; Get another Char 42100100 # FGETC ; Get another Char
A020000a # CMPSKIPI.E R0 10 ; Stop When LF is reached E000A020000a # CMPSKIPI.E R0 10 ; Stop When LF is reached
3C00 @Purge_Line_Comment # JUMP @Purge_Line_Comment ; Otherwise keep looping 3C00 @Purge_Line_Comment # JUMP @Purge_Line_Comment ; Otherwise keep looping
3C00 @Tokenize_Line_0 # JUMP @Tokenize_Line_0 ; Return as if this never happened 3C00 @Tokenize_Line_0 # JUMP @Tokenize_Line_0 ; Return as if this never happened
@ -143,15 +143,15 @@ A020000a # CMPSKIPI.E R0 10 ; Stop When LF is reached
09000430 # COPY R3 R0 ; Copy Char for comparison 09000430 # COPY R3 R0 ; Copy Char for comparison
:Store_String_0 :Store_String_0
210E0000 # STORE8 R0 R14 0 ; Store the Byte E100210E0000 # STORE8 R0 R14 0 ; Store the Byte
42100100 # FGETC ; Get next Byte 42100100 # FGETC ; Get next Byte
0FEE0001 # ADDUI R14 R14 1 ; Prep for next loop E1000FEE0001 # ADDUI R14 R14 1 ; Prep for next loop
C303 @Store_String_0 # CMPJUMPI.NE R0 R3 @Store_String_0 ; Loop if matching not found E100C303 @Store_String_0 # CMPJUMPI.NE R0 R3 @Store_String_0 ; Loop if matching not found
# ;; Clean up # ;; Clean up
0FEE0004 # ADDUI R14 R14 4 ; Correct Malloc E1000FEE0004 # ADDUI R14 R14 4 ; Correct Malloc
2D200002 # LOADUI R0 2 ; Using type string E0002D200002 # LOADUI R0 2 ; Using type string
23020004 # STORE32 R0 R2 4 ; Set node type E10023020004 # STORE32 R0 R2 4 ; Set node type
3C00 @Tokenize_Line_1 # JUMP @Tokenize_Line_1 3C00 @Tokenize_Line_1 # JUMP @Tokenize_Line_1
@ -160,14 +160,14 @@ C303 @Store_String_0 # CMPJUMPI.NE R0 R3 @Store_String_0 ; Loop if matching not
# ;; And node pointer in R2 # ;; And node pointer in R2
# ;; Modifies node Text to point to string # ;; Modifies node Text to point to string
:Store_Atom :Store_Atom
210E0000 # STORE8 R0 R14 0 ; Store the Byte E100210E0000 # STORE8 R0 R14 0 ; Store the Byte
42100100 # FGETC ; Get next Byte 42100100 # FGETC ; Get next Byte
0FEE0001 # ADDUI R14 R14 1 ; Prep for next loop E1000FEE0001 # ADDUI R14 R14 1 ; Prep for next loop
A0300009 # CMPSKIPI.NE R0 9 ; If char is Tab E000A0300009 # CMPSKIPI.NE R0 9 ; If char is Tab
3C00 @Store_Atom_Done # JUMP @Store_Atom_Done ; Be done 3C00 @Store_Atom_Done # JUMP @Store_Atom_Done ; Be done
A030000a # CMPSKIPI.NE R0 10 ; If char is LF E000A030000a # CMPSKIPI.NE R0 10 ; If char is LF
3C00 @Store_Atom_Done # JUMP @Store_Atom_Done ; Be done 3C00 @Store_Atom_Done # JUMP @Store_Atom_Done ; Be done
A0300020 # CMPSKIPI.NE R0 32 ; If char is Space E000A0300020 # CMPSKIPI.NE R0 32 ; If char is Space
3C00 @Store_Atom_Done # JUMP @Store_Atom_Done ; Be done 3C00 @Store_Atom_Done # JUMP @Store_Atom_Done ; Be done
# ;; Otherwise loop # ;; Otherwise loop
@ -175,7 +175,7 @@ A0300020 # CMPSKIPI.NE R0 32 ; If char is Space
:Store_Atom_Done :Store_Atom_Done
# ;; Cleanup # ;; Cleanup
0FEE0001 # ADDUI R14 R14 1 ; Correct Malloc E1000FEE0001 # ADDUI R14 R14 1 ; Correct Malloc
0D01001F # RET R15 0D01001F # RET R15
@ -199,10 +199,10 @@ A0300020 # CMPSKIPI.NE R0 32 ; If char is Space
:cmpbyte :cmpbyte
0503A024 # LOADXU8 R0 R2 R4 ; Get a byte of our first string 0503A024 # LOADXU8 R0 R2 R4 ; Get a byte of our first string
0503A134 # LOADXU8 R1 R3 R4 ; Get a byte of our second string 0503A134 # LOADXU8 R1 R3 R4 ; Get a byte of our second string
0F440001 # ADDUI R4 R4 1 ; Prep for next loop E1000F440001 # ADDUI R4 R4 1 ; Prep for next loop
05004001 # CMP R0 R0 R1 ; Compare the bytes 05004001 # CMP R0 R0 R1 ; Compare the bytes
A0210000 # CMPSKIPI.E R1 0 ; Stop if byte is NULL E000A0210000 # CMPSKIPI.E R1 0 ; Stop if byte is NULL
2C50 @cmpbyte # JUMP.E R0 @cmpbyte ; Loop if bytes are equal E0002C50 @cmpbyte # JUMP.E R0 @cmpbyte ; Loop if bytes are equal
# ;; Done # ;; Done
# ;; Restore registers # ;; Restore registers
@ -220,40 +220,40 @@ A0210000 # CMPSKIPI.E R1 0 ; Stop if byte is NULL
# ;; Return to whatever called it # ;; Return to whatever called it
:Identify_Macros :Identify_Macros
# ;; Initializ # ;; Initializ
2D2101d0 # LOADUI R1 $Identify_Macros_string E0002D21 $Identify_Macros_string # LOADUI R1 $Identify_Macros_string
0900042D # COPY R2 R13 ; i = head 0900042D # COPY R2 R13 ; i = head
# ;; Main Loop # ;; Main Loop
:Identify_Macros_0 :Identify_Macros_0
18020008 # LOAD32 R0 R2 8 ; Get Pointer to Text E10018020008 # LOAD32 R0 R2 8 ; Get Pointer to Text
2D0F @strcmp # CALLI R15 @strcmp E0002D0F @strcmp # CALLI R15 @strcmp
2C60 @Identify_Macros_1 # JUMP.NE R0 @Identify_Macros_1 E0002C60 @Identify_Macros_1 # JUMP.NE R0 @Identify_Macros_1
# ;; It is a definition # ;; It is a definition
# ;; Set i->Type = macro # ;; Set i->Type = macro
2D200001 # LOADUI R0 1 ; The Enum value for macro E0002D200001 # LOADUI R0 1 ; The Enum value for macro
23020004 # STORE32 R0 R2 4 ; Set node type E10023020004 # STORE32 R0 R2 4 ; Set node type
# ;; Set i->Text = i->Next->Text # ;; Set i->Text = i->Next->Text
18420000 # LOAD32 R4 R2 0 ; Get Next E10018420000 # LOAD32 R4 R2 0 ; Get Next
18040008 # LOAD32 R0 R4 8 ; Get Next->Text E10018040008 # LOAD32 R0 R4 8 ; Get Next->Text
23020008 # STORE32 R0 R2 8 ; Set i->Text = Next->Text E10023020008 # STORE32 R0 R2 8 ; Set i->Text = Next->Text
# ;; Set i->Expression = i->next->next->Text # ;; Set i->Expression = i->next->next->Text
18440000 # LOAD32 R4 R4 0 ; Get Next->Next E10018440000 # LOAD32 R4 R4 0 ; Get Next->Next
18040008 # LOAD32 R0 R4 8 ; Get Next->Next->Text E10018040008 # LOAD32 R0 R4 8 ; Get Next->Next->Text
18340004 # LOAD32 R3 R4 4 ; Get Next->Next->type E10018340004 # LOAD32 R3 R4 4 ; Get Next->Next->type
A0330002 # CMPSKIPI.NE R3 2 ; If node is a string E000A0330002 # CMPSKIPI.NE R3 2 ; If node is a string
0F000001 # ADDUI R0 R0 1 ; Skip first char E1000F000001 # ADDUI R0 R0 1 ; Skip first char
2302000c # STORE32 R0 R2 12 ; Set Expression = Next->Next->Text E1002302000c # STORE32 R0 R2 12 ; Set Expression = Next->Next->Text
# ;; Set i->Next = i->Next->Next->Next # ;; Set i->Next = i->Next->Next->Next
18440000 # LOAD32 R4 R4 0 ; Get Next->Next->Next E10018440000 # LOAD32 R4 R4 0 ; Get Next->Next->Next
23420000 # STORE32 R4 R2 0 ; Set i->Next = Next->Next->Next E10023420000 # STORE32 R4 R2 0 ; Set i->Next = Next->Next->Next
:Identify_Macros_1 :Identify_Macros_1
18220000 # LOAD32 R2 R2 0 ; Get node->next E10018220000 # LOAD32 R2 R2 0 ; Get node->next
2CA2 @Identify_Macros_0 # JUMP.NZ R2 @Identify_Macros_0 ; Loop if i not NULL E0002CA2 @Identify_Macros_0 # JUMP.NZ R2 @Identify_Macros_0 ; Loop if i not NULL
0D01001F # RET R15 0D01001F # RET R15
:Identify_Macros_string :Identify_Macros_string
@ -269,13 +269,13 @@ A0330002 # CMPSKIPI.NE R3 2 ; If node is a string
# ;; Main loop # ;; Main loop
:Line_Macro_0 :Line_Macro_0
18300004 # LOAD32 R3 R0 4 ; Load Node type E10018300004 # LOAD32 R3 R0 4 ; Load Node type
1820000c # LOAD32 R2 R0 12 ; Load Expression pointer E1001820000c # LOAD32 R2 R0 12 ; Load Expression pointer
18100008 # LOAD32 R1 R0 8 ; Load Text pointer E10018100008 # LOAD32 R1 R0 8 ; Load Text pointer
18000000 # LOAD32 R0 R0 0 ; Load Next pointer E10018000000 # LOAD32 R0 R0 0 ; Load Next pointer
A0330001 # CMPSKIPI.NE R3 1 ; If a macro E000A0330001 # CMPSKIPI.NE R3 1 ; If a macro
2D0F @setExpression # CALLI R15 @setExpression ; Apply to other nodes E0002D0F @setExpression # CALLI R15 @setExpression ; Apply to other nodes
2CA0 @Line_Macro_0 # JUMP.NZ R0 @Line_Macro_0 ; If Next is Null Don't loop E0002CA0 @Line_Macro_0 # JUMP.NZ R0 @Line_Macro_0 ; If Next is Null Don't loop
0D01001F # RET R15 0D01001F # RET R15
@ -293,17 +293,17 @@ A0330001 # CMPSKIPI.NE R3 1 ; If a macro
09000440 # COPY R4 R0 ; Use R4 for Node pointer 09000440 # COPY R4 R0 ; Use R4 for Node pointer
:setExpression_0 :setExpression_0
18340004 # LOAD32 R3 R4 4 ; Load type into R3 E10018340004 # LOAD32 R3 R4 4 ; Load type into R3
A0330001 # CMPSKIPI.NE R3 1 ; Check if Macro E000A0330001 # CMPSKIPI.NE R3 1 ; Check if Macro
3C00 @setExpression_1 # JUMP @setExpression_1 ; Move to next if Macro 3C00 @setExpression_1 # JUMP @setExpression_1 ; Move to next if Macro
18040008 # LOAD32 R0 R4 8 ; Load Text pointer into R0 for Comparision E10018040008 # LOAD32 R0 R4 8 ; Load Text pointer into R0 for Comparision
2D0F @strcmp # CALLI R15 @strcmp ; compare Text and Macro Text E0002D0F @strcmp # CALLI R15 @strcmp ; compare Text and Macro Text
2C60 @setExpression_1 # JUMP.NE R0 @setExpression_1 ; Move to next if not Match E0002C60 @setExpression_1 # JUMP.NE R0 @setExpression_1 ; Move to next if not Match
2324000c # STORE32 R2 R4 12 ; Set node->Expression = Exp E1002324000c # STORE32 R2 R4 12 ; Set node->Expression = Exp
:setExpression_1 :setExpression_1
18440000 # LOAD32 R4 R4 0 ; Load Next E10018440000 # LOAD32 R4 R4 0 ; Load Next
2CA4 @setExpression_0 # JUMP.NZ R4 @setExpression_0 ; Loop if next isn't NULL E0002CA4 @setExpression_0 # JUMP.NZ R4 @setExpression_0 ; Loop if next isn't NULL
:setExpression_Done :setExpression_Done
# ;; Restore registers # ;; Restore registers
@ -321,30 +321,30 @@ A0330001 # CMPSKIPI.NE R3 1 ; Check if Macro
:Process_String_0 :Process_String_0
# ;; Get node type # ;; Get node type
18100004 # LOAD32 R1 R0 4 ; Load Type E10018100004 # LOAD32 R1 R0 4 ; Load Type
A0210002 # CMPSKIPI.E R1 2 ; If not a string E000A0210002 # CMPSKIPI.E R1 2 ; If not a string
3C00 @Process_String_Done # JUMP @Process_String_Done ; Just go to next 3C00 @Process_String_Done # JUMP @Process_String_Done ; Just go to next
# ;; Its a string # ;; Its a string
18100008 # LOAD32 R1 R0 8 ; Get Text pointer E10018100008 # LOAD32 R1 R0 8 ; Get Text pointer
14210000 # LOAD8 R2 R1 0 ; Get first char of Text E10014210000 # LOAD8 R2 R1 0 ; Get first char of Text
# ;; Deal with ' # ;; Deal with '
A0220027 # CMPSKIPI.E R2 39 ; If char is not ' E000A0220027 # CMPSKIPI.E R2 39 ; If char is not '
3C00 @Process_String_1 # JUMP @Process_String_1 ; Move to next label 3C00 @Process_String_1 # JUMP @Process_String_1 ; Move to next label
# ;; Simply use Hex strings as is # ;; Simply use Hex strings as is
0F110001 # ADDUI R1 R1 1 ; Move Text pointer by 1 E1000F110001 # ADDUI R1 R1 1 ; Move Text pointer by 1
2310000c # STORE32 R1 R0 12 ; Set expression to Text + 1 E1002310000c # STORE32 R1 R0 12 ; Set expression to Text + 1
3C00 @Process_String_Done # JUMP @Process_String_Done ; And move on 3C00 @Process_String_Done # JUMP @Process_String_Done ; And move on
:Process_String_1 :Process_String_1
# ;; Deal with \" # ;; Deal with \"
2D0F @Hexify_String # CALLI R15 @Hexify_String E0002D0F @Hexify_String # CALLI R15 @Hexify_String
:Process_String_Done :Process_String_Done
18000000 # LOAD32 R0 R0 0 ; Load Next E10018000000 # LOAD32 R0 R0 0 ; Load Next
2CA0 @Process_String_0 # JUMP.NZ R0 @Process_String_0 ; If Next isn't NULL Recurse down list E0002CA0 @Process_String_0 # JUMP.NZ R0 @Process_String_0 ; If Next isn't NULL Recurse down list
0D01001F # RET R15 0D01001F # RET R15
@ -360,20 +360,20 @@ A0220027 # CMPSKIPI.E R2 39 ; If char is not '
# ;; Initialize # ;; Initialize
09000510 # MOVE R1 R0 ; Move R0 out of the way 09000510 # MOVE R1 R0 ; Move R0 out of the way
23E1000c # STORE32 R14 R1 12 ; Set node expression pointer E10023E1000c # STORE32 R14 R1 12 ; Set node expression pointer
18110008 # LOAD32 R1 R1 8 ; Load Text pointer into R2 E10018110008 # LOAD32 R1 R1 8 ; Load Text pointer into R2
0F110001 # ADDUI R1 R1 1 ; SKip leading \" E1000F110001 # ADDUI R1 R1 1 ; SKip leading \"
# ;; Main Loop # ;; Main Loop
:Hexify_String_0 :Hexify_String_0
18010000 # LOAD32 R0 R1 0 ; Load 4 bytes into R0 from Text E10018010000 # LOAD32 R0 R1 0 ; Load 4 bytes into R0 from Text
B02000ff # ANDI R2 R0 0xFF ; Preserve byte to check for NULL E100B02000ff # ANDI R2 R0 0xFF ; Preserve byte to check for NULL
2D0F @hex32 # CALLI R15 @hex32 ; Convert to hex and store in Expression E0002D0F @hex32 # CALLI R15 @hex32 ; Convert to hex and store in Expression
0F110004 # ADDUI R1 R1 4 ; Pointer Text pointer to next 4 bytes E1000F110004 # ADDUI R1 R1 4 ; Pointer Text pointer to next 4 bytes
2CA2 @Hexify_String_0 # JUMP.NZ R2 @Hexify_String_0 E0002CA2 @Hexify_String_0 # JUMP.NZ R2 @Hexify_String_0
# ;; Done # ;; Done
0FEE0001 # ADDUI R14 R14 1 ; Correct malloc value E1000FEE0001 # ADDUI R14 R14 1 ; Correct malloc value
0902800F # POPR R0 R15 0902800F # POPR R0 R15
0D01001F # RET R15 0D01001F # RET R15
@ -385,26 +385,26 @@ B02000ff # ANDI R2 R0 0xFF ; Preserve byte to check for NULL
# ;; Returns to whatever called it # ;; Returns to whatever called it
:hex32 :hex32
0902000F # PUSHR R0 R15 0902000F # PUSHR R0 R15
2D600010 # SR0I R0 16 ; Do high word first E0002D600010 # SR0I R0 16 ; Do high word first
2D0F @hex16 # CALLI R15 @hex16 E0002D0F @hex16 # CALLI R15 @hex16
0902800F # POPR R0 R15 0902800F # POPR R0 R15
:hex16 :hex16
0902000F # PUSHR R0 R15 0902000F # PUSHR R0 R15
2D600008 # SR0I R0 8 ; Do high byte first E0002D600008 # SR0I R0 8 ; Do high byte first
2D0F @hex8 # CALLI R15 @hex8 E0002D0F @hex8 # CALLI R15 @hex8
0902800F # POPR R0 R15 0902800F # POPR R0 R15
:hex8 :hex8
0902000F # PUSHR R0 R15 0902000F # PUSHR R0 R15
2D600004 # SR0I R0 4 ; Do high nybble first E0002D600004 # SR0I R0 4 ; Do high nybble first
2D0F @hex4 # CALLI R15 @hex4 E0002D0F @hex4 # CALLI R15 @hex4
0902800F # POPR R0 R15 0902800F # POPR R0 R15
:hex4 :hex4
B000000f # ANDI R0 R0 0xF ; isolate nybble E100B000000f # ANDI R0 R0 0xF ; isolate nybble
0F000030 # ADDUI R0 R0 48 ; convert to ascii E1000F000030 # ADDUI R0 R0 48 ; convert to ascii
A0400039 # CMPSKIPI.LE R0 57 ; If nybble was greater than '9' E000A0400039 # CMPSKIPI.LE R0 57 ; If nybble was greater than '9'
0F000007 # ADDUI R0 R0 7 ; Shift it into 'A' range of ascii E1000F000007 # ADDUI R0 R0 7 ; Shift it into 'A' range of ascii
210E0000 # STORE8 R0 R14 0 ; Store Hex Char E100210E0000 # STORE8 R0 R14 0 ; Store Hex Char
0FEE0001 # ADDUI R14 R14 1 ; Increment address pointer E1000FEE0001 # ADDUI R14 R14 1 ; Increment address pointer
0D01001F # RET R15 ; Get next nybble or return if done 0D01001F # RET R15 ; Get next nybble or return if done
@ -418,24 +418,24 @@ A0400039 # CMPSKIPI.LE R0 57 ; If nybble was greater than '9'
# ;; Process Text # ;; Process Text
:Eval_Immediates_0 :Eval_Immediates_0
18230000 # LOAD32 R2 R3 0 ; Load Node->Next E10018230000 # LOAD32 R2 R3 0 ; Load Node->Next
1803000c # LOAD32 R0 R3 12 ; Load Expression pointer E1001803000c # LOAD32 R0 R3 12 ; Load Expression pointer
2CA0 @Eval_Immediates_1 # JUMP.NZ R0 @Eval_Immediates_1 ; Don't do anything if Expression is set E0002CA0 @Eval_Immediates_1 # JUMP.NZ R0 @Eval_Immediates_1 ; Don't do anything if Expression is set
18030004 # LOAD32 R0 R3 4 ; Load Node type E10018030004 # LOAD32 R0 R3 4 ; Load Node type
2CA0 @Eval_Immediates_1 # JUMP.NZ R0 @Eval_Immediates_1 ; Don't do anything if Typed E0002CA0 @Eval_Immediates_1 # JUMP.NZ R0 @Eval_Immediates_1 ; Don't do anything if Typed
18030008 # LOAD32 R0 R3 8 ; Load Text pointer E10018030008 # LOAD32 R0 R3 8 ; Load Text pointer
14100000 # LOAD8 R1 R0 0 ; Get first char of Text E10014100000 # LOAD8 R1 R0 0 ; Get first char of Text
2D0F @numerate_string # CALLI R15 @numerate_string ; Convert to number in R0 E0002D0F @numerate_string # CALLI R15 @numerate_string ; Convert to number in R0
A0210030 # CMPSKIPI.E R1 48 ; Skip next comparision if '0' E000A0210030 # CMPSKIPI.E R1 48 ; Skip next comparision if '0'
2C90 @Eval_Immediates_1 # JUMP.Z R0 @Eval_Immediates_1 ; Don't do anything if string isn't a number E0002C90 @Eval_Immediates_1 # JUMP.Z R0 @Eval_Immediates_1 ; Don't do anything if string isn't a number
20E3000c # STORE R14 R3 12 ; Preserve pointer to expression E10020E3000c # STORE R14 R3 12 ; Preserve pointer to expression
2D0F @hex16 # CALLI R15 @hex16 ; Shove our number into expression E0002D0F @hex16 # CALLI R15 @hex16 ; Shove our number into expression
0FEE0001 # ADDUI R14 R14 1 ; Allocate enough space for a null E1000FEE0001 # ADDUI R14 R14 1 ; Allocate enough space for a null
# ;; Handle looping # ;; Handle looping
:Eval_Immediates_1 :Eval_Immediates_1
09000532 # MOVE R3 R2 ; Prepare for next loop 09000532 # MOVE R3 R2 ; Prepare for next loop
2CA3 @Eval_Immediates_0 # JUMP.NZ R3 @Eval_Immediates_0 ; And loop E0002CA3 @Eval_Immediates_0 # JUMP.NZ R3 @Eval_Immediates_0 ; And loop
0D01001F # RET R15 0D01001F # RET R15
@ -454,55 +454,55 @@ A0210030 # CMPSKIPI.E R1 48 ; Skip next comparision if '0'
09000510 # MOVE R1 R0 ; Get Text pointer out of the way 09000510 # MOVE R1 R0 ; Get Text pointer out of the way
0D000022 # FALSE R2 ; Set Negative flag to false 0D000022 # FALSE R2 ; Set Negative flag to false
0D000023 # FALSE R3 ; Set current count to Zero 0D000023 # FALSE R3 ; Set current count to Zero
14010001 # LOAD8 R0 R1 1 ; Get second byte E10014010001 # LOAD8 R0 R1 1 ; Get second byte
A0300078 # CMPSKIPI.NE R0 120 ; If the second byte is x E000A0300078 # CMPSKIPI.NE R0 120 ; If the second byte is x
3C00 @numerate_string_hex # JUMP @numerate_string_hex ; treat string like hex 3C00 @numerate_string_hex # JUMP @numerate_string_hex ; treat string like hex
# ;; Deal with Decimal input # ;; Deal with Decimal input
2D24000a # LOADUI R4 10 ; Multiply by 10 E0002D24000a # LOADUI R4 10 ; Multiply by 10
14010000 # LOAD8 R0 R1 0 ; Get a byte E10014010000 # LOAD8 R0 R1 0 ; Get a byte
A030002d # CMPSKIPI.NE R0 45 ; If - toggle flag E000A030002d # CMPSKIPI.NE R0 45 ; If - toggle flag
0D000032 # TRUE R2 ; So that we know to negate 0D000032 # TRUE R2 ; So that we know to negate
A0220000 # CMPSKIPI.E R2 0 ; If toggled E000A0220000 # CMPSKIPI.E R2 0 ; If toggled
0F110001 # ADDUI R1 R1 1 ; Move to next E1000F110001 # ADDUI R1 R1 1 ; Move to next
:numerate_string_dec :numerate_string_dec
14010000 # LOAD8 R0 R1 0 ; Get a byte E10014010000 # LOAD8 R0 R1 0 ; Get a byte
A0300000 # CMPSKIPI.NE R0 0 ; If NULL E000A0300000 # CMPSKIPI.NE R0 0 ; If NULL
3C00 @numerate_string_done # JUMP @numerate_string_done ; Be done 3C00 @numerate_string_done # JUMP @numerate_string_done ; Be done
05006334 # MUL R3 R3 R4 ; Shift counter by 10 05006334 # MUL R3 R3 R4 ; Shift counter by 10
10000030 # SUBI R0 R0 48 ; Convert ascii to number E10010000030 # SUBI R0 R0 48 ; Convert ascii to number
A0100000 # CMPSKIPI.GE R0 0 ; If less than a number E000A0100000 # CMPSKIPI.GE R0 0 ; If less than a number
3C00 @numerate_string_done # JUMP @numerate_string_done ; Terminate NOW 3C00 @numerate_string_done # JUMP @numerate_string_done ; Terminate NOW
A050000a # CMPSKIPI.L R0 10 ; If more than a number E000A050000a # CMPSKIPI.L R0 10 ; If more than a number
3C00 @numerate_string_done # JUMP @numerate_string_done ; Terminate NOW 3C00 @numerate_string_done # JUMP @numerate_string_done ; Terminate NOW
05001330 # ADDU R3 R3 R0 ; Don't add to the count 05001330 # ADDU R3 R3 R0 ; Don't add to the count
0F110001 # ADDUI R1 R1 1 ; Move onto next byte E1000F110001 # ADDUI R1 R1 1 ; Move onto next byte
3C00 @numerate_string_dec # JUMP @numerate_string_dec 3C00 @numerate_string_dec # JUMP @numerate_string_dec
# ;; Deal with Hex input # ;; Deal with Hex input
:numerate_string_hex :numerate_string_hex
14010000 # LOAD8 R0 R1 0 ; Get a byte E10014010000 # LOAD8 R0 R1 0 ; Get a byte
A0200030 # CMPSKIPI.E R0 48 ; All hex strings start with 0x E000A0200030 # CMPSKIPI.E R0 48 ; All hex strings start with 0x
3C00 @numerate_string_done # JUMP @numerate_string_done ; Be done if not a match 3C00 @numerate_string_done # JUMP @numerate_string_done ; Be done if not a match
0F110002 # ADDUI R1 R1 2 ; Move to after leading 0x E1000F110002 # ADDUI R1 R1 2 ; Move to after leading 0x
:numerate_string_hex_0 :numerate_string_hex_0
14010000 # LOAD8 R0 R1 0 ; Get a byte E10014010000 # LOAD8 R0 R1 0 ; Get a byte
2C90 @numerate_string_done # JUMP.Z R0 @numerate_string_done ; If NULL Be done E0002C90 @numerate_string_done # JUMP.Z R0 @numerate_string_done ; If NULL Be done
2D530004 # SL0I R3 4 ; Shift counter by 16 E0002D530004 # SL0I R3 4 ; Shift counter by 16
10000030 # SUBI R0 R0 48 ; Convert ascii number to number E10010000030 # SUBI R0 R0 48 ; Convert ascii number to number
A050000a # CMPSKIPI.L R0 10 ; If A-F E000A050000a # CMPSKIPI.L R0 10 ; If A-F
10000007 # SUBI R0 R0 7 ; Shove into Range E10010000007 # SUBI R0 R0 7 ; Shove into Range
A0500010 # CMPSKIPI.L R0 16 ; If a-f E000A0500010 # CMPSKIPI.L R0 16 ; If a-f
10000020 # SUBI R0 R0 32 ; Shove into Range E10010000020 # SUBI R0 R0 32 ; Shove into Range
05001330 # ADDU R3 R3 R0 ; Add to the count 05001330 # ADDU R3 R3 R0 ; Add to the count
0F110001 # ADDUI R1 R1 1 ; Get next Hex E1000F110001 # ADDUI R1 R1 1 ; Get next Hex
3C00 @numerate_string_hex_0 # JUMP @numerate_string_hex_0 3C00 @numerate_string_hex_0 # JUMP @numerate_string_hex_0
# ;; Clean up # ;; Clean up
:numerate_string_done :numerate_string_done
A0220000 # CMPSKIPI.E R2 0 ; If Negate flag has been set E000A0220000 # CMPSKIPI.E R2 0 ; If Negate flag has been set
09000033 # NEG R3 R3 ; Make the number negative 09000033 # NEG R3 R3 ; Make the number negative
09000503 # MOVE R0 R3 ; Put number in R0 09000503 # MOVE R0 R3 ; Put number in R0
@ -523,18 +523,18 @@ A0220000 # CMPSKIPI.E R2 0 ; If Negate flag has been set
# ;; Process Node # ;; Process Node
:Preserve_Other_0 :Preserve_Other_0
18200000 # LOAD32 R2 R0 0 ; Load Node->Next E10018200000 # LOAD32 R2 R0 0 ; Load Node->Next
18100004 # LOAD32 R1 R0 4 ; Load Node type E10018100004 # LOAD32 R1 R0 4 ; Load Node type
2CA1 @Preserve_Other_1 # JUMP.NZ R1 @Preserve_Other_1 ; Don't do anything if Typed E0002CA1 @Preserve_Other_1 # JUMP.NZ R1 @Preserve_Other_1 ; Don't do anything if Typed
1810000c # LOAD32 R1 R0 12 ; Load Expression pointer E1001810000c # LOAD32 R1 R0 12 ; Load Expression pointer
2CA1 @Preserve_Other_1 # JUMP.NZ R1 @Preserve_Other_1 ; Don't do anything if Expression is set E0002CA1 @Preserve_Other_1 # JUMP.NZ R1 @Preserve_Other_1 ; Don't do anything if Expression is set
18100008 # LOAD32 R1 R0 8 ; Load Text pointer E10018100008 # LOAD32 R1 R0 8 ; Load Text pointer
2310000c # STORE32 R1 R0 12 ; Set Expression pointer to Text pointer E1002310000c # STORE32 R1 R0 12 ; Set Expression pointer to Text pointer
# ;; Loop through nodes # ;; Loop through nodes
:Preserve_Other_1 :Preserve_Other_1
09000502 # MOVE R0 R2 ; Prepare for next loop 09000502 # MOVE R0 R2 ; Prepare for next loop
2CA0 @Preserve_Other_0 # JUMP.NZ R0 @Preserve_Other_0 E0002CA0 @Preserve_Other_0 # JUMP.NZ R0 @Preserve_Other_0
0D01001F # RET R15 0D01001F # RET R15
@ -543,28 +543,28 @@ A0220000 # CMPSKIPI.E R2 0 ; If Negate flag has been set
# ;; Starting with HEAD # ;; Starting with HEAD
:Print_Hex :Print_Hex
# ;; Prep TAPE_02 # ;; Prep TAPE_02
2D201101 # LOADUI R0 0x1101 E0002D201101 # LOADUI R0 0x1101
42100001 # FOPEN_WRITE 42100001 # FOPEN_WRITE
# ;; Initialize # ;; Initialize
0900040D # COPY R0 R13 ; Start with HEAD 0900040D # COPY R0 R13 ; Start with HEAD
2D211101 # LOADUI R1 0x1101 ; Write to Tape_02 E0002D211101 # LOADUI R1 0x1101 ; Write to Tape_02
:Print_Hex_0 :Print_Hex_0
18200000 # LOAD32 R2 R0 0 ; Load Node->Next E10018200000 # LOAD32 R2 R0 0 ; Load Node->Next
18300004 # LOAD32 R3 R0 4 ; Load Node type E10018300004 # LOAD32 R3 R0 4 ; Load Node type
1800000c # LOAD32 R0 R0 12 ; Load Expression pointer E1001800000c # LOAD32 R0 R0 12 ; Load Expression pointer
10330001 # SUBI R3 R3 1 ; Check for Macros E10010330001 # SUBI R3 R3 1 ; Check for Macros
2C93 @Print_Hex_1 # JUMP.Z R3 @Print_Hex_1 ; Don't print Macros E0002C93 @Print_Hex_1 # JUMP.Z R3 @Print_Hex_1 ; Don't print Macros
2D0F @Print_Line # CALLI R15 @Print_Line ; Print the Expression E0002D0F @Print_Line # CALLI R15 @Print_Line ; Print the Expression
# ;; Loop down the nodes # ;; Loop down the nodes
:Print_Hex_1 :Print_Hex_1
09000502 # MOVE R0 R2 ; Prepare for next loop 09000502 # MOVE R0 R2 ; Prepare for next loop
2CA0 @Print_Hex_0 # JUMP.NZ R0 @Print_Hex_0 ; Keep looping if not NULL E0002CA0 @Print_Hex_0 # JUMP.NZ R0 @Print_Hex_0 ; Keep looping if not NULL
# ;; Done writing File # ;; Done writing File
2D201101 # LOADUI R0 0x1101 ; Close TAPE_01 E0002D201101 # LOADUI R0 0x1101 ; Close TAPE_01
42100002 # FCLOSE 42100002 # FCLOSE
0D01001F # RET R15 0D01001F # RET R15
@ -579,16 +579,16 @@ A0220000 # CMPSKIPI.E R2 0 ; If Negate flag has been set
09000530 # MOVE R3 R0 ; Get Pointer safely out of the way 09000530 # MOVE R3 R0 ; Get Pointer safely out of the way
:Print_Line_0 :Print_Line_0
15030000 # LOADU8 R0 R3 0 ; Get our first byte E10015030000 # LOADU8 R0 R3 0 ; Get our first byte
A0300000 # CMPSKIPI.NE R0 0 ; If the loaded byte is NULL E000A0300000 # CMPSKIPI.NE R0 0 ; If the loaded byte is NULL
3C00 @Print_Line_Done # JUMP @Print_Line_Done ; Be done 3C00 @Print_Line_Done # JUMP @Print_Line_Done ; Be done
42100200 # FPUTC ; Otherwise print 42100200 # FPUTC ; Otherwise print
0F330001 # ADDUI R3 R3 1 ; Increment for next loop E1000F330001 # ADDUI R3 R3 1 ; Increment for next loop
3C00 @Print_Line_0 # JUMP @Print_Line_0 ; And Loop 3C00 @Print_Line_0 # JUMP @Print_Line_0 ; And Loop
# ;; Clean up # ;; Clean up
:Print_Line_Done :Print_Line_Done
2D20000a # LOADUI R0 10 ; Put in Newline char E0002D20000a # LOADUI R0 10 ; Put in Newline char
42100200 # FPUTC ; Write it out 42100200 # FPUTC ; Write it out
0D01001F # RET R15 0D01001F # RET R15

View File

@ -1,432 +0,0 @@
## Copyright (C) 2016 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you an redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see <http://www.gnu.org/licenses/>.
# :start
2D2F0394 # LOADUI R15 $stack ; Put stack at end of program
# ;; We will be using R14 for our condition codes
# ;; We will be using R13 for storage of Head
# ;; Main program
# ;; Reads contents of Tape_01 and writes desired contents onto Tape_02
# ;; Accepts no arguments and HALTS when done
# :main
# ;; Prep TAPE_01
2D201100 # LOADUI R0 0x1100
42100000 # FOPEN_READ
# ;; Prepare to Read File
0D00002E # FALSE R14
0D000021 # FALSE R1
2D0F0018 # CALLI R15 @ReadFile
# ;; Done reading File
2D201100 # LOADUI R0 0x1100 ; Close TAPE_01
42100002 # FCLOSE
# ;; Enter Editor Loop
090005D1 # MOVE R13 R1 ; Set R13 to Head
2D0F0134 # CALLI R15 @EditorLoop
# ;; And We are Done
FFFFFFFF # HALT
# ;; Readfile function
# ;; Recieves pointer to head in R1
# ;; Creates Nodes and imports text until EOF
# ;; Alters R0 R1 R14
# ;; Returns to whatever called it
# :ReadFile
# ;; Allocate another Node
2D20000c # LOADUI R0 12
2D0F0100 # CALLI R15 @malloc
# ;; Get another line into list
0902001F # PUSHR R1 R15
2D211100 # LOADUI R1 0x1100 ; Read from tape_01
2D0F001c # CALLI R15 @Readline
0902801F # POPR R1 R15
09000301 # SWAP R0 R1
2D0F00a0 # CALLI R15 @addline
09000301 # SWAP R0 R1
# ;; Loop if not reached EOF
2C9Effdc # JUMP.Z R14 @ReadFile
0D01001F # RET R15
# ;; Readline function
# ;; Recieves Pointer to node in R0
# ;; And Input in R1
# ;; Allocates Text segment on Heap
# ;; Sets node's pointer to Text segment
# ;; Sets R14 to True if EOF reached
# ;; Returns to whatever called it
# :Readline
# ;; Preserve registers
0902000F # PUSHR R0 R15
0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15
0902003F # PUSHR R3 R15
0902004F # PUSHR R4 R15
# ;; Initialize
09000540 # MOVE R4 R0
2D200100 # LOADUI R0 256
2D0F00bc # CALLI R15 @malloc
09000520 # MOVE R2 R0
0D000023 # FALSE R3
# :Readline_0
42100100 # FGETC ; Read a Char
# ;; Flag if reached EOF
A0100000 # CMPSKIPI.GE R0 0
0D00003E # TRUE R14
# ;; Stop if EOF
A0100000 # CMPSKIPI.GE R0 0
3C00003c # JUMP @Readline_2
# ;; Handle Backspace
A020007f # CMPSKIPI.E R0 127
3C000010 # JUMP @Readline_1
# ;; Move back 1 character if R3 > 0
A0430000 # CMPSKIPI.LE R3 0
11330001 # SUBUI R3 R3 1
# ;; Hopefully they keep typing
3C00ffdc # JUMP @Readline_0
# :Readline_1
# ;; Replace all CR with LF
A030000d # CMPSKIPI.NE R0 13
2D20000a # LOADUI R0 10
# ;; Store the Byte
05049023 # STOREX8 R0 R2 R3
# ;; Check for EOL
A030000a # CMPSKIPI.NE R0 10
3C000014 # JUMP @Readline_2
# ;; Prevent lines from exceeding 255 chars
A04300ff # CMPSKIPI.LE R3 255
3C00000c # JUMP @Readline_2
# ;; Prep for next loop
0F330001 # ADDUI R3 R3 1
3C00ffb8 # JUMP @Readline_0
# :Readline_2
# ;; Set Text pointer
23240008 # STORE32 R2 R4 8
# ;; Restore Registers
0902804F # POPR R4 R15
0902803F # POPR R3 R15
0902802F # POPR R2 R15
0902801F # POPR R1 R15
0902800F # POPR R0 R15
0D01001F # RET R15
# ;; addline Function
# ;; Recieves pointers in R0 R1
# ;; Alters R0 if NULL
# ;; Appends nodes together
# ;; Returns to whatever called it
# :addline
# ;; Preserve Registers
0902002F # PUSHR R2 R15
0902001F # PUSHR R1 R15
0902000F # PUSHR R0 R15
# ;; Handle if Head is NULL
2CA00010 # JUMP.NZ R0 @addline_0
0902800F # POPR R0 R15
0902001F # PUSHR R1 R15
3C000020 # JUMP @addline_2
# :addline_0
# ;; Handle if Head->next is NULL
18200000 # LOAD32 R2 R0 0
2CA20010 # JUMP.NZ R2 @addline_1
# ;; Set head->next = p
23100000 # STORE32 R1 R0 0
# ;; Set p->prev = head
23010004 # STORE32 R0 R1 4
3C00000c # JUMP @addline_2
# :addline_1
# ;; Handle case of Head->next not being NULL
18000000 # LOAD32 R0 R0 0
2D0Fffcc # CALLI R15 @addline
# :addline_2
# ;; Restore registers
0902800F # POPR R0 R15
0902801F # POPR R1 R15
0902802F # POPR R2 R15
0D01001F # RET R15
# ;; Primative malloc function
# ;; Recieves number of bytes to allocate in R0
# ;; Returns pointer to block of that size in R0
# ;; Returns to whatever called it
# :malloc
# ;; Preserve registers
0902001F # PUSHR R1 R15
# ;; Get current malloc pointer
2E010020 # LOADR R1 @malloc_pointer
# ;; Deal with special case
A0310000 # CMPSKIPI.NE R1 0 ; If Zero set to our start of heap space
2D214000 # LOADUI R1 0x4000
# ;; update malloc pointer
09000301 # SWAP R0 R1
05000101 # ADD R1 R0 R1
2F01000c # STORER R1 @malloc_pointer
# ;; Done
# ;; Restore registers
0902801F # POPR R1 R15
0D01001F # RET R15
# ;; Our static value for malloc pointer
# :malloc_pointer
00000000 # NOP
# ;; Editor Loop
# ;; Provides user interaction
# ;; Requires R13 to be pointer to Head
# ;; Internally loops
# ;; Returns nothing
# :EditorLoop
0D000021 # FALSE R1 ; Read from tty
42100100 # FGETC ; Read a Char
# ;; Quit if q
A0300071 # CMPSKIPI.NE R0 113
0D01001F # RET R15
# ;; Print if p
1FE00070 # CMPUI R14 R0 112
2C6E0014 # JUMP.NE R14 @EditorLoop_0
180D0008 # LOAD32 R0 R13 8
0D000021 # FALSE R1
2D0F0118 # CALLI R15 @PrintLine
3C00ffdc # JUMP @EditorLoop
# :EditorLoop_0
# ;; Move forward if f
1FE00066 # CMPUI R14 R0 102
2C6E0014 # JUMP.NE R14 @EditorLoop_1
180D0000 # LOAD32 R0 R13 0 ; Load head->next
# ;; If head->next isn't null make it the new head
A0200000 # CMPSKIPI.E R0 0
090005D0 # MOVE R13 R0
3C00ffc4 # JUMP @EditorLoop
# :EditorLoop_1
# ;; Move backward if b
1FE00062 # CMPUI R14 R0 98
2C6E0014 # JUMP.NE R14 @EditorLoop_2
180D0004 # LOAD32 R0 R13 4 ; Load head->prev
# ;; If head->prev isn't null make it the new head
A0200000 # CMPSKIPI.E R0 0
090005D0 # MOVE R13 R0
3C00ffac # JUMP @EditorLoop
# :EditorLoop_2
# ;; Edit Line if e
1FE00065 # CMPUI R14 R0 101
2C6E0014 # JUMP.NE R14 @EditorLoop_3
# ;; Change Head's Text
0900040D # COPY R0 R13
0D000021 # FALSE R1 ; Read from tty
2D0Ffe98 # CALLI R15 @Readline
3C00ff94 # JUMP @EditorLoop
# :EditorLoop_3
# ;; Writeout to tape_02 if w
1FE00077 # CMPUI R14 R0 119
2C6E0028 # JUMP.NE R14 @EditorLoop_4
# ;; Prep TAPE_02
2D201101 # LOADUI R0 0x1101
42100001 # FOPEN_WRITE
0900040D # COPY R0 R13
2D211101 # LOADUI R1 0x1101
2D0F0058 # CALLI R15 @GetRoot
2D0F0074 # CALLI R15 @PrintAll
2D201101 # LOADUI R0 0x1101 ; Close TAPE_02
42100002 # FCLOSE
3C00ff68 # JUMP @EditorLoop
# :EditorLoop_4
# ;; Append node if a
1FE00061 # CMPUI R14 R0 97
2C6E0010 # JUMP.NE R14 @EditorLoop_5
0900040D # COPY R0 R13
2D0F00dc # CALLI R15 @AppendLine
3C00ff54 # JUMP @EditorLoop
# :EditorLoop_5
# ;; Insert node if i
1FE00069 # CMPUI R14 R0 105
2C6E0010 # JUMP.NE R14 @EditorLoop_6
0900040D # COPY R0 R13
2D0F0108 # CALLI R15 @InsertLine
3C00ff40 # JUMP @EditorLoop
# :EditorLoop_6
# ;; Delete node if d
1FE00064 # CMPUI R14 R0 100
2C6E0014 # JUMP.NE R14 @EditorLoop_7
0900040D # COPY R0 R13
2D0F0134 # CALLI R15 @RemoveLine
090005D0 # MOVE R13 R0
3C00ff28 # JUMP @EditorLoop
# :EditorLoop_7
3C00ff24 # JUMP @EditorLoop
# ;; GetRoot function
# ;; Walks backwards through nodes until beginning
# ;; Recieves node pointer in R0 and Returns result in R0
# ;; Returns to whatever called it
# :GetRoot
# ;; Preserve registers
0902001F # PUSHR R1 R15
# :GetRoot_0
# ;; Get Head->Prev
18100004 # LOAD32 R1 R0 4
A0310000 # CMPSKIPI.NE R1 0
3C00000c # JUMP @GetRoot_1
09000501 # MOVE R0 R1
3C00fff0 # JUMP @GetRoot_0
# :GetRoot_1
# ;; Restore registers
0902801F # POPR R1 R15
0D01001F # RET R15
# ;; Printall Function
# ;; Prints all lines to Interface in R1
# ;; Starting at node in R0
# ;; Does not alter registers
# ;; Returns to whatever called it
# :PrintAll
# ;; Preserve registers
0902000F # PUSHR R0 R15
0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15
# :PrintAll_0
18200000 # LOAD32 R2 R0 0 ; Store Head->Next in R2
18000008 # LOAD32 R0 R0 8 ; Set R0 to Head->Text
2D0F0024 # CALLI R15 @PrintLine ; Prints Head->Text
A0320000 # CMPSKIPI.NE R2 0 ; If Head->Next is NULL
3C00000c # JUMP @PrintAll_1 ; Stop Looping
09000502 # MOVE R0 R2 ; Otherwise Move to Next Node
3C00ffe8 # JUMP @PrintAll_0 ; And Loop
# :PrintAll_1
# ;; Restore registers
0902802F # POPR R2 R15
0902801F # POPR R1 R15
0902800F # POPR R0 R15
0D01001F # RET R15
# ;; Printline function
# ;; Recieves a string pointer in R0
# ;; Prints string interface specified in R1
# ;; Does not alter registers
# ;; Returns to whatever called it
# :PrintLine
# ;; Preserve registers
0902000F # PUSHR R0 R15
0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15
0902003F # PUSHR R3 R15
# ;; Initialize
09000520 # MOVE R2 R0
0D000023 # FALSE R3
# ;; Deal with NULL Pointer
A0320000 # CMPSKIPI.NE R2 0
3C00001c # JUMP @PrintLine_1
# :PrintLine_0
0503A023 # LOADXU8 R0 R2 R3 ; Load char from string
# ;; Don't print NULLs
A0300000 # CMPSKIPI.NE R0 0
3C000010 # JUMP @PrintLine_1
42100200 # FPUTC
# ; Print the char
0F330001 # ADDUI R3 R3 1 ; Prep for next loop
3C00ffec # JUMP @PrintLine_0
# :PrintLine_1
# ;; Restore registers
0902803F # POPR R3 R15
0902802F # POPR R2 R15
0902801F # POPR R1 R15
0902800F # POPR R0 R15
0D01001F # RET R15
# ;; AppendLine Function
# ;; Recieves a Node in R0
# ;; Creates a new Node and appends it
# ;; Does not alter registers
# ;; Returns to whatever calls it
# :AppendLine
# ;; Preserve registers
0902000F # PUSHR R0 R15
0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15
# ;; Initialize
09000510 # MOVE R1 R0
# ;; Allocate another Node
2D20000c # LOADUI R0 12
2D0Ffe40 # CALLI R15 @malloc
# ;; Check if head->Next is null
18210000 # LOAD32 R2 R1 0
A0220000 # CMPSKIPI.E R2 0 ; If head->Next is something
23020004 # STORE32 R0 R2 4 ; Set head->next->prev to p
# ;; Setup p and head
23200000 # STORE32 R2 R0 0 ; p->next = head->next
23100004 # STORE32 R1 R0 4 ; p->prev = head
23010000 # STORE32 R0 R1 0 ; head->next = p
# ;; Restore Registers
0902802F # POPR R2 R15
0902801F # POPR R1 R15
0902800F # POPR R0 R15
0D01001F # RET R15
# ;; InsertLine Function
# ;; Recieves a Node in R0
# ;; Creates a new Node and prepends it
# ;; Does not alter registers
# ;; Returns to whatever called it
# :InsertLine
# ;; Preserve Registers
0902000F # PUSHR R0 R15
0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15
# ;; Initialize
09000510 # MOVE R1 R0
# ;; Allocate another Node
2D20000c # LOADUI R0 12
2D0Ffe00 # CALLI R15 @malloc
# ;; Check if Head->Prev is Null
18210004 # LOAD32 R2 R1 4
A0220000 # CMPSKIPI.E R2 0 ; If head->prev is something
23020000 # STORE32 R0 R2 0 ; Set head->prev->next to p
# ;; Setup p and head
23200004 # STORE32 R2 R0 4 ; p->prev = head->prev
23100000 # STORE32 R1 R0 0 ; p->next = head
23010004 # STORE32 R0 R1 4 ; head->prev = p
# ;; Restore Registers
0902802F # POPR R2 R15
0902801F # POPR R1 R15
0902800F # POPR R0 R15
0D01001F # RET R15
# ;; RemoveLine Function
# ;; Recieves Node in R0
# ;; Returns replacement node in R0
# ;; Returns to whatever called it
# :RemoveLine
# ;; Preserve Registers
0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15
# ;; Initialize
09000510 # MOVE R1 R0
18010004 # LOAD32 R0 R1 4 ; put p->prev in R0
18210000 # LOAD32 R2 R1 0 ; put p->next in R2
# ;; Keep links
A0200000 # CMPSKIPI.E R0 0 ; If p->prev is not null
23200000 # STORE32 R2 R0 0 ; p->prev->next = p->next
A0220000 # CMPSKIPI.E R2 0 ; If p->next is not null
23020004 # STORE32 R0 R2 4 ; p->next->prev = p->prev
# ;; Attempt to save what is left of the list
A0300000 # CMPSKIPI.NE R0 0 ; If p->prev is null
09000502 # MOVE R0 R2 ; return p->next
# ;; Restore Registers
0902802F # POPR R2 R15
0902801F # POPR R1 R15
0D01001F # RET R15
# ;; Where our stack begins
# :stack

View File

@ -1,7 +1,7 @@
## Copyright (C) 2016 Jeremiah Orians ## Copyright (C) 2016 Jeremiah Orians
## This file is part of stage0. ## This file is part of stage0.
## ##
## stage0 is free software: you an redistribute it and/or modify ## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by ## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or ## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version. ## (at your option) any later version.
@ -15,28 +15,28 @@
## along with stage0. If not, see <http://www.gnu.org/licenses/>. ## along with stage0. If not, see <http://www.gnu.org/licenses/>.
:start :start
2D2F $stack # LOADUI R15 $stack ; Put stack at end of program E0002D2F $stack # LOADUI R15 $stack ; Put stack at end of program
# ;; We will be using R14 for our condition codes # ;; We will be using R14 for our condition codes
# ;; We will be using R13 for storage of Head # ;; We will be using R13 for storage of Head
E0002D2C4000 # LOADUI R12 0x4000 ; We will be using R12 for the HEAP
# ;; Main program # ;; Main program
# ;; Reads contents of Tape_01 and writes desired contents onto Tape_02 # ;; Reads contents of Tape_01 and writes desired contents onto Tape_02
# ;; Accepts no arguments and HALTS when done # ;; Accepts no arguments and HALTS when done
:main :main
# ;; Prep TAPE_01 # ;; Prep TAPE_01
2D201100 # LOADUI R0 0x1100 E0002D201100 # LOADUI R0 0x1100
42100000 # FOPEN_READ 42100000 # FOPEN_READ
# ;; Prepare to Read File # ;; Prepare to Read File
0D00002E # FALSE R14 0D00002E # FALSE R14
0D000021 # FALSE R1 0D000021 # FALSE R1
2D0F @ReadFile # CALLI R15 @ReadFile E0002D0F @ReadFile # CALLI R15 @ReadFile
# ;; Done reading File # ;; Done reading File
2D201100 # LOADUI R0 0x1100 ; Close TAPE_01 E0002D201100 # LOADUI R0 0x1100 ; Close TAPE_01
42100002 # FCLOSE 42100002 # FCLOSE
# ;; Enter Editor Loop # ;; Enter Editor Loop
090005D1 # MOVE R13 R1 ; Set R13 to Head 090005D1 # MOVE R13 R1 ; Set R13 to Head
2D0F @EditorLoop # CALLI R15 @EditorLoop E0002D0F @EditorLoop # CALLI R15 @EditorLoop
# ;; And We are Done # ;; And We are Done
FFFFFFFF # HALT FFFFFFFF # HALT
@ -48,18 +48,18 @@ FFFFFFFF # HALT
# ;; Returns to whatever called it # ;; Returns to whatever called it
:ReadFile :ReadFile
# ;; Allocate another Node # ;; Allocate another Node
2D20000c # LOADUI R0 12 0900040C # COPY R0 R12 ; Copy Current free into R0
2D0F @malloc # CALLI R15 @malloc E1000FCC000c # ADDUI R12 R12 12 ; Allocate Node
# ;; Get another line into list # ;; Get another line into list
0902001F # PUSHR R1 R15 0902001F # PUSHR R1 R15
2D211100 # LOADUI R1 0x1100 ; Read from tape_01 E0002D211100 # LOADUI R1 0x1100 ; Read from tape_01
2D0F @Readline # CALLI R15 @Readline E0002D0F @Readline # CALLI R15 @Readline
0902801F # POPR R1 R15 0902801F # POPR R1 R15
09000301 # SWAP R0 R1 09000301 # SWAP R0 R1
2D0F @addline # CALLI R15 @addline E0002D0F @addline # CALLI R15 @addline
09000301 # SWAP R0 R1 09000301 # SWAP R0 R1
# ;; Loop if not reached EOF # ;; Loop if not reached EOF
2C9E @ReadFile # JUMP.Z R14 @ReadFile E0002C9E @ReadFile # JUMP.Z R14 @ReadFile
0D01001F # RET R15 0D01001F # RET R15
@ -79,44 +79,49 @@ FFFFFFFF # HALT
0902004F # PUSHR R4 R15 0902004F # PUSHR R4 R15
# ;; Initialize # ;; Initialize
09000540 # MOVE R4 R0 09000540 # MOVE R4 R0
2D200100 # LOADUI R0 256 0900040C # COPY R0 R12 ; Get where space is free
2D0F @malloc # CALLI R15 @malloc
09000520 # MOVE R2 R0 09000520 # MOVE R2 R0
0D000023 # FALSE R3 0D000023 # FALSE R3
:Readline_0 :Readline_0
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
# ;; Flag if reached EOF # ;; Flag if reached EOF
A0100000 # CMPSKIPI.GE R0 0 E000A0100000 # CMPSKIPI.GE R0 0
0D00003E # TRUE R14 0D00003E # TRUE R14
# ;; Stop if EOF # ;; Stop if EOF
A0100000 # CMPSKIPI.GE R0 0 E000A0100000 # CMPSKIPI.GE R0 0
3C00 @Readline_2 # JUMP @Readline_2 3C00 @Readline_2 # JUMP @Readline_2
# ;; Handle Backspace # ;; Handle Backspace
A020007f # CMPSKIPI.E R0 127 E000A020007f # CMPSKIPI.E R0 127
3C00 @Readline_1 # JUMP @Readline_1 3C00 @Readline_1 # JUMP @Readline_1
# ;; Move back 1 character if R3 > 0 # ;; Move back 1 character if R3 > 0
A0430000 # CMPSKIPI.LE R3 0 E000A0430000 # CMPSKIPI.LE R3 0
11330001 # SUBUI R3 R3 1 E10011330001 # SUBUI R3 R3 1
# ;; Hopefully they keep typing # ;; Hopefully they keep typing
3C00 @Readline_0 # JUMP @Readline_0 3C00 @Readline_0 # JUMP @Readline_0
:Readline_1 :Readline_1
# ;; Replace all CR with LF # ;; Replace all CR with LF
A030000d # CMPSKIPI.NE R0 13 E000A030000d # CMPSKIPI.NE R0 13
2D20000a # LOADUI R0 10 E0002D20000a # LOADUI R0 10
# ;; Store the Byte # ;; Store the Byte
05049023 # STOREX8 R0 R2 R3 05049023 # STOREX8 R0 R2 R3
# ;; Check for EOL
A030000a # CMPSKIPI.NE R0 10
3C00 @Readline_2 # JUMP @Readline_2
# ;; Prevent lines from exceeding 255 chars
A04300ff # CMPSKIPI.LE R3 255
3C00 @Readline_2 # JUMP @Readline_2
# ;; Prep for next loop # ;; Prep for next loop
0F330001 # ADDUI R3 R3 1 E1000F330001 # ADDUI R3 R3 1
# ;; Check for EOL
E000A030000a # CMPSKIPI.NE R0 10
3C00 @Readline_2 # JUMP @Readline_2
# ;; Otherwise loop
3C00 @Readline_0 # JUMP @Readline_0 3C00 @Readline_0 # JUMP @Readline_0
:Readline_2 :Readline_2
# ;; Set Text pointer # ;; Set Text pointer
23240008 # STORE32 R2 R4 8 E000A0230000 # CMPSKIPI.E R3 0 ; Don't bother for Empty strings
E10023240008 # STORE32 R2 R4 8
# ;; Correct Malloc
05000CC3 # ADD R12 R12 R3 ; Ensure actually allocates exactly the amount of space required
# ;; Restore Registers # ;; Restore Registers
0902804F # POPR R4 R15 0902804F # POPR R4 R15
0902803F # POPR R3 R15 0902803F # POPR R3 R15
@ -137,23 +142,26 @@ A04300ff # CMPSKIPI.LE R3 255
0902001F # PUSHR R1 R15 0902001F # PUSHR R1 R15
0902000F # PUSHR R0 R15 0902000F # PUSHR R0 R15
# ;; Handle if Head is NULL # ;; Handle if Head is NULL
2CA0 @addline_0 # JUMP.NZ R0 @addline_0 E0002CA0 @addline_0 # JUMP.NZ R0 @addline_0
0902800F # POPR R0 R15 0902800F # POPR R0 R15
0902001F # PUSHR R1 R15 0902001F # PUSHR R1 R15
3C00 @addline_2 # JUMP @addline_2 3C00 @addline_2 # JUMP @addline_2
:addline_0 :addline_0
# ;; Handle if Head->next is NULL # ;; Handle if Head->next is NULL
18200000 # LOAD32 R2 R0 0 E10018200000 # LOAD32 R2 R0 0
2CA2 @addline_1 # JUMP.NZ R2 @addline_1 E0002CA2 @addline_1 # JUMP.NZ R2 @addline_1
# ;; Set head->next = p # ;; Set head->next = p
23100000 # STORE32 R1 R0 0 E10023100000 # STORE32 R1 R0 0
# ;; Set p->prev = head # ;; Set p->prev = head
23010004 # STORE32 R0 R1 4 E10023010004 # STORE32 R0 R1 4
3C00 @addline_2 # JUMP @addline_2 3C00 @addline_2 # JUMP @addline_2
:addline_1 :addline_1
# ;; Handle case of Head->next not being NULL # ;; Handle case of Head->next not being NULL
18000000 # LOAD32 R0 R0 0 E10018000000 # LOAD32 R0 R0 0 ; Move to next node
2D0F @addline # CALLI R15 @addline E10018200000 # LOAD32 R2 R0 0 ; Get node->next
E000A0220000 # CMPSKIPI.E R2 0 ; If it is not null
3C00 @addline_1 # JUMP @addline_1 ; Move to the next node and try again
3C00 @addline_0 # JUMP @addline_0 ; Else simply act as if we got this node in the first place
:addline_2 :addline_2
# ;; Restore registers # ;; Restore registers
0902800F # POPR R0 R15 0902800F # POPR R0 R15
@ -162,31 +170,6 @@ A04300ff # CMPSKIPI.LE R3 255
0D01001F # RET R15 0D01001F # RET R15
# ;; Primative malloc function
# ;; Recieves number of bytes to allocate in R0
# ;; Returns pointer to block of that size in R0
# ;; Returns to whatever called it
:malloc
# ;; Preserve registers
0902001F # PUSHR R1 R15
# ;; Get current malloc pointer
2E01 @malloc_pointer # LOADR R1 @malloc_pointer
# ;; Deal with special case
A0310000 # CMPSKIPI.NE R1 0 ; If Zero set to our start of heap space
2D214000 # LOADUI R1 0x4000
# ;; update malloc pointer
09000301 # SWAP R0 R1
05000101 # ADD R1 R0 R1
2F01 @malloc_pointer # STORER R1 @malloc_pointer
# ;; Done
# ;; Restore registers
0902801F # POPR R1 R15
0D01001F # RET R15
# ;; Our static value for malloc pointer
:malloc_pointer
00000000 # NOP
# ;; Editor Loop # ;; Editor Loop
# ;; Provides user interaction # ;; Provides user interaction
# ;; Requires R13 to be pointer to Head # ;; Requires R13 to be pointer to Head
@ -196,76 +179,76 @@ A0310000 # CMPSKIPI.NE R1 0 ; If Zero set to our start of heap space
0D000021 # FALSE R1 ; Read from tty 0D000021 # FALSE R1 ; Read from tty
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
# ;; Quit if q # ;; Quit if q
A0300071 # CMPSKIPI.NE R0 113 E000A0300071 # CMPSKIPI.NE R0 113
0D01001F # RET R15 0D01001F # RET R15
# ;; Print if p # ;; Print if p
1FE00070 # CMPUI R14 R0 112 E1001FE00070 # CMPUI R14 R0 112
2C6E @EditorLoop_0 # JUMP.NE R14 @EditorLoop_0 E0002C6E @EditorLoop_0 # JUMP.NE R14 @EditorLoop_0
180D0008 # LOAD32 R0 R13 8 E100180D0008 # LOAD32 R0 R13 8
0D000021 # FALSE R1 0D000021 # FALSE R1
2D0F @PrintLine # CALLI R15 @PrintLine E0002D0F @PrintLine # CALLI R15 @PrintLine
3C00 @EditorLoop # JUMP @EditorLoop 3C00 @EditorLoop # JUMP @EditorLoop
:EditorLoop_0 :EditorLoop_0
# ;; Move forward if f # ;; Move forward if f
1FE00066 # CMPUI R14 R0 102 E1001FE00066 # CMPUI R14 R0 102
2C6E @EditorLoop_1 # JUMP.NE R14 @EditorLoop_1 E0002C6E @EditorLoop_1 # JUMP.NE R14 @EditorLoop_1
180D0000 # LOAD32 R0 R13 0 ; Load head->next E100180D0000 # LOAD32 R0 R13 0 ; Load head->next
# ;; If head->next isn't null make it the new head # ;; If head->next isn't null make it the new head
A0200000 # CMPSKIPI.E R0 0 E000A0200000 # CMPSKIPI.E R0 0
090005D0 # MOVE R13 R0 090005D0 # MOVE R13 R0
3C00 @EditorLoop # JUMP @EditorLoop 3C00 @EditorLoop # JUMP @EditorLoop
:EditorLoop_1 :EditorLoop_1
# ;; Move backward if b # ;; Move backward if b
1FE00062 # CMPUI R14 R0 98 E1001FE00062 # CMPUI R14 R0 98
2C6E @EditorLoop_2 # JUMP.NE R14 @EditorLoop_2 E0002C6E @EditorLoop_2 # JUMP.NE R14 @EditorLoop_2
180D0004 # LOAD32 R0 R13 4 ; Load head->prev E100180D0004 # LOAD32 R0 R13 4 ; Load head->prev
# ;; If head->prev isn't null make it the new head # ;; If head->prev isn't null make it the new head
A0200000 # CMPSKIPI.E R0 0 E000A0200000 # CMPSKIPI.E R0 0
090005D0 # MOVE R13 R0 090005D0 # MOVE R13 R0
3C00 @EditorLoop # JUMP @EditorLoop 3C00 @EditorLoop # JUMP @EditorLoop
:EditorLoop_2 :EditorLoop_2
# ;; Edit Line if e # ;; Edit Line if e
1FE00065 # CMPUI R14 R0 101 E1001FE00065 # CMPUI R14 R0 101
2C6E @EditorLoop_3 # JUMP.NE R14 @EditorLoop_3 E0002C6E @EditorLoop_3 # JUMP.NE R14 @EditorLoop_3
# ;; Change Head's Text # ;; Change Head's Text
0900040D # COPY R0 R13 0900040D # COPY R0 R13
0D000021 # FALSE R1 ; Read from tty 0D000021 # FALSE R1 ; Read from tty
2D0F @Readline # CALLI R15 @Readline E0002D0F @Readline # CALLI R15 @Readline
3C00 @EditorLoop # JUMP @EditorLoop 3C00 @EditorLoop # JUMP @EditorLoop
:EditorLoop_3 :EditorLoop_3
# ;; Writeout to tape_02 if w # ;; Writeout to tape_02 if w
1FE00077 # CMPUI R14 R0 119 E1001FE00077 # CMPUI R14 R0 119
2C6E @EditorLoop_4 # JUMP.NE R14 @EditorLoop_4 E0002C6E @EditorLoop_4 # JUMP.NE R14 @EditorLoop_4
# ;; Prep TAPE_02 # ;; Prep TAPE_02
2D201101 # LOADUI R0 0x1101 E0002D201101 # LOADUI R0 0x1101
42100001 # FOPEN_WRITE 42100001 # FOPEN_WRITE
0900040D # COPY R0 R13 0900040D # COPY R0 R13
2D211101 # LOADUI R1 0x1101 E0002D211101 # LOADUI R1 0x1101
2D0F @GetRoot # CALLI R15 @GetRoot E0002D0F @GetRoot # CALLI R15 @GetRoot
2D0F @PrintAll # CALLI R15 @PrintAll E0002D0F @PrintAll # CALLI R15 @PrintAll
2D201101 # LOADUI R0 0x1101 ; Close TAPE_02 E0002D201101 # LOADUI R0 0x1101 ; Close TAPE_02
42100002 # FCLOSE 42100002 # FCLOSE
3C00 @EditorLoop # JUMP @EditorLoop 3C00 @EditorLoop # JUMP @EditorLoop
:EditorLoop_4 :EditorLoop_4
# ;; Append node if a # ;; Append node if a
1FE00061 # CMPUI R14 R0 97 E1001FE00061 # CMPUI R14 R0 97
2C6E @EditorLoop_5 # JUMP.NE R14 @EditorLoop_5 E0002C6E @EditorLoop_5 # JUMP.NE R14 @EditorLoop_5
0900040D # COPY R0 R13 0900040D # COPY R0 R13
2D0F @AppendLine # CALLI R15 @AppendLine E0002D0F @AppendLine # CALLI R15 @AppendLine
3C00 @EditorLoop # JUMP @EditorLoop 3C00 @EditorLoop # JUMP @EditorLoop
:EditorLoop_5 :EditorLoop_5
# ;; Insert node if i # ;; Insert node if i
1FE00069 # CMPUI R14 R0 105 E1001FE00069 # CMPUI R14 R0 105
2C6E @EditorLoop_6 # JUMP.NE R14 @EditorLoop_6 E0002C6E @EditorLoop_6 # JUMP.NE R14 @EditorLoop_6
0900040D # COPY R0 R13 0900040D # COPY R0 R13
2D0F @InsertLine # CALLI R15 @InsertLine E0002D0F @InsertLine # CALLI R15 @InsertLine
3C00 @EditorLoop # JUMP @EditorLoop 3C00 @EditorLoop # JUMP @EditorLoop
:EditorLoop_6 :EditorLoop_6
# ;; Delete node if d # ;; Delete node if d
1FE00064 # CMPUI R14 R0 100 E1001FE00064 # CMPUI R14 R0 100
2C6E @EditorLoop_7 # JUMP.NE R14 @EditorLoop_7 E0002C6E @EditorLoop_7 # JUMP.NE R14 @EditorLoop_7
0900040D # COPY R0 R13 0900040D # COPY R0 R13
2D0F @RemoveLine # CALLI R15 @RemoveLine E0002D0F @RemoveLine # CALLI R15 @RemoveLine
090005D0 # MOVE R13 R0 090005D0 # MOVE R13 R0
3C00 @EditorLoop # JUMP @EditorLoop 3C00 @EditorLoop # JUMP @EditorLoop
:EditorLoop_7 :EditorLoop_7
@ -281,8 +264,8 @@ A0200000 # CMPSKIPI.E R0 0
0902001F # PUSHR R1 R15 0902001F # PUSHR R1 R15
:GetRoot_0 :GetRoot_0
# ;; Get Head->Prev # ;; Get Head->Prev
18100004 # LOAD32 R1 R0 4 E10018100004 # LOAD32 R1 R0 4
A0310000 # CMPSKIPI.NE R1 0 E000A0310000 # CMPSKIPI.NE R1 0
3C00 @GetRoot_1 # JUMP @GetRoot_1 3C00 @GetRoot_1 # JUMP @GetRoot_1
09000501 # MOVE R0 R1 09000501 # MOVE R0 R1
3C00 @GetRoot_0 # JUMP @GetRoot_0 3C00 @GetRoot_0 # JUMP @GetRoot_0
@ -303,10 +286,10 @@ A0310000 # CMPSKIPI.NE R1 0
0902001F # PUSHR R1 R15 0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15 0902002F # PUSHR R2 R15
:PrintAll_0 :PrintAll_0
18200000 # LOAD32 R2 R0 0 ; Store Head->Next in R2 E10018200000 # LOAD32 R2 R0 0 ; Store Head->Next in R2
18000008 # LOAD32 R0 R0 8 ; Set R0 to Head->Text E10018000008 # LOAD32 R0 R0 8 ; Set R0 to Head->Text
2D0F @PrintLine # CALLI R15 @PrintLine ; Prints Head->Text E0002D0F @PrintLine # CALLI R15 @PrintLine ; Prints Head->Text
A0320000 # CMPSKIPI.NE R2 0 ; If Head->Next is NULL E000A0320000 # CMPSKIPI.NE R2 0 ; If Head->Next is NULL
3C00 @PrintAll_1 # JUMP @PrintAll_1 ; Stop Looping 3C00 @PrintAll_1 # JUMP @PrintAll_1 ; Stop Looping
09000502 # MOVE R0 R2 ; Otherwise Move to Next Node 09000502 # MOVE R0 R2 ; Otherwise Move to Next Node
3C00 @PrintAll_0 # JUMP @PrintAll_0 ; And Loop 3C00 @PrintAll_0 # JUMP @PrintAll_0 ; And Loop
@ -333,16 +316,16 @@ A0320000 # CMPSKIPI.NE R2 0 ; If Head->Next is NULL
09000520 # MOVE R2 R0 09000520 # MOVE R2 R0
0D000023 # FALSE R3 0D000023 # FALSE R3
# ;; Deal with NULL Pointer # ;; Deal with NULL Pointer
A0320000 # CMPSKIPI.NE R2 0 E000A0320000 # CMPSKIPI.NE R2 0
3C00 @PrintLine_1 # JUMP @PrintLine_1 3C00 @PrintLine_1 # JUMP @PrintLine_1
:PrintLine_0 :PrintLine_0
0503A023 # LOADXU8 R0 R2 R3 ; Load char from string 0503A023 # LOADXU8 R0 R2 R3 ; Load char from string
# ;; Don't print NULLs # ;; Don't print NULLs
A0300000 # CMPSKIPI.NE R0 0 E000A0300000 # CMPSKIPI.NE R0 0
3C00 @PrintLine_1 # JUMP @PrintLine_1 3C00 @PrintLine_1 # JUMP @PrintLine_1
42100200 # FPUTC 42100200 # FPUTC
# ; Print the char # ; Print the char
0F330001 # ADDUI R3 R3 1 ; Prep for next loop E1000F330001 # ADDUI R3 R3 1 ; Prep for next loop
3C00 @PrintLine_0 # JUMP @PrintLine_0 3C00 @PrintLine_0 # JUMP @PrintLine_0
:PrintLine_1 :PrintLine_1
# ;; Restore registers # ;; Restore registers
@ -366,16 +349,16 @@ A0300000 # CMPSKIPI.NE R0 0
# ;; Initialize # ;; Initialize
09000510 # MOVE R1 R0 09000510 # MOVE R1 R0
# ;; Allocate another Node # ;; Allocate another Node
2D20000c # LOADUI R0 12 0900040C # COPY R0 R12
2D0F @malloc # CALLI R15 @malloc E1000FCC000c # ADDUI R12 R12 12
# ;; Check if head->Next is null # ;; Check if head->Next is null
18210000 # LOAD32 R2 R1 0 E10018210000 # LOAD32 R2 R1 0
A0220000 # CMPSKIPI.E R2 0 ; If head->Next is something E000A0220000 # CMPSKIPI.E R2 0 ; If head->Next is something
23020004 # STORE32 R0 R2 4 ; Set head->next->prev to p E10023020004 # STORE32 R0 R2 4 ; Set head->next->prev to p
# ;; Setup p and head # ;; Setup p and head
23200000 # STORE32 R2 R0 0 ; p->next = head->next E10023200000 # STORE32 R2 R0 0 ; p->next = head->next
23100004 # STORE32 R1 R0 4 ; p->prev = head E10023100004 # STORE32 R1 R0 4 ; p->prev = head
23010000 # STORE32 R0 R1 0 ; head->next = p E10023010000 # STORE32 R0 R1 0 ; head->next = p
# ;; Restore Registers # ;; Restore Registers
0902802F # POPR R2 R15 0902802F # POPR R2 R15
0902801F # POPR R1 R15 0902801F # POPR R1 R15
@ -396,16 +379,16 @@ A0220000 # CMPSKIPI.E R2 0 ; If head->Next is something
# ;; Initialize # ;; Initialize
09000510 # MOVE R1 R0 09000510 # MOVE R1 R0
# ;; Allocate another Node # ;; Allocate another Node
2D20000c # LOADUI R0 12 0900040C # COPY R0 R12
2D0F @malloc # CALLI R15 @malloc E1000FCC000c # ADDUI R12 R12 12
# ;; Check if Head->Prev is Null # ;; Check if Head->Prev is Null
18210004 # LOAD32 R2 R1 4 E10018210004 # LOAD32 R2 R1 4
A0220000 # CMPSKIPI.E R2 0 ; If head->prev is something E000A0220000 # CMPSKIPI.E R2 0 ; If head->prev is something
23020000 # STORE32 R0 R2 0 ; Set head->prev->next to p E10023020000 # STORE32 R0 R2 0 ; Set head->prev->next to p
# ;; Setup p and head # ;; Setup p and head
23200004 # STORE32 R2 R0 4 ; p->prev = head->prev E10023200004 # STORE32 R2 R0 4 ; p->prev = head->prev
23100000 # STORE32 R1 R0 0 ; p->next = head E10023100000 # STORE32 R1 R0 0 ; p->next = head
23010004 # STORE32 R0 R1 4 ; head->prev = p E10023010004 # STORE32 R0 R1 4 ; head->prev = p
# ;; Restore Registers # ;; Restore Registers
0902802F # POPR R2 R15 0902802F # POPR R2 R15
0902801F # POPR R1 R15 0902801F # POPR R1 R15
@ -423,15 +406,15 @@ A0220000 # CMPSKIPI.E R2 0 ; If head->prev is something
0902002F # PUSHR R2 R15 0902002F # PUSHR R2 R15
# ;; Initialize # ;; Initialize
09000510 # MOVE R1 R0 09000510 # MOVE R1 R0
18010004 # LOAD32 R0 R1 4 ; put p->prev in R0 E10018010004 # LOAD32 R0 R1 4 ; put p->prev in R0
18210000 # LOAD32 R2 R1 0 ; put p->next in R2 E10018210000 # LOAD32 R2 R1 0 ; put p->next in R2
# ;; Keep links # ;; Keep links
A0200000 # CMPSKIPI.E R0 0 ; If p->prev is not null E000A0200000 # CMPSKIPI.E R0 0 ; If p->prev is not null
23200000 # STORE32 R2 R0 0 ; p->prev->next = p->next E10023200000 # STORE32 R2 R0 0 ; p->prev->next = p->next
A0220000 # CMPSKIPI.E R2 0 ; If p->next is not null E000A0220000 # CMPSKIPI.E R2 0 ; If p->next is not null
23020004 # STORE32 R0 R2 4 ; p->next->prev = p->prev E10023020004 # STORE32 R0 R2 4 ; p->next->prev = p->prev
# ;; Attempt to save what is left of the list # ;; Attempt to save what is left of the list
A0300000 # CMPSKIPI.NE R0 0 ; If p->prev is null E000A0300000 # CMPSKIPI.NE R0 0 ; If p->prev is null
09000502 # MOVE R0 R2 ; return p->next 09000502 # MOVE R0 R2 ; return p->next
# ;; Restore Registers # ;; Restore Registers
0902802F # POPR R2 R15 0902802F # POPR R2 R15

View File

@ -18,6 +18,7 @@
LOADUI R15 $stack ; Put stack at end of program LOADUI R15 $stack ; Put stack at end of program
;; We will be using R14 for our condition codes ;; We will be using R14 for our condition codes
;; We will be using R13 for storage of Head ;; We will be using R13 for storage of Head
LOADUI R12 0x4000 ; We will be using R12 for the HEAP
;; Main program ;; Main program
@ -52,8 +53,8 @@
;; Returns to whatever called it ;; Returns to whatever called it
:ReadFile :ReadFile
;; Allocate another Node ;; Allocate another Node
LOADUI R0 12 COPY R0 R12 ; Copy Current free into R0
CALLI R15 @malloc ADDUI R12 R12 12 ; Allocate Node
;; Get another line into list ;; Get another line into list
PUSHR R1 R15 PUSHR R1 R15
LOADUI R1 0x1100 ; Read from tape_01 LOADUI R1 0x1100 ; Read from tape_01
@ -83,8 +84,7 @@
PUSHR R4 R15 PUSHR R4 R15
;; Initialize ;; Initialize
MOVE R4 R0 MOVE R4 R0
FALSE R0 ; Get where space is free COPY R0 R12 ; Get where space is free
CALLI R15 @malloc
MOVE R2 R0 MOVE R2 R0
FALSE R3 FALSE R3
:Readline_0 :Readline_0
@ -132,8 +132,7 @@
CMPSKIPI.E R3 0 ; Don't bother for Empty strings CMPSKIPI.E R3 0 ; Don't bother for Empty strings
STORE32 R2 R4 8 STORE32 R2 R4 8
;; Correct Malloc ;; Correct Malloc
MOVE R0 R3 ; Ensure actually allocates exactly ADD R12 R12 R3 ; Ensure actually allocates exactly the amount of space required
CALLI R15 @malloc ; the amount of space required
;; Restore Registers ;; Restore Registers
POPR R4 R15 POPR R4 R15
POPR R3 R15 POPR R3 R15
@ -187,33 +186,6 @@
RET R15 RET R15
;; Primative malloc function
;; Recieves number of bytes to allocate in R0
;; Returns pointer to block of that size in R0
;; Returns to whatever called it
:malloc
;; Preserve registers
PUSHR R1 R15
;; Get current malloc pointer
LOADR R1 @malloc_pointer
;; Deal with special case
CMPSKIPI.NE R1 0 ; If Zero set to our start of heap space
LOADUI R1 0x4000
;; update malloc pointer
SWAP R0 R1
ADD R1 R0 R1
STORER R1 @malloc_pointer
;; Done
;; Restore registers
POPR R1 R15
RET R15
;; Our static value for malloc pointer
:malloc_pointer
NOP
;; Editor Loop ;; Editor Loop
;; Provides user interaction ;; Provides user interaction
;; Requires R13 to be pointer to Head ;; Requires R13 to be pointer to Head
@ -414,8 +386,8 @@
;; Initialize ;; Initialize
MOVE R1 R0 MOVE R1 R0
;; Allocate another Node ;; Allocate another Node
LOADUI R0 12 COPY R0 R12
CALLI R15 @malloc ADDUI R12 R12 12
;; Check if head->Next is null ;; Check if head->Next is null
LOAD32 R2 R1 0 LOAD32 R2 R1 0
@ -447,8 +419,8 @@
;; Initialize ;; Initialize
MOVE R1 R0 MOVE R1 R0
;; Allocate another Node ;; Allocate another Node
LOADUI R0 12 COPY R0 R12
CALLI R15 @malloc ADDUI R12 R12 12
;; Check if Head->Prev is Null ;; Check if Head->Prev is Null
LOAD32 R2 R1 4 LOAD32 R2 R1 4

View File

@ -1,7 +1,7 @@
## Copyright (C) 2016 Jeremiah Orians ## Copyright (C) 2016 Jeremiah Orians
## This file is part of stage0. ## This file is part of stage0.
## ##
## stage0 is free software: you an redistribute it and/or modify ## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by ## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or ## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version. ## (at your option) any later version.
@ -16,7 +16,7 @@
# :start # :start
0D00002E # FALSE R14 ; R14 will be storing our current address 0D00002E # FALSE R14 ; R14 will be storing our current address
2D2F00e0 # LOADUI R15 $end ; We will be using R15 for our stack E0002D2F0118 # LOADUI R15 $end ; We will be using R15 for our stack
# ;; Main program functionality # ;; Main program functionality
@ -24,29 +24,29 @@
# ;; Accepts no arguments and HALTS when done # ;; Accepts no arguments and HALTS when done
# :main # :main
# ;; Prep TAPE_01 # ;; Prep TAPE_01
2D201100 # LOADUI R0 0x1100 E0002D201100 # LOADUI R0 0x1100
42100000 # FOPEN_READ 42100000 # FOPEN_READ
# ;; Prep TAPE_02 # ;; Prep TAPE_02
2D201101 # LOADUI R0 0x1101 E0002D201101 # LOADUI R0 0x1101
42100001 # FOPEN_WRITE 42100001 # FOPEN_WRITE
# ;; Perform main loop # ;; Perform main loop
# :main_0 # :main_0
2D211100 # LOADUI R1 0x1100 ; Read from tape_01 E0002D211100 # LOADUI R1 0x1100 ; Read from tape_01
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
# ;; Check for EOF # ;; Check for EOF
A0100000 # CMPSKIPI.GE R0 0 E000A0100000 # CMPSKIPI.GE R0 0
3C000010 # JUMP @main_1 3C000010 # JUMP @main_1
# ;; Process that byte # ;; Process that byte
2D0F0020 # CALLI R15 @dehex E0002D0F0022 # CALLI R15 @dehex
# ;; Increment address # ;; Increment address
0FEE0001 # ADDUI R14 R14 1 E1000FEE0001 # ADDUI R14 R14 1
# ;; Get next byte # ;; Get next byte
3C00ffe8 # JUMP @main_0 3C00ffdc # JUMP @main_0
# :main_1 # :main_1
# ;; Close up as we are done # ;; Close up as we are done
2D201100 # LOADUI R0 0x1100 ; Close TAPE_01 E0002D201100 # LOADUI R0 0x1100 ; Close TAPE_01
42100002 # FCLOSE 42100002 # FCLOSE
2D201101 # LOADUI R0 0x1101 ; Close TAPE_02 E0002D201101 # LOADUI R0 0x1101 ; Close TAPE_02
42100002 # FCLOSE 42100002 # FCLOSE
FFFFFFFF # HALT FFFFFFFF # HALT
@ -56,29 +56,29 @@ FFFFFFFF # HALT
# ;; Prints address every 4th byte # ;; Prints address every 4th byte
# ;; Alters R0 # ;; Alters R0
# ;; Returns to whatever called it # ;; Returns to whatever called it
# :dehex # :dehex 5a
0902001F # PUSHR R1 R15 ; Preserve R1 0902001F # PUSHR R1 R15 ; Preserve R1
0902000F # PUSHR R0 R15 ; Save byte until after address 0902000F # PUSHR R0 R15 ; Save byte until after address
B00E0003 # ANDI R0 R14 3 ; Get mod 4 of address E100B00E0003 # ANDI R0 R14 3 ; Get mod 4 of address
2D211101 # LOADUI R1 0x1101 ; We want it on TAPE_02 E0002D211101 # LOADUI R1 0x1101 ; We want it on TAPE_02
A0200000 # CMPSKIPI.E R0 0 ; if not zero E000A0200000 # CMPSKIPI.E R0 0 ; if not zero
3C000024 # JUMP @dehex_0 ; Skip placing address 3C000028 # JUMP @dehex_0 ; Skip placing address
# ;; Prepend new line # ;; Prepend new line
2D20000a # LOADUI R0 10 ; First print line feed E0002D20000a # LOADUI R0 10 ; First print line feed
42100200 # FPUTC ; Write it 42100200 # FPUTC ; Write it
# ;; Write out address # ;; Write out address
0900040E # COPY R0 R14 ; Prep for call 0900040E # COPY R0 R14 ; Prep for call
2D0F002c # CALLI R15 @hex32 ; Let it handle the details E0002D0F0030 # CALLI R15 @hex32 ; Let it handle the details
# ;; Write out : char # ;; Write out : char
2D20003a # LOADUI R0 58 ; Prep E0002D20003a # LOADUI R0 58 ; Prep
42100200 # FPUTC ; Write it 42100200 # FPUTC ; Write it
# ;; Write out tab # ;; Write out tab
2D200009 # LOADUI R0 9 ; Prep E0002D200009 # LOADUI R0 9 ; Prep
42100200 # FPUTC ; Write it 42100200 # FPUTC ; Write it
# :dehex_0 # :dehex_0 a0
0902800F # POPR R0 R15 ; Restore byte recieved 0902800F # POPR R0 R15 ; Restore byte recieved
2D0F0034 # CALLI R15 @hex8 ; Use a subset E0002D0F003a # CALLI R15 @hex8 ; Use a subset
2D200020 # LOADUI R0 32 ; Prep for writing space E0002D200020 # LOADUI R0 32 ; Prep for writing space
42100200 # FPUTC ; Write it 42100200 # FPUTC ; Write it
0902801F # POPR R1 R15 ; Restore R1 0902801F # POPR R1 R15 ; Restore R1
0D01001F # RET R15 ; Return to caller 0D01001F # RET R15 ; Return to caller
@ -88,26 +88,27 @@ A0200000 # CMPSKIPI.E R0 0 ; if not zero
# ;; Accepts 32bit value in R0 # ;; Accepts 32bit value in R0
# ;; Require R1 to be the device to write the results # ;; Require R1 to be the device to write the results
# ;; Returns to whatever called it # ;; Returns to whatever called it
# :hex32 # :hex32 bc
0902000F # PUSHR R0 R15 0902000F # PUSHR R0 R15
2D600010 # SR0I R0 16 ; Do high word first E0002D600010 # SR0I R0 16 ; Do high word first
2D0F0008 # CALLI R15 @hex16 E0002D0F0004 # CALLI R15 @hex16
0902800F # POPR R0 R15 0902800F # POPR R0 R15
# :hex16 # :hex16 d0
0902000F # PUSHR R0 R15 0902000F # PUSHR R0 R15
2D600008 # SR0I R0 8 ; Do high byte first E0002D600008 # SR0I R0 8 ; Do high byte first
2D0F0008 # CALLI R15 @hex8 E0002D0F0004 # CALLI R15 @hex8
0902800F # POPR R0 R15 0902800F # POPR R0 R15
# :hex8 # :hex8 e4
0902000F # PUSHR R0 R15 0902000F # PUSHR R0 R15
2D600004 # SR0I R0 4 ; Do high nybble first E0002D600004 # SR0I R0 4 ; Do high nybble first
2D0F0008 # CALLI R15 @hex4 E0002D0F0004 # CALLI R15 @hex4
0902800F # POPR R0 R15 0902800F # POPR R0 R15
# :hex4 # :hex4 f8
B000000f # ANDI R0 R0 0x000F ; isolate nybble E100B000000f # ANDI R0 R0 0x000F ; isolate nybble
0F000030 # ADDUI R0 R0 48 ; convert to ascii E1000F000030 # ADDUI R0 R0 48 ; convert to ascii
A0400039 # CMPSKIPI.LE R0 57 ; If nybble was greater than '9' E000A0400039 # CMPSKIPI.LE R0 57 ; If nybble was greater than '9'
0F000007 # ADDUI R0 R0 7 ; Shift it into 'A' range of ascii E1000F000007 # ADDUI R0 R0 7 ; Shift it into 'A' range of ascii
42100200 # FPUTC ; Print char 42100200 # FPUTC ; Print char
0D01001F # RET R15 ; Get next nybble or return if done 0D01001F # RET R15 ; Get next nybble or return if done
# :end # ;; Where we are putting our stack
# :end 118

View File

@ -14,97 +14,97 @@
## You should have received a copy of the GNU General Public License ## You should have received a copy of the GNU General Public License
## along with stage0. If not, see <http://www.gnu.org/licenses/>. ## along with stage0. If not, see <http://www.gnu.org/licenses/>.
#:start # :start 0
2D2B0001 # LOADUI R11 1 ; Our toggle E0002D2B0001 # LOADUI R11 1 ; Our toggle
# ;; R14 is storing our condition code # ;; R14 is storing our condition code
# ;; R15 is storing our nybble # ;; R15 is storing our nybble
# ;; Prep TAPE_01 # ;; Prep TAPE_01
2D201100 # LOADUI R0 0x1100 E0002D201100 # LOADUI R0 0x1100
42100000 # FOPEN_READ 42100000 # FOPEN_READ
# ;; Prep TAPE_02 # ;; Prep TAPE_02
2D201101 # LOADUI R0 0x1101 E0002D201101 # LOADUI R0 0x1101
42100001 # FOPEN_WRITE 42100001 # FOPEN_WRITE
2D211100 # LOADUI R1 0x1100 ; Read from tape_01 E0002D211100 # LOADUI R1 0x1100 ; Read from tape_01
# ;; Main program loop # ;; Main program loop
# ;; Halts when done # ;; Halts when done
# :loop 18 # :loop 20
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
# ;; Check for EOF # ;; Check for EOF
2CC00098 # JUMP.NP R0 @finish E0002CC000b8 # JUMP.NP R0 @finish
3C000038 # JUMP @hex ; Convert it 3C000044 # JUMP @hex ; Convert it
# :loop_1 24 # :loop_1 2e
2CC0fff4 # JUMP.NP R0 @loop ; Don't use nonhex chars E0002CC0ffec # JUMP.NP R0 @loop ; Don't use nonhex chars
2C9B0010 # JUMP.Z R11 @loop_2 ; Jump if toggled E0002C9B000e # JUMP.Z R11 @loop_2 ; Jump if toggled
# ;; Process first byte of pair # ;; Process first byte of pair
B0F0000f # ANDI R15 R0 0xF ; Store First nibble E100B0F0000f # ANDI R15 R0 0xF ; Store First nibble
0D00002B # FALSE R11 ; Flip the toggle 0D00002B # FALSE R11 ; Flip the toggle
3C00ffe4 # JUMP @loop 3C00ffd8 # JUMP @loop
# :loop_2 38 # :loop_2 48
2D5F0004 # SL0I R15 4 ; Shift our first nibble E0002D5F0004 # SL0I R15 4 ; Shift our first nibble
B000000f # ANDI R0 R0 0xF ; Mask out top E100B000000f # ANDI R0 R0 0xF ; Mask out top
0500000F # ADD R0 R0 R15 ; Combine nibbles 0500000F # ADD R0 R0 R15 ; Combine nibbles
2D1B0001 # LOADI R11 1 ; Flip the toggle E0002D1B0001 # LOADI R11 1 ; Flip the toggle
2D211101 # LOADUI R1 0x1101 ; Write the combined byte E0002D211101 # LOADUI R1 0x1101 ; Write the combined byte
42100200 # FPUTC ; To TAPE_02 42100200 # FPUTC ; To TAPE_02
2D211100 # LOADUI R1 0x1100 ; Read from tape_01 E0002D211100 # LOADUI R1 0x1100 ; Read from tape_01
3C00ffc4 # JUMP @loop ; Try to get more bytes 3C00ffae # JUMP @loop ; Try to get more bytes
# ;; Hex function # ;; Hex function
# ;; Converts Ascii chars to their hex values # ;; Converts Ascii chars to their hex values
# ;; Or -1 if not a hex char # ;; Or -1 if not a hex char
# ;; Returns to whatever called it # ;; Returns to whatever called it
# :hex 58 # :hex 72
# ;; Deal with line comments starting with # # ;; Deal with line comments starting with #
A0300023 # CMPSKIPI.NE R0 35 E000A0300023 # CMPSKIPI.NE R0 35
3C000044 # JUMP @ascii_comment 3C000050 # JUMP @ascii_comment
# ;; Deal with line comments starting with ; # ;; Deal with line comments starting with ;
A030003b # CMPSKIPI.NE R0 59 E000A030003b # CMPSKIPI.NE R0 59
3C00003c # JUMP @ascii_comment 3C000046 # JUMP @ascii_comment
# ;; Deal with all ascii less than '0' # ;; Deal with all ascii less than '0'
A0100030 # CMPSKIPI.GE R0 48 E000A0100030 # CMPSKIPI.GE R0 48
3C000040 # JUMP @ascii_other 3C00004a # JUMP @ascii_other
# ;; Deal with '0'-'9' # ;; Deal with '0'-'9'
A0000039 # CMPSKIPI.G R0 57 E000A0000039 # CMPSKIPI.G R0 57
3C00001c # JUMP @ascii_num 3C00001e # JUMP @ascii_num
# ;; Unset high bit to set everything into uppercase # ;; Unset high bit to set everything into uppercase
B00000df # ANDI R0 R0 0xDF E100B00000df # ANDI R0 R0 0xDF
# ;; Deal with all ascii less than 'A' # ;; Deal with all ascii less than 'A'
A0100041 # CMPSKIPI.GE R0 65 E000A0100041 # CMPSKIPI.GE R0 65
3C00002c # JUMP @ascii_other 3C000030 # JUMP @ascii_other
# ;; Deal with 'A'-'F' # ;; Deal with 'A'-'F'
A0000046 # CMPSKIPI.G R0 70 E000A0000046 # CMPSKIPI.G R0 70
3C000010 # JUMP @ascii_high 3C00000e # JUMP @ascii_high
# ;; Ignore the rest # ;; Ignore the rest
3C000020 # JUMP @ascii_other 3C000022 # JUMP @ascii_other
# :ascii_num 90 # :ascii_num b8
11000030 # SUBUI R0 R0 48 E10011000030 # SUBUI R0 R0 48
3C00ff90 # JUMP @loop_1 3C00ff6c # JUMP @loop_1
# :ascii_high 98 # :ascii_high c2
11000037 # SUBUI R0 R0 55 E10011000037 # SUBUI R0 R0 55
3C00ff88 # JUMP @loop_1 3C00ff62 # JUMP @loop_1
# :ascii_comment a0 # :ascii_comment cc
42100100 # FGETC ; Read another char 42100100 # FGETC ; Read another char
A020000a # CMPSKIPI.E R0 10 ; Stop at the end of line E000A020000a # CMPSKIPI.E R0 10 ; Stop at the end of line
3C00fff8 # JUMP @ascii_comment ; Otherwise keep looping 3C00fff2 # JUMP @ascii_comment ; Otherwise keep looping
# :ascii_other ac # :ascii_other da
0D000030 # TRUE R0 0D000030 # TRUE R0
3C00ff74 # JUMP @loop_1 3C00ff4c # JUMP @loop_1
# ;; Finish function # ;; Finish function
# ;; Cleans up at the end of the program # ;; Cleans up at the end of the program
# ;; Performs the HALT # ;; Performs the HALT
# :finish b4 # :finish e2
2D201100 # LOADUI R0 0x1100 ; Close TAPE_01 E0002D201100 # LOADUI R0 0x1100 ; Close TAPE_01
42100002 # FCLOSE 42100002 # FCLOSE
2D201101 # LOADUI R0 0x1101 ; Close TAPE_02 E0002D201101 # LOADUI R0 0x1101 ; Close TAPE_02
42100002 # FCLOSE 42100002 # FCLOSE
FFFFFFFF # HALT FFFFFFFF # HALT

View File

@ -14,203 +14,204 @@
## You should have received a copy of the GNU General Public License ## You should have received a copy of the GNU General Public License
## along with stage0. If not, see <http://www.gnu.org/licenses/>. ## along with stage0. If not, see <http://www.gnu.org/licenses/>.
#:start 0 # :start 0
2D2B0200 # LOADUI R11 0x200 ; Where we are putting our address pointers E0002D2B0200 # LOADUI R11 0x200 ; Where we are putting our address pointers
0D00003C # TRUE R12 ; Our toggle 0D00003C # TRUE R12 ; Our toggle
0D00002D # FALSE R13 ; Our PC counter 0D00002D # FALSE R13 ; Our PC counter
2D2E0040 # LOADUI R14 $getLables_2 ; our first iterator E0002D2E0050 # LOADUI R14 $getLables_2 ; our first iterator
# ;; We will be using R15 for holding our processed nybbles # ;; We will be using R15 for holding our processed nybbles
# ;; Prep TAPE_01 # ;; Prep TAPE_01
2D201100 # LOADUI R0 0x1100 E0002D201100 # LOADUI R0 0x1100
42100000 # FOPEN_READ 42100000 # FOPEN_READ
# ;; Prep TAPE_02 # ;; Prep TAPE_02
2D201101 # LOADUI R0 0x1101 E0002D201101 # LOADUI R0 0x1101
42100001 # FOPEN_WRITE 42100001 # FOPEN_WRITE
2D211100 # LOADUI R1 0x1100 ; Read from tape_01 E0002D211100 # LOADUI R1 0x1100 ; Read from tape_01
# ;; Function for collecting the address of all labels # ;; Function for collecting the address of all labels
#:getLables 24 # :getLables 2e
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
2CC00048 # JUMP.NP R0 @stage2 ; Check for EOF
# ;; Check for EOF
E0002CC00052 # JUMP.NP R0 @stage2
# ;; Check for Label # ;; Check for Label
A030003A # CMPSKIPI.NE R0 58 ; If the Char is : the next char is the label E000A030003a # CMPSKIPI.NE R0 58 ; If the Char is : the next char is the label
3C000030 # JUMP @storeLabel 3C000036 # JUMP @storeLabel
# ;; Check for pointer to label # ;; Check for pointer to label
A0300040 # CMPSKIPI.NE R0 64 ; If the Char is @ the next char is the pointer to a label E000A0300040 # CMPSKIPI.NE R0 64 ; If the Char is @ the next char is the pointer to a label
3C00001C # JUMP @ignorePointer 3C00001e # JUMP @ignorePointer
# ;; Otherwise attempt to process # ;; Otherwise attempt to process
3C0000DC # JUMP @hex ; Convert it 3C000100 # JUMP @hex ; Convert it
#:getLables_2 40 # :getLables_2 50
2CC0FFE4 # JUMP.NP R0 @getLables ; Don't record, nonhex values E0002CC0ffd8 # JUMP.NP R0 @getLables ; Don't record, nonhex values
090006CC # NOT R12 R12 ; Flip the toggle 090006CC # NOT R12 R12 ; Flip the toggle
2C9CFFDC # JUMP.Z R12 @getLables ; First half doesn't need anything E0002C9Cffce # JUMP.Z R12 @getLables ; First half doesn't need anything
# ;; Deal with case of second half of byte # ;; Deal with case of second half of byte
0FDD0001 # ADDUI R13 R13 1 ; increment PC now that we have a full byte E1000FDD0001 # ADDUI R13 R13 1 ; increment PC now that we have a full byte
3C00FFD4 # JUMP @getLables 3C00ffc4 # JUMP @getLables
#:ignorePointer 54 # :ignorePointer 6a
# ;; Ignore the pointer for now # ;; Ignore the pointer for now
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
0FDD0002 # ADDUI R13 R13 2 ; The pointer will end up taking 2 bytes E1000FDD0002 # ADDUI R13 R13 2 ; The pointer will end up taking 2 bytes
3C00FFC8 # JUMP @getLables 3C00ffb6 # JUMP @getLables
# ;; Function for storing the address of the label # ;; Function for storing the address of the label
#:storeLabel 60 # :storeLabel 78
# ;; Get the char of the Label # ;; Get the char of the Label
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
# ;; We require 2 bytes to store the pointer values # ;; We require 2 bytes to store the pointer values
2D500001 # SL0I R0 1 ; Thus we multiply our label by 2 E0002D500001 # SL0I R0 1 ; Thus we multiply our label by 2
# ;; Store the current Program counter # ;; Store the current Program counter
0504ADB0 # STOREX16 R13 R11 R0 0504ADB0 # STOREX16 R13 R11 R0
# ;; Label is safely stored, return # ;; Label is safely stored, return
3C00FFB8 # JUMP @getLables 3C00ffa4 # JUMP @getLables
# ;; Now that we have all of the label addresses, # ;; Now that we have all of the label addresses,
# ;; We can process input to produce our output # ;; We can process input to produce our output
#:stage2 70 # :stage2 8a
# ;; We first need to rewind tape_01 to perform our second pass # ;; We first need to rewind tape_01 to perform our second pass
2D201100 # LOADUI R0 0x1100 E0002D201100 # LOADUI R0 0x1100
42100003 # REWIND 42100003 # REWIND
# ;; Reset our toggle and counter # ;; Reset our toggle and counter
2D291101 # LOADUI R9 0x1101 ; Where to write the combined byte E0002D291101 # LOADUI R9 0x1101 ; Where to write the combined byte
0D00003C # TRUE R12 ; Our toggle 0D00003C # TRUE R12 ; Our toggle
0D00002D # FALSE R13 ; Our PC counter 0D00002D # FALSE R13 ; Our PC counter
2D2E00A4 # LOADUI R14 $loop_hex ; The hex return target E0002D2E00ca # LOADUI R14 $loop_hex ; The hex return target
# :loop a8
42100100 # FGETC ; Read a Char
#:loop 88
42100100 # FGETC ; Read a Char
# ;; Check for EOF # ;; Check for EOF
2CC000E8 # JUMP.NP R0 @finish E0002CC0010e # JUMP.NP R0 @finish
# ;; Check for Label # ;; Check for Label
A030003A # CMPSKIPI.NE R0 58 ; Make sure we jump over the label E000A030003a # CMPSKIPI.NE R0 58 ; Make sure we jump over the label
3C000044 # JUMP @ignoreLabel 3C00004e # JUMP @ignoreLabel
# ;; Check for Pointer # ;; Check for Pointer
A0300040 # CMPSKIPI.NE R0 64 ; If it is a pointer Deal with it E000A0300040 # CMPSKIPI.NE R0 64 ; If it is a pointer Deal with it
3C000044 # JUMP @storePointer 3C00004c # JUMP @storePointer
# ;; Process Char # ;; Process Char
3C000078 # JUMP @hex ; Convert it 3C000086 # JUMP @hex ; Convert it
#:loop_hex a4 # :loop_hex ca
2CC0FFE4 # JUMP.NP R0 @loop ; Don't use nonhex chars E0002CC0ffd8 # JUMP.NP R0 @loop ; Don't use nonhex chars
090006CC # NOT R12 R12 ; Flip the toggle 090006CC # NOT R12 R12 ; Flip the toggle
2CAC000C # JUMP.NZ R12 @loop_second_nybble ; Jump if toggled E0002CAC000a # JUMP.NZ R12 @loop_second_nybble ; Jump if toggled
# ;; Process first byte of pair # ;; Process first byte of pair
B0F0000F # ANDI R15 R0 0xF ; Store First nibble E100B0F0000f # ANDI R15 R0 0xF ; Store First nibble
3C00FFD4 # JUMP @loop 3C00ffc4 # JUMP @loop
#:loop_second_nybble b8 # :loop_second_nybble e4
2D5F0004 # SL0I R15 4 ; Shift our first nibble E0002D5F0004 # SL0I R15 4 ; Shift our first nibble
B000000F # ANDI R0 R0 0xF ; Mask out top E100B000000f # ANDI R0 R0 0xF ; Mask out top
0500000F # ADD R0 R0 R15 ; Combine nibbles 0500000F # ADD R0 R0 R15 ; Combine nibbles
09000319 # SWAP R1 R9 ; Set to write to tape_2 09000319 # SWAP R1 R9 ; Set to write to tape_2
42100200 # FPUTC ; To TAPE_02 42100200 # FPUTC ; To TAPE_02
09000319 # SWAP R1 R9 ; Restore from tape_1 09000319 # SWAP R1 R9 ; Restore from tape_1
0FDD0001 # ADDUI R13 R13 1 ; increment PC now that we have a full byte E1000FDD0001 # ADDUI R13 R13 1 ; increment PC now that we have a full byte
3C00FFB4 # JUMP @loop ; Try to get more bytes 3C00ff9e # JUMP @loop ; Try to get more bytes
#:ignoreLabel d8 # :ignoreLabel 10a
# ;; Consume next char # ;; Consume next char
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
3C00FFAC # JUMP @loop 3C00ff96 # JUMP @loop
#:storePointer e0 # :storePointer 112
# ;; Correct the PC to reflect the size of the pointer # ;; Correct the PC to reflect the size of the pointer
0FDD0002 # ADDUI R13 R13 2 ; Exactly 2 bytes E1000FDD0002 # ADDUI R13 R13 2 ; Exactly 2 bytes
# ;; Get the char of the Label # ;; Get the char of the Label
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
# ;; Since we stored a short pointer taking up 2 bytes # ;; Since we stored a short pointer taking up 2 bytes
2D500001 # SL0I R0 1 ; Thus we multiply our label by 2 to get where it is stored E0002D500001 # SL0I R0 1 ; Thus we multiply our label by 2 to get where it is stored
0503C3B0 # LOADXU16 R3 R11 R0 ; Load the address of the label 0503C3B0 # LOADXU16 R3 R11 R0 ; Load the address of the label
# ;; We now have to calculate the distance and store the 2 bytes # ;; We now have to calculate the distance and store the 2 bytes
0500233D # SUB R3 R3 R13 ; First determine the difference between the current PC and the stored PC of the label 0500233D # SUB R3 R3 R13 ; First determine the difference between the current PC and the stored PC of the label
0F330004 # ADDUI R3 R3 4 ; Adjust for relative positioning
# ;; Store Upper byte # ;; Store Upper byte
B003FF00 # ANDI R0 R3 0xFF00 ; Mask out everything but top byte E100B003ff00 # ANDI R0 R3 0xFF00 ; Mask out everything but top byte
2D400008 # SARI R0 8 ; Drop the bottom 8 bits E0002D400008 # SARI R0 8 ; Drop the bottom 8 bits
09000319 # SWAP R1 R9 ; Write the byte 09000319 # SWAP R1 R9 ; Write the byte
42100200 # FPUTC ; To TAPE_02 42100200 # FPUTC ; To TAPE_02
# ;; Store Lower byte # ;; Store Lower byte
B00300FF # ANDI R0 R3 0xFF ; Preserve bottom half for later E100B00300ff # ANDI R0 R3 0xFF ; Preserve bottom half for later
42100200 # FPUTC ; Write the byte to TAPE_02 42100200 # FPUTC ; Write the byte to TAPE_02
09000319 # SWAP R1 R9 ; Restore Read 09000319 # SWAP R1 R9 ; Restore Read
3C00FF74 # JUMP @loop 3C00ff58 # JUMP @loop
# ;; Hex function # ;; Hex function
# ;; Returns hex value of ascii char # ;; Returns hex value of ascii char
# ;; Or -1 if not a hex char # ;; Or -1 if not a hex char
#:hex 118 # :hex 150
# ;; Deal with line comments starting with # # ;; Deal with line comments starting with #
A0300023 # CMPSKIPI.NE R0 35 E000A0300023 # CMPSKIPI.NE R0 35
3C000044 # JUMP @ascii_comment 3C000050 # JUMP @ascii_comment
# ;; Deal with line comments starting with ; # ;; Deal with line comments starting with ;
A030003B # CMPSKIPI.NE R0 59 E000A030003b # CMPSKIPI.NE R0 59
3C00003C # JUMP @ascii_comment 3C000046 # JUMP @ascii_comment
# ;; Deal with all ascii less than '0' # ;; Deal with all ascii less than '0'
A0100030 # CMPSKIPI.GE R0 48 E000A0100030 # CMPSKIPI.GE R0 48
3C000040 # JUMP @ascii_other 3C00004a # JUMP @ascii_other
# ;; Deal with '0'-'9' # ;; Deal with '0'-'9'
A0000039 # CMPSKIPI.G R0 57 E000A0000039 # CMPSKIPI.G R0 57
3C00001C # JUMP @ascii_num 3C00001e # JUMP @ascii_num
# ;; Deal with all ascii less than 'A' # ;; Deal with all ascii less than 'A'
A0100041 # CMPSKIPI.GE R0 65 E000A0100041 # CMPSKIPI.GE R0 65
3C000030 # JUMP @ascii_other 3C000036 # JUMP @ascii_other
# ;; Unset high bit to set everything into uppercase # ;; Unset high bit to set everything into uppercase
B00000DF # ANDI R0 R0 0xDF E100B00000df # ANDI R0 R0 0xDF
# ;; Deal with 'A'-'F' # ;; Deal with 'A'-'F'
A0000046 # CMPSKIPI.G R0 70 E000A0000046 # CMPSKIPI.G R0 70
3C000010 # JUMP @ascii_high 3C00000e # JUMP @ascii_high
# ;; Ignore the rest # ;; Ignore the rest
3C000020 # JUMP @ascii_other 3C000022 # JUMP @ascii_other
#:ascii_num 150 # :ascii_num 196
11000030 # SUBUI R0 R0 48 E10011000030 # SUBUI R0 R0 48
0D01000E # JSR_COROUTINE R14 0D01000E # JSR_COROUTINE R14
#:ascii_high 158 # :ascii_high 1a0
11000037 # SUBUI R0 R0 55 E10011000037 # SUBUI R0 R0 55
0D01000E # JSR_COROUTINE R14 0D01000E # JSR_COROUTINE R14
#:ascii_comment 160 # :ascii_comment 1aa
42100100 # FGETC ; Read another char 42100100 # FGETC ; Read another char
A020000A # CMPSKIPI.E R0 10 ; Stop at the end of line E000A020000a # CMPSKIPI.E R0 10 ; Stop at the end of line
3C00FFF8 # JUMP @ascii_comment ; Otherwise keep looping 3C00fff2 # JUMP @ascii_comment ; Otherwise keep looping
#:ascii_other 16c # :ascii_other 1b8
0D000030 # TRUE R0 0D000030 # TRUE R0
0D01000E # JSR_COROUTINE R14 0D01000E # JSR_COROUTINE R14
#:finish 174 # :finish 1c0
2D201100 # LOADUI R0 0x1100 ; Close TAPE_01 E0002D201100 # LOADUI R0 0x1100 ; Close TAPE_01
42100002 # FCLOSE 42100002 # FCLOSE
2D201101 # LOADUI R0 0x1101 ; Close TAPE_02 E0002D201101 # LOADUI R0 0x1101 ; Close TAPE_02
42100002 # FCLOSE 42100002 # FCLOSE
FFFFFFFF # HALT FFFFFFFF # HALT
# ;; Where all of our pointers will be stored for our locations # ;; Where all of our pointers will be stored for our locations
#:table 188 # :table 1d8

View File

@ -145,7 +145,6 @@
;; We now have to calculate the distance and store the 2 bytes ;; We now have to calculate the distance and store the 2 bytes
SUB R3 R3 R13 ; First determine the difference between the current PC and the stored PC of the label SUB R3 R3 R13 ; First determine the difference between the current PC and the stored PC of the label
ADDUI R3 R3 4 ; Adjust for relative positioning
;; Store Upper byte ;; Store Upper byte
ANDI R0 R3 0xFF00 ; Mask out everything but top byte ANDI R0 R3 0xFF00 ; Mask out everything but top byte

View File

@ -30,37 +30,37 @@
# ;; We will be using R13 for our register size in bytes # ;; We will be using R13 for our register size in bytes
# ;; We will be using R14 for our head-node # ;; We will be using R14 for our head-node
2D2F @1 # LOADUI R15 $stack ; We will be using R15 for our stack E0002D2F 0400 # LOADUI R15 $stack ; We will be using R15 for our stack
# ;; Main program functionality # ;; Main program functionality
# ;; Reads in Tape_01 and writes out results onto Tape_02 # ;; Reads in Tape_01 and writes out results onto Tape_02
# ;; Accepts no arguments and HALTS when done # ;; Accepts no arguments and HALTS when done
# :main 4 # :main 6
:2 :2
# ;; Initialize header info # ;; Initialize header info
0D000010 # READSCID R0 ; Get process capabilities 0D000010 # READSCID R0 ; Get process capabilities
B010000f # ANDI R1 R0 0xF ; We only care about size nybble E100B010000f # ANDI R1 R0 0xF ; We only care about size nybble
2D200001 # LOADUI R0 1 ; Assume we are 8bit E0002D200001 # LOADUI R0 1 ; Assume we are 8bit
05032D01 # SL0 R13 R0 R1 ; Let size nybble correct answer 05032D01 # SL0 R13 R0 R1 ; Let size nybble correct answer
0900049D # COPY R9 R13 ; Prepare Header size 0900049D # COPY R9 R13 ; Prepare Header size
2D590001 # SL0I R9 1 ; Double to make proper size E0002D590001 # SL0I R9 1 ; Double to make proper size
# ;; Prep TAPE_01 # ;; Prep TAPE_01
2D201100 # LOADUI R0 0x1100 E0002D201100 # LOADUI R0 0x1100
42100000 # FOPEN_READ 42100000 # FOPEN_READ
# ;; Intialize environment # ;; Intialize environment
2D211100 # LOADUI R1 0x1100 ; Read from tape_01 E0002D211100 # LOADUI R1 0x1100 ; Read from tape_01
0D00002C # FALSE R12 ; Set holder to zero 0D00002C # FALSE R12 ; Set holder to zero
0D00002B # FALSE R11 ; Set PC counter to zero 0D00002B # FALSE R11 ; Set PC counter to zero
0D00002A # FALSE R10 ; Our toggle 0D00002A # FALSE R10 ; Our toggle
2D280500 # LOADUI R8 0x500 ; Where we want our heap to start E0002D280700 # LOADUI R8 0x700 ; Where we want our heap to start
# ;; Perform first pass # ;; Perform first pass
2D0F @3 # CALLI R15 @first_pass E0002D0F @3 # CALLI R15 @first_pass
# ;; We need to rewind tape_01 to perform our second pass # ;; We need to rewind tape_01 to perform our second pass
2D201100 # LOADUI R0 0x1100 E0002D201100 # LOADUI R0 0x1100
42100003 # REWIND 42100003 # REWIND
# ;; Reintialize environment # ;; Reintialize environment
@ -69,14 +69,14 @@ B010000f # ANDI R1 R0 0xF ; We only care about size nybble
0D00002A # FALSE R10 ; Our toggle 0D00002A # FALSE R10 ; Our toggle
# ;; Prep TAPE_02 # ;; Prep TAPE_02
2D201101 # LOADUI R0 0x1101 E0002D201101 # LOADUI R0 0x1101
42100001 # FOPEN_WRITE 42100001 # FOPEN_WRITE
2D0F @4 # CALLI R15 @second_pass E0002D0F @4 # CALLI R15 @second_pass
# ;; Close up as we are done # ;; Close up as we are done
2D201100 # LOADUI R0 0x1100 ; Close TAPE_01 E0002D201100 # LOADUI R0 0x1100 ; Close TAPE_01
42100002 # FCLOSE 42100002 # FCLOSE
2D201101 # LOADUI R0 0x1101 ; Close TAPE_02 E0002D201101 # LOADUI R0 0x1101 ; Close TAPE_02
42100002 # FCLOSE 42100002 # FCLOSE
FFFFFFFF # HALT FFFFFFFF # HALT
@ -85,41 +85,41 @@ FFFFFFFF # HALT
# ;; Reads Tape_01 and creates our label table # ;; Reads Tape_01 and creates our label table
# ;; Will Overwrite R0 R10 R11 # ;; Will Overwrite R0 R10 R11
# ;; Returns to Main function when done # ;; Returns to Main function when done
# :first_pass 70 # :first_pass 8a
:3 :3
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
# ;; Check for EOF # ;; Check for EOF
A0100000 # CMPSKIPI.GE R0 0 E000A0100000 # CMPSKIPI.GE R0 0
0D01001F # RET R15 0D01001F # RET R15
# ;; Check for and deal with label (:) # ;; Check for and deal with label (:)
A030003a # CMPSKIPI.NE R0 58 E000A030003a # CMPSKIPI.NE R0 58
3C00 @5 # JUMP @storeLabel 3C00 @5 # JUMP @storeLabel
# ;; Check for and deal with pointers to labels # ;; Check for and deal with pointers to labels
# ;; Starting with (@) # ;; Starting with (@)
A0300040 # CMPSKIPI.NE R0 64 E000A0300040 # CMPSKIPI.NE R0 64
3C00 @6 # JUMP @ThrowAwayPointer 3C00 @6 # JUMP @ThrowAwayPointer
# ;; Then dealing with ($) # ;; Then dealing with ($)
A0300024 # CMPSKIPI.NE R0 36 E000A0300024 # CMPSKIPI.NE R0 36
3C00 @6 # JUMP @ThrowAwayPointer 3C00 @6 # JUMP @ThrowAwayPointer
# ;; Now check for absolute addresses (&) # ;; Now check for absolute addresses (&)
A0300026 # CMPSKIPI.NE R0 38 E000A0300026 # CMPSKIPI.NE R0 38
3C00 @7 # JUMP @ThrowAwayAddress 3C00 @7 # JUMP @ThrowAwayAddress
# ;; Otherwise attempt to process # ;; Otherwise attempt to process
2D0F @8 # CALLI R15 @hex ; Convert it E0002D0F @8 # CALLI R15 @hex ; Convert it
2CC0 @3 # JUMP.NP R0 @first_pass ; Don't record, nonhex values E0002CC0 @3 # JUMP.NP R0 @first_pass ; Don't record, nonhex values
# ;; Flip the toggle # ;; Flip the toggle
090006AA # NOT R10 R10 090006AA # NOT R10 R10
2C9A @3 # JUMP.Z R10 @first_pass ; Jump if toggled E0002C9A @3 # JUMP.Z R10 @first_pass ; Jump if toggled
# ;; Deal with case of second half of byte # ;; Deal with case of second half of byte
0FBB0001 # ADDUI R11 R11 1 ; increment PC now that that we have a full byte E1000FBB0001 # ADDUI R11 R11 1 ; increment PC now that that we have a full byte
3C00 @3 # JUMP @first_pass 3C00 @3 # JUMP @first_pass
@ -128,49 +128,49 @@ A0300026 # CMPSKIPI.NE R0 38
# ;; To write desired contents onto Tape_02 # ;; To write desired contents onto Tape_02
# ;; Will Overwrite R0 R10 R11 # ;; Will Overwrite R0 R10 R11
# ;; Returns to Main function when done # ;; Returns to Main function when done
# :second_pass b4 # :second_pass e0
:4 :4
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
# ;; Check for EOF # ;; Check for EOF
A0100000 # CMPSKIPI.GE R0 0 E000A0100000 # CMPSKIPI.GE R0 0
0D01001F # RET R15 0D01001F # RET R15
# ;; Check for and deal with label # ;; Check for and deal with label
A030003a # CMPSKIPI.NE R0 58 E000A030003a # CMPSKIPI.NE R0 58
3C00 @9 # JUMP @ThrowAwayLabel 3C00 @9 # JUMP @ThrowAwayLabel
# ;; Check for and deal with Pointers to labels # ;; Check for and deal with Pointers to labels
A0300040 # CMPSKIPI.NE R0 64 ; @ for relative E000A0300040 # CMPSKIPI.NE R0 64 ; @ for relative
3C00 @a # JUMP @StoreRelativePointer 3C00 @a # JUMP @StoreRelativePointer
A0300024 # CMPSKIPI.NE R0 36 ; $ for absolute E000A0300024 # CMPSKIPI.NE R0 36 ; $ for absolute
3C00 @b # JUMP @StoreAbsolutePointer 3C00 @b # JUMP @StoreAbsolutePointer
A0300026 # CMPSKIPI.NE R0 38 ; & for address E000A0300026 # CMPSKIPI.NE R0 38 ; & for address
3C00 @c # JUMP @StoreAbsoluteAddress 3C00 @c # JUMP @StoreAbsoluteAddress
# ;; Process everything else # ;; Process everything else
2D0F @8 # CALLI R15 @hex ; Attempt to Convert it E0002D0F @8 # CALLI R15 @hex ; Attempt to Convert it
A0100000 # CMPSKIPI.GE R0 0 ; Don't record, nonhex values E000A0100000 # CMPSKIPI.GE R0 0 ; Don't record, nonhex values
3C00 @4 # JUMP @second_pass ; Move onto Next char 3C00 @4 # JUMP @second_pass ; Move onto Next char
# ;; Determine if we got a full byte # ;; Determine if we got a full byte
090006AA # NOT R10 R10 090006AA # NOT R10 R10
2C9A @d # JUMP.Z R10 @second_pass_0 ; Jump if toggled E0002C9A @d # JUMP.Z R10 @second_pass_0 ; Jump if toggled
# ;; Deal with case of first half of byte # ;; Deal with case of first half of byte
B0C0000f # ANDI R12 R0 0x0F ; Store our first nibble E100B0C0000f # ANDI R12 R0 0x0F ; Store our first nibble
3C00 @4 # JUMP @second_pass 3C00 @4 # JUMP @second_pass
# :second_pass_0 fc # :second_pass_0 13a
:d :d
# ;; Deal with case of second half of byte # ;; Deal with case of second half of byte
2D5C0004 # SL0I R12 4 ; Shift our first nybble E0002D5C0004 # SL0I R12 4 ; Shift our first nybble
B000000f # ANDI R0 R0 0x0F ; Mask out top E100B000000f # ANDI R0 R0 0x0F ; Mask out top
0500000C # ADD R0 R0 R12 ; Combine nybbles 0500000C # ADD R0 R0 R12 ; Combine nybbles
2D211101 # LOADUI R1 0x1101 ; Write the combined byte E0002D211101 # LOADUI R1 0x1101 ; Write the combined byte
42100200 # FPUTC ; To TAPE_02 42100200 # FPUTC ; To TAPE_02
2D211100 # LOADUI R1 0x1100 ; Read from tape_01 E0002D211100 # LOADUI R1 0x1100 ; Read from tape_01
0FBB0001 # ADDUI R11 R11 1 ; increment PC now that that we have a full byte E1000FBB0001 # ADDUI R11 R11 1 ; increment PC now that that we have a full byte
3C00 @4 # JUMP @second_pass 3C00 @4 # JUMP @second_pass
@ -179,18 +179,18 @@ B000000f # ANDI R0 R0 0x0F ; Mask out top
# ;; Its static variable for storing the next index to be used # ;; Its static variable for storing the next index to be used
# ;; Will overwrite R0 # ;; Will overwrite R0
# ;; Returns to first pass when done # ;; Returns to first pass when done
# :storeLabel 11c # :storeLabel 164
:5 :5
09000408 # COPY R0 R8 ; get current malloc 09000408 # COPY R0 R8 ; get current malloc
05000889 # ADD R8 R8 R9 ; update malloc 05000889 # ADD R8 R8 R9 ; update malloc
# ;; Add node info # ;; Add node info
05048B0D # STOREX R11 R0 R13 ; Store the PC of the label 05048B0D # STOREX R11 R0 R13 ; Store the PC of the label
20E00000 # STORE R14 R0 0 ; Store the Previous Head E10020E00000 # STORE R14 R0 0 ; Store the Previous Head
090005E0 # MOVE R14 R0 ; Update Head 090005E0 # MOVE R14 R0 ; Update Head
# ;; Store the name of the Label # ;; Store the name of the Label
2D0F @e # CALLI R15 @writeout_token E0002D0F @e # CALLI R15 @writeout_token
# ;; And be done # ;; And be done
3C00 @3 # JUMP @first_pass 3C00 @3 # JUMP @first_pass
@ -203,14 +203,13 @@ B000000f # ANDI R0 R0 0x0F ; Mask out top
# ;; Writes out the offset # ;; Writes out the offset
# ;; Modifies R0 R11 # ;; Modifies R0 R11
# ;; Jumps back into Pass2 # ;; Jumps back into Pass2
# :StoreRelativePointer 138 # :StoreRelativePointer 184
:a :a
# ;; Correct the PC to reflect the size of the pointer # ;; Correct the PC to reflect the size of the pointer
0FBB0002 # ADDUI R11 R11 2 ; Exactly 2 bytes E1000FBB0002 # ADDUI R11 R11 2 ; Exactly 2 bytes
2D0F @o # CALLI R15 @Match_string ; Find the Match E0002D0F @o # CALLI R15 @Match_string ; Find the Match
0500200B # SUB R0 R0 R11 ; Determine the difference 0500200B # SUB R0 R0 R11 ; Determine the difference
0F000004 # ADDUI R0 R0 4 ; Adjust for relative positioning E0002D0F @p # CALLI R15 @ProcessImmediate ; Write out the value
2D0F @p # CALLI R15 @ProcessImmediate ; Write out the value
3C00 @4 # JUMP @second_pass 3C00 @4 # JUMP @second_pass
@ -221,12 +220,12 @@ B000000f # ANDI R0 R0 0x0F ; Mask out top
# ;; Writes out the absolute address of match # ;; Writes out the absolute address of match
# ;; Modifies R0 R11 # ;; Modifies R0 R11
# ;; Jumps back into Pass2 # ;; Jumps back into Pass2
# :StoreAbsolutePointer 150 # :StoreAbsolutePointer 1a4
:b :b
# ;; Correct the PC to reflect the size of the pointer # ;; Correct the PC to reflect the size of the pointer
0FBB0002 # ADDUI R11 R11 2 ; Exactly 2 bytes E1000FBB0002 # ADDUI R11 R11 2 ; Exactly 2 bytes
2D0F @o # CALLI R15 @Match_string ; Find the Match E0002D0F @o # CALLI R15 @Match_string ; Find the Match
2D0F @p # CALLI R15 @ProcessImmediate ; Write out the value E0002D0F @p # CALLI R15 @ProcessImmediate ; Write out the value
3C00 @4 # JUMP @second_pass 3C00 @4 # JUMP @second_pass
@ -237,16 +236,16 @@ B000000f # ANDI R0 R0 0x0F ; Mask out top
# ;; Writes out the full absolute address [32 bit machine] # ;; Writes out the full absolute address [32 bit machine]
# ;; Modifies R0 R11 # ;; Modifies R0 R11
# ;; Jumpbacs back into Pass2 # ;; Jumpbacs back into Pass2
# :StoreAbsoluteAddress 160 # :StoreAbsoluteAddress 1ba
:c :c
# ;; COrrect the PC to reflect the size of the address # ;; Correct the PC to reflect the size of the address
0FBB0004 # ADDUI R11 R11 4 ; 4 Bytes on 32bit machines E1000FBB0004 # ADDUI R11 R11 4 ; 4 Bytes on 32bit machines
2D0F @o # CALLI R15 @Match_string ; Find the Match E0002D0F @o # CALLI R15 @Match_string ; Find the Match
B020ffff # ANDI R2 R0 0xFFFF ; Save bottom half for next function E100B020ffff # ANDI R2 R0 0xFFFF ; Save bottom half for next function
2D400010 # SARI R0 16 ; Drop bottom 16 bits E0002D400010 # SARI R0 16 ; Drop bottom 16 bits
2D0F @p # CALLI R15 @ProcessImmediate ; Write out top 2 bytes E0002D0F @p # CALLI R15 @ProcessImmediate ; Write out top 2 bytes
09000502 # MOVE R0 R2 ; Use the saved 16bits 09000502 # MOVE R0 R2 ; Use the saved 16bits
2D0F @p # CALLI R15 @ProcessImmediate ; Write out bottom 2 bytes E0002D0F @p # CALLI R15 @ProcessImmediate ; Write out bottom 2 bytes
3C00 @4 # JUMP @second_pass 3C00 @4 # JUMP @second_pass
@ -254,7 +253,7 @@ B020ffff # ANDI R2 R0 0xFFFF ; Save bottom half for next function
# ;; Writes the Token [minus first char] to the address # ;; Writes the Token [minus first char] to the address
# ;; given by malloc and updates malloc pointer # ;; given by malloc and updates malloc pointer
# ;; Returns starting address of string # ;; Returns starting address of string
# :writeout_token 180 # :writeout_token 1e6
:e :e
# ;; Preserve registers # ;; Preserve registers
0902001F # PUSHR R1 R15 0902001F # PUSHR R1 R15
@ -264,30 +263,30 @@ B020ffff # ANDI R2 R0 0xFFFF ; Save bottom half for next function
09000428 # COPY R2 R8 ; Get current malloc pointer 09000428 # COPY R2 R8 ; Get current malloc pointer
# ;; Our core loop # ;; Our core loop
# :writeout_token_0 18c # :writeout_token_0 1f2
:r :r
42100100 # FGETC ; Get another byte 42100100 # FGETC ; Get another byte
# ;; Deal with termination cases # ;; Deal with termination cases
A0300020 # CMPSKIPI.NE R0 32 ; Finished if space E000A0300020 # CMPSKIPI.NE R0 32 ; Finished if space
3C00 @q # JUMP @writeout_token_done 3C00 @q # JUMP @writeout_token_done
A0300009 # CMPSKIPI.NE R0 9 ; Finished if tab E000A0300009 # CMPSKIPI.NE R0 9 ; Finished if tab
3C00 @q # JUMP @writeout_token_done 3C00 @q # JUMP @writeout_token_done
A030000a # CMPSKIPI.NE R0 10 ; Finished if newline E000A030000a # CMPSKIPI.NE R0 10 ; Finished if newline
3C00 @q # JUMP @writeout_token_done 3C00 @q # JUMP @writeout_token_done
A030ffff # CMPSKIPI.NE R0 -1 ; Finished if EOF E000A030ffff # CMPSKIPI.NE R0 -1 ; Finished if EOF
3C00 @q # JUMP @writeout_token_done 3C00 @q # JUMP @writeout_token_done
# ;; Deal with valid input # ;; Deal with valid input
21080000 # STORE8 R0 R8 0 ; Write out the byte E10021080000 # STORE8 R0 R8 0 ; Write out the byte
0F880001 # ADDUI R8 R8 1 ; Increment E1000F880001 # ADDUI R8 R8 1 ; Increment
3C00 @r # JUMP @writeout_token_0 ; Keep looping 3C00 @r # JUMP @writeout_token_0 ; Keep looping
# ;; Clean up now that we are done # ;; Clean up now that we are done
# :writeout_token_done 1bc # :writeout_token_done 22e
:q :q
# ;; Fix malloc # ;; Fix malloc
0F880001 # ADDUI R8 R8 1 E1000F880001 # ADDUI R8 R8 1
# ;; Prepare for return # ;; Prepare for return
09000502 # MOVE R0 R2 09000502 # MOVE R0 R2
@ -305,33 +304,33 @@ A030ffff # CMPSKIPI.NE R0 -1 ; Finished if EOF
# ;; Reads a token # ;; Reads a token
# ;; Then returns address of match in R0 # ;; Then returns address of match in R0
# ;; Returns to whatever called it # ;; Returns to whatever called it
# :Match_string 1d0 # :Match_string 244
:o :o
# ;; Preserve registers # ;; Preserve registers
0902001F # PUSHR R1 R15 0902001F # PUSHR R1 R15
0902002F # PUSHR R2 R15 0902002F # PUSHR R2 R15
# ;; Initialize for Loop # ;; Initialize for Loop
2D0F @e # CALLI R15 @writeout_token ; Get our desired string E0002D0F @e # CALLI R15 @writeout_token ; Get our desired string
09000510 # MOVE R1 R0 ; Position our desired string 09000510 # MOVE R1 R0 ; Position our desired string
0900042E # COPY R2 R14 ; Begin at our head node 0900042E # COPY R2 R14 ; Begin at our head node
# ;; Loop until we find a match # ;; Loop until we find a match
# :Match_string_0 1e4 # :Match_string_0 25a
:h :h
05000029 # ADD R0 R2 R9 ; Where the string is located 05000029 # ADD R0 R2 R9 ; Where the string is located
2D0F @f # CALLI R15 @strcmp E0002D0F @f # CALLI R15 @strcmp
2C50 @g # JUMP.E R0 @Match_string_1 ; It is a match! E0002C50 @g # JUMP.E R0 @Match_string_1 ; It is a match!
# ;; Prepare for next loop # ;; Prepare for next loop
13220000 # LOAD R2 R2 0 ; Move to next node E10013220000 # LOAD R2 R2 0 ; Move to next node
2CA2 @h # JUMP.NZ R2 @Match_string_0 ; Keep looping E0002CA2 @h # JUMP.NZ R2 @Match_string_0 ; Keep looping
0D000032 # TRUE R2 ; Set result to -1 if not found 0D000032 # TRUE R2 ; Set result to -1 if not found
# :Match_string_1 1fc # :Match_string_1 27a
:g :g
# ;; Store the correct answer # ;; Store the correct answer
A022ffff # CMPSKIPI.E R2 -1 ; Otherwise get the value E000A022ffff # CMPSKIPI.E R2 -1 ; Otherwise get the value
0503802D # LOADX R0 R2 R13 ; Get the value we care about 0503802D # LOADX R0 R2 R13 ; Get the value we care about
# ;; Restore registers # ;; Restore registers
@ -344,7 +343,7 @@ A022ffff # CMPSKIPI.E R2 -1 ; Otherwise get the value
# ;; Recieves two pointers in R0 and R1 # ;; Recieves two pointers in R0 and R1
# ;; Returns the difference between the strings in R0 # ;; Returns the difference between the strings in R0
# ;; Returns to whatever called it # ;; Returns to whatever called it
# :strcmp 210 # :strcmp 290
:f :f
# ;; Preserve registers # ;; Preserve registers
0902001F # PUSHR R1 R15 0902001F # PUSHR R1 R15
@ -355,16 +354,16 @@ A022ffff # CMPSKIPI.E R2 -1 ; Otherwise get the value
# ;; Setup registers # ;; Setup registers
09000520 # MOVE R2 R0 09000520 # MOVE R2 R0
09000531 # MOVE R3 R1 09000531 # MOVE R3 R1
2D240000 # LOADUI R4 0 E0002D240000 # LOADUI R4 0
# :cmpbyte 22c # :cmpbyte 2ae
:i :i
0503A024 # LOADXU8 R0 R2 R4 ; Get a byte of our first string 0503A024 # LOADXU8 R0 R2 R4 ; Get a byte of our first string
0503A134 # LOADXU8 R1 R3 R4 ; Get a byte of our second string 0503A134 # LOADXU8 R1 R3 R4 ; Get a byte of our second string
0F440001 # ADDUI R4 R4 1 ; Prep for next loop E1000F440001 # ADDUI R4 R4 1 ; Prep for next loop
05004101 # CMP R1 R0 R1 ; Compare the bytes 05004101 # CMP R1 R0 R1 ; Compare the bytes
A0200000 # CMPSKIPI.E R0 0 ; Stop if byte is NULL E000A0200000 # CMPSKIPI.E R0 0 ; Stop if byte is NULL
2C51 @i # JUMP.E R1 @cmpbyte ; Loop if bytes are equal E0002C51 @i # JUMP.E R1 @cmpbyte ; Loop if bytes are equal
# ;; Done # ;; Done
09000501 # MOVE R0 R1 ; Prepare for return 09000501 # MOVE R0 R1 ; Prepare for return
@ -382,7 +381,7 @@ A0200000 # CMPSKIPI.E R0 0 ; Stop if byte is NULL
# ;; Writes out the values to Tape_02 # ;; Writes out the values to Tape_02
# ;; Doesn't modify registers # ;; Doesn't modify registers
# ;; Returns to whatever called it # ;; Returns to whatever called it
# :ProcessImmediate 25c # :ProcessImmediate 2e4
:p :p
# ;; Preserve registers # ;; Preserve registers
0902000F # PUSHR R0 R15 0902000F # PUSHR R0 R15
@ -390,12 +389,12 @@ A0200000 # CMPSKIPI.E R0 0 ; Stop if byte is NULL
0902002F # PUSHR R2 R15 0902002F # PUSHR R2 R15
# ;; Break up Immediate # ;; Break up Immediate
B02000ff # ANDI R2 R0 0xFF ; Put lower byte in R2 E100B02000ff # ANDI R2 R0 0xFF ; Put lower byte in R2
2D400008 # SARI R0 8 ; Drop Bottom byte from R0 E0002D400008 # SARI R0 8 ; Drop Bottom byte from R0
B00000ff # ANDI R0 R0 0xFF ; Maskout everything outside of top byte E100B00000ff # ANDI R0 R0 0xFF ; Maskout everything outside of top byte
# ;; Write out Top Byte # ;; Write out Top Byte
2D211101 # LOADUI R1 0x1101 ; Write the byte E0002D211101 # LOADUI R1 0x1101 ; Write the byte
42100200 # FPUTC ; To TAPE_02 42100200 # FPUTC ; To TAPE_02
# ;; Write out bottom Byte # ;; Write out bottom Byte
@ -416,10 +415,10 @@ B00000ff # ANDI R0 R0 0xFF ; Maskout everything outside of top byte
# ;; for Pass1, Will update R11 and modify R0 # ;; for Pass1, Will update R11 and modify R0
# ;; Will return to the start of first_pass # ;; Will return to the start of first_pass
# ;; Never call this function, only jump to it # ;; Never call this function, only jump to it
# :ThrowAwayPointer 294 # :ThrowAwayPointer 324
:6 :6
0FBB0002 # ADDUI R11 R11 2 ; Pointers always take up 2 bytes E1000FBB0002 # ADDUI R11 R11 2 ; Pointers always take up 2 bytes
2D0F @j # CALLI R15 @throwAwayToken ; Get rid of rest of token E0002D0F @j # CALLI R15 @throwAwayToken ; Get rid of rest of token
3C00 @3 # JUMP @first_pass ; Then return to the proper place 3C00 @3 # JUMP @first_pass ; Then return to the proper place
@ -428,10 +427,10 @@ B00000ff # ANDI R0 R0 0xFF ; Maskout everything outside of top byte
# ;; for Pass1, Will update R11 and modify R0 # ;; for Pass1, Will update R11 and modify R0
# ;; Will return to the start of first_pass # ;; Will return to the start of first_pass
# ;; Never call this function, conly jump to it # ;; Never call this function, conly jump to it
# :ThrowAwayAddress 2a0 # :ThrowAwayAddress 334
:7 :7
0FBB0004 # ADDUI R11 R11 4 ; Addresses on 32bit systems take up 4 bytes E1000FBB0004 # ADDUI R11 R11 4 ; Addresses on 32bit systems take up 4 bytes
2D0F @j # CALLI R15 @throwAwayToken ; Get rid of rest of token E0002D0F @j # CALLI R15 @throwAwayToken ; Get rid of rest of token
3C00 @3 # JUMP @first_pass ; Then return to the proper place 3C00 @3 # JUMP @first_pass ; Then return to the proper place
@ -440,9 +439,9 @@ B00000ff # ANDI R0 R0 0xFF ; Maskout everything outside of top byte
# ;; for Pass2, Will update R11 and modify R0 # ;; for Pass2, Will update R11 and modify R0
# ;; Will return to the start of second_pass # ;; Will return to the start of second_pass
# ;; Never call this function, only jump to it # ;; Never call this function, only jump to it
# :ThrowAwayLabel 2ac # :ThrowAwayLabel 344
:9 :9
2D0F @j # CALLI R15 @throwAwayToken ; Get rid of rest of token E0002D0F @j # CALLI R15 @throwAwayToken ; Get rid of rest of token
3C00 @4 # JUMP @second_pass 3C00 @4 # JUMP @second_pass
@ -451,24 +450,24 @@ B00000ff # ANDI R0 R0 0xFF ; Maskout everything outside of top byte
# ;; The rest of the characters in a token # ;; The rest of the characters in a token
# ;; This Will alter the values of R0 R1 # ;; This Will alter the values of R0 R1
# ;; Returns back to whatever called it # ;; Returns back to whatever called it
# :throwAwayToken 2b4 # :throwAwayToken 34e
:j :j
42100100 # FGETC ; Read a Char 42100100 # FGETC ; Read a Char
# ;; Stop looping if space # ;; Stop looping if space
A0300020 # CMPSKIPI.NE R0 32 E000A0300020 # CMPSKIPI.NE R0 32
0D01001F # RET R15 0D01001F # RET R15
# ;; Stop looping if tab # ;; Stop looping if tab
A0300009 # CMPSKIPI.NE R0 9 E000A0300009 # CMPSKIPI.NE R0 9
0D01001F # RET R15 0D01001F # RET R15
# ;; Stop looping if newline # ;; Stop looping if newline
A030000a # CMPSKIPI.NE R0 10 E000A030000a # CMPSKIPI.NE R0 10
0D01001F # RET R15 0D01001F # RET R15
# ;; Stop looping if EOF # ;; Stop looping if EOF
A030ffff # CMPSKIPI.NE R0 -1 E000A030ffff # CMPSKIPI.NE R0 -1
0D01001F # RET R15 0D01001F # RET R15
# ;; Otherwise keep looping # ;; Otherwise keep looping
@ -482,58 +481,58 @@ A030ffff # CMPSKIPI.NE R0 -1
# ;; Returning the converted value of a hex character # ;; Returning the converted value of a hex character
# ;; This function will alter the values of R0 # ;; This function will alter the values of R0
# ;; Returns back to whatever called it # ;; Returns back to whatever called it
# :hex 2dc # :hex 37e
:8 :8
# ;; Deal with line comments starting with # # ;; Deal with line comments starting with #
A0300023 # CMPSKIPI.NE R0 35 E000A0300023 # CMPSKIPI.NE R0 35
3C00 @k # JUMP @ascii_comment 3C00 @k # JUMP @ascii_comment
# ;; Deal with line comments starting with ; # ;; Deal with line comments starting with ;
A030003b # CMPSKIPI.NE R0 59 E000A030003b # CMPSKIPI.NE R0 59
3C00 @k # JUMP @ascii_comment 3C00 @k # JUMP @ascii_comment
# ;; Deal with all ascii less than '0' # ;; Deal with all ascii less than '0'
A0100030 # CMPSKIPI.GE R0 48 E000A0100030 # CMPSKIPI.GE R0 48
3C00 @l # JUMP @ascii_other 3C00 @l # JUMP @ascii_other
# ;; Deal with '0'-'9' # ;; Deal with '0'-'9'
A0000039 # CMPSKIPI.G R0 57 E000A0000039 # CMPSKIPI.G R0 57
3C00 @m # JUMP @ascii_num 3C00 @m # JUMP @ascii_num
# ;; Deal with all ascii less than 'A' # ;; Deal with all ascii less than 'A'
A0100041 # CMPSKIPI.GE R0 65 E000A0100041 # CMPSKIPI.GE R0 65
3C00 @l # JUMP @ascii_other 3C00 @l # JUMP @ascii_other
# ;; Unset high bit to set everything into uppercase # ;; Unset high bit to set everything into uppercase
B00000df # ANDI R0 R0 0xDF E100B00000df # ANDI R0 R0 0xDF
# ;; Deal with 'A'-'F' # ;; Deal with 'A'-'F'
A0000046 # CMPSKIPI.G R0 70 E000A0000046 # CMPSKIPI.G R0 70
3C00 @n # JUMP @ascii_high 3C00 @n # JUMP @ascii_high
# ;; Ignore the rest # ;; Ignore the rest
3C00 @l # JUMP @ascii_other 3C00 @l # JUMP @ascii_other
# :ascii_num 314 # :ascii_num 3c4
:m :m
11000030 # SUBUI R0 R0 48 E10011000030 # SUBUI R0 R0 48
0D01001F # RET R15 0D01001F # RET R15
# :ascii_high 31c # :ascii_high 3ce
:n :n
11000037 # SUBUI R0 R0 55 E10011000037 # SUBUI R0 R0 55
0D01001F # RET R15 0D01001F # RET R15
# :ascii_comment 324 # :ascii_comment 3d8
:k :k
42100100 # FGETC ; Read another char 42100100 # FGETC ; Read another char
2CC0 @l # JUMP.NP R0 @ascii_other ; Stop with EOF E0002CC0 @l # JUMP.NP R0 @ascii_other ; Stop with EOF
A020000a # CMPSKIPI.E R0 10 ; Stop at the end of line E000A020000a # CMPSKIPI.E R0 10 ; Stop at the end of line
3C00 @k # JUMP @ascii_comment ; Otherwise keep looping 3C00 @k # JUMP @ascii_comment ; Otherwise keep looping
# :ascii_other 334 # :ascii_other 3ec
:l :l
0D000030 # TRUE R0 0D000030 # TRUE R0
0D01001F # RET R15 0D01001F # RET R15
# ;; Where we will putting our stack # ;; Where we will putting our stack
# :stack 33c # :stack 3f4
:1 :1

View File

@ -52,7 +52,7 @@
FALSE R12 ; Set holder to zero FALSE R12 ; Set holder to zero
FALSE R11 ; Set PC counter to zero FALSE R11 ; Set PC counter to zero
FALSE R10 ; Our toggle FALSE R10 ; Our toggle
LOADUI R8 0x500 ; Where we want our heap to start LOADUI R8 0x700 ; Where we want our heap to start
;; Perform first pass ;; Perform first pass
CALLI R15 @first_pass CALLI R15 @first_pass
@ -205,7 +205,6 @@
ADDUI R11 R11 2 ; Exactly 2 bytes ADDUI R11 R11 2 ; Exactly 2 bytes
CALLI R15 @Match_string ; Find the Match CALLI R15 @Match_string ; Find the Match
SUB R0 R0 R11 ; Determine the difference SUB R0 R0 R11 ; Determine the difference
ADDUI R0 R0 4 ; Adjust for relative positioning
CALLI R15 @ProcessImmediate ; Write out the value CALLI R15 @ProcessImmediate ; Write out the value
JUMP @second_pass JUMP @second_pass

View File

@ -1,10 +1,10 @@
8f465d3ec1cba00a7d024a1964e74bb6d241f86a73c77d95d8ceb10d09c8f7b9 roms/CAT 695698ebc7ed1d3acbcded1bd832a6b49b9a7c2a37c216a9fccdc0e89e976e99 roms/CAT
59f0502748af32e3096e026a95e77216179cccfe803a05803317414643e2fcec roms/DEHEX 662b14485df5da61c3f5ad63151932985914b2fe074c21798e20ba2d83b45ecc roms/DEHEX
b3a910f18c6bc0ef4aa7a53cb3f0216a9f143319da67ed2a02210fe88b1e1131 roms/forth f4bbf9e9c4828170d0c153ac265382dc705643f95efd2a029243326d426be5a4 roms/forth
7c3887f791999aa9c1b8415d8e5be93afcf916b505296d9da7bd7a22531a84b5 roms/lisp 2b80849180d5fb3757bcca2471b6337808e5b5ca80b18d93fa82ddef0435b84b roms/lisp
47bc5a29e37bbe4cac31ba612f5e452210b0c4364e529116b9a1c4976912c29d roms/M0 3020b194ead31ae19ba66fc35ed95465514373f6005896350d1608c9efabbdca roms/M0
24a4d74eb2eb7a82e68335643855658b27b5a6c3b13db473539f3e08d6f26ceb roms/SET 059d38e34275029f2de5f600f08fe01bd13cd173f7da58e3fbec7114074beff2 roms/SET
0a427b14020354d1c785f5f900677e0059fce8f8d4456e9c19e5528cb17101eb roms/stage0_monitor 23929c57f41414f57583457d0500f22b5b1c80f39c79522e23c8b13e5afb191d roms/stage0_monitor
3ea7fed1429400c1d6fc5b85180c4114755dfb1e6b88d69e7ecc465a40523bc8 roms/stage1_assembler-0 13b45134a88c1c6db349cb40f82269cee9edfce71ac644dc0e137bad053bf5ce roms/stage1_assembler-0
b6aabcc3418a0a28f4ed32ace43b20103d9d21dffae03e7936cb14fa0e044013 roms/stage1_assembler-1 156f555fce5b02f52445652b1ed0b443295706cdfbe23c5a021bd4efc77179bb roms/stage1_assembler-1
7b02babee42a3c05b001fb44fb0917383d8f185e2817d57ad2349a4b36dfa4ed roms/stage1_assembler-2 2c02c50958f489a660a4915d2a9e207a0c61f411d42628bdaf4dcf6bf7149a9d roms/stage1_assembler-2

View File

@ -133,29 +133,37 @@ void decode_1OP(struct Instruction* c)
} }
/* Deal with 2OPI */ /* Deal with 2OPI */
void decode_2OPI(struct Instruction* c) void decode_2OPI(struct lilith* vm, struct Instruction* c)
{ {
c->raw_Immediate = c->raw2*0x100 + c->raw3; c->raw_Immediate = (uint8_t)vm->memory[vm->ip];
vm->ip = vm->ip + 1;
uint8_t hold = (uint8_t)vm->memory[vm->ip];
vm->ip = vm->ip + 1;
c->raw_Immediate = c->raw_Immediate*0x100 + hold;
c->Immediate[0] = c->operation[4]; c->Immediate[0] = c->operation[4];
c->Immediate[1] = c->operation[5]; c->Immediate[1] = c->operation[5];
c->Immediate[2] = c->operation[6]; c->Immediate[2] = c->operation[6];
c->Immediate[3] = c->operation[7]; c->Immediate[3] = c->operation[7];
c->reg0 = c->raw1/16; c->reg0 = c->raw3/16;
c->reg1 = c->raw1%16; c->reg1 = c->raw3%16;
} }
/* Deal with 1OPI */ /* Deal with 1OPI */
void decode_1OPI(struct Instruction* c) void decode_1OPI(struct lilith* vm, struct Instruction* c)
{ {
c->raw_Immediate = c->raw2*0x100 + c->raw3; c->raw_Immediate = (uint8_t)vm->memory[vm->ip];
vm->ip = vm->ip + 1;
uint8_t hold = (uint8_t)vm->memory[vm->ip];
vm->ip = vm->ip + 1;
c->raw_Immediate = c->raw_Immediate*0x100 + hold;
c->Immediate[0] = c->operation[4]; c->Immediate[0] = c->operation[4];
c->Immediate[1] = c->operation[5]; c->Immediate[1] = c->operation[5];
c->Immediate[2] = c->operation[6]; c->Immediate[2] = c->operation[6];
c->Immediate[3] = c->operation[7]; c->Immediate[3] = c->operation[7];
c->HAL_CODE = 0; c->HAL_CODE = 0;
c->raw_XOP = c->raw1/16; c->raw_XOP = c->raw3/16;
c->XOP[0] = c->operation[2]; c->XOP[0] = c->operation[7];
c->reg0 = c->raw1%16; c->reg0 = c->raw3%16;
} }
/* Deal with 0OPI */ /* Deal with 0OPI */
void decode_0OPI(struct Instruction* c) void decode_0OPI(struct Instruction* c)
@ -1698,7 +1706,7 @@ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c)
/* 0x0E ... 0x2B */ /* 0x0E ... 0x2B */
/* 0xB0 ... 0xDF */ /* 0xB0 ... 0xDF */
switch(c->raw0) switch(c->raw2)
{ {
case 0x0E: /* ADDI */ case 0x0E: /* ADDI */
{ {
@ -2082,7 +2090,7 @@ bool eval_Integer_1OPI(struct lilith* vm, struct Instruction* c)
char Name[20] = "ILLEGAL_1OPI"; char Name[20] = "ILLEGAL_1OPI";
#endif #endif
uint32_t Opcode = (c->raw0 * 16) + c->raw_XOP; uint32_t Opcode = (c->raw2 * 16) + c->raw_XOP;
switch(Opcode) switch(Opcode)
{ {
@ -2650,17 +2658,15 @@ void eval_instruction(struct lilith* vm, struct Instruction* current)
eval_1OP_Int(vm, current); eval_1OP_Int(vm, current);
break; break;
} }
case 0x0E ... 0x2B: /* Integer 2OPI */ case 0xE1: /* Integer 2OPI */
case 0xB0 ... 0xDF:
{ {
decode_2OPI(current); decode_2OPI(vm, current);
eval_2OPI_Int(vm, current); eval_2OPI_Int(vm, current);
break; break;
} }
case 0x2C ... 0x2F: /* Integer 1OPI */ case 0xE0: /* Integer 1OPI */
case 0xA0 ... 0xA1:
{ {
decode_1OPI(current); decode_1OPI(vm, current);
eval_Integer_1OPI(vm, current); eval_Integer_1OPI(vm, current);
break; break;
} }

View File

@ -24,10 +24,17 @@ FILE* tape_02;
char tty_getchar(); char tty_getchar();
#endif #endif
/* Stub as the current specification makes all instructions 4 bytes but future enhancements may change that */ /* Use first byte of next instruction to identify size */
int next_instruction_size(struct lilith* vm) int next_instruction_size(struct lilith* vm)
{ {
return 4; uint8_t c = (uint8_t)vm->memory[vm->ip];
switch(c)
{
case 0xE0: return 6;
case 0xE1: return 6;
default: return 4;
}
} }
/* Correctly write out bytes on little endian hardware */ /* Correctly write out bytes on little endian hardware */
@ -1310,8 +1317,7 @@ void JUMP_C(struct lilith* vm, struct Instruction* c)
{ {
if(Carry_bit_set(vm->reg[c->reg0])) if(Carry_bit_set(vm->reg[c->reg0]))
{ {
/* Adust the IP relative the the start of this instruction*/ vm->ip = vm->ip + c->raw_Immediate;
vm->ip = vm->ip + c->raw_Immediate - 4;
} }
} }
@ -1319,8 +1325,7 @@ void JUMP_B(struct lilith* vm, struct Instruction* c)
{ {
if(Borrow_bit_set(vm->reg[c->reg0])) if(Borrow_bit_set(vm->reg[c->reg0]))
{ {
/* Adust the IP relative the the start of this instruction*/ vm->ip = vm->ip + c->raw_Immediate;
vm->ip = vm->ip + c->raw_Immediate - 4;
} }
} }
@ -1328,8 +1333,7 @@ void JUMP_O(struct lilith* vm, struct Instruction* c)
{ {
if(Overflow_bit_set(vm->reg[c->reg0])) if(Overflow_bit_set(vm->reg[c->reg0]))
{ {
/* Adust the IP relative the the start of this instruction*/ vm->ip = vm->ip + c->raw_Immediate;
vm->ip = vm->ip + c->raw_Immediate - 4;
} }
} }
@ -1337,8 +1341,7 @@ void JUMP_G(struct lilith* vm, struct Instruction* c)
{ {
if(GreaterThan_bit_set(vm->reg[c->reg0])) if(GreaterThan_bit_set(vm->reg[c->reg0]))
{ {
/* Adust the IP relative the the start of this instruction*/ vm->ip = vm->ip + c->raw_Immediate;
vm->ip = vm->ip + c->raw_Immediate - 4;
} }
} }
@ -1346,8 +1349,7 @@ void JUMP_GE(struct lilith* vm, struct Instruction* c)
{ {
if(GreaterThan_bit_set(vm->reg[c->reg0]) || EQual_bit_set(vm->reg[c->reg0])) if(GreaterThan_bit_set(vm->reg[c->reg0]) || EQual_bit_set(vm->reg[c->reg0]))
{ {
/* Adust the IP relative the the start of this instruction*/ vm->ip = vm->ip + c->raw_Immediate;
vm->ip = vm->ip + c->raw_Immediate - 4;
} }
} }
@ -1355,8 +1357,7 @@ void JUMP_E(struct lilith* vm, struct Instruction* c)
{ {
if(EQual_bit_set(vm->reg[c->reg0])) if(EQual_bit_set(vm->reg[c->reg0]))
{ {
/* Adust the IP relative the the start of this instruction*/ vm->ip = vm->ip + c->raw_Immediate;
vm->ip = vm->ip + c->raw_Immediate - 4;
} }
} }
@ -1364,8 +1365,7 @@ void JUMP_NE(struct lilith* vm, struct Instruction* c)
{ {
if(!EQual_bit_set(vm->reg[c->reg0])) if(!EQual_bit_set(vm->reg[c->reg0]))
{ {
/* Adust the IP relative the the start of this instruction*/ vm->ip = vm->ip + c->raw_Immediate;
vm->ip = vm->ip + c->raw_Immediate - 4;
} }
} }
@ -1373,8 +1373,7 @@ void JUMP_LE(struct lilith* vm, struct Instruction* c)
{ {
if(LessThan_bit_set(vm->reg[c->reg0]) || EQual_bit_set(vm->reg[c->reg0])) if(LessThan_bit_set(vm->reg[c->reg0]) || EQual_bit_set(vm->reg[c->reg0]))
{ {
/* Adust the IP relative the the start of this instruction*/ vm->ip = vm->ip + c->raw_Immediate;
vm->ip = vm->ip + c->raw_Immediate - 4;
} }
} }
@ -1382,8 +1381,7 @@ void JUMP_L(struct lilith* vm, struct Instruction* c)
{ {
if(LessThan_bit_set(vm->reg[c->reg0])) if(LessThan_bit_set(vm->reg[c->reg0]))
{ {
/* Adust the IP relative the the start of this instruction*/ vm->ip = vm->ip + c->raw_Immediate;
vm->ip = vm->ip + c->raw_Immediate - 4;
} }
} }
@ -1391,8 +1389,7 @@ void JUMP_Z(struct lilith* vm, struct Instruction* c)
{ {
if(0 == vm->reg[c->reg0]) if(0 == vm->reg[c->reg0])
{ {
/* Adust the IP relative the the start of this instruction*/ vm->ip = vm->ip + c->raw_Immediate;
vm->ip = vm->ip + c->raw_Immediate - 4;
} }
} }
@ -1400,8 +1397,7 @@ void JUMP_NZ(struct lilith* vm, struct Instruction* c)
{ {
if(0 != vm->reg[c->reg0]) if(0 != vm->reg[c->reg0])
{ {
/* Adust the IP relative the the start of this instruction*/ vm->ip = vm->ip + c->raw_Immediate;
vm->ip = vm->ip + c->raw_Immediate - 4;
} }
} }
@ -1414,7 +1410,7 @@ void CALLI(struct lilith* vm, struct Instruction* c)
vm->reg[c->reg0] = vm->reg[c->reg0] + reg_size; vm->reg[c->reg0] = vm->reg[c->reg0] + reg_size;
/* Update PC */ /* Update PC */
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
void LOADI(struct lilith* vm, struct Instruction* c) void LOADI(struct lilith* vm, struct Instruction* c)
@ -1459,60 +1455,60 @@ void SR1I(struct lilith* vm, struct Instruction* c)
void LOADR(struct lilith* vm, struct Instruction* c) void LOADR(struct lilith* vm, struct Instruction* c)
{ {
vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate -4), false, reg_size); vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate), false, reg_size);
} }
void LOADR8(struct lilith* vm, struct Instruction* c) void LOADR8(struct lilith* vm, struct Instruction* c)
{ {
vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate -4), true, 1); vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate), true, 1);
} }
void LOADRU8(struct lilith* vm, struct Instruction* c) void LOADRU8(struct lilith* vm, struct Instruction* c)
{ {
vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate -4), false, 1); vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate), false, 1);
} }
void LOADR16(struct lilith* vm, struct Instruction* c) void LOADR16(struct lilith* vm, struct Instruction* c)
{ {
vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate -4), true, 2); vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate), true, 2);
} }
void LOADRU16(struct lilith* vm, struct Instruction* c) void LOADRU16(struct lilith* vm, struct Instruction* c)
{ {
vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate -4), false, 2); vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate), false, 2);
} }
void LOADR32(struct lilith* vm, struct Instruction* c) void LOADR32(struct lilith* vm, struct Instruction* c)
{ {
vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate -4), true, 4); vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate), true, 4);
} }
void LOADRU32(struct lilith* vm, struct Instruction* c) void LOADRU32(struct lilith* vm, struct Instruction* c)
{ {
vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate -4), false, 4); vm->reg[c->reg0] = readin_bytes(vm, (vm->ip + c->raw_Immediate), false, 4);
} }
void STORER(struct lilith* vm, struct Instruction* c) void STORER(struct lilith* vm, struct Instruction* c)
{ {
writeout_bytes(vm, (vm->ip + c->raw_Immediate - 4), vm->reg[c->reg0], reg_size); writeout_bytes(vm, (vm->ip + c->raw_Immediate), vm->reg[c->reg0], reg_size);
} }
void STORER8(struct lilith* vm, struct Instruction* c) void STORER8(struct lilith* vm, struct Instruction* c)
{ {
writeout_bytes(vm, (vm->ip + c->raw_Immediate - 4), vm->reg[c->reg0], 1); writeout_bytes(vm, (vm->ip + c->raw_Immediate), vm->reg[c->reg0], 1);
} }
void STORER16(struct lilith* vm, struct Instruction* c) void STORER16(struct lilith* vm, struct Instruction* c)
{ {
writeout_bytes(vm, (vm->ip + c->raw_Immediate - 4), vm->reg[c->reg0], 2); writeout_bytes(vm, (vm->ip + c->raw_Immediate), vm->reg[c->reg0], 2);
} }
void STORER32(struct lilith* vm, struct Instruction* c) void STORER32(struct lilith* vm, struct Instruction* c)
{ {
writeout_bytes(vm, (vm->ip + c->raw_Immediate - 4), vm->reg[c->reg0], 4); writeout_bytes(vm, (vm->ip + c->raw_Immediate), vm->reg[c->reg0], 4);
} }
void JUMP(struct lilith* vm, struct Instruction* c) void JUMP(struct lilith* vm, struct Instruction* c)
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
void JUMP_P(struct lilith* vm, struct Instruction* c) void JUMP_P(struct lilith* vm, struct Instruction* c)
@ -1521,7 +1517,7 @@ void JUMP_P(struct lilith* vm, struct Instruction* c)
tmp1 = (signed_vm_register)(vm->reg[c->reg0]); tmp1 = (signed_vm_register)(vm->reg[c->reg0]);
if(0 <= tmp1) if(0 <= tmp1)
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
} }
@ -1531,7 +1527,7 @@ void JUMP_NP(struct lilith* vm, struct Instruction* c)
tmp1 = (signed_vm_register)(vm->reg[c->reg0]); tmp1 = (signed_vm_register)(vm->reg[c->reg0]);
if(0 > tmp1) if(0 > tmp1)
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
} }
@ -1542,7 +1538,7 @@ void CMPJUMPI_G(struct lilith* vm, struct Instruction* c)
tmp2 = (signed_vm_register)(vm->reg[c->reg1]); tmp2 = (signed_vm_register)(vm->reg[c->reg1]);
if(tmp1 > tmp2) if(tmp1 > tmp2)
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
} }
@ -1553,7 +1549,7 @@ void CMPJUMPI_GE(struct lilith* vm, struct Instruction* c)
tmp2 = (signed_vm_register)(vm->reg[c->reg1]); tmp2 = (signed_vm_register)(vm->reg[c->reg1]);
if(tmp1 >= tmp2) if(tmp1 >= tmp2)
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
} }
@ -1561,7 +1557,7 @@ void CMPJUMPI_E(struct lilith* vm, struct Instruction* c)
{ {
if((vm->reg[c->reg0]) == (vm->reg[c->reg1])) if((vm->reg[c->reg0]) == (vm->reg[c->reg1]))
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
} }
@ -1569,7 +1565,7 @@ void CMPJUMPI_NE(struct lilith* vm, struct Instruction* c)
{ {
if((vm->reg[c->reg0]) != (vm->reg[c->reg1])) if((vm->reg[c->reg0]) != (vm->reg[c->reg1]))
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
} }
@ -1580,7 +1576,7 @@ void CMPJUMPI_LE(struct lilith* vm, struct Instruction* c)
tmp2 = (signed_vm_register)(vm->reg[c->reg1]); tmp2 = (signed_vm_register)(vm->reg[c->reg1]);
if(tmp1 <= tmp2) if(tmp1 <= tmp2)
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
} }
@ -1591,7 +1587,7 @@ void CMPJUMPI_L(struct lilith* vm, struct Instruction* c)
tmp2 = (signed_vm_register)(vm->reg[c->reg1]); tmp2 = (signed_vm_register)(vm->reg[c->reg1]);
if(tmp1 < tmp2) if(tmp1 < tmp2)
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
} }
@ -1599,7 +1595,7 @@ void CMPJUMPUI_G(struct lilith* vm, struct Instruction* c)
{ {
if((vm->reg[c->reg0]) > (vm->reg[c->reg1])) if((vm->reg[c->reg0]) > (vm->reg[c->reg1]))
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
} }
@ -1607,7 +1603,7 @@ void CMPJUMPUI_GE(struct lilith* vm, struct Instruction* c)
{ {
if((vm->reg[c->reg0]) >= (vm->reg[c->reg1])) if((vm->reg[c->reg0]) >= (vm->reg[c->reg1]))
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
} }
@ -1615,7 +1611,7 @@ void CMPJUMPUI_LE(struct lilith* vm, struct Instruction* c)
{ {
if((vm->reg[c->reg0]) <= (vm->reg[c->reg1])) if((vm->reg[c->reg0]) <= (vm->reg[c->reg1]))
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
} }
@ -1623,7 +1619,7 @@ void CMPJUMPUI_L(struct lilith* vm, struct Instruction* c)
{ {
if((vm->reg[c->reg0]) < (vm->reg[c->reg1])) if((vm->reg[c->reg0]) < (vm->reg[c->reg1]))
{ {
vm->ip = vm->ip + c->raw_Immediate - 4; vm->ip = vm->ip + c->raw_Immediate;
} }
} }
@ -1635,7 +1631,7 @@ void CMPSKIPI_G(struct lilith* vm, struct Instruction* c)
if(tmp1 > tmp2) if(tmp1 > tmp2)
{ {
vm->ip = vm->ip + 4; vm->ip = vm->ip + next_instruction_size(vm);
} }
} }