.. sx microprogram v 1.0   10 July 2006
.. include  djnz            3 July 2011
..
.s
x.ts
x.fp
x.sp
x.nx
y.ff
y.arg
b.tbus
b.dbus
b.pc
d.fp
d.ts
a.tbus
a.pc
j.pc1
j.pcarg
j.tbus
alu.add
alu.sub
alu.inc
alu.dec
alu.z
alu.eq
alu.op
alu.p1
alu.p2
.. load registers
lir
lts
lfp
lsp
lnx
lff
lpc
mR
mW
.. next micro ads
ifT
ifF
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
  x.sp alu.p1 a.tbus mR b.dbus lff ;
  x.sp alu.dec b.tbus lsp ;
  x.ts y.ff alu.op b.tbus lts j.pc1 lpc /fetch ;
:uop
..  alu(ts op ?)->ts, pc+1, fetch
  x.ts alu.op b.tbus lts j.pc1 lpc /fetch ;
:get
..  sp+1
..  ts->mW(sp)		; push ts
..  alu(fp-arg)->tbus, mR(tbus)->ts, pc+1, fetch
  x.sp alu.inc b.tbus lsp ;
  d.ts x.sp alu.p1 a.tbus mW ;
  x.fp y.arg alu.sub a.tbus mR b.dbus 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
  x.sp alu.p1 a.tbus mR b.dbus lts ;
  x.sp alu.dec b.tbus lsp j.pc1 lpc /fetch ;
:ld
..  sp+1
..  ts->mW(sp)		; push ts
..  mR(arg)->ts, pc+1, fetch
  x.sp alu.inc b.tbus lsp ;
  d.ts x.sp alu.p1 a.tbus mW ;
  y.arg alu.p2 a.tbus mR b.dbus 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
  x.sp alu.p1 a.tbus mR b.dbus lff ;
  x.sp alu.dec b.tbus lsp ;
  x.ts y.ff alu.add a.tbus mR b.dbus 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
  x.sp alu.p1 a.tbus mR b.dbus lnx ;
  x.sp alu.dec b.tbus lsp ;
  x.sp alu.p1 a.tbus mR b.dbus lff ;
  x.nx y.ff alu.add a.tbus d.ts mW ;
  x.sp alu.dec b.tbus lsp /popts ;
:lit
..  sp+1
..  ts->mW(sp)		; push ts
..  arg->ts, pc+1, fetch
  x.sp alu.inc b.tbus lsp ;
  d.ts x.sp alu.p1 a.tbus mW ;
  y.arg alu.p2 b.tbus 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 x.sp alu.p1 a.tbus mR b.dbus lts ;
  x.sp alu.dec b.tbus lsp /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 x.sp alu.p1 a.tbus mR b.dbus lts ;
  x.sp alu.dec b.tbus lsp /fetch ;
:call
.. <call with ret ads on ts>
..  sp+1
..  ts->mW(sp), pc+1		; flush stack
..  pc->ts
..  arg->tbus->nx, mR(tbus)->ir	; fetch fun, nx=ads
..  alu(sp+arg)->tbus, fp->mW(tbus) ; save old fp
..  alu(sp+arg)->fp->sp	; new fp, sp
..  alu(nx+1)->pc, fetch
  x.sp alu.inc b.tbus lsp ;
  x.sp alu.p1 a.tbus d.ts mW j.pc1 lpc ;
  b.pc lts ;
  y.arg alu.p2 b.tbus lnx a.tbus mR lir ;
  x.sp y.arg alu.add a.tbus d.fp mW ;
  x.sp y.arg alu.add b.tbus lfp lsp ;
  x.nx alu.inc j.tbus lpc /fetch ;
:ret
.. <ret with retads on TS>
.. <retv with retads on frame>
..  sp->ff
..  alu(fp=ff), ifFalse r2	; do retv
..  ts->pc  			; do ret
..  alu(fp-arg)->sp
..  mR(sp)->ts			; pop ts
..  sp-1
..  mR(fp)->fp, fetch		; restore fp
  x.sp alu.p1 b.tbus lff ;
  x.fp y.ff alu.eq ifF /r2 ;
  x.ts alu.p1 j.tbus lpc ;
  x.fp y.arg alu.sub b.tbus lsp ;
  x.sp alu.p1 a.tbus mR b.dbus lts ;
  x.sp alu.dec b.tbus lsp ;
  x.fp alu.p1 a.tbus mR b.dbus lfp /fetch ;
:r2
..  alu(fp+1)->tbus, mR(tbus)->ff ; ret ads
..  ff->pc
..  alu(fp-arg)->sp
..  mR(fp)->fp, fetch
  x.fp alu.inc a.tbus mR b.dbus lff ;
  y.ff alu.p2 j.tbus lpc ;
  x.fp y.arg alu.sub b.tbus lsp ;
  x.fp alu.p1 a.tbus mR b.dbus lfp /fetch ;
:inc
..  ts->nx	; save ts
..  alu(fp-arg)->tbus, mR(tbus)->ts
..  alu(ts+1)->ts
..  alu(fp-arg)->tbus, ts->mW(tbus)
..  nx->ts, pc+1, fetch
  x.ts alu.p1 b.tbus lnx ;
  x.fp y.arg alu.sub a.tbus mR b.dbus lts ;
  x.ts alu.inc b.tbus lts ;
  x.fp y.arg alu.sub a.tbus d.ts mW ;
  x.nx alu.p1 b.tbus lts j.pc1 lpc /fetch ;
:dec
..  ; similar to inc but alu.dec at line 3
  x.ts alu.p1 b.tbus lnx ;
  x.fp y.arg alu.sub a.tbus mR b.dbus lts ;
  x.ts alu.dec b.tbus lts ;
  x.fp y.arg alu.sub a.tbus d.ts mW ;
  x.nx alu.p1 b.tbus lts j.pc1 lpc /fetch ;
:djnz
..  alu(ts,dec)->ts
..  alu(ts=0) ifTrue djnz2
..  pc+arg, fetch
  x.ts alu.dec b.tbus lts ;
  x.ts alu.z ifT /djnz2 ;
  j.pcarg lpc /fetch ;
:djnz2
..  mR(sp)->ts
..  sp-1, pc+1, fetch
  x.sp alu.p1 a.tbus mR b.dbus lts ;
  x.sp alu.dec lsp j.pc1 lpc /fetch ;
:sys
:array
:end
  trap j.pc1 lpc /fetch ;
..
.e


