more emulator features, sub # instr
This commit is contained in:
		| @@ -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,11 +531,12 @@ 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 not kb then | ||||||
| 		if con.blinkFrame < con.blinkFrames/2 then | 		if con.blinkFrame < con.blinkFrames/2 then | ||||||
| 			local curx, cury = con.scrX + #con.input*7 + 2, con.scrY+3 | 			local curx, cury = con.scrX + #con.input*7 + 2, con.scrY+3 | ||||||
| 			lg.rectangle("fill", curx, cury, 8, 12) | 			lg.rectangle("fill", curx, cury, 8, 12) | ||||||
| @@ -529,18 +545,110 @@ local function RedrawConsole(con) | |||||||
| 		if con.blinkFrame >= con.blinkFrames then con.blinkFrame = 0 end | 		if con.blinkFrame >= con.blinkFrames then con.blinkFrame = 0 end | ||||||
| 		if #con.input==0 then | 		if #con.input==0 then | ||||||
| 			lg.setColor(0.5,0.5,0.5) | 			lg.setColor(0.5,0.5,0.5) | ||||||
| 		lg.print(con.tempError or "Type a Command (@addr | addr=byte | addr=byte1 byte2 ...)", con.scrX+2+8, con.scrY+4) | 			lg.print(con.tempError or "Enter Command (>ticks | !addr | @addr | addr=byte | addr=byte1 byte2...)", con.scrX+2+8, con.scrY+4) | ||||||
| 		else | 		else | ||||||
| 			lg.print(con.input, con.scrX+2, con.scrY+4) | 			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 = {} |  | ||||||
| PlaySound = function(name, delay) |  | ||||||
| 	if (not delay) or delay==0 then |  | ||||||
| 	local sound = Sounds[name] or error("no sound with name: " .. name) | 	local sound = Sounds[name] or error("no sound with name: " .. name) | ||||||
| 	sound.lastPlayed = (sound.lastPlayed % #sound.sources) + 1 | 	sound.lastPlayed = (sound.lastPlayed % #sound.sources) + 1 | ||||||
| 	sound.sources[sound.lastPlayed]:play() | 	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> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Redo
					Redo