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/06/16 07:47] appledogsd:isa [2026/06/18 04:53] (current) appledog
Line 3: Line 3:
 == ISA Overview == ISA Overview
 The SD-8516 instruction set is organized into four tiers. Numbering is canonical The SD-8516 instruction set is organized into four tiers. Numbering is canonical
-in decimal (as defined in ''arch.h''); hex is given alongside for convenience.+in decimal (as defined in ''arch.h'' and ''arch.ts''); hex is given alongside for convenience.
  
 * **Tier 1 - Core** behaves like a RISC instruction set: small, orthogonal, and complete on its own. Target this first. Everything above it can be synthesized from the core if you have to. * **Tier 1 - Core** behaves like a RISC instruction set: small, orthogonal, and complete on its own. Target this first. Everything above it can be synthesized from the core if you have to.
 * **Tier 2 - Extended** are quality-of-life instructions for hand assemblers. ''ADD reg, imm'' is the canonical example: you do not need it (load the immediate and ''ADD''), but it is provided for convenience. ''MUL'' is in the same spirit, since you can loop with ''ADD''. * **Tier 2 - Extended** are quality-of-life instructions for hand assemblers. ''ADD reg, imm'' is the canonical example: you do not need it (load the immediate and ''ADD''), but it is provided for convenience. ''MUL'' is in the same spirit, since you can loop with ''ADD''.
 * **Tier 3 - CISC** are heavier, mostly VAX- and 680x0-flavored instructions: block memory, queue management, character scanning, jump tables. Each one folds a small loop into a single fetch-execute. * **Tier 3 - CISC** are heavier, mostly VAX- and 680x0-flavored instructions: block memory, queue management, character scanning, jump tables. Each one folds a small loop into a single fetch-execute.
-* **Tier 4 - Acceleration** are instructions added primarily to speed up a specific consumer: the LLVM backend (''MOVSX''/''MOVZX'', indexed addressing), the Forth system (''LSTEP'' and friends), or the hardware (PPU). They exist to remove instructions from a hot path, not to add expressiveness.+* **Tier 4 - Acceleration** are instructions added primarily to speed up a specific consumer: the LLVM backend (''MOVSX''/''MOVZX'', indexed addressing), the Forth system (''LSTEP'' and friends), or the hardware (PPU/ASU). They exist to remove instructions from a hot path, not to add expressiveness.
  
 A handful of opcodes carry aliases (e.g. ''JC''/''JAE'', ''BC''/''BAE'', ''CMPC''/''CMPC3''); both names assemble to the same byte. A handful of opcodes carry aliases (e.g. ''JC''/''JAE'', ''BC''/''BAE'', ''CMPC''/''CMPC3''); both names assemble to the same byte.
  
-//Removed since the previous revision: CASE3 (201), CASEB, PAB, UAB. These slots are no longer emitted and should not be relied upon.//+//Deprecated since the previous revision: CASE3, CASEB, PAB, UABand conditional JMPR.//
  
 === Tier 1: Core (RISC) === Tier 1: Core (RISC)
Line 18: Line 18:
  
 | #   | hex  | Mnemonic | Example       | Description                                  | Flags   | | #   | hex  | Mnemonic | Example       | Description                                  | Flags   |
