Files
stack/ucode.src
2026-03-07 23:45:11 -05:00

419 lines
11 KiB
Plaintext

; Copyright (C) 2026 Paul Carver Harrison
microcode length 512
microcode width 36
microcode padding left
microcode target vhex
microcode output ucode.hex
mapping length 64
mapping target vhex
mapping output umap.hex
field md 1 0 read=0,write=1
field mssrc 1 0 ucode=0,rma=1
field ms 2 0 nop=0,word=1,hword=2,byte=3
field rwe 1 0
field rma 2 0 pcp=0,dsp=1,rsp=2,tmp=3
field rd 3 imm pcp=0,dsp=1,rsp=2,tmp=3,mdr=4,tos=5,acc=6,imm=7
field rs2 2 imm mdr=0,tos=1,acc=2,imm=3
field rs1 3 imm pcp=0,dsp=1,rsp=2,tmp=3,mdr=4,tos=5,acc=6,imm=7
field aluop 4 0 a,not,add,sub,sgt,slt,gt,lt,and,or,xor,lsl,asr,mul,sextb,sexth
field alusrc 1 0 ucode=0,rma=1
field cci 1 0
field cce 1 0
field seqsrc 1 0 imm=0,map=1
field seqop 2 0 step=0,jump=1,retn=2,call=3
field imm 9 0
sub fetch 000h
; fetch instruction and increment pcp. jump to instruction
rma=pcp,md=read,ms=byte
rwe,aluop=add,rd=pcp,rs1=pcp,imm=1,seqop=jump,seqsrc=map
end
sub aluop1
rwe,alusrc=rma,rd=tos,rs1=tos,rs2=tos,seqop=retn
end
sub aluop2
rwe,aluop=a,rd=tmp,rs1=mdr
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,alusrc=rma,rma=tmp,rd=tos,rs1=tos,rs2=mdr,seqop=retn
end
sub aluopi
rwe,aluop=a,rd=tmp,rs1=mdr
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,alusrc=rma,rma=tmp,rd=tos,rs1=tos,rs2=mdr,seqop=retn
end
sub pushdb
; *(++((word *)dsp)) = tos
rwe,aluop=add,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=dsp,md=write,ms=word
; tos = *pcp++
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub pushdhu
; *(++((word *)dsp)) = tos
rwe,aluop=add,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=dsp,md=write,ms=word
; read half-word into tos
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=lsl,rd=tos,rs1=mdr,imm=8
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=or,rd=tos,rs1=tos,rs2=mdr,seqop=retn
end
sub pushdwu
; *(++((word *)dsp)) = tos
rwe,aluop=add,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=dsp,md=write,ms=word
; read word into tos
; 0
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=lsl,rd=tos,rs1=mdr,imm=8
; 1
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=or,rd=tos,rs1=tos,rs2=mdr
rwe,aluop=lsl,rd=tos,rs1=mdr,imm=8
; 2
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=or,rd=tos,rs1=tos,rs2=mdr
rwe,aluop=lsl,rd=tos,rs1=mdr,imm=8
; 3
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=or,rd=tos,rs1=tos,rs2=mdr,seqop=retn
end
sub pushdha
seqop=retn
end
sub pushdwa
seqop=retn
end
sub swap
rma=dsp,md=read,ms=word
rd=acc,rs1=mdr,rwe,aluop=a
rd=mdr,rs1=tos,rwe,aluop=a
rma=dsp,md=write,ms=word
rd=tos,rs1=acc,rwe,aluop=a,seqop=retn
end
sub dup
rwe,aluop=add,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=dsp,md=write,ms=word,seqop=retn
end
sub drop
; tos = *(((word *)dsp)--)
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
; fetch word from memory and store on data stack
sub fetchdw
; tmp = tos
rwe,aluop=a,rd=tmp,rs1=tos
; mdr = *(word *)tmp
rma=tmp,md=read,ms=word
; tos = mdr
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
; fetch byte from memory and store on data stack
sub fetchdb
rwe,aluop=a,rd=tmp,rs1=tos
rma=tmp,md=read,ms=byte
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
; fetch word from memory and store on return stack
sub fetchrw
; mdr = *(word *)tos; rsp -= 4
rwe,aluop=a,rd=tmp,rs1=tos
rma=tmp,md=read,ms=word,rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
; push onto return stack
rma=rsp,md=write,ms=word
; pop off data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
; fetch byte from memory and store on return stack
sub fetchrb
; mdr = *(byte *)tos; rsp -= 4
rwe,aluop=a,rd=tmp,rs1=tos
rma=tmp,md=read,ms=byte,rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
; push onto return stack
rma=rsp,md=write,ms=word
; pop off data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub storedw
; mdr = *(word *)tos; dsp -= 4
rwe,aluop=a,rd=tmp,rs1=tos
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rma=tmp,md=write,ms=word
; pop off data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub storedb
; mdr = *(word *)tos; dsp -= 4
rwe,aluop=a,rd=tmp,rs1=tos
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rma=tmp,md=write,ms=byte
; pop off data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub rtod
; push TOS onto data stack
rwe,aluop=add,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=dsp,md=write,ms=word
; pop top of return stack into TOS
rma=rsp,md=read,ms=word,rwe,aluop=add,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub dtor
; push TOS onto return stack
rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=rsp,md=write,ms=word
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub pstoredw
seqop=retn
end
sub pstoredb
seqop=retn
end
sub jump
; transfer TOS to PCP
rwe,aluop=a,rd=pcp,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub jumpz
; ACC = NOS = value to check
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=acc,rs1=mdr
; TMP = TOS = branch address
rwe,aluop=a,rd=tmp,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr
; If not zero, next ISA instruction
aluop=a,rs1=acc,cce=1,cci=1,seqop=retn
; If zero, jump to address in TMP
rwe,aluop=a,rd=pcp,rs1=tmp,seqop=retn
end
sub jumpnz
; ACC = NOS = value to check
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=acc,rs1=mdr
; TMP = TOS = branch address
rwe,aluop=a,rd=tmp,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr
; If zero, next ISA instruction
aluop=a,rs1=acc,cce=1,cci=0,seqop=retn
; If not zero, jump to address in TMP
rwe,aluop=a,rd=pcp,rs1=tmp,seqop=retn
end
sub call
; push PCP onto return stack
rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=mdr,rs1=pcp
rma=rsp,md=write,ms=word
; PCP = TOS
rwe,aluop=a,rd=pcp,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub callz
; ACC = NOS = value to check
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=acc,rs1=mdr
; TMP = TOS = branch address
rwe,aluop=a,rd=tmp,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr
; If not zero, next ISA instruction
aluop=a,rs1=acc,cce=1,cci=1,seqop=retn
; push PCP onto return stack
rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=mdr,rs1=pcp
rma=rsp,md=write,ms=word
; If zero, jump to address in TMP
rwe,aluop=a,rd=pcp,rs1=tmp,seqop=retn
end
sub callnz
; ACC = NOS = value to check
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=acc,rs1=mdr
; TMP = TOS = branch address
rwe,aluop=a,rd=tmp,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr
; If zero, next ISA instruction
aluop=a,rs1=acc,cce=1,cci=0,seqop=retn
; push PCP onto return stack
rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=mdr,rs1=pcp
rma=rsp,md=write,ms=word
; If not zero, jump to address in TMP
rwe,aluop=a,rd=pcp,rs1=tmp,seqop=retn
end
sub ret
rma=rsp,md=read,ms=word,rwe,aluop=add,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=pcp,rs1=mdr,seqop=retn
end
sub retz
; ACC = TOS = value to check
rwe,aluop=a,rd=acc,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr
; If not zero, next ISA instruction
aluop=a,rs1=acc,cce=1,cci=1,seqop=retn
; return
rma=rsp,md=read,ms=word,rwe,aluop=add,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=pcp,rs1=mdr,seqop=retn
end
sub retnz
; ACC = TOS = value to check
rwe,aluop=a,rd=acc,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr
; If zero, next ISA instruction
aluop=a,rs1=acc,cce=1,cci=0,seqop=retn
; return
rma=rsp,md=read,ms=word,rwe,aluop=add,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=pcp,rs1=mdr,seqop=retn
end
sub over
rwe,aluop=add,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=dsp,md=write,ms=word,rwe,aluop=sub,rd=tmp,rs1=dsp,imm=4
rma=tmp,md=read,ms=word
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub repeatri
rma=rsp,md=read,ms=word
rwe,aluop=sub,rd=mdr,rs1=mdr,imm=1
aluop=a,rs1=mdr,cce,seqop=jump,imm=1E0h
rma=rsp,md=write,ms=word
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=sextb,rd=mdr,rs1=mdr
rwe,aluop=add,rd=pcp,rs1=pcp,rs2=mdr,seqop=retn
end
sub rot
seqop=call,imm=dtor
seqop=call,imm=swap
seqop=call,imm=rtod
seqop=call,imm=swap
seqop=retn
sub nop
seqop=retn
end
sub repeatri_ret 1EEh
rma=pcp,md=read,ms=byte,rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
rwe,aluop=add,rd=pcp,rs1=pcp,imm=1,seqop=retn
end
sub init 1F8h
; nop required on startup
imm=0
; data stack starts at 4000h and grows up
rwe,aluop=a,rd=dsp,imm=40h
rwe,aluop=lsl,rd=dsp,rs1=dsp,imm=8
; return stack starts at 4400h and grows down
rwe,aluop=a,rd=rsp,imm=44h
rwe,aluop=lsl,rd=rsp,rs1=rsp,imm=8
; init done
seqop=retn
end
map aluop1*4,aluop2*4,aluopi*4,swap,dup,drop,over,fetchdw,fetchdb,fetchrw,fetchrb,storedw,storedb,pstoredw,pstoredb,rtod,dtor,jump,jumpz,jumpnz,call,callz,callnz,ret,retz,retnz,pushdb,pushdhu,pushdwu,pushdha,pushdwa,repeatri