Hode Computer Instruction Set

  0 0 0 0 0 0 0 0 0 b b b 0 0 0 0   HALT Rb halt processor (wait for interrupt), display Rb contents
  0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0   IRET return from interrupt (PC = (FFFE); PS = (FFFC))
  0 0 0 0 0 0 0 0 0 b b b 0 1 0 0   WRPS Rb write processor status from Rb
  0 0 0 0 0 0 d d d 0 0 0 0 1 1 0   RDPS Rd read processor status into Rd
  0 0 0 0 0 0 x x x x x x x x x 1   BR .+2+2*x always branch
  0 0 0 0 0 1 x x x x x x x x x 0   BEQ .+2+2*x branch if equal (Z = 1)
  0 0 0 0 0 1 x x x x x x x x x 1   BNE .+2+2*x branch if not equal (Z = 0)
  0 0 0 0 1 0 x x x x x x x x x 0   BLT .+2+2*x branch if less than (N ^ V = 1)
  0 0 0 0 1 0 x x x x x x x x x 1   BGE .+2+2*x branch if greater than or equal to (N ^ V = 0)
  0 0 0 0 1 1 x x x x x x x x x 0   BLE .+2+2*x branch if less than or equal to (N ^ V | Z = 1)
  0 0 0 0 1 1 x x x x x x x x x 1   BGT .+2+2*x branch if greater than (N ^ V | Z = 0)
  0 0 0 1 0 0 x x x x x x x x x 0   BLO .+2+2*x branch if lower than (C = 1)
  0 0 0 1 0 0 x x x x x x x x x 1   BHIS .+2+2*x branch if higher than or same as (C = 0)
  0 0 0 1 0 1 x x x x x x x x x 0   BLOS .+2+2*x branch if lower than or same as (C | Z = 1)
  0 0 0 1 0 1 x x x x x x x x x 1   BHI .+2+2*x branch if higher than (C | Z = 0)
  0 0 0 1 1 0 x x x x x x x x x 0   BMI .+2+2*x branch if minus (N = 1)
  0 0 0 1 1 0 x x x x x x x x x 1   BPL .+2+2*x branch if plus (N = 0)
  0 0 0 1 1 1 x x x x x x x x x 0   BVS .+2+2*x branch if overflow (V = 1)
  0 0 0 1 1 1 x x x x x x x x x 1   BVC .+2+2*x branch if no overflow (V = 0)
  0 0 1 a a a d d d 0 0 0 0 0 0 0   LSR Rd,Ra logical shift right N Z V C   (Rd = Ra >>> 1)
  0 0 1 a a a d d d 0 0 0 0 0 0 1   ASR Rd,Ra arithmetic shift right N Z V C   (Rd = Ra >> 1)
  0 0 1 a a a d d d 0 0 0 0 0 1 0   CSR Rd,Ra carry shift (rotate) right N Z V C   (Rd = C:Ra >> 1)
  0 0 1 0 0 0 d d d b b b 0 1 0 0   MOV Rd,Rb move N Z 0 -   (Rd = Rb)
  0 0 1 0 0 0 d d d b b b 0 1 0 1   NEG Rd,Rb negate N Z V -   (Rd = - Rb)
  0 0 1 0 0 0 d d d b b b 0 1 1 0   INC Rd,Rb increment N Z V -   (Rd = Rb + 1)
  0 0 1 0 0 0 d d d b b b 0 1 1 1   COM Rd,Rb complement N Z 0 -   (Rd = ~ Rb)
  0 0 1 a a a d d d b b b 1 0 0 0   OR Rd,Ra,Rb or N Z 0 -   (Rd = Ra | Rb)
  0 0 1 a a a d d d b b b 1 0 0 1   AND Rd,Ra,Rb and N Z 0 -   (Rd = Ra & Rb)
  0 0 1 a a a d d d b b b 1 0 1 0   XOR Rd,Ra,Rb xor N Z 0 -   (Rd = Ra ^ Rb)
  0 0 1 a a a d d d b b b 1 1 0 0   ADD Rd,Ra,Rb add N Z V C   (Rd = Ra + Rb)
  0 0 1 a a a d d d b b b 1 1 0 1   SUB Rd,Ra,Rb subtract N Z V C   (Rd = Ra - Rb)
  0 0 1 a a a d d d b b b 1 1 1 0   ADC Rd,Ra,Rb add with carry N Z V C   (Rd = Ra + Rb + C)
  0 0 1 a a a d d d b b b 1 1 1 1   SBB Rd,Ra,Rb subtract with borrow N Z V C   (Rd = Ra - Rb - C)
  0 1 0 a a a d d d x x x x x x x   STW Rd,x(Ra) store word from Rd into memory x(Ra)
  0 1 1 a a a d d d x x x x x x x   STB Rd,x(Ra) store byte from Rd into memory x(Ra)
  1 0 0 a a a d d d x x x x x x x   LDA Rd,x(Ra) load address of x(Ra) into Rd
  1 0 1 a a a d d d x x x x x x x   LDBU Rd,x(Ra) load zero-extended byte from x(Ra) into Rd
  1 1 0 a a a d d d x x x x x x x   LDW Rd,x(Ra) load word from x(Ra) into Rd
  1 1 1 a a a d d d x x x x x x x   LDBS Rd,x(Ra) load sign-extended byte from x(Ra) into Rd

Registers: 8 16-bit registers R0..R7 (R7 is used as the program counter)

Arithmetic instructions (LSR,ASR,CSR,MOV,NEG,INC,COM,OR,AND,XOR,ADD,SUB,ADC,SBB) will not write R7 (PC) but always update condition codes as shown above. This allows using SUB to compare two registers without needing a scratch register for the result of the subtract. Likewise AND can be used for bit testing.

Load instruction (LDW,LDBU,LDBS not LDA) of memory operand 0(%R7) will increment R7 (PC) by 2 so it may be used as a load immediate instruction unless Rd is also R7.

To call a subroutine, do something like:

                    LDA %R5,2(%R7)  ; put return address in R5
                    BR  subroutine  ; branch to subroutine
                    ...             ; returns here
            
Or if a long jump is needed:
                    LDA %R5,4(%R7)  ; put return address in R5
                    LDW %R7,0(%R7)  ; jump to subroutine
                    .WORD subroutine
                    ...             ; returns here
            
The return is like this:
                subroutine:
                    ...
                    LDA %R7,0(%R5)  ; return to caller
            

Processor Status Word (PS):

  IE 1 1 1 1 1 1 1 1 1 1 1 N Z V C  

Other