stage0/ISA_HEX_Map.org

46 KiB

## Copyright (C) 2016 Jeremiah Orians ## This file is part of stage0. ## ## stage0 is free software: you can 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/>.

High level programming information that is likely useful

M0

What is it?

M0 is the most minimal macro-assembler possible to self bootstrap on the Knight ISA specification. In fact it is so minimal that a definition file or individual definitions need to be prepended to source files for it to work. And example of a definitions is the following: DEFINE ADD 05000

What are its assumptions?

  • all numbers outside of quotes are to be converted to 4 hex nybbles.
  • all strings are to be converted into hex form and start with a " and end with a ", no nesting
  • all definitions need to be applied if possible.
  • definitions can not be recursive or nested
  • all other details about the resulting binary will be handled by a hex2 assembler or better.
  • Line comments start with # or ; and continue to the end of the line and are not output

How to use it

Simply create a definition, such as DEFINE ADD 05000 and then use ADD where you need 05000 That is it.

Does it provide any error checking?

No

Seriously?

M0 assumes you write perfect code and never make a single mistake. If you want an macro assembler that helps to catch dumb mistakes, use something else.

Can I use M0 without stage0 vm?

Yes, that is why https://github.com/oriansj/MESCC_Tools exists

Hex2

What is it?

Hex2 is a standard set of rules that are architecture dependent which when combined with an implementation that support it functions like an advanced hex assembler. The goal behind hex2 is that any programmer should be able to implement a compatable implemention within a couple hours in C, or a couple of days in assembly or a couple of weeks if they hand encode it in hex itself. Its design is optimal for instruction sets that are nybble aligned or at worst verbose for instruction sets that are byte aligned.

What are its assumptions?

The most important assumption is that ALL labels are globally unique and should have only 1 instance.

Hex2 only assumes 4 types of inputs:

  1. Hex nybbles to be assembled
  2. Line comments beginning with # or ; to be ignored and dropped
  3. Labels that begin with :
  4. Pointers to labels that start with @,$ or &

For pointers starting with @, it is assumed that the user wants the 16bit relative displacement required by the preceeding instruction to the label; this is primarily used for jump, calli address immediates and PC relative loads and stores. For pointers starting with $, it is assumed that the user wants the 16bit absolute address of the label; 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; 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?

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, a hex assembler which supports those extensions can be considered fully compliant as long as hex2 compliant programs can be compiled correctly.

How to use it

In theory, you should never have to use hex2 directly as it is a rather tedious language to program in. Its primary design is to allow extremely low level and auditable bootstrap programs. But should you wish to do so, it'll probably be advisable for it to look something like this: :Store_String_0 05049045 # STOREX8 R0 R4 R5 ; Store the Byte 42100100 # FGETC ; Get next Byte 0F550001 # ADDUI R5 R5 1 ; Prep for next loop C306 @Store_String_0 # CMPJUMPI.NE R0 R6 @Store_String_0 ; Loop if matching not found

With very clear label names, a mixture of low and high level comments. It does become possible to write fixable code. But lets be honest, the only time you need to write hex2 is: When bootstrapping something new/ugly without M0 OR All of stage0 was lost due to a category 5 disaster.

Should you use it?

Only if engaged in low level bootstrapping with the desire to defend against the trusting trust attack in an auditable fashion. Otherwise, just use gcc or llvm and save yourself alot of responsibility.

Instruction Listing

00 xx xx xx :: NOP

Hex Name Comment
00 00 00 00 Proper NOP
00 xx xx xx NOP equivelent. Although these instructions will all be treated as NOPs. DO NOT USE THEM.

4OP Groups

4OP nn is the XOP, a = b OP c Cond d

01 nn ab cd :: 4OP Integer group

