User Tools

Site Tools


sd:isa

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
sd:isa [2026/05/06 12:32] appledogsd: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.
  
-| 01 | LD_MEM  | LDA [$5]      | Load register from memory location | | 
 | 00 | LD_IMM  | LDA $5        | Load register with immediate value | | | 00 | LD_IMM  | LDA $5        | Load register with immediate value | |
 +| 01 | LD_MEM  | LDA [$5]      | Load register from memory location | |
 | 02 | LD_REG  | LDA [X]       | load register from memory location | | | 02 | LD_REG  | LDA [X]       | load register from memory location | |
 | 05 | ST_MEM  | STA [$10]     | Store register in memory location | | | 05 | ST_MEM  | STA [$10]     | Store register in memory location | |
Line 27: Line 27:
 | 32 | AND     | AND dst, src  | Bitwise AND (compare two integers bit by bit) | | | 32 | AND     | AND dst, src  | Bitwise AND (compare two integers bit by bit) | |
 | 33 | OR      | OR dst, src   | Bitwise OR (same) | | | 33 | OR      | OR dst, src   | Bitwise OR (same) | |
-| 34 | XOR     OR dst, src   | Bitwise XOR | |+| 34 | XOR     XOR dst, src  | Bitwise XOR | |
 | 35 | NOT     | NOT reg       | Invert all bits in an integer word | | | 35 | NOT     | NOT reg       | Invert all bits in an integer word | |
 | 46 | SHL     | SHL A         | Shift left   | Z, N, C | | 46 | SHL     | SHL A         | Shift left   | Z, N, C |
Line 38: Line 38:
 | 67 | JC      | JC @label     | Jump if carry set   | None | | 67 | JC      | JC @label     | Jump if carry set   | None |
 | 68 | JNC     | JNC @label    | Jump if carry clear | None | | 68 | JNC     | JNC @label    | Jump if carry clear | None |
