Here is where we may have differing interpretations of what the bits
in the data pile may actually mean. This in particular refers to
printing the signed or unsigned versions of the bits given. Also,
interpreting some byte as a character or just a raw number.
Uses the stack and register, respectively, to jump to an absolute
address. The stack based jump pops a word off the stack to perform a
jump, while the register based one uses the operand to figure out
which register to use.
Instead of making routines to handle data in the `ret` register, just
store the result of POP into the last word register.
This means we are no longer using vm_pop_* or POP_ROUTINES for the
vm_execute script on OP_POP: instead we'll just use vm_mov_* which
automatically pops the datum for us, while moving the datum to the
last register.
Instead of having 3 differing macros for each typed version of each
opcode, just supply the type as a symbol to the macro, which will
concatenated the type to all the places necessary.
Relies on D(BYTE|HWORD|WORD) and OP_*_(BYTE|HWORD|WORD) being a
consistent naming style.
Registers are now just words, with pushing from and moving to
registers with specified subtypes just pushing those types into the
word registers. That means there are 8 word registers which can act
as 16 half word registers, which themselves can act as 64 byte
registers.
Uses some bit hacks to quickly check what data type an opcode may have
by shifting down to units then casting it to a data_type_t.
Not very well tested yet, we'll need to see now.
Instead of taking an operand and a register, mov just uses the stack
for the operand. Therefore, there's no need for a register member in
inst_t.
As a result, PUSH_*_REGISTER now uses the operand for the register.
Introduced an enum (opcode_type_t) for the masks and values of each
opcode, which allows defining a single enum which checks an opcode by
a opcode_type_t.
By default, a zero initialised set of instructions are NOOPs, which is
great.
Last two bits of a push opcode is always 01. Rest of the bits are
used to distinguish between differing types of push. This makes it
easier to inspect on the byte level what type of opcode we have.