Add subgroup
Hex Name Comment
01 00 ab cd ADD.CI a b c d a = b + c + CARRY? d [signed]
01 01 ab cd ADD.CO a b c d a = b + c; d = CARRY? [signed]
01 02 ab cd ADD.CIO a b c d a = b + c + CARRY? d; d = CARRY? [signed]
01 03 ab cd ADDU.CI a b c d a = b + c + CARRY? d [unsigned]
01 04 ab cd ADDU.CO a b c d a = b + c; d = CARRY? [unsigned]
01 05 ab cd ADDU.CIO a b c d a = b + c + CARRY? d; d = CARRY? [unsigned]
Subtract subgroup
Hex Name Comment
01 06 ab cd SUB.BI a b c d a = b - c - BORROW? d [signed]
01 07 ab cd SUB.BO a b c d a = b - c; d = BORROW? [signed]
01 08 ab cd SUB.BIO a b c d a = b - c - BORROW? d; d = BORROW? [signed]
01 09 ab cd SUBU.BI a b c d a = b - c - BORROW? d [unsigned]
01 0A ab cd SUBU.BO a b c d a = b - c; d = BORROW? [unsigned]
01 0B ab cd SUBU.BIO a b c d a = b - c - BORROW? d; d = BORROW? [unsigned]
long math subgroup
Hex Name Comment
01 0C ab cd MULTIPLY a b c d a = MUL c d; b = MULH c d [signed]
01 0D ab cd MULTIPLYU a b c d a = MUL c d; b = MULH c d [unsigned]
01 0E ab cd DIVIDE a b c d a = DIV c d; b = MOD c d [signed]
01 0F ab cd DIVIDEU a b c d a = DIV c d; b = MOD c d [unsigned]
Logic subgroup
Hex Name Comment
01 10 ab cd MUX a b c d a = (c & ~b) | (d & b)
01 11 ab cd NMUX a b c d a = (c & b) | (d & ~b)
01 12 ab cd SORT a b c d a = MAX(c, d); b = MIN(c, d) [signed]
01 13 ab cd SORTU a b c d a = MAX(c, d); b = MIN(c, d) [unsigned]
Reserved Block
Hex Name
01 14 xx xx Reserved
Reserved
01 FF xx xx Reserved

02 nn ab cd :: 4OP Floating group

03 nn ab cd :: 4OP SIMD group

04 nn ab cd :: 4OP Reserved group

3OP Groups

3OP nn n is the XOP, a = b OP c

05 nn na bc :: 3OP Integer group

Turing group
Hex Name Comment
05 00 0a bc ADD a b c a = b + c [signed]
05 00 1a bc ADDU a b c a = b + c [unsigned]
05 00 2a bc SUB a b c a = b - c [signed]
05 00 3a bc SUBU a b c a = b - c [unsigned]
05 00 4a bc CMP a b c a = b CMP c [signed]
05 00 5a bc CMPU a b c a = b CMP c [unsigned]
Convience group
Hex Name Comment
05 00 6a bc MUL a b c a = b * c [signed] bottom n bits
05 00 7a bc MULH a b c a = (b * c) >> n [signed] top n bits
05 00 8a bc MULU a b c a = b * c [unsigned] bottom n bits
05 00 9a bc MULUH a b c a = (b * c) >> n [unsigned] top n bits
05 00 Aa bc DIV a b c a = b / c [signed]
05 00 Ba bc MOD a b c a = b % c [signed]
05 00 Ca bc DIVU a b c a = b / c [unsigned]
05 00 Da bc MODU a b c a = b % c [unsigned]
Reserved group 0
Hex Name
05 00 Ex xx Reserved
05 00 Fx xx Reserved
Sort group
Hex Name Comment
05 01 0a bc MAX a b c a = MAX(b, c) [signed]
05 01 1a bc MAXU a b c a = MAX(b, c) [unsigned]
05 01 2a bc MIN a b c a = MIN(b, c) [signed]
05 01 3a bc MINU a b c a = MIN(b, c) [unsigned]
Binary packing group

Due to the complexity of building/programming the pack instructions, the have been removed to simplify the porting task. The Opcodes will be preserved should we wish in the future to be binary compatable with the Knight specification.

