Some things that were previously hard VM-level errors are now handled by
interrupts. While this is relatively easy to handle, I was wanting a
little more structure for the error types - so, errors that should
invoke an interrupt are passed along in their own structure in a
VmError::Interrupt variant. If an error is raised during the tick()
phase of execution that would cause an interrupt, that interrupt is
intercepted and the VM continues.
The State::interrupt() function also will catch double faults and triple
faults, with a triple fault being its own variant in the VmError
structure (so it cannot be intercepted as an interrupt by accident).
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Exception definition is a little more comprehensive
* Add error state exceptions including double fault
* Exception numbers are now roughly in the order of their importance
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Number tokens with a dollar sign are kind of cumbersome and don't really
serve a purpose, so I'm removing them.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
It makes sense to allow users to set the initial register values. This
allows someone to e.g. enable interrupts once the VM has started, or set
the initial stack pointer value.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Interrupts need to be on 8-byte (or 64-bit) bounds. I had mistakenly
decided to shift right by 5 (which isn't even dividing by 64, it's 32)
-but since this an address pointing at byte ranges, that should be
divided by 8, or >> 3.
Additionally, interrupts add all 32 general purpose registers to the
stack because otherwise they become useless.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Aligned values are a little funky, because the size of the line can't be
determined without knowing what address we're at. So the
DataLines iterator now takes a start address, so it is able to correctly
calculate alignment padding.
Also, the length of the data section uses the DataLines iterator now so
there isn't a complex re-implementation of the same logic.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Cargo is finding more reasons to do unnecessary rebuilds, so I've added
the rerun_except crate to its build.rs as well to ignore .asm files
before recompiling.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Lots of null bytes in a row are a common thing, so the instructions
available can't start with a null pair of bytes anymore.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Interrupts require functions being aligned on 64-bit boundaries.
Alignment is now allowed via the .align <intsize> directive, aligning
the current address to a new alignment.
* Datasection iteration doesn't require keeping track of the current
position.
* Rudimentary disassembler for breaking down the contents of an object
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Instruction assembler used to use macros for handling source,
dest-source, source-source, etc instructions. It did not have a
source-source implementation, however, so the two source-source
instructions (cmpeq and cmplt) were treated as dest-source. This has
been refactored into some local methods that handle this now.
* Syntax for interrupts and interrupt returns are implemented and appear
to be working
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
Assembler has more discrete passes now, but things are kind of bare on
the error message front. But, everything is working as it did
previously, so we can move on to more interesting things.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Preprocessor uses an LRPAR generated lexer and a custom parser to
filter comments and set defines. Includes and conditional compilation
will come next.
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Call/ret/push/pop are implemented and appear to be working
* Call/ret/push/pop is specified in the 0x2000 block, replacing the
mov instruction
* Mov instruction is now specified in the 0x3000 block
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* compile flag and compile_out argument to the driver allow the program
to be compiled only
* if '-' is supplied to compile_out, it will output to STDOUT instead
* if '-' is supplied to input, it will read from STDIN instead
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
* Data section names are encoded in the object file format
* Objects can be converted into their file format layouts
* Add writing/reading test to make sure that an object converted to
bytes and then back from bytes is equal to hopefully catch major
object translations
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>