mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-04-18 02:06:43 +00:00
added missing instructions. Also changed NEG to in the table to avoid confusion
parent
eb0e02f4ac
commit
226529e3fb
@ -3,48 +3,46 @@
|
||||
### Instruction table with affected flags
|
||||
| Instruction mnemonic | Operands | Opcode | `C Z S O B` |
|
||||
| -------------------- |:-------- |:------:|:--------- |
|
||||
| **ADD** *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x02 | `X X X X -` |
|
||||
| **AND** *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x04 | `0 X X 0 -` |
|
||||
| **BRK** | *None* | 0x00 |`- - - - 1` |
|
||||
| **CALL** *target* | *mem/reg/imm* | 0x15 |`- - - - -` |
|
||||
| **CMP** *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x0C |`X X X X -` |
|
||||
| **DIV** *source* | *mem/reg/imm* | 0x18 |`- - - - -` |
|
||||
| **HWI** *source* | *mem/reg/imm* | 0x09 |`- - - - -` |
|
||||
| **HWQ** *source* | *mem/reg/imm* | 0x1C |`- - - - -` |
|
||||
| **JC** *target* | *mem/reg/imm* | 0x21 |`- - - - -` |
|
||||
| **JG** *target* | *mem/reg/imm* | 0x0F |`- - - - -` |
|
||||
| **JGE** *target* | *mem/reg/imm* | 0x10 |`- - - - -` |
|
||||
| **JL** *target* | *mem/reg/imm* | 0x11 |`- - - - -` |
|
||||
| **JLE** *target* | *mem/reg/imm* | 0x12 |`- - - - -` |
|
||||
| **JMP** *target* | *mem/reg/imm* | 0x0A |`- - - - -` |
|
||||
| **JNC** *target* | *mem/reg/imm* | 0x22 |`- - - - -` |
|
||||
| **JNO** *target* | *mem/reg/imm* | 0x25 |`- - - - -` |
|
||||
| **JNS** *target* | *mem/reg/imm* | 0x1B |`- - - - -` |
|
||||
| **JNZ** *target* | *mem/reg/imm* | 0x0D |`- - - - -` |
|
||||
| **JO** *target* | *mem/reg/imm* | 0x24 |`- - - - -` |
|
||||
| **JS** *target* | *mem/reg/imm* | 0x1A |`- - - - -` |
|
||||
| **JZ** *target* | *mem/reg/imm* | 0x0E |`- - - - -` |
|
||||
| **MOV** *destination*, *source* | *mem/reg*, *mem/reg/imm* |0x01 |`- - - - -` |
|
||||
| **MUL** *source* | *mem/reg/imm* | 0x17 |`X - - X -` |
|
||||
| **NEG** *destination* | *mem/reg* | 0x19 |`1 X X X -`* |
|
||||
| **NOP** | *None* | 0x3F |`- - - - -` |
|
||||
| **NOT** *destination* | *mem/reg* | 0x1D |`- - - - -` |
|
||||
| **OR** *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x05 |`0 X X 0 -` |
|
||||
| **POP** *destination* | *mem/reg* | 0x14 |`- - - - -` |
|
||||
| **PUSH** *source* | *mem/reg/imm* | 0x13 |`- - - - -` |
|
||||
| **RCL** *destination*, *count* | *mem/reg*, *mem/reg/imm* | 0x27 |`X - - X -` |
|
||||
| **RCR** *destination*, *count* | *mem/reg*, *mem/reg/imm* | 0x28 |`X - - X -` |
|
||||
| **RET** *optional-pop-value* | *imm/None* | 0x16 |`- - - - -` |
|
||||
| **ROL** *destination*, *count* | *mem/reg*, *mem/reg/imm* | 0x23 |`X - - X -` |
|
||||
| **ROR** *destination*, *count* | *mem/reg*, *mem/reg/imm* | 0x20 |`X - - X -` |
|
||||
| **SHL** *destination*, *count* | *mem/reg*, *mem/reg/imm* | 0x06 |`X - - X -` |
|
||||
| **SHR** *destination*, *count* | *mem/reg*, *mem/reg/imm* | 0x07 |`X - - X -` |
|
||||
| **SUB** *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x03 |`X X X X -` |
|
||||
| **TEST** *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x0B |`0 X X 0 -` |
|
||||
| **XCHG** *destination*, *source* | *mem/reg*, *mem/reg* | 0x1F |`- - - - -` |
|
||||
| **XOR** *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x26 |`0 X X 0 -` |
|
||||
|
||||
*NEG instruction: CF is set to 0 if destination=0
|
||||
| [**ADD**](#ADD) *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x02 | `X X X X -` |
|
||||
| [**AND**](#AND) *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x04 | `0 X X 0 -` |
|
||||
| [**BRK**](#BRK) | *None* | 0x00 |`- - - - 1` |
|
||||
| [**CALL**](#CALL) *target* | *mem/reg/imm* | 0x15 |`- - - - -` |
|
||||
| [**CMP**](#CMP) *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x0C |`X X X X -` |
|
||||
| [**DIV**](#DIV) *source* | *mem/reg/imm* | 0x18 |`- - - - -` |
|
||||
| [**HWI**](#HWI) *source* | *mem/reg/imm* | 0x09 |`- - - - -` |
|
||||
| [**HWQ**](#HWQ) *source* | *mem/reg/imm* | 0x1C |`- - - - -` |
|
||||
| [**JC**](#JC) *target* | *mem/reg/imm* | 0x21 |`- - - - -` |
|
||||
| [**JG**](#JG) *target* | *mem/reg/imm* | 0x0F |`- - - - -` |
|
||||
| [**JGE**](#JGE) *target* | *mem/reg/imm* | 0x10 |`- - - - -` |
|
||||
| [**JL**](#JL) *target* | *mem/reg/imm* | 0x11 |`- - - - -` |
|
||||
| [**JLE**](#JLE) *target* | *mem/reg/imm* | 0x12 |`- - - - -` |
|
||||
| [**JMP**](#JMP) *target* | *mem/reg/imm* | 0x0A |`- - - - -` |
|
||||
| [**JNC**](#JNC) *target* | *mem/reg/imm* | 0x22 |`- - - - -` |
|
||||
| [**JNO**](#JNO) *target* | *mem/reg/imm* | 0x25 |`- - - - -` |
|
||||
| [**JNS**](#JNS) *target* | *mem/reg/imm* | 0x1B |`- - - - -` |
|
||||
| [**JNZ**](#JNZ) *target* | *mem/reg/imm* | 0x0D |`- - - - -` |
|
||||
| [**JO**](#JO) *target* | *mem/reg/imm* | 0x24 |`- - - - -` |
|
||||
| [**JS**](#JS) *target* | *mem/reg/imm* | 0x1A |`- - - - -` |
|
||||
| [**JZ**](#JZ) *target* | *mem/reg/imm* | 0x0E |`- - - - -` |
|
||||
| [**MOV**](#MOV) *destination*, *source* | *mem/reg*, *mem/reg/imm* |0x01 |`- - - - -` |
|
||||
| [**MUL**](#MUL) *source* | *mem/reg/imm* | 0x17 |`X - - X -` |
|
||||
| [**NEG**](#NEG) *destination* | *mem/reg* | 0x19 |`X X X X -`* |
|
||||
| [**NOP**](#NOP) | *None* | 0x3F |`- - - - -` |
|
||||
| [**NOT**](#NOT) *destination* | *mem/reg* | 0x1D |`- - - - -` |
|
||||
| [**OR**](#OR) *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x05 |`0 X X 0 -` |
|
||||
| [**POP**](#POP) *destination* | *mem/reg* | 0x14 |`- - - - -` |
|
||||
| [**PUSH**](#PUSH) *source* | *mem/reg/imm* | 0x13 |`- - - - -` |
|
||||
| [**RCL**](#RCL) *destination*, *count* | *mem/reg*, *mem/reg/imm* | 0x27 |`X - - X -` |
|
||||
| [**RCR**](#RCR) *destination*, *count* | *mem/reg*, *mem/reg/imm* | 0x28 |`X - - X -` |
|
||||
| [**RET**](#RET) *optional-pop-value* | *imm/None* | 0x16 |`- - - - -` |
|
||||
| [**ROL**](#ROL) *destination*, *count* | *mem/reg*, *mem/reg/imm* | 0x23 |`X - - X -` |
|
||||
| [**ROR**](#ROR) *destination*, *count* | *mem/reg*, *mem/reg/imm* | 0x20 |`X - - X -` |
|
||||
| [**SHL**](#SHL) *destination*, *count* | *mem/reg*, *mem/reg/imm* | 0x06 |`X - - X -` |
|
||||
| [**SHR**](#SHR) *destination*, *count* | *mem/reg*, *mem/reg/imm* | 0x07 |`X - - X -` |
|
||||
| [**SUB**](#SUB) *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x03 |`X X X X -` |
|
||||
| [**TEST**](#TEST) *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x0B |`0 X X 0 -` |
|
||||
| [**XCHG**](#XCHG) *destination*, *source* | *mem/reg*, *mem/reg* | 0x1F |`- - - - -` |
|
||||
| [**XOR**](#XOR) *destination*, *source* | *mem/reg*, *mem/reg/imm* | 0x26 |`0 X X 0 -` |
|
||||
|
||||
### Instruction encoding
|
||||
Instructions are 1-3 words long and are fully defined by the first word.
|
||||
@ -53,13 +51,13 @@ are the opcode, and the remaining 10 bits are split into a 5 bit destination ope
|
||||
and a 5 bit source operand.
|
||||
In bits, a basic instruction has the format: `sssssdddddoooooo`
|
||||
|
||||
Operand value:
|
||||
Operand value:
|
||||
|
||||
| Description | Value |
|
||||
| --- | --- |
|
||||
| Invalid or none | `00000` |
|
||||
| Immediate value at IP+1 | `11111` |
|
||||
| [Immediate value at IP+1] | `11110` |
|
||||
| Description | Value |
|
||||
| --- | --- |
|
||||
| Invalid or none | `00000` |
|
||||
| Immediate value at IP+1 | `11111` |
|
||||
| [Immediate value at IP+1] | `11110` |
|
||||
| Register | `00001`-`01000` |
|
||||
| [Register] | `01001`-`10000` |
|
||||
| Register + Immediate value at IP+1 | `10001`-`11000` |
|
||||
@ -81,7 +79,18 @@ MOV A, 0x20
|
||||
|
||||
This human readable format is parsed by the assembler which will output the actual binary opcodes and operands. More about the encoding can be read [below](#Encoding).
|
||||
|
||||
## Flags
|
||||
Some instructions will change certain flags based on their result. These are in a special non read-write register.
|
||||
The only way to set these flags is by using instructions and the only way to read these flags is with the jump behaviour
|
||||
|
||||
> NOTE: The flags might be readable in the future
|
||||
|
||||
for more information check the [docs](https://github.com/simon987/Much-Assembly-Required/wiki/CPU#the-flags-register)
|
||||
|
||||
####
|
||||
|
||||
## Instructions
|
||||
|
||||
### BRK
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
@ -118,7 +127,7 @@ destination = source
|
||||
|
||||
### Pseudo code
|
||||
```py
|
||||
destination = destination + source
|
||||
result = destination + source
|
||||
```
|
||||
|
||||
### SUB
|
||||
@ -131,9 +140,6 @@ destination = destination + source
|
||||
#### Description
|
||||
`SUB` subtracts the source operand from the destination operand and stores the result in destination.
|
||||
|
||||
> ? TODO: is this implemented?
|
||||
> When an immediate byte value is subtracted from a word operand, the immediate value is first sign-extended to the size of the destination operand.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination = destination - source
|
||||
@ -179,19 +185,17 @@ destination = destination | source
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `SHL destination, count` | `0x06` | `destination` : `reg` / `mem` | `X` | `-` | `-` | `X` | `-` |
|
||||
| `SHL destination, count` | `0x06` | `destination` : `reg` / `mem` | `X` | `X` | `X` | `X` | `-` |
|
||||
| | | `count` : `reg` / `mem` / `imm` |
|
||||
|
||||
#### Description
|
||||
`SHL` shifts the bits of the destination operand upward (toward the
|
||||
most significant bit) by the number of bit positions specified in
|
||||
the second operand (count). As bits are transferred out of the
|
||||
the second operand (`count`). As bits are transferred out of the
|
||||
left (high-order) end of the destination, zero bits are shifted
|
||||
into the right (low-order) end.
|
||||
|
||||
> ? TODO: is this implemented?
|
||||
> The carry flag (CF) is set equal
|
||||
to the last bit shifted out of the left end.
|
||||
The carry flag (CF) is set equal to the last bit shifted out of the left end.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
@ -212,10 +216,6 @@ SHR shifts the bits of the destination operand downward (toward
|
||||
out of the right (low-order) end of the destination, zero bits are
|
||||
shifted into the left (high-order) end.
|
||||
|
||||
> ? TODO: is this implemented?
|
||||
> The carry flag (CF) is set
|
||||
equal to the last bit shifted out of the right end.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination = destination >> count
|
||||
@ -272,10 +272,6 @@ destination & source # flags will be set
|
||||
destination and updates the flags. None of the operands are
|
||||
changed.
|
||||
|
||||
> ? TODO: is this implemented correctly?
|
||||
> I see differing results using test/jz vs cmp/jnz that seem to involve overflow from the latter?
|
||||
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination - source # flags will be set
|
||||
@ -452,13 +448,12 @@ The result of the multiplication is stored into `Y:A` where the higher order bit
|
||||
|
||||
The carry and overflow flags are set to 1 if the high-order of the result is bigger than 0; otherwise, CF and OF are reset to 0.
|
||||
|
||||
> This is a somewhat complicated instruction
|
||||
> See the [source](https://github.com/simon987/Much-Assembly-Required/blob/master/Server/source/main/java/net/simon987/server/assembly/instruction/MulInstruction.java) if needed
|
||||
> This is a somewhat complicated instruction,
|
||||
> see the [source](https://github.com/simon987/Much-Assembly-Required/blob/master/Server/source/main/java/net/simon987/server/assembly/instruction/MulInstruction.java) if needed
|
||||
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
|
||||
# result is a 32-bit integer
|
||||
result = A * source
|
||||
# get the 16 most significant bits of result
|
||||
@ -486,12 +481,12 @@ A = (result & 0x00ff)
|
||||
#### Description
|
||||
`DIV` performs unsigned division on `Y:A` with `source` as divisor and stores the result into `A` and the remainder in `Y`.
|
||||
|
||||
> NOTE: `DIV` operates on a 32 bit integer composed of `Y:A`. So multiple `DIV` instructions without setting Y to what you want will result into weird results
|
||||
> NOTE: `DIV` operates on a 32 bit integer composed of `Y:A`. So multiple `DIV` instructions without setting Y to what you want will result into unexpected results
|
||||
|
||||
Note that a division by 0 will set the (undocumented) error flag and the break flag. This will halt execution.
|
||||
> NOTE: that a division by 0 will set the (undocumented) error flag and the break flag. This will halt execution.
|
||||
|
||||
> This is a somewhat complicated instruction
|
||||
> See the [source](https://github.com/simon987/Much-Assembly-Required/blob/master/Server/source/main/java/net/simon987/server/assembly/instruction/DivInstruction.java) if needed
|
||||
> This is a somewhat complicated instruction,
|
||||
> see the [source](https://github.com/simon987/Much-Assembly-Required/blob/master/Server/source/main/java/net/simon987/server/assembly/instruction/DivInstruction.java) if needed
|
||||
|
||||
|
||||
#### Pseudo code
|
||||
@ -516,7 +511,7 @@ Y = temp % source
|
||||
| `NEG destintation` | `0x19` | `destination` : `mem` / `reg` | `X` | `X` | `X` | `X` | `-` |
|
||||
|
||||
#### Description
|
||||
`NEG` subtracts the destination operand from 0 and returns the result in the destination. This effectively produces the two's complement of the operand.
|
||||
`NEG` subtracts the `destination` operand from 0 and returns the result in the `destination`. This effectively produces the two's complement of the operand.
|
||||
|
||||
If the operand is zero, the carry flag is cleared; in all other cases, the carry flag is set.
|
||||
|
||||
@ -543,7 +538,7 @@ else
|
||||
| `JS target` | `0x1A` | `target` : `mem` / `reg` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JS` jumps to the target if the sign flag **IS** set.
|
||||
`JS` jumps to the `target` if the sign flag **IS** set.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
@ -558,7 +553,7 @@ if SIGN_FLAG == 1:
|
||||
| `JNS target` | `0x1B` | `target` : `mem` / `reg` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JNS` jumps to the target if the sign flag **IS NOT** set.
|
||||
`JNS` jumps to the `target` if the sign flag **IS NOT** set.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
@ -578,7 +573,10 @@ if SIGN_FLAG == 0:
|
||||
#### Pseudo code
|
||||
```py
|
||||
if hardware_memory[source] != None:
|
||||
B = get_hardware_id(hardware_memory[source]) # not sure how to (pseudo) code this
|
||||
# not sure how to (pseudo) code this
|
||||
B = get_hardware_id(
|
||||
hardware_memory[source]
|
||||
)
|
||||
else:
|
||||
B = 0
|
||||
```
|
||||
@ -587,7 +585,7 @@ else:
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `NOT destintation` | `0x1D` | `source` : `mem` / `reg` | `-` | `-` | `-` | `-` | `-` |
|
||||
| `NOT destination` | `0x1D` | `source` : `mem` / `reg` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`NOT` inverts each bit in its operand, i.e. forms the one's complement.
|
||||
@ -597,4 +595,287 @@ else:
|
||||
dest = ~dest
|
||||
```
|
||||
|
||||
## Encoding
|
||||
### XCHG
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `XCHG destination, source` | `0x1F` | `destination` : `mem` / `reg` | `-` | `-` | `-` | `-` | `-` |
|
||||
| | | `source` : `mem` / `reg` |
|
||||
|
||||
#### Description
|
||||
`XCHG` switches the contents of two operands.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
temp = destination
|
||||
destination = source
|
||||
source = destination
|
||||
```
|
||||
|
||||
### ROR
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `ROR destination, count` | `0x20` | `destination` : `mem` / `reg` | `X` | `-` | `-` | `X` | `-` |
|
||||
| | | `count` : `mem` / `reg`, `imm` |
|
||||
|
||||
#### Description
|
||||
`ROR` shifts the bits of `destination` operand to the right by the number of bit positions specified by `count`.
|
||||
|
||||
if `count` is greater than 15 it will be the remainder of a division by 16.
|
||||
|
||||
as bits are transferred out the right (low-order) end of the destination, they re-enter on the left (high-order) end. The carry flag (CF) is updated to match the last bit shifted out of the right end.
|
||||
|
||||
if `count` equals 1 then the overflow flag will be set if the sign bit of `destination` has changed
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
count = count % 16
|
||||
|
||||
# TODO: less implementation more pseudo code
|
||||
if (destination & 0x8000) > 0: # check if sign bit was set
|
||||
old_sign_bit = 1
|
||||
else
|
||||
old_sign_bit = 0
|
||||
|
||||
destination = #... ROR magic
|
||||
|
||||
if (destination & 0x8000) > 0: # check if sign bit was set
|
||||
new_sign_bit = 1
|
||||
else
|
||||
new_sign_bit = 0
|
||||
|
||||
if count == 1:
|
||||
OVERFLOW_FLAG = (old_signbit == new_signbit) # check if sign bit changed
|
||||
|
||||
if new_sign_bit == 1:
|
||||
CARRY_FLAG = 1
|
||||
else:
|
||||
CARRY_FLAG = 1
|
||||
```
|
||||
|
||||
# JC
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JC target` | `0x21` | `target` : `mem` / `reg` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JC` jumps to the `target` if the carry flag **IS** set.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if CARRY_FLAG == 1:
|
||||
IP = target
|
||||
```
|
||||
|
||||
# JNC
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JNC target` | `0x22` | `target` : `mem` / `reg` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JNC` jumps to the `target` if the carry flag **IS NOT** set.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if CARRY_FLAG == 0:
|
||||
IP = target
|
||||
```
|
||||
|
||||
### ROL
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `ROL destination, count` | `0x23` | `destination` : `mem` / `reg` | `X` | `-` | `-` | `X` | `-` |
|
||||
| | | `count` : `mem` / `reg`, `imm` |
|
||||
|
||||
#### Description
|
||||
`ROL` shifts the bits of `destination` operand to the left by the number of bit positions specified by `count`.
|
||||
|
||||
if `count` is greater than 15 it will be the remainder of a division by 16.
|
||||
|
||||
as bits are transferred out the left (high-order) end of the destination, they re-enter on the right (low-order) end. The carry flag (CF) is updated to match the last bit shifted out of the left end.
|
||||
|
||||
if `count` equals 1 then the overflow flag will be set if the sign bit of `destination` has changed
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
count = count % 16
|
||||
|
||||
# TODO: less implementation more pseudo code
|
||||
if (destination & 0x8000) > 0: # check if sign bit was set
|
||||
old_sign_bit = 1
|
||||
else
|
||||
old_sign_bit = 0
|
||||
|
||||
destination = #... ROL magic
|
||||
|
||||
# carry flag might be set
|
||||
|
||||
if (destination & 0x8000) > 0: # check if sign bit was set
|
||||
new_sign_bit = 1
|
||||
else
|
||||
new_sign_bit = 0
|
||||
|
||||
if count == 1:
|
||||
OVERFLOW_FLAG = (old_signbit == new_signbit) # check if sign bit changed
|
||||
|
||||
# TODO: less implementation more pseudo code
|
||||
if (destination & 0x01) == 1:
|
||||
CARRY_FLAG = 1
|
||||
else:
|
||||
CARRY_FLAG = 1
|
||||
```
|
||||
|
||||
# JO
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JO target` | `0x24` | `target` : `mem` / `reg` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JO` jumps to the `target` if the overflow flag **IS** set.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if OVERFLOW_FLAG == 1:
|
||||
IP = target
|
||||
```
|
||||
|
||||
# JNO
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JNO target` | `0x25` | `target` : `mem` / `reg` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JNO` jumps to the `target` if the overflow flag **IS NOT** set.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if OVERFLOW_FLAG == 0:
|
||||
IP = target
|
||||
```
|
||||
|
||||
XOR destination, source mem/reg, mem/reg/imm 0x26 0 X X 0 -
|
||||
### XOR
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `XOR destination, source` | `0x26` | `destination` : `reg` / `mem` | `0` | `X` | `X` | `0` | `-` |
|
||||
| | | `source` : `reg` / `mem` / `imm` |
|
||||
|
||||
#### Description
|
||||
XOR performs a bit-by-bit "exclusive or" on its two operands, and
|
||||
returns the result in the destination operand. XOR sets each bit
|
||||
of the result to one if only one of the corresponding bits is set
|
||||
to one.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination = destination ^ source
|
||||
```
|
||||
|
||||
### RCL
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `RCL destination, count` | `0x27` | `destination` : `mem` / `reg` | `X` | `-` | `-` | `X` | `-` |
|
||||
| | | `count` : `mem` / `reg`, `imm` |
|
||||
|
||||
#### Description
|
||||
`RCL` shifts the bits of the `destination` operand to the left by the
|
||||
number of bit positions specified in the count operand. A bit
|
||||
shifted out of the left (high-order) end of the destination enters
|
||||
the carry flag (CF), and the displaced carry flag rotates around
|
||||
to enter the vacated right-most bit position of the destination.
|
||||
Another way of looking at this is to consider the carry flag as
|
||||
the highest order bit of the word being rotated.
|
||||
|
||||
if `count` is bigger than 16 it will be the remainder of a division by 17.
|
||||
|
||||
The shift is repeated the number of times indicated by the `count` operand
|
||||
|
||||
if `count` equals 1 then the overflow flag will be set if the sign bit of `destination` has changed
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
count = count % 17
|
||||
|
||||
# TODO: less implementation more pseudo code
|
||||
if (destination & 0x8000) > 0:
|
||||
old_sign_bit = 1
|
||||
else
|
||||
old_sign_bit = 0
|
||||
|
||||
destination = # ... RCL magic
|
||||
|
||||
# carry flag might be set
|
||||
|
||||
if (destination & 0x8000) > 0:
|
||||
new_sign_bit = 1
|
||||
else:
|
||||
new_sign_bit = 0
|
||||
|
||||
if count == 1:
|
||||
OVERFLOW_FLAG = old_sign_bit == new_sign_bit)
|
||||
```
|
||||
|
||||
### RCR
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `RCR destination, count` | `0x28` | `destination` : `mem` / `reg` | `X` | `-` | `-` | `X` | `-` |
|
||||
| | | `count` : `mem` / `reg`, `imm` |
|
||||
|
||||
#### Description
|
||||
`RCR` shifts the bits of the `destination` operand to the right by the
|
||||
number of bit positions specified in the `count` operand. A bit
|
||||
shifted out of the right (low-order) end of the destination enters
|
||||
the carry flag (CF), and the displaced carry flag rotates around
|
||||
to enter the vacated left-most bit position of the destination.
|
||||
Another way of looking at this is to consider the carry flag as
|
||||
the lowest order bit of the word being rotated.
|
||||
|
||||
if `count` is bigger than 16 it will be the remainder of a division by 17.
|
||||
|
||||
The shift is repeated the number of times indicated by the `count` operand
|
||||
|
||||
if `count` equals 1 then the overflow flag will be set if the sign bit of `destination` has changed
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
count = count % 17
|
||||
|
||||
# TODO: less implementation more pseudo code
|
||||
if (destination & 0x8000) > 0:
|
||||
old_sign_bit = 1
|
||||
else
|
||||
old_sign_bit = 0
|
||||
|
||||
destination = # ... RCL magic
|
||||
|
||||
# carry flag might be set
|
||||
|
||||
if (destination & 0x8000) > 0:
|
||||
new_sign_bit = 1
|
||||
else:
|
||||
new_sign_bit = 0
|
||||
|
||||
if count == 1:
|
||||
OVERFLOW_FLAG = old_sign_bit == new_sign_bit)
|
||||
```
|
||||
|
||||
### NOP
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `NOP` | `0x3F` | | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
### Description
|
||||
`NOP` is an instruction that performs no operation. Often used for timing purposes, as a placeholder or for aligning purposes.
|
||||
|
||||
### Pseudo code
|
||||
```py
|
||||
# do nothing
|
||||
```
|
||||
|
Loading…
x
Reference in New Issue
Block a user