Hex Name Comment
05 01 4a bc Reserved
Reserved
05 01 Fx xx Reserved
Logical group
Hex Name Comment
05 02 0a bc AND a b c a = b & c
05 02 1a bc OR a b c a = b | c
05 02 2a bc XOR a b c a = b XOR c
05 02 3a bc NAND a b c a != b & c
05 02 4a bc NOR a b c a != b | c
05 02 5a bc XNOR a b c a != b XOR c
05 02 6a bc MPQ a b c a = b MPQ c [Converse Nonimplication]
05 02 7a bc LPQ a b c a = b LPQ c [Material Nonimplication]
05 02 8a bc CPQ a b c a = b CPQ c [Material Implication]
05 02 9a bc BPQ a b c a = b BPQ c [Converse Implication]
Reserved group 1
Hex Name
05 02 Ax xx Reserved
Reserved
05 02 Fx xx Reserved
Bit rotation group
Hex Name Comment
05 03 0a bc SAL a b c a = b << c [arithmetically]
05 03 1a bc SAR a b c a = b >> c [arithmetically]
05 03 2a bc SL0 a b c a = b << c [Fill with zeros]
05 03 3a bc SR0 a b c a = b >> c [Fill with zeros]
05 03 4a bc SL1 a b c a = b << c [Fill with ones]
05 03 5a bc SR1 a b c a = b >> c [Fill with ones]
05 03 6a bc ROL a b c a = ROL(b, c) [Circular rotate left]
05 03 7a bc ROR a b c a = ROR(b, c) [Circular rotate right]
Load group
Hex Name Comment
05 03 8a bc LOADX a b c a = MEM[b+c]
05 03 9a bc LOADX8 a b c a = MEM[b+c] [signed 8bits]
05 03 Aa bc LOADXU8 a b c a = MEM[b+c] [unsigned 8bits]
05 03 Ba bc LOADX16 a b c a = MEM[b+c] [signed 16bits]
05 03 Ca bc LOADXU16 a b c a = MEM[b+c] [unsigned 16bits]
05 03 Da bc LOADX32 a b c a = MEM[b+c] [signed 32bits]
05 03 Ea bc LOADXU32 a b c a = MEM[b+c] [unsigned 32bits]
05 03 Fx xx Reserved
05 04 0x xx Reserved
05 04 1x xx Reserved
05 04 2x xx Reserved
05 04 3x xx Reserved
05 04 4x xx Reserved
05 04 5x xx Reserved
05 04 6x xx Reserved
05 04 7x xx Reserved
Store group
Hex Name Comment
05 04 8a bc STOREX a b c MEM[b+c] = a
05 04 9a bc STOREX8 a b c MEM[b+c] = a [8bits]
05 04 Aa bc STOREX16 a b c MEM[b+c] = a [16bits]
05 04 Ba bc STOREX32 a b c MEM[b+c] = a [32bits]
05 04 Cx xx Reserved
05 04 Dx xx Reserved
05 04 Ex xx Reserved
05 04 Fx xx Reserved
CMPJUMP group
Hex Name Comment
05 05 0a bc CMPJUMP.G a b c a > b ? PC = c
05 05 1a bc CMPJUMP.GE a b c a >= b ? PC = c
05 05 2a bc CMPJUMP.E a b c a == b ? PC = c
05 05 3a bc CMPJUMP.NE a b c a != b ? PC = c
05 05 4a bc CMPJUMP.LE a b c a <= b ? PC = c
05 05 5a bc CMPJUMP.L a b c a < b ? PC = c
05 05 6x xx Reserved
Reserved
05 05 Fx xx Reserved
05 06 0a bc CMPJUMPU.G a b c a > b ? PC = c
05 06 1a bc CMPJUMPU.GE a b c a >= b ? PC = c
05 06 2a bc Reserved
05 06 3a bc Reserved
05 06 4a bc CMPJUMPU.LE a b c a <= b ? PC = c
05 06 5a bc CMPJUMPU.L a b c a < b ? PC = c
05 06 6x xx Reserved
Reserved
05 06 Fx xx Reserved
Reserved group 2
Hex Name
05 07 0x xx Reserved
Reserved
05 FF Fx xx Reserved

06 nn na bc :: 3OP Floating group

07 nn na bc :: 3OP SIMD group

08 nn na bc :: 3OP Reserved group

2OP Groups

2OP nn nn is the XOP, a = OP b