-| 0   | $00  | [[#ld|LD_IMM]]   | LDA #$5       | Load register with an immediate value        |         |+| 0   | $00  | [[#ld|LD_IMM]]   | LDA $5        | Load register with an immediate value        |         |
 | 1   | $01  | [[#ld|LD_MEM]]   | LDA [$5]      | Load register from memory (absolute)                 | | 1   | $01  | [[#ld|LD_MEM]]   | LDA [$5]      | Load register from memory (absolute)                 |
 | 2   | $02  | [[#ld|LD_REG]]   | LDA [X]       | Load register from memory (register pointer) |         | | 2   | $02  | [[#ld|LD_REG]]   | LDA [X]       | Load register from memory (register pointer) |         |
-| 3   | $03  | [[#ld|LD_IMM8]]  | LDAL #$5      | Load byte register with an immediate                 |+| 3   | $03  | [[#ld|LD_IMM8]]  | LDAL $5       | Load byte register with an immediate                 |
 | 4   | $04  | [[#ld|LD_MEM8]]  | LDAL [$5]     | Load byte from memory (absolute)                     | | 4   | $04  | [[#ld|LD_MEM8]]  | LDAL [$5]     | Load byte from memory (absolute)                     |
 | 5   | $05  | [[#ld|LD_REG8]]  | LDAL [X]      | Load byte from memory (register pointer)             | | 5   | $05  | [[#ld|LD_REG8]]  | LDAL [X]      | Load byte from memory (register pointer)             |
Line 27: Line 27:
 | 7   | $07  | [[#ld|ST_REG]]   | STA [X]       | Store register to memory (register pointer)  |         | | 7   | $07  | [[#ld|ST_REG]]   | STA [X]       | Store register to memory (register pointer)  |         |
 | 9   | $09  | [[#mov|MOV]]     | MOV Y, A      | Copy register to register (//same width//          | | 9   | $09  | [[#mov|MOV]]     | MOV Y, A      | Copy register to register (//same width//          |
-| 11  | $0B  | PUSH     | PUSH A        | Push register onto stack                             | +| 11  | $0B  | [[#PUSH]]     | PUSH A        | Push register onto stack                             | 
-| 12  | $0C  | POP      | POP Y         | Pop stack into register                      |         | +| 12  | $0C  | [[#POP]]      | POP Y         | Pop stack into register                      |         | 
-| 15  | $0F  | PUSHF    | PUSHF         | Push flags                                           | +| 15  | $0F  | [[#PUSHF]]    | PUSHF         | Push flags                                           | 
-| 16  | $10  | POPF     | POPF          | Pop flags                                    | *       | +| 16  | $10  | [[#POPF]]     | POPF          | Pop flags                                    | *       | 
-| 23  | $17  | INC      | INC X         | Increment register by 1 (any width)          |         | +| 23  | $17  | [[#INC]]      | INC X         | Increment register by 1 (any width)          |         | 
-| 24  | $18  | DEC      | DEC Y         | Decrement register by 1 (any width)          |         | +| 24  | $18  | [[#DEC]]      | DEC Y         | Decrement register by 1 (any width)          |         | 
-| 30  | $1E  | ADD      | ADD X, Y      | X = X + Y                                             | +| 30  | $1E  | [[#ADD]]      | ADD X, Y      | X = X + Y                                             | 
-| 31  | $1F  | SUB      | SUB X, Y      | X = X - Y                                             | +| 31  | $1F  | [[#SUB]]      | SUB X, Y      | X = X - Y                                             | 
-| 50  | $32  | AND      | AND dst, src  | Bitwise AND                                  |         | +| 50  | $32  | [[#AND]]      | AND dst, src  | Bitwise AND                                  |         | 
-| 51  | $33  | OR       | OR dst, src   | Bitwise OR                                           | +| 51  | $33  | [[#OR]]       | OR dst, src   | Bitwise OR                                           | 
-| 52  | $34  | XOR      | XOR dst, src  | Bitwise XOR                                  |         | +| 52  | $34  | [[#XOR]]      | XOR dst, src  | Bitwise XOR                                  |         | 
-| 53  | $35  | NOT      | NOT reg       | Bitwise NOT (invert all bits)                |         | +| 53  | $35  | [[#NOT]]      | NOT reg       | Bitwise NOT (invert all bits)                |         | 
-| 70  | $46  | SHL      | SHL A         | Shift left                                   | Z N C   | +| 70  | $46  | [[#SHL]]      | SHL A         | Shift left                                   | Z N C   | 
-| 71  | $47  | SHR      | SHR A         | Shift right                                  | Z N C   | +| 71  | $47  | [[#SHR]]      | SHR A         | Shift right                                  | Z N C   | 
-| 90  | $5A  | CMP      | CMP A, B      | Compare (subtract, discard result)           | Z N C V | +| 90  | $5A  | [[#CMP]]      | CMP A, B      | Compare (subtract, discard result)           | Z N C V | 
-| 91  | $5B  | CMP_IMM  | CMP A, #$1    | Compare against immediate                    | Z N C V | +| 91  | $5B  | [[#CMP_IMM]]  | CMP A, $1     | Compare against immediate                    | Z N C V | 
-| 100 | $64  | JMP      | JMP @label    | Unconditional jump                                   | +| 100 | $64  | [[#JMP]]      | JMP @label    | Unconditional jump                                   | 
-| 101 | $65  | JZ       | JZ @label     | Jump if zero                                         | +| 101 | $65  | [[#JZ]]       | JZ @label     | Jump if zero                                         | 
-| 102 | $66  | JNZ      | JNZ @label    | Jump if not zero                                     | +| 102 | $66  | [[#JNZ]]      | JNZ @label    | Jump if not zero                                     | 
-| 105 | $69  | JC       | JC @label     | Jump if carry set (alias //JAE//           |         | +| 105 | $69  | [[#JC]]       | JC @label     | Jump if carry set (alias //JAE//           |         | 
-| 106 | $6A  | JNC      | JNC @label    | Jump if carry clear (alias //JNAE//                |+| 106 | $6A  | [[#JNC]]      | JNC @label    | Jump if carry clear (alias //JNAE//                |
 | 130 | $82  | [[#call|CALL]]   | CALL @label   | Call subroutine (push IP, jump)              |         | | 130 | $82  | [[#call|CALL]]   | CALL @label   | Call subroutine (push IP, jump)              |         |
-| 133 | $85  | RET      | RET           | Return from subroutine (pop IP)              |         | +| 133 | $85  | [[#RET]]      | RET           | Return from subroutine (pop IP)              |         | 
-| 134 | $86  | INT      | INT $10       | Software interrupt                                   | +| 134 | $86  | [[#INT]]      | INT $10       | Software interrupt                                   | 
-| 135 | $87  | RTI      | RTI           | Return from interrupt                        | *       | +| 135 | $87  | [[#RTI]]      | RTI           | Return from interrupt                        | *       | 
-| 182 | $B6  | SETF     | SETF #$80     | Set bits in the flags register               | *       | +| 182 | $B6  | [[#SETF]]     | SETF $80      | Set bits in the flags register               | *       | 
-| 183 | $B7  | CLRF     | CLRF #$80     | Clear bits in the flags register             | *       | +| 183 | $B7  | [[#CLRF]]     | CLRF $80      | Clear bits in the flags register             | *       | 
-| 184 | $B8  | TESTF    | TESTF #$80    | Non-destructive AND against flags            | Z C     | +| 184 | $B8  | [[#TESTF]]    | TESTF $80     | Non-destructive AND against flags            | Z C     | 
-| 254 | $FE  | NOP      | NOP           | No operation                                         | +| 254 | $FE  | [[#NOP]]      | NOP           | No operation                                         | 
-| 255 | $FF  | HALT     | HALT          | Halt CPU (sets HALT flag)                    |         |+| 255 | $FF  | [[#HALT]]     | HALT          | Halt CPU (sets HALT flag)                    |         | 
 + 
 +Although this is intended as a RISC core, there are some extras here, primarily LD-8bit hot path, which is done to speed up execution of 8 bit loads by about 30%. Additionally, INC, DEC and CALL/RET are semi-RISC because you can ADD reg, #1 or PUSH ptr0 and JMP (then POP IP to return). INT and RTI are suspect here, as well as CMP_IMM (you can just load into a register and use register compare). But these instructions are so common that it is difficult to justify not including them. The core set is intended to be minimalist, but not obtusely so. 
 + 
 +POPF however, is a strong canidate for removal. It would really only be needed for a kind of protected mode, interrupt mode or kernal mode, and we dont use it currently. 
 + 
 +Finally, it may be interesting to fuse CMP and JZ. Imagine, any CMP and conditional jump could be a CJMP. ex. ''CJZ A, B, address'' -- if they're equal, then we jump. One instruction. We save a dispatch and a byte. 
 + 
 +Consider: 
 +* No CMP exists in isolation 
 +* No JZ exists without responding to a change in the Z flag. 
 +* CJZ A, A can test for zero after a load if we really need one. 
 + 
 +Further investigate: 
 +* Does the cost of flag calculation outweight dispatch for how often a CMP occurrs?
  
 === Tier 2: Extended (Quality of Life) === Tier 2: Extended (Quality of Life)
Line 62: Line 76:
 they trade an opcode for fewer instructions in common patterns. they trade an opcode for fewer instructions in common patterns.
  
-| #   | hex  | Mnemonic     | Example         | Description                                       | Flags   | +| #   | hex  | Mnemonic     | Example         | Description                                      | Flags   | 
-| 10  | $0A  | XCHG         | XCHG X, Y       | Swap two registers                                |         | +| 10  | $0A  | XCHG         | XCHG X, Y       | Swap two registers                               |         | 
-| 13  | $0D  | PUSHA        | PUSHA           | Push all registers                                |         | +| 13  | $0D  | PUSHA        | PUSHA           | Push all registers                               |         | 
-| 14  | $0E  | POPA         | POPA            | Pop all registers                                 | *       | +| 14  | $0E  | POPA         | POPA            | Pop all registers                                | *       | 
-| 17  | $11  | PUSH2        | PUSH2 A, B      | Push 2 registers                                  |         | +| 17  | $11  | PUSH2        | PUSH2 A, B      | Push 2 registers                                 |         | 
-| 18  | $12  | POP2         | POP2 A, B       | Pop 2 registers                                   |         | +| 18  | $12  | POP2         | POP2 A, B       | Pop 2 registers                                  |         | 
-| 19  | $13  | PUSH3        | PUSH3 A, B, X   | Push 3 registers                                  |         | +| 19  | $13  | PUSH3        | PUSH3 A, B, X   | Push 3 registers                                 |         | 
-| 20  | $14  | POP3         | POP3 A, B, X    | Pop 3 registers                                   |         | +| 20  | $14  | POP3         | POP3 A, B, X    | Pop 3 registers                                  |         | 
-| 21  | $15  | PUSH4        | PUSH4 A,B,X,  | Push 4 registers                                  |         | +| 21  | $15  | PUSH4        | PUSH4 A,B,X,  | Push 4 registers                                 |         | 
-| 22  | $16  | POP4         | POP4 A,B,X,   | Pop 4 registers                                   |         | +| 22  | $16  | POP4         | POP4 A,B,X,   | Pop 4 registers                                  |         | 
-| 25  | $19  | [[#step|ST_PD]]      | STA [-, BLX]    | Pre-decrement store (alias //DPUSH//            |         | +| 25  | $19  | [[#step|ST_PD]]      | STA [-, BLX]    | Pre-decrement store (alias //DPUSH//   |         | 
-| 26  | $1A  | [[#step|LD_FS]]      | LDA [BLX, +]    | Load + forward step (alias //DPOP//             |         | +| 26  | $1A  | [[#step|LD_FS]]      | LDA [BLX, +]    | Load + forward step (alias //DPOP//    |         | 
-| 27  | $1B  | [[#step|ST_FS]]      | STA [BLX, +]    | Store + forward step                              |         | +| 27  | $1B  | [[#step|ST_FS]]      | STA [BLX, +]    | Store + forward step                     |         | 
-| 32  | $20  | MUL          | MUL X, Y        | X = X * Y                                          |         | +| 32  | $20  | MUL          | MUL X, Y        | X = X * Y                                        |         | 
-| 33  | $21  | DIV          | DIV X, Y        | X = X / Y (unsigned)                               |         | +| 33  | $21  | DIV          | DIV X, Y        | X = X / Y (unsigned)                             |         | 
-| 34  | $22  | MOD          | MOD X, Y        | X = X % Y (unsigned)                               |         | +| 34  | $22  | MOD          | MOD X, Y        | X = X % Y (unsigned)                             |         | 
-| 35  | $23  | ADD_REG_IMM  | ADD X, #$1234   | X = X + immediate                                 |         | +| 35  | $23  | ADD_REG_IMM  | ADD X, $1234    | X = X + immediate                                |         | 
-| 36  | $24  | SUB_REG_IMM  | SUB X, #$ABCD   | X = X - immediate                                 |         | +| 36  | $24  | SUB_REG_IMM  | SUB X, $ABCD    | X = X - immediate                                |         | 
-| 37  | $25  | MUL_REG_IMM  | MUL X, #$100    | X = X * immediate                                 |         | +| 37  | $25  | MUL_REG_IMM  | MUL X, $100     | X = X * immediate                                |         | 
-| 38  | $26  | DIV_REG_IMM  | DIV X, #$10     | X = X / immediate (unsigned)                      |         | +| 38  | $26  | DIV_REG_IMM  | DIV X, $10      | X = X / immediate (unsigned)                     |         | 
-| 39  | $27  | MOD_REG_IMM  | MOD X, #$FF     | X = X % immediate (unsigned)                      |         | +| 39  | $27  | MOD_REG_IMM  | MOD X, $FF      | X = X % immediate (unsigned)                     |         | 
-| 40  | $28  | ADDC         | ADDC X, Y       | X = X + Y + carry                                 |         | +| 40  | $28  | ADDC         | ADDC X, Y       | X = X + Y + carry                                |         | 
-| 41  | $29  | SUBC         | SUBC X, Y       | X = X - Y - borrow                                |         | +| 41  | $29  | SUBC         | SUBC X, Y       | X = X - Y - borrow                               |         | 
-| 42  | $2A  | ADDC_REG_IMM | ADDC X, #$5     | X = X + immediate + carry                         |         | +| 42  | $2A  | ADDC_REG_IMM | ADDC X, $5      | X = X + immediate + carry                        |         | 
-| 43  | $2B  | SUBC_REG_IMM | SUBC X, #$1     | X = X - immediate - borrow                        |         | +| 43  | $2B  | SUBC_REG_IMM | SUBC X, $1      | X = X - immediate - borrow                       |         | 
-| 54  | $36  | TEST         | TEST dst, src   | Non-destructive AND                               |         | +| 54  | $36  | TEST         | TEST dst, src   | Non-destructive AND                              |         | 
-| 55  | $37  | AND_IMM      | AND dst, #imm   | Bitwise AND with immediate                        |         | +| 55  | $37  | AND_IMM      | AND dst, #imm   | Bitwise AND with immediate                       |         | 
-| 56  | $38  | OR_IMM       | OR dst, #imm    | Bitwise OR with immediate                         |         | +| 56  | $38  | OR_IMM       | OR dst, #imm    | Bitwise OR with immediate                        |         | 
-| 57  | $39  | XOR_IMM      | XOR dst, #imm   | Bitwise XOR with immediate                        |         | +| 57  | $39  | XOR_IMM      | XOR dst, #imm   | Bitwise XOR with immediate                       |         | 
-| 72  | $48  | SHLC         | SHLC A          | Shift left through carry                          | Z N C   | +| 72  | $48  | SHLC         | SHLC A          | Shift left through carry                         | Z N C   | 
-| 73  | $49  | SHRC         | SHRC A          | Shift right through carry                         | Z N C   | +| 73  | $49  | SHRC         | SHRC A          | Shift right through carry                        | Z N C   | 
-| 74  | $4A  | ROL          | ROL A           | Rotate left                                       | Z N C   | +| 74  | $4A  | ROL          | ROL A           | Rotate left                                      | Z N C   | 
-| 75  | $4B  | ROR          | ROR A           | Rotate right                                      | Z N C   | +| 75  | $4B  | ROR          | ROR A           | Rotate right                                     | Z N C   | 
-| 76  | $4C  | ROLC         | ROLC A          | Rotate left through carry                         | Z N C   | +| 76  | $4C  | ROLC         | ROLC A          | Rotate left through carry                        | Z N C   | 
-| 77  | $4D  | RORC         | RORC A          | Rotate right through carry                        | Z N C   | +| 77  | $4D  | RORC         | RORC A          | Rotate right through carry                       | Z N C   | 
-| 80  | $50  | [[#shx|SHL_X]]       | SHL_X A, C      | Shift left by count //(confirm semantics)//       | Z N C   | +| 80  | $50  | [[#shx|SHL_X]] | SHL_X A, C    | Shift left by count //(confirm semantics)//      | Z N C   | 
-| 81  | $51  | [[#shx|SHR_X]]       | SHR_X A, C      | Shift right by count //(confirm semantics)//      | Z N C   | +| 81  | $51  | [[#shx|SHR_X]] | SHR_X A, C    | Shift right by count //(confirm semantics)//     | Z N C   | 
-| 103 | $67  | JN           | JN @label       | Jump if negative                                  |         | +| 103 | $67  | JN           | JN @label       | Jump if negative                                 |         | 
-| 104 | $68  | JNN          | JNN @label      | Jump if not negative                              |         | +| 104 | $68  | JNN          | JNN @label      | Jump if not negative                             |         | 
-| 107 | $6B  | JO           | JO @label       | Jump if overflow (alias //JV//                  |         | +| 107 | $6B  | JO           | JO @label       | Jump if overflow (alias //JV//                 |         | 
-| 108 | $6C  | JNO          | JNO @label      | Jump if no overflow (alias //JNV//              |         | +| 108 | $6C  | JNO          | JNO @label      | Jump if no overflow (alias //JNV//             |         | 
-| 110 | $6E  | JMPR         | JMPR X          | Jump to address in register                       |         | +| 110 | $6E  | JMPR         | JMPR X          | Jump to address in register                      |         | 
-| 111 | $6F  | JL           | JL @label       | Jump if less (signed)                             |         | +| 111 | $6F  | JL           | JL @label       | Jump if less (signed)                            |         | 
-| 112 | $70  | JLE          | JLE @label      | Jump if less or equal (signed)                    |         | +| 112 | $70  | JLE          | JLE @label      | Jump if less or equal (signed)                   |         | 
-| 113 | $71  | JG           | JG @label       | Jump if greater (signed)                          |         | +| 113 | $71  | JG           | JG @label       | Jump if greater (signed)                         |         | 
-| 114 | $72  | JGE          | JGE @label      | Jump if greater or equal (signed)                 |         | +| 114 | $72  | JGE          | JGE @label      | Jump if greater or equal (signed)                |         | 
-| 115 | $73  | JA           | JA @label       | Jump if above (unsigned)                          |         | +| 115 | $73  | JA           | JA @label       | Jump if above (unsigned)                         |         | 
-| 116 | $74  | JNA          | JNA @label      | Jump if not above (unsigned)                      |         | +| 116 | $74  | JNA          | JNA @label      | Jump if not above (unsigned)                     |         | 
-| 120 | $78  | [[#branch|BZ]]   | BZ @near        | Branch if zero (2-byte relative, +/-127)          |         | +| 120 | $78  | [[#branch|BZ]]   | BZ @near        | Branch if zero (2-byte relative, +/-127)     |         | 
-| 121 | $79  | [[#branch|BNZ]]  | BNZ @near       | Branch if not zero                                |         | +| 121 | $79  | [[#branch|BNZ]]  | BNZ @near       | Branch if not zero                           |         | 
-| 122 | $7A  | [[#branch|BC]]   | BC @near        | Branch if carry (alias //BAE//                  |         | +| 122 | $7A  | [[#branch|BC]]   | BC @near        | Branch if carry (alias //BAE//             |         | 
-| 123 | $7B  | [[#branch|BNC]]  | BNC @near       | Branch if no carry (alias //BNAE//              |         | +| 123 | $7B  | [[#branch|BNC]]  | BNC @near       | Branch if no carry (alias //BNAE//         |         | 
-| 124 | $7C  | [[#branch|BA]]   | BA @near        | Branch if above (unsigned)                        |         | +| 124 | $7C  | [[#branch|BA]]   | BA @near        | Branch if above (unsigned)                   |         | 
-| 125 | $7D  | [[#branch|BNA]]  | BNA @near       | Branch if not above (unsigned)                    |         | +| 125 | $7D  | [[#branch|BNA]]  | BNA @near       | Branch if not above (unsigned)               |         | 
-| 126 | $7E  | [[#branch|BG]]   | BG @near        | Branch if greater (signed)                        |         | +| 126 | $7E  | [[#branch|BG]]   | BG @near        | Branch if greater (signed)                   |         | 
-| 127 | $7F  | [[#branch|BGE]]  | BGE @near       | Branch if greater or equal (signed)               |         | +| 127 | $7F  | [[#branch|BGE]]  | BGE @near       | Branch if greater or equal (signed)          |         | 
-| 128 | $80  | [[#branch|BL]]   | BL @near        | Branch if less (signed)                           |         | +| 128 | $80  | [[#branch|BL]]   | BL @near        | Branch if less (signed)                      |         | 
-| 129 | $81  | [[#branch|BLE]]  | BLE @near       | Branch if less or equal (signed)                  |         | +| 129 | $81  | [[#branch|BLE]]  | BLE @near       | Branch if less or equal (signed)             |         | 
-| 160 | $A0  | [[#setflag|SEZ]] | SEZ             | Set zero flag                                     | Z       | +| 160 | $A0  | [[#setflag|SEZ]] | SEZ             | Set zero flag                                | Z       | 
-| 161 | $A1  | [[#setflag|SEN]] | SEN             | Set negative flag                                 | N       | +| 161 | $A1  | [[#setflag|SEN]] | SEN             | Set negative flag                            | N       | 
-| 162 | $A2  | [[#setflag|SEC]] | SEC             | Set carry flag                                    | C       | +| 162 | $A2  | [[#setflag|SEC]] | SEC             | Set carry flag                               | C       | 
-| 163 | $A3  | [[#setflag|SEV]] | SEV             | Set overflow flag                                 | V       | +| 163 | $A3  | [[#setflag|SEV]] | SEV             | Set overflow flag                            | V       | 
-| 164 | $A4  | [[#see|SEE]]     | SEE             | Set exception/extra flag                          | E       | +| 164 | $A4  | [[#see|SEE]]     | SEE             | Set exception/extra flag                     | E       | 
-| 165 | $A5  | [[#sef|SEF]]     | SEF             | Set F (free) flag                                 | F       | +| 165 | $A5  | [[#sef|SEF]]     | SEF             | Set F (free) flag                            | F       | 
-| 166 | $A6  | [[#seb|SEB]]     | SEB             | Set B (bonus) flag                                | B       | +| 166 | $A6  | [[#seb|SEB]]     | SEB             | Set B (bonus) flag                           | B       | 
-| 167 | $A7  | [[#seu|SEU]]     | SEU             | Set U (user) flag                                 | U       | +| 167 | $A7  | [[#seu|SEU]]     | SEU             | Set U (user) flag                            | U       | 
-| 168 | $A8  | [[#sed|SED]]     | SED             | Set debug (trace) flag                            | D       | +| 168 | $A8  | [[#sed|SED]]     | SED             | Set debug (trace) flag                       | D       | 
-| 169 | $A9  | [[#sei|SEI]]     | SEI             | Set interrupt-enable flag                         | I       | +| 169 | $A9  | [[#sei|SEI]]     | SEI             | Set interrupt-enable flag                    | I       | 
-| 170 | $AA  | [[#ssi|SSI]]     | SSI             | Set sound-interrupt flag                          | S       | +| 170 | $AA  | [[#ssi|SSI]]     | SSI             | Set sound-interrupt flag                     | S       | 
-| 171 | $AB  | CLZ          | CLZ             | Clear zero flag                                   | Z       | +| 171 | $AB  | CLZ          | CLZ             | Clear zero flag                                  | Z       | 
-| 172 | $AC  | CLN          | CLN             | Clear negative flag                               | N       | +| 172 | $AC  | CLN          | CLN             | Clear negative flag                              | N       | 
-| 173 | $AD  | CLC          | CLC             | Clear carry flag                                  | C       | +| 173 | $AD  | CLC          | CLC             | Clear carry flag                                 | C       | 
-| 174 | $AE  | CLV          | CLV             | Clear overflow flag                               | V       | +| 174 | $AE  | CLV          | CLV             | Clear overflow flag                              | V       | 
-| 175 | $AF  | CLE          | CLE             | Clear exception/extra flag                        | E       | +| 175 | $AF  | CLE          | CLE             | Clear exception/extra flag                       | E       | 
-| 176 | $B0  | CLF          | CLF             | Clear F flag                                      | F       | +| 176 | $B0  | CLF          | CLF             | Clear F flag                                     | F       | 
-| 177 | $B1  | CLB          | CLB             | Clear B flag                                      | B       | +| 177 | $B1  | CLB          | CLB             | Clear B flag                                     | B       | 
-| 178 | $B2  | CLU          | CLU             | Clear U flag                                      | U       | +| 178 | $B2  | CLU          | CLU             | Clear U flag                                     | U       | 
-| 179 | $B3  | CLD          | CLD             | Clear debug flag                                  | D       | +| 179 | $B3  | CLD          | CLD             | Clear debug flag                                 | D       | 
-| 180 | $B4  | CLI          | CLI             | Clear interrupt-enable flag                       | I       | +| 180 | $B4  | CLI          | CLI             | Clear interrupt-enable flag                      | I       | 
-| 181 | $B5  | CSI          | CSI             | Clear sound-interrupt flag                        | S       |+| 181 | $B5  | CSI          | CSI             | Clear sound-interrupt flag                       | S       |
  
 === Tier 3: CISC (VAX-style) === Tier 3: CISC (VAX-style)
Line 148: Line 162:
  
 | #   | hex  | Mnemonic      | Example            | Description                                | Flags | | #   | hex  | Mnemonic      | Example            | Description                                | Flags |
-| 140 | $8C  | [[#memcopy|MEMCOPY]]  | MEMCOPY src, dst, n | Copy n bytes ptr to ptr (handles overlap)  |       | +| 140 | $8C  | [[#memcopy|MEMCOPY]]  | MEMCOPY src, dst, n | Copy n bytes ptr to ptr           |       | 
-| 141 | $8D  | [[#scan|SCAN]]        | SCAN ELM, reg       | Scan memory for a 1-4 byte needle          | Z     | +| 141 | $8D  | [[#scan|SCAN]]        | SCAN ELM, reg       | Scan memory for a 1-4 byte needle | Z     | 
-| 142 | $8E  | [[#cmpc|CMPC]]        | CMPC ELM, FLD, C    | Compare characters (alias //CMPC3//      | Z C   | +| 142 | $8E  | [[#cmpc|CMPC]]        | CMPC ELM, FLD, C    | Compare characters (alias //CMPC3// | Z C   | 
-| 143 | $8F  | [[#skpc|SKPC]]        | SKPC ELM, AL        | Skip characters (anti-scan)                |       | +| 143 | $8F  | [[#skpc|SKPC]]        | SKPC ELM, AL        | Skip characters (anti-scan)           |       | 
-| 144 | $90  | [[#skpc|SKPC_IMM]]    | SKPC ELM, #$20      | Skip characters (immediate needle)         |       | +| 144 | $90  | [[#skpc|SKPC_IMM]]    | SKPC ELM, $20       | Skip characters (immediate needle)    |       | 
-| 145 | $91  | [[#que|INSQUE]]       | INSQUE reg, reg     | Insert into queue                          |       | +| 145 | $91  | [[#que|INSQUE]]       | INSQUE reg, reg     | Insert into queue                     |       | 
-| 146 | $92  | [[#que|INSQUE_PTR]]   | INSQUE reg, [reg]   | Insert into queue (pointer form)           |       | +| 146 | $92  | [[#que|INSQUE_PTR]]   | INSQUE reg, [reg]   | Insert into queue (pointer form)      |       | 
-| 147 | $93  | [[#que|REMQUE]]       | REMQUE reg          | Remove from queue                          | Z     |+| 147 | $93  | [[#que|REMQUE]]       | REMQUE reg          | Remove from queue                     | Z     |
 | 148 | $94  | [[#scanque|SCANQUE]]  | SCANQUE H, N, O     | Scan a queue, matching a field (reg offset)| Z     | | 148 | $94  | [[#scanque|SCANQUE]]  | SCANQUE H, N, O     | Scan a queue, matching a field (reg offset)| Z     |
 | 149 | $95  | [[#scanque|SCANQUE_IMM]] | SCANQUE H, N, #O | Scan a queue, matching a field (imm offset)| Z     | | 149 | $95  | [[#scanque|SCANQUE_IMM]] | SCANQUE H, N, #O | Scan a queue, matching a field (imm offset)| Z     |
 | 200 | $C8  | [[#case|CASE]]        | CASE AL, #limit     | Inline jump table; CALL table[selector]    | V ER  | | 200 | $C8  | [[#case|CASE]]        | CASE AL, #limit     | Inline jump table; CALL table[selector]    | V ER  |
-| 202 | $CA  | [[#casetab|CASETAB]]  | CASETAB ELM, AL, #limit | Jump table at a base address           | V ER  | +| 202 | $CA  | [[#casetab|CASETAB]]  | CASETAB ELM, AL, #limit | Jump table at a base address      | V ER  | 
-| 203 | $CB  | [[#cvtan|CVTAN]]      | CVTAN AL            | Convert ASCII '0'-'Z' to number 0-35       | O C   | +| 203 | $CB  | [[#cvtan|CVTAN]]      | CVTAN AL            | Convert ASCII '0'-'Z' to number 0-35  | O C   | 
-| 204 | $CC  | [[#cvtna|CVTNA]]      | CVTNA AL            | Convert number 0-35 to ASCII '0'-'Z'       | O C   |+| 204 | $CC  | [[#cvtna|CVTNA]]      | CVTNA AL            | Convert number 0-35 to ASCII '0'-'Z'  | O C   |
  
 === Tier 4: Acceleration (LLVM / Forth / Hardware) === Tier 4: Acceleration (LLVM / Forth / Hardware)
-Instructions added to remove work from a specific hot path rather than to add +Instructions added to remove work from a specific hot path rather than to add expressiveness. Each one has a primary consumer noted below. 
-expressiveness. Each one has a primary consumer noted below.+ 
 +Canidates for inclusion: LEA, fused CMP-Bcc and CMP-Jcc, conditional move, LD_IDX16
  
 | #   | hex  | Mnemonic | Example          | Description                                  | Consumer | Flags | | #   | hex  | Mnemonic | Example          | Description                                  | Consumer | Flags |
Line 196: Line 211:
 from the tables above. from the tables above.
  
-<wrap #ld /> +<wrap #ld_imm /> 
-**''LD_IMM / LD_MEM / LD_REG / LD_IMM8 / LD_MEM8 / LD_REG8 / ST_MEM / ST_REG''**\\ +**''#0 $00 LD_IMM''**\\ 
-The core load/store setWord loads come in three addressing modes -immediate +Load register with an immediate value''A = $5'' (16/24/32-bit depending on register width). 
-(''#$5''), absolute (''[$5]''), and register-pointer (''[X]'') -- and the ''*8'' + 
-variants are their byte-width counterpartsStores provide absolute and +<wrap #ld_mem /> 
-register-pointer formsWider-than-16-bit memory access uses 24-bit pointer +**''#$01 LD_MEM''**\\ 
-registers (the paired registers such as BLX/ELM) as the pointer operand; there is +Load register from memory (absolute address). ''A = [$5]''
-no separate "24-bit load" opcodeFor indexed access with a displacement, see the + 
-acceleration-tier [[#idx|indexed loads and stores]].+<wrap #ld_reg /> 
 +**''#2 $02 LD_REG''**\\ 
 +Load register from memory (register-indirect pointer). ''A = [X]''
 + 
 +<wrap #ld_imm8 /> 
 +**''#3 $03 LD_IMM8''**\\ 
 +Load byte register with an immediate value''AL = $5''
 + 
 +<wrap #ld_mem8 /> 
 +**''#4 $04 LD_MEM8''**\\ 
 +Load byte from memory (absolute). ''AL = [$5]''. 
 + 
 +<wrap #ld_reg8 /> 
 +**''#5 $05 LD_REG8''**\\ 
 +Load byte from memory (register-indirect). ''AL = [X]''
 + 
 +<wrap #st_mem /> 
 +**''#6 $06 ST_MEM''**\\ 
 +Store register to memory (absolute). ''[$10] = A''
 + 
 +<wrap #st_reg /> 
 +**''#7 $07 ST_REG''**\\ 
 +Store register to memory (register-indirect). ''[X= A''.
  
 <wrap #mov /> <wrap #mov />
 **''#9 $09 MOV dst, src''**\\ **''#9 $09 MOV dst, src''**\\
-Register-to-register copy. **MOV requires source and destination of equal width**; +Register-to-register copy ex. ''Y = A''. **MOV requires source and destination of equal width**; this is enforced at assemble time. A move that changes width is not a MOV -- use [[#movx|MOVSX/MOVZX]] to widen. The assembler rejects a mismatched-width MOV rather than guessing which bytes you meant. Mismatched MOV is undefined at execution time.
-this is enforced at assemble time. A move that changes width is not a MOV -- use +
-[[#movx|MOVSX/MOVZX]] to widen. The assembler rejects a mismatched-width MOV rather +
-than guessing which bytes you meant.+
  
-<wrap #call /> +<wrap #push /> 
-**''#130 $82 CALL addr / CALL reg / #131 $83 CALLR reg''**\\ +**''#11 $0B PUSH''**\\ 
-CALL pushes the return address (the instruction after the call) and jumps to the +Push register onto stack. ''SP -= width; [SP] = A''
-target. CALLR takes a register operand and dispatches on its width16-bit and + 
-8-bit registers combine with the current bank, 24-bit registers give a full +<wrap #pop /
-address, and a 32-bit pair (e.gAB) is narrowed to 24 bits by discarding the high +**''#12 $0C POP''**\\ 
-byteThis makes 32-bit register pairs usable as function pointers.+Pop stack into register. ''Y = [SP]; SP += width''
 + 
 +<wrap #pushf /> 
 +**''#15 $0F PUSHF''**\\ 
 +Push flags register onto stack. 
 + 
 +<wrap #popf /> 
 +**''#16 $10 POPF''**\\ 
 +Pop stack into flags register. * 
 + 
 +<wrap #inc /> 
 +**''#23 $17 INC''**\\ 
 +Increment register by 1 (any width)''X += 1''Sets Z/N flags. 
 + 
 +<wrap #dec /> 
 +**''#24 $18 DEC''**\\ 
 +Decrement register by 1 (any width)''-= 1''. Sets Z/N flags.
  
 <wrap #step /> <wrap #step />
Line 227: Line 277:
 pointer (''LDA [BLX, +]''), and ST_FS stores then advances. These collapse the pointer (''LDA [BLX, +]''), and ST_FS stores then advances. These collapse the
 pointer bookkeeping of a copy loop into the access itself. pointer bookkeeping of a copy loop into the access itself.
 +
 +<wrap #mov-x />
 +**''#28 $1C MOVSX dst, src / #29 $1D MOVZX dst, src''**\\
 +Move with sign-extend (MOVSX) or zero-extend (MOVZX). The source is read at its own
 +width and written across the full destination, with the high bytes filled from the
 +source's sign bit (MOVSX) or with zero (MOVZX). The destination **must be strictly
 +wider** than the source; this is checked at assemble time. Both fully define the
 +destination, so unlike a byte ALU op there is no partial-register hazard, and the
 +in-place overlapping case (''MOVSX A, AL'') is well defined.
 +
 +These exist to collapse the compiler's extend sequence: without a native
 +sign-extend, widening a signed ''char'' to ''int'' took three ops
 +(''AND''/''XOR''/''SUB'' implementing the ''(x ^ 0x80) - 0x80'' identity). MOVSX does
 +it in one. Integer promotion makes signed widening pervasive in C, so this is a
 +recurring code-size win. MOVZX similarly drops the masking immediate of an
 +''AND $FF'' style zero-extend.
 +
 +<wrap #add />
 +**''#30 $1E ADD''**\\
 +Add registers. ''X = X + Y''. Updates Z N C V.
 +
 +<wrap #sub />
 +**''#31 $1F SUB''**\\
 +Subtract registers. ''X = X - Y''. Updates Z N C V.
 +
 +<wrap #and />
 +**''#50 $32 AND''**\\
 +Bitwise AND. ''dst = dst & src''. Updates Z N.
 +
 +<wrap #or />
 +**''#51 $33 OR''**\\
 +Bitwise OR. ''dst = dst | src''. Updates Z N.
 +
 +<wrap #xor />
 +**''#52 $34 XOR''**\\
 +Bitwise XOR. ''dst = dst ^ src''. Updates Z N.
 +
 +<wrap #not />
 +**''#53 $35 NOT''**\\
 +Bitwise NOT (invert all bits). ''reg = ~reg''. Updates Z N.
 +
 +<wrap #shl />
 +**''#70 $46 SHL''**\\
 +Shift left. ''A <<= count''. Updates Z N C.
 +
 +<wrap #shr />
 +**''#71 $47 SHR''**\\
 +Shift right (logical). ''A >>= count''. Updates Z N C.
  
 <wrap #shx /> <wrap #shx />
Line 234: Line 332:
 the current emulator handler before relying on this entry.// the current emulator handler before relying on this entry.//
  
-<wrap #branch /> +<wrap #cmp /> 
-**''#120-#129 Branches (BZ, BNZ, BC, BNC, BA, BNA, BG, BGE, BL, BLE)''**\\ +**''#90 $64 CMP''**\\ 
-Two-byte relative branches with a signed 8-bit displacement (range -128..+127 from +Compare registers (subtract, discard result). ''tmp = A B''Updates Z N C V.
-the instruction). They mirror the absolute jumps but encode shorter and stay +
-position-independent, so they are preferred for tight local loopsBC/BAE and +
-BNC/BNAE are aliases. For targets outside +/-127, use the absolute jumps.+
  
-<wrap #setflag /> +<wrap #cmp_imm /> 
-**''#160 SEZ / #161 SEN / #162 SEC / #163 SEV''**\\ +**''#91 $5B CMP_IMM''**\\ 
-Set the zero, negative, carry, and overflow flags respectivelyUseful when you are +Compare register against immediate. ''tmp = A - $1''. Updates Z N C V.
-certain no intervening operation disturbs the flag -- for example, carry survives +
-POP and MOV, so it is a common error/clear channel out of a routine (''JC @error'').+
  
-<wrap #see /> +<wrap #jmp /> 
-**''#164 $A4 SEE''**\\ Set the Exception flag. Used by some interrupts and the +**''#100 $64 JMP''**\\ 
-system to signal an error, but free for your own use otherwiseThink of it as an +Unconditional jump''IP = @label''.
-"Extra" flag.+
  
-<wrap #sef /> +<wrap #jz /> 
-**''#165 $A5 SEF''**\\ Set the F ("free"flag. Used for "first-statement" in BASIC; +**''#101 $65 JZ''**\\ 
-otherwise safe for machine-language use.+Jump if zero. ''if (ZIP = @label''.
  
-<wrap #seb /> +<wrap #jnz /> 
-**''#166 $A6 SEB''**\\ Set the B ("bonus"flag. Used for BREAK in BASIC; otherwise +**''#102 $66 JNZ''**\\ 
-safe for machine-language use.+Jump if not zero. ''if (!ZIP = @label''.
  
-<wrap #seu /> +<wrap #jc /> 
-**''#167 $A7 SEU''**\\ Set the User flag. Not used by the system; reserved for the +**''#105 $69 JC''**\\ 
-programmer.+Jump if carry set (alias JAE for unsigned {{{>=)}}}. ''if (C) IP = @label''.
  
-<wrap #sed /> +<wrap #jnc /> 
-**''#168 $A8 SED''**\\ Set Debug. Emits trace messages while on; slows the system +**''#106 $6A JNC''**\\ 
-considerablyTrace output may be compiled out in some builds.+Jump if carry clear (alias JNAE for unsigned <)''if (!C) IP = @label''.
  
-<wrap #sei /> +<wrap #call /> 
-**''#169 $A9 SEI''**\\ Enable/disable interruptsWith interrupts offINT will not +**''#130 $82 CALL addr / CALL reg / #131 $83 CALLR reg''**\\ 
-fire.+CALL pushes the return address (the instruction after the call) and jumps to the 
 +targetCALLR takes a register operand and dispatches on its width: 16-bit and 
 +8-bit registers combine with the current bank24-bit registers give a full 
 +address, and a 32-bit pair (e.g. AB) is narrowed to 24 bits by discarding the high 
 +byte. This makes 32-bit register pairs usable as function pointers.
  
-<wrap #ssi /> +<wrap #branch /> 
-**''#170 $AA SSI''**\\ Set the Sound Interrupt flagManaged by the KERNAL; +**''#120-#129 Branches (BZ, BNZ, BC, BNC, BA, BNA, BG, BGE, BL, BLE)''**\\ 
-semi-reserved and may be removed.+Two-byte relative branches with a signed 8-bit displacement (range -128..+127 from 
 +the instruction)They mirror the absolute jumps but encode shorter and stay 
 +position-independent, so they are preferred for tight local loops. BC/BAE and 
 +BNC/BNAE are aliases. For targets outside +/-127, use the absolute jumps.
  
 <wrap #memcopy /> <wrap #memcopy />
Line 290: Line 389:
 <wrap #cmpc /> <wrap #cmpc />
 **''#142 $8E CMPC ELM, FLD, C''** (alias //CMPC3//)\\ **''#142 $8E CMPC ELM, FLD, C''** (alias //CMPC3//)\\
-Non-zero byte compare, useful for strings. Compares up to C characters; C returns +Non-zero byte compare, useful for strings. Compares up to C characters; C returns either the index of the first mismatch or the matched length. Sets ZERO on a full match; otherwise CARRY distinguishes the -1 / +1 ordering.
-either the index of the first mismatch or the matched length. Sets ZERO on a full +
-match; otherwise CARRY distinguishes the -1 / +1 ordering.+
  
-CMPC allows early termination when ''byte_a == 0'' -- the C-string "begins with" +CMPC allows early termination when ''byte_a == 0'' -- the C-string "begins with" semantics. If both strings reach a terminator at the same position with all prior bytes equal, the loop exits matched (Z=1, C=1). Only ''byte_a'' is tested because by that point ''byte_a == byte_b'' is already proven, so ''byte_a == 0'' implies ''byte_b == 0''. This lets CMPC do double duty: fixed-length compare and null-terminated strcmp in one instruction.
-semantics. If both strings reach a terminator at the same position with all prior +
-bytes equal, the loop exits matched (Z=1, C=1). Only ''byte_a'' is tested because by +
-that point ''byte_a == byte_b`` is already proven, so ''byte_a == 0'' implies +
-''byte_b == 0''. This lets CMPC do double duty: fixed-length compare and +
-null-terminated strcmp in one instruction.+
  
 <wrap #skpc /> <wrap #skpc />
Line 305: Line 397:
 Anti-scan: advance while the needle //is// found, stopping at the first Anti-scan: advance while the needle //is// found, stopping at the first
 non-matching position. A word-or-wider needle steps by needle width. Most often used non-matching position. A word-or-wider needle steps by needle width. Most often used
-to skip spaces: ''SKPC ELM, #$20'' leaves ELM just past the last space.+to skip spaces: ''SKPC ELM, $20'' leaves ELM just past the last space.
  
 <wrap #que /> <wrap #que />
Line 331: Line 423:
 you write CRUD for a struct); the register form exists so generic kernel queue you write CRUD for a struct); the register form exists so generic kernel queue
 helpers can take "field offset" as a parameter. helpers can take "field offset" as a parameter.
 +
 +<wrap #setflag />
 +**''#160 SEZ / #161 SEN / #162 SEC / #163 SEV''**\\
 +Set the zero, negative, carry, and overflow flags respectively. Useful when you are
 +certain no intervening operation disturbs the flag -- for example, carry survives
 +POP and MOV, so it is a common error/clear channel out of a routine (''JC @error'').
 +
 +<wrap #see />
 +**''#164 $A4 SEE''**\\ Set the Exception flag. Used by some interrupts and the
 +system to signal an error, but free for your own use otherwise. Think of it as an
 +"Extra" flag.
 +
 +<wrap #sef />
 +**''#165 $A5 SEF''**\\ Set the F ("free") flag. Used for "first-statement" in BASIC;
 +otherwise safe for machine-language use.
 +
 +<wrap #seb />
 +**''#166 $A6 SEB''**\\ Set the B ("bonus") flag. Used for BREAK in BASIC; otherwise
 +safe for machine-language use.
 +
 +<wrap #seu />
 +**''#167 $A7 SEU''**\\ Set the User flag. Not used by the system; reserved for the
 +programmer.
 +
 +<wrap #sed />
 +**''#168 $A8 SED''**\\ Set Debug. Emits trace messages while on; slows the system
 +considerably. Trace output may be compiled out in some builds.
 +
 +<wrap #sei />
 +**''#169 $A9 SEI''**\\ Enable/disable interrupts. With interrupts off, INT will not
 +fire.
 +
 +<wrap #ssi />
 +**''#170 $AA SSI''**\\ Set the Sound Interrupt flag. Managed by the KERNAL;
 +semi-reserved and may be removed.
  
 <wrap #case /> <wrap #case />
Line 360: Line 487:
 <wrap #casetab /> <wrap #casetab />
 **''#202 $CA CASETAB base, selector, #limit''**\\ **''#202 $CA CASETAB base, selector, #limit''**\\
-Jump table held at a base address rather than inline. Indexes an address from the +Jump table held at a base address rather than inline. Indexes an address from the table at ''base'' by ''selector'', bounded by ''limit'', and dispatches to it.
-table at ''base'' by ''selector'', bounded by ''limit'', and dispatches to it. +
-//The precise indexing and out-of-bounds policy should be confirmed against the +
-current emulator handler: the older CASE3 (computed table at base) and CASEB +
-(scanned ''[selector][addr]'' table) were removed, and CASETAB is the surviving +
-table-at-base form.//+
  
 <wrap #cvtan /> <wrap #cvtan />
 **''#203 $CB CVTAN reg8''**\\ **''#203 $CB CVTAN reg8''**\\
-Convert ASCII to number. Maps '0'-'Z' to 0-35. Sets Overflow if the character is not +Convert ASCII to number. Maps '0'-'Z' to 0-35. Sets Overflow if the character is not a decimal digit (0-9) and Carry if it is not a hex digit (0-15). Also a fast digit test: ''MOV reg8, AL'' then ''CVTAN reg8'' lets you branch with JO/JNO (JV/JNV). Designed for zoned decimal, and works for zoned hex.
-a decimal digit (0-9) and Carry if it is not a hex digit (0-15). Also a fast digit +
-test: ''MOV reg8, AL'' then ''CVTAN reg8'' lets you branch with JO/JNO (JV/JNV). +
-Designed for zoned decimal, and works for zoned hex.+
  
 <wrap #cvtna /> <wrap #cvtna />
Line 378: Line 497:
 Convert number to ASCII, the inverse of CVTAN. Maps 0-35 to '0'-'Z'. Sets Overflow Convert number to ASCII, the inverse of CVTAN. Maps 0-35 to '0'-'Z'. Sets Overflow
 if outside 0-9 and Carry if outside 0-15. if outside 0-9 and Carry if outside 0-15.
- 
-<wrap #movx /> 
-**''#28 $1C MOVSX dst, src / #29 $1D MOVZX dst, src''**\\ 
-Move with sign-extend (MOVSX) or zero-extend (MOVZX). The source is read at its own 
-width and written across the full destination, with the high bytes filled from the 
-source's sign bit (MOVSX) or with zero (MOVZX). The destination **must be strictly 
-wider** than the source; this is checked at assemble time. Both fully define the 
-destination, so unlike a byte ALU op there is no partial-register hazard, and the 
-in-place overlapping case (''MOVSX A, AL'') is well defined. 
- 
-These exist to collapse the compiler's extend sequence: without a native 
-sign-extend, widening a signed ''char'' to ''int'' took three ops 
-(''AND''/''XOR''/''SUB'' implementing the ''(x ^ 0x80) - 0x80'' identity). MOVSX does 
-it in one. Integer promotion makes signed widening pervasive in C, so this is a 
-recurring code-size win. MOVZX similarly drops the masking immediate of an 
-''AND #$FF'' style zero-extend. 
  
 <wrap #idx /> <wrap #idx />
-**''#210 LD_IDXI / #211 LD_IDXR / #212 ST_IDXI / #213 ST_IDXR''**\\ +**''#210 LD_IDXI / #211 LD_IDXR / #212 ST_IDXI / #213 ST_IDXR''**\\ Indexed load/store: a 24-bit pointer register plus a displacement. The ''I'' forms take a signed byte immediate (-128..+127); the ''R'' forms take a register offset. These back the compiler's frame-slot and struct-field access (''[ptr + disp]''). The pointer base must be a 24-bit register; the effective address reads the base at its
-Indexed load/store: a 24-bit pointer register plus a displacement. The ''I'' forms +
-take a signed byte immediate (-128..+127); the ''R'' forms take a register offset. +
-These back the compiler's frame-slot and struct-field access (''[ptr + disp]''). The +
-pointer base must be a 24-bit register; the effective address reads the base at its+
 true width before applying the offset. true width before applying the offset.
  
Line 417: Line 516:
 in memory: in memory:
  
-<code+<codify armasm
-    LDFLX $F000       ; loop start +    LDFLX $F000       ; 8 byte loop data start 
-    LDA #1 +    LDA #1            ; start at 
-    STA [FLX] +    STA [FLX]         ; write starting counter at first four bytes 
-    LDA #1000 +    LDA #1000         ; go until 1000 
-    STA [FLX+4]+    STA [FLX+4]       ; write finish (until) counter at second four bytes
 loop: loop:
-    <body> +    LSTEPM            ; INC N1, if N1==N2 set Z=1
-    LSTEPM+
     JNZ @loop     JNZ @loop
-</code>+</codify> 
 + 
 +Unlike a DEC loop it counts upward and supports an arbitrary start. The generalized form of this is [[#lstep|LSTEP]] which counts downwards instead.
  
-Unlike a DEC loop it counts upward and supports an arbitrary start. It is a kludge +Only used by Forth. It is recommended to use LSTEP insteadthis instruction is a canidate for removal.
-for Forth and has been generalized by [[#lstep|LSTEP]]once Forth uses LSTEP, +
-LSTEPM is a candidate for removal.+
  
 <wrap #ttos /> <wrap #ttos />
Line 447: Line 545:
 inspired by the VAX SOB (subtract one and branch) and the 68000 DBcc. inspired by the VAX SOB (subtract one and branch) and the 68000 DBcc.
  
-<code>+<codify armasm>
     LDC #1000       ; loop range     LDC #1000       ; loop range
 loop: loop:
-    <body> 
     LSTEP C, @loop     LSTEP C, @loop
-</code>+</codify>
sd/isa.1781596052.txt.gz · Last modified: by appledog

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki