sd:isa
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| sd:isa [2026/05/06 12:28] – appledog | sd:isa [2026/06/10 04:36] (current) – appledog | ||
|---|---|---|---|
| Line 9: | Line 9: | ||
| === Core instruction set | === Core instruction set | ||
| - | 27 RISC-style instructions. A small core. | + | 36 RISC-style instructions. A small core. |
| - | | 00 | LD_IMM | + | | 00 | LD_IMM |
| - | | 02 | LD_REG | + | | 01 | LD_MEM |
| - | | 06 | ST_REG | + | | 02 | LD_REG |
| - | | 09 | MOV | MOV Y, A | Copy A up on Y | | | + | | 05 | ST_MEM |
| - | | 0B | PUSH | PUSH A | Push A onto stack -- ye scurvy dog! | | | + | | 06 | ST_REG |
| - | | 0C | POP | POP Y | + | | 09 | MOV | MOV Y, A | Copy A up on Y | | |
| - | | 0F | PUSHF | PUSHF | + | | 0B | PUSH | PUSH A | Push A onto stack -- ye scurvy dog! | | |
| - | | 10 | POPF | POPF | Pop " | + | | 0C | POP | POP Y |
| - | | 15 | INC | INC X | + | | 0F | PUSHF | PUSHF |
| - | | 16 | DEC | DEC Y | + | | 10 | POPF | POPF | Pop flags back | | |
| - | | 1E | ADD | ADD X, Y | Add X = X + Y | | | + | | 15 | INC | INC X |
| - | | 1F | SUB | SUB X, Y | Subtract X = X - Y | | | + | | 16 | DEC | DEC Y |
| - | | 32 | AND | AND dst, src | Bitwise AND (compare two integers bit by bit) | | | + | | 1E | ADD | ADD X, Y | Add X = X + Y | | |
| - | | 33 | OR | OR dst, src | + | | 1F | SUB | SUB X, Y | Subtract X = X - Y | | |
| - | | 34 | XOR | + | | 32 | AND | AND dst, src | Bitwise AND (compare two integers bit by bit) | | |
| - | | 35 | NOT | NOT reg | + | | 33 | OR | OR dst, src |
| - | | 46 | SHL | SHL A | + | | 34 | XOR |
| - | | 47 | SHR | SHR A | + | | 35 | NOT | NOT reg |
| + | | 46 | SHL | SHL A | ||
| + | | 47 | SHR | SHR A | ||
| | 5A | CMP | CMP A, B | Compare (subtract, discard result) | Z, N, C, V | | | 5A | CMP | CMP A, B | Compare (subtract, discard result) | Z, N, C, V | | ||
| | 5B | CMP_IMM | CMP A, 0x0001 | Compare (subtract, discard result) | Z, N, C, V | | | 5B | CMP_IMM | CMP A, 0x0001 | Compare (subtract, discard result) | Z, N, C, V | | ||
| - | | 64 | JMP | | Unconditional jump | None | | + | | 64 | JMP |
| - | | 65 | JZ | | Jump if zero | None | | + | | 65 | JZ | JZ @label |
| - | | 84 | CALL | | Call subroutine (push IP, jump) | | | + | | 66 | JNZ | JNZ @label |
| - | | 85 | RET | | Return from subroutine (pop IP) | | | + | | 67 | JC | JC @label |
| + | | 68 | JNC | JNC @label | ||
| + | | 84 | [[#call|CALL]] | ||
| + | | 85 | RET | ||
| + | | 86 | INT | INT 0x10 | Software interrupt | | | ||
| + | | 87 | RTI | RTI | Return from Interrupt | ||
| | B6 | SETF | SETF 0x80 | Set bits in flags | * | | | B6 | SETF | SETF 0x80 | Set bits in flags | * | | ||
| | B7 | CLRF | CLRF 0x80 | Clear bits in flags | * | | | B7 | CLRF | CLRF 0x80 | Clear bits in flags | * | | ||
| | B8 | TESTF | TESTF 0x80 | Non-destructive AND | Z C | | | B8 | TESTF | TESTF 0x80 | Non-destructive AND | Z C | | ||
| + | | FE | NOP | No operation | | | ||
| + | | FF | HALT | Halt CPU (sets HALT flag) | H | | ||
| === Core-2 instructions | === Core-2 instructions | ||
| - | 10 instructions. Some instructions are not strictly RISC but still considered core. For example, LD_MEM occurs too many times for it to be considered an extended opcode. MUL is another one included here; MUL is technically an extended opcode (can loop over ADD) but it is a fundamental operation, so it is included here. | + | 29 instructions. Some instructions |
| - | | 01 | LD_MEM | + | | 0A | XCHG |
| - | | 05 | ST_MEM | + | | 20 | MUL |
| - | | 20 | MUL | MUL X, Y | Multiply X = X * Y | | | + | | 21 | DIV |
| - | | 21 | DIV | DIV X, Y | Divide X = X / Y | | | + | | 22 | MOD |
| - | | 22 | MOD | MOD X, Y | Modulo X = X % Y | | | + | | 23 | ADD_REG_IMM |
| - | | 66 | JNZ | JNZ @label | + | | 24 | SUB_REG_IMM |
| - | | 67 | JC | JC @label | + | | 25 | MUL_REG_IMM |
| - | | 68 | JNC | + | | 26 | DIV_REG_IMM |
| - | | 86 | INT | + | | 27 | MOD_REG_IMM |
| - | | 87 | RTI | + | | 28 | ADDC | ADDC X, Y | Add with carry; X = X + Y + carry flag | | |
| + | | 29 | SUBC | ||
| + | | 30 | ADDC_REG_IMM | ||
| + | | 31 | SUBC_REG_IMM | ||
| + | | 37 | AND_IMM | ||
| + | | 38 | OR_IMM | ||
| + | |||
| + | export const JN:u8 = 103; // JN addr | ||
| + | export const JNN:u8 = 104; // JNN addr | ||
| + | export const JO:u8 = 107; // JO addr | ||
| + | export const JNO:u8 = 108; // JNO addr | ||
| + | |||
| + | | 4A | ROL | ROL A | Rotate left | Z, N, C | | ||
| + | | 4B | ROR | ROR A | Rotate right | Z, N, C | | ||
| + | | A0 | [[# | ||
| + | | A1 | [[# | ||
| + | | A2 | [[# | ||
| + | | A3 | [[# | ||
| + | | AB | CLZ | | Clear zero flag | Z | | ||
| + | | AC | CLN | | Clear negative flag | N | | ||
| + | | AD | CLC | | Clear carry flag | C | | ||
| + | | AE | CLV | | Clear overflow flag | V | | ||
| === Extended instruction set | === Extended instruction set | ||
| - | 53 instructions. Some of these are more extended than others. For example, | + | 50 instructions. Some of these are more extended than others. For example, |
| | 03 | LD_REG24 | | 03 | LD_REG24 | ||
| Line 60: | Line 90: | ||
| | 07 | ST_REG24 | | 07 | ST_REG24 | ||
| | 08 | ST_IMM24 | | 08 | ST_IMM24 | ||
| - | | 0A | XCHG | XCHG X, Y | Swap dem two -- X an Y trade place, quick quick | | | ||
| | 0D | PUSHA | PUSHA | Save all registers in ye treasure chest | | | | 0D | PUSHA | PUSHA | Save all registers in ye treasure chest | | | ||
| | 0E | POPA | POPA | Get the registers back | | | | 0E | POPA | POPA | Get the registers back | | | ||
| + | |||
| + | PUSH2 = 17 // push 2 | ||
| + | POP2 = 18 // pop 2 | ||
| + | PUSH3 = 19 // push 3 | ||
| + | POP3 = 20 // pop 3 | ||
| + | PUSH4 = 21 // push 4 | ||
| + | POP4 = 22 // pop 4 | ||
| ST_PD 25 // pre-dec store. | ST_PD 25 // pre-dec store. | ||
| Line 68: | Line 104: | ||
| ST_FS 27 // store+forward step. STA [BLX, +] | ST_FS 27 // store+forward step. STA [BLX, +] | ||
| - | | 23 | ADD_REG_IMM | ||
| - | | 24 | SUB_REG_IMM | ||
| - | | 25 | MUL_REG_IMM | ||
| - | | 26 | DIV_REG_IMM | ||
| - | | 27 | MOD_REG_IMM | ||
| - | | 28 | ADDC | ADDC X, Y | Add with carry; X = X + Y + carry flag | | | ||
| - | | 29 | SUBC | SUBC X, Y | Subtract with borrow; X = X - Y - borrow | | | ||
| - | | 30 | ADDC_REG_IMM | ||
| - | | 31 | SUBC_REG_IMM | ||
| | 36 | TEST | TEST dst, src | Non-destructive AND | | | | 36 | TEST | TEST dst, src | Non-destructive AND | | | ||
| - | | 37 | AND_IMM | ||
| - | | 38 | OR_IMM | ||
| | 48 | SHLC | SHLC A | Shift left | Z, N, C | | | 48 | SHLC | SHLC A | Shift left | Z, N, C | | ||
| | 49 | SHRC | SHRC A | Shift right | Z, N, C | | | 49 | SHRC | SHRC A | Shift right | Z, N, C | | ||
| - | | 4A | ROL | ROL A | Rotate left | Z, N, C | | ||
| - | | 4B | ROR | ROR A | Rotate right | Z, N, C | | ||
| | 4C | ROLC | ROLC A | Rotate left | Z, N, C | | | 4C | ROLC | ROLC A | Rotate left | Z, N, C | | ||
| | 4D | RORC | RORC A | Rotate right | Z, N, C | | | 4D | RORC | RORC A | Rotate right | Z, N, C | | ||
| - | | A0 | [[# | + | JMPR = 109 // JMPR reg |
| - | | A1 | [[# | + | JZR = 110 // JZR reg |
| - | | A2 | [[# | + | JNZR = 111 // JNZR reg |
| - | | A3 | [[# | + | JNR = 112 // JNR reg |
| + | JNNR = 113 // JNNR reg | ||
| + | JCR = 114 // JCR reg | ||
| + | JNCR = 115 // JNCR reg | ||
| + | JOR = 116 // JOR reg | ||
| + | JNOR = 117 // JNOR reg | ||
| + | |||
| | A4 | [[# | | A4 | [[# | ||
| | A5 | [[# | | A5 | [[# | ||
| Line 98: | Line 128: | ||
| | A9 | [[# | | A9 | [[# | ||
| | AA | [[# | | AA | [[# | ||
| - | | AB | CLZ | | Clear zero flag | Z | | ||
| - | | AC | CLN | | Clear negative flag | N | | ||
| - | | AD | CLC | | Clear carry flag | C | | ||
| - | | AE | CLV | | Clear overflow flag | V | | ||
| | AF | CLE | CLE | Clear E | E | | | AF | CLE | CLE | Clear E | E | | ||
| | B0 | CLF | CLF | Clear F Flag (user flag) | F | | | B0 | CLF | CLF | Clear F Flag (user flag) | F | | ||
| Line 115: | Line 141: | ||
| ST_IDXR 213 // ST [ptr + reg], reg | ST_IDXR 213 // ST [ptr + reg], reg | ||
| | | ||
| - | | FB | BASIC | Reserved | + | |
| - | | FC | YIELD | Yield thread priority | Y | | + | | FB | CNOP |
| - | | FD | BREAK | Reserved | | | + | | FC | YIELD | YIELD | Yield thread priority | Y | |
| - | | FE | NOP | No operation | | | + | | FD | BREAK | BREAK |Reserved | | |
| - | | FF | HALT | Halt CPU (sets HALT flag) | H | | + | |
| === CISC instruction set | === CISC instruction set | ||
| - | 7 instructions. CISC style, usually inspired by VAX, 680x0, or other CISC-leaning processors. | + | 24 instructions. CISC style, usually inspired by VAX, 680x0, or other CISC-leaning processors. |
| | 8C | [[# | | 8C | [[# | ||
| Line 129: | Line 155: | ||
| | 8F | [[# | | 8F | [[# | ||
| | 90 | [[# | | 90 | [[# | ||
| + | |||
| + | | 91 | INSQUE | INSQUE | INSQUE REG, REG | | | ||
| + | | 92 | INSQUE_PTR | INSQUE | INSQUE REG, [REG] | | | ||
| + | | 93 | REMQUE | REMQUE | | | | ||
| + | | 94 | [[# | ||
| + | | 95 | SCANQUE_IMM | SCANQUE | | | | ||
| + | |||
| + | |||
| | 98 | [[# | | 98 | [[# | ||
| | 99 | [[# | | 99 | [[# | ||
| Line 137: | Line 171: | ||
| | CB | [[# | | CB | [[# | ||
| | CC | [[# | | CC | [[# | ||
| + | |||
| + | The PPU extended commands are included at the CISC level: | ||
| + | |||
| + | | #220 | [[# | ||
| + | | #221 | [[# | ||
| + | | #222 | [[# | ||
| + | | #223 | [[# | ||
| + | | #224 | [[# | ||
| + | | #225 | [[# | ||
| + | | #226 | [[# | ||
| + | | #227 | [[# | ||
| + | | #229 | [[# | ||
| + | |||
| + | As are the forth acceleration opcodes: | ||
| + | |||
| + | | F0 | [[# | ||
| + | | F1 | TTOS | TTOS | Test TOS. CD=AB, AB=[ELY], ELY+=4, ZF=(CD==0) | Z | | ||
| + | | F2 | LIT | LIT | push AB to stack, load next 4 bytes into AB. | | | ||
| + | | F3 | [[# | ||
| == Dictionary | == Dictionary | ||
| here you will find information about each opcode. | here you will find information about each opcode. | ||
| + | |||
| + | <wrap #call />< | ||
| + | **'' | ||
| + | |||
| + | The CALLR instruction takes a register operand and dispatches based on the register' | ||
| <wrap #sez />< | <wrap #sez />< | ||
| Line 173: | Line 231: | ||
| <wrap #cmpc3 /> | <wrap #cmpc3 /> | ||
| **''# | **''# | ||
| + | |||
| + | Note: CMPC3 allows early termination on byte_a == 0: This is the " | ||
| <wrap #skpc /> | <wrap #skpc /> | ||
| **''# | **''# | ||
| + | |||
| + | <wrap #remque /> | ||
| + | The classic VAX semantic for REMQUE used the V flag for "queue was already empty before the call." SD-8516' | ||
| + | |||
| + | * VAX V=1 "you tried to remove from an empty queue" (error condition) | ||
| + | * SD-8516 Z=1 "you successfully removed the last item; the queue is now empty" (state condition) | ||
| + | |||
| + | <wrap #scanque />#148 $98 SCANQUE H, N, O\\ Both SCANQUE forms take three operands; head, needle and offset. SCANQUE_IMM treats offset as an IMM (byte). SCANQUE takes the offset in any register (allowing for larger offsets than +255). | ||
| + | |||
| + | SCANQUE. One-upping the VAX. SCANQUE combines queue traversal with a structured-field match in one fetch-execute cycle, which is the inner loop of every lookup operation in a hash chain, free list, or PCB table. | ||
| + | |||
| + | The split between SCANQUE (register offset) and SCANQUE_IMM (immediate offset) is the pragmatic call: most of the time you know the offset (you are writing CRUD for a struct). However, having the register form means you can write generic kernel-level queue helpers that take "field offset" | ||
| <wrap #pab /> | <wrap #pab /> | ||
| Line 202: | Line 274: | ||
| <wrap #case /> | <wrap #case /> | ||
| **''# | **''# | ||
| + | |||
| + | CASE is unusual because it reads from the instruction stream as data. The inline jump table isn't fetched and decoded, it's just structured bytes. This is the same pattern as LD_IMM (where the operand is fetched), but pushed further: an opcode-controlled variable-size payload. The bookkeeping all comes down to two derived addresses: | ||
| + | |||
| + | * IP + 3 * sel: the table slot containing the jump target. Read with read_24bit. | ||
| + | * IP + 3 * lim + 3: the first byte after the table. Used as the return point (and as the IP destination on OOB). | ||
| + | |||
| + | Both are masked to 24 bits because IP arithmetic in a 24-bit address space wraps. | ||
| + | |||
| + | OOB sets two flags and falls through (doesn' | ||
| + | |||
| + | Flags otherwise untouched. CASE only writes V and ER. Z, N, C, etc. survive across the instruction, | ||
| + | |||
| + | Note: A single entry CASE can be used as a CALLZ. CALL if register is zero, otherwise not. | ||
| <wrap #case3 /> | <wrap #case3 /> | ||
| Line 215: | Line 300: | ||
| **''# | **''# | ||
| + | <wrap #ppixel /> | ||
| + | Draw a pixel at X, Y color in C. | ||
| + | |||
| + | <wrap #lstepm /> | ||
| + | **'' | ||
| + | |||
| + | LDC #0 | ||
| + | LDD #1000 | ||
| + | loop: | ||
| + | <do something> | ||
| + | INC C | ||
| + | CMP C, D | ||
| + | JNZ @loop | ||
| + | |||
| + | This is a tight loop that runs 1,000 times. Many people might try to remove the CMP and use of D by doing this: | ||
| + | |||
| + | LDC #1000 | ||
| + | loop: | ||
| + | <do something> | ||
| + | DEC C | ||
| + | JNZ @loop | ||
| + | |||
| + | This is a tight loop, but this is even tighter: | ||
| + | |||
| + | < | ||
| + | LDFLX $F000 ; loop start | ||
| + | LDA #1 | ||
| + | STA [FLX] | ||
| + | LDA #1000 | ||
| + | STA [FLX+4] | ||
| + | loop: | ||
| + | <do something> | ||
| + | LSTEPM | ||
| + | JNZ @loop | ||
| + | </ | ||
| + | |||
| + | The benefit of this is you can count from X to Y. It is not a DEC loop. And, it's done at [FLX] and [FLX+4]. This is mainly a kludge for Forth and has been generalized in LSTEP. If I can get Forth to use LSTEP I will remove LSTEPM. | ||
| + | |||
| + | <wrap #lstep /> | ||
| + | **'' | ||
| + | |||
| + | |||
| + | < | ||
| + | LDC #1000 ; loop range | ||
| + | |||
| + | loop: | ||
| + | <do something> | ||
| + | LSTEP C, @loop | ||
| + | </ | ||
| + | |||
| + | This is a decrement-and-JNZ in one opcode. It is heavily inspired by the VAX instruction SOB (subtract one and branch) and the 68000' | ||
sd/isa.1778070487.txt.gz · Last modified: by appledog