09 nn nn ab :: 2OP Integer group

Numeric group
Hex Name Comment
09 00 00 ab NEG a b a = -b
09 00 01 ab ABS a b a = | b |
09 00 02 ab NABS a b a = - | b |
Movement group
Hex Name Comment
09 00 03 ab SWAP a b a <=> b
09 00 04 ab COPY a b a = b
09 00 05 ab MOVE a b a = b; b = 0
09 00 06 ab NOT a b a = !b
Reserved Block 0
Hex Name
09 00 07 xx Reserved
Reserved
09 00 FF xx Reserved
Function call group
Hex Name Comment
09 01 00 ab BRANCH a b MEM[b] = PC; PC = a
09 01 01 ab CALL a b MEM[b] = PC; b = b + (register size in bytes); PC = a
Stack group
Hex Name Comment
09 02 00 ab PUSHR a b MEM[b] = a; b = b + (register size in bytes)
09 02 01 ab PUSH8 a b MEM[b] = bottom_8_bits(a); b = b + 1
09 02 02 ab PUSH16 a b MEM[b] = bottome_16_bits(a); b = b + 2
09 02 03 ab PUSH32 a b MEM[b] = bottome_32_bits(a); b = b + 4
09 02 04 xx Reserved
Reserved
09 02 7F xx Reserved
09 02 80 ab POPR a b a = MEM[b]; MEM[b] = 0; b = b - (register size in bytes)
09 02 81 ab POP8 a b a = MEM[b] (signed); MEM[b] = 0; b = b - 1
09 02 82 ab POPU8 a b a = MEM[b] (unsigned); MEM[b] = 0; b = b - 1
09 02 83 ab POP16 a b a = MEM[b] (signed); MEM[b] = 0; b = b - 2
09 02 84 ab POPU16 a b a = MEM[b] (unsigned); MEM[b] = 0; b = b - 2
09 02 85 ab POP32 a b a = MEM[b] (signed); MEM[b] = 0; b = b - 4
09 02 86 ab POPU32 a b a = MEM[b] (signed); MEM[b] = 0; b = b - 4
Reserved
09 02 FF xx Reserved
CMPSKIP group
Hex Name Comment
09 03 00 ab CMPSKIP.G a b a > b ? Skip Next instruction
09 03 01 ab CMPSKIP.GE a b a >= b ? Skip Next instruction
09 03 02 ab CMPSKIP.E a b a == b ? Skip Next instruction
09 03 03 ab CMPSKIP.NE a b a != b ? Skip Next instruction
09 03 04 ab CMPSKIP.LE a b a <= b ? Skip Next instruction
09 03 05 ab CMPSKIP.L a b a < b ? Skip Next instruction
09 03 06 xx Reserved
Reserved
09 03 7F ab Reserved
09 03 80 ab CMPSKIPU.G a b a > b ? Skip Next instruction
09 03 81 ab CMPSKIPU.GE a b a >= b ? Skip Next instruction
09 03 82 ab Reserved
09 03 83 ab Reserved
09 03 84 ab CMPSKIPU.LE a b a <= b ? Skip Next instruction
09 03 85 ab CMPSKIPU.L a b a < b ? Skip Next instruction
09 03 86 xx Reserved
Reserved
09 03 FF ab Reserved
Reserved Block 1
Hex Name
09 02 87 xx Reserved
Reserved
09 FF FF xx Reserved

0A nn nn ab :: 2OP Floating group

0B nn nn ab :: 2OP SIMD group

0C nn nn ab :: 2OP Reserved group

1OP Groups

1OP nn nn n is the XOP, a = OP a

0D nn nn na :: 1OP group

