mirror of
				https://github.com/simon987/Much-Assembly-Required.git
				synced 2025-11-04 10:06:54 +00:00 
			
		
		
		
	Added first draft of instructions up to 0x1D
				
			
							parent
							
								
									53571e7e73
								
							
						
					
					
						commit
						804af72104
					
				@ -62,4 +62,535 @@ Operand value:
 | 
			
		||||
| [Immediate value at IP+1] | `11110` |  
 | 
			
		||||
| Register | `00001`-`01000` |
 | 
			
		||||
| [Register]  | `01001`-`10000` |
 | 
			
		||||
| Register + Immediate value at IP+1 | `10001`-`11000` |
 | 
			
		||||
| Register + Immediate value at IP+1 | `10001`-`11000` |
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
***
 | 
			
		||||
> NOTE: Work In Progress
 | 
			
		||||
# Instruction Set
 | 
			
		||||
## Introduction
 | 
			
		||||
This is an effort to specify the specific MAR Assembly Instruction Set and its behaviour. The instruction set is a subset of the 8086 instruction set. A more detailed specification if the 8086 Instruction Set can be found [here](http://www.ousob.com/ng/iapx86/ng2e5.php). Note that the MAR Instruction Set can differ from the 8086 Instruction Set.
 | 
			
		||||
 | 
			
		||||
This manual tries to describe how to use the instructions and show any side effects they might have.
 | 
			
		||||
 | 
			
		||||
Each instruction has a `Mnemonic` or syntax. This is the way the instruction is written in human readable format. This exists of the instruction name and its operands (if any).
 | 
			
		||||
 | 
			
		||||
```s
 | 
			
		||||
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).
 | 
			
		||||
 | 
			
		||||
## Instructions
 | 
			
		||||
### BRK
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `BRK`    | `0x00` |          |  `-`  |  `-` |  `-` |    `-`   |  `1`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`BRK` sets the break flag. This will halt execution until the next game 'tick', where it will be cleared and execution resumes from the start of the `.text` label.
 | 
			
		||||
 | 
			
		||||
### MOV
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `MOV destination, source`    | `0x01` |  `destination` : `reg` / `mem` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
| | | `source` : `reg` / `mem` / `imm` |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`MOV` transfers (copies) a word from the source operand to the destination operand.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
destination = source
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### ADD
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `ADD destination, source`    | `0x02` |  `destination` : `reg` / `mem` |  `X`  |  `X` |  `X` |    `X`   |  `-`  |
 | 
			
		||||
| | | `source` : `reg` / `mem` / `imm` |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`ADD` replaces the destination operand with the sum of the source and destination operands. It sets the carry flag if there is an overflow.
 | 
			
		||||
 | 
			
		||||
### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
destination = destination + source
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### SUB
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `SUB destination, source`    | `0x03` |  `destination` : `reg` / `mem` |  `X`  |  `X` |  `X` |    `X`   |  `-`  |
 | 
			
		||||
| | | `source` : `reg` / `mem` / `imm` |
 | 
			
		||||
 | 
			
		||||
#### 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
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### AND
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `AND destination, source`    | `0x04` |  `destination` : `reg` / `mem` |  `0`  |  `X` |  `X` |    `0`   |  `-`  |
 | 
			
		||||
| | | `source` : `reg` / `mem` / `imm` |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`AND` performs a bit-by-bit logical AND operation on its operands
 | 
			
		||||
    and stores the result in destination. `AND` sets each bit of the
 | 
			
		||||
    result to one if both of the corresponding bits of the operands
 | 
			
		||||
    are one.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
destination = destination & source
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### OR
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `OR destination, source`    | `0x05` |  `destination` : `reg` / `mem` |  `0`  |  `X` |  `X` |    `0`   |  `-`  |
 | 
			
		||||
| | | `source` : `reg` / `mem` / `imm` |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`OR` performs a bit-by-bit logical inclusive OR operation on its
 | 
			
		||||
    operands and returns the result to destination. `OR` sets each bit
 | 
			
		||||
    of the result to one if either or both of the corresponding bits
 | 
			
		||||
    of the operands are one.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
destination = destination | source
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### SHL (Shift Logical Left)
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `SHL destination, count`    | `0x06` |  `destination` : `reg` / `mem` |  `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
 | 
			
		||||
    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.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
destination = destination << count
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### SHR (Shift Logical Right)
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `SHR destination, count`    | `0x07` |  `destination` : `reg` / `mem` |  `X`  |  `-` |  `-` |    `X`   |  `-`  |
 | 
			
		||||
| | | `count` : `reg` / `mem` / `imm` |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
SHR shifts the bits of the destination operand downward (toward
 | 
			
		||||
    the least significant bit) by the number of bit positions
 | 
			
		||||
    specified in the second operand (count). As bits are transferred
 | 
			
		||||
    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
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### HWI (Hardware Interrupt)
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `HWI source`    | `0x09` |  `source` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`HWI` triggers an [Hardware Interrupt](https://github.com/simon987/Much-Assembly-Required/wiki/Hardware). `source` should be the address of the harware device. This is differnt from the RAM memory addresses. See the documentation of the hardware devices to see what an `HWI` does for each device.
 | 
			
		||||
 | 
			
		||||
### JMP
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `JMP target`    | `0x0A` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`JMP` performs an unconditional jump to the target memory address and will resume execution there.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
IP = target
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### TEST
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `TEST destination, source`    | `0x0B` |  `destination` : `reg` / `mem` |  `0`  |  `X` |  `X` |    `0`   |  `-`  |
 | 
			
		||||
| | | `source` : `reg` / `mem` / `imm` |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`TEST` performs a logical AND operation on its two operands and
 | 
			
		||||
    updates the flags. None of the operands are changed.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
destination & source      # flags will be set
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### CMP
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `CMP destination, source`    | `0x0C` |  `destination` : `reg` / `mem` |  `X`  |  `X` |  `X` |    `X`   |  `-`  |
 | 
			
		||||
| | | `source` : `reg` / `mem` / `imm` |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`CMP` compares two numbers by subtracting the source from the
 | 
			
		||||
    destination and updates the flags. None of the operands are
 | 
			
		||||
    changed.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
destination - source   # flags will be set
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### JNZ
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `JNZ target`    | `0x0D` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`JNZ` performs a jump if the zero flag **IS NOT** set.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
if ZERO_FLAG == 0:
 | 
			
		||||
    IP = target
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### JZ
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `JZ target`    | `0x0E` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`JZ` performs a jump if the the zero flag **IS** set.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
if ZERO_FLAG == 1:
 | 
			
		||||
    IP = target
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### JG
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `JG target`    | `0x0F` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`JG` performs a jump if the sign flag **IS EQUAL** to the overflow flag **AND** the zero flag **IS NOT** set.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
if SIGN_FLAG == OVERFLOW_FLAG and ZERO_FLAG == 0:
 | 
			
		||||
    IP = target
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### JGE
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `JGE target`    | `0x10` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`JGE` performs a jump if the sign flag **IS EQUAL** to the overflow flag
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
if SIGN_FLAG == OVERFLOW_FLAG:
 | 
			
		||||
    IP = target
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### JL
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `JL target`    | `0x11` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`JL` performs a jump if the sign flag **IS NOT EQUAL** to the overflow flag
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
if SIGN_FLAG != OVERFLOW_FLAG:
 | 
			
		||||
    IP = target
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### JLE
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `JLE target`    | `0x12` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`JLE` performs a jump if the sign flag **IS NOT EQUAL** to the overflow flag **OR** the zero flag **IS** set
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
if SIGN_FLAG != OVERFLOW_FLAG or ZERO_FLAG == 1:
 | 
			
		||||
    IP = target
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### PUSH
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `PUSH source`    | `0x13` |  `source` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`PUSH` decrements the stack pointer by one and then copies `source` to the address the stack pointer is pointing to.
 | 
			
		||||
> The stack grows downwards from 0xFFFF -> 0x0000
 | 
			
		||||
> So decrementing will 'grow' the stack
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
SP = SP - 1
 | 
			
		||||
memory[SP] = source
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### POP
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `POP destintation`    | `0x14` |  `destination` : `reg` / `mem` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`POP` copies the value of the memory address specified in the stack pointer to the `destination` and increments the stack pointer.
 | 
			
		||||
> The stack grows downwards from 0xFFFF -> 0x0000
 | 
			
		||||
> So incrementing will 'shrink' the stack
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
destination = memory[SP]
 | 
			
		||||
SP = SP + 1
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### CALL
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `CALL target`    | `0x15` |  `target` : `reg` / `mem` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`CALL` pushes the current instruction pointer on to the stack and then performs a jump to the `target` address
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
SP = SP - 1
 | 
			
		||||
memory[SP] = IP
 | 
			
		||||
IP = target
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### RET
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `RET [amount]`    | `0x16` |  `amount` : `imm` / `None` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`RET` jumps to the address stored at the stack pointer and then increments (pops) that address of the stack.
 | 
			
		||||
When `amount` is given increment the stack pointer the number of times given in amount.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
IP = memory[SP]
 | 
			
		||||
if amount == None:
 | 
			
		||||
    amount = 0
 | 
			
		||||
SP = SP + 1 + amount
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### MUL
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `MUL source`    | `0x17` |  `source` : `mem` / `reg` / `imm` |  `X`  |  `-` |  `-` |    `X`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`MUL` performs unsigned multiplication with `A` and `source` and stores the result into `Y:A`.
 | 
			
		||||
 | 
			
		||||
The result of the multiplication is stored into `Y:A` where the higher order bits are stored in `Y` and the lower order bits are stored in `A`
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
 | 
			
		||||
# result is a 32-bit integer
 | 
			
		||||
result = A * source
 | 
			
		||||
# get the 16 most significant bits of result
 | 
			
		||||
higher_order_word = (result & 0xff00)
 | 
			
		||||
 | 
			
		||||
if higher_order_word != 0:
 | 
			
		||||
    OVERFLOW_FLAG = 1
 | 
			
		||||
    CARRY_FLAG = 1
 | 
			
		||||
    Y = higher_order_word
 | 
			
		||||
else:
 | 
			
		||||
    OVERFLOW_FLAG = 0
 | 
			
		||||
    CARRY_FLAG = 0
 | 
			
		||||
A = (result & 0x00ff)
 | 
			
		||||
 | 
			
		||||
# result is stored in Y:A
 | 
			
		||||
# you can check if you need Y by check the flags
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### DIV
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `DIV source`    | `0x18` |  `source` : `mem` / `reg` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `X`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`DIV` performs unsigned division on `A` with `source` as divisor and stores the result into `A` and the remainder in `Y`.
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
 | 
			
		||||
if source == 0:
 | 
			
		||||
    ERROR_FLAG = 1
 | 
			
		||||
    BREAK_FLAG = 1
 | 
			
		||||
 | 
			
		||||
# temp is a 32-bit integer
 | 
			
		||||
temp = (Y << 16) | A
 | 
			
		||||
 | 
			
		||||
A = temp / source # result is floored
 | 
			
		||||
Y = temp % source
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### NEG
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `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.
 | 
			
		||||
 | 
			
		||||
If the operand is zero, the carry flag is cleared; in all other cases, the carry flag is set.
 | 
			
		||||
 | 
			
		||||
Attempting to negate a word containing -32,768 causes no change to the operand and sets the Overflow Flag.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
if destination == 0:
 | 
			
		||||
    CARRY_FLAG = 0
 | 
			
		||||
    ZERO_FLAG = 1
 | 
			
		||||
else:
 | 
			
		||||
    CARRY_FLAG = 1
 | 
			
		||||
 | 
			
		||||
if destination == -32768:
 | 
			
		||||
    OVERFLOW_FLAG = 1
 | 
			
		||||
else
 | 
			
		||||
    destination = 0 - destination # or destination = destination + (-dest)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### JS
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `JS target`    | `0x1A` |  `target` : `mem` / `reg` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`JS` jumps to the target if the sign flag **IS** set.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
if SIGN_FLAG == 1:
 | 
			
		||||
    IP = target
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### JNS
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `JNS target`    | `0x1B` |  `target` : `mem` / `reg` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`JNS` jumps to the target if the sign flag **IS NOT** set.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
if SIGN_FLAG == 0:
 | 
			
		||||
    IP = target
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### HWQ
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `HWQ source`    | `0x1C` |  `source` : `mem` / `reg` / `imm` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`HWQ` queries the hardware id of the hardware at the hardware address specified by `source`
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
if hardware_memory[source] != None:
 | 
			
		||||
    B = get_hardware_id(hardware_memory[source]) # not sure how to (pseudo) code this
 | 
			
		||||
else:
 | 
			
		||||
    B = 0
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### NOT
 | 
			
		||||
#### Details
 | 
			
		||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
 | 
			
		||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
 | 
			
		||||
| `NOT destintation`    | `0x1D` |  `source` : `mem` / `reg` |  `-`  |  `-` |  `-` |    `-`   |  `-`  |
 | 
			
		||||
 | 
			
		||||
#### Description
 | 
			
		||||
`NOT` inverts each bit in its operand, i.e. forms the one's complement.
 | 
			
		||||
 | 
			
		||||
#### Pseudo code
 | 
			
		||||
```py
 | 
			
		||||
dest = ~dest
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Encoding
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user