419 lines
11 KiB
Plaintext
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 |