State group
Hex Name Comment
0D 00 00 0a READPC a a = PC
0D 00 00 1a READSCID a a = SCID
0D 00 00 2a FALSE a a = 0
0D 00 00 3a TRUE a a = FF … FF
Reserved block 0
Hex Name
0D 00 00 4x Reserved
Reserved
0D 00 FF Fx Reserved
Function return group
Hex Name Comment
0D 01 00 0a JSR_COROUTINE a PC = a
0D 01 00 1a RET a a = a - (register size in bytes); PC = MEM[a]; MEM[a] = 0
Reserved block 1
Hex Name
0D 01 00 2x Reserved
Reserved
0D 01 FF Fx Reserved
Stack state group
Hex Name Comment
0D 02 00 0a PUSHPC a MEM[a] = PC; a = a + (register size in bytes)
0D 02 00 1a POPPC a PC = MEM[a]; a = a - (register size in bytes)
Reserved
Hex Name
0D 02 00 2x Reserved
Reserved
0D FF FF Fx Reserved

0OPI group

0OPI ii ii is the Immediate, OP ii ii

Unconditional jumps

Hex Name Comment
3C 00 ii ii JUMP ii ii PC = PC + ii ii

Reserved Block 0

At this time these instructions only produce a warning; but could do anything. DO NOT USE.

Hex Name
3D 00 00 00 Reserved
Reserved
41 FF FF FF Reserve

HALCODE Group

42 hh hh hh is the HALCODE callID, invalid HALCODE SHOULD NOT BE USED.

HALCODE Reserved for Operating Systems

The following block contains both instructions that are reserved for Operating systems and for internal use by Operating systems. When initialized by the Operating system, the HALCODEs are tagged with a priviledge mode, if the binary is not also tagged with permissions for that mode, an illegal instruction trap occurs when the HALCODE is decoded.

The default reserved Block: 42000000-420FFFFF; however all HALCODEs can be remapped, replaced and repurposed by the Operating system after initialization and you should refer to your system documentation from your Operating system provider to know what mappings have been exposed for use.

Example posix mapping
Hex Name Comment
42 00 00 02 FOPEN open(char* FILENAME, int FLAGS, int MODE) using R0, R1 and R2 respectively
42 00 00 03 FCLOSE close(int FD) using R0
42 00 00 08 FSEEK seek(int FD, off_t OFFSET, int WHENCE) using R0, R1 and R2 respectively
42 00 00 3C EXIT exit(int ERROR_CODE) using R0
42 00 00 3F UNAME uname(struct utsname* BUF) using R0
42 00 00 5A CHMOD chmod(char* PATHNAME, int MODE) using R0 and R1 respectively
42 10 01 00 FGETC read 1 byte into register 0 from device who's ID is in register 1
42 10 02 00 FPUTC write 1 byte from register 0 to device who's ID is in register 1

Tape console HALCODE

This HALCODE is used for interacting with any tape console attached to the system.

Reference specific notes

In this reference implementation we will be interacting with a simplified version of the series 10 console. All compatible implementations need to ensure to implement functional equivelents. Provided of course that any deviations would not change any output specified to be written to tape. Padding with Zeros til start/end of page/segment however is acceptable.

Standard compatibility requirements

The following 3 devices must exist with the following exact IDs

Interface Name ID
Keyboard/tty 00 00 00 00
Tape 1 00 00 11 00
Tape 2 00 00 11 01
Required Device HALCODE
Hex Name Comment
42 10 00 00 FOPEN_READ Feed on device who's ID matches the contents of register 0 until first non-zero byte is found.
42 10 00 01 FOPEN_WRITE Feed on device who's ID matches the contents of register 0 until first zero byte is found
42 10 00 02 FCLOSE Close out writes to device who's ID matches the contents of register 0.
42 10 00 03 REWIND rewind back to first non-zero byte found on tape.
42 10 00 04 FSEEK seek forward or backward the number of bytes specified in register 1 on
the device who's ID matches the contents of register 0.
Reserved Block for Hardware specific implementation details
Hex Name
42 10 00 04 Reserved
Reserved
42 10 00 FF Reserved
Required Device capability HALCODE
Device Read HALCODE
Hex Name Comment
42 10 01 00 FGETC read 1 byte into register 0 from device who's ID is in register 1
Reserved Block for Hardware specific implementation details
Hex Name
42 10 01 01 Reserved
Reserved
42 10 01 FF Reserved
Device Write HALCODE
Hex Name Comment
42 10 02 00 FPUTC write 1 byte from register 0 to device who's ID is in register 1
Reserved Block for Hardware specific implementation details
Hex Name
42 10 02 01 Reserved
Reserved
42 10 02 FF Reserved
Reserved Block for Future HALCODE Expansion
Hex Name
42 10 03 00 Reserved
Reserved
42 10 FF FF Reserved
Device physical specifications
Hex Name Comment
42 11 00 00 HAL_MEM Loads the total amount of physical Memory that is functional into register 0
Reserved Block for Future HALCODE Expansion
Hex Name
42 12 00 00 Reserved
Reserved
42 FF FF FF Reserved

