.. sx2 microprogram v 1.0   14 July 2006
..
.s
x.ts
x.fp
x.nx
y.ff
y.arg
y.u
b.tbus
b.dbus
b.sp
d.fp
d.ts
d.v
d.u
a.tbus
a.pc
a.sp
a.fp
j.pc1
j.pcarg
j.tbus
so.sp
so.spx
si.inc
si.dec
si.k
si.tbus
w.v1
w.v2
w.v3
w.v4
w.varg
z.dbus
z.ts
t.v
t.pc
t.bus
u.iru
u.dbus
alu.add
alu.sub
alu.inc
alu.dec
alu.add2
alu.z
alu.eq
alu.op
alu.p1
alu.p2
.. load registers
lir
lts
lfp
lsp
lnx
lff
lpc
lv1
lv2
lv3
lv4
lvarg
lu
mR
mW
.. next micro ads
ifT
ifF
ifu0
ifp0
ifargm
skipu
decode
trap
.m
:fetch
..  mR(pc)->ir, dispatch
  a.pc mR lir decode ;
:bop
..  mR(sp)->ff
..  sp-1
..  alu(ts op ff)->ts, pc+1, fetch
  so.sp si.dec lsp a.sp mR b.dbus lff ;
  x.ts y.ff alu.op b.tbus t.bus lts j.pc1 lpc /fetch ;
:uop
..  alu(ts op ?)->ts, pc+1, fetch
  x.ts alu.op b.tbus t.bus lts j.pc1 lpc /fetch ;
:get
..  sp+1
..  ts->mW(sp)		; push ts
..  alu(fp-arg)->tbus, mR(tbus)->ts, pc+1, fetch
  so.spx si.inc lsp a.sp d.ts mW ;
  x.fp y.arg alu.sub a.tbus mR b.dbus t.bus lts j.pc1 lpc /fetch ;
:get1
..  push ts, v[arg]->ts
  so.spx si.inc lsp a.sp d.ts mW w.v1 t.v lts j.pc1 lpc /fetch ;
:get2
  so.spx si.inc lsp a.sp d.ts mW w.v2 t.v lts j.pc1 lpc /fetch ;
:get3
  so.spx si.inc lsp a.sp d.ts mW w.v3 t.v lts j.pc1 lpc /fetch ;
:get4
  so.spx si.inc lsp a.sp d.ts mW w.v4 t.v lts j.pc1 lpc /fetch ;
:put
..  alu(fp-arg)->tbus, ts->mW(tbus)
..  mR(sp)->ts		; pop ts
..  sp-1, pc+1, fetch
  x.fp y.arg alu.sub a.tbus d.ts mW ;
:popts
  so.sp si.dec lsp a.sp mR b.dbus t.bus lts j.pc1 lpc /fetch ;
:put1
..  ts->v[arg], pop ts
  z.ts lv1 so.sp si.dec lsp a.sp mR b.dbus t.bus lts j.pc1 lpc /fetch ;
:put2
  z.ts lv2 so.sp si.dec lsp a.sp mR b.dbus t.bus lts j.pc1 lpc /fetch ;
:put3
  z.ts lv3 so.sp si.dec lsp a.sp mR b.dbus t.bus lts j.pc1 lpc /fetch ;
:put4
  z.ts lv4 so.sp si.dec lsp a.sp mR b.dbus t.bus lts j.pc1 lpc /fetch ;
:ld
..  sp+1
..  ts->mW(sp)		; push ts
..  mR(arg)->ts, pc+1, fetch
  so.spx si.inc lsp a.sp d.ts mW ;
  y.arg alu.p2 a.tbus mR b.dbus t.bus lts j.pc1 lpc /fetch ;
:st
..  ts->mW(arg)
..  mR(sp)->ts		; pop ts
..  sp-1, pc+1, fetch
  d.ts y.arg alu.p2 a.tbus mW /popts ;
:ldx
..  mR(sp)->ff	 	; pop ads
..  sp-1
..  alu(ff+ts)->tbus, mR(tbus)->ts, pc+1, fetch
  so.sp si.dec lsp a.sp mR b.dbus lff ;
  x.ts y.ff alu.add a.tbus mR b.dbus t.bus lts j.pc1 lpc /fetch ;
:stx
..  mR(sp)->nx		; pop idx
..  sp-1
..  mR(sp)->ff		; pop ads
..  alu(nx+ff)->tbus, ts->mW(tbus)
..  sp-1
..  mR(sp)->ts		; pop ts
..  sp-1, pc+1, fetch
  so.sp si.dec lsp a.sp mR b.dbus lnx ;
  so.sp si.dec lsp a.sp mR b.dbus lff ;
  x.nx y.ff alu.add a.tbus d.ts mW /popts ;
:lit
..  sp+1
..  ts->mW(sp)		; push ts
..  arg->ts, pc+1, fetch
  so.spx si.inc lsp a.sp d.ts mW y.arg alu.p2 b.tbus t.bus lts j.pc1 lpc /fetch ;
:jmp
  j.pcarg lpc /fetch ;
:jt
..  alu(ts=0), ifTrue j3  ; if true, don't jump
  x.ts alu.z ifT /j3 ;
:j2
..  <jump>
..  pc+arg, mR(sp)->ts	; pop ts
..  sp-1, fetch
  j.pcarg lpc so.sp si.dec lsp a.sp mR b.dbus t.bus lts /fetch ;
:jf
..  alu(ts=0), ifTrue j2 ; if true,  jump
  x.ts alu.z ifT /j2 ;
:j3
..  <don't jump>
..  pc+1, mR(sp)->ts	; pop ts
..  sp-1, fetch
  j.pc1 lpc so.sp si.dec lsp a.sp mR b.dbus t.bus lts /fetch ;
