add stack subroutines
This commit is contained in:
parent
c1fc5d6399
commit
8cfdea1004
@ -45,7 +45,6 @@ local function decodeNumber(n)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function mnemFromLine(line, instrs, validWords)
|
local function mnemFromLine(line, instrs, validWords)
|
||||||
local firstWord = line:match("^[^ ]+")
|
|
||||||
local imms = {}
|
local imms = {}
|
||||||
local function addNum(n)
|
local function addNum(n)
|
||||||
n = trim(n)
|
n = trim(n)
|
||||||
@ -83,7 +82,7 @@ local function mnemFromLine(line, instrs, validWords)
|
|||||||
end
|
end
|
||||||
local function addByte(state, val, code)
|
local function addByte(state, val, code)
|
||||||
assert(val>=-128 and val<=255, "invalid byte "..val)
|
assert(val>=-128 and val<=255, "invalid byte "..val)
|
||||||
assert(state.memory[state.curAddr]==nil, "overwriting memory at "..state.curAddr)
|
assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr))
|
||||||
state.memory[state.curAddr] = val%256
|
state.memory[state.curAddr] = val%256
|
||||||
if code then state.codeMap[state.curAddr] = true end
|
if code then state.codeMap[state.curAddr] = true end
|
||||||
state.curAddr = state.curAddr + 1
|
state.curAddr = state.curAddr + 1
|
||||||
@ -95,7 +94,7 @@ local function addWord(state, val, code)
|
|||||||
end
|
end
|
||||||
local function addSpace(state, len)
|
local function addSpace(state, len)
|
||||||
for i = 1, len do
|
for i = 1, len do
|
||||||
assert(state.memory[state.curAddr]==nil, "overwriting memory at "..state.curAddr)
|
assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr))
|
||||||
state.memory[state.curAddr] = false
|
state.memory[state.curAddr] = false
|
||||||
state.curAddr = state.curAddr + 1
|
state.curAddr = state.curAddr + 1
|
||||||
end
|
end
|
||||||
@ -460,12 +459,11 @@ local function toSigned8(x) return x>=128 and x-256 or x end
|
|||||||
local function disassembleMemory(mem, code, arch)
|
local function disassembleMemory(mem, code, arch)
|
||||||
print("Disassembly:")
|
print("Disassembly:")
|
||||||
local mnems = mnemsFromArch(arch)
|
local mnems = mnemsFromArch(arch)
|
||||||
|
|
||||||
local addr = 0
|
local addr = 0
|
||||||
local function nextByte(d) local b = mem[addr]; addr = addr+1; return b or d; end
|
local function nextByte(d) local b = mem[addr]; addr = addr+1; return b or d; end
|
||||||
local lastaddr = 0
|
local lastaddr = 0
|
||||||
local jmpaddrs = {}
|
local jmpaddrs = {}
|
||||||
local labelnum = 0
|
|
||||||
local subnum = 0
|
|
||||||
while addr<=0xFFFF do
|
while addr<=0xFFFF do
|
||||||
local startaddr = addr
|
local startaddr = addr
|
||||||
local opcode = nextByte()
|
local opcode = nextByte()
|
||||||
@ -479,13 +477,10 @@ local function disassembleMemory(mem, code, arch)
|
|||||||
end
|
end
|
||||||
if jmpdest then
|
if jmpdest then
|
||||||
if not jmpaddrs[jmpdest] then
|
if not jmpaddrs[jmpdest] then
|
||||||
jmpaddrs[jmpdest] = {
|
jmpaddrs[jmpdest] = { rel = mnem.rel, from = {}, }
|
||||||
name = (mnem.rel and "label_"..labelnum or "subroutine_"..subnum),
|
|
||||||
from = {},
|
|
||||||
}
|
|
||||||
if mnem.rel then labelnum = labelnum+1 else subnum = subnum+1 end
|
|
||||||
end
|
end
|
||||||
table.insert(jmpaddrs[jmpdest].from, startaddr)
|
table.insert(jmpaddrs[jmpdest].from, startaddr)
|
||||||
|
jmpaddrs[jmpdest].rel = jmpaddrs[jmpdest].rel and mnem.rel
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
addr = addr + mnem.len - 1
|
addr = addr + mnem.len - 1
|
||||||
@ -493,6 +488,12 @@ local function disassembleMemory(mem, code, arch)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
local labelnum, subnum = 0, 0
|
||||||
|
for _, jmp in pairs(jmpaddrs) do
|
||||||
|
if jmp.rel then jmp.name = "label_" ..labelnum; labelnum = labelnum+1;
|
||||||
|
else jmp.name = "subroutine_"..subnum ; subnum = subnum +1; end
|
||||||
|
end
|
||||||
|
|
||||||
addr = 0
|
addr = 0
|
||||||
while addr<=0xFFFF do
|
while addr<=0xFFFF do
|
||||||
local startaddr = addr
|
local startaddr = addr
|
||||||
|
@ -113,10 +113,14 @@ sbc a 4F 1 C-=A, set flags
|
|||||||
Jumps (J):
|
Jumps (J):
|
||||||
jmp imm16 60 3 I=imm16
|
jmp imm16 60 3 I=imm16
|
||||||
jsr imm16 63 3 I=imm16, Q=I
|
jsr imm16 63 3 I=imm16, Q=I
|
||||||
|
jss imm16 E2 5 I=imm16, *(S++++)=I-1
|
||||||
jmp p 64 1 I=P
|
jmp p 64 1 I=P
|
||||||
jsr p 65 1 I=P, Q=I
|
|
||||||
jmp q 66 1 I=Q
|
jmp q 66 1 I=Q
|
||||||
|
jsr p 65 1 I=P, Q=I
|
||||||
jsr q 67 1 I=Q, Q=I
|
jsr q 67 1 I=Q, Q=I
|
||||||
|
jss p E4 3 I=P, *(S++++)=I-1
|
||||||
|
jss q E5 3 I=Q, *(S++++)=I-1
|
||||||
|
rts E1 3 I=*(----S)+1
|
||||||
jpr imm8 31 2 I+=imm8
|
jpr imm8 31 2 I+=imm8
|
||||||
jnz imm8 30 2 I+=imm8 if !Zero
|
jnz imm8 30 2 I+=imm8 if !Zero
|
||||||
jpz imm8 32 2 I+=imm8 if Zero
|
jpz imm8 32 2 I+=imm8 if Zero
|
||||||
@ -137,7 +141,7 @@ pop c 48 2 C=*(--S)
|
|||||||
pop p 43 3 P=*(----S)
|
pop p 43 3 P=*(----S)
|
||||||
pop q 49 3 Q=*(----S)
|
pop q 49 3 Q=*(----S)
|
||||||
psh imm8 3B 3 *(S++)=imm8
|
psh imm8 3B 3 *(S++)=imm8
|
||||||
psh imm16 3C 5 *(S++++)=imm16
|
phw imm16 3C 5 *(S++++)=imm16
|
||||||
|
|
||||||
8-bit Load/Store (B):
|
8-bit Load/Store (B):
|
||||||
lda imm8 20 2 A=imm8, update zero flag
|
lda imm8 20 2 A=imm8, update zero flag
|
||||||
@ -229,7 +233,7 @@ ldq p 8E 1 Q=P
|
|||||||
lds p 8F 1 S=P
|
lds p 8F 1 S=P
|
||||||
ldv p 90 1 V=P
|
ldv p 90 1 V=P
|
||||||
|
|
||||||
Opcodes used: 216/255
|
Opcodes used: 221/255
|
||||||
0123456789ABCDEF
|
0123456789ABCDEF
|
||||||
00 | C---------------
|
00 | C---------------
|
||||||
10 | UUIIUIIUUUUUUUUU
|
10 | UUIIUIIUUUUUUUUU
|
||||||
@ -245,5 +249,5 @@ A0 | AAAAAAAAAAAAAAAA
|
|||||||
B0 | AAAAAAAAAAAAAAAA
|
B0 | AAAAAAAAAAAAAAAA
|
||||||
C0 | BBBBBBBBBBBBWWWW
|
C0 | BBBBBBBBBBBBWWWW
|
||||||
D0 | AAAAAAAAAAAAAAAA
|
D0 | AAAAAAAAAAAAAAAA
|
||||||
E0 | M---------------
|
E0 | MJJJJJ----------
|
||||||
F0 | CCCCC----------C
|
F0 | CCCCC----------C
|
||||||
|
@ -17,7 +17,7 @@ roms = {
|
|||||||
} },
|
} },
|
||||||
{ pos = {-34, 16, 17}, size = {32, 32, 32}, signals = {
|
{ pos = {-34, 16, 17}, size = {32, 32, 32}, signals = {
|
||||||
"_", "_", "_", "_", "_", "_", "_", "_",
|
"_", "_", "_", "_", "_", "_", "_", "_",
|
||||||
"_", "_", "memSaveNZ", "instrPre", "instrLoadPre", "always1", "instrLoad", "adrOut",
|
"_", "_", "memSaveNZ", "instrPre", "instrLoadPre", "always1", "instrLoadSel", "adrOut",
|
||||||
"memWriteAlur", "memSave", "instrNext0NZ", "instrNext0Z", "instrNext0NC", "instrNext0C", "instrLoadSub", "instrLoad",
|
"memWriteAlur", "memSave", "instrNext0NZ", "instrNext0Z", "instrNext0NC", "instrNext0C", "instrLoadSub", "instrLoad",
|
||||||
"instrNext2", "instrNext1", "instrNext0", "memSaveU", "memSaveT", "memSaveC", "memSaveB", "memSaveA",
|
"instrNext2", "instrNext1", "instrNext0", "memSaveU", "memSaveT", "memSaveC", "memSaveB", "memSaveA",
|
||||||
} },
|
} },
|
||||||
@ -42,10 +42,10 @@ operations = {
|
|||||||
instrSub7 = {"base","instrLoadSub","instrNext2","instrNext1","instrNext0"},
|
instrSub7 = {"base","instrLoadSub","instrNext2","instrNext1","instrNext0"},
|
||||||
instrSub23Cond = {"base","instrLoadSub","instrNext1"},
|
instrSub23Cond = {"base","instrLoadSub","instrNext1"},
|
||||||
instrSwapIV = {"base","adwlI","adwSaveV","adrlV","adrSaveI","loadInstr"},
|
instrSwapIV = {"base","adwlI","adwSaveV","adrlV","adrSaveI","loadInstr"},
|
||||||
instrPreload = {"adrlI","adrInc","adrSaveI","adrOut","memRead","instrLoadPre"},
|
instrPreload = {"adrlI","adrInc","adrSaveI","adrOut","memRead","instrLoadSel","instrLoadPre"},
|
||||||
instrNextPre = {"base","instrPre","instrLoad","instrLoadSub"},
|
instrNextPre = {"base","instrPre","instrLoad","instrLoadSub"},
|
||||||
|
|
||||||
loadInstr = {"adrOut","memRead","instrLoad","instrLoadSub"},
|
loadInstr = {"adrOut","memRead","instrLoadSel","instrLoad","instrLoadSub"},
|
||||||
loadReg = {"adrOut","memRead","memSave"},
|
loadReg = {"adrOut","memRead","memSave"},
|
||||||
storeReg = {"adrOut","memWrite","memWriteAlur"},
|
storeReg = {"adrOut","memWrite","memWriteAlur"},
|
||||||
loadRegT = {"loadReg","memSaveT"},
|
loadRegT = {"loadReg","memSaveT"},
|
||||||
@ -67,7 +67,7 @@ operations = {
|
|||||||
storeStackRel = {"adrlS","adrrTX","storeReg"},
|
storeStackRel = {"adrlS","adrrTX","storeReg"},
|
||||||
storeStackRel161 = {"storeStackRel" },
|
storeStackRel161 = {"storeStackRel" },
|
||||||
storeStackRel162 = {"storeStackRel","adrInc"},
|
storeStackRel162 = {"storeStackRel","adrInc"},
|
||||||
storeStackRelU = {"adrlS","adrrTX","storeReg","alurU"},
|
storeStackRelU = {"storeStackRel","alurU"},
|
||||||
load161 = { "loadReg","memSaveU"},
|
load161 = { "loadReg","memSaveU"},
|
||||||
load162 = {"adrInc","loadReg","memSaveT"},
|
load162 = {"adrInc","loadReg","memSaveT"},
|
||||||
store161 = { "storeReg"},
|
store161 = { "storeReg"},
|
||||||
@ -94,6 +94,8 @@ operations = {
|
|||||||
jmpAbsP = {"jmpAbs","adrlP"},
|
jmpAbsP = {"jmpAbs","adrlP"},
|
||||||
jmpAbsQ = {"jmpAbs","adrlQ"},
|
jmpAbsQ = {"jmpAbs","adrlQ"},
|
||||||
saveRetAddr = {"adwlI","adwInc","adwSaveQ"},
|
saveRetAddr = {"adwlI","adwInc","adwSaveQ"},
|
||||||
|
pushRetAddr1 = {"alurIH","pushReg"},
|
||||||
|
pushRetAddr2 = {"alurIL","pushReg"},
|
||||||
|
|
||||||
aluA = {"alulA","aluSaveA"},
|
aluA = {"alulA","aluSaveA"},
|
||||||
aluB = {"alulB","aluSaveB"},
|
aluB = {"alulB","aluSaveB"},
|
||||||
@ -109,19 +111,26 @@ operations = {
|
|||||||
aluOpXor = {"aluRun","aluXor" , "aluSaveNZ"},
|
aluOpXor = {"aluRun","aluXor" , "aluSaveNZ"},
|
||||||
aluOpAnn = {"aluRun","aluAnd","aluRInv", "aluSaveNZ"},
|
aluOpAnn = {"aluRun","aluAnd","aluRInv", "aluSaveNZ"},
|
||||||
aluOpCmp = {"aluOpSub"},
|
aluOpCmp = {"aluOpSub"},
|
||||||
aluOpInc = {"aluOpAdd", "aluCinOn"},
|
aluOpInc = {"aluOpAdd","aluCinOn"},
|
||||||
aluOpDec = {"aluOpAdd","aluRInv","aluCinOn"},
|
aluOpDec = {"aluOpAdd","aluRInv"},
|
||||||
aluOpMov = {"aluAdd","aluSaveNZ"},
|
aluOpMov = {"aluAdd","aluSaveNZ"},
|
||||||
aluOpShl = {"aluShift" ,"aluSaveNZ"},
|
aluOpShl = {"aluShift" ,"aluSaveNZ"},
|
||||||
aluOpShr = {"aluShift","aluShiftRight" ,"aluSaveNZ"},
|
aluOpShr = {"aluShift","aluShiftRight" ,"aluSaveNZ"},
|
||||||
aluOpRol = {"aluShift", "aluShiftRoll" ,"aluSaveNZ"},
|
aluOpRol = {"aluShift", "aluShiftRoll" ,"aluSaveNZ"},
|
||||||
aluOpRor = {"aluShift","aluShiftRight","aluShiftRoll" ,"aluSaveNZ"},
|
aluOpRor = {"aluShift","aluShiftRight","aluShiftRoll" ,"aluSaveNZ"},
|
||||||
aluOpSra = {"aluShift","aluShiftRight", "aluShiftArith","aluSaveNZ"},
|
aluOpSra = {"aluShift","aluShiftRight", "aluShiftArith","aluSaveNZ"},
|
||||||
|
|
||||||
|
clearRegs = {
|
||||||
|
"aluSaveA","aluSaveB","aluSaveC","aluSaveU","aluSaveT",
|
||||||
|
"adwSaveP","adwSaveQ","adwSaveS","adwSaveV",
|
||||||
|
"adrSaveI",
|
||||||
|
"aluSaveNZ","aluSaveCarry",
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
instructions = {
|
instructions = {
|
||||||
{ category = "Control", catlet="C" },
|
{ category = "Control", catlet="C" },
|
||||||
{ mnem="rst" , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","adrSaveI","aluSaveA","aluSaveB","aluSaveC","aluSaveU","aluSaveT","adwSaveP","adwSaveQ","adwSaveS","adwSaveV","loadInstr"}, desc="Clear all registers and set I=0" },
|
{ mnem="rst" , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","clearRegs","loadInstr"}, desc="Clear all registers and set I=0" },
|
||||||
{ mnem="hlt" , opcode=0xF0, {"runFlgClk","instrNext"}, desc="Halt non-interrupt execution" },
|
{ mnem="hlt" , opcode=0xF0, {"runFlgClk","instrNext"}, desc="Halt non-interrupt execution" },
|
||||||
{ mnem="run" , opcode=0xF1, {"runFlgClk","runFlgVal","instrNext"}, desc ="Resume non-interrupt execution" },
|
{ mnem="run" , opcode=0xF1, {"runFlgClk","runFlgVal","instrNext"}, desc ="Resume non-interrupt execution" },
|
||||||
{ mnem="int" , opcode=0xF2, {"instrSwapIV","intFlgVal","intFlgClk","irqFlgClk"}, },
|
{ mnem="int" , opcode=0xF2, {"instrSwapIV","intFlgVal","intFlgClk","irqFlgClk"}, },
|
||||||
@ -235,10 +244,14 @@ instructions = {
|
|||||||
{ category = "Jumps", catlet="J" },
|
{ category = "Jumps", catlet="J" },
|
||||||
{ mnem="jmp imm16" , opcode=0x60, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT" }, desc="I=imm16" },
|
{ mnem="jmp imm16" , opcode=0x60, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT" }, desc="I=imm16" },
|
||||||
{ mnem="jsr imm16" , opcode=0x63, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT","saveRetAddr"}, desc="I=imm16, Q=I" },
|
{ mnem="jsr imm16" , opcode=0x63, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT","saveRetAddr"}, desc="I=imm16, Q=I" },
|
||||||
{ mnem="jmp p" , opcode=0x64, jmp=true, {"jmpAbsP" }, desc="I=P" },
|
{ mnem="jss imm16" , opcode=0xE2, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushRetAddr1","instrSub3"}, {"pushRetAddr2","instrSub4"}, {"jmpAbsUT"}, desc="I=imm16, *(S++++)=I-1" },
|
||||||
{ mnem="jsr p" , opcode=0x65, jmp=true, {"jmpAbsP","saveRetAddr"}, desc="I=P, Q=I" },
|
{ mnem="jmp p" , opcode=0x64, {"jmpAbsP" }, desc="I=P" },
|
||||||
{ mnem="jmp q" , opcode=0x66, jmp=true, {"jmpAbsQ" }, desc="I=Q" },
|
{ mnem="jmp q" , opcode=0x66, {"jmpAbsQ" }, desc="I=Q" },
|
||||||
{ mnem="jsr q" , opcode=0x67, jmp=true, {"jmpAbsQ","saveRetAddr"}, desc="I=Q, Q=I" },
|
{ mnem="jsr p" , opcode=0x65, {"jmpAbsP","saveRetAddr"}, desc="I=P, Q=I" },
|
||||||
|
{ mnem="jsr q" , opcode=0x67, {"jmpAbsQ","saveRetAddr"}, desc="I=Q, Q=I" },
|
||||||
|
{ mnem="jss p" , opcode=0xE4, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsP"}, desc="I=P, *(S++++)=I-1" },
|
||||||
|
{ mnem="jss q" , opcode=0xE5, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsQ"}, desc="I=Q, *(S++++)=I-1" },
|
||||||
|
{ mnem="rts" , opcode=0xE1, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"jmpAbsUT","adrInc"}, desc="I=*(----S)+1" },
|
||||||
{ mnem="jpr imm8" , opcode=0x31, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub1"}, {"jmpRelT"}, desc="I+=imm8" },
|
{ mnem="jpr imm8" , opcode=0x31, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub1"}, {"jmpRelT"}, desc="I+=imm8" },
|
||||||
{ mnem="jnz imm8" , opcode=0x30, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NZ" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Zero" },
|
{ mnem="jnz imm8" , opcode=0x30, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NZ" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Zero" },
|
||||||
{ mnem="jpz imm8" , opcode=0x32, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0Z" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero" },
|
{ mnem="jpz imm8" , opcode=0x32, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0Z" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero" },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user