102 lines
2.7 KiB
Markdown
102 lines
2.7 KiB
Markdown
|
Operations in MAL
|
||
|
=================
|
||
|
|
||
|
In MAL there is one main type of operation, and several sub-operations which can
|
||
|
be attached.
|
||
|
|
||
|
ALU Operations
|
||
|
--------------
|
||
|
|
||
|
There are three parts to any ALU operation...
|
||
|
|
||
|
### Choosing which registers to write to
|
||
|
|
||
|
You can write to any number of registers, as long as those registers can be
|
||
|
written to. [./registers.md](See here for the distinctions between registers.)
|
||
|
|
||
|
The formatting for is, is simply to add any number of register names, and a
|
||
|
equals sign afterwards:
|
||
|
|
||
|
REG1 = ... = REGN =
|
||
|
|
||
|
### Choosing what to set them to
|
||
|
|
||
|
This is the fun part. There are 64 possible ALU operations, and is increased to
|
||
|
192 distinct operations when working with shifter, but a large number of them
|
||
|
produce nonsense, and thus ain't available from MAL.
|
||
|
|
||
|
Assuming `A` is any readable register, except `H`, the following is the full
|
||
|
list of operations before shifting:
|
||
|
|
||
|
A
|
||
|
-A
|
||
|
INV(A)
|
||
|
A + 1
|
||
|
|
||
|
H
|
||
|
INV(H)
|
||
|
H + 1
|
||
|
|
||
|
A AND H
|
||
|
A OR H
|
||
|
A + H
|
||
|
A + H + 1
|
||
|
H - A
|
||
|
H - 1
|
||
|
|
||
|
0
|
||
|
1
|
||
|
-1
|
||
|
|
||
|
It is important to notice how not all operations are equally valid for both A
|
||
|
and H, for example `-A` have no `H` counterpart.
|
||
|
|
||
|
### Possibly do some shifting
|
||
|
|
||
|
The shifter is hooked directly up to the ALU output, which means that shifting
|
||
|
always happens last. Shifting is added to the operations, after any other
|
||
|
operation. The MIC1 only support left shifting 8, and right rotating 1:
|
||
|
|
||
|
<< 8
|
||
|
>> 1
|
||
|
|
||
|
### Summary
|
||
|
|
||
|
It is thus possible to take several different smaller parts, and combine them
|
||
|
into a large (though useless) operation like this:
|
||
|
|
||
|
MDR = H = MAR AND H << 8
|
||
|
|
||
|
Other Operations
|
||
|
----------------
|
||
|
|
||
|
In addition to the ALU operations, some misc other operations exist. Most of
|
||
|
these can be executed in the same cycle as an ALU operation.
|
||
|
|
||
|
Adding one or more of these to an ALU operation, can be done by separating them
|
||
|
with a semicolon, like so:
|
||
|
|
||
|
MDR = A + 1; wr; fetch; goto(MBR)
|
||
|
|
||
|
Lets go over them quickly:
|
||
|
|
||
|
- `rd`: Reads the `MAR`th word from memory to `MDR`. `MAR` can be set same
|
||
|
clock cycle.
|
||
|
- `wr`: Writes `MDR` to the `MAR`th word in memory. `MAR` and `MDR` can be set
|
||
|
same clock cycle.
|
||
|
- `fetch`: Reads the `PC`th byte from program memory to `MBR`. `PC` can be set
|
||
|
same clock cycle.
|
||
|
|
||
|
- `goto LABEL1`: Specifies a specific label to jump to. Equal to setting the
|
||
|
BPC to the position of the label. Usable any clock cycle.
|
||
|
- `if (X) goto LABEL1; else goto LABEL2`: Jumps to either label depending upon
|
||
|
the value of X. X can be the virtual registers `Z` or `N`. Usable any clock
|
||
|
cycle.
|
||
|
|
||
|
- `goto (MBR)`: Sets the BPC to the value of `MBR`. `MBR` can be loaded same
|
||
|
clock cycle.
|
||
|
- `goto (MBR or 0x100)`: Sets the BPC to the value of `MBR OR 0x100`. Adding
|
||
|
by `0x100`, but faster. `MBR` can be loaded same clock cycle.
|
||
|
|
||
|
Using the last two might be tricky.
|