:call
.. ; call, keep ret ads on ts
..  push ts, pc+1					; flush ts
..  pc->ts, arg->pc, if u=0 fetch	; save ret ads
.. <save v>
..    alu(fp-u)->fp, skipu
..    vn->mW(fp), fp+1->fp
..    ... repeat to v1, fetch
  so.spx si.inc lsp a.sp d.ts mW j.pc1 lpc ;
  t.pc lts y.arg alu.p2 j.tbus lpc ifu0 /fetch ;
.. <save v>
  x.fp y.u alu.sub b.tbus lfp skipu ;
  w.v4 a.fp d.v mW x.fp alu.inc b.tbus lfp ;
  w.v3 a.fp d.v mW x.fp alu.inc b.tbus lfp ;
  w.v2 a.fp d.v mW x.fp alu.inc b.tbus lfp ;
  w.v1 a.fp d.v mW x.fp alu.inc b.tbus lfp /fetch ;
:fun
..  ; fun.p.u.k
..  fp->mW(sp+k), sp+k->sp 		; save old fp, new sp
..  sp->fp						; new fp
..  sp+1, u->mW(sp), iru->u		; push u
..  pc+1, if p=0 fetch
.. <cache v>
..    alu(fp-u)->fp, skipu
..    mR(fp)->vn, fp+1->fp
..    ..  repeat to v1, fetch
  si.k lsp so.spx a.sp d.fp mW ;
  b.sp lfp ;
  si.inc so.spx lsp a.sp d.u mW u.iru lu ;
  j.pc1 lpc ifp0 /fetch ;
:cachev
  x.fp y.u alu.sub b.tbus lfp skipu ;
  a.fp mR z.dbus lv4 x.fp alu.inc b.tbus lfp ;
  a.fp mR z.dbus lv3 x.fp alu.inc b.tbus lfp ;
  a.fp mR z.dbus lv2 x.fp alu.inc b.tbus lfp ;
  a.fp mR z.dbus lv1 x.fp alu.inc b.tbus lfp /fetch ;
:ret
.. ; ret with retads on TS
.. ; retv with retads on frame
..  sp-1->ff
..  alu(fp=ff), ifFalse r2	; do retv
.. <doret>
..  ts->pc  			; do ret
..  mR(sp)->u			; pop u
..  alu(fp-arg)->sp
..  pop ts
..  mR(fp)->fp, if u=0 fetch ; restore fp
..  <cache v>, fetch
  si.dec so.spx b.sp lff ;
  x.fp y.ff alu.eq ifF /r2 ;
.. <doret>
  x.ts alu.p1 j.tbus lpc ;
  so.sp a.sp mR u.dbus lu ;
  x.fp y.arg alu.sub si.tbus lsp ;
  so.sp si.dec lsp a.sp mR b.dbus t.bus lts ifu0 /r3 ;
  a.fp mR b.dbus lfp /cachev ;
:r2
.. <doretv>
..  alu(fp+2)->tbus, mR(tbus)->ff ; ret ads
..  ff->pc
..  alu(fp+1)->tbus, mR(tbus)->u  ; pop u
..  alu(fp-arg)->sp, if u=0 r3 ; skip cachev
..  mR(fp)->fp cachev
  x.fp alu.add2 a.tbus mR b.dbus lff ;
  y.ff alu.p2 j.tbus lpc ;
  x.fp alu.inc a.tbus mR u.dbus lu ;
  x.fp y.arg alu.sub si.tbus lsp ifu0 /r3 ;
  a.fp mR b.dbus lfp /cachev ;
:r3
..  <ret end>
  a.fp mR b.dbus lfp /fetch ;
:inc
..  ts->nx, v[arg]->ts  if arg > maxv inc2
..  <update v>
..  alu(ts+1)->ts
..  ts->v[arg], nx->ts, pc+1, fetch
  x.ts alu.p1 b.tbus lnx w.varg t.v lts ifargm /inc2 ;
  x.ts alu.inc b.tbus t.bus lts ;
  z.ts lvarg x.nx alu.p1 b.tbus t.bus lts j.pc1 lpc /fetch ;
:inc2
..  <update SS>
..  alu(fp-arg)->tbus, mR(tbus)->ts
..  alu(ts+1)->ts
..  alu(fp-arg)->tbus, ts->mW(tbus)
..  nx->ts, pc+1, fetch
  x.fp y.arg alu.sub a.tbus mR b.dbus t.bus lts ;
  x.ts alu.inc b.tbus t.bus lts ;
  x.fp y.arg alu.sub a.tbus d.ts mW ;
  x.nx alu.p1 b.tbus t.bus lts j.pc1 lpc /fetch ;
:dec
..  ts->nx, v[arg]->ts  if arg > maxv inc2
..  <update v>
..  alu(ts-1)->ts
..  ts->v[arg], nx->ts, pc+1, fetch
  x.ts alu.p1 b.tbus lnx w.varg t.v lts ifargm /dec2 ;
  x.ts alu.dec b.tbus t.bus lts ;
  z.ts lvarg x.nx alu.p1 b.tbus t.bus lts j.pc1 lpc /fetch ;
:dec2
..  <update SS>
..  alu(fp-arg)->tbus, mR(tbus)->ts
..  alu(ts-1)->ts
..  alu(fp-arg)->tbus, ts->mW(tbus)
..  nx->ts, pc+1, fetch
  x.fp y.arg alu.sub a.tbus mR b.dbus t.bus lts ;
  x.ts alu.dec b.tbus t.bus lts ;
  x.fp y.arg alu.sub a.tbus d.ts mW ;
  x.nx alu.p1 b.tbus t.bus lts j.pc1 lpc /fetch ;
:sys
:array
:end
  trap j.pc1 lpc /fetch ;
..
.e
