You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

918 lines
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
5 years ago
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) \vert (d & b) |
| 01 11 ab cd | NMUX a b c d | a = (c & b) \vert (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 \vert 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 \vert 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 = \vert b \vert |
| 09 00 02 ab | NABS a b | a = - \vert b \vert |
**** 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 |
6 years ago
| 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 \vert 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 \vert 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 | |
5 years ago
** 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 \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.
DO NOT USE.
5 years ago
| 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.
5 years ago
|--------------+------------+------------+------------+------------------|
| opcode 8bits | XOP 16bits | Reg0 4bits | Reg1 4bits | Immediate 16bits |
|--------------+------------+------------+------------+------------------|
5 years ago
| Opcode | Function group | Length in Bytes |
|--------+----------------+-----------------|
| E1 | Integer group | 6 |
*** Class F 1OPI
5 years ago
|--------------+------------+------------+------------------|
| 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
5 years ago
*** 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.
5 years ago
*** 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.
5 years ago
*** 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