; 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