mal-note/operations.md

105 lines
2.8 KiB
Markdown
Raw Permalink Normal View History

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
2015-12-16 22:28:07 +00:00
written to. [See here for the distinctions between registers.](./registers.md)
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
2015-12-18 17:20:42 +00:00
It is very important to note that the N and Z flip-flops are set after the ALU
operation, not after eventual shifting.
### 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.