more emulator features, sub # instr
This commit is contained in:
parent
4ae98df548
commit
6de62423e8
@ -65,7 +65,9 @@ local instructions = {
|
|||||||
{ mnem="ADD #" , opcode=0x6B, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="Add %imm8 to %A, %flags" , ccode={"loadimmedt","addf(cpu.a,cpu.t); lni;"} },
|
{ mnem="ADD #" , opcode=0x6B, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="Add %imm8 to %A, %flags" , ccode={"loadimmedt","addf(cpu.a,cpu.t); lni;"} },
|
||||||
-- { mnem="ADB #" , opcode=0x , {"loadImmedT","instrSub1"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="" , ccode={"loadimmedt","addf(cpu.b,cpu.t); lni;"} },
|
-- { mnem="ADB #" , opcode=0x , {"loadImmedT","instrSub1"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="" , ccode={"loadimmedt","addf(cpu.b,cpu.t); lni;"} },
|
||||||
-- { mnem="ADC #" , opcode=0x , {"loadImmedT","instrSub1"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="" , ccode={"loadimmedt","addf(cpu.c,cpu.t); lni;"} },
|
-- { mnem="ADC #" , opcode=0x , {"loadImmedT","instrSub1"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="" , ccode={"loadimmedt","addf(cpu.c,cpu.t); lni;"} },
|
||||||
|
{ mnem="SUB #" , opcode=0xEB, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="Subtract %imm8 from %A, %flags" , ccode={"loadimmedt","subf(cpu.a,cpu.t); lni;"} },
|
||||||
{ mnem="ADC #" , opcode=0x69, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="Add %imm8 plus the Carry Flag to %A, %flags" , ccode={"loadimmedt","addf(cpu.a,cpu.t+cpu.cf); lni;"} },
|
{ mnem="ADC #" , opcode=0x69, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="Add %imm8 plus the Carry Flag to %A, %flags" , ccode={"loadimmedt","addf(cpu.a,cpu.t+cpu.cf); lni;"} },
|
||||||
|
{ mnem="SBC #" , opcode=0xE9, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="Subtract %imm8 from %A including the Carry Flag, %flags" , ccode={"loadimmedt","addf(cpu.a,~cpu.t+cpu.cf); lni;"} },
|
||||||
{ mnem="CMP #" , opcode=0xC9, {"loadImmedT","instrSub1"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="%cmp %imm8 from %A" , ccode={"loadimmedt","cmpf(cpu.a,cpu.t); lni;"} },
|
{ mnem="CMP #" , opcode=0xC9, {"loadImmedT","instrSub1"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="%cmp %imm8 from %A" , ccode={"loadimmedt","cmpf(cpu.a,cpu.t); lni;"} },
|
||||||
{ mnem="AND #" , opcode=0x29, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="Bitwise AND %A with %imm8, %zflag" , ccode={"loadimmedt","cpu.a&=cpu.t; setzf(cpu.a); lni;"} },
|
{ mnem="AND #" , opcode=0x29, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="Bitwise AND %A with %imm8, %zflag" , ccode={"loadimmedt","cpu.a&=cpu.t; setzf(cpu.a); lni;"} },
|
||||||
{ mnem="ORA #" , opcode=0x09, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="Bitwise OR %A with %imm8, %zflag" , ccode={"loadimmedt","cpu.a|=cpu.t; setzf(cpu.a); lni;"} },
|
{ mnem="ORA #" , opcode=0x09, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="Bitwise OR %A with %imm8, %zflag" , ccode={"loadimmedt","cpu.a|=cpu.t; setzf(cpu.a); lni;"} },
|
||||||
@ -82,7 +84,7 @@ local instructions = {
|
|||||||
-- { mnem="sbb zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.b,cpu.u); lni;"} },
|
-- { mnem="sbb zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.b,cpu.u); lni;"} },
|
||||||
-- { mnem="sbc zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.c,cpu.u); lni;"} },
|
-- { mnem="sbc zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.c,cpu.u); lni;"} },
|
||||||
{ mnem="ADC zpg" , opcode=0x65, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="Add %zpgIn plus the Carry Flag to %A, %flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u+cpu.cf); lni;"} },
|
{ mnem="ADC zpg" , opcode=0x65, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="Add %zpgIn plus the Carry Flag to %A, %flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u+cpu.cf); lni;"} },
|
||||||
{ mnem="SBC zpg" , opcode=0xE5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="Subtract %zpgIn from %A including the Carry Flag, %flags", ccode={"loadimmedt","loadstackrelu","addf(cpu.a,-cpu.u+cpu.cf); lni;"} },
|
{ mnem="SBC zpg" , opcode=0xE5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="Subtract %zpgIn from %A including the Carry Flag, %flags", ccode={"loadimmedt","loadstackrelu","addf(cpu.a,~cpu.u+cpu.cf); lni;"} },
|
||||||
{ mnem="CMP zpg" , opcode=0xC5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="%cmp %zpgIn from %A" , ccode={"loadimmedt","loadstackrelu","cmpf(cpu.a,cpu.u); lni;"} },
|
{ mnem="CMP zpg" , opcode=0xC5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="%cmp %zpgIn from %A" , ccode={"loadimmedt","loadstackrelu","cmpf(cpu.a,cpu.u); lni;"} },
|
||||||
{ mnem="AND zpg" , opcode=0x25, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="Bitwise AND %A with %zpgIn, %flags" , ccode={"loadimmedt","loadstackrelu","cpu.a&=cpu.u; setzf(cpu.a); lni;"} },
|
{ mnem="AND zpg" , opcode=0x25, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="Bitwise AND %A with %zpgIn, %flags" , ccode={"loadimmedt","loadstackrelu","cpu.a&=cpu.u; setzf(cpu.a); lni;"} },
|
||||||
{ mnem="ORA zpg" , opcode=0x05, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="Bitwise OR %A with %zpgIn, %flags" , ccode={"loadimmedt","loadstackrelu","cpu.a|=cpu.u; setzf(cpu.a); lni;"} },
|
{ mnem="ORA zpg" , opcode=0x05, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="Bitwise OR %A with %zpgIn, %flags" , ccode={"loadimmedt","loadstackrelu","cpu.a|=cpu.u; setzf(cpu.a); lni;"} },
|
||||||
@ -112,7 +114,7 @@ local instructions = {
|
|||||||
{ mnem="SUB C" , opcode=0xFB, {"aluA", "alurC","aluOpSub" ,"instrNext"}, desc="Subtract %C from %A, %flags" , ccode={"subf(cpu.a,cpu.c); lni;"} },
|
{ mnem="SUB C" , opcode=0xFB, {"aluA", "alurC","aluOpSub" ,"instrNext"}, desc="Subtract %C from %A, %flags" , ccode={"subf(cpu.a,cpu.c); lni;"} },
|
||||||
-- { mnem="sbb C" , opcode=0x , {"aluB", "alurC","aluOpSub" ,"instrNext"}, desc="B-=C, set flags" , ccode={"subf(cpu.b,cpu.c); lni;"} },
|
-- { mnem="sbb C" , opcode=0x , {"aluB", "alurC","aluOpSub" ,"instrNext"}, desc="B-=C, set flags" , ccode={"subf(cpu.b,cpu.c); lni;"} },
|
||||||
{ mnem="ADC C" , opcode=0x79, {"aluA", "alurC","aluOpAddC","instrNext"}, desc="Add %C plus the Carry Flag to %A, %flags" , ccode={"addf(cpu.a,cpu.c+cpu.cf); lni;"} },
|
{ mnem="ADC C" , opcode=0x79, {"aluA", "alurC","aluOpAddC","instrNext"}, desc="Add %C plus the Carry Flag to %A, %flags" , ccode={"addf(cpu.a,cpu.c+cpu.cf); lni;"} },
|
||||||
{ mnem="SBC C" , opcode=0xF9, {"aluA", "alurC","aluOpSubC","instrNext"}, desc="Subtract %C form %A including the Carry Flag, %flags" , ccode={"addf(cpu.a,-cpu.c+cpu.cf); lni;"} },
|
{ mnem="SBC C" , opcode=0xF9, {"aluA", "alurC","aluOpSubC","instrNext"}, desc="Subtract %C form %A including the Carry Flag, %flags" , ccode={"addf(cpu.a,~cpu.c+cpu.cf); lni;"} },
|
||||||
{ mnem="CMP C" , opcode=0xD9, {"alulA","alurC","aluOpSub" ,"instrNext"}, desc="%cmp %C from %A" , ccode={"cmpf(cpu.a,cpu.c); lni;"} },
|
{ mnem="CMP C" , opcode=0xD9, {"alulA","alurC","aluOpSub" ,"instrNext"}, desc="%cmp %C from %A" , ccode={"cmpf(cpu.a,cpu.c); lni;"} },
|
||||||
{ mnem="AND C" , opcode=0x39, {"aluA", "alurC","aluOpAnd" ,"instrNext"}, desc="Bitwise AND %A with %C, %flags" , ccode={"cpu.a&=cpu.c; setzf(cpu.a); lni;"} },
|
{ mnem="AND C" , opcode=0x39, {"aluA", "alurC","aluOpAnd" ,"instrNext"}, desc="Bitwise AND %A with %C, %flags" , ccode={"cpu.a&=cpu.c; setzf(cpu.a); lni;"} },
|
||||||
{ mnem="ORA C" , opcode=0x19, {"aluA", "alurC","aluOpIor" ,"instrNext"}, desc="Bitwise OR %A with %C, %flags" , ccode={"cpu.a|=cpu.c; setzf(cpu.a); lni;"} },
|
{ mnem="ORA C" , opcode=0x19, {"aluA", "alurC","aluOpIor" ,"instrNext"}, desc="Bitwise OR %A with %C, %flags" , ccode={"cpu.a|=cpu.c; setzf(cpu.a); lni;"} },
|
||||||
|
2
8608.asm
2
8608.asm
@ -41,7 +41,9 @@
|
|||||||
DEC {value: u8} => $C6 @ value
|
DEC {value: u8} => $C6 @ value
|
||||||
ICC {value: u8} => $47 @ value
|
ICC {value: u8} => $47 @ value
|
||||||
ADD #{value: i8} => $6B @ value
|
ADD #{value: i8} => $6B @ value
|
||||||
|
SUB #{value: i8} => $EB @ value
|
||||||
ADC #{value: i8} => $69 @ value
|
ADC #{value: i8} => $69 @ value
|
||||||
|
SBC #{value: i8} => $E9 @ value
|
||||||
CMP #{value: i8} => $C9 @ value
|
CMP #{value: i8} => $C9 @ value
|
||||||
AND #{value: i8} => $29 @ value
|
AND #{value: i8} => $29 @ value
|
||||||
ORA #{value: i8} => $09 @ value
|
ORA #{value: i8} => $09 @ value
|
||||||
|
Binary file not shown.
@ -4,7 +4,12 @@
|
|||||||
-- This file deals mostly with the user interface, controls, and high-level functions.
|
-- This file deals mostly with the user interface, controls, and high-level functions.
|
||||||
-- Emulation of the CPU internals is done by the 8608emulator.dll library. See 8608emulator.c for details.
|
-- Emulation of the CPU internals is done by the 8608emulator.dll library. See 8608emulator.c for details.
|
||||||
|
|
||||||
|
-- Number of frames to highlight memory and instructions when they're accessed
|
||||||
local MainHighlightTime = 8
|
local MainHighlightTime = 8
|
||||||
|
-- If true, char display renders in default print fallback mode; otherwise, terminal print mode is used
|
||||||
|
local PrintMode = true
|
||||||
|
-- Maximum number of CPU cycles per frame
|
||||||
|
local MaxTicksPerFrame = 555
|
||||||
|
|
||||||
require("colorset")
|
require("colorset")
|
||||||
local ffi = require("ffi")
|
local ffi = require("ffi")
|
||||||
@ -17,6 +22,11 @@ local lk = love.keyboard
|
|||||||
local la = love.audio
|
local la = love.audio
|
||||||
|
|
||||||
local PlaySound
|
local PlaySound
|
||||||
|
local CPURequestInterrupt
|
||||||
|
local TimerSchedule
|
||||||
|
local TickCPU
|
||||||
|
|
||||||
|
local jsrInstrs = {0x20, 0x2C, 0x0C}
|
||||||
|
|
||||||
----
|
----
|
||||||
local function InitColorset()
|
local function InitColorset()
|
||||||
@ -220,15 +230,17 @@ local ProgramDisplay = {
|
|||||||
fontHeight = 12,
|
fontHeight = 12,
|
||||||
numLines = 34,
|
numLines = 34,
|
||||||
highlightTime = MainHighlightTime,
|
highlightTime = MainHighlightTime,
|
||||||
|
maxChars = 30,
|
||||||
}
|
}
|
||||||
local function toPrintableChar(v)
|
local function toPrintableChar(v)
|
||||||
if v>=0x20 and v<=0x7E then return string.char(v)
|
if v>=0x20 and v<=0x7E then return string.char(v)
|
||||||
else return "\\x"..string.format("%02X", v) end
|
else return "\\x"..string.format("%02X", v) end
|
||||||
end
|
end
|
||||||
local function pdLinesFromDasm(dasm)
|
local function pdLinesFromDasm(dasm, maxChars)
|
||||||
local div = " | "
|
local div = "|"
|
||||||
local lines, addrLines, lineAddrs = {}, {}, {}
|
local lines, addrLines, lineAddrs = {}, {}, {}
|
||||||
local function addDasmLine(addr, data, text)
|
local function addDasmLine(addr, data, text)
|
||||||
|
text = text:sub(1, maxChars - #div*2 - 8)
|
||||||
local dataStr = ""
|
local dataStr = ""
|
||||||
if data then
|
if data then
|
||||||
local dt = {}
|
local dt = {}
|
||||||
@ -274,7 +286,7 @@ local function pdLinesFromDasm(dasm)
|
|||||||
local datastr = {}
|
local datastr = {}
|
||||||
for v in datah:gfind("[0-9a-fA-F][0-9a-fA-F]") do
|
for v in datah:gfind("[0-9a-fA-F][0-9a-fA-F]") do
|
||||||
if #data>=maxlen then
|
if #data>=maxlen then
|
||||||
addDasmLine(addr+len-#data, data, "\""..table.concat(datastr.."\""))
|
addDasmLine(addr+len-#data, data, "\""..table.concat(datastr).."\"")
|
||||||
data = {}
|
data = {}
|
||||||
datastr = {}
|
datastr = {}
|
||||||
end
|
end
|
||||||
@ -285,7 +297,7 @@ local function pdLinesFromDasm(dasm)
|
|||||||
if len<=maxlen then
|
if len<=maxlen then
|
||||||
addDasmLine(addr, data, text)
|
addDasmLine(addr, data, text)
|
||||||
elseif #data>0 then
|
elseif #data>0 then
|
||||||
addDasmLine(addr+len-#data, data, "\""..table.concat(datastr.."\""))
|
addDasmLine(addr+len-#data, data, "\""..table.concat(datastr).."\"")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -298,7 +310,7 @@ local function InitProgramDisplay(pd, dasmText)
|
|||||||
lg.print("Program", pd.scrX, pd.scrY-12)
|
lg.print("Program", pd.scrX, pd.scrY-12)
|
||||||
lg.rectangle("line", pd.scrX, pd.scrY, pd.width, pd.height)
|
lg.rectangle("line", pd.scrX, pd.scrY, pd.width, pd.height)
|
||||||
pd.firstLine = 1
|
pd.firstLine = 1
|
||||||
pd.lines, pd.addrLines, pd.lineAddrs = pdLinesFromDasm(dasmText)
|
pd.lines, pd.addrLines, pd.lineAddrs = pdLinesFromDasm(dasmText, pd.maxChars)
|
||||||
pd.midLine = math.floor(pd.numLines/2)
|
pd.midLine = math.floor(pd.numLines/2)
|
||||||
pd.init = true
|
pd.init = true
|
||||||
end
|
end
|
||||||
@ -368,7 +380,7 @@ local function InitCharDisplay(cd)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local Keyboard = {
|
local Keyboard = {
|
||||||
addrRange = {0x0500, 0x05FF},
|
addrRange = {0xF100, 0xF1FF},
|
||||||
queueSize = 16,
|
queueSize = 16,
|
||||||
queue = {},
|
queue = {},
|
||||||
interrupts = false,
|
interrupts = false,
|
||||||
@ -392,7 +404,6 @@ local function KeyboardOnWrite(addr, cpu, mem, kb)
|
|||||||
mem.c.data[addr] = kb.queue[1] or 0
|
mem.c.data[addr] = kb.queue[1] or 0
|
||||||
end
|
end
|
||||||
local keycodes = require("keycodes")
|
local keycodes = require("keycodes")
|
||||||
local CPURequestInterrupt
|
|
||||||
local function KeyboardOnKey(kb, key, press, cpu, mem)
|
local function KeyboardOnKey(kb, key, press, cpu, mem)
|
||||||
local code = keycodes[key] or keycodes["invalid"]
|
local code = keycodes[key] or keycodes["invalid"]
|
||||||
if code==0x7F then print("invalid key: "..key) end
|
if code==0x7F then print("invalid key: "..key) end
|
||||||
@ -431,10 +442,11 @@ local function RedrawKeyInfo(x, y, uk, run)
|
|||||||
printHighlight("[R] "..(run and "Stop" or "Run "), 23, lk.isDown("r"), x, y)
|
printHighlight("[R] "..(run and "Stop" or "Run "), 23, lk.isDown("r"), x, y)
|
||||||
if not run then
|
if not run then
|
||||||
printHighlight("[S] Step" , 33, lk.isDown("s"), x, y)
|
printHighlight("[S] Step" , 33, lk.isDown("s"), x, y)
|
||||||
end
|
|
||||||
-- printHighlight("[T] Tick once" , 48, lk.isDown("t"), x, y)
|
-- printHighlight("[T] Tick once" , 48, lk.isDown("t"), x, y)
|
||||||
printHighlight("[I] Interrupt" , 43, lk.isDown("i"), x, y)
|
printHighlight("[X] Step Over" , 43, lk.isDown("x"), x, y)
|
||||||
printHighlight("[Q] Quit" , 70, lk.isDown("q"), x, y)
|
end
|
||||||
|
printHighlight("[I] Interrupt" , 58, lk.isDown("i"), x, y)
|
||||||
|
printHighlight("[Q] Quit" , 73, lk.isDown("q"), x, y)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -471,12 +483,15 @@ local function gpioDiv(addr, cpu, mem, gpio)
|
|||||||
WriteMemory(mem, base+0x02, math.floor(gpio.divLeft/gpio.divRight))
|
WriteMemory(mem, base+0x02, math.floor(gpio.divLeft/gpio.divRight))
|
||||||
WriteMemory(mem, base+0x03, gpio.divLeft%gpio.divRight)
|
WriteMemory(mem, base+0x03, gpio.divLeft%gpio.divRight)
|
||||||
end
|
end
|
||||||
|
local function gpioPopcount(v)
|
||||||
|
return 0 -- todo
|
||||||
|
end
|
||||||
local gpioFunctions = {
|
local gpioFunctions = {
|
||||||
[0x00] = gpioSetValue("mulLeft" , gpioMul),
|
[0x00] = gpioSetValue("mulLeft" , gpioMul),
|
||||||
[0x01] = gpioSetValue("mulRight", gpioMul),
|
[0x01] = gpioSetValue("mulRight", gpioMul),
|
||||||
[0x02] = gpioSetValue("divLeft" , gpioDiv),
|
[0x02] = gpioSetValue("divLeft" , gpioDiv),
|
||||||
[0x03] = gpioSetValue("divRight", gpioDiv),
|
[0x03] = gpioSetValue("divRight", gpioDiv),
|
||||||
[0x04] = function(addr, cpu, mem, gpio) WriteMemory(mem, addr, gpioPopcount(readMemory(mem, addr))) end,
|
[0x04] = function(addr, cpu, mem, gpio) WriteMemory(mem, addr, gpioPopcount(ReadMemory(mem, addr))) end,
|
||||||
[0x05] = function(addr, cpu, mem, gpio) gpio.timerCount = 60/10; WriteMemory(mem, addr, 0); end
|
[0x05] = function(addr, cpu, mem, gpio) gpio.timerCount = 60/10; WriteMemory(mem, addr, 0); end
|
||||||
}
|
}
|
||||||
local function GPIOOnWrite(addr, cpu, mem, gpio)
|
local function GPIOOnWrite(addr, cpu, mem, gpio)
|
||||||
@ -516,31 +531,124 @@ local function InitConsole(con)
|
|||||||
con.prevInputIdx = 0
|
con.prevInputIdx = 0
|
||||||
con.tempError = nil
|
con.tempError = nil
|
||||||
end
|
end
|
||||||
local function RedrawConsole(con)
|
local function RedrawConsole(con, kb)
|
||||||
lg.setColor(0,0,0)
|
lg.setColor(0,0,0)
|
||||||
lg.rectangle("fill", con.scrX, con.scrY, con.width, con.height)
|
lg.rectangle("fill", con.scrX, con.scrY, con.width, con.height)
|
||||||
lg.setColor(1,1,1)
|
lg.setColor(1,1,1)
|
||||||
lg.rectangle("line", con.scrX, con.scrY, con.width, con.height)
|
lg.rectangle("line", con.scrX, con.scrY, con.width, con.height)
|
||||||
if con.blinkFrame < con.blinkFrames/2 then
|
if not kb then
|
||||||
local curx, cury = con.scrX + #con.input*7 + 2, con.scrY+3
|
if con.blinkFrame < con.blinkFrames/2 then
|
||||||
lg.rectangle("fill", curx, cury, 8, 12)
|
local curx, cury = con.scrX + #con.input*7 + 2, con.scrY+3
|
||||||
end
|
lg.rectangle("fill", curx, cury, 8, 12)
|
||||||
con.blinkFrame = con.blinkFrame + 1
|
end
|
||||||
if con.blinkFrame >= con.blinkFrames then con.blinkFrame = 0 end
|
con.blinkFrame = con.blinkFrame + 1
|
||||||
if #con.input==0 then
|
if con.blinkFrame >= con.blinkFrames then con.blinkFrame = 0 end
|
||||||
lg.setColor(0.5,0.5,0.5)
|
if #con.input==0 then
|
||||||
lg.print(con.tempError or "Type a Command (@addr | addr=byte | addr=byte1 byte2 ...)", con.scrX+2+8, con.scrY+4)
|
lg.setColor(0.5,0.5,0.5)
|
||||||
else
|
lg.print(con.tempError or "Enter Command (>ticks | !addr | @addr | addr=byte | addr=byte1 byte2...)", con.scrX+2+8, con.scrY+4)
|
||||||
lg.print(con.input, con.scrX+2, con.scrY+4)
|
else
|
||||||
|
lg.print(con.input, con.scrX+2, con.scrY+4)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function ConsoleError(con, err)
|
local function ConsoleError(con, err)
|
||||||
con.tempError = err
|
con.tempError = err
|
||||||
end
|
end
|
||||||
local function ConsoleExec(con, mem)
|
local function conWriteDataBlock(con, mem, addr, data)
|
||||||
|
local writeTime = 2
|
||||||
|
ConsoleError(con, "Writing")
|
||||||
|
for i, byte in ipairs(data) do
|
||||||
|
TimerSchedule((i-1)*writeTime, function()
|
||||||
|
if con.tempError ~= nil then
|
||||||
|
con.tempError = con.tempError .. "."
|
||||||
|
end
|
||||||
|
mem.c.data[(addr+i-1)%65536] = byte
|
||||||
|
PlaySound("write")
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
TimerSchedule((#data-1)*writeTime, function()
|
||||||
|
PlaySound("writeDone")
|
||||||
|
PlaySound("success")
|
||||||
|
ConsoleError(con, "Wrote " .. #data .. " byte" .. (#data>1 and "s" or "") .. " to address $" .. string.format("%04X", addr))
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
local function tickCpuOnce(cpu, mem, byInstr)
|
||||||
|
TickCPU(cpu, mem, 1, byInstr, nil)
|
||||||
|
end
|
||||||
|
local function tickCpuUntil(con, cpu, mem, contfunc, strfunc, donestr, step)
|
||||||
|
con.tempError = ""
|
||||||
|
local tickTime = 1
|
||||||
|
local tickStep, byInstr
|
||||||
|
if step then
|
||||||
|
tickStep = step
|
||||||
|
byInstr = true
|
||||||
|
else
|
||||||
|
tickStep = MaxTicksPerFrame
|
||||||
|
byInstr = false
|
||||||
|
end
|
||||||
|
local i = 1
|
||||||
|
local recFunc
|
||||||
|
recFunc = function()
|
||||||
|
for j = 1, tickStep do
|
||||||
|
if contfunc(i) then
|
||||||
|
tickCpuOnce(cpu, mem, byInstr)
|
||||||
|
else
|
||||||
|
PlaySound("writeDone")
|
||||||
|
PlaySound("success")
|
||||||
|
ConsoleError(con, donestr)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
i = i+1
|
||||||
|
end
|
||||||
|
if con.tempError ~= nil then
|
||||||
|
con.tempError = strfunc(i)
|
||||||
|
end
|
||||||
|
PlaySound("write")
|
||||||
|
TimerSchedule(tickTime, recFunc)
|
||||||
|
end
|
||||||
|
recFunc()
|
||||||
|
end
|
||||||
|
local function tickCpuStepOver(con, cpu, mem, pd)
|
||||||
|
local stepOver = false
|
||||||
|
for _, v in ipairs(jsrInstrs) do
|
||||||
|
if cpu.c.instr == v then
|
||||||
|
stepOver = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not stepOver then
|
||||||
|
tickCpuOnce(cpu, mem, true)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local line = pd.addrLines and pd.addrLines[(cpu.c.i-1)%65536]
|
||||||
|
if not line then
|
||||||
|
tickCpuOnce(cpu, mem, true)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local addr
|
||||||
|
while not addr do
|
||||||
|
line = line+1
|
||||||
|
local addrs = pd.lineAddrs[line]
|
||||||
|
if not addrs then
|
||||||
|
tickCpuOnce(cpu, mem, true)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
addr = addrs[1]
|
||||||
|
end
|
||||||
|
--print(string.format("%04X", addr))
|
||||||
|
tickCpuUntil(con, cpu, mem,
|
||||||
|
--function() return (cpu.c.i ~= (addr+1)%65536) and (cpu.c.rfg==1) end,
|
||||||
|
function() return (cpu.c.i ~= (addr+1)%65536) end,
|
||||||
|
function() return "Running to address $" .. string.format("%04X", addr) end,
|
||||||
|
nil,
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
end
|
||||||
|
local function ConsoleExec(con, cpu, mem)
|
||||||
PlaySound("enter")
|
PlaySound("enter")
|
||||||
if con.input=="" then
|
if con.input=="" then
|
||||||
PlaySound("error")
|
PlaySound("error")
|
||||||
|
con.tempError = nil
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -564,6 +672,69 @@ local function ConsoleExec(con, mem)
|
|||||||
MemoryDisplays[1].addr = addr
|
MemoryDisplays[1].addr = addr
|
||||||
ConsoleError(con, "Memory display set to address $" .. string.format("%04X", addr))
|
ConsoleError(con, "Memory display set to address $" .. string.format("%04X", addr))
|
||||||
PlaySound("success")
|
PlaySound("success")
|
||||||
|
elseif ip:sub(1, 1)=="!" then
|
||||||
|
if RunCPU then
|
||||||
|
ConsoleError(con, "CPU must be paused to change execution")
|
||||||
|
PlaySound("error")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local rest = ip:sub(2, #ip)
|
||||||
|
local addr = tonumber(rest, 16)
|
||||||
|
if not addr then
|
||||||
|
ConsoleError(con, "Error: Expected a hex number")
|
||||||
|
PlaySound("error")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if addr<0 then addr = 0 end
|
||||||
|
if addr>65535 then addr = 65535 end
|
||||||
|
cpu.c.i = (addr+1)%65536
|
||||||
|
cpu.c.cycle = 0
|
||||||
|
cpu.c.instr = ReadMemory(mem, addr)
|
||||||
|
ConsoleError(con, "CPU instruction pointer set to $" .. string.format("%04X", addr))
|
||||||
|
PlaySound("success")
|
||||||
|
elseif ip:sub(1, 2)==">>" then
|
||||||
|
if RunCPU then
|
||||||
|
ConsoleError(con, "CPU must be paused to step")
|
||||||
|
PlaySound("error")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local rest = ip:sub(3, #ip)
|
||||||
|
local addr = tonumber(rest, 16)
|
||||||
|
if not addr then
|
||||||
|
ConsoleError(con, "Error: Expected a hex number")
|
||||||
|
PlaySound("error")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if addr<0 then addr = 0 end
|
||||||
|
if addr>65535 then addr = 65535 end
|
||||||
|
tickCpuUntil(con, cpu, mem,
|
||||||
|
function() return cpu.c.i ~= (addr+1)%65536 end,
|
||||||
|
function() return "Running to address $" .. string.format("%04X", addr) end,
|
||||||
|
"Ran to address " .. string.format("%04X", addr),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
elseif ip:sub(1, 1)==">" then
|
||||||
|
if RunCPU then
|
||||||
|
ConsoleError(con, "CPU must be paused to single-step")
|
||||||
|
PlaySound("error")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local rest = ip:sub(2, #ip)
|
||||||
|
local steps = tonumber(rest, 16)
|
||||||
|
if rest=="" then steps = 1 end
|
||||||
|
if not steps then
|
||||||
|
ConsoleError(con, "Error: Expected a hex number")
|
||||||
|
PlaySound("error")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if steps<1 then steps = 1 end
|
||||||
|
if steps>65535 then steps = 65535 end
|
||||||
|
tickCpuUntil(con, cpu, mem,
|
||||||
|
function(i) return i<=steps; end,
|
||||||
|
function(i) return "Step $"..string.format("%X", i).."/$"..string.format("%X", steps) end,
|
||||||
|
"Ran $" .. string.format("%02X", steps) .. " steps",
|
||||||
|
steps<(MaxTicksPerFrame/4) and steps or nil
|
||||||
|
)
|
||||||
elseif ip:find("=") then
|
elseif ip:find("=") then
|
||||||
local addrS, rest = ip:match("^ *([0-9a-fA-F]+) *= *([0-9a-fA-F ]+)$")
|
local addrS, rest = ip:match("^ *([0-9a-fA-F]+) *= *([0-9a-fA-F ]+)$")
|
||||||
local addr = tonumber(addrS or "", 16)
|
local addr = tonumber(addrS or "", 16)
|
||||||
@ -582,27 +753,27 @@ local function ConsoleExec(con, mem)
|
|||||||
end
|
end
|
||||||
table.insert(data, byte)
|
table.insert(data, byte)
|
||||||
end
|
end
|
||||||
for i, byte in ipairs(data) do
|
|
||||||
mem.c.data[(addr+i-1)%65536] = byte
|
conWriteDataBlock(con, mem, addr, data)
|
||||||
PlaySound("write", i)
|
else
|
||||||
end
|
ConsoleError(con, "Error: Unknown command")
|
||||||
PlaySound("writeDone", #data)
|
PlaySound("error")
|
||||||
PlaySound("success", #data)
|
|
||||||
ConsoleError(con, "Wrote " .. #data .. " byte" .. (#data>1 and "s" or "") .. " to address $" .. string.format("%04X", addr))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function shiftDown()
|
local function shiftDown()
|
||||||
return lk.isDown("lshift") or lk.isDown("rshift")
|
return lk.isDown("lshift") or lk.isDown("rshift")
|
||||||
end
|
end
|
||||||
local function ConsoleKey(con, k, mem)
|
local function ConsoleKey(con, k, cpu, mem)
|
||||||
local add
|
local add
|
||||||
if k=="backspace" then con.input = con.input:sub(1, #con.input-1)
|
if k=="backspace" then con.input = con.input:sub(1, #con.input-1)
|
||||||
|
elseif shiftDown() and k=="1" then add = "!"
|
||||||
elseif shiftDown() and k=="2" then add = "@"
|
elseif shiftDown() and k=="2" then add = "@"
|
||||||
|
elseif shiftDown() and k=="." then add = ">"
|
||||||
elseif k>="0" and k<="9" then add = k
|
elseif k>="0" and k<="9" then add = k
|
||||||
elseif #k==1 and k>="a" and k<="f" then add = k:upper()
|
elseif #k==1 and k>="a" and k<="f" then add = k:upper()
|
||||||
elseif k=="=" then add = "="
|
elseif k=="=" then add = "="
|
||||||
elseif k=="space" then add = " "
|
elseif k=="space" then add = " "
|
||||||
elseif k=="return" then ConsoleExec(con, mem)
|
elseif k=="return" then ConsoleExec(con, cpu, mem)
|
||||||
elseif k=="up" and con.prevInputs[con.prevInputIdx+1] then
|
elseif k=="up" and con.prevInputs[con.prevInputIdx+1] then
|
||||||
if con.prevInputIdx==0 then con.prevInputs[0] = con.input end
|
if con.prevInputIdx==0 then con.prevInputs[0] = con.input end
|
||||||
con.prevInputIdx = con.prevInputIdx + 1
|
con.prevInputIdx = con.prevInputIdx + 1
|
||||||
@ -637,6 +808,10 @@ local soundNames = {
|
|||||||
"success",
|
"success",
|
||||||
"write","writeDone",
|
"write","writeDone",
|
||||||
}
|
}
|
||||||
|
local soundCounts = {
|
||||||
|
--["step"] = 100,
|
||||||
|
["write"] = 100,
|
||||||
|
}
|
||||||
local function InitSound()
|
local function InitSound()
|
||||||
for _, name in ipairs(soundNames) do
|
for _, name in ipairs(soundNames) do
|
||||||
local sound = {
|
local sound = {
|
||||||
@ -645,33 +820,36 @@ local function InitSound()
|
|||||||
lastPlayed = 0,
|
lastPlayed = 0,
|
||||||
}
|
}
|
||||||
local fn = "content/" .. name .. ".wav"
|
local fn = "content/" .. name .. ".wav"
|
||||||
for i = 1, 4 do
|
for i = 1, soundCounts[name] or 4 do
|
||||||
table.insert(sound.sources, la.newSource(fn, "static"))
|
table.insert(sound.sources, la.newSource(fn, "static"))
|
||||||
end
|
end
|
||||||
Sounds[name] = sound
|
Sounds[name] = sound
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local SoundFrame = 0
|
PlaySound = function(name)
|
||||||
local QueuedSounds = {}
|
local sound = Sounds[name] or error("no sound with name: " .. name)
|
||||||
PlaySound = function(name, delay)
|
sound.lastPlayed = (sound.lastPlayed % #sound.sources) + 1
|
||||||
if (not delay) or delay==0 then
|
sound.sources[sound.lastPlayed]:play()
|
||||||
local sound = Sounds[name] or error("no sound with name: " .. name)
|
|
||||||
sound.lastPlayed = (sound.lastPlayed % #sound.sources) + 1
|
|
||||||
sound.sources[sound.lastPlayed]:play()
|
|
||||||
else
|
|
||||||
local time = SoundFrame + delay
|
|
||||||
QueuedSounds[time] = QueuedSounds[time] or {}
|
|
||||||
table.insert(QueuedSounds[time], name)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
local function UpdateSound()
|
|
||||||
if QueuedSounds[SoundFrame] then
|
----
|
||||||
for _, name in ipairs(QueuedSounds[SoundFrame]) do
|
-- Timer
|
||||||
PlaySound(name)
|
|
||||||
|
local TimerFrame = 0
|
||||||
|
local TimerSchedules = {}
|
||||||
|
TimerSchedule = function(time, func)
|
||||||
|
local frame = TimerFrame + time
|
||||||
|
TimerSchedules[frame] = TimerSchedules[frame] or {}
|
||||||
|
table.insert(TimerSchedules[frame], func)
|
||||||
|
end
|
||||||
|
local function UpdateTimer()
|
||||||
|
if TimerSchedules[TimerFrame] then
|
||||||
|
for _, func in ipairs(TimerSchedules[TimerFrame]) do
|
||||||
|
func()
|
||||||
end
|
end
|
||||||
QueuedSounds[SoundFrame] = nil
|
TimerSchedules[TimerFrame] = nil
|
||||||
end
|
end
|
||||||
SoundFrame = SoundFrame + 1
|
TimerFrame = TimerFrame + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -777,7 +955,7 @@ local CPU = {
|
|||||||
c = ffi.new("struct CPU"),
|
c = ffi.new("struct CPU"),
|
||||||
}
|
}
|
||||||
local cpuDll = ffi.load("8608emulator.dll")
|
local cpuDll = ffi.load("8608emulator.dll")
|
||||||
local function TickCPU(cpu, mem, count, countinstrs, breakaddr)
|
TickCPU = function(cpu, mem, count, countinstrs, breakaddr)
|
||||||
local countleft = count
|
local countleft = count
|
||||||
while countleft>0 do
|
while countleft>0 do
|
||||||
countleft = cpuDll.TickCPU(cpu.c, mem.c, countleft, countinstrs and 1 or 0, breakaddr or 0xFFFFFFFF)
|
countleft = cpuDll.TickCPU(cpu.c, mem.c, countleft, countinstrs and 1 or 0, breakaddr or 0xFFFFFFFF)
|
||||||
@ -792,10 +970,6 @@ CPURequestInterrupt = function(cpu)
|
|||||||
cpu.c.irq = 1;
|
cpu.c.irq = 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
function RunToNextInstr(cpu)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
--local function RedrawVideoDisplay(vd, mem)
|
--local function RedrawVideoDisplay(vd, mem)
|
||||||
@ -825,20 +999,32 @@ local function RedrawCharDisplay(cd, mem)
|
|||||||
local acolor = cd.addrColor + abase
|
local acolor = cd.addrColor + abase
|
||||||
local colormem = ReadMemory(mem, acolor)
|
local colormem = ReadMemory(mem, acolor)
|
||||||
local colorid = colormem%64
|
local colorid = colormem%64
|
||||||
local highlight = colormem>=128
|
local highlight = PrintMode or colormem>=128
|
||||||
lg.setColor(ColorSet[colorid])
|
lg.setColor(ColorSet[colorid])
|
||||||
|
local scrx = cd.scrX + cx*cd.fontWidth
|
||||||
|
local scry = cd.scrY + cy*cd.fontHeight
|
||||||
|
local scrw = cd.fontWidth
|
||||||
|
local scrh = cd.fontHeight
|
||||||
if highlight then
|
if highlight then
|
||||||
lg.rectangle("fill", cd.scrX + cx*cd.fontWidth, cd.scrY + cy*cd.fontHeight, cd.fontWidth, cd.fontHeight)
|
lg.rectangle("fill", scrx, scry, scrw, scrh)
|
||||||
lg.setColor(0, 0, 0)
|
if PrintMode then lg.setColor(1,1,1) else lg.setColor(0,0,0) end
|
||||||
end
|
end
|
||||||
local val = ReadMemory(mem, achar)%128
|
local val = ReadMemory(mem, achar)%128
|
||||||
if val>=32 then
|
if val>=0x20 and val<=0x7F then -- printable ascii
|
||||||
local char = string.char(val)
|
local char = string.char(val)
|
||||||
lg.print(char, cd.scrX + cx*cd.fontWidth, cd.scrY + cy*cd.fontHeight)
|
lg.print(char, scrx, scry)
|
||||||
elseif val>=16 and val<=31 then
|
elseif val>=0x10 and val<=0x17 then -- solid color
|
||||||
local r, g, b = math.floor(val/4)%2, math.floor(val/2)%2, val%2
|
local r, g, b = math.floor(val/4)%2, math.floor(val/2)%2, val%2
|
||||||
lg.setColor(r, g, b)
|
lg.setColor(r, g, b)
|
||||||
lg.rectangle("fill", cd.scrX + cx*cd.fontWidth, cd.scrY + cy*cd.fontHeight, cd.fontWidth, cd.fontHeight)
|
lg.rectangle("fill", scrx, scry, scrw, scrh)
|
||||||
|
elseif val>=0x80 and val<=0x8F then -- 2x2 pixels
|
||||||
|
lg.setColor(0,0,0)
|
||||||
|
if val %2==1 then lg.rectangle("fill", scrx+scrw/2, scry+scrh/2, scrw/2, scrh/2) end -- bottom right
|
||||||
|
if math.floor(val/2)%2==1 then lg.rectangle("fill", scrx , scry+scrh/2, scrw/2, scrh/2) end -- bottom left
|
||||||
|
if math.floor(val/4)%2==1 then lg.rectangle("fill", scrx+scrw/2, scry , scrw/2, scrh/2) end -- top right
|
||||||
|
if math.floor(val/4)%2==1 then lg.rectangle("fill", scrx , scry , scrw/2, scrh/2) end -- top left
|
||||||
|
elseif val>=0xA0 and val<=0xDF then -- kana
|
||||||
|
-- todo
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -861,9 +1047,9 @@ local function RedrawWindow(usekeyboard, runcpu)
|
|||||||
RedrawStackDisplay(StackDisplay, CPU, Memory)
|
RedrawStackDisplay(StackDisplay, CPU, Memory)
|
||||||
RedrawProgramDisplay(ProgramDisplay, CPU, Memory)
|
RedrawProgramDisplay(ProgramDisplay, CPU, Memory)
|
||||||
for _, md in ipairs(MemoryDisplays) do RedrawMemoryDisplay(md, CPU, Memory) end
|
for _, md in ipairs(MemoryDisplays) do RedrawMemoryDisplay(md, CPU, Memory) end
|
||||||
RedrawFPSCounter(128+32, 4)
|
RedrawFPSCounter(128, 4)
|
||||||
RedrawKeyInfo(128+32+64+16, 4, usekeyboard, runcpu)
|
RedrawKeyInfo(128+64+16, 4, usekeyboard, runcpu)
|
||||||
RedrawConsole(Console)
|
RedrawConsole(Console, usekeyboard)
|
||||||
|
|
||||||
lg.setCanvas()
|
lg.setCanvas()
|
||||||
end
|
end
|
||||||
@ -955,13 +1141,14 @@ local function endFrame()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local RunCPU = false
|
local RunCPU = false
|
||||||
local CPUSpeed = 555
|
local CPUSpeed = MaxTicksPerFrame
|
||||||
local UseKeyboard = false
|
local UseKeyboard = false
|
||||||
function love.draw()
|
function love.draw()
|
||||||
startFrame()
|
startFrame()
|
||||||
|
|
||||||
|
UpdateTimer()
|
||||||
|
|
||||||
UpdateGPIO(GPIO, CPU, Memory)
|
UpdateGPIO(GPIO, CPU, Memory)
|
||||||
UpdateSound()
|
|
||||||
|
|
||||||
CPU.c.frame = CPU.c.frame + 1
|
CPU.c.frame = CPU.c.frame + 1
|
||||||
if RunCPU then
|
if RunCPU then
|
||||||
@ -984,14 +1171,14 @@ function love.keypressed(k)
|
|||||||
KeyboardOnKey(Keyboard, k, true, CPU, Memory)
|
KeyboardOnKey(Keyboard, k, true, CPU, Memory)
|
||||||
else
|
else
|
||||||
if k=="q" then le.quit()
|
if k=="q" then le.quit()
|
||||||
elseif k=="s" and not RunCPU then TickCPU(CPU, Memory, 1, true , nil); PlaySound("step");
|
elseif k=="s" and (not RunCPU) then tickCpuOnce(CPU, Memory, true); PlaySound("step");
|
||||||
|
elseif k=="x" and (not RunCPU) then tickCpuStepOver(Console, CPU, Memory, ProgramDisplay); PlaySound("step");
|
||||||
--elseif k=="t" then TickCPU(CPU, Memory, 1, false, nil)
|
--elseif k=="t" then TickCPU(CPU, Memory, 1, false, nil)
|
||||||
--elseif k=="o" then RunToNextInstr(cpu)
|
|
||||||
elseif k=="r" then RunCPU = not RunCPU; PlaySound(RunCPU and "runOn" or "runOff");
|
elseif k=="r" then RunCPU = not RunCPU; PlaySound(RunCPU and "runOn" or "runOff");
|
||||||
elseif k=="i" then CPU.c.irq = 1; PlaySound("interrupt");
|
elseif k=="i" then CPU.c.irq = 1; PlaySound("interrupt");
|
||||||
--elseif k=="u" then CPU.c.rfg = 1
|
--elseif k=="u" then CPU.c.rfg = 1
|
||||||
else
|
else
|
||||||
ConsoleKey(Console, k, Memory)
|
ConsoleKey(Console, k, CPU, Memory)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -414,7 +414,7 @@ void cpu_instr_227_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=l
|
|||||||
void cpu_instr_227_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
void cpu_instr_227_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||||
void cpu_instr_229_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
|
void cpu_instr_229_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
|
||||||
void cpu_instr_229_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
|
void cpu_instr_229_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
|
||||||
void cpu_instr_229_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->u+cpu->cf); lni; }
|
void cpu_instr_229_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,~cpu->u+cpu->cf); lni; }
|
||||||
void cpu_instr_230_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
|
void cpu_instr_230_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
|
||||||
void cpu_instr_230_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
|
void cpu_instr_230_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
|
||||||
void cpu_instr_230_2(struct CPU* const cpu, struct Memory* const mem) { instrpreload; addf(cpu->u, 1 ); cpu->cycle++; }
|
void cpu_instr_230_2(struct CPU* const cpu, struct Memory* const mem) { instrpreload; addf(cpu->u, 1 ); cpu->cycle++; }
|
||||||
@ -424,7 +424,11 @@ void cpu_instr_231_1(struct CPU* const cpu, struct Memory* const mem) { loadstac
|
|||||||
void cpu_instr_231_2(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->u); lni; }
|
void cpu_instr_231_2(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->u); lni; }
|
||||||
void cpu_instr_232_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
|
void cpu_instr_232_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
|
||||||
void cpu_instr_232_1(struct CPU* const cpu, struct Memory* const mem) { cpu->p=(cpu->p+signed8(cpu->t))%65536; lni; }
|
void cpu_instr_232_1(struct CPU* const cpu, struct Memory* const mem) { cpu->p=(cpu->p+signed8(cpu->t))%65536; lni; }
|
||||||
|
void cpu_instr_233_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
|
||||||
|
void cpu_instr_233_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,~cpu->t+cpu->cf); lni; }
|
||||||
void cpu_instr_234_0(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
void cpu_instr_234_0(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||||
|
void cpu_instr_235_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
|
||||||
|
void cpu_instr_235_1(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->t); lni; }
|
||||||
void cpu_instr_237_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
void cpu_instr_237_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
|
||||||
void cpu_instr_237_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
void cpu_instr_237_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
|
||||||
void cpu_instr_237_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadut; setzf(cpu->a); cpu->cycle++; }
|
void cpu_instr_237_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadut; setzf(cpu->a); cpu->cycle++; }
|
||||||
@ -444,7 +448,7 @@ void cpu_instr_243_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=l
|
|||||||
void cpu_instr_243_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
void cpu_instr_243_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
|
||||||
void cpu_instr_246_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a, 1 ); lni; }
|
void cpu_instr_246_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a, 1 ); lni; }
|
||||||
void cpu_instr_247_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=cpu->b; lni; }
|
void cpu_instr_247_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=cpu->b; lni; }
|
||||||
void cpu_instr_249_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->c+cpu->cf); lni; }
|
void cpu_instr_249_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,~cpu->c+cpu->cf); lni; }
|
||||||
void cpu_instr_250_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c, 1 ); lni; }
|
void cpu_instr_250_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c, 1 ); lni; }
|
||||||
void cpu_instr_251_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->c); lni; }
|
void cpu_instr_251_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->c); lni; }
|
||||||
void cpu_instr_252_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=(cpu->p+signed8(cpu->a))%65536; lni; }
|
void cpu_instr_252_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=(cpu->p+signed8(cpu->a))%65536; lni; }
|
||||||
@ -686,9 +690,9 @@ CPUInstruction CPUInstructions[256][8] = {
|
|||||||
{cpu_instr_230_0,cpu_instr_230_1,cpu_instr_230_2,cpu_instr_230_3,0,0,0,0},
|
{cpu_instr_230_0,cpu_instr_230_1,cpu_instr_230_2,cpu_instr_230_3,0,0,0,0},
|
||||||
{cpu_instr_231_0,cpu_instr_231_1,cpu_instr_231_2,0,0,0,0,0},
|
{cpu_instr_231_0,cpu_instr_231_1,cpu_instr_231_2,0,0,0,0,0},
|
||||||
{cpu_instr_232_0,cpu_instr_232_1,0,0,0,0,0,0},
|
{cpu_instr_232_0,cpu_instr_232_1,0,0,0,0,0,0},
|
||||||
{0,0,0,0,0,0,0,0},
|
{cpu_instr_233_0,cpu_instr_233_1,0,0,0,0,0,0},
|
||||||
{cpu_instr_234_0,0,0,0,0,0,0,0},
|
{cpu_instr_234_0,0,0,0,0,0,0,0},
|
||||||
{0,0,0,0,0,0,0,0},
|
{cpu_instr_235_0,cpu_instr_235_1,0,0,0,0,0,0},
|
||||||
{0,0,0,0,0,0,0,0},
|
{0,0,0,0,0,0,0,0},
|
||||||
{cpu_instr_237_0,cpu_instr_237_1,cpu_instr_237_2,cpu_instr_237_3,0,0,0,0},
|
{cpu_instr_237_0,cpu_instr_237_1,cpu_instr_237_2,cpu_instr_237_3,0,0,0,0},
|
||||||
{0,0,0,0,0,0,0,0},
|
{0,0,0,0,0,0,0,0},
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
-- These are the keycodes provided by the keyboard peripheral to the CPU within the emulator.
|
|
||||||
-- copied from Brick_LuaLogic/bricks/input/keyboard-global.lua
|
-- copied from Brick_LuaLogic/bricks/input/keyboard-global.lua
|
||||||
|
-- with some key names changed from Torque format to LOVE format.
|
||||||
|
|
||||||
return {
|
return {
|
||||||
["backspace"] = 8,
|
["backspace"] = 8,
|
||||||
["tab"] = 9,
|
["tab"] = 9,
|
||||||
["return"] = 13,
|
["return"] = 13,
|
||||||
|
|
||||||
["lshift"] = 16,
|
["lshift"] = 16, -- 0x10
|
||||||
["lcontrol"] = 17,
|
["lctrl"] = 17, --["lcontrol"] = 17,
|
||||||
["lalt"] = 18,
|
["lalt"] = 18,
|
||||||
|
|
||||||
-- this block does not match vkey codes
|
-- this block does not match vkey codes
|
||||||
["rshift"] = 20,
|
["rshift"] = 20, -- 0x14
|
||||||
["rcontrol"] = 21,
|
["rctrl"] = 21, --["rcontrol"] = 21,
|
||||||
["ralt"] = 22,
|
["ralt"] = 22,
|
||||||
|
|
||||||
-- this block does not match vkey codes
|
-- this block does not match vkey codes
|
||||||
@ -20,6 +21,7 @@ return {
|
|||||||
["="] = 25,
|
["="] = 25,
|
||||||
[","] = 26,
|
[","] = 26,
|
||||||
["."] = 27,
|
["."] = 27,
|
||||||
|
["-"] = 28, -- not in bl
|
||||||
["/"] = 29,
|
["/"] = 29,
|
||||||
["`"] = 30,
|
["`"] = 30,
|
||||||
|
|
||||||
@ -50,7 +52,7 @@ return {
|
|||||||
["["] = 60,
|
["["] = 60,
|
||||||
["\\"] = 61,
|
["\\"] = 61,
|
||||||
["]"] = 62,
|
["]"] = 62,
|
||||||
["apostrophe"] = 63,
|
["\'"] = 63, --["apostrophe"] = 63,
|
||||||
|
|
||||||
["a"] = 65,
|
["a"] = 65,
|
||||||
["b"] = 66,
|
["b"] = 66,
|
||||||
@ -79,22 +81,22 @@ return {
|
|||||||
["y"] = 89,
|
["y"] = 89,
|
||||||
["z"] = 90,
|
["z"] = 90,
|
||||||
|
|
||||||
["numpad0"] = 96,
|
["kp0"] = 96, --["numpad0"] = 96,
|
||||||
["numpad1"] = 97,
|
["kp1"] = 97, --["numpad1"] = 97,
|
||||||
["numpad2"] = 98,
|
["kp2"] = 98, --["numpad2"] = 98,
|
||||||
["numpad3"] = 99,
|
["kp3"] = 99, --["numpad3"] = 99,
|
||||||
["numpad4"] = 100,
|
["kp4"] = 100, --["numpad4"] = 100,
|
||||||
["numpad5"] = 101,
|
["kp5"] = 101, --["numpad5"] = 101,
|
||||||
["numpad6"] = 102,
|
["kp6"] = 102, --["numpad6"] = 102,
|
||||||
["numpad7"] = 103,
|
["kp7"] = 103, --["numpad7"] = 103,
|
||||||
["numpad8"] = 104,
|
["kp8"] = 104, --["numpad8"] = 104,
|
||||||
["numpad9"] = 105,
|
["kp9"] = 105, --["numpad9"] = 105,
|
||||||
["*"] = 106,
|
["kp*"] = 106, --["*"] = 106,
|
||||||
["+"] = 107,
|
["kp+"] = 107, --["+"] = 107,
|
||||||
["numpadenter"] = 108,
|
["kpenter"] = 108, --["numpadenter"] = 108,
|
||||||
["minus"] = 109,
|
["kp-"] = 109, --["minus"] = 109,
|
||||||
["numpaddecimal"] = 110,
|
["kp."] = 110, --["numpaddecimal"] = 110,
|
||||||
--["/"] = 111, -- already 29
|
["kp/"] = 111, --["/"] = 111,
|
||||||
|
|
||||||
["f1"] = 112,
|
["f1"] = 112,
|
||||||
["f2"] = 113,
|
["f2"] = 113,
|
||||||
@ -109,5 +111,5 @@ return {
|
|||||||
["f11"] = 122,
|
["f11"] = 122,
|
||||||
["f12"] = 123,
|
["f12"] = 123,
|
||||||
|
|
||||||
["invalid"] = 127,
|
--["invalid"] = 127,
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -1,18 +1,260 @@
|
|||||||
outp | addr | data (base 16)
|
outp | addr | data (base 16)
|
||||||
|
|
||||||
0:0 | 0 | ; FAIL:
|
0:0 | 0 | ; CURSORPOS:
|
||||||
0:0 | 0 | fa ; INC C
|
2:0 | 2 | ; SHIFTDOWN:
|
||||||
1:0 | 1 | 98 fd ; BRA FAIL
|
3:0 | 3 | ; TESTCHAR:
|
||||||
3:0 | 3 | ; RESET:
|
fc00:0 | fc00 | fc 20 ; PRINTCHAR
|
||||||
3:0 | 3 | 58 ; CLI
|
fc02:0 | fc02 | fd 1b ; GETCHAR
|
||||||
4:0 | 4 | fe ; INC B
|
fc04:0 | fc04 | fc 92 ; PRINTSTRING
|
||||||
5:0 | 5 | cd f0 05 ; STA TIMER
|
fc06:0 | fc06 | fd 59 ; GETSTRING
|
||||||
8:0 | 8 | 18 ; HLT
|
fc08:0 | fc08 | fc 9f ; PRINTHEX
|
||||||
9:0 | 9 | 98 f8 ; BRA RESET
|
fc0a:0 | fc0a | fd 8e ; SLEEP
|
||||||
b:0 | b | 41 ; RST
|
fc20:0 | fc20 | ; PRINTCHAR:
|
||||||
c:0 | c | ; INTERRUPT:
|
fc20:0 | fc20 | 48 ; PHA
|
||||||
c:0 | c | f6 ; INC A
|
fc21:0 | fc21 | 54 ; PHX
|
||||||
d:0 | d | 38 ; RUN
|
fc22:0 | fc22 | c9 0a ; CMP #$0A
|
||||||
e:0 | e | 40 ; RTI
|
fc24:0 | fc24 | f0 1a ; BEQ PRINTCHAR_NL
|
||||||
fffc:0 | fffc | 00 03 ; RESET
|
fc26:0 | fc26 | c9 0c ; CMP #$0C
|
||||||
fffe:0 | fffe | 00 0c ; INTERRUPT
|
fc28:0 | fc28 | f0 3d ; BEQ PRINT_CLS
|
||||||
|
fc2a:0 | fc2a | c9 08 ; CMP #$08
|
||||||
|
fc2c:0 | fc2c | f0 28 ; BEQ BACKSPACE
|
||||||
|
fc2e:0 | fc2e | a6 00 ; LDX CURSORPOS
|
||||||
|
fc30:0 | fc30 | c1 ; STA X+
|
||||||
|
fc31:0 | fc31 | 86 00 ; STX CURSORPOS
|
||||||
|
fc33:0 | fc33 | a5 01 ; LDA CURSORPOS+1
|
||||||
|
fc35:0 | fc35 | d0 06 ; BNE PRINTCHAR_RETURN
|
||||||
|
fc37:0 | fc37 | a5 00 ; LDA CURSORPOS
|
||||||
|
fc39:0 | fc39 | c9 c4 ; CMP #SCREEN_CHAR_OVFPG
|
||||||
|
fc3b:0 | fc3b | f0 2f ; BEQ SCROLLUP
|
||||||
|
fc3d:0 | fc3d | ; PRINTCHAR_RETURN:
|
||||||
|
fc3d:0 | fc3d | 74 ; PLX
|
||||||
|
fc3e:0 | fc3e | 68 ; PLA
|
||||||
|
fc3f:0 | fc3f | 60 ; RTS
|
||||||
|
fc40:0 | fc40 | ; PRINTCHAR_NL:
|
||||||
|
fc40:0 | fc40 | a5 01 ; LDA CURSORPOS+1
|
||||||
|
fc42:0 | fc42 | 29 c0 ; AND #$100-SCREEN_WIDTH
|
||||||
|
fc44:0 | fc44 | c9 c0 ; CMP #$100-SCREEN_WIDTH
|
||||||
|
fc46:0 | fc46 | d0 06 ; BNE NOSCROLLUP
|
||||||
|
fc48:0 | fc48 | a5 00 ; LDA CURSORPOS
|
||||||
|
fc4a:0 | fc4a | c9 c3 ; CMP #SCREEN_CHAR_MAXPG
|
||||||
|
fc4c:0 | fc4c | f0 1e ; BEQ SCROLLUP
|
||||||
|
fc4e:0 | fc4e | ; NOSCROLLUP:
|
||||||
|
fc4e:0 | fc4e | 6b 40 ; ADD #$40
|
||||||
|
fc50:0 | fc50 | 47 00 ; ICC CURSORPOS
|
||||||
|
fc52:0 | fc52 | 85 01 ; STA CURSORPOS+1
|
||||||
|
fc54:0 | fc54 | 98 e7 ; BRA PRINTCHAR_RETURN
|
||||||
|
fc56:0 | fc56 | ; BACKSPACE:
|
||||||
|
fc56:0 | fc56 | a5 01 ; LDA CURSORPOS+1
|
||||||
|
fc58:0 | fc58 | 29 3f ; AND #SCREEN_WIDTH-1
|
||||||
|
fc5a:0 | fc5a | f0 e1 ; BEQ PRINTCHAR_RETURN
|
||||||
|
fc5c:0 | fc5c | a6 00 ; LDX CURSORPOS
|
||||||
|
fc5e:0 | fc5e | e8 ff ; ADX #-1
|
||||||
|
fc60:0 | fc60 | 86 00 ; STX CURSORPOS
|
||||||
|
fc62:0 | fc62 | a9 00 ; LDA #$00
|
||||||
|
fc64:0 | fc64 | 81 ; STA X
|
||||||
|
fc65:0 | fc65 | 98 d6 ; BRA PRINTCHAR_RETURN
|
||||||
|
fc67:0 | fc67 | ; PRINT_CLS:
|
||||||
|
fc67:0 | fc67 | 20 fc a0 ; JSR CLEARSCREEN
|
||||||
|
fc6a:0 | fc6a | 98 d1 ; BRA PRINTCHAR_RETURN
|
||||||
|
fc6c:0 | fc6c | ; SCROLLUP:
|
||||||
|
fc6c:0 | fc6c | 14 ; PHY
|
||||||
|
fc6d:0 | fc6d | 48 ; PHA
|
||||||
|
fc6e:0 | fc6e | 5c ; PHB
|
||||||
|
fc6f:0 | fc6f | 1c ; PHC
|
||||||
|
fc70:0 | fc70 | aa c0 00 ; LDX #SCREEN_CHAR
|
||||||
|
fc73:0 | fc73 | a8 c0 40 ; LDY #SCREEN_CHAR+SCREEN_WIDTH
|
||||||
|
fc76:0 | fc76 | 2b 0f ; LDC #SCREEN_HEIGHT-1
|
||||||
|
fc78:0 | fc78 | ; SCROLLUP_LPOUT:
|
||||||
|
fc78:0 | fc78 | ab 40 ; LDB #SCREEN_WIDTH
|
||||||
|
fc7a:0 | fc7a | ; SCROLLUP_LPIN:
|
||||||
|
fc7a:0 | fc7a | f1 ; LDA Y+
|
||||||
|
fc7b:0 | fc7b | c1 ; STA X+
|
||||||
|
fc7c:0 | fc7c | de ; DEC B
|
||||||
|
fc7d:0 | fc7d | d0 fb ; BNE SCROLLUP_LPIN
|
||||||
|
fc7f:0 | fc7f | da ; DEC C
|
||||||
|
fc80:0 | fc80 | d0 f6 ; BNE SCROLLUP_LPOUT
|
||||||
|
fc82:0 | fc82 | 86 00 ; STX CURSORPOS
|
||||||
|
fc84:0 | fc84 | a9 00 ; LDA #$00
|
||||||
|
fc86:0 | fc86 | ab 40 ; LDB #SCREEN_WIDTH
|
||||||
|
fc88:0 | fc88 | ; SCROLLUP_LPC:
|
||||||
|
fc88:0 | fc88 | c1 ; STA X+
|
||||||
|
fc89:0 | fc89 | de ; DEC B
|
||||||
|
fc8a:0 | fc8a | d0 fc ; BNE SCROLLUP_LPC
|
||||||
|
fc8c:0 | fc8c | 3c ; PLC
|
||||||
|
fc8d:0 | fc8d | 7c ; PLB
|
||||||
|
fc8e:0 | fc8e | 68 ; PLA
|
||||||
|
fc8f:0 | fc8f | 34 ; PLY
|
||||||
|
fc90:0 | fc90 | 98 ab ; BRA PRINTCHAR_RETURN
|
||||||
|
fc92:0 | fc92 | ; PRINTSTRING:
|
||||||
|
fc92:0 | fc92 | 48 ; PHA
|
||||||
|
fc93:0 | fc93 | 54 ; PHX
|
||||||
|
fc94:0 | fc94 | ; PRINTSTRING_LOOP:
|
||||||
|
fc94:0 | fc94 | e1 ; LDA X+
|
||||||
|
fc95:0 | fc95 | f0 05 ; BEQ PRINTSTRING_DONE
|
||||||
|
fc97:0 | fc97 | 20 fc 20 ; JSR PRINTCHAR
|
||||||
|
fc9a:0 | fc9a | 98 f8 ; BRA PRINTSTRING_LOOP
|
||||||
|
fc9c:0 | fc9c | ; PRINTSTRING_DONE:
|
||||||
|
fc9c:0 | fc9c | 74 ; PLX
|
||||||
|
fc9d:0 | fc9d | 68 ; PLA
|
||||||
|
fc9e:0 | fc9e | 60 ; RTS
|
||||||
|
fc9f:0 | fc9f | ; PRINTHEX:
|
||||||
|
fc9f:0 | fc9f | 60 ; RTS
|
||||||
|
fca0:0 | fca0 | ; CLEARSCREEN:
|
||||||
|
fca0:0 | fca0 | 54 ; PHX
|
||||||
|
fca1:0 | fca1 | 14 ; PHY
|
||||||
|
fca2:0 | fca2 | 48 ; PHA
|
||||||
|
fca3:0 | fca3 | 5c ; PHB
|
||||||
|
fca4:0 | fca4 | 1c ; PHC
|
||||||
|
fca5:0 | fca5 | aa c0 00 ; LDX #SCREEN_CHAR
|
||||||
|
fca8:0 | fca8 | a8 c8 00 ; LDY #SCREEN_COLOR
|
||||||
|
fcab:0 | fcab | a9 10 ; LDA #SCREEN_HEIGHT
|
||||||
|
fcad:0 | fcad | 85 00 ; STA CURSORPOS
|
||||||
|
fcaf:0 | fcaf | a9 00 ; LDA #0
|
||||||
|
fcb1:0 | fcb1 | ab 26 ; LDB #SCREEN_BLACK
|
||||||
|
fcb3:0 | fcb3 | ; CLSLPOUT:
|
||||||
|
fcb3:0 | fcb3 | 2b 40 ; LDC #SCREEN_WIDTH
|
||||||
|
fcb5:0 | fcb5 | ; CLSLPIN:
|
||||||
|
fcb5:0 | fcb5 | c1 ; STA X+
|
||||||
|
fcb6:0 | fcb6 | d3 ; STB Y+
|
||||||
|
fcb7:0 | fcb7 | da ; DEC C
|
||||||
|
fcb8:0 | fcb8 | d0 fb ; BNE CLSLPIN
|
||||||
|
fcba:0 | fcba | c6 00 ; DEC CURSORPOS
|
||||||
|
fcbc:0 | fcbc | d0 f5 ; BNE CLSLPOUT
|
||||||
|
fcbe:0 | fcbe | aa c0 00 ; LDX #SCREEN_CHAR
|
||||||
|
fcc1:0 | fcc1 | 86 00 ; STX CURSORPOS
|
||||||
|
fcc3:0 | fcc3 | 3c ; PLC
|
||||||
|
fcc4:0 | fcc4 | 7c ; PLB
|
||||||
|
fcc5:0 | fcc5 | 68 ; PLA
|
||||||
|
fcc6:0 | fcc6 | 34 ; PLY
|
||||||
|
fcc7:0 | fcc7 | 74 ; PLX
|
||||||
|
fcc8:0 | fcc8 | 60 ; RTS
|
||||||
|
fcc9:0 | fcc9 | ; WAITKEY:
|
||||||
|
fcc9:0 | fcc9 | 20 fd 8e ; JSR SLEEP
|
||||||
|
fccc:0 | fccc | ; GETKEY:
|
||||||
|
fccc:0 | fccc | ed f1 00 ; LDA KEYBOARD
|
||||||
|
fccf:0 | fccf | f0 f8 ; BEQ WAITKEY
|
||||||
|
fcd1:0 | fcd1 | 60 ; RTS
|
||||||
|
fcd2:0 | fcd2 | ; KEY_SYMBOLS:
|
||||||
|
fcd2:0 | fcd2 | 30 30 29 31 31 21 32 32 40 33 33 23 34 34 24 35 35 25 36 36 5e 37 37 26 38 38 2a 39 39 28 ; "00)11!22@33#44$55%66^77&88*99("
|
||||||
|
fcf0:0 | fcf0 | 18 3b 3a 19 3d 2b 1a 2c 3c 1b 2e 3e 1c 2d 5f 1d 2f 3f 1e 60 7e ; "\x18;:\x19=+\x1A,<\x1B.>\x1C-_\x1D/?\x1E`~"
|
||||||
|
fd05:0 | fd05 | 3c 5b 7b 3d 5c 7c 3e 5d 7d 3f 27 22 ; "\x3C[{\x3D\\|\x3E]}\x3F'\x22"
|
||||||
|
fd11:0 | fd11 | 0d 0a 0a ; "\x0d\x0A\x0A"
|
||||||
|
fd14:0 | fd14 | 20 20 20 08 08 08 ; " \x08\x08\x08"
|
||||||
|
fd1a:0 | fd1a | 00 ; "\0"
|
||||||
|
fd1b:0 | fd1b | ; GETCHAR:
|
||||||
|
fd1b:0 | fd1b | 5c ; PHB
|
||||||
|
fd1c:0 | fd1c | ; GETCHAR_RESTART:
|
||||||
|
fd1c:0 | fd1c | 20 fc cc ; JSR GETKEY
|
||||||
|
fd1f:0 | fd1f | b7 ; TAB
|
||||||
|
fd20:0 | fd20 | 29 7b ; AND #$7B
|
||||||
|
fd22:0 | fd22 | c9 10 ; CMP #$10
|
||||||
|
fd24:0 | fd24 | f0 2c ; BEQ SHIFTKEY
|
||||||
|
fd26:0 | fd26 | 97 ; TBA
|
||||||
|
fd27:0 | fd27 | c9 80 ; CMP #$80
|
||||||
|
fd29:0 | fd29 | 90 f1 ; BLT GETCHAR_RESTART
|
||||||
|
fd2b:0 | fd2b | 29 7f ; AND #$7F
|
||||||
|
fd2d:0 | fd2d | c9 41 ; CMP #$41
|
||||||
|
fd2f:0 | fd2f | 90 04 ; BLT NOT_LETTER
|
||||||
|
fd31:0 | fd31 | c9 5a ; CMP #$5A
|
||||||
|
fd33:0 | fd33 | 10 1b ; BLE GETCHAR_RETURN
|
||||||
|
fd35:0 | fd35 | ; NOT_LETTER:
|
||||||
|
fd35:0 | fd35 | 54 ; PHX
|
||||||
|
fd36:0 | fd36 | aa fc d2 ; LDX #KEY_SYMBOLS
|
||||||
|
fd39:0 | fd39 | ; KEY_SYM_LP:
|
||||||
|
fd39:0 | fd39 | e3 ; LDB X+
|
||||||
|
fd3a:0 | fd3a | f0 11 ; BEQ KEY_SYM_DONE
|
||||||
|
fd3c:0 | fd3c | ; KEY_SYM_CONTINUE:
|
||||||
|
fd3c:0 | fd3c | dd ; CMP B
|
||||||
|
fd3d:0 | fd3d | f0 04 ; BEQ KEY_SYM_MATCH
|
||||||
|
fd3f:0 | fd3f | e8 02 ; ADX #2
|
||||||
|
fd41:0 | fd41 | 98 f6 ; BRA KEY_SYM_LP
|
||||||
|
fd43:0 | fd43 | ; KEY_SYM_MATCH:
|
||||||
|
fd43:0 | fd43 | a7 02 ; LDB SHIFTDOWN
|
||||||
|
fd45:0 | fd45 | f0 02 ; BEQ KEY_SYM_NOSHIFT
|
||||||
|
fd47:0 | fd47 | e8 01 ; ADX #1
|
||||||
|
fd49:0 | fd49 | ; KEY_SYM_NOSHIFT:
|
||||||
|
fd49:0 | fd49 | a1 ; LDA X
|
||||||
|
fd4a:0 | fd4a | 74 ; PLX
|
||||||
|
fd4b:0 | fd4b | 98 03 ; BRA GETCHAR_RETURN
|
||||||
|
fd4d:0 | fd4d | ; KEY_SYM_DONE:
|
||||||
|
fd4d:0 | fd4d | 74 ; PLX
|
||||||
|
fd4e:0 | fd4e | 98 cc ; BRA GETCHAR_RESTART
|
||||||
|
fd50:0 | fd50 | ; GETCHAR_RETURN:
|
||||||
|
fd50:0 | fd50 | 7c ; PLB
|
||||||
|
fd51:0 | fd51 | 60 ; RTS
|
||||||
|
fd52:0 | fd52 | ; SHIFTKEY:
|
||||||
|
fd52:0 | fd52 | 97 ; TBA
|
||||||
|
fd53:0 | fd53 | 29 80 ; AND #$80
|
||||||
|
fd55:0 | fd55 | 85 02 ; STA SHIFTDOWN
|
||||||
|
fd57:0 | fd57 | 98 c3 ; BRA GETCHAR_RESTART
|
||||||
|
fd59:0 | fd59 | ; GETSTRING:
|
||||||
|
fd59:0 | fd59 | 48 ; PHA
|
||||||
|
fd5a:0 | fd5a | 54 ; PHX
|
||||||
|
fd5b:0 | fd5b | ; GETSTRING_LOOP:
|
||||||
|
fd5b:0 | fd5b | 20 fd 1b ; JSR GETCHAR
|
||||||
|
fd5e:0 | fd5e | 20 fc 20 ; JSR PRINTCHAR
|
||||||
|
fd61:0 | fd61 | c1 ; STA X+
|
||||||
|
fd62:0 | fd62 | c9 08 ; CMP #$08
|
||||||
|
fd64:0 | fd64 | d0 02 ; BNE GETSTRING_NOBK
|
||||||
|
fd66:0 | fd66 | e8 fe ; ADX #-2
|
||||||
|
fd68:0 | fd68 | ; GETSTRING_NOBK:
|
||||||
|
fd68:0 | fd68 | c9 0a ; CMP #$0A
|
||||||
|
fd6a:0 | fd6a | d0 ef ; BNE GETSTRING_LOOP
|
||||||
|
fd6c:0 | fd6c | e8 ff ; ADX #-1
|
||||||
|
fd6e:0 | fd6e | a9 00 ; LDA #$00
|
||||||
|
fd70:0 | fd70 | 81 ; STA X
|
||||||
|
fd71:0 | fd71 | 74 ; PLX
|
||||||
|
fd72:0 | fd72 | 68 ; PLA
|
||||||
|
fd73:0 | fd73 | 60 ; RTS
|
||||||
|
fd74:0 | fd74 | ; STRCMP:
|
||||||
|
fd74:0 | fd74 | 54 ; PHX
|
||||||
|
fd75:0 | fd75 | 14 ; PHY
|
||||||
|
fd76:0 | fd76 | 48 ; PHA
|
||||||
|
fd77:0 | fd77 | 5c ; PHB
|
||||||
|
fd78:0 | fd78 | ; STRCMP_NEXTCHAR:
|
||||||
|
fd78:0 | fd78 | e1 ; LDA X+
|
||||||
|
fd79:0 | fd79 | f0 08 ; BEQ STRCMP_XOVER
|
||||||
|
fd7b:0 | fd7b | f3 ; LDB Y+
|
||||||
|
fd7c:0 | fd7c | f0 08 ; BEQ STRCMP_YOVER
|
||||||
|
fd7e:0 | fd7e | dd ; CMP B
|
||||||
|
fd7f:0 | fd7f | f0 f7 ; BEQ STRCMP_NEXTCHAR
|
||||||
|
fd81:0 | fd81 | 98 06 ; BRA STRCMP_RETURN
|
||||||
|
fd83:0 | fd83 | ; STRCMP_XOVER:
|
||||||
|
fd83:0 | fd83 | b1 ; LDA Y
|
||||||
|
fd84:0 | fd84 | 98 03 ; BRA STRCMP_RETURN
|
||||||
|
fd86:0 | fd86 | ; STRCMP_YOVER:
|
||||||
|
fd86:0 | fd86 | e8 ff ; ADX #-1
|
||||||
|
fd88:0 | fd88 | a1 ; LDA X
|
||||||
|
fd89:0 | fd89 | ; STRCMP_RETURN:
|
||||||
|
fd89:0 | fd89 | 7c ; PLB
|
||||||
|
fd8a:0 | fd8a | 68 ; PLA
|
||||||
|
fd8b:0 | fd8b | 34 ; PLY
|
||||||
|
fd8c:0 | fd8c | 74 ; PLX
|
||||||
|
fd8d:0 | fd8d | 60 ; RTS
|
||||||
|
fd8e:0 | fd8e | ; SLEEP:
|
||||||
|
fd8e:0 | fd8e | cd f0 05 ; STA TIMER
|
||||||
|
fd91:0 | fd91 | 18 ; HLT
|
||||||
|
fd92:0 | fd92 | 60 ; RTS
|
||||||
|
fd93:0 | fd93 | ; STR_HI:
|
||||||
|
fd93:0 | fd93 | 48 49 00 ; "HI\0"
|
||||||
|
fd96:0 | fd96 | ; STR_HIRES:
|
||||||
|
fd96:0 | fd96 | 48 45 4c 4c 4f 21 0a 00 ; "HELLO!\n\0"
|
||||||
|
fd9e:0 | fd9e | ; RESET:
|
||||||
|
fd9e:0 | fd9e | 20 fc a0 ; JSR CLEARSCREEN
|
||||||
|
fda1:0 | fda1 | 58 ; CLI
|
||||||
|
fda2:0 | fda2 | ; INPUTLP:
|
||||||
|
fda2:0 | fda2 | aa 02 00 ; LDX #$0200
|
||||||
|
fda5:0 | fda5 | 20 fd 59 ; JSR GETSTRING
|
||||||
|
fda8:0 | fda8 | a8 fd 93 ; LDY #STR_HI
|
||||||
|
fdab:0 | fdab | 20 fd 74 ; JSR STRCMP
|
||||||
|
fdae:0 | fdae | d0 f2 ; BNE INPUTLP
|
||||||
|
fdb0:0 | fdb0 | aa fd 96 ; LDX #STR_HIRES
|
||||||
|
fdb3:0 | fdb3 | 20 fc 92 ; JSR PRINTSTRING
|
||||||
|
fdb6:0 | fdb6 | 98 ea ; BRA INPUTLP
|
||||||
|
fdb8:0 | fdb8 | 18 ; HLT
|
||||||
|
fdb9:0 | fdb9 | 41 ; RST
|
||||||
|
fdba:0 | fdba | ; INTERRUPT:
|
||||||
|
fdba:0 | fdba | 38 ; RUN
|
||||||
|
fdbb:0 | fdbb | 40 ; RTI
|
||||||
|
fffc:0 | fffc | fd 9e ; RESET
|
||||||
|
fffe:0 | fffe | fd ba ; INTERRUPT
|
||||||
|
Binary file not shown.
@ -32,7 +32,9 @@ ICC zpg 47 4 Add the Carrry Flag to the value at an given 8-bit address,
|
|||||||
|
|
||||||
8-bit Arithmetic and Logic (A):
|
8-bit Arithmetic and Logic (A):
|
||||||
ADD # 6B 2 Add a given 8-bit value to the value in the A register, and set the Carry Flag and Zero Flag according to the result
|
ADD # 6B 2 Add a given 8-bit value to the value in the A register, and set the Carry Flag and Zero Flag according to the result
|
||||||
|
SUB # EB 2 Subtract a given 8-bit value from the value in the A register, and set the Carry Flag and Zero Flag according to the result
|
||||||
ADC # 69 2 Add a given 8-bit value plus the Carry Flag to the value in the A register, and set the Carry Flag and Zero Flag according to the result
|
ADC # 69 2 Add a given 8-bit value plus the Carry Flag to the value in the A register, and set the Carry Flag and Zero Flag according to the result
|
||||||
|
SBC # E9 2 Subtract a given 8-bit value from the value in the A register including the Carry Flag, and set the Carry Flag and Zero Flag according to the result
|
||||||
CMP # C9 2 Set the Carry Flag and Zero Flag according to the result of subtracting a given 8-bit value from the value in the A register
|
CMP # C9 2 Set the Carry Flag and Zero Flag according to the result of subtracting a given 8-bit value from the value in the A register
|
||||||
AND # 29 2 Bitwise AND the value in the A register with a given 8-bit value, and set the Zero Flag according to the result
|
AND # 29 2 Bitwise AND the value in the A register with a given 8-bit value, and set the Zero Flag according to the result
|
||||||
ORA # 09 2 Bitwise OR the value in the A register with a given 8-bit value, and set the Zero Flag according to the result
|
ORA # 09 2 Bitwise OR the value in the A register with a given 8-bit value, and set the Zero Flag according to the result
|
||||||
@ -205,7 +207,7 @@ TXV 96 1 Copy the 16-bit value in the X register into the 16-bit Inte
|
|||||||
TAS 95 1 Copy the value in the A register into the 8-bit Stack Pointer register
|
TAS 95 1 Copy the value in the A register into the 8-bit Stack Pointer register
|
||||||
TSA B5 1 Copy the 8-bit Stack Pointer into the A register
|
TSA B5 1 Copy the 8-bit Stack Pointer into the A register
|
||||||
|
|
||||||
Opcodes used: 189/256
|
Opcodes used: 191/256
|
||||||
0123456789ABCDEF
|
0123456789ABCDEF
|
||||||
00 | CC-BJA-BSA--JJ--
|
00 | CC-BJA-BSA--JJ--
|
||||||
10 | B--BSA-MCA-BSA-B
|
10 | B--BSA-MCA-BSA-B
|
||||||
@ -221,5 +223,5 @@ A0 | WBWBWBWBWBWBWWWW
|
|||||||
B0 | BBWBMMMMWBWBWBWB
|
B0 | BBWBMMMMWBWBWBWB
|
||||||
C0 | WB-B-AU-XA--JB-B
|
C0 | WB-B-AU-XA--JB-B
|
||||||
D0 | BBWB--UM-AU-XAU-
|
D0 | BBWB--UM-AU-XAU-
|
||||||
E0 | WBWB-AUAX-C--B-B
|
E0 | WBWB-AUAXACA-B-B
|
||||||
F0 | BBWB--UM-AUAXAUA
|
F0 | BBWB--UM-AUAXAUA
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
For a quick guide on how to use this project, see [getting-started.md](getting-started.md)<br>
|
For a quick guide on how to use this project, see [getting-started.md](getting-started.md)<br>
|
||||||
|
|
||||||
For a detailed description of the architecture, see [architecture.md](architecture.md)<br>
|
For a detailed description of the architecture, see [architecture.md](architecture.md)<br>
|
||||||
For a list of instructions, see [instructionList.txt](instructionList.txt)
|
For a list of instructions, see [instructionList.txt](instructionList.txt)<br>
|
||||||
For a memory map of the 8608-based computer, see [memoryMap.md](memoryMap.md)
|
For a memory map of the 8608-based computer, see [memoryMap.md](memoryMap.md)
|
||||||
|
|
||||||
To use the emulator, simply drag-and-drop an assembly code file onto [emulator/8608-emulator.bat](emulator/8608-emulator.bat)
|
To use the emulator, simply drag-and-drop an assembly code file onto [emulator/8608-emulator.bat](emulator/8608-emulator.bat)<br>
|
||||||
You must include the 8608 architecture file into your assembly code: [8608.asm](8608.asm)<br>
|
You must include the 8608 architecture file into your assembly code: [8608.asm](8608.asm)<br>
|
||||||
`#include "8608/8608.asm"`<br>
|
`#include "8608/8608.asm"`
|
||||||
|
|
||||||
Note: This project depends on several pieces of free and open-source software,<br>
|
Note: This project depends on several pieces of free and open-source software,<br>
|
||||||
whose binaries are included in the repository:<br>
|
whose binaries are included in the repository:<br>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user