Reserved Block 1

At this time these instructions only produce a warning; but could do anything. DO NOT USE.

Hex Name
43 00 00 00 Reserved
Reserved
AF FF FF FF Reserved

Bit optimization group

Hex Name Comment
B0 ab ii ii ANDI a b ii ii a = b & ii ii
B1 ab ii ii ORI a b ii ii a = b | ii ii
B2 ab ii ii XORI a b ii ii a = b XOR ii ii
B3 ab ii ii NANDI a b ii ii a != b && ii ii
B4 ab ii ii NORI a b ii ii a != b | ii ii
B5 ab ii ii XNORI a b ii ii a != b XOR ii ii
B6 00 00 00 Reserved
Reserved
BF FF FF FF Reserved

Extended instruction block

This block specified for instructions that require immediates

1OPI Groups

1OPI i ii ii is the Immediate, a = a OP i ii ii

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 | 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 | 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. DO NOT USE.

Hex Name
E1 01 00 00 00 00 Reserved
Reserved
EF FF FF FF FF FF Reserved

0OP

Hex Name Comment
FF xx xx xx HALT equivelent. Although these instructions will all be treated as HALTs. DO NOT USE THEM.
FF FF FF FF Proper HALT

Encoding/Decoding Reference

Registers

There is a direct and consistent relationship between the nybbles and the registers.

Hex Name
0 REG0
1 REG1
2 REG2
3 REG3
4 REG4
5 REG5
6 REG6
7 REG7
8 REG8
9 REG9
A REG10
B REG11
C REG12
D REG13
E REG14
F REG15

Instruction Formats

All instructions are encoded left to right with the first byte being the lowest address. This ordering was selected simply because makes the starting IP address 0 and is the obvious ordering for those with left to right written langauges.

Class A 4OP

opcode 8bits XOP 8bits Reg0 4bits Reg1 4bits Reg2 4bits Reg3 4bits
Opcode Function group Length in Bytes
01 Integer group 4

Class B 3OP

opcode 8bits XOP 12bits Reg0 4bits Reg1 4bits Reg2 4bits
Opcode Function group Length in Bytes
05 Integer group 4

Class C 2OP

opcode 8bits XOP 16bits Reg0 4bits Reg1 4bits
Opcode Function group Length in Bytes
09 Integer group 4

Class D 1OP

opcode 8bits XOP 20bits Reg0 4bits
Opcode Function group Length in Bytes
0D Integer group 4

Class E 2OPI

This is a very rare and special group as each entry consumes a piece of the precious 256 entry opcode space.

opcode 8bits XOP 16bits Reg0 4bits Reg1 4bits Immediate 16bits
Opcode Function group Length in Bytes
E1 Integer group 6

Class F 1OPI

opcode 8bits XOP 20bits Reg0 4bits Immediate 16bits
Opcode Function group Length in Bytes
E0 Integer group 6

Class G 0OPI

opcode 8bits XOP 8bits Immediate 16bits
Opcode Function group Length in Bytes
3C Integer group 4

Class H Halcode

opcode 8bits HALCODE 24bits
Opcode Function group Length in Bytes
42 HALCODE 4

Class I 0OP

opcode 8bits XOP 24bits
Opcode Function group Length in Bytes
00 NOP 4
FF HALT 4

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

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. This will result in a page fault if the next byte is in the next page and the instruction will have to be restarted

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.

Systems supporting more HALCODES than those listed in this document must implement HALCODE 0x42FFFFFF which must provide a DEVICE LIST and HALCODE 0x42000000 which must provide a HALCODE LIST