notes:comporg:spring2024:virconref
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
notes:comporg:spring2024:virconref [2024/02/19 15:34] – [TIME] wedge | notes:comporg:spring2024:virconref [2024/04/24 19:17] (current) – [SPU] gsalce | ||
---|---|---|---|
Line 1: | Line 1: | ||
======Vircon32 ASM Reference Guide====== | ======Vircon32 ASM Reference Guide====== | ||
- | |||
This document is based on Vircon32 DevTools **v24.02.04**; | This document is based on Vircon32 DevTools **v24.02.04**; | ||
Line 42: | Line 41: | ||
Use commas to separate values (create " | Use commas to separate values (create " | ||
+ | |||
+ | =====Vircon32 Instruction Set===== | ||
+ | |||
+ | ^ control | ||
+ | | [[# | ||
+ | | [[# | ||
+ | | | [[# | ||
+ | | | [[# | ||
+ | | | [[# | ||
+ | | | | [[# | ||
+ | | | | [[# | ||
+ | | | | [[# | ||
+ | | | | [[# | ||
+ | | | | [[# | ||
+ | | | | [[# | ||
+ | | | | [[# | ||
=====Vircon32 Memory Map===== | =====Vircon32 Memory Map===== | ||
Line 90: | Line 105: | ||
| OUT | 0x206 | GPU_DrawingPointX | | OUT | 0x206 | GPU_DrawingPointX | ||
| OUT | 0x207 | GPU_DrawingPointY | | OUT | 0x207 | GPU_DrawingPointY | ||
- | | ??? | 0x208 | GPU_DrawingScaleX | + | | ??? | 0x208 | GPU_DrawingScaleX |
- | | ??? | 0x209 | GPU_DrawingScaleY | + | | ??? | 0x209 | GPU_DrawingScaleY |
| ??? | 0x20A | GPU_DrawingAngle | | ??? | 0x20A | GPU_DrawingAngle | ||
| OUT | 0x20B | GPU_RegionMinX | | OUT | 0x20B | GPU_RegionMinX | ||
Line 122: | Line 137: | ||
| ??? | 0x300 | SPU_Command | | ??? | 0x300 | SPU_Command | ||
| ??? | 0x301 | SPU_GlobalVolume | | ??? | 0x301 | SPU_GlobalVolume | ||
- | | | + | | |
- | | | + | | |
| ??? | 0x304 | SPU_SoundLength | | ??? | 0x304 | SPU_SoundLength | ||
| ??? | 0x305 | SPU_SoundPlayWithLoop | | ??? | 0x305 | SPU_SoundPlayWithLoop | ||
Line 159: | Line 174: | ||
| OUT | 0x400 | INP_SelectedGamepad | | OUT | 0x400 | INP_SelectedGamepad | ||
| ??? | 0x401 | INP_GamepadConnected | | ??? | 0x401 | INP_GamepadConnected | ||
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
| | ||
====CARTRIDGE==== | ====CARTRIDGE==== | ||
Line 187: | Line 202: | ||
^ opcode | ^ opcode | ||
- | | 0x00 | HLT | control | + | | 0x00 | |
- | | 0x01 | WAIT | control | + | | 0x01 | |
- | | 0x02 | JMP | branch | + | | 0x02 | |
- | | 0x03 | CALL | branch | + | | 0x03 | |
- | | 0x04 | RET | branch | + | | 0x04 | |
- | | 0x05 | JT | branch | + | | 0x05 | |
- | | 0x06 | JF | branch | + | | 0x06 | |
- | | 0x07 | IEQ | | + | | 0x07 | |
+ | | 0x08 | [[# | ||
+ | | 0x09 | [[# | ||
+ | | 0x0A | [[# | ||
+ | | 0x0B | [[# | ||
+ | | 0x0C | [[# | ||
+ | |||
+ | ====HLT==== | ||
+ | |||
+ | ====WAIT==== | ||
+ | |||
+ | ====JMP==== | ||
+ | Unconditional jump. Forcibly redirect program flow to indicated address. The address is somewhere else in the program logic, likely identified by some set label. | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | |||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Processing actions=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Description=== | ||
+ | JMP performs an unconditional jump to the address specified by its operand. After processing this instruction the CPU will continue execution at the new address. | ||
+ | |||
+ | ===Examples=== | ||
+ | Jumping to a label (memory address/ | ||
< | < | ||
- | | + | jmp _label |
- | INE, // Integer | + | ... |
- | IGT, // Integer Greater Than | + | _label: |
- | IGE, // Integer | + | </ |
- | ILT, // Integer Less Than | + | |
- | ILE, // Integer Less or Equal | + | Jumping to address stored in register: |
+ | |||
+ | < | ||
+ | jmp R0 | ||
+ | </ | ||
+ | |||
+ | ====CALL==== | ||
+ | |||
+ | ====RET==== | ||
+ | |||
+ | ====JT==== | ||
+ | Jump if True: a conditional jump typically used following a comparison instruction, | ||
+ | |||
+ | ===NOTE=== | ||
+ | For the purposes of comparisons and conditional jumps on Vircon32: | ||
+ | |||
+ | * true is 1 (technically non-zero) | ||
+ | * false is 0 | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Effect=== | ||
+ | |||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Description=== | ||
+ | JT performs a jump only if its first operand is true, i.e. non zero when taken as an integer. In that case its behavior is the same as an unconditional jump. Otherwise it has no effect. | ||
+ | |||
+ | ====JF==== | ||
+ | Jump if False: a conditional jump typically used following a comparison instruction, | ||
+ | |||
+ | ===NOTE=== | ||
+ | For the purposes of comparisons and conditional jumps on Vircon32: | ||
+ | |||
+ | * true is 1 (technically non-zero) | ||
+ | * false is 0 | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Effect=== | ||
+ | |||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Description=== | ||
+ | JF performs a jump only if its first operand is false, i.e. zero when taken as an integer. In that case its behavior is the same as an unconditional jump. Otherwise it has no effect. | ||
+ | |||
+ | ====IEQ==== | ||
+ | Integer Compare Equality: comparisons allow us typically to evaluate two values, in accordance with some relational operation, resulting in a true (1) or false (0) result. | ||
+ | |||
+ | Should the first operand contain the same information as the second operand, the result will be true. Otherwise, false. | ||
+ | |||
+ | ===NOTE=== | ||
+ | For the purposes of comparisons and conditional jumps on Vircon32: | ||
+ | |||
+ | * true is 1 (technically non-zero) | ||
+ | * false is 0 | ||
+ | |||
+ | There are six relational operations: | ||
+ | |||
+ | * is equal to | ||
+ | * is not equal to | ||
+ | * is less than | ||
+ | * is than or equal to | ||
+ | * is greater than | ||
+ | * is greater than or equal to | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Processing actions=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Description=== | ||
+ | IEQ takes two operands interpreted as integers, and checks if they are equal. It will store the boolean result in the first operand, which is always a register. | ||
+ | |||
+ | ====INE==== | ||
+ | Integer | ||
+ | |||
+ | Here, we test to see if the first operand is not equal to the second operand. If they are equal, the result is false, otherwise, not being equal yields a result of true. | ||
+ | |||
+ | ===NOTE=== | ||
+ | For the purposes of comparisons and conditional jumps on Vircon32: | ||
+ | |||
+ | * true is 1 (technically non-zero) | ||
+ | * false is 0 | ||
+ | |||
+ | There are six relational operations: | ||
+ | |||
+ | * is equal to | ||
+ | * is not equal to | ||
+ | * is less than | ||
+ | * is than or equal to | ||
+ | * is greater than | ||
+ | * is greater than or equal to | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Processing actions=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Description=== | ||
+ | INE takes two operands interpreted as integers, and checks if they are different. It will store the boolean result in the first operand, which is always a register. | ||
+ | |||
+ | ====IGT==== | ||
+ | Integer | ||
+ | |||
+ | In this case, we are testing if the first operand is greater than the second operand. | ||
+ | |||
+ | ===NOTE=== | ||
+ | For the purposes of comparisons and conditional jumps on Vircon32: | ||
+ | |||
+ | * true is 1 (technically non-zero) | ||
+ | * false is 0 | ||
+ | |||
+ | There are six relational operations: | ||
+ | |||
+ | * is equal to | ||
+ | * is not equal to | ||
+ | * is less than | ||
+ | * is than or equal to | ||
+ | * is greater than | ||
+ | * is greater than or equal to | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Processing actions=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Description=== | ||
+ | IGT takes two operands interpreted as integers, and checks if the first one is greater than the second. It will store the boolean result in the first operand, which is always a register. | ||
+ | |||
+ | |||
+ | ====IGE==== | ||
+ | Integer Greater Than Or Equal: comparisons allow us typically to evaluate two values, in accordance with some relational operation, resulting in a true (1) or false (0) result. | ||
+ | |||
+ | In this case, we are testing if the first operand is greater than or equal to the second operand. | ||
+ | |||
+ | ===NOTE=== | ||
+ | For the purposes of comparisons and conditional jumps on Vircon32: | ||
+ | |||
+ | * true is 1 (technically non-zero) | ||
+ | * false is 0 | ||
+ | |||
+ | There are six relational operations: | ||
+ | |||
+ | * is equal to | ||
+ | * is not equal to | ||
+ | * is less than | ||
+ | * is than or equal to | ||
+ | * is greater than | ||
+ | * is greater than or equal to | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Processing actions=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Description=== | ||
+ | IGE takes two operands interpreted as integers, and checks if the first one is greater or equal to the second. It will store the boolean result in the first operand, which is always a register. | ||
+ | |||
+ | ====ILT==== | ||
+ | Integer | ||
+ | |||
+ | In this case, we are testing if the first operand is less than the second operand. | ||
+ | |||
+ | ===NOTE=== | ||
+ | For the purposes of comparisons and conditional jumps on Vircon32: | ||
+ | |||
+ | * true is 1 (technically non-zero) | ||
+ | * false is 0 | ||
+ | |||
+ | There are six relational operations: | ||
+ | |||
+ | * is equal to | ||
+ | * is not equal to | ||
+ | * is less than | ||
+ | * is than or equal to | ||
+ | * is greater than | ||
+ | * is greater than or equal to | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Processing actions=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Description=== | ||
+ | ILT takes two operands interpreted as integers, and checks if the first one is less than the second. It will store the boolean result in the first operand, which is always a register. | ||
+ | |||
+ | ====ILE==== | ||
+ | Integer Less Than Or Equal: comparisons allow us typically to evaluate two values, in accordance with some relational operation, resulting in a true (1) or false (0) result. | ||
+ | |||
+ | In this case, we are testing if the first operand is less than or equal to the second operand. | ||
+ | |||
+ | ===NOTE=== | ||
+ | For the purposes of comparisons and conditional jumps on Vircon32: | ||
+ | |||
+ | * true is 1 (technically non-zero) | ||
+ | * false is 0 | ||
+ | |||
+ | There are six relational operations: | ||
+ | |||
+ | * is equal to | ||
+ | * is not equal to | ||
+ | * is less than | ||
+ | * is than or equal to | ||
+ | * is greater than | ||
+ | * is greater than or equal to | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Processing actions=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: if Register1 <= Register2 then Register1 = 1 else Register1 = 0</ | ||
+ | |||
+ | ===Description=== | ||
+ | ILE takes two operands interpreted as integers, and checks if the first one is less or equal to the second. It will store the boolean result in the first operand, which is always a register. | ||
+ | |||
+ | ====FEQ==== | ||
+ | ====FNE==== | ||
+ | ====FGT==== | ||
+ | ====FGE==== | ||
+ | ====FLT==== | ||
+ | ====FLE==== | ||
| | ||
- | | + | ====MOV==== |
- | FEQ, // Float Equal | + | MOVE: your general purpose data-copying instruction. |
- | FNE, // Float Not Equal | + | |
- | FGT, // Float Greater Than | + | ===Addressing=== |
- | FGE, // Float Greater or Equal | + | MOVE, like other data-centric instructions, |
- | FLT, // Float Less Than | + | |
- | FLE, // Float Less or Equal | + | * **register**: |
- | + | * **immediate**: | |
- | // data movement | + | * **indirect**: |
- | MOV, // Move data | + | * **indexed**: |
- | | + | * **immediate**: |
- | PUSH, | + | * **indexed**: |
- | POP, | + | * **register**: |
+ | |||
+ | Indirect processing is accomplished with the **< | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | * Variant 3: < | ||
+ | * Variant 4: < | ||
+ | * Variant 5: < | ||
+ | * Variant 6: < | ||
+ | * Variant 7: < | ||
+ | * Variant 8: < | ||
+ | |||
+ | ===Processing actions=== | ||
+ | |||
+ | ==Register Destination== | ||
+ | * Immediate: < | ||
+ | * Register: < | ||
+ | * Indirect with Immediate reference: < | ||
+ | * Indirect with Register reference: < | ||
+ | * Indirect Indexed with Register: < | ||
+ | |||
+ | ==Memory Destination== | ||
+ | * Indirect with Immediate reference: < | ||
+ | * Indirect with Register reference: < | ||
+ | * Indirect with Indexed reference: < | ||
+ | |||
+ | ===Description=== | ||
+ | MOV copies the value indicated in its second operand into the register or memory address indicated by its first operand. MOV is the most complex instruction to process because it needs to distinguish between 8 different addressing modes. | ||
+ | |||
+ | The instruction specifies which of the 8 modes to use in its “Addressing mode” field, being the possible values interpreted as follows: | ||
+ | |||
+ | ==MOV Addressing modes== | ||
+ | |||
+ | ^ Binary | ||
+ | | 000 | Register 1 | Immediate Value | | ||
+ | | 001 | Register 1 | Register 2 | | ||
+ | | 010 | Register 1 | Memory < | ||
+ | | 011 | Register 1 | Memory < | ||
+ | | 100 | Register 1 | Memory < | ||
+ | | 101 | < | ||
+ | | 110 | < | ||
+ | | 111 | < | ||
+ | |||
+ | ====LEA==== | ||
+ | Load Effective Address | ||
+ | |||
+ | ===Addressing=== | ||
+ | MOVE, like other data-centric instructions, | ||
+ | |||
+ | * **register**: | ||
+ | * **immediate**: | ||
+ | * **indirect**: | ||
+ | * **indexed**: | ||
+ | * **immediate**: | ||
+ | * **indexed**: | ||
+ | * **register**: | ||
+ | |||
+ | Indirect processing is accomplished with the **< | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | * Variant 1: < | ||
+ | * Variant 2: < | ||
+ | |||
+ | ===Processing actions=== | ||
+ | * Register: < | ||
+ | * Indexed: < | ||
+ | |||
+ | ===Description=== | ||
+ | LEA takes a memory address as second operand. It stores that address (not its contents) into the register given as first operand. The most useful case is when the address is given in the form pointer + offset, since the addition is automatically performed. | ||
+ | |||
+ | ====PUSH==== | ||
+ | Save to top of stack | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | * < | ||
+ | |||
+ | ===Processing actions=== | ||
+ | * < | ||
+ | |||
+ | ===Description=== | ||
+ | PUSH uses the CPU hardware | ||
+ | |||
+ | ====POP==== | ||
+ | Load from top of stack | ||
+ | |||
+ | ===Structure and variants=== | ||
+ | * < | ||
+ | |||
+ | ===Processing actions=== | ||
+ | * < | ||
+ | |||
+ | ===Description=== | ||
+ | POP uses the CPU hardware stack to remove a value from the top of the stack and write it in the given register. When you POP a value off the stack, the STACK POINTER (SP) is adjusted upward by one address offset (stack grows down, shrinks up). | ||
+ | |||
+ | < | ||
IN, // Read from an I/O port | IN, // Read from an I/O port | ||
OUT, // Write to an I/O port | OUT, // Write to an I/O port |
notes/comporg/spring2024/virconref.1708374888.txt.gz · Last modified: 2024/02/19 15:34 by wedge