-| 84 | CALL    | CALL @label   | Call subroutine (push IP, jump) | |+| 84 | [[#call|CALL]]    | CALL @label   | Call subroutine (push IP, jump) | |
 | 85 | RET                   | Return from subroutine (pop IP) | | | 85 | RET                   | Return from subroutine (pop IP) | |
 +| 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.+29 instructions. Some instructions which are not strictly RISC but still considered core.
  
-| 20 | MUL      | MUL X, Y     | Multiply X = X * Y  | | +| 0A | XCHG          | XCHG X, Y                   | Swap dem two -- X an Y trade place, quick quick | | 
-| 21 | DIV      | DIV X, Y     | Divide X = X / Y | | +| 20 | MUL           | MUL X, Y     | Multiply X = X * Y  | | 
-| 22 | MOD      | MOD X, Y     | Modulo X = X % Y | | +| 21 | DIV           | DIV X, Y     | Divide X = X / Y | | 
-86 INT      INT 0x10     Software interrupt | | +| 22 | MOD           | MOD X, Y     | Modulo X = X % Y | | 
-87 RTI      RTI          Return from Interrupt | |+23 ADD_REG_IMM   ADD X, $1234          Add immediate word value; X = X + immediate | | 
 +24 SUB_REG_IMM   SUB X, $ABCD          Subtract immediate; X = X - immediate | | 
 +| 25 | MUL_REG_IMM   | MUL X, $100           | Multiply by immediate; X:Y = X * immediate | | 
 +| 26 | DIV_REG_IMM   | DIV X, $10            | Divide by immediate; X = quotient, Y = remainder | | 
 +| 27 | MOD_REG_IMM   | MOD X, $FF            | Modulo by immediate; X = X % immediate | | 
 +| 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  | ADDC X, $5            | Add imm w/carry; X = X + imm + carry | | 
 +| 31 | SUBC_REG_IMM  | SUBC X, $1            | Subtract w/carry X = X - imm - borrow | | 
 +| 37 | AND_IMM       | AND dst, imm          | Bitwise AND with immediate | | 
 +| 38 | OR_IMM        | OR dst, imm           | Bitwise OR with immediate | | 
 + 
 +    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 | [[#sez|SEZ]]  | SEZ | Set zero flag | Z | 
 +| A1 | [[#sen|SEN]]  | SEN | Set negative flag | N | 
 +| A2 | [[#sec|SEC]]  | SEC | Set carry flag | C | 
 +| A3 | [[#sev|SEV]]  | SEV | Set overflow flag | V | 
 +| AB | CLZ           | | Clear zero flag | Z | 
 +| AC | CLN           | | Clear negative flag | N | 
 +| AD | CLC           | | Clear carry flag | C | 
 +| AE | CLV           | | Clear overflow flag |
  
 === Extended instruction set === Extended instruction set
-53 instructions. Some of these are more extended than others. For example, load from a memory location is, in fact+50 instructions. Some of these are more extended than others. For example, PUSHA and POPA are very useful because they are very fast. If you have to push or pop more than 4 registers at once you can consider PUSHA.
  
 | 03 | LD_REG24      | LDA [X:Y]      | Load register from memory location using [low_byte:word] | | | 03 | LD_REG24      | LDA [X:Y]      | Load register from memory location using [low_byte:word] | |
Line 60: Line 90:
 | 07 | ST_REG24      | STA [X:Y]      | Store A in memory using [low_byte:word] registers. | | | 07 | ST_REG24      | STA [X:Y]      | Store A in memory using [low_byte:word] registers. | |
 | 08 | ST_IMM24      | STA [$0:$A0]   | Store register in memory location [bank:addr] | | | 08 | ST_IMM24      | STA [$0:$A0]   | Store register in memory location [bank:addr] | |
-| 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.        STA [-, BLX]     ST_PD 25     // pre-dec store.        STA [-, BLX]
Line 68: Line 104:
     ST_FS 27     // store+forward step.   STA [BLX, +]     ST_FS 27     // store+forward step.   STA [BLX, +]
  
-| 23 | ADD_REG_IMM   | ADD X, $1234          | Add immediate word value; X = X + immediate | | 
-| 24 | SUB_REG_IMM   | SUB X, $ABCD          | Subtract immediate; X = X - immediate | | 
-| 25 | MUL_REG_IMM   | MUL X, $100           | Multiply by immediate; X:Y = X * immediate | | 
-| 26 | DIV_REG_IMM   | DIV X, $10            | Divide by immediate; X = quotient, Y = remainder | | 
-| 27 | MOD_REG_IMM   | MOD X, $FF            | Modulo by immediate; X = X % immediate | | 
-| 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  | ADDC X, $5            | Add imm w/carry; X = X + imm + carry | | 
-| 31 | SUBC_REG_IMM  | SUBC X, $1            | Subtract w/carry X = X - imm - borrow | | 
 | 36 | TEST          | TEST dst, src         | Non-destructive AND | | | 36 | TEST          | TEST dst, src         | Non-destructive AND | |
-| 37 | AND_IMM       | AND dst, imm          | Bitwise AND with immediate | | 
-| 38 | OR_IMM        | OR dst, imm           | Bitwise OR with immediate | | 
 | 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 | [[#sez|SEZ]]  | SEZ | Set zero flag | Z | +    JMPR = 109         // JMPR reg 
-| A1 | [[#sen|SEN]]  | SEN | Set negative flag | N | +    JZR = 110          // JZR reg 
-| A2 | [[#sec|SEC]]  | SEC | Set carry flag | C | +    JNZR = 111         // JNZR reg 
-| A3 | [[#sev|SEV]]  | SEV | Set overflow flag | V |+    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 | [[#see|SEE]]  | SEE | Set Extra Flag (User flag) | E | | A4 | [[#see|SEE]]  | SEE | Set Extra Flag (User flag) | E |
 | A5 | [[#sef|SEF]]  | SEF | Set Free Flag (User flag) | F | | A5 | [[#sef|SEF]]  | SEF | Set Free Flag (User flag) | F |
Line 98: Line 128:
 | A9 | [[#sei|SEI]]  | | Set Enable Interrupt | I | | A9 | [[#sei|SEI]]  | | Set Enable Interrupt | I |
 | AA | [[#ssi|SSI]]  | | Enable Sound System Interrupts | S | | AA | [[#ssi|SSI]]  | | Enable Sound System Interrupts | S |
-| 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          CNOP | Instruction Count / Timer | | 
-| 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
-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 | [[#memcopy|MEMCOPY]]  | MEMCOPY src, dst, n | Copy memory from ptr to ptr. | | | 8C | [[#memcopy|MEMCOPY]]  | MEMCOPY src, dst, n | Copy memory from ptr to ptr. | |
Line 129: Line 155:
 | 8F | [[#skpc|SKPC]]        | SKPC ELM, AL | Skip characters | | | 8F | [[#skpc|SKPC]]        | SKPC ELM, AL | Skip characters | |
 | 90 | [[#skpc|SKPC_IMM]]    | SKPC ELM, $20 | Skip characters (immediate) | | | 90 | [[#skpc|SKPC_IMM]]    | SKPC ELM, $20 | Skip characters (immediate) | |
 +
 +| 91 | INSQUE | INSQUE | INSQUE REG, REG | |
 +| 92 | INSQUE_PTR | INSQUE | INSQUE REG, [REG] | |
 +| 93 | REMQUE | REMQUE | | |
 +| 94 | [[#scanque|SCANQUE]] | SCANQUE | | |
 +| 95 | SCANQUE_IMM | SCANQUE | | |
 +
 +
 | 98 | [[#pab|PAB]]          | PAB | Pack low 4 bytes of A and low 4 bytes of B into AL | | | 98 | [[#pab|PAB]]          | PAB | Pack low 4 bytes of A and low 4 bytes of B into AL | |
 | 99 | [[#uab|UAB]]          | UAB | Unpack AL into low 4 bytes of AL and low 4 bytes of BL | | | 99 | [[#uab|UAB]]          | UAB | Unpack AL into low 4 bytes of AL and low 4 bytes of BL | |
Line 137: Line 171:
 | CB | [[#cvtan|CVTAN]]      | CVTAN AL | Zone converter ASCII 0-Z to Number) | | CB | [[#cvtan|CVTAN]]      | CVTAN AL | Zone converter ASCII 0-Z to Number) |
 | CC | [[#cvtna|CVTNA]]      | CVNAT AL | Zone converter 0-35 to ASCII '0' to 'Z' | | CC | [[#cvtna|CVTNA]]      | CVNAT AL | Zone converter 0-35 to ASCII '0' to 'Z' |
 +
 +The PPU extended commands are included at the CISC level:
 +
 +| #220 | [[#PPIXEL]]  | PPIXEL  | PPU draw_pixel          |
 +| #221 | [[#PLINE]    | PLINE   | PPU draw_line           |
 +| #222 | [[#PRECT]    | PRECT   | PPU draw_rect           |
 +| #223 | [[#PRECTF]   | PRECTF  | PPU draw_rect_filled    |
 +| #224 | [[#PCIRC]    | PCIRC   | PPU draw_circle         |
 +| #225 | [[#PCIRCF]   | PCIRCF  | PPU draw_circle_filled  |
 +| #226 | [[#PCLEAR]   | PCLEAR  | PPU clear_screen        |
 +| #227 | [[#PBLIT]    | PBLIT   | PPU draw tile           |
 +| #229 | [[#PTIMER]   | PTIMER  | PPU timer function      |
 +
 +As are the forth acceleration opcodes:
 +
 +| F0 | [[#lstepm|LSTEPM]]  | LSTEPM      | Loop Step in-memory (see Dictionary for details) | Z |
 +| 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 | [[#lstep|LSTEP]]  | LSTEP A, @label     | Loop Step direct (see Dictionary for details) | Z |
  
 == Dictionary == Dictionary
 here you will find information about each opcode. here you will find information about each opcode.
 +
 +<wrap #call /><wrap #call /><wrap #callr /><wrap #callr />
 +**''CALL addr / CALL reg / CALLR reg''**\\ CALL pushes the return address of the next instruction and jumps to the location.
 +
 +The CALLR instruction takes a register operand and dispatches based on the register's size: 16-bit registers use the current bank combined with a 16-bit address, 8-bit registers work similarly, and 24-bit registers provide a full 24-bit address. For function pointers stored in 32-bit register pairs like AB, CALLR will convert the address to 24 bits by discarding the high byte.
  
 <wrap #sez /><wrap #sen /><wrap #sec /><wrap #sev /> <wrap #sez /><wrap #sen /><wrap #sec /><wrap #sev />
Line 173: Line 231:
 <wrap #cmpc3 /> <wrap #cmpc3 />
 **''#142 $8E CMPC3 ELM, FLD, C''**\\ Non-zero byte compare. Useful for comparing strings. Scan up to C characters. The total number of characters scanned will be returned in C. So, C will point to either the first matching character, or will contain the string length. Sets ZERO on a match. If zero is not set, they don't match and Carry indicates if the STRCMP is -1 (not set) or +1 (set). **''#142 $8E CMPC3 ELM, FLD, C''**\\ Non-zero byte compare. Useful for comparing strings. Scan up to C characters. The total number of characters scanned will be returned in C. So, C will point to either the first matching character, or will contain the string length. Sets ZERO on a match. If zero is not set, they don't match and Carry indicates if the STRCMP is -1 (not set) or +1 (set).
 +
 +Note: CMPC3 allows early termination on byte_a == 0: This is the "begins with" / C-string semantics. If both strings reach a null terminator at the same position with all preceding bytes matching, the loop exits with matched=true (Z=1, C=1). Only byte_a is checked because by the time you reach this line, you've already proven byte_a == byte_b, so byte_a == 0 implies byte_b == 0. This makes CMPC3 do double duty; fixed-length compare and null-terminated strcmp in one instruction.
  
 <wrap #skpc /> <wrap #skpc />
 **''#143 $8F SKPC ELM, reg''**\\ Anti-scan. Scans until the character/word/etc. is not found. If a word width or wider register is used, will skip by needle width. Ends with ELM pointing to the first non-matching character. Most of the time this is used to skip spaces: ''SKPC ELM, $20 ; skip spaces, ELM points after last space.'' **''#143 $8F SKPC ELM, reg''**\\ Anti-scan. Scans until the character/word/etc. is not found. If a word width or wider register is used, will skip by needle width. Ends with ELM pointing to the first non-matching character. Most of the time this is used to skip spaces: ''SKPC ELM, $20 ; skip spaces, ELM points after last space.''
 +
 +<wrap #remque />REMQUE\\ REMQUE's Z-flag semantic is worth a kernal-side note
 +The classic VAX semantic for REMQUE used the V flag for "queue was already empty before the call." SD-8516's REMQUE uses Z for "queue is now empty after the call"; a different question entirely. Both are useful signals, but they're not equivalent.
 +
 +* 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" as a parameter without recompiling. Its "one of those" tradeoffs. 99% of the time you use IMM, but the general form is the REG version.
  
 <wrap #pab /> <wrap #pab />
Line 202: Line 274:
 <wrap #case /> <wrap #case />
 **''#200 $C8 CASE selector, #limit''**\\ switch-case. Index an address from selector and CALL to it. Limit is an immediate value (0-255) that represents the length of the table. If selector > limit it will silently fall-through (not CALL). If you need to detect whether or not the CALL occurred it is suggested that the handlers produce an error code (the 'default' of which is that no handler was called). Table format: [addr][addr][addr]... **''#200 $C8 CASE selector, #limit''**\\ switch-case. Index an address from selector and CALL to it. Limit is an immediate value (0-255) that represents the length of the table. If selector > limit it will silently fall-through (not CALL). If you need to detect whether or not the CALL occurred it is suggested that the handlers produce an error code (the 'default' of which is that no handler was called). Table format: [addr][addr][addr]...
 +
 +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't trap). VAX-style CASE would raise an exception. SC-8516's CASE sets V and ER but lets execution continue at the post-table point. That's a different policy -- error recoverable -- software decides whether to handle the case. If the caller wants trap-on-OOB behavior, it's a follow-up JV some_handler after the CASE.
 +
 +Flags otherwise untouched. CASE only writes V and ER. Z, N, C, etc. survive across the instruction, which is convenient if the selector was computed by an arithmetic op whose flags you still want.
 +
 +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:
 **''#204 $CC CVTNA reg8''**\\ Convert number to ASCII. Will convert the number 0 to 35 in a register to the ASCII characters '0' to 'Z'. Overflow is set if it is not a digit (0-9) and Carry is set if it is not a hexidecimal (0-F). This is the inverse of CVTAN. This instruction is designed to work with zoned decimal but can also work with zoned hexidecimal (this essentially means numbers in strings). **''#204 $CC CVTNA reg8''**\\ Convert number to ASCII. Will convert the number 0 to 35 in a register to the ASCII characters '0' to 'Z'. Overflow is set if it is not a digit (0-9) and Carry is set if it is not a hexidecimal (0-F). This is the inverse of CVTAN. This instruction is designed to work with zoned decimal but can also work with zoned hexidecimal (this essentially means numbers in strings).
  
 +<wrap #ppixel />
 +Draw a pixel at X, Y color in C.
 +
 +<wrap #lstepm />
 +**''$F0 LSTEPM''**\\ Loop Step in-memory. A Forth acceleration opcode. First, it increments the 4-byte loop counter at [FLX]. Then it compares the value [FLX] to the 4-byte loop termination value at [FLX+4]. If the values match, it sets the Z flag. This provides the ability to create extremely tight loops, so long as you are willing to use an 8 byte loop counter and limit. For example;
 +
 +    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:
 +
 +<code>
 +    LDFLX $F000       ; loop start
 +    LDA #1
 +    STA [FLX]
 +    LDA #1000
 +    STA [FLX+4]
 +loop:
 +    <do something>
 +    LSTEPM
 +    JNZ @loop
 +</code>
 +
 +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 />
 +**''$F3 LSTEP reg, @addr''**\\ Loop Step. A generalized version of the Forth acceleration opcode. This opcode lets you create very tight loops:
 +
 +
 +<code>
 +    LDC #1000       ; loop range
 +
 +loop:
 +    <do something>
 +    LSTEP C, @loop
 +</code>
 +
 +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's DBcc.
sd/isa.1778070764.txt.gz · Last modified: by appledog

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki