;; s2 simulator in asm

.symbol
  PC    1000
  IR    1001
  M     10000
  R     1100
  OP    1002
  IRR1  1003
  IRR2  1004
  IRR3  1005
  XOP   1006
  DISP  1007
  ADS   1008
  _ADD  10
  _TRAP 19
  c22   4194303  ;; 0x03fffff 22 bits
  c17   131071   ;; 0x01ffff  17 bits
  bit16 65536    ;; 0x010000  bit 16

.code 0
:eval
  ld r1 PC
  ld r2 @M r1
  st IR r2         ;; IR = M[PC]
  add r1 r1 #1
  st PC r1         ;; PC++
  jal r31 decode
  ld r1 OP
  eq r3 r1 #31
  jf r3 next       ;; not xop
  ld r1 XOP
  eq r3 r1 #_ADD
  jt r3 doAdd
  ;; other xop
  jmp eval
:next
  eq r3 r1 #_TRAP
  jt r3 exit
  ;; other op
  jmp eval
:exit
  trap 0

:doAdd
  ld r1 IRR2
  ld r2 @R r1      ;; R[r2]
  ld r1 IRR3
  ld r3 @R r1      ;; R[r3]
  add r2 r2 r3
  ld r4 IRR1
  st @R r4 r2      ;; R[r1] = R[r2]+R[r3]
  jmp eval

:decode
  ld r1 IR
  and r2 r1 #4095  ;; bit 11..0
  st XOP r2
  shr r2 r1 #12
  and r2 r2 #31    ;; 5 bits
  st IRR3 r2       ;; bit 16..13
  shr r2 r1 #17
  and r2 r2 #31
  st IRR2 r2       ;; bit 21..17
  shr r2 r1 #22
  and r2 r2 #31
  st IRR1 r2       ;; bit 27..23
  mv r2 #c22
  and r2 r1 r2
  st ADS r2        ;; bit 21..0
  and r2 r1 #c17
  and r3 r1 #bit16 ;; sign extension
  jf r3 skip
  mv r1 #32767     ;; 15 bits of 1
  shl r1 r1 #17
  or r2 r2 r1
:skip
  st DISP r2
  ret r31
.end
