Compare commits
	
		
			3 Commits
		
	
	
		
			eaae7bb2d2
			...
			5f78ead08b
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 5f78ead08b | ||
|   | 7aa99412ba | ||
|   | 717a9d9b08 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +0,0 @@ | |||||||
| .vscode |  | ||||||
| programs |  | ||||||
							
								
								
									
										460
									
								
								8608-definition.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										460
									
								
								8608-definition.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,460 @@ | |||||||
|  | -- 8608-definition.lua | ||||||
|  | -- This file contains the formal definitions for each instruction in the 8608 architecture. | ||||||
|  | -- It is used by generate-architecture.lua to generate the following: | ||||||
|  | --   instructionList.txt, a human-readable list of all instructions. | ||||||
|  | --   8608.asm, a set of definitions for CustomAsm that allows it to assemble 8608 programs. | ||||||
|  | --   The microcode ROM data, which is built into the physical CPU to control it. | ||||||
|  |  | ||||||
|  | return { | ||||||
|  |  | ||||||
|  | -- List of every control line in the CPU | ||||||
|  | -- Organized by bit position within the four microcode ROMs | ||||||
|  | roms = { | ||||||
|  | 	{ pos = {0, 0, 0}, size = {64, 16, 64}, signals = { | ||||||
|  | 		"alulU", "alulT", "alulC", "alulB", "alulA", "alurIL", "alurIH", "alurVL", | ||||||
|  | 		"alurVH", "alurSL", "alurSH", "alurQL", "alurQH", "alurPL", "alurPH", "alurU", | ||||||
|  | 		"alurT", "alurC", "alurB", "alurA", "alur1", "alur2", "alurm1", "alurm2", | ||||||
|  | 		"adrrhU", "adrrhC", "adrrlT", "adrrTX", "adrrlB", "adrrBX", "adwrhU", "adwrhC", | ||||||
|  | 		"adwrlT", "adwrTX", "adwrlB", "adwrBX", "adwlI", "adwlV", "adwlS", "adwlQ", | ||||||
|  | 		"adwlP", "adrlI", "adrlV", "adrlS", "adrlQ", "adrlP", "aluAdd", "adwSaveV", | ||||||
|  | 		"aluRun", "aluRInv", "aluCinOn", "aluCinC", "memWriteAlur", "adrInc", "adwInc", "aluXor", | ||||||
|  | 		"aluIor", "aluAnd", "memWriteAlur", "adrOut", "adrSaveI", "adwSaveP", "adwSaveQ", "adwSaveS", | ||||||
|  | 	} }, | ||||||
|  | 	{ pos = {-34, 16, 0}, size = {32, 32, 8}, signals = { | ||||||
|  | 		"aluSaveU", "aluSaveT", "aluSaveC", "aluSaveB", "aluSaveA", "aluSaveCarry", "aluSaveNZ", "always1", | ||||||
|  | 	} }, | ||||||
|  | 	{ pos = {-34, 16, 17}, size = {32, 32, 32}, signals = { | ||||||
|  | 		"_", "_", "_", "_", "_", "_", "_", "_", | ||||||
|  | 		"_", "memSaveF", "memSaveNZ", "instrPre", "instrLoadPre", "always1", "instrLoadSel", "adrOut", | ||||||
|  | 		"memWriteAlur", "memSave", "instrNext0NZ", "instrNext0Z", "instrNext0NC", "instrNext0C", "instrLoadSub", "instrLoad", | ||||||
|  | 		"instrNext2", "instrNext1", "instrNext0", "memSaveU", "memSaveT", "memSaveC", "memSaveB", "memSaveA", | ||||||
|  | 	} }, | ||||||
|  | 	{ pos = {66, 16, 0}, size = {32, 32, 32}, signals = { | ||||||
|  | 		"adrr1", "adrrm1", "adrrm2", "adrr2", "adwrm1", "adwrm2", "adwr2", "adwr1", | ||||||
|  | 		"memRead", "memWrite", "runFlgVal", "runFlgClk", "intFlgVal", "intFlgClk", "irqFlgClk", "always1", | ||||||
|  | 		"aluShiftArith", "aluShiftRoll", "aluShiftRight", "aluShift", "alurF", "_", "_", "_", | ||||||
|  | 		"_", "_", "_", "_", "_", "_", "_", "_", | ||||||
|  | 	} }, | ||||||
|  | }, | ||||||
|  |  | ||||||
|  | -- Macro operations | ||||||
|  | -- These can be used as a shortcut to convey that multiple control lines should be set | ||||||
|  | -- Macro definitions may contain other macros | ||||||
|  | operations = { | ||||||
|  | 	base = {"always1"}, | ||||||
|  | 	 | ||||||
|  | 	instrNext = {"base","adrlI","adrInc","adrSaveI","loadInstr"}, | ||||||
|  | 	instrSub1 = {"base","instrLoadSub",                          "instrNext0"}, | ||||||
|  | 	instrSub2 = {"base","instrLoadSub",             "instrNext1",            }, | ||||||
|  | 	instrSub3 = {"base","instrLoadSub",             "instrNext1","instrNext0"}, | ||||||
|  | 	instrSub4 = {"base","instrLoadSub","instrNext2",                         }, | ||||||
|  | 	instrSub5 = {"base","instrLoadSub","instrNext2",             "instrNext0"}, | ||||||
|  | 	instrSub6 = {"base","instrLoadSub","instrNext2","instrNext1",            }, | ||||||
|  | 	instrSub7 = {"base","instrLoadSub","instrNext2","instrNext1","instrNext0"}, | ||||||
|  | 	instrSub23Cond = {"base","instrLoadSub","instrNext1"}, | ||||||
|  | 	instrSwapIV = {"base","adwlI","adwSaveV","adrlV","adrSaveI","loadInstr"}, | ||||||
|  | 	instrPreload = {"adrlI","adrInc","adrSaveI","adrOut","memRead","instrLoadSel","instrLoadPre"}, | ||||||
|  | 	instrNextPre = {"base","instrPre","instrLoad","instrLoadSub"}, | ||||||
|  | 	 | ||||||
|  | 	loadInstr = {"adrOut","memRead","instrLoadSel","instrLoad","instrLoadSub"}, | ||||||
|  | 	loadReg = {"adrOut","memRead","memSave"}, | ||||||
|  | 	storeReg = {"adrOut","memWrite","memWriteAlur"}, | ||||||
|  | 	loadRegT = {"loadReg","memSaveT"}, | ||||||
|  | 	 | ||||||
|  | 	pushReg = {"storeReg","adrlS","adwlS","adwInc","adwSaveS"}, | ||||||
|  | 	popReg = {"loadReg","adrlS","adrrm1","adwlS","adwrm1","adwSaveS"}, | ||||||
|  | 	pop161 = {"popReg","memSaveT"}, | ||||||
|  | 	pop162 = {"popReg","memSaveU"}, | ||||||
|  | 	 | ||||||
|  | 	loadImmed = {"adrlI","adrInc","adrSaveI","loadReg"}, | ||||||
|  | 	loadImmedT = {"loadImmed","memSaveT"}, | ||||||
|  | 	loadImm161 = {"loadImmed","memSaveU"}, | ||||||
|  | 	loadImm162 = {"loadImmed","memSaveT"}, | ||||||
|  | 	loadStackRel = {"adrlS","adrrTX","loadReg"}, | ||||||
|  | 	loadStackRelT = {"loadStackRel","memSaveT"}, | ||||||
|  | 	loadStackRelU = {"loadStackRel","memSaveU"}, | ||||||
|  | 	loadStackRel161 = {"loadStackRel",         "memSaveU"}, | ||||||
|  | 	loadStackRel162 = {"loadStackRel","adrInc","memSaveT"}, | ||||||
|  | 	storeStackRel = {"adrlS","adrrTX","storeReg"}, | ||||||
|  | 	storeStackRel161 = {"storeStackRel"         }, | ||||||
|  | 	storeStackRel162 = {"storeStackRel","adrInc"}, | ||||||
|  | 	storeStackRelU = {"storeStackRel","alurU"}, | ||||||
|  | 	load161 = {         "loadReg","memSaveU"}, | ||||||
|  | 	load162 = {"adrInc","loadReg","memSaveT"}, | ||||||
|  | 	store161 = {         "storeReg"}, | ||||||
|  | 	store162 = {"adrInc","storeReg"}, | ||||||
|  | 	loadUTU  = {"adrrUT",        "loadReg","memSaveU"}, | ||||||
|  | 	loadUTUP = {"adrrUT","adrlP","loadReg","memSaveU"}, | ||||||
|  | 	loadUTUQ = {"adrrUT","adrlQ","loadReg","memSaveU"}, | ||||||
|  | 	storeUT  = {"adrrUT",        "storeReg"}, | ||||||
|  | 	storeUTP = {"adrrUT","adrlP","storeReg"}, | ||||||
|  | 	storeUTQ = {"adrrUT","adrlQ","storeReg"}, | ||||||
|  | 	memSaveFlags = {"memSaveNZ"}, | ||||||
|  | 	 | ||||||
|  | 	adwrUT = {"adwrhU","adwrlT"}, | ||||||
|  | 	adrrUT = {"adrrhU","adrrlT"}, | ||||||
|  | 	adwrCB = {"adwrhC","adwrlB"}, | ||||||
|  | 	adwIncUT  = {"adwrUT",        "adwInc"}, | ||||||
|  | 	adwIncUTP = {"adwrUT","adwlP","adwInc"}, | ||||||
|  | 	adwIncUTQ = {"adwrUT","adwlQ","adwInc"}, | ||||||
|  | 	adwP = {"adwlP","adwSaveP"}, | ||||||
|  | 	adwQ = {"adwlQ","adwSaveQ"}, | ||||||
|  | 	adwS = {"adwlS","adwSaveS"}, | ||||||
|  | 	incP  = {"adwP","adwInc"}, | ||||||
|  | 	incQ  = {"adwQ","adwInc"}, | ||||||
|  | 	incP2 = {"adwP","adwr2"}, | ||||||
|  | 	incQ2 = {"adwP","adwr2"}, | ||||||
|  | 	 | ||||||
|  | 	jmpRelT = {"instrNext","adrrTX"}, | ||||||
|  | 	jmpAbs = {"base","loadInstr","adrSaveI"}, | ||||||
|  | 	jmpAbsUT = {"jmpAbs","adrrUT"}, | ||||||
|  | 	jmpAbsP = {"jmpAbs","adrlP"}, | ||||||
|  | 	jmpAbsQ = {"jmpAbs","adrlQ"}, | ||||||
|  | 	saveRetAddr = {"adwlI","adwInc","adwSaveQ"}, | ||||||
|  | 	pushRetAddr1 = {"alurIH","pushReg"}, | ||||||
|  | 	pushRetAddr2 = {"alurIL","pushReg"}, | ||||||
|  | 	 | ||||||
|  | 	aluA = {"alulA","aluSaveA"}, | ||||||
|  | 	aluB = {"alulB","aluSaveB"}, | ||||||
|  | 	aluC = {"alulC","aluSaveC"}, | ||||||
|  | 	aluT = {"alulT","aluSaveT"}, | ||||||
|  | 	aluU = {"alulU","aluSaveU"}, | ||||||
|  | 	aluOpAdd = {"aluRun","aluAdd","aluSaveCarry","aluSaveNZ"                     }, | ||||||
|  | 	aluOpAddC= {"aluRun","aluAdd","aluSaveCarry","aluSaveNZ",          "aluCinC" }, | ||||||
|  | 	aluOpSub = {"aluRun","aluAdd","aluSaveCarry","aluSaveNZ","aluRInv","aluCinOn"}, | ||||||
|  | 	aluOpSubC= {"aluRun","aluAdd","aluSaveCarry","aluSaveNZ","aluRInv","aluCinC" }, | ||||||
|  | 	aluOpAnd = {"aluRun","aluAnd"          , "aluSaveNZ"}, | ||||||
|  | 	aluOpIor = {"aluRun","aluIor"          , "aluSaveNZ"}, | ||||||
|  | 	aluOpXor = {"aluRun","aluXor"          , "aluSaveNZ"}, | ||||||
|  | 	aluOpCmp = {"aluOpSub"}, | ||||||
|  | 	aluOpInc = {"aluOpAdd","aluCinOn"}, | ||||||
|  | 	aluOpDec = {"aluOpAdd","aluRInv"}, | ||||||
|  | 	aluOpMov = {"aluAdd","aluSaveNZ"}, | ||||||
|  | 	aluOpShl = {"aluRun", "aluShift"                                               ,"aluSaveNZ"}, | ||||||
|  | 	aluOpShr = {"aluRun", "aluShift","aluShiftRight"                               ,"aluSaveNZ"}, | ||||||
|  | 	aluOpRol = {"aluRun", "aluShift",                "aluShiftRoll"                ,"aluSaveNZ"}, | ||||||
|  | 	aluOpRor = {"aluRun", "aluShift","aluShiftRight","aluShiftRoll"                ,"aluSaveNZ"}, | ||||||
|  | 	aluOpSra = {"aluRun", "aluShift","aluShiftRight",               "aluShiftArith","aluSaveNZ"}, | ||||||
|  | 	 | ||||||
|  | 	clearRegs = { | ||||||
|  | 		"aluSaveA","aluSaveB","aluSaveC","aluSaveU","aluSaveT", | ||||||
|  | 		"adwSaveP","adwSaveQ","adwSaveS","adwSaveV", | ||||||
|  | 		"adrSaveI", | ||||||
|  | 		"aluSaveNZ","aluSaveCarry", | ||||||
|  | 	} | ||||||
|  | }, | ||||||
|  |  | ||||||
|  | -- List of definitions for every instruction | ||||||
|  | -- Each instruction definition contains: | ||||||
|  | --   Mnemonic: The mnemonic used to generate the assembler definitions and instruction list. | ||||||
|  | --     This is what must literally appear in the assembly code in order to generate this instruction, other than immediate values. | ||||||
|  | --     "imm8" means an 8-bit value. | ||||||
|  | --     "imm16" means a 16-bit value. | ||||||
|  | --   Opcode: The machine code byte that represents this operation. | ||||||
|  | --     Used by the assembler generator to map mnemonics to opcodes. | ||||||
|  | --     Used by the microcode generator to place the instruction's data within the microcode ROM, which is addressed by opcode. | ||||||
|  | --   List of control signals: Specifies the control lines that will be activated by the microcode when the instruction is executed. | ||||||
|  | --     Instructions may take multiple clock cycles. To convey this, each clock cycle is represented by an independent list of microcode signals. | ||||||
|  | --     Under the hood, the microcode ROM uses a 10-bit address: 8 bits for the opcode, and 2 bits for the clock cycle. | ||||||
|  | --     Because of this, each opcode may only use up to 4 clock cycles. | ||||||
|  | --     If more are required, the least significant bit of the opcode can be set by a control line, incrementing the opcode. | ||||||
|  | --     This causes one instruction to use up multiple opcodes. | ||||||
|  | --     The need for this is determined automatically by the microcode generator: whenever an instruction specifies more than 4 lists of control signals. | ||||||
|  | --   Description: A brief description of the instruction. Used to generate the instruction list. | ||||||
|  | --   C Code: Used to generate an emulator (as part of a separate project). | ||||||
|  | -- Categories can be specified. These serve only to organize the instruction list. | ||||||
|  | --   The category letter determines what letter will be used to represent the instructions in the opcode map, located at the bottom of the instruction list. | ||||||
|  | instructions = { | ||||||
|  | 	{ category = "Control", catlet="C" }, | ||||||
|  | 	{ mnem="rst"         , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","clearRegs","loadInstr"}, desc="Clear all registers and set I=0", ccode={"cpu.a=0; cpu.b=0; cpu.c=0; cpu.u=0; cpu.t=0; cpu.p=0; cpu.q=0; cpu.s=0; cpu.v=0; cpu.i=0; cpu.cf=0; cpu.nz=0; cpu.irq=0; cpu.ifg=0; cpu.rfg=1; cpu.ien=0; lni;"} }, | ||||||
|  | 	{ mnem="hlt"         , opcode=0xF0, {"runFlgClk","instrNext"}, desc="Halt non-interrupt execution", ccode={"cpu.rfg=0; lni;"} }, | ||||||
|  | 	{ mnem="run"         , opcode=0xF1, {"runFlgClk","runFlgVal","instrNext"}, desc ="Resume non-interrupt execution", ccode={"cpu.rfg=1; lni;"} }, | ||||||
|  | 	{ mnem="int"         , opcode=0xF2, {"instrSwapIV","intFlgVal","intFlgClk","irqFlgClk"}, ccode={"cpu.irq=0; cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=(t-1)%65536; lni;"} }, | ||||||
|  | 	{ mnem="brk"         , opcode=0xF3, {"instrSwapIV","adwInc","intFlgVal","intFlgClk"}, desc="Trigger interrupt", ccode={"cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} }, | ||||||
|  | 	{ mnem="irt"         , opcode=0xF4, {"instrSwapIV","adwInc","intFlgClk"}, desc="Return from interrupt", ccode={"cpu.ifg=0; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} }, | ||||||
|  | 	{ mnem="nop"         , opcode=0xFF, {"instrNext"}, desc="Do nothing", ccode={"lni;"}, }, | ||||||
|  | 	{ mnem="ien"         , opcode=0xF5, {"instrNext"}, desc="Enbale interrupts", ccode={"cpu.ien=1; lni;"}, }, -- todo | ||||||
|  | 	{ mnem="idi"         , opcode=0xF6, {"instrNext"}, desc="Disable interrupts", ccode={"cpu.ien=0; lni;"}, }, -- todo | ||||||
|  | 	 | ||||||
|  | 	{ category = "16-bit Inc/Dec", catlet="I" }, | ||||||
|  | 	{ mnem="inc p"       , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++", ccode={"cpu.p++; lni;"} }, | ||||||
|  | 	{ mnem="dec p"       , opcode=0x15, {"adwlP","adwrm1","adwSaveP","instrNext"}, desc="P--", ccode={"cpu.p--; lni;"} }, | ||||||
|  | 	{ mnem="inc q"       , opcode=0x13, {"adwlQ","adwInc","adwSaveQ","instrNext"}, desc="Q++", ccode={"cpu.q++; lni;"} }, | ||||||
|  | 	{ mnem="dec q"       , opcode=0x16, {"adwlQ","adwrm1","adwSaveQ","instrNext"}, desc="Q--", ccode={"cpu.q--; lni;"} }, | ||||||
|  | 	 | ||||||
|  | 	{ category = "8-bit Unary", catlet="U" }, | ||||||
|  | 	{ mnem="inc a"       , opcode=0x10,                                                            {"aluA","alur1" ,"aluOpAdd" ,"instrNext"}, desc="A++, set flags"  , ccode={"addf(cpu.a, 1    ); lni;"} }, | ||||||
|  | 	{ mnem="dec a"       , opcode=0x11,                                                            {"aluA","alurm1","aluOpAdd" ,"instrNext"}, desc="A--, set flags"  , ccode={"addf(cpu.a,-1    ); lni;"} }, | ||||||
|  | 	{ mnem="icc a"       , opcode=0x1B,                                                            {"aluA",         "aluOpAddC","instrNext"}, desc="A+=CF, set flags", ccode={"addf(cpu.a,cpu.cf); lni;"} }, | ||||||
|  | 	{ mnem="inc b"       , opcode=0x19,                                                            {"aluB","alur1" ,"aluOpAdd" ,"instrNext"}, desc="B++, set flags"  , ccode={"addf(cpu.b, 1    ); lni;"} }, | ||||||
|  | 	{ mnem="dec b"       , opcode=0x1A,                                                            {"aluB","alurm1","aluOpAdd" ,"instrNext"}, desc="B--, set flags"  , ccode={"addf(cpu.b,-1    ); lni;"} }, | ||||||
|  | 	{ mnem="icc b"       , opcode=0x1C,                                                            {"aluB",         "aluOpAddC","instrNext"}, desc="B+=CF, set flags", ccode={"addf(cpu.b,cpu.cf); lni;"} }, | ||||||
|  | 	{ mnem="inc c"       , opcode=0x17,                                                            {"aluC","alur1" ,"aluOpAdd" ,"instrNext"}, desc="C++, set flags"  , ccode={"addf(cpu.c, 1    ); lni;"} }, | ||||||
|  | 	{ mnem="dec c"       , opcode=0x18,                                                            {"aluC","alurm1","aluOpAdd" ,"instrNext"}, desc="C--, set flags"  , ccode={"addf(cpu.c,-1    ); lni;"} }, | ||||||
|  | 	{ mnem="icc c"       , opcode=0x1D,                                                            {"aluC",         "aluOpAddC","instrNext"}, desc="C+=CF, set flags", ccode={"addf(cpu.c,cpu.cf); lni;"} }, | ||||||
|  | 	{ mnem="tst a"       , opcode=0x14,                                                            {"alulA",        "aluOpCmp" ,"instrNext"}, desc="Set flags according to A-0", ccode={"tst(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="tst b"       , opcode=0x1E,                                                            {"alulB",        "aluOpCmp" ,"instrNext"}, desc="Set flags according to B-0", ccode={"tst(cpu.b); lni;"} }, | ||||||
|  | 	{ mnem="tst c"       , opcode=0x1F,                                                            {"alulC",        "aluOpCmp" ,"instrNext"}, desc="Set flags according to C-0", ccode={"tst(cpu.c); lni;"} }, | ||||||
|  | 	{ mnem="inc *s+imm8" , opcode=0x2B, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alur1" ,"aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)++, set flags"  , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u, 1    );","instrloadpre"} }, | ||||||
|  | 	{ mnem="dec *s+imm8" , opcode=0x2C, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alurm1","aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)--, set flags"  , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,-1    );","instrloadpre"} }, | ||||||
|  | 	{ mnem="icc *s+imm8" , opcode=0x2D, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU",         "aluOpAddC","instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)+=CF, set flags", ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,cpu.cf);","instrloadpre"} }, | ||||||
|  | 	{ mnem="tst *s+imm8" , opcode=0x2E, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"alulU",        "aluOpCmp" ,"instrNext"},                                                   desc="Set flags according to *(S+imm8)-0", ccode={"loadimmedt","loadstackrelu","tst(cpu.u); lni;"} }, | ||||||
|  | 	 | ||||||
|  | 	{ category = "16-bit Arithmetic", catlet = "X"}, | ||||||
|  | 	{ mnem="adp imm8"    , opcode=0x4A, {"loadImmedT","instrSub1"}, {"adwP","adwrTX","instrNext"}, desc="P+=imm8 signed", ccode={"loadimmedt","cpu.p+=signed8(cpu.t); lni;"} }, | ||||||
|  | 	{ mnem="adq imm8"    , opcode=0x4B, {"loadImmedT","instrSub1"}, {"adwQ","adwrTX","instrNext"}, desc="Q+=imm8 signed", ccode={"loadimmedt","cpu.q+=signed8(cpu.t); lni;"} }, | ||||||
|  | 	{ mnem="ads imm8"    , opcode=0x4C, {"loadImmedT","instrSub1"}, {"adwS","adwrTX","instrNext"}, desc="S+=imm8 signed", ccode={"loadimmedt","cpu.s+=signed8(cpu.t); lni;"} }, | ||||||
|  | 	{ mnem="adp b"       , opcode=0xE6, {"adwP","adwrBX","instrNext"}, desc="P+=B signed", ccode={"cpu.p+=signed8(cpu.b); lni;"} }, | ||||||
|  | 	{ mnem="adq b"       , opcode=0xE7, {"adwQ","adwrBX","instrNext"}, desc="Q+=B signed", ccode={"cpu.q+=signed8(cpu.b); lni;"} }, | ||||||
|  | 	{ mnem="ads b"       , opcode=0xE8, {"adwS","adwrBX","instrNext"}, desc="S+=B signed", ccode={"cpu.s+=signed8(cpu.b); lni;"} }, | ||||||
|  | 	 | ||||||
|  | 	{ category = "8-bit Arithmetic/Logic", catlet="A" }, | ||||||
|  | 	{ mnem="add imm8"    , opcode=0x24, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=imm8, set flags"                , ccode={"loadimmedt","addf(cpu.a,cpu.t); lni;"} }, | ||||||
|  | 	{ mnem="adb imm8"    , opcode=0x72, {"loadImmedT","instrSub1"},                                {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=imm8, set flags"                , ccode={"loadimmedt","addf(cpu.b,cpu.t); lni;"} }, | ||||||
|  | 	{ mnem="adc imm8"    , opcode=0x73, {"loadImmedT","instrSub1"},                                {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=imm8, set flags"                , ccode={"loadimmedt","addf(cpu.c,cpu.t); lni;"} }, | ||||||
|  | 	{ mnem="acc imm8"    , opcode=0x78, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=imm8+CF, set flags"             , ccode={"loadimmedt","addf(cpu.a,cpu.t+cpu.cf); lni;"} }, | ||||||
|  | 	{ mnem="cmp imm8"    , opcode=0x71, {"loadImmedT","instrSub1"},                                {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-imm8"     , ccode={"loadimmedt","cmpf(cpu.a,cpu.t); lni;"} }, | ||||||
|  | 	{ mnem="and imm8"    , opcode=0x74, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=imm8, set zero flag"            , ccode={"loadimmedt","cpu.a&=cpu.t; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="ior imm8"    , opcode=0x75, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=imm8, set zero flag"            , ccode={"loadimmedt","cpu.a|=cpu.t; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="xor imm8"    , opcode=0x76, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=imm8, set zero flag"            , ccode={"loadimmedt","cpu.a^=cpu.t; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="shl imm8"    , opcode=0xD0, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=imm8, set zero flag"           , ccode={"loadimmedt","cpu.a<<=cpu.t; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="shr imm8"    , opcode=0xD1, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A>>=imm8, set zero flag"           , ccode={"loadimmedt","cpu.a>>=cpu.t; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="rol imm8"    , opcode=0xD2, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=imm8, set zero flag"          , ccode={"loadimmedt","cpu.a=rol(cpu.a,cpu.t); setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="ror imm8"    , opcode=0xD3, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=imm8, set zero flag"          , ccode={"loadimmedt","cpu.a=ror(cpu.a,cpu.t); setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="sra imm8"    , opcode=0xD4, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=imm8, set zero flag"          , ccode={"loadimmedt","cpu.a=sra(cpu.a,cpu.t); setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="add *s+imm8" , opcode=0xAE, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u); lni;"} }, | ||||||
|  | 	{ mnem="adb *s+imm8" , opcode=0x9B, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","addf(cpu.b,cpu.u); lni;"} }, | ||||||
|  | 	{ mnem="adc *s+imm8" , opcode=0x9C, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","addf(cpu.c,cpu.u); lni;"} }, | ||||||
|  | 	{ mnem="sub *s+imm8" , opcode=0xAF, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","subf(cpu.a,cpu.u); lni;"} }, | ||||||
|  | 	{ mnem="sbb *s+imm8" , opcode=0x9D, {"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 *s+imm8" , opcode=0x9E, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","subf(cpu.c,cpu.u); lni;"} }, | ||||||
|  | 	{ mnem="acc *s+imm8" , opcode=0xB5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=*(S+imm8)+CF, set flags"        , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u+cpu.cf); lni;"} }, | ||||||
|  | 	{ mnem="scc *s+imm8" , opcode=0xB7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=*(S+imm8)+CF, set flags"        , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,-cpu.u+cpu.cf); lni;"} }, | ||||||
|  | 	{ mnem="cmp *s+imm8" , opcode=0xB0, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-*(S+imm8)", ccode={"loadimmedt","loadstackrelu","cmpf(cpu.a,cpu.u); lni;"} }, | ||||||
|  | 	{ mnem="and *s+imm8" , opcode=0xB1, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=*(S+imm8), set zero flag"       , ccode={"loadimmedt","loadstackrelu","cpu.a&=cpu.u; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="ior *s+imm8" , opcode=0xB2, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=*(S+imm8), set zero flag"       , ccode={"loadimmedt","loadstackrelu","cpu.a|=cpu.u; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="xor *s+imm8" , opcode=0xB3, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=*(S+imm8), set zero flag"       , ccode={"loadimmedt","loadstackrelu","cpu.a^=cpu.u; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="shl *s+imm8" , opcode=0xD5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag"      , ccode={"loadimmedt","loadstackrelu","cpu.a<<=cpu.u; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="shr *s+imm8" , opcode=0xD6, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag"      , ccode={"loadimmedt","loadstackrelu","cpu.a>>=cpu.u; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="rol *s+imm8" , opcode=0xD7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=*(S+imm8), set zero flag"     , ccode={"loadimmedt","loadstackrelu","cpu.a=rol(cpu.a,cpu.u); setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="ror *s+imm8" , opcode=0xD8, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=*(S+imm8), set zero flag"     , ccode={"loadimmedt","loadstackrelu","cpu.a=ror(cpu.a,cpu.u); setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="sra *s+imm8" , opcode=0xD9, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=*(S+imm8), set zero flag"     , ccode={"loadimmedt","loadstackrelu","cpu.a=sra(cpu.a,cpu.u); setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="add b"       , opcode=0xA0,                                                            {"aluA", "alurB","aluOpAdd" ,"instrNext"}, desc="A+=B, set flags"                   , ccode={"addf(cpu.a,cpu.b); lni;"} }, | ||||||
|  | 	{ mnem="adc b"       , opcode=0x9F,                                                            {"aluC", "alurB","aluOpAdd" ,"instrNext"}, desc="C+=B, set flags"                   , ccode={"addf(cpu.c,cpu.b); lni;"} }, | ||||||
|  | 	{ mnem="sub b"       , opcode=0xA1,                                                            {"aluA", "alurB","aluOpSub" ,"instrNext"}, desc="A-=B, set flags"                   , ccode={"subf(cpu.a,cpu.b); lni;"} }, | ||||||
|  | 	{ mnem="sbc b"       , opcode=0xB6,                                                            {"aluC", "alurB","aluOpSub" ,"instrNext"}, desc="C-=B, set flags"                   , ccode={"subf(cpu.c,cpu.b); lni;"} }, | ||||||
|  | 	{ mnem="acc b"       , opcode=0xB8,                                                            {"aluA", "alurB","aluOpAddC","instrNext"}, desc="A+=B+CF, set flags"                , ccode={"addf(cpu.a,cpu.b+cpu.cf); lni;"} }, | ||||||
|  | 	{ mnem="scc b"       , opcode=0xB9,                                                            {"aluA", "alurB","aluOpSubC","instrNext"}, desc="A-=B+CF, set flags"                , ccode={"addf(cpu.a,-cpu.b+cpu.cf); lni;"} }, | ||||||
|  | 	{ mnem="cmp b"       , opcode=0xA2,                                                            {"alulA","alurB","aluOpSub" ,"instrNext"}, desc="set flags according to A-B"        , ccode={"cmpf(cpu.a,cpu.b); lni;"} }, | ||||||
|  | 	{ mnem="and b"       , opcode=0xA3,                                                            {"aluA", "alurB","aluOpAnd" ,"instrNext"}, desc="A&=B, set zero flag"               , ccode={"cpu.a&=cpu.b; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="ior b"       , opcode=0xA4,                                                            {"aluA", "alurB","aluOpIor" ,"instrNext"}, desc="A|=B, set zero flag"               , ccode={"cpu.a|=cpu.b; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="xor b"       , opcode=0xA5,                                                            {"aluA", "alurB","aluOpXor" ,"instrNext"}, desc="A^=B, set zero flag"               , ccode={"cpu.a^=cpu.b; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="shl b"       , opcode=0xDA,                                                            {"aluA", "alurB","aluOpShl" ,"instrNext"}, desc="A<<=B, set zero flag"              , ccode={"cpu.a<<=cpu.b; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="shr b"       , opcode=0xDB,                                                            {"aluA", "alurB","aluOpShr" ,"instrNext"}, desc="A>>=B, set zero flag"              , ccode={"cpu.a>>=cpu.b; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="rol b"       , opcode=0xDC,                                                            {"aluA", "alurB","aluOpRol" ,"instrNext"}, desc="A<<<=B, set zero flag"             , ccode={"cpu.a=rol(cpu.a,cpu.b); setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="ror b"       , opcode=0xDD,                                                            {"aluA", "alurB","aluOpRor" ,"instrNext"}, desc="A>>>=B, set zero flag"             , ccode={"cpu.a=ror(cpu.a,cpu.b); setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="sra b"       , opcode=0xDE,                                                            {"aluA", "alurB","aluOpSra" ,"instrNext"}, desc="A>>a=B, set zero flag"             , ccode={"cpu.a=sra(cpu.a,cpu.b); setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="add c"       , opcode=0xA7,                                                            {"aluA", "alurC","aluOpAdd" ,"instrNext"}, desc="A+=C, set flags"                   , ccode={"addf(cpu.a,cpu.c); lni;"} }, | ||||||
|  | 	{ mnem="adb c"       , opcode=0xBD,                                                            {"aluB", "alurC","aluOpAdd" ,"instrNext"}, desc="B+=C, set flags"                   , ccode={"addf(cpu.b,cpu.c); lni;"} }, | ||||||
|  | 	{ mnem="sub c"       , opcode=0xA8,                                                            {"aluA", "alurC","aluOpSub" ,"instrNext"}, desc="A-=C, set flags"                   , ccode={"subf(cpu.a,cpu.c); lni;"} }, | ||||||
|  | 	{ mnem="sbb c"       , opcode=0xBC,                                                            {"aluB", "alurC","aluOpSub" ,"instrNext"}, desc="B-=C, set flags"                   , ccode={"subf(cpu.b,cpu.c); lni;"} }, | ||||||
|  | 	{ mnem="acc c"       , opcode=0xBA,                                                            {"aluA", "alurC","aluOpAddC","instrNext"}, desc="A+=C+CF, set flags"                , ccode={"addf(cpu.a,cpu.c+cpu.cf); lni;"} }, | ||||||
|  | 	{ mnem="scc c"       , opcode=0xBB,                                                            {"aluA", "alurC","aluOpSubC","instrNext"}, desc="A-=C+CF, set flags"                , ccode={"addf(cpu.a,-cpu.c+cpu.cf); lni;"} }, | ||||||
|  | 	{ mnem="cmp c"       , opcode=0xA9,                                                            {"alulA","alurC","aluOpSub" ,"instrNext"}, desc="set flags according to A-C"        , ccode={"cmpf(cpu.a,cpu.c); lni;"} }, | ||||||
|  | 	{ mnem="and c"       , opcode=0xAA,                                                            {"aluA", "alurC","aluOpAnd" ,"instrNext"}, desc="A&=C, set zero flag"               , ccode={"cpu.a&=cpu.c; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="ior c"       , opcode=0xAB,                                                            {"aluA", "alurC","aluOpIor" ,"instrNext"}, desc="A|=C, set zero flag"               , ccode={"cpu.a|=cpu.c; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="xor c"       , opcode=0xAC,                                                            {"aluA", "alurC","aluOpXor" ,"instrNext"}, desc="A^=C, set zero flag"               , ccode={"cpu.a^=cpu.c; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="shl c"       , opcode=0xDF,                                                            {"aluA", "alurC","aluOpShl" ,"instrNext"}, desc="A<<=C, set zero flag"              , ccode={"cpu.a<<=cpu.c; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="shr c"       , opcode=0x4D,                                                            {"aluA", "alurC","aluOpShr" ,"instrNext"}, desc="A>>=C, set zero flag"              , ccode={"cpu.a>>=cpu.c; setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="rol c"       , opcode=0x3E,                                                            {"aluA", "alurC","aluOpRol" ,"instrNext"}, desc="A<<<=C, set zero flag"             , ccode={"cpu.a=rol(cpu.a,cpu.c); setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="ror c"       , opcode=0x3F,                                                            {"aluA", "alurC","aluOpRor" ,"instrNext"}, desc="A>>>=C, set zero flag"             , ccode={"cpu.a=ror(cpu.a,cpu.c); setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="sra c"       , opcode=0x2F,                                                            {"aluA", "alurC","aluOpSra" ,"instrNext"}, desc="A>>a=C, set zero flag"             , ccode={"cpu.a=sra(cpu.a,cpu.c); setzf(cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="adb a"       , opcode=0xBE,                                                            {"aluB", "alurA","aluOpAdd" ,"instrNext"}, desc="B+=A, set flags"                   , ccode={"addf(cpu.b,cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="sbb a"       , opcode=0xBF,                                                            {"aluB", "alurA","aluOpSub" ,"instrNext"}, desc="B-=A, set flags"                   , ccode={"subf(cpu.b,cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="adc a"       , opcode=0x4E,                                                            {"aluC", "alurA","aluOpAdd" ,"instrNext"}, desc="C+=A, set flags"                   , ccode={"addf(cpu.c,cpu.a); lni;"} }, | ||||||
|  | 	{ mnem="sbc a"       , opcode=0x4F,                                                            {"aluC", "alurA","aluOpSub" ,"instrNext"}, desc="C-=A, set flags"                   , ccode={"subf(cpu.c,cpu.a); lni;"} }, | ||||||
|  | 	 | ||||||
|  | 	{ category = "Jumps" , catlet="J" }, | ||||||
|  | 	{ mnem="jmp imm16"   , opcode=0x60, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT"              }, desc="I=imm16"     , ccode={"loadimm161","loadimm162","jmpabsut"} }, | ||||||
|  | 	{ mnem="jsr imm16"   , opcode=0x63, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT","saveRetAddr"}, desc="I=imm16, Q=I", ccode={"loadimm161","loadimm162","jmpabsut saveretaddr"} }, | ||||||
|  | 	{ mnem="jss imm16"   , opcode=0xE2, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushRetAddr1","instrSub3"}, {"pushRetAddr2","instrSub4"}, {"jmpAbsUT"}, desc="I=imm16, *(S++++)=I-1", ccode={"loadimm161","loadimm162","pushretaddr1","pushretaddr2","jmpabsut"} }, | ||||||
|  | 	{ mnem="jmp p"       , opcode=0x64, {"jmpAbsP"              }, desc="I=P"     , ccode={"jmpabsp"} }, | ||||||
|  | 	{ mnem="jmp q"       , opcode=0x66, {"jmpAbsQ"              }, desc="I=Q"     , ccode={"jmpabsq"} }, | ||||||
|  | 	{ mnem="jsr p"       , opcode=0x65, {"jmpAbsP","saveRetAddr"}, desc="I=P, Q=I", ccode={"jmpabsp","saveretaddr"} }, | ||||||
|  | 	{ mnem="jsr q"       , opcode=0x67, {"jmpAbsQ","saveRetAddr"}, desc="I=Q, Q=I", ccode={"jmpabsq","saveretaddr"} }, | ||||||
|  | 	{ mnem="jss p"       , opcode=0xE4, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsP"}, desc="I=P, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsp"} }, | ||||||
|  | 	{ mnem="jss q"       , opcode=0xE5, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsQ"}, desc="I=Q, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsq"} }, | ||||||
|  | 	{ mnem="rts"         , opcode=0xE1, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"jmpAbsUT","adrInc"}, desc="I=*(----S)+1", ccode={"pop161","pop162","jmpabsutplus1"} }, | ||||||
|  | 	{ mnem="jpr imm8"    , opcode=0x31, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub1"}, {"jmpRelT"}, desc="I+=imm8", ccode={"loadimmedt","jmprelt"} }, | ||||||
|  | 	{ mnem="jnz imm8"    , opcode=0x30, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NZ"               }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Zero"       , ccode={"loadimmedt","if( cpu.nz               ) { jmprelt } else { lni }"} }, | ||||||
|  | 	{ mnem="jpz imm8"    , opcode=0x32, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0Z"                }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero"        , ccode={"loadimmedt","if(!cpu.nz               ) { jmprelt } else { lni }"} }, | ||||||
|  | 	{ mnem="jlt imm8"    , opcode=0x33, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC"               }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Carry"      , ccode={"loadimmedt","if(!cpu.cf               ) { jmprelt } else { lni }"} }, | ||||||
|  | 	{ mnem="jge imm8"    , opcode=0x34, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C"                }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Carry"       , ccode={"loadimmedt","if( cpu.cf               ) { jmprelt } else { lni }"} }, | ||||||
|  | 	{ mnem="jgt imm8"    , opcode=0x35, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if(  cpu.nz &&    cpu.cf ) { jmprelt } else { lni }"} }, | ||||||
|  | 	{ mnem="jle imm8"    , opcode=0x36, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry", ccode={"loadimmedt","if((!cpu.nz) || (!cpu.cf)) { jmprelt } else { lni }"} }, | ||||||
|  | 	 | ||||||
|  | 	{ category = "Stack" , catlet="S" }, | ||||||
|  | 	{ mnem="psh a"       , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A", ccode={"pushbyte(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="psh b"       , opcode=0x44, {"pushReg","alurB","instrSub1"}, {"instrNext"}, desc="*(S++)=B", ccode={"pushbyte(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="psh c"       , opcode=0x45, {"pushReg","alurC","instrSub1"}, {"instrNext"}, desc="*(S++)=C", ccode={"pushbyte(cpu.c);","lni;"} }, | ||||||
|  | 	{ mnem="psh f"       , opcode=0xE9, {"pushReg","alurF","instrSub1"}, {"instrNext"}, desc="*(S++)=F", ccode={"int f = cpu.nz | (cpu.cf<<1); pushbyte(f);","lni;"} }, | ||||||
|  | 	{ mnem="psh p"       , opcode=0x41, {"pushReg","alurPH","instrSub1"}, {"pushReg","alurPL","instrSub2"}, {"instrNext"}, desc="*(S++++)=P", ccode={"push161(cpu.p);","push162(cpu.p);","lni;"} }, | ||||||
|  | 	{ mnem="psh q"       , opcode=0x46, {"pushReg","alurQH","instrSub1"}, {"pushReg","alurQL","instrSub2"}, {"instrNext"}, desc="*(S++++)=Q", ccode={"push161(cpu.q);","push162(cpu.q);","lni;"} }, | ||||||
|  | 	{ mnem="pop a"       , opcode=0x42, {"popReg","memSaveA","instrSub1"}, {"instrNext"}, desc="A=*(--S)", ccode={"cpu.a=popbyte;","lni;"} }, | ||||||
|  | 	{ mnem="pop b"       , opcode=0x47, {"popReg","memSaveB","instrSub1"}, {"instrNext"}, desc="B=*(--S)", ccode={"cpu.b=popbyte;","lni;"} }, | ||||||
|  | 	{ mnem="pop c"       , opcode=0x48, {"popReg","memSaveC","instrSub1"}, {"instrNext"}, desc="C=*(--S)", ccode={"cpu.c=popbyte;","lni;"} }, | ||||||
|  | 	{ mnem="pop f"       , opcode=0xEA, {"popReg","memSaveF","instrSub1"}, {"instrNext"}, desc="F=*(--S)", ccode={"int f=popbyte; cpu.nz = f&1; cpu.cf = (f>>1)&1;","lni;"} }, | ||||||
|  | 	{ mnem="pop p"       , opcode=0x43, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*(----S)", ccode={"pop161","pop162","cpu.p=wordut; lni;"} }, | ||||||
|  | 	{ mnem="pop q"       , opcode=0x49, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*(----S)", ccode={"pop161","pop162","cpu.q=wordut; lni;"} }, | ||||||
|  | 	{ mnem="psh imm8"    , opcode=0x3B, {"loadImmedT","instrSub1"}, {"pushReg","alurT","instrSub2"}, {"instrNext"}, desc="*(S++)=imm8", ccode={"loadimmedt;","pushbyte(cpu.t);","lni;"} }, | ||||||
|  | 	{ mnem="phw imm16"   , opcode=0x3C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushReg","alurU","instrSub3"}, {"pushReg","alurT","instrSub4"}, {"instrNext"}, desc="*(S++++)=imm16", ccode={"loadimm161","loadimm162","pushbyte(cpu.u);","pushbyte(cpu.t);","lni;"} }, -- 0x3D | ||||||
|  | 	 | ||||||
|  | 	{ category = "8-bit Load/Store", catlet="B" }, | ||||||
|  | 	{ mnem="lda imm8"    , opcode=0x20,                             {"loadImmed",   "memSaveA","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=imm8, update zero flag", ccode={"cpu.a=loadimmed; setzf(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="ldb imm8"    , opcode=0x26,                             {"loadImmed",   "memSaveB","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=imm8, update zero flag", ccode={"cpu.b=loadimmed; setzf(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="ldc imm8"    , opcode=0x27,                             {"loadImmed",   "memSaveC","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=imm8, update zero flag", ccode={"cpu.c=loadimmed; setzf(cpu.c);","lni;"} }, | ||||||
|  | 	{ mnem="lda *s+imm8" , opcode=0x28, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveA","memSaveFlags","instrSub2"}, {"instrNext"}, desc="A=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.a=loadstackrel; setzf(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="ldb *s+imm8" , opcode=0x29, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveB","memSaveFlags","instrSub2"}, {"instrNext"}, desc="B=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.b=loadstackrel; setzf(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="ldc *s+imm8" , opcode=0x2A, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveC","memSaveFlags","instrSub2"}, {"instrNext"}, desc="C=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.c=loadstackrel; setzf(cpu.c);","lni;"} }, | ||||||
|  | 	{ mnem="sta *s+imm8" , opcode=0x96, {"loadImmedT","instrSub1"}, {"storeStackRel","alurA","instrSub2"}, {"instrNext"}, desc="*s+imm8=A", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="stb *s+imm8" , opcode=0x97, {"loadImmedT","instrSub1"}, {"storeStackRel","alurB","instrSub2"}, {"instrNext"}, desc="*s+imm8=B", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="stc *s+imm8" , opcode=0x98, {"loadImmedT","instrSub1"}, {"storeStackRel","alurC","instrSub2"}, {"instrNext"}, desc="*s+imm8=C", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="lda *imm16"  , opcode=0x51, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT",        "loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*imm16, update zero flag",   ccode={"loadimm161","loadimm162","cpu.a=loadut; setzf(cpu.a);", "lni;"} }, | ||||||
|  | 	{ mnem="ldb *imm16"  , opcode=0x56, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT",        "loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*imm16, update zero flag",   ccode={"loadimm161","loadimm162","cpu.b=loadut; setzf(cpu.b);", "lni;"} }, | ||||||
|  | 	{ mnem="ldc *imm16"  , opcode=0x57, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT",        "loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*imm16, update zero flag",   ccode={"loadimm161","loadimm162","cpu.c=loadut; setzf(cpu.c);", "lni;"} }, | ||||||
|  | 	{ mnem="sta *imm16"  , opcode=0x50, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT",        "storeReg","alurA",                  "instrSub3"}, {"instrNext"}, desc="*imm16=A",                     ccode={"loadimm161","loadimm162","storeut(cpu.a);",             "lni;"} }, | ||||||
|  | 	{ mnem="stb *imm16"  , opcode=0x58, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT",        "storeReg","alurB",                  "instrSub3"}, {"instrNext"}, desc="*imm16=B",                     ccode={"loadimm161","loadimm162","storeut(cpu.b);",             "lni;"} }, | ||||||
|  | 	{ mnem="stc *imm16"  , opcode=0x59, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT",        "storeReg","alurC",                  "instrSub3"}, {"instrNext"}, desc="*imm16=C",                     ccode={"loadimm161","loadimm162","storeut(cpu.c);",             "lni;"} }, | ||||||
|  | 	{ mnem="lda *p+imm16", opcode=0x01, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadput; setzf(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="ldb *p+imm16", opcode=0xF7, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadput; setzf(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="ldc *p+imm16", opcode=0xFE, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadput; setzf(cpu.c);","lni;"} }, | ||||||
|  | 	{ mnem="lda *q+imm16", opcode=0xEB, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadqut; setzf(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="ldb *q+imm16", opcode=0x08, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadqut; setzf(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="ldc *q+imm16", opcode=0x09, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadqut; setzf(cpu.c);","lni;"} }, | ||||||
|  | 	{ mnem="sta *p+imm16", opcode=0x0A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurA",                  "instrSub3"}, {"instrNext"}, desc="*P+imm16=A",                   ccode={"loadimm161","loadimm162","storeput(cpu.a);",            "lni;"} }, | ||||||
|  | 	{ mnem="stb *p+imm16", opcode=0x0B, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurB",                  "instrSub3"}, {"instrNext"}, desc="*P+imm16=B",                   ccode={"loadimm161","loadimm162","storeput(cpu.b);",            "lni;"} }, | ||||||
|  | 	{ mnem="stc *p+imm16", opcode=0x0C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurC",                  "instrSub3"}, {"instrNext"}, desc="*P+imm16=C",                   ccode={"loadimm161","loadimm162","storeput(cpu.c);",            "lni;"} }, | ||||||
|  | 	{ mnem="sta *q+imm16", opcode=0x0D, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurA",                  "instrSub3"}, {"instrNext"}, desc="*Q+imm16=A",                   ccode={"loadimm161","loadimm162","storequt(cpu.a);",            "lni;"} }, | ||||||
|  | 	{ mnem="stb *q+imm16", opcode=0x0E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurB",                  "instrSub3"}, {"instrNext"}, desc="*Q+imm16=B",                   ccode={"loadimm161","loadimm162","storequt(cpu.b);",            "lni;"} }, | ||||||
|  | 	{ mnem="stc *q+imm16", opcode=0x0F, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurC",                  "instrSub3"}, {"instrNext"}, desc="*Q+imm16=C",                   ccode={"loadimm161","loadimm162","storequt(cpu.c);",            "lni;"} }, | ||||||
|  | 	{ mnem="lda *p"      , opcode=0x53, {"adrlP","loadReg", "memSaveA",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P, update zero flag", ccode={"cpu.a=loadp; setzf(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="ldb *p"      , opcode=0x5E, {"adrlP","loadReg", "memSaveB",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P, update zero flag", ccode={"cpu.b=loadp; setzf(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="ldc *p"      , opcode=0x5F, {"adrlP","loadReg", "memSaveC",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P, update zero flag", ccode={"cpu.c=loadp; setzf(cpu.c);","lni;"} }, | ||||||
|  | 	{ mnem="lda *q"      , opcode=0x55, {"adrlQ","loadReg", "memSaveA",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q, update zero flag", ccode={"cpu.a=loadq; setzf(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="ldb *q"      , opcode=0x61, {"adrlQ","loadReg", "memSaveB",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q, update zero flag", ccode={"cpu.b=loadq; setzf(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="ldc *q"      , opcode=0x62, {"adrlQ","loadReg", "memSaveC",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q, update zero flag", ccode={"cpu.c=loadq; setzf(cpu.c);","lni;"} }, | ||||||
|  | 	{ mnem="sta *p"      , opcode=0x52, {"adrlP","storeReg","alurA",                         "instrSub1"}, {"instrNext"}, desc="*P=A", ccode={"storep(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="stb *p"      , opcode=0x5A, {"adrlP","storeReg","alurB",                         "instrSub1"}, {"instrNext"}, desc="*P=B", ccode={"storep(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="stc *p"      , opcode=0x5B, {"adrlP","storeReg","alurC",                         "instrSub1"}, {"instrNext"}, desc="*P=C", ccode={"storep(cpu.c);","lni;"} }, | ||||||
|  | 	{ mnem="sta *q"      , opcode=0x54, {"adrlQ","storeReg","alurA",                         "instrSub1"}, {"instrNext"}, desc="*Q=A", ccode={"storeq(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="stb *q"      , opcode=0x5C, {"adrlQ","storeReg","alurB",                         "instrSub1"}, {"instrNext"}, desc="*Q=B", ccode={"storeq(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="stc *q"      , opcode=0x5D, {"adrlQ","storeReg","alurC",                         "instrSub1"}, {"instrNext"}, desc="*Q=C", ccode={"storeq(cpu.c);","lni;"} }, | ||||||
|  | 	{ mnem="lda *p++"    , opcode=0xC6, {"adrlP","loadReg", "memSaveA","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P++, update zero flag", ccode={"cpu.a=loadpinc; setzf(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="ldb *p++"    , opcode=0xC7, {"adrlP","loadReg", "memSaveB","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P++, update zero flag", ccode={"cpu.b=loadpinc; setzf(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="ldc *p++"    , opcode=0xC8, {"adrlP","loadReg", "memSaveC","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P++, update zero flag", ccode={"cpu.c=loadpinc; setzf(cpu.c);","lni;"} }, | ||||||
|  | 	{ mnem="lda *q++"    , opcode=0xC9, {"adrlQ","loadReg", "memSaveA","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q++, update zero flag", ccode={"cpu.a=loadqinc; setzf(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="ldb *q++"    , opcode=0xCA, {"adrlQ","loadReg", "memSaveB","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q++, update zero flag", ccode={"cpu.b=loadqinc; setzf(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="ldc *q++"    , opcode=0xCB, {"adrlQ","loadReg", "memSaveC","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q++, update zero flag", ccode={"cpu.c=loadqinc; setzf(cpu.c);","lni;"} }, | ||||||
|  | 	{ mnem="sta *p++"    , opcode=0xC0, {"adrlP","storeReg","alurA",   "incP",               "instrSub1"}, {"instrNext"}, desc="*P++=A", ccode={"storepinc(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="stb *p++"    , opcode=0xC1, {"adrlP","storeReg","alurB",   "incP",               "instrSub1"}, {"instrNext"}, desc="*P++=B", ccode={"storepinc(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="stc *p++"    , opcode=0xC2, {"adrlP","storeReg","alurC",   "incP",               "instrSub1"}, {"instrNext"}, desc="*P++=C", ccode={"storepinc(cpu.c);","lni;"} }, | ||||||
|  | 	{ mnem="sta *q++"    , opcode=0xC3, {"adrlQ","storeReg","alurA",   "incQ",               "instrSub1"}, {"instrNext"}, desc="*Q++=A", ccode={"storeqinc(cpu.a);","lni;"} }, | ||||||
|  | 	{ mnem="stb *q++"    , opcode=0xC4, {"adrlQ","storeReg","alurB",   "incQ",               "instrSub1"}, {"instrNext"}, desc="*Q++=B", ccode={"storeqinc(cpu.b);","lni;"} }, | ||||||
|  | 	{ mnem="stc *q++"    , opcode=0xC5, {"adrlQ","storeReg","alurC",   "incQ",               "instrSub1"}, {"instrNext"}, desc="*Q++=C", ccode={"storeqinc(cpu.c);","lni;"} }, | ||||||
|  | 	 | ||||||
|  | 	{ category = "16-bit Load/Store", catlet="W" }, | ||||||
|  | 	{ mnem="ldp imm16"   , opcode=0x21, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; lni;"} }, | ||||||
|  | 	{ mnem="ldq imm16"   , opcode=0x23, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; lni;"} }, | ||||||
|  | 	{ mnem="lds imm16"   , opcode=0x25, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveS","instrNext"}, desc="S=imm16", ccode={"loadimm161","loadimm162","cpu.s=wordut; lni;"} }, | ||||||
|  | 	{ mnem="ldv imm16"   , opcode=0x22, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveV","instrNext"}, desc="V=imm16", ccode={"loadimm161","loadimm162","cpu.v=wordut; lni;"} }, | ||||||
|  | 	{ mnem="ldp *s+imm8" , opcode=0x7A, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} }, | ||||||
|  | 	{ mnem="ldq *s+imm8" , opcode=0x7B, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} }, | ||||||
|  | 	{ mnem="stp *s+imm8" , opcode=0x7E, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurPH","instrSub2"}, {"storeStackRel162","alurPL","instrSub3"}, {"instrNext"}, desc="*S+imm8=P", ccode={"loadimmedt","storestackrel161(cpu.p);","storestackrel162(cpu.p);","lni;"} }, | ||||||
|  | 	{ mnem="stq *s+imm8" , opcode=0x7F, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurQH","instrSub2"}, {"storeStackRel162","alurQL","instrSub3"}, {"instrNext"}, desc="*S+imm8=Q", ccode={"loadimmedt","storestackrel161(cpu.q);","storestackrel162(cpu.q);","lni;"} }, | ||||||
|  | 	{ mnem="ldp *imm16"  , opcode=0x68, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU" ,"adwIncUT", "adwSaveP","instrSub3"}, {"adrlP","loadRegT",          "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0x69 | ||||||
|  | 	{ mnem="ldq *imm16"  , opcode=0x6A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU" ,"adwIncUT", "adwSaveQ","instrSub3"}, {"adrlQ","loadRegT",          "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0x6B | ||||||
|  | 	{ mnem="stp *imm16"  , opcode=0x6C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT" ,"alurPH",              "instrSub3"}, {"storeUT","adrInc","alurPL", "instrSub4"}, {                    "instrNext"}, desc="*imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;"       } }, -- 0x6D | ||||||
|  | 	{ mnem="stq *imm16"  , opcode=0x6E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT" ,"alurQH",              "instrSub3"}, {"storeUT","adrInc","alurQL", "instrSub4"}, {                    "instrNext"}, desc="*imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;"       } }, -- 0x6F | ||||||
|  | 	{ mnem="ldp *p+imm16", opcode=0xEC, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUP","adwIncUTP","adwSaveP","instrSub3"}, {"adrlP","loadRegT",          "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P+imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0xED | ||||||
|  | 	{ mnem="ldq *p+imm16", opcode=0xEE, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUP","adwIncUTP","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT",          "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P+imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0xEF | ||||||
|  | 	{ mnem="ldp *q+imm16", opcode=0xF8, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUQ","adwIncUTQ","adwSaveP","instrSub3"}, {"adrlP","loadRegT",          "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q+imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0xF9 | ||||||
|  | 	{ mnem="ldq *q+imm16", opcode=0xFA, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUQ","adwIncUTQ","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT",          "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*Q+imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0xFB | ||||||
|  | 	{ mnem="stq *p+imm16", opcode=0x06, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUTQ","alurQH",              "instrSub3"}, {"storeUTQ","adrInc","alurQL","instrSub4"}, {                    "instrNext"}, desc="*P+imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;"       } }, -- 0x07 | ||||||
|  | 	{ mnem="stp *q+imm16", opcode=0xFC, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUTP","alurPH",              "instrSub3"}, {"storeUTP","adrInc","alurPL","instrSub4"}, {                    "instrNext"}, desc="*Q+imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;"       } }, -- 0xFD | ||||||
|  | 	{ mnem="ldp *p"      , opcode=0x92, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, | ||||||
|  | 	{ mnem="ldq *p"      , opcode=0x93, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.q=wordut; lni;"} }, | ||||||
|  | 	{ mnem="ldp *q"      , opcode=0x94, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.p=wordut; lni;"} }, | ||||||
|  | 	{ mnem="ldq *q"      , opcode=0x95, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, | ||||||
|  | 	{ mnem="stp *q"      , opcode=0x7C, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2"}, {"instrNext"}, desc="*Q=P", ccode={"storeq(hibyte(cpu.p));","storeqp1(lobyte(cpu.p));","lni;"} }, | ||||||
|  | 	{ mnem="stq *p"      , opcode=0x7D, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2"}, {"instrNext"}, desc="*P=Q", ccode={"storep(hibyte(cpu.q));","storepp1(lobyte(cpu.q));","lni;"} }, | ||||||
|  | 	{ mnem="ldq *p++"    , opcode=0xCC, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2","incP2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P++++", ccode={"cpu.u=loadpinc;","cpu.t=loadpinc;","cpu.q=wordut; lni;"} }, | ||||||
|  | 	{ mnem="ldp *q++"    , opcode=0xCD, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2","incQ2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q++++", ccode={"cpu.u=loadqinc;","cpu.t=loadqinc;","cpu.p=wordut; lni;"} }, | ||||||
|  | 	{ mnem="stp *q++"    , opcode=0xCE, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2","incQ2"}, {"instrNext"}, desc="*Q++++=P", ccode={"storeqinc(hibyte(cpu.p));","storeqinc(lobyte(cpu.p));","lni;"} }, | ||||||
|  | 	{ mnem="stq *p++"    , opcode=0xCF, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2","incP2"}, {"instrNext"}, desc="*P++++=Q", ccode={"storepinc(hibyte(cpu.q));","storepinc(lobyte(cpu.q));","lni;"} }, | ||||||
|  | 	 | ||||||
|  | 	{ category = "Moves" , catlet="M" }, | ||||||
|  | 	{ mnem="lda b"       , opcode=0x80, {"alurB" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=B", ccode={"cpu.a=cpu.b; lni;"} }, | ||||||
|  | 	{ mnem="lda c"       , opcode=0x81, {"alurC" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=C", ccode={"cpu.a=cpu.c; lni;"} }, | ||||||
|  | 	{ mnem="ldb a"       , opcode=0x82, {"alurA" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=A", ccode={"cpu.b=cpu.a; lni;"} }, | ||||||
|  | 	{ mnem="ldb c"       , opcode=0x83, {"alurC" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=C", ccode={"cpu.b=cpu.c; lni;"} }, | ||||||
|  | 	{ mnem="ldc a"       , opcode=0x84, {"alurA" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=A", ccode={"cpu.c=cpu.a; lni;"} }, | ||||||
|  | 	{ mnem="ldc b"       , opcode=0x85, {"alurB" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=B", ccode={"cpu.c=cpu.b; lni;"} }, | ||||||
|  | 	{ mnem="lda pl"      , opcode=0x86, {"alurPL","aluOpMov","aluSaveA","instrNext"}, desc="A=P&FF", ccode={"cpu.a=lobyte(cpu.p); lni;"} }, | ||||||
|  | 	{ mnem="lda ph"      , opcode=0x87, {"alurPH","aluOpMov","aluSaveA","instrNext"}, desc="A=P>>8", ccode={"cpu.a=hibyte(cpu.p); lni;"} }, | ||||||
|  | 	{ mnem="lda ql"      , opcode=0x88, {"alurQL","aluOpMov","aluSaveA","instrNext"}, desc="A=Q&FF", ccode={"cpu.a=lobyte(cpu.q); lni;"} }, | ||||||
|  | 	{ mnem="lda qh"      , opcode=0x89, {"alurQH","aluOpMov","aluSaveA","instrNext"}, desc="A=Q>>8", ccode={"cpu.a=hibyte(cpu.q); lni;"} }, | ||||||
|  | 	{ mnem="ldb pl"      , opcode=0x37, {"alurPL","aluOpMov","aluSaveB","instrNext"}, desc="B=P&FF", ccode={"cpu.b=lobyte(cpu.p); lni;"} }, | ||||||
|  | 	{ mnem="ldc ph"      , opcode=0x38, {"alurPH","aluOpMov","aluSaveC","instrNext"}, desc="C=P>>8", ccode={"cpu.c=hibyte(cpu.p); lni;"} }, | ||||||
|  | 	{ mnem="ldb ql"      , opcode=0x39, {"alurQL","aluOpMov","aluSaveB","instrNext"}, desc="B=Q&FF", ccode={"cpu.b=lobyte(cpu.q); lni;"} }, | ||||||
|  | 	{ mnem="ldc qh"      , opcode=0x3A, {"alurQH","aluOpMov","aluSaveC","instrNext"}, desc="C=Q>>8", ccode={"cpu.c=hibyte(cpu.q); lni;"} }, | ||||||
|  | 	{ mnem="ldp q"       , opcode=0x8A, {"adwlQ" ,           "adwSaveP","instrNext"}, desc="P=Q", ccode={"cpu.p=cpu.q; lni;"} }, | ||||||
|  | 	{ mnem="ldp s"       , opcode=0x8B, {"adwlS" ,           "adwSaveP","instrNext"}, desc="P=S", ccode={"cpu.p=cpu.s; lni;"} }, | ||||||
|  | 	{ mnem="ldp v"       , opcode=0x8C, {"adwlV" ,           "adwSaveP","instrNext"}, desc="P=V", ccode={"cpu.p=cpu.v; lni;"} }, | ||||||
|  | 	{ mnem="ldp i"       , opcode=0x8D, {"adwlI" ,           "adwSaveP","instrNext"}, desc="P=I", ccode={"cpu.p=cpu.i; lni;"} }, | ||||||
|  | 	{ mnem="ldp cb"      , opcode=0x91, {"adwrCB",           "adwSaveP","instrNext"}, desc="P=(C<<8)+B", ccode={"cpu.p=wordcb; lni;"} }, | ||||||
|  | 	{ mnem="ldq cb"      , opcode=0xE0, {"adwrCB",           "adwSaveQ","instrNext"}, desc="Q=(C<<8)+B", ccode={"cpu.q=wordcb; lni;"} }, | ||||||
|  | 	{ mnem="ldq p"       , opcode=0x8E, {"adwlP" ,           "adwSaveQ","instrNext"}, desc="Q=P", ccode={"cpu.q=cpu.p; lni;"} }, | ||||||
|  | 	{ mnem="lds p"       , opcode=0x8F, {"adwlP" ,           "adwSaveS","instrNext"}, desc="S=P", ccode={"cpu.s=cpu.p; lni;"} }, | ||||||
|  | 	{ mnem="ldv p"       , opcode=0x90, {"adwlP" ,           "adwSaveV","instrNext"}, desc="V=P", ccode={"cpu.v=cpu.p; lni;"} }, | ||||||
|  | }, | ||||||
|  |  | ||||||
|  | -- Aliases for instructions | ||||||
|  | -- Used to generate the assembler definitions. | ||||||
|  | -- imm8neg instead of imm8 means the immediate value will be negated when assembling. | ||||||
|  | aliases = { | ||||||
|  | 	["jpz imm8" ] = {"jeq imm8"}, | ||||||
|  | 	["jnz imm8" ] = {"jne imm8"}, | ||||||
|  | 	["jmp q"    ] = {"ret"     }, | ||||||
|  | 	["add imm8" ] = {"sub imm8neg"}, | ||||||
|  | 	["adb imm8" ] = {"sbb imm8neg"}, | ||||||
|  | 	["adc imm8" ] = {"sbc imm8neg"}, | ||||||
|  | 	["acc imm8" ] = {"scc imm8neg"}, | ||||||
|  | }, | ||||||
|  |  | ||||||
|  | -- Filename to generate the assembler definitions file to. | ||||||
|  | assemblerDefsFile = "8608.asm", | ||||||
|  | -- Header to be inserted at the top of the assembler definitions file | ||||||
|  | assemblerDefsHeader = [[ | ||||||
|  | ; 8608.asm | ||||||
|  | ; Include this file into a CustomAsm assembly file to use the 8608 architecture, like so: | ||||||
|  | ;   #include "8608.asm" | ||||||
|  | ; See CustomAsm for more info: https://github.com/hlorenzi/customasm | ||||||
|  |  | ||||||
|  | ; Generated by generate-architecture.lua using the definitions in 8608-definition.lua | ||||||
|  | ; Definitions for all instructions in the 8608 architecture. | ||||||
|  | ]], | ||||||
|  |  | ||||||
|  | -- Filename to generate the instruction listing file to. | ||||||
|  | instructionListFile = "instructionList.txt", | ||||||
|  | -- Header to be inserted at the top of the instruction listing file | ||||||
|  | instructionListHeader = [[ | ||||||
|  | instructionList.txt | ||||||
|  | List of all instructions in the 8608 architecture. | ||||||
|  |  | ||||||
|  | Instructions are encoded as the opcode, followed by any immediate values. | ||||||
|  | 16-bit immediates are encoded in big-endian byte order. | ||||||
|  |  | ||||||
|  | Each instruction is described in order of: Mnemonic, Opcode, Clock cycles, Description | ||||||
|  | ]], | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										798
									
								
								8608.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										798
									
								
								8608.asm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,798 @@ | |||||||
|  | ; 8608.asm | ||||||
|  | ; Include this file into a customasm assembly file to use the 8608 architecture, like so: | ||||||
|  | ;   #include "8608.asm" | ||||||
|  |  | ||||||
|  | ; Generated by generate-architecture.lua using the definitions in 8608-definition.lua | ||||||
|  | ; Definitions for all instructions in the 8608 architecture. | ||||||
|  | #ruledef { | ||||||
|  | 	rst => $00 | ||||||
|  | 	hlt => $F0 | ||||||
|  | 	run => $F1 | ||||||
|  | 	int => $F2 | ||||||
|  | 	brk => $F3 | ||||||
|  | 	irt => $F4 | ||||||
|  | 	nop => $FF | ||||||
|  | 	ien => $F5 | ||||||
|  | 	idi => $F6 | ||||||
|  | 	inc p => $12 | ||||||
|  | 	dec p => $15 | ||||||
|  | 	inc q => $13 | ||||||
|  | 	dec q => $16 | ||||||
|  | 	inc a => $10 | ||||||
|  | 	dec a => $11 | ||||||
|  | 	icc a => $1B | ||||||
|  | 	inc b => $19 | ||||||
|  | 	dec b => $1A | ||||||
|  | 	icc b => $1C | ||||||
|  | 	inc c => $17 | ||||||
|  | 	dec c => $18 | ||||||
|  | 	icc c => $1D | ||||||
|  | 	tst a => $14 | ||||||
|  | 	tst b => $1E | ||||||
|  | 	tst c => $1F | ||||||
|  | 	inc *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$2B @ value`8 | ||||||
|  | 	} | ||||||
|  | 	inc *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$2B @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	dec *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$2C @ value`8 | ||||||
|  | 	} | ||||||
|  | 	dec *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$2C @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	icc *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$2D @ value`8 | ||||||
|  | 	} | ||||||
|  | 	icc *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$2D @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	tst *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$2E @ value`8 | ||||||
|  | 	} | ||||||
|  | 	tst *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$2E @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	adp {value: i8} => $4A @ value | ||||||
|  | 	adq {value: i8} => $4B @ value | ||||||
|  | 	ads {value: i8} => $4C @ value | ||||||
|  | 	adp b => $E6 | ||||||
|  | 	adq b => $E7 | ||||||
|  | 	ads b => $E8 | ||||||
|  | 	add {value: i8} => $24 @ value | ||||||
|  | 	sub {value:i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		$24 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	adb {value: i8} => $72 @ value | ||||||
|  | 	sbb {value:i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		$72 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	adc {value: i8} => $73 @ value | ||||||
|  | 	sbc {value:i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		$73 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	acc {value: i8} => $78 @ value | ||||||
|  | 	scc {value:i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		$78 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	cmp {value: i8} => $71 @ value | ||||||
|  | 	and {value: i8} => $74 @ value | ||||||
|  | 	ior {value: i8} => $75 @ value | ||||||
|  | 	xor {value: i8} => $76 @ value | ||||||
|  | 	shl {value: i8} => $D0 @ value | ||||||
|  | 	shr {value: i8} => $D1 @ value | ||||||
|  | 	rol {value: i8} => $D2 @ value | ||||||
|  | 	ror {value: i8} => $D3 @ value | ||||||
|  | 	sra {value: i8} => $D4 @ value | ||||||
|  | 	add *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$AE @ value`8 | ||||||
|  | 	} | ||||||
|  | 	add *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$AE @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	adb *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$9B @ value`8 | ||||||
|  | 	} | ||||||
|  | 	adb *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$9B @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	adc *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$9C @ value`8 | ||||||
|  | 	} | ||||||
|  | 	adc *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$9C @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	sub *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$AF @ value`8 | ||||||
|  | 	} | ||||||
|  | 	sub *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$AF @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	sbb *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$9D @ value`8 | ||||||
|  | 	} | ||||||
|  | 	sbb *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$9D @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	sbc *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$9E @ value`8 | ||||||
|  | 	} | ||||||
|  | 	sbc *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$9E @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	acc *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$B5 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	acc *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$B5 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	scc *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$B7 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	scc *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$B7 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	cmp *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$B0 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	cmp *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$B0 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	and *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$B1 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	and *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$B1 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	ior *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$B2 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	ior *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$B2 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	xor *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$B3 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	xor *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$B3 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	shl *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$D5 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	shl *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$D5 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	shr *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$D6 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	shr *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$D6 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	rol *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$D7 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	rol *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$D7 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	ror *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$D8 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	ror *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$D8 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	sra *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$D9 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	sra *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$D9 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	add b => $A0 | ||||||
|  | 	adc b => $9F | ||||||
|  | 	sub b => $A1 | ||||||
|  | 	sbc b => $B6 | ||||||
|  | 	acc b => $B8 | ||||||
|  | 	scc b => $B9 | ||||||
|  | 	cmp b => $A2 | ||||||
|  | 	and b => $A3 | ||||||
|  | 	ior b => $A4 | ||||||
|  | 	xor b => $A5 | ||||||
|  | 	shl b => $DA | ||||||
|  | 	shr b => $DB | ||||||
|  | 	rol b => $DC | ||||||
|  | 	ror b => $DD | ||||||
|  | 	sra b => $DE | ||||||
|  | 	add c => $A7 | ||||||
|  | 	adb c => $BD | ||||||
|  | 	sub c => $A8 | ||||||
|  | 	sbb c => $BC | ||||||
|  | 	acc c => $BA | ||||||
|  | 	scc c => $BB | ||||||
|  | 	cmp c => $A9 | ||||||
|  | 	and c => $AA | ||||||
|  | 	ior c => $AB | ||||||
|  | 	xor c => $AC | ||||||
|  | 	shl c => $DF | ||||||
|  | 	shr c => $4D | ||||||
|  | 	rol c => $3E | ||||||
|  | 	ror c => $3F | ||||||
|  | 	sra c => $2F | ||||||
|  | 	adb a => $BE | ||||||
|  | 	sbb a => $BF | ||||||
|  | 	adc a => $4E | ||||||
|  | 	sbc a => $4F | ||||||
|  | 	jmp {value: i16} => $60 @ value | ||||||
|  | 	jsr {value: i16} => $63 @ value | ||||||
|  | 	jss {value: i16} => $E2 @ value | ||||||
|  | 	jmp p => $64 | ||||||
|  | 	jmp q => $66 | ||||||
|  | 	ret => $66 | ||||||
|  | 	jsr p => $65 | ||||||
|  | 	jsr q => $67 | ||||||
|  | 	jss p => $E4 | ||||||
|  | 	jss q => $E5 | ||||||
|  | 	rts => $E1 | ||||||
|  | 	jpr {addr} => { | ||||||
|  | 		reladdr = addr - $ - 2 | ||||||
|  | 		assert(reladdr <=  127, "jpr: Relative jump target is too far away") | ||||||
|  | 		assert(reladdr >= -128, "jpr: Relative jump target is too far away") | ||||||
|  | 		$31 @ reladdr`8 | ||||||
|  | 	} | ||||||
|  | 	jnz {addr} => { | ||||||
|  | 		reladdr = addr - $ - 2 | ||||||
|  | 		assert(reladdr <=  127, "jnz: Relative jump target is too far away") | ||||||
|  | 		assert(reladdr >= -128, "jnz: Relative jump target is too far away") | ||||||
|  | 		$30 @ reladdr`8 | ||||||
|  | 	} | ||||||
|  | 	jne {addr} => { | ||||||
|  | 		reladdr = addr - $ - 2 | ||||||
|  | 		assert(reladdr <=  127, "jne: Relative jump target is too far away") | ||||||
|  | 		assert(reladdr >= -128, "jne: Relative jump target is too far away") | ||||||
|  | 		$30 @ reladdr`8 | ||||||
|  | 	} | ||||||
|  | 	jpz {addr} => { | ||||||
|  | 		reladdr = addr - $ - 2 | ||||||
|  | 		assert(reladdr <=  127, "jpz: Relative jump target is too far away") | ||||||
|  | 		assert(reladdr >= -128, "jpz: Relative jump target is too far away") | ||||||
|  | 		$32 @ reladdr`8 | ||||||
|  | 	} | ||||||
|  | 	jeq {addr} => { | ||||||
|  | 		reladdr = addr - $ - 2 | ||||||
|  | 		assert(reladdr <=  127, "jeq: Relative jump target is too far away") | ||||||
|  | 		assert(reladdr >= -128, "jeq: Relative jump target is too far away") | ||||||
|  | 		$32 @ reladdr`8 | ||||||
|  | 	} | ||||||
|  | 	jlt {addr} => { | ||||||
|  | 		reladdr = addr - $ - 2 | ||||||
|  | 		assert(reladdr <=  127, "jlt: Relative jump target is too far away") | ||||||
|  | 		assert(reladdr >= -128, "jlt: Relative jump target is too far away") | ||||||
|  | 		$33 @ reladdr`8 | ||||||
|  | 	} | ||||||
|  | 	jge {addr} => { | ||||||
|  | 		reladdr = addr - $ - 2 | ||||||
|  | 		assert(reladdr <=  127, "jge: Relative jump target is too far away") | ||||||
|  | 		assert(reladdr >= -128, "jge: Relative jump target is too far away") | ||||||
|  | 		$34 @ reladdr`8 | ||||||
|  | 	} | ||||||
|  | 	jgt {addr} => { | ||||||
|  | 		reladdr = addr - $ - 2 | ||||||
|  | 		assert(reladdr <=  127, "jgt: Relative jump target is too far away") | ||||||
|  | 		assert(reladdr >= -128, "jgt: Relative jump target is too far away") | ||||||
|  | 		$35 @ reladdr`8 | ||||||
|  | 	} | ||||||
|  | 	jle {addr} => { | ||||||
|  | 		reladdr = addr - $ - 2 | ||||||
|  | 		assert(reladdr <=  127, "jle: Relative jump target is too far away") | ||||||
|  | 		assert(reladdr >= -128, "jle: Relative jump target is too far away") | ||||||
|  | 		$36 @ reladdr`8 | ||||||
|  | 	} | ||||||
|  | 	psh a => $40 | ||||||
|  | 	psh b => $44 | ||||||
|  | 	psh c => $45 | ||||||
|  | 	psh f => $E9 | ||||||
|  | 	psh p => $41 | ||||||
|  | 	psh q => $46 | ||||||
|  | 	pop a => $42 | ||||||
|  | 	pop b => $47 | ||||||
|  | 	pop c => $48 | ||||||
|  | 	pop f => $EA | ||||||
|  | 	pop p => $43 | ||||||
|  | 	pop q => $49 | ||||||
|  | 	psh {value: i8} => $3B @ value | ||||||
|  | 	phw {value: i16} => $3C @ value | ||||||
|  | 	lda {value: i8} => $20 @ value | ||||||
|  | 	ldb {value: i8} => $26 @ value | ||||||
|  | 	ldc {value: i8} => $27 @ value | ||||||
|  | 	lda *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$28 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	lda *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$28 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	ldb *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$29 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	ldb *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$29 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	ldc *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$2A @ value`8 | ||||||
|  | 	} | ||||||
|  | 	ldc *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$2A @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	sta *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$96 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	sta *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$96 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	stb *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$97 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	stb *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$97 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	stc *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$98 @ value`8 | ||||||
|  | 	} | ||||||
|  | 	stc *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$98 @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	lda *{value: i16} => $51 @ value | ||||||
|  | 	ldb *{value: i16} => $56 @ value | ||||||
|  | 	ldc *{value: i16} => $57 @ value | ||||||
|  | 	sta *{value: i16} => $50 @ value | ||||||
|  | 	stb *{value: i16} => $58 @ value | ||||||
|  | 	stc *{value: i16} => $59 @ value | ||||||
|  | 	lda *p+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$01 @ value`16 | ||||||
|  | 	} | ||||||
|  | 	lda *p-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$01 @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	ldb *p+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$F7 @ value`16 | ||||||
|  | 	} | ||||||
|  | 	ldb *p-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$F7 @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	ldc *p+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$FE @ value`16 | ||||||
|  | 	} | ||||||
|  | 	ldc *p-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$FE @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	lda *q+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$EB @ value`16 | ||||||
|  | 	} | ||||||
|  | 	lda *q-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$EB @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	ldb *q+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$08 @ value`16 | ||||||
|  | 	} | ||||||
|  | 	ldb *q-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$08 @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	ldc *q+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$09 @ value`16 | ||||||
|  | 	} | ||||||
|  | 	ldc *q-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$09 @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	sta *p+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$0A @ value`16 | ||||||
|  | 	} | ||||||
|  | 	sta *p-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$0A @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	stb *p+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$0B @ value`16 | ||||||
|  | 	} | ||||||
|  | 	stb *p-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$0B @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	stc *p+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$0C @ value`16 | ||||||
|  | 	} | ||||||
|  | 	stc *p-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$0C @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	sta *q+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$0D @ value`16 | ||||||
|  | 	} | ||||||
|  | 	sta *q-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$0D @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	stb *q+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$0E @ value`16 | ||||||
|  | 	} | ||||||
|  | 	stb *q-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$0E @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	stc *q+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$0F @ value`16 | ||||||
|  | 	} | ||||||
|  | 	stc *q-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$0F @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	lda *p => $53 | ||||||
|  | 	ldb *p => $5E | ||||||
|  | 	ldc *p => $5F | ||||||
|  | 	lda *q => $55 | ||||||
|  | 	ldb *q => $61 | ||||||
|  | 	ldc *q => $62 | ||||||
|  | 	sta *p => $52 | ||||||
|  | 	stb *p => $5A | ||||||
|  | 	stc *p => $5B | ||||||
|  | 	sta *q => $54 | ||||||
|  | 	stb *q => $5C | ||||||
|  | 	stc *q => $5D | ||||||
|  | 	lda *p++ => $C6 | ||||||
|  | 	ldb *p++ => $C7 | ||||||
|  | 	ldc *p++ => $C8 | ||||||
|  | 	lda *q++ => $C9 | ||||||
|  | 	ldb *q++ => $CA | ||||||
|  | 	ldc *q++ => $CB | ||||||
|  | 	sta *p++ => $C0 | ||||||
|  | 	stb *p++ => $C1 | ||||||
|  | 	stc *p++ => $C2 | ||||||
|  | 	sta *q++ => $C3 | ||||||
|  | 	stb *q++ => $C4 | ||||||
|  | 	stc *q++ => $C5 | ||||||
|  | 	ldp {value: i16} => $21 @ value | ||||||
|  | 	ldq {value: i16} => $23 @ value | ||||||
|  | 	lds {value: i16} => $25 @ value | ||||||
|  | 	ldv {value: i16} => $22 @ value | ||||||
|  | 	ldp *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$7A @ value`8 | ||||||
|  | 	} | ||||||
|  | 	ldp *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$7A @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	ldq *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$7B @ value`8 | ||||||
|  | 	} | ||||||
|  | 	ldq *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$7B @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	stp *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$7E @ value`8 | ||||||
|  | 	} | ||||||
|  | 	stp *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$7E @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	stq *s+{value: i8} => { | ||||||
|  | 		assert(value <= 127, "Relative address is too far away") | ||||||
|  | 		assert(value >= -128, "Relative address is too far away") | ||||||
|  | 		$7F @ value`8 | ||||||
|  | 	} | ||||||
|  | 	stq *s-{value: i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 127, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -128, "Relative address is too far away") | ||||||
|  | 		$7F @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | 	ldp *{value: i16} => $68 @ value | ||||||
|  | 	ldq *{value: i16} => $6A @ value | ||||||
|  | 	stp *{value: i16} => $6C @ value | ||||||
|  | 	stq *{value: i16} => $6E @ value | ||||||
|  | 	ldp *p+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$EC @ value`16 | ||||||
|  | 	} | ||||||
|  | 	ldp *p-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$EC @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	ldq *p+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$EE @ value`16 | ||||||
|  | 	} | ||||||
|  | 	ldq *p-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$EE @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	ldp *q+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$F8 @ value`16 | ||||||
|  | 	} | ||||||
|  | 	ldp *q-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$F8 @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	ldq *q+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$FA @ value`16 | ||||||
|  | 	} | ||||||
|  | 	ldq *q-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$FA @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	stq *p+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$06 @ value`16 | ||||||
|  | 	} | ||||||
|  | 	stq *p-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$06 @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	stp *q+{value: i16} => { | ||||||
|  | 		assert(value <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(value >= -32768, "Relative address is too far away") | ||||||
|  | 		$FC @ value`16 | ||||||
|  | 	} | ||||||
|  | 	stp *q-{value: i16} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= 32767, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= -32768, "Relative address is too far away") | ||||||
|  | 		$FC @ mvalue`16 | ||||||
|  | 	} | ||||||
|  | 	ldp *p => $92 | ||||||
|  | 	ldq *p => $93 | ||||||
|  | 	ldp *q => $94 | ||||||
|  | 	ldq *q => $95 | ||||||
|  | 	stp *q => $7C | ||||||
|  | 	stq *p => $7D | ||||||
|  | 	ldq *p++ => $CC | ||||||
|  | 	ldp *q++ => $CD | ||||||
|  | 	stp *q++ => $CE | ||||||
|  | 	stq *p++ => $CF | ||||||
|  | 	lda b => $80 | ||||||
|  | 	lda c => $81 | ||||||
|  | 	ldb a => $82 | ||||||
|  | 	ldb c => $83 | ||||||
|  | 	ldc a => $84 | ||||||
|  | 	ldc b => $85 | ||||||
|  | 	lda pl => $86 | ||||||
|  | 	lda ph => $87 | ||||||
|  | 	lda ql => $88 | ||||||
|  | 	lda qh => $89 | ||||||
|  | 	ldb pl => $37 | ||||||
|  | 	ldc ph => $38 | ||||||
|  | 	ldb ql => $39 | ||||||
|  | 	ldc qh => $3A | ||||||
|  | 	ldp q => $8A | ||||||
|  | 	ldp s => $8B | ||||||
|  | 	ldp v => $8C | ||||||
|  | 	ldp i => $8D | ||||||
|  | 	ldp cb => $91 | ||||||
|  | 	ldq cb => $E0 | ||||||
|  | 	ldq p => $8E | ||||||
|  | 	lds p => $8F | ||||||
|  | 	ldv p => $90 | ||||||
|  | } | ||||||
							
								
								
									
										
											BIN
										
									
								
								arch8608.ods
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								arch8608.ods
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,716 +0,0 @@ | |||||||
|  |  | ||||||
| local function loadutf8table(fn) |  | ||||||
| 	local tt = {} |  | ||||||
| 	for l in io.lines(fn) do if l~="" then |  | ||||||
| 		local c, d = l:match("^([^ ]+) (.+)$") |  | ||||||
| 		local t = {}; for v in d:gmatch("[^ ]+") do table.insert(t, tonumber(v, 16)) end; |  | ||||||
| 		tt[c] = t |  | ||||||
| 	end end |  | ||||||
| 	return tt |  | ||||||
| end |  | ||||||
| local utf8table = loadutf8table((RelPath or "./").."utf8table.txt") |  | ||||||
|  |  | ||||||
| local function trim(s) return s:gsub("^ +", ""):gsub(" +$", "").."" end |  | ||||||
| local function getutf8len(c) |  | ||||||
| 	local d = c:byte() |  | ||||||
| 	if     bit.band(d, 0xE0)==0xC0 then return 2 |  | ||||||
| 	elseif bit.band(d, 0xF0)==0xE0 then return 3 |  | ||||||
| 	elseif bit.band(d, 0xF8)==0xF0 then return 4 |  | ||||||
| 	else error("invalid utf8 first byte: "..string.format("%02X", d)) end |  | ||||||
| end |  | ||||||
| local function validWordsFromInstrs(instrs) |  | ||||||
| 	local words = {} |  | ||||||
| 	for mnem, _ in pairs(instrs) do |  | ||||||
| 		for word in mnem:gmatch("[^ ]+") do |  | ||||||
| 			words[word] = true |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	return words |  | ||||||
| end |  | ||||||
| local function lobyte(n) return n%256 end |  | ||||||
| local function hibyte(n) return math.floor(n/256) end |  | ||||||
| local function decodeNumber(n) |  | ||||||
| 	n = trim(n) |  | ||||||
| 	local sign = 1; if n:sub(1, 1)=="-" then sign = -1; n = n:sub(2, #n); end; |  | ||||||
| 	if     n:sub(1, 1)=="$"                                 then return sign*(tonumber(n:sub(2, #n  ), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2) |  | ||||||
| 	elseif n:sub(1, 2)=="0x"                                then return sign*(tonumber(n:sub(3, #n  ), 16) or error("invalid hex number "..n)), math.ceil((#n-2)/2) |  | ||||||
| 	elseif n:sub(#n, #n)=="h" and n:find("^[0-9a-fA-F]+h$") then return sign*(tonumber(n:sub(1, #n-1), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2) |  | ||||||
| 	elseif n:sub(1, 2)=="0b"                                then return sign*(tonumber(n:sub(3, #n  ),  2) or error("invalid binary number "..n)), math.ceil((#n-2)/8) |  | ||||||
| 	elseif n:sub(#n, #n)=="b" and n:find("^[01]+b$")        then return sign*(tonumber(n:sub(1, #n-1),  2) or error("invalid binary number "..n)), math.ceil((#n-1)/8) |  | ||||||
| 	elseif n:sub(1, 3)=="lo(" and n:sub(#n, #n)==")"        then return lobyte(decodeNumber(n:sub(4, #n-1))), 1 |  | ||||||
| 	elseif n:sub(1, 3)=="hi(" and n:sub(#n, #n)==")"        then return hibyte(decodeNumber(n:sub(4, #n-1))), 1 |  | ||||||
| 	elseif n:find("^[0-9]+$") then |  | ||||||
| 		local v = sign*(tonumber(n) or error("invalid decimal number "..n)) |  | ||||||
| 		if v>=-128 and v<=255 then return v, 1 |  | ||||||
| 		elseif v>=-32768 and v<=65535 then return v, 2 |  | ||||||
| 		else error("out-of-range number "..v) end |  | ||||||
| 	else |  | ||||||
| 		return nil |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| local function mnemFromLine(line, instrs, validWords) |  | ||||||
| 	local imms = {} |  | ||||||
| 	local function addNum(n) |  | ||||||
| 		n = trim(n) |  | ||||||
| 		local val, len = decodeNumber(n) |  | ||||||
| 		assert(val and len, "invalid number "..n) |  | ||||||
| 		local linei8  = line:gsub(n, "imm8", 1, true):lower() |  | ||||||
| 		local linei16 = line:gsub(n, "imm16", 1, true):lower() |  | ||||||
| 		if len==1 and (not instrs[linei8]) and instrs[linei16] then len = 2 end |  | ||||||
| 		table.insert(imms, { val = val, len = len } ) |  | ||||||
| 		return " imm"..(len*8).." " |  | ||||||
| 	end |  | ||||||
| 	local function addLabel(n) |  | ||||||
| 		n = trim(n) |  | ||||||
| 		local len = 2 |  | ||||||
| 		local linei8 = line:gsub(n, "imm8", 1, true):lower() |  | ||||||
| 		if instrs[linei8] then len = 1 end |  | ||||||
| 		table.insert(imms, { label = n, len = len } ) |  | ||||||
| 		return " imm"..(len*8).." " |  | ||||||
| 	end |  | ||||||
| 	 |  | ||||||
| 	local mnem = " "..line:gsub(" ", "  ").." " |  | ||||||
| 	mnem = mnem:gsub("%- *", " %+%-") |  | ||||||
| 	mnem = mnem:gsub("([%*%+])", " %1 ") |  | ||||||
| 	mnem = mnem:gsub(" %-?%$[0-9a-fA-F]+ "       , function(n)                                 return addNum  (n)     end) |  | ||||||
| 	mnem = mnem:gsub(" %-?0x[0-9a-fA-F]+ "       , function(n)                                 return addNum  (n)     end) |  | ||||||
| 	mnem = mnem:gsub(" %-?0b[01]+ "              , function(n)                                 return addNum  (n)     end) |  | ||||||
| 	mnem = mnem:gsub(" %-?[0-9a-fA-F]+h "        , function(n) if not validWords[trim(n)] then return addNum  (n) end end) |  | ||||||
| 	mnem = mnem:gsub(" %-?[01]+b "               , function(n) if not validWords[trim(n)] then return addNum  (n) end end) |  | ||||||
| 	mnem = mnem:gsub(" %-?[0-9]+ "               , function(n) if not validWords[trim(n)] then return addNum  (n) end end) |  | ||||||
| 	mnem = mnem:gsub(" [a-zA-Z_][a-zA-Z0-9_%.]* ", function(n) if not validWords[trim(n)] then return addLabel(n) end end) |  | ||||||
| 	mnem = trim(mnem):gsub(" +", " "):lower() |  | ||||||
| 	 |  | ||||||
| 	if not instrs[mnem] then mnem = mnem:gsub("%+ imm", "imm") end |  | ||||||
| 	 |  | ||||||
| 	return mnem, imms |  | ||||||
| end |  | ||||||
| local function addByte(state, val, code) |  | ||||||
| 	assert(val>=-128 and val<=255, "invalid byte "..val) |  | ||||||
| 	assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr)) |  | ||||||
| 	state.memory[state.curAddr] = val%256 |  | ||||||
| 	if code then state.codeMap[state.curAddr] = true end |  | ||||||
| 	state.curAddr = state.curAddr + 1 |  | ||||||
| end |  | ||||||
| local function addWord(state, val, code) |  | ||||||
| 	assert(val>=0 and val<=65535, "invalid word "..val) |  | ||||||
| 	addByte(state, math.floor(val/256), code) |  | ||||||
| 	addByte(state, val%256, code) |  | ||||||
| end |  | ||||||
| local function addSpace(state, len) |  | ||||||
| 	for i = 1, len do |  | ||||||
| 		assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr)) |  | ||||||
| 		state.memory[state.curAddr] = false |  | ||||||
| 		state.curAddr = state.curAddr + 1 |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| local function assembleInstruction(line, state, instrs, validWords) |  | ||||||
| 	local mnem, imms = mnemFromLine(line, instrs, validWords) |  | ||||||
| 	local opcode = instrs[mnem] or error("invalid instruction \""..line.."\" (mnem \""..mnem.."\")") |  | ||||||
| 	local writeimms = true |  | ||||||
| 	local padlen = 0 |  | ||||||
| 	local isInstr |  | ||||||
| 	if type(opcode)=="function" then |  | ||||||
| 		padlen, writeimms = opcode(imms) |  | ||||||
| 		addSpace(state, padlen) |  | ||||||
| 	elseif opcode>=0 then |  | ||||||
| 		isInstr = true |  | ||||||
| 		addByte(state, opcode, isInstr) |  | ||||||
| 	end |  | ||||||
| 	if writeimms then |  | ||||||
| 		for _, imm in ipairs(imms) do |  | ||||||
| 			if imm.val then |  | ||||||
| 				if     imm.len==1 then addByte(state, imm.val, isInstr) |  | ||||||
| 				elseif imm.len==2 then addWord(state, imm.val, isInstr) |  | ||||||
| 				else error("invalid imm len") end |  | ||||||
| 			elseif imm.label then |  | ||||||
| 				table.insert(state.labelReplacements, { |  | ||||||
| 					name = imm.label, |  | ||||||
| 					addr = state.curAddr, |  | ||||||
| 					len = imm.len, |  | ||||||
| 					rel = imm.len==1, |  | ||||||
| 					isCode = isInstr, |  | ||||||
| 				}) |  | ||||||
| 				state.curAddr = state.curAddr + imm.len |  | ||||||
| 			else error("invalid imm") end |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| local directiveFunctions = { |  | ||||||
| 	fn     = function(state, fn) state.fileName = fn end, |  | ||||||
| 	ln     = function(state, ln) state.lineNum = tonumber(ln) end, |  | ||||||
| 	org    = function(state, addr) state.curAddr = decodeNumber(addr) or error("Invalid origin \""..addr.."\"") end, |  | ||||||
| 	align  = function(state, alns) local aln = decodeNumber(alns); if state.curAddr % aln ~= 0 then state.curAddr = state.curAddr + (aln - state.curAddr%aln) end end, |  | ||||||
| 	define = true, |  | ||||||
| 	space  = function(state, amts) local amt = decodeNumber(amts); state.curAddr = state.curAddr + amt; end, |  | ||||||
| } |  | ||||||
| local function postEvaluateExpression(expr, labels) |  | ||||||
| 	 |  | ||||||
| end |  | ||||||
| local function assembleCode(code, instrs, uexprs) |  | ||||||
| 	local validWords = validWordsFromInstrs(instrs) |  | ||||||
| 	 |  | ||||||
| 	local state = { |  | ||||||
| 		lineNum = 0, |  | ||||||
| 		fileName = "", |  | ||||||
| 		curAddr = 0, |  | ||||||
| 		memory = {}, |  | ||||||
| 		codeMap = {}, |  | ||||||
| 		labelReplacements = {}, |  | ||||||
| 		labelAddrs = {}, |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	for line in code:gmatch("[^\n]+") do |  | ||||||
| 		line = trim(line) |  | ||||||
| 		if line:sub(1, 1)=="." then -- directive |  | ||||||
| 			local dir, rest = line:match("^%.([^ ]+) *(.*)$") |  | ||||||
| 			assert(dir and rest, "no directive on line "..line) |  | ||||||
| 			local dirf = directiveFunctions[dir] or error("invalid directive "..dir) |  | ||||||
| 			dirf(state, rest) |  | ||||||
| 		elseif line:sub(#line, #line)==":" then -- label |  | ||||||
| 			local name = line:sub(1, #line-1) |  | ||||||
| 			assert(not state.labelAddrs[name], "redefinition of label "..name) |  | ||||||
| 			state.labelAddrs[name] = state.curAddr |  | ||||||
| 		elseif line:find("[^ ]") then |  | ||||||
| 			assembleInstruction(line, state, instrs, validWords) |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	 |  | ||||||
| 	for _, rep in ipairs(state.labelReplacements) do |  | ||||||
| 		local expr = uexprs[rep.name] |  | ||||||
| 		if expr then |  | ||||||
| 			local val = postEvaluateExpression(expr, state.labelAddrs) |  | ||||||
| 			if     rep.len==1 then addByte(state, val, rep.isCode) |  | ||||||
| 			elseif rep.len==2 then addWord(state, val, rep.isCode) |  | ||||||
| 			else error("invalid expr replace len "..rep.len) end |  | ||||||
| 		else |  | ||||||
| 			local labelAddr = state.labelAddrs[rep.name] or error("no label named "..rep.name) |  | ||||||
| 			state.curAddr = rep.addr |  | ||||||
| 			if     rep.len==1 then addByte(state, labelAddr-(rep.addr+1), rep.isCode) |  | ||||||
| 			elseif rep.len==2 then addWord(state, labelAddr             , rep.isCode) |  | ||||||
| 			else error("invalid labelreplace len "..rep.len) end |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	 |  | ||||||
| 	return state.memory, state.codeMap |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local function readFile(fn) |  | ||||||
| 	local fi, err = io.open(fn, "r") |  | ||||||
| 	if not fi then error("could not open file "..fn..": "..err) end |  | ||||||
| 	local text = fi:read("*a") |  | ||||||
| 	fi:close() |  | ||||||
| 	return text |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local function separateCommas(l) |  | ||||||
| 	local c = {}; for a in l:gmatch("[^,]+") do table.insert(c, trim(a)) end; return c; |  | ||||||
| end |  | ||||||
| local function evaluateExpression(expr, uexprs) |  | ||||||
| 	expr = expr:gsub("[^%+%-%*%/]+", function(word) |  | ||||||
| 		local val = decodeNumber(word) or error("invalid number in expression: "..word) |  | ||||||
| 		return val |  | ||||||
| 	end) |  | ||||||
| 	assert(not expr:find("[^a-zA-Z0-9_%(%)%+%-%*%/ \t\r\n]"), "invalid char in expression: "..expr) |  | ||||||
| 	local exprf = loadstring("return "..expr) |  | ||||||
| 	local eval = exprf() or error("invalid expr: "..expr) |  | ||||||
| 	return eval |  | ||||||
| end |  | ||||||
| local function preprocessCode(code) |  | ||||||
| 	code = "\n"..code.."\n" |  | ||||||
| 	 |  | ||||||
| 	local curscope = "" |  | ||||||
| 	local codet = {} |  | ||||||
| 	local wordt = {} |  | ||||||
| 	local lastword = "" |  | ||||||
| 	local function addword(word) |  | ||||||
| 		lastword = word |  | ||||||
| 		if word:sub(1, 1)=="." and not directiveFunctions[word:sub(2, #word)] then word = curscope..word end |  | ||||||
| 		table.insert(codet, word) |  | ||||||
| 	end |  | ||||||
| 	for i = 1, #code do |  | ||||||
| 		local c = code:sub(i, i) |  | ||||||
| 		if c:find("[%.a-zA-Z0-9_]") then table.insert(wordt, c) |  | ||||||
| 		else |  | ||||||
| 			if #wordt>0 then |  | ||||||
| 				addword(table.concat(wordt)) |  | ||||||
| 				wordt = {} |  | ||||||
| 			end |  | ||||||
| 			if c==":" and lastword:sub(1, 1)~="." and not lastword:find("_BRACE_") then |  | ||||||
| 				curscope = lastword |  | ||||||
| 			end |  | ||||||
| 			table.insert(codet, c) |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	 |  | ||||||
| 	code = "\n"..table.concat(codet).."\n" |  | ||||||
| 	 |  | ||||||
| 	local funcmacros = {} |  | ||||||
| 	code = code:gsub(".define ([%.a-zA-Z0-9_]+)%(([^%)]+)%) ([^\n]+)", function(name, args, repl) |  | ||||||
| 		local argt = separateCommas(args) |  | ||||||
| 		for argidx, arg in ipairs(argt) do assert(not arg:find("[^a-zA-Z0-9_]"), "invalid character in macro arg name: "..name.." "..arg) end |  | ||||||
| 		repl = " "..repl.." " |  | ||||||
| 		local invoc = 0 |  | ||||||
| 		funcmacros[name] = function(b, callargs) |  | ||||||
| 			invoc = invoc + 1 |  | ||||||
| 			local callargt = separateCommas(callargs) |  | ||||||
| 			local callrepl = repl |  | ||||||
| 			for argidx, arg in ipairs(argt) do |  | ||||||
| 				local callarg = callargt[argidx] |  | ||||||
| 				callrepl = callrepl:gsub("([^a-zA-Z0-9_])"..arg.."([^a-zA-Z0-9_])", "%1"..callarg.."%2") |  | ||||||
| 			end |  | ||||||
| 			callrepl = callrepl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_") |  | ||||||
| 			return b..callrepl |  | ||||||
| 		end |  | ||||||
| 		return "" |  | ||||||
| 	end) |  | ||||||
| 	for name, replf in pairs(funcmacros) do code = code:gsub("([^a-zA-Z0-9_])"..name.." *%(([^%)]+)%)", replf) end |  | ||||||
| 	 |  | ||||||
| 	local simplemacros = {} |  | ||||||
| 	code = code:gsub("%.define +([%.a-zA-Z0-9_]+) +([^\n]+)", function(name, repl) |  | ||||||
| 		assert(not simplemacros[name], "Redefinition of macro "..name) |  | ||||||
| 		simplemacros[name] = repl |  | ||||||
| 		return "" |  | ||||||
| 	end) |  | ||||||
| 	--for name, repl in pairs(simplemacros) do code = code:gsub(name, repl, 1, true) end |  | ||||||
| 	for name, repl in pairs(simplemacros) do |  | ||||||
| 		local invoc = 0 |  | ||||||
| 		code = code:gsub("([^a-zA-Z0-9_])"..name.."([^a-zA-Z0-9_])", function(b, a) |  | ||||||
| 			invoc = invoc+1 |  | ||||||
| 			return b..(repl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_"))..a |  | ||||||
| 		end) |  | ||||||
| 	end |  | ||||||
| 	 |  | ||||||
| 	code = code:gsub("\\", "\n") |  | ||||||
| 	 |  | ||||||
| 	local uexprs = {} |  | ||||||
| 	 |  | ||||||
| 	local codet = {} |  | ||||||
| 	local exprt = {} |  | ||||||
| 	local parenLevel = 0 |  | ||||||
| 	for i = 1, #code do |  | ||||||
| 		local c = code:sub(i, i) |  | ||||||
| 		if c=="(" then |  | ||||||
| 			if parenLevel>0 then table.insert(exprt, c) end |  | ||||||
| 			parenLevel = parenLevel+1 |  | ||||||
| 		elseif c==")" then |  | ||||||
| 			parenLevel = parenLevel-1 |  | ||||||
| 			if parenLevel==0 then |  | ||||||
| 				table.insert(codet, evaluateExpression(table.concat(exprt), uexprs)) |  | ||||||
| 				exprt = {} |  | ||||||
| 			else |  | ||||||
| 				table.insert(exprt, c) |  | ||||||
| 			end |  | ||||||
| 		else |  | ||||||
| 			if parenLevel==0 then table.insert(codet, c) |  | ||||||
| 			else                  table.insert(exprt, c) end |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	code = table.concat(codet) |  | ||||||
| 	 |  | ||||||
| 	return code, uexprs |  | ||||||
| end |  | ||||||
| local function fixCode(code) |  | ||||||
| 	code = code:gsub(",", " ") |  | ||||||
| 	code = code:gsub(":([^\\/])", ":\n%1") |  | ||||||
| 	code = code:gsub("[ \t]+:", ":") |  | ||||||
| 	code = code:gsub("%]", " %] ") |  | ||||||
| 	code = code:gsub("%[", " %[ ") |  | ||||||
| 	code = code:gsub("%*", " %* ") |  | ||||||
| 	code = code:gsub("\n[ \t\r\n]*", "\n") |  | ||||||
| 	code = code:gsub(" +", " ") |  | ||||||
| 	 |  | ||||||
| 	return code |  | ||||||
| end |  | ||||||
| local stringEscapes = { ["\\"] = "\\", ["n"] = "\n", ["r"] = "\r", ["t"] = "\t", ["0"] = "\0", ["\""] = "\"", ["\'"] = "\'", } |  | ||||||
| local prefixIdx = 0 |  | ||||||
| local function prefixCode(code, fn) -- fix strings, add line numbers |  | ||||||
| 	prefixIdx = prefixIdx + 1 |  | ||||||
| 	 |  | ||||||
| 	local outt = {} |  | ||||||
| 	local outnextnl = {} |  | ||||||
| 	local linenum = 1 |  | ||||||
| 	local skipnl = false |  | ||||||
| 	local function last() return outt[#outt] end |  | ||||||
| 	local function out(c) assert(type(c)=="string"); table.insert(outt, c); end |  | ||||||
| 	local function outn(n) out("$"..string.format("%02X", n)) out("\\") end |  | ||||||
| 	local function outnext(c) assert(type(c)=="string"); table.insert(outnextnl, c); end |  | ||||||
| 	local state = "code" -- code, comment, string, stringesc, commentml |  | ||||||
| 	 |  | ||||||
| 	local lastbracelabel = 0 |  | ||||||
| 	local function bracelabel() lastbracelabel = lastbracelabel+1; return "_BRACE_"..string.format("%02d", prefixIdx)..lastbracelabel.."_"; end |  | ||||||
| 	local bracestack = {} |  | ||||||
| 	local bracehasmid = {} |  | ||||||
| 	local lastnl = false |  | ||||||
| 	 |  | ||||||
| 	local utf8str = "" |  | ||||||
| 	local utf8len = 0 |  | ||||||
| 	 |  | ||||||
| 	local function newline() |  | ||||||
| 		lastnl = true |  | ||||||
| 		for _, v in ipairs(outnextnl) do |  | ||||||
| 			if v=="\n" and skipnl then out("\\") |  | ||||||
| 			else                       out(v)    end |  | ||||||
| 		end; outnextnl = {}; |  | ||||||
| 	end |  | ||||||
| 	 |  | ||||||
| 	out(".ln 1"); out("\n"); |  | ||||||
| 	for i = 1, #code do |  | ||||||
| 		local c = code:sub(i, i) |  | ||||||
| 		local cn = code:sub(i+1, i+1) |  | ||||||
| 		local cp = code:sub(i-1, i-1) |  | ||||||
| 		 |  | ||||||
| 		if state=="code" then |  | ||||||
| 			if     c=="\r" then |  | ||||||
| 			elseif c=="\n" or (c=="/" and cn~="/" and cn~="*") then |  | ||||||
| 				linenum = linenum+1 |  | ||||||
| 				if not skipnl then out("\n") out(".ln "..linenum); out("\n"); end |  | ||||||
| 				newline() |  | ||||||
| 				skipnl = false |  | ||||||
| 			elseif c=="#"  or c==";" or (c=="/" and cn=="/") then state = "comment" |  | ||||||
| 			elseif c=="/" and cn=="*" then state = "commentml" |  | ||||||
| 			elseif c=="\t" or c==" " then if (not lastnl) then out(" ") end |  | ||||||
| 			elseif c=="\"" then state = "string" lastnl = false |  | ||||||
| 			elseif c=="\\" then skipnl = true; out("\\"); |  | ||||||
| 			elseif c==":" then out(c); if skipnl then out("\\") else out("\n") end; lastnl = true; |  | ||||||
| 			elseif c:find("^[a-zA-Z0-9_%.%$%(%)%*,%[%]%+%-%*%/]$") then out(c); lastnl = false |  | ||||||
| 			elseif c=="{" then |  | ||||||
| 				table.insert(bracestack, bracelabel()) |  | ||||||
| 				if not lastnl then out(bracestack[#bracestack].."MID") end |  | ||||||
| 				outnext(bracestack[#bracestack].."START:"); outnext("\n"); |  | ||||||
| 			elseif c=="}" then |  | ||||||
| 				if not lastnl then out(bracestack[#bracestack].."START") end |  | ||||||
| 				if not bracehasmid[#bracestack] then outnext(bracestack[#bracestack].."MID:"); outnext("\n"); end |  | ||||||
| 				outnext(bracestack[#bracestack].."END:"); outnext("\n"); |  | ||||||
| 				bracehasmid[#bracestack] = nil |  | ||||||
| 				bracestack[#bracestack] = nil |  | ||||||
| 			elseif c=="|" then |  | ||||||
| 				if not lastnl then out(bracestack[#bracestack].."END") end |  | ||||||
| 				outnext(bracestack[#bracestack].."MID:"); outnext("\n"); |  | ||||||
| 				bracehasmid[#bracestack] = true |  | ||||||
| 			else error("invalid char "..c) end |  | ||||||
| 		elseif state=="comment" then |  | ||||||
| 			if c=="\n" then state = "code" out("\n") newline() end |  | ||||||
| 		elseif state=="commentml" then |  | ||||||
| 			if c=="/" and cp=="*" then state = "code" end |  | ||||||
| 		elseif state=="string" then |  | ||||||
| 			if     c=="\\"       then state = "stringesc" |  | ||||||
| 			elseif c=="\""       then state = "code" |  | ||||||
| 			elseif c:byte()>=128 then |  | ||||||
| 				utf8str = c |  | ||||||
| 				utf8len = getutf8len(c) |  | ||||||
| 				state = "stringutf8" |  | ||||||
| 			else outn(c:byte()) end |  | ||||||
| 		elseif state=="stringesc" then |  | ||||||
| 			outn(string.byte(stringEscapes[c] or error("invalid escape "..c))); state = "string"; |  | ||||||
| 		elseif state=="stringutf8" then |  | ||||||
| 			utf8str = utf8str..c |  | ||||||
| 			if #utf8str == utf8len then |  | ||||||
| 				local valt = utf8table[utf8str] |  | ||||||
| 				if not valt then local datastr = ""; for i = 1, #utf8str do datastr = datastr .. string.format("%02X ", utf8str:sub(i, i):byte()) end; |  | ||||||
| 					error("Unrecognized UTF-8 character: "..datastr); end |  | ||||||
| 				for i, v in ipairs(valt) do outn(v) end |  | ||||||
| 				state = "string" |  | ||||||
| 			end |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	assert(#bracestack==0, "unclosed brace") |  | ||||||
| 	local code2 = table.concat(outt) |  | ||||||
| 	 |  | ||||||
| 	return code2 |  | ||||||
| end |  | ||||||
| local function fixFilename(fn) |  | ||||||
| 	fn = fn:gsub("[^a-zA-Z0-9_]", "_") |  | ||||||
| 	return fn |  | ||||||
| end |  | ||||||
| local function includeFile(fn) |  | ||||||
| 	local code = readFile(fn) |  | ||||||
| 	code = prefixCode(code, fn) |  | ||||||
| 	local fnf = fixFilename(fn) |  | ||||||
| 	code = ".fn "..fnf.."\n"..code |  | ||||||
| 	code = code:gsub(".include ([^\r\n]+)", function(fn2) |  | ||||||
| 		fn2 = fn:gsub("[^\\/]+$", "")..fn2 |  | ||||||
| 		return "\n"..includeFile(fn2).."\n"..".fn "..fnf.."\n" |  | ||||||
| 	end) |  | ||||||
| 	return code |  | ||||||
| end |  | ||||||
| local function instrsFromArch(arch) |  | ||||||
| 	local function arraySize(imms) local s = 1; for i = 1, #imms do s = s*(imms[i].val or error("invalid array size")) end; return s; end |  | ||||||
| 	local instrs = { |  | ||||||
| 		imm8  = function() return 0, true end, |  | ||||||
| 		imm16 = function() return 0, true end, |  | ||||||
| 		byte  = function() return 1, false end, |  | ||||||
| 		word  = function() return 2, false end, |  | ||||||
| 		["byte imm8"] = function() return 0, true end, |  | ||||||
| 		["word imm16"] = function() return 0, true end, |  | ||||||
| 		["byte [ imm8 ]" ] = function(imms) return arraySize(imms)  , false end, |  | ||||||
| 		["byte [ imm16 ]"] = function(imms) return arraySize(imms)  , false end, |  | ||||||
| 		["word [ imm8 ]" ] = function(imms) return arraySize(imms)*2, false end, |  | ||||||
| 		["word [ imm16 ]"] = function(imms) return arraySize(imms)*2, false end, |  | ||||||
| 	} |  | ||||||
| 	local function addMnem(mnem, opcode) |  | ||||||
| 		instrs[mnem] = opcode |  | ||||||
| 		if mnem:find("%*") then instrs[mnem:gsub("%*", "%[").." ]"] = opcode end |  | ||||||
| 	end |  | ||||||
| 	for _, instr in ipairs(arch.instructions) do |  | ||||||
| 		if instr.mnem then |  | ||||||
| 			local mnem = instr.mnem |  | ||||||
| 			mnem = mnem:gsub("([%*%+%-])", " %1 ") |  | ||||||
| 			mnem = trim(mnem):gsub(" +", " ") |  | ||||||
| 			addMnem(mnem, instr.opcode) |  | ||||||
| 			local alias = arch.aliases[trim(mnem)] |  | ||||||
| 			if alias then for _, v in ipairs(alias) do addMnem(v, instr.opcode) end end |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	return instrs |  | ||||||
| end |  | ||||||
| local function assembleFile(fn, arch) |  | ||||||
| 	local code = includeFile(fn) |  | ||||||
| 	code, uexprs = preprocessCode(code) |  | ||||||
| 	code = fixCode(code) |  | ||||||
| 	local instrs = instrsFromArch(arch) |  | ||||||
| 	local mem, code = assembleCode(code, instrs, uexprs) |  | ||||||
| 	return mem, code |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local function mnemsFromArch(arch) |  | ||||||
| 	local mnems = {} |  | ||||||
| 	for _, instr in ipairs(arch.instructions) do |  | ||||||
| 		if instr.mnem then |  | ||||||
| 			local len = 1 |  | ||||||
| 			for l in instr.mnem:gmatch("imm([0-9]+)") do len = len + tonumber(l)/8 end |  | ||||||
| 			mnems[instr.opcode] = { mnem = instr.mnem, rel = instr.rel, jmp = instr.jmp, len = len, } |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	return mnems |  | ||||||
| end |  | ||||||
| local function toSigned8(x) return x>=128 and x-256 or x end |  | ||||||
| local function disassembleMemory(mem, code, arch) |  | ||||||
| 	local mnems = mnemsFromArch(arch) |  | ||||||
| 	 |  | ||||||
| 	local addr = 0 |  | ||||||
| 	local function nextByte(d) local b = mem[addr]; addr = addr+1; return b or d; end |  | ||||||
| 	local lastaddr = 0 |  | ||||||
| 	local jmpaddrs = {} |  | ||||||
| 	while addr<=0xFFFF do |  | ||||||
| 		local startaddr = addr |  | ||||||
| 		local opcode = nextByte() |  | ||||||
| 		if opcode and ((not code) or code[startaddr]) then |  | ||||||
| 			local mnem = mnems[opcode] |  | ||||||
| 			if mnem then |  | ||||||
| 				if mnem.jmp then |  | ||||||
| 					local jmpdest |  | ||||||
| 					if     mnem.rel then jmpdest = toSigned8(nextByte(0)) + addr |  | ||||||
| 					else                 jmpdest = nextByte(0)*256 + nextByte(0) |  | ||||||
| 					end |  | ||||||
| 					if jmpdest then |  | ||||||
| 						if not jmpaddrs[jmpdest] then |  | ||||||
| 							jmpaddrs[jmpdest] = { rel = mnem.rel, from = {}, } |  | ||||||
| 						end |  | ||||||
| 						table.insert(jmpaddrs[jmpdest].from, startaddr) |  | ||||||
| 						jmpaddrs[jmpdest].rel = jmpaddrs[jmpdest].rel and mnem.rel |  | ||||||
| 					end |  | ||||||
| 				else |  | ||||||
| 					addr = addr + mnem.len - 1 |  | ||||||
| 				end |  | ||||||
| 			end |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	local labelnum, subnum = 0, 0 |  | ||||||
| 	for _, jmp in pairs(jmpaddrs) do |  | ||||||
| 		if jmp.rel then jmp.name = "label_"     ..labelnum; labelnum = labelnum+1; |  | ||||||
| 		else            jmp.name = "subroutine_"..subnum  ; subnum   = subnum  +1; end |  | ||||||
| 	end |  | ||||||
| 	 |  | ||||||
| 	local lines = {} |  | ||||||
| 	addr = 0 |  | ||||||
| 	while addr<=0xFFFF do |  | ||||||
| 		local startaddr = addr |  | ||||||
| 		local opcode = nextByte() |  | ||||||
| 		if opcode and ((not code) or code[startaddr]) then |  | ||||||
| 			local line = {} |  | ||||||
| 			local mnem = mnems[opcode].mnem or "???" |  | ||||||
| 			table.insert(line, trim(mnem:gsub("imm[0-9]+", ""))) |  | ||||||
| 			local tlen = 1 |  | ||||||
| 			for lens in mnem:gmatch("imm([0-9]+)") do local len = tonumber(lens)/8 |  | ||||||
| 				if len==1 then |  | ||||||
| 					local data = nextByte(0) |  | ||||||
| 					local jmp |  | ||||||
| 					if mnems[opcode].rel then |  | ||||||
| 						local jmpdest = (addr + toSigned8(data))%65536 |  | ||||||
| 						jmp = jmpaddrs[jmpdest] |  | ||||||
| 						if jmp then |  | ||||||
| 							table.insert(line, jmp.name) |  | ||||||
| 							--table.insert(line, ";") |  | ||||||
| 							--table.insert(line, "$"..string.format("%04X", jmpdest)..",") |  | ||||||
| 						end |  | ||||||
| 					end |  | ||||||
| 					if not jmp then table.insert(line, "$"..string.format("%02X", data)) end |  | ||||||
| 				elseif len==2 then |  | ||||||
| 					local data = nextByte(0)*256 + nextByte(0) |  | ||||||
| 					local jmp |  | ||||||
| 					if mnems[opcode].jmp then |  | ||||||
| 						local jmpdest = data |  | ||||||
| 						jmp = jmpaddrs[jmpdest] |  | ||||||
| 						if jmp then |  | ||||||
| 							table.insert(line, jmp.name) |  | ||||||
| 							--table.insert(line, ";") |  | ||||||
| 						end |  | ||||||
| 					end |  | ||||||
| 					if not jmp then table.insert(line, "$"..string.format("%04X", data)) end |  | ||||||
| 				else error("invalid imm len") end |  | ||||||
| 				tlen = tlen + len |  | ||||||
| 			end |  | ||||||
| 			local lineb = {} |  | ||||||
| 			for i = addr-tlen, addr-1 do |  | ||||||
| 				table.insert(lineb, string.format("%02X", mem[i] or 0)) |  | ||||||
| 			end |  | ||||||
| 			local label = "" |  | ||||||
| 			local jmp = jmpaddrs[startaddr] |  | ||||||
| 			if jmp then label = jmp.name..":" end |  | ||||||
| 			local lb = table.concat(lineb, " ") |  | ||||||
| 			if lastaddr~=addr-tlen then table.insert(lines, "...") end |  | ||||||
| 			table.insert(lines, string.format("%04X", addr-tlen).." | "..(" "):rep(8-#lb)..lb.." | "..(" "):rep(13-#label)..label.." "..table.concat(line, " ")) |  | ||||||
| 			lastaddr = addr |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	return table.concat(lines, "\n") |  | ||||||
| end |  | ||||||
| local function memToHex(hex) |  | ||||||
| 	local mem = {} |  | ||||||
| 	local addr = 0 |  | ||||||
| 	for d in hex:gmatch("[0-9a-fA-F][0-9a-fA-F]") do |  | ||||||
| 		mem[addr] = tonumber(d, 16) |  | ||||||
| 		addr = addr+1 |  | ||||||
| 	end |  | ||||||
| 	return mem |  | ||||||
| end |  | ||||||
| local function disassembleHex(hex, arch) |  | ||||||
| 	return disassembleMemory(memToHex(hex), arch) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local printableCharsS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`-=[]\\;\',./~!@#$%^&*()_+{}|:\"<> " |  | ||||||
| local printableChars = {}; for i = 1, #printableCharsS do printableChars[printableCharsS:sub(i, i)] = true end; |  | ||||||
| local function toPrintableChar(n) |  | ||||||
| 	local c = string.char(n) |  | ||||||
| 	return printableChars[c] and c or "?" |  | ||||||
| end |  | ||||||
| local function printMemory(mem) |  | ||||||
| 	local anynonempty = false |  | ||||||
| 	local lastbase = -16 |  | ||||||
| 	local lastline = "" |  | ||||||
| 	local numreps = 0 |  | ||||||
| 	local lines = {} |  | ||||||
| 	local function closereps(base) |  | ||||||
| 		if numreps~=0 then |  | ||||||
| 			table.insert(lines, "(repeated "..numreps.." more times, up to "..string.format("%04X", base+15)..")") |  | ||||||
| 			numreps = 0 |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	for base = 0, 0xFFF0, 16 do |  | ||||||
| 		local line = {} |  | ||||||
| 		local strt = {} |  | ||||||
| 		local nonempty = false |  | ||||||
| 		for addr = base, base+15 do |  | ||||||
| 			if addr%4==0 then table.insert(line, " ") end |  | ||||||
| 			if mem[addr]==false then |  | ||||||
| 				nonempty = true |  | ||||||
| 				table.insert(line, "XX ") |  | ||||||
| 				table.insert(strt, "X") |  | ||||||
| 			elseif mem[addr] then |  | ||||||
| 				nonempty = true |  | ||||||
| 				table.insert(line, string.format("%02X", mem[addr]).." ") |  | ||||||
| 				table.insert(strt, toPrintableChar(mem[addr])) |  | ||||||
| 			else |  | ||||||
| 				table.insert(line, "-- ") |  | ||||||
| 				table.insert(strt, "-") |  | ||||||
| 			end |  | ||||||
| 		end |  | ||||||
| 		if nonempty then |  | ||||||
| 			local l = table.concat(line) |  | ||||||
| 			if l~=lastline or base~=lastbase+16 then |  | ||||||
| 				closereps(base-16) |  | ||||||
| 				if base ~= lastbase+16 then table.insert(lines, "...") end |  | ||||||
| 				table.insert(lines, string.format("%04X", base).." | "..l.." | "..table.concat(strt)) |  | ||||||
| 			else |  | ||||||
| 				numreps = numreps+1 |  | ||||||
| 			end |  | ||||||
| 			lastline = l |  | ||||||
| 			lastbase = base |  | ||||||
| 			anynonempty = true |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	closereps(lastbase) |  | ||||||
| 	if not anynonempty then table.insert(lines, "Empty") end |  | ||||||
| 	 |  | ||||||
| 	return table.concat(lines, "\n") |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local HasTs = ts~=nil |  | ||||||
| local ts = ts or { |  | ||||||
| 	call = function() end, |  | ||||||
| 	eval = function() end, |  | ||||||
| } |  | ||||||
| ts.eval [[ |  | ||||||
| 	function commandShiftBrick(%x, %y, %z) { commandToServer('shiftBrick', %x, %y, %z); } |  | ||||||
| 	function commandPlantBrick() { commandToServer('plantBrick'); } |  | ||||||
| ]] |  | ||||||
| local function plantBrickAt(brickpos, pos) |  | ||||||
| 	local dx, dy, dz = pos[1]-brickpos[1], pos[2]-brickpos[2], pos[3]-brickpos[3] |  | ||||||
| 	ts.call("commandShiftBrick", dy, -dx, dz) |  | ||||||
| 	ts.call("commandPlantBrick") |  | ||||||
| 	brickpos[1], brickpos[2], brickpos[3] = pos[1], pos[2], pos[3] |  | ||||||
| end |  | ||||||
| local function buildMemory(mem, romsize, offset, len) |  | ||||||
| 	offset = offset or 0 |  | ||||||
| 	 |  | ||||||
| 	local rombytes = romsize[1]*romsize[2]*romsize[3]/8 |  | ||||||
| 	if len and len>rombytes then error("rom not big enough to hold "..len.." bytes (holds "..rombytes..")") end |  | ||||||
| 	if not len then |  | ||||||
| 		for i = 0, 0xFFFF do |  | ||||||
| 			if mem[i] and (i<offset or i>=offset+rombytes) then error("memory does not fit in rom at addr "..string.format("%04X", i)) end |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	 |  | ||||||
| 	local brickpos = {0, 0, 0} |  | ||||||
| 	for x = 0, romsize[1]-1 do |  | ||||||
| 		for y = 0, romsize[2]-1 do |  | ||||||
| 			for z = 0, romsize[3]-1 do |  | ||||||
| 				local addr = offset + ((romsize[3]/8)*(x + y*romsize[1]) + math.floor(z/8)) |  | ||||||
| 				local pow = math.pow(2, z%8) |  | ||||||
| 				local data = (addr>=offset and ((not len) or addr<offset+len) and mem[addr]) or 0 |  | ||||||
| 				local bit = math.floor(data/pow)%2 |  | ||||||
| 				if bit==1 then plantBrickAt(brickpos, {x, -y, z}) end |  | ||||||
| 			end |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local function strtovec(str) local v = {}; for word in str:gmatch("[^ \t\r\n]+") do table.insert(v, tonumber(word)) end; return v; end |  | ||||||
| if HasTs or (not AsmIncluded) then |  | ||||||
| 	function AssembleBuildFile(fn, romsizes, offsets, lens) local offset = tonumber(offsets); local len = tonumber(lens); local romsize = strtovec(romsizes); |  | ||||||
| 		local arch = require("rom-8608-defs") |  | ||||||
| 		local mem, code = assembleFile(fn, arch) |  | ||||||
| 		print(""..fn:match("[^/\\]+$").."\n") |  | ||||||
| 		 |  | ||||||
| 		print("Memory Dump:") |  | ||||||
| 		print(printMemory(mem)) |  | ||||||
| 		print() |  | ||||||
| 		print("Disassembly:") |  | ||||||
| 		print(disassembleMemory(mem, code, arch)) |  | ||||||
| 		print() |  | ||||||
| 		 |  | ||||||
| 		assert(#romsize==3, "incorrect rom size") |  | ||||||
| 		buildMemory(mem, romsize, offset, len) |  | ||||||
| 	end |  | ||||||
| 	ts.eval [[ |  | ||||||
| 		function AssembleBuildFile(%fn, %romsize, %offset, %len) { luacall("AssembleBuildFile", strReplace(%fn, "$", "Add-ons/_misc/rom/8608programs/"), %romsize, %offset, %len); } |  | ||||||
| 	]] |  | ||||||
| 	if not HasTs then AssembleBuildFile(arg[1] or "../8608programs/test.asm", "16 16 8", "0", "256") end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| return { |  | ||||||
| 	assembleFile = assembleFile, |  | ||||||
| 	disassembleMemory = disassembleMemory, |  | ||||||
| 	printMemory = printMemory, |  | ||||||
| } |  | ||||||
| @@ -1,3 +0,0 @@ | |||||||
| luajit gendefs.lua |  | ||||||
| gcc 8608emulator.c -shared -Ofast -o 8608emulator.dll |  | ||||||
| pause |  | ||||||
| @@ -1,147 +0,0 @@ | |||||||
|  |  | ||||||
| #define lobyte(x) (x&0xFF) |  | ||||||
| #define hibyte(x) ((x>>8)&0xFF) |  | ||||||
| #define wordfrombytes(h,l) (((h<<8)&0xFF00)|(l&0xFF)) |  | ||||||
| #define popbyte readmemory(--cpu->s) |  | ||||||
| #define loadimmed readmemory(cpu->i++) |  | ||||||
| #define loadstackrel readmemory((cpu->s+signed8(cpu->t))%65536) |  | ||||||
| #define loadstackrelp1 readmemory((cpu->s+signed8(cpu->t)+1)%65536) |  | ||||||
| #define wordut (wordfrombytes(cpu->u, cpu->t)) |  | ||||||
| #define wordcb (wordfrombytes(cpu->c, cpu->b)) |  | ||||||
| #define loadut readmemory(wordut) |  | ||||||
| #define loadutp1 readmemory((wordut+1)%65536) |  | ||||||
| #define loadp readmemory(cpu->p) |  | ||||||
| #define loadpinc readmemory(cpu->p++) |  | ||||||
| #define loadpp1 readmemory((cpu->p+1)%65536) |  | ||||||
| #define loadq readmemory(cpu->q) |  | ||||||
| #define loadqinc readmemory(cpu->q++) |  | ||||||
| #define loadqp1 readmemory((cpu->q+1)%65536) |  | ||||||
| #define signed8(x) (x>=128 ? x|0xFF00 : x) |  | ||||||
|  |  | ||||||
| #define setzf(x) cpu->nz=(x!=0); |  | ||||||
| #define loadimmedt cpu->t = loadimmed; |  | ||||||
| #define loadimm161 cpu->u = loadimmed; |  | ||||||
| #define loadimm162 cpu->t = loadimmed; |  | ||||||
| #define loadstackrelu cpu->u = loadstackrel; |  | ||||||
| #define storestackrel(x) writememory(cpu->s+signed8(cpu->t), x); |  | ||||||
| #define storestackrel161(x) writememory((cpu->s+signed8(cpu->t)  )%65536, hibyte(x)); |  | ||||||
| #define storestackrel162(x) writememory((cpu->s+signed8(cpu->t)+1)%65536, lobyte(x)); |  | ||||||
| #define loadstackrel161 cpu->u=loadstackrel; |  | ||||||
| #define loadstackrel162 cpu->t=loadstackrelp1; |  | ||||||
| #define storeut(x) writememory(wordut, x); |  | ||||||
| #define storeutp1(x) writememory((wordut+1)%65536, x); |  | ||||||
| #define storep(x) writememory(cpu->p, x); |  | ||||||
| #define storepinc(x) writememory(cpu->p++, x); |  | ||||||
| #define storepp1(x) writememory((cpu->p+1)%65536, x); |  | ||||||
| #define storeq(x) writememory(cpu->q, x); |  | ||||||
| #define storeqinc(x) writememory(cpu->q++, x); |  | ||||||
| #define storeqp1(x) writememory((cpu->q+1)%65536, x); |  | ||||||
| #define pushretaddr1 writememory(cpu->s++, hibyte((cpu->i-1)%65536)); |  | ||||||
| #define pushretaddr2 writememory(cpu->s++, lobyte((cpu->i-1)%65536)); |  | ||||||
| #define lni cpu->instr = readmemory(cpu->i++); cpu->cycle = 0; |  | ||||||
| #define ldi cpu->instr = readmemory(cpu->i); cpu->cycle = 0; |  | ||||||
| #define addf(x,y) { x=(x+y)&0x1FF; cpu->cf=x>=256; x&=0xFF; setzf(x); } |  | ||||||
| #define subf(x,y) addf(x,(-y)&0xFF); |  | ||||||
| #define cmpf(x,y) { int t=x+((-y)&0xFF); cpu->cf=t>=256; t&=0xFF; setzf(t); } |  | ||||||
| #define rol(x,y) x=(x<<y)|(x>>(8-y)); |  | ||||||
| #define ror(x,y) x=(x>>y)|(x<<(8-y)); |  | ||||||
| #define sra(x,y) x=(x>>y); |  | ||||||
| #define jmpabsp cpu->i=cpu->p; lni; |  | ||||||
| #define jmpabsq cpu->i=cpu->q; lni; |  | ||||||
| #define jmpabsut cpu->i=wordut; lni; |  | ||||||
| #define jmpabsutplus1 cpu->i=(wordut+1)%65536; lni; |  | ||||||
| #define pushbyte(b) writememory(cpu->s++, b); |  | ||||||
| #define push161(x) pushbyte(hibyte(x)); |  | ||||||
| #define push162(x) pushbyte(lobyte(x)); |  | ||||||
| #define pop161 cpu->t=popbyte; |  | ||||||
| #define pop162 cpu->u=popbyte; |  | ||||||
| #define tst(x) cpu->cf = x>=128; cpu->nz = x!=0; |  | ||||||
| #define instrpreload cpu->instrpre = loadimmed; |  | ||||||
| #define instrloadpre cpu->instr = cpu->instrpre; |  | ||||||
| #define jmprelt cpu->i = (cpu->i + signed8(cpu->t))%65536; lni; |  | ||||||
| #define saveretaddr cpu->q = (cpu->i+1)%65536; |  | ||||||
|  |  | ||||||
| #define readmemory(x) _readmemory(cpu, mem, x) |  | ||||||
| #define writememory(x, y) _writememory(cpu, mem, x, y) |  | ||||||
|  |  | ||||||
| struct CPU { |  | ||||||
| 	int a; |  | ||||||
| 	int b; |  | ||||||
| 	int c; |  | ||||||
| 	int u; |  | ||||||
| 	int t; |  | ||||||
| 	int p; |  | ||||||
| 	int q; |  | ||||||
| 	int s; |  | ||||||
| 	int v; |  | ||||||
| 	int i; |  | ||||||
| 	int cf; |  | ||||||
| 	int nz; |  | ||||||
| 	int irq; |  | ||||||
| 	int ifg; |  | ||||||
| 	int rfg; |  | ||||||
| 	int ien; |  | ||||||
| 	int instr; |  | ||||||
| 	int cycle; |  | ||||||
| 	int instrpre; |  | ||||||
| 	int frame; |  | ||||||
| }; |  | ||||||
| struct Event { |  | ||||||
| 	int id; |  | ||||||
| 	int addr; |  | ||||||
| }; |  | ||||||
| struct Memory { |  | ||||||
| 	int data[65536]; |  | ||||||
| 	int canwrite[65536]; |  | ||||||
| 	int writes[65536]; |  | ||||||
| 	int reads[65536]; |  | ||||||
| 	int onread[65536]; |  | ||||||
| 	int onwrite[65536]; |  | ||||||
| 	struct Event events[4096]; |  | ||||||
| 	int numevents; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| void postEvent(struct Memory* const mem, int id, int addr) { |  | ||||||
| 	if(mem->numevents<4096) { |  | ||||||
| 		mem->events[mem->numevents].id = id; |  | ||||||
| 		mem->events[mem->numevents].addr = addr; |  | ||||||
| 		mem->numevents++; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| int _readmemory(const struct CPU* const cpu, struct Memory* const mem, const int addr) { |  | ||||||
| 	int addr2 = addr%65536; |  | ||||||
| 	mem->reads[addr2] = cpu->frame; |  | ||||||
| 	if(mem->onread[addr2]) { |  | ||||||
| 		postEvent(mem, mem->onread[addr2], addr2); |  | ||||||
| 	} |  | ||||||
| 	return mem->data[addr2]; |  | ||||||
| } |  | ||||||
| int _writememory(const struct CPU* const cpu, struct Memory* const mem, const int addr, const int data) { |  | ||||||
| 	int addr2 = addr%65536; |  | ||||||
| 	if(mem->canwrite[addr2]) { |  | ||||||
| 		mem->writes[addr2] = cpu->frame; |  | ||||||
| 		mem->data[addr2] = data%256; |  | ||||||
| 	} |  | ||||||
| 	if(mem->onwrite[addr2]) { |  | ||||||
| 		postEvent(mem, mem->onwrite[addr2], addr2); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| typedef void(*CPUInstruction)(struct CPU* const cpu, struct Memory* const mem); |  | ||||||
|  |  | ||||||
| #include "instructions_gen.c" |  | ||||||
|  |  | ||||||
| int TickCPU(struct CPU* const cpu, struct Memory* const mem, const int count, const int countinstrs, const int breakaddr) { |  | ||||||
| 	int i = 0; |  | ||||||
| 	while(i<count) { |  | ||||||
| 		if(cpu->irq && !cpu->ifg && cpu->cycle==0 && cpu->ien) { cpu->instr = 0xF2; } |  | ||||||
| 		if(cpu->rfg || cpu->ifg || cpu->irq) { |  | ||||||
| 			CPUInstruction instr = CPUInstructions[cpu->instr][cpu->cycle]; |  | ||||||
| 			if(instr) instr(cpu, mem); |  | ||||||
| 			if(!countinstrs || cpu->cycle==0) { i++; } |  | ||||||
| 			if(cpu->i==breakaddr) { i = count; break; } |  | ||||||
| 		} else { i = count; break; } |  | ||||||
| 		if(mem->numevents!=0) { break; } |  | ||||||
| 	} |  | ||||||
| 	return count-i; |  | ||||||
| } |  | ||||||
										
											Binary file not shown.
										
									
								
							| @@ -1,678 +0,0 @@ | |||||||
| --love 1 |  | ||||||
|  |  | ||||||
| require("colorset") |  | ||||||
| local ffi = require("ffi") |  | ||||||
| RelPath = "../" |  | ||||||
| AsmIncluded = true |  | ||||||
| local asm = dofile("../assembler-8608.lua") |  | ||||||
| local Arch = dofile("../rom-8608-defs.lua") |  | ||||||
|  |  | ||||||
| local lg = love.graphics |  | ||||||
| local li = love.image |  | ||||||
| local le = love.event |  | ||||||
| local lt = love.timer |  | ||||||
| local lk = love.keyboard |  | ||||||
|  |  | ||||||
| ---- |  | ||||||
| local function InitColorset() |  | ||||||
| 	for i = 0, 63 do |  | ||||||
| 		local c = ColorSet[i+1] |  | ||||||
| 		ColorSet[i] = { |  | ||||||
| 			c[1]/255, |  | ||||||
| 			c[2]/255, |  | ||||||
| 			c[3]/255, |  | ||||||
| 		} |  | ||||||
| 		ColorSet[i+1] = nil |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local eventTypes = {} |  | ||||||
| local function registerEvent(mem, addrFirst, addrLast, read, write, func) |  | ||||||
| 	table.insert(eventTypes, func) |  | ||||||
| 	local id = #eventTypes |  | ||||||
| 	for addr = addrFirst, addrLast do |  | ||||||
| 		if read  then mem.c.onread [addr] = id end |  | ||||||
| 		if write then mem.c.onwrite[addr] = id end |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| local function handleEvents(cpu, mem) |  | ||||||
| 	for i = 0, mem.c.numevents-1 do |  | ||||||
| 		local event = mem.c.events[i] |  | ||||||
| 		eventTypes[event.id](event.addr, cpu, mem) |  | ||||||
| 	end |  | ||||||
| 	mem.c.numevents = 0 |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local RegDisplay = { |  | ||||||
| 	scrX = 384+16, scrY = 32+8, |  | ||||||
| 	width = 128, height = 192, |  | ||||||
| 	fontWidth = 8, fontHeight = 12, |  | ||||||
| 	registers = { |  | ||||||
| 		{ name = "A"  , idx = "a"    , x=8,y=8      ,w=2}, |  | ||||||
| 		{ name = "B"  , idx = "b"    , x=8,y=8+16   ,w=2}, |  | ||||||
| 		{ name = "C"  , idx = "c"    , x=8,y=8+16* 2,w=2}, |  | ||||||
| 		{ name = "U"  , idx = "u"    , x=8,y=8+16* 3,w=2}, |  | ||||||
| 		{ name = "T"  , idx = "t"    , x=8,y=8+16* 4,w=2}, |  | ||||||
| 		{ name = "P"  , idx = "p"    , x=8,y=8+16* 5,w=4}, |  | ||||||
| 		{ name = "Q"  , idx = "q"    , x=8,y=8+16* 6,w=4}, |  | ||||||
| 		{ name = "S"  , idx = "s"    , x=8,y=8+16* 7,w=4}, |  | ||||||
| 		{ name = "V"  , idx = "v"    , x=8,y=8+16* 8,w=4}, |  | ||||||
| 		{ name = "I"  , idx = "i"    , x=8,y=8+16* 9,w=4}, |  | ||||||
| 		{ name = "Ins", idx = "instr", x=8,y=8+16*10,w=2}, |  | ||||||
| 		{ name = "Cyc", idx = "cycle", x=64+8-16,y=8+16*10,w=2}, |  | ||||||
| 	}, |  | ||||||
| 	flags = { |  | ||||||
| 		{ name = "CF" , idx = "cf" , x=64+8,y=8     }, |  | ||||||
| 		{ name = "NZ" , idx = "nz" , x=64+8,y=8+16  }, |  | ||||||
| 		{ name = "IRq", idx = "irq", x=64+8,y=8+16*2}, |  | ||||||
| 		{ name = "IEn", idx = "ien", x=64+8,y=8+16*5}, |  | ||||||
| 		{ name = "Int", idx = "ifg", x=64+8,y=8+16*3}, |  | ||||||
| 		{ name = "Run", idx = "rfg", x=64+8,y=8+16*4}, |  | ||||||
| 	}, |  | ||||||
| } |  | ||||||
| local function InitRegDisplay(rd) |  | ||||||
| 	lg.print("Registers", rd.scrX, rd.scrY-16) |  | ||||||
| 	lg.rectangle("line", rd.scrX, rd.scrY, rd.width, rd.height+1) |  | ||||||
| 	for i, reg in ipairs(rd.registers) do |  | ||||||
| 		lg.rectangle("line", rd.scrX+reg.x+(rd.fontWidth*(4-reg.w)), rd.scrY+reg.y, rd.fontWidth*reg.w+1, rd.fontHeight+1) |  | ||||||
| 		lg.print(reg.name, rd.scrX+reg.x+32+4, reg.y + rd.scrY) |  | ||||||
| 	end |  | ||||||
| 	for i, flg in pairs(rd.flags) do |  | ||||||
| 		lg.rectangle("line", rd.scrX+flg.x, rd.scrY+flg.y, rd.fontHeight+1, rd.fontHeight+1) |  | ||||||
| 		lg.print(flg.name, rd.scrX+flg.x+rd.fontHeight+4, flg.y+rd.scrY) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| local function printValue(val, w, x, y, fw) |  | ||||||
| 	for i = 1, w do |  | ||||||
| 		local v = math.floor(val/math.pow(16,i-1))%16 |  | ||||||
| 		lg.print(string.format("%01X", v), x+(fw*(4-i)), y+1) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| local function RedrawRegDisplay(rd, cpu, mem) |  | ||||||
| 	for i, reg in ipairs(rd.registers) do |  | ||||||
| 		lg.setColor(0,0,0) |  | ||||||
| 		lg.rectangle("fill", rd.scrX+reg.x+(rd.fontWidth*(4-reg.w)), rd.scrY+reg.y, rd.fontWidth*reg.w, rd.fontHeight) |  | ||||||
| 		lg.setColor(1,1,1) |  | ||||||
| 		local val = cpu.c[reg.idx]%(math.pow(16, reg.w)) |  | ||||||
| 		printValue(val, reg.w, rd.scrX+reg.x, rd.scrY+reg.y, rd.fontWidth) |  | ||||||
| 	end |  | ||||||
| 	for i, flg in pairs(rd.flags) do |  | ||||||
| 		local val = cpu.c[flg.idx] |  | ||||||
| 		if val~=0 then |  | ||||||
| 			lg.setColor(1,1,1) |  | ||||||
| 		else |  | ||||||
| 			lg.setColor(0,0,0) |  | ||||||
| 		end |  | ||||||
| 		lg.rectangle("fill", rd.scrX+flg.x, rd.scrY+flg.y, rd.fontHeight, rd.fontHeight) |  | ||||||
| 	end |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local ReadMemory |  | ||||||
| local WriteMemory |  | ||||||
| local StackDisplay = { |  | ||||||
| 	scrX = 8+384+32+6, scrY = 32+192+32-4, |  | ||||||
| 	lines = 16, fontHeight = 12, |  | ||||||
| } |  | ||||||
| local function InitStackDisplay(sd) |  | ||||||
| 	sd.width = 96+1 |  | ||||||
| 	sd.height = 12+(sd.lines*sd.fontHeight) |  | ||||||
| 	lg.print("Stack", sd.scrX, sd.scrY-16) |  | ||||||
| 	lg.rectangle("line", sd.scrX, sd.scrY, sd.width+1, sd.height+1) |  | ||||||
| end |  | ||||||
| local function RedrawStackDisplay(sd, cpu, mem) |  | ||||||
| 	lg.setColor(0,0,0) |  | ||||||
| 	lg.rectangle("fill", sd.scrX, sd.scrY, sd.width, sd.height) |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| 	for i = 1, sd.lines do |  | ||||||
| 		local addr = (cpu.c.s-i)%65536 |  | ||||||
| 		local val = ReadMemory(mem, addr) |  | ||||||
| 		lg.print(string.format("%04X -%2i %02X", addr, i, val), sd.scrX+8, sd.scrY+8+(12*(i-1))) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local MemoryDisplays = { |  | ||||||
| 	{ |  | ||||||
| 		scrX = 8, scrY = 32+192+32-4, |  | ||||||
| 		columns = 16, columnSpace = 4, rows = 16, |  | ||||||
| 		fontHeight = 12, |  | ||||||
| 		showAscii = false, |  | ||||||
| 		addr = 0x3000, |  | ||||||
| 		highlightTime = 8, |  | ||||||
| 	}, |  | ||||||
| } |  | ||||||
| local function InitMemoryDisplay(md) |  | ||||||
| 	local cw = 7 |  | ||||||
| 	md.mainCols = 9+md.columns*3+md.columnSpace-1 |  | ||||||
| 	md.width = cw*(md.mainCols)+cw*(md.showAscii and (md.columns+5) or 0)-8 |  | ||||||
| 	md.height = 12+md.fontHeight*md.rows |  | ||||||
| 	lg.print("Memory", md.scrX, md.scrY-16) |  | ||||||
| 	lg.rectangle("line", md.scrX, md.scrY, md.width+1, md.height+1) |  | ||||||
| end |  | ||||||
| local function RedrawMemoryDisplay(md, cpu, mem) |  | ||||||
| 	lg.setColor(0,0,0) |  | ||||||
| 	lg.rectangle("fill", md.scrX, md.scrY, md.width, md.height) |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| 	 |  | ||||||
| 	local highlightAddrs = {} |  | ||||||
| 	highlightAddrs[cpu.c.p] = "P" |  | ||||||
| 	highlightAddrs[cpu.c.q] = "Q" |  | ||||||
| 	highlightAddrs[cpu.c.s] = "S" |  | ||||||
| 	highlightAddrs[cpu.c.v] = "V" |  | ||||||
| 	highlightAddrs[(cpu.c.i-1)%65536] = "I" |  | ||||||
| 	 |  | ||||||
| 	local cw = 7 |  | ||||||
| 	 |  | ||||||
| 	local tickDraw = cpu.c.frame-md.highlightTime |  | ||||||
| 	for l = 1, md.rows do |  | ||||||
| 		local addr = md.addr + (l-1)*md.columns |  | ||||||
| 		local lx = md.scrX+8 |  | ||||||
| 		local ly = md.scrY+8+(md.fontHeight*(l-1)) |  | ||||||
| 		lg.print(string.format("%04X", addr).." | ", lx, ly) |  | ||||||
| 		lx = lx+(cw*7) |  | ||||||
| 		for x = 1, md.columns do |  | ||||||
| 			local a = addr + (x-1) |  | ||||||
| 			local v = ReadMemory(mem, a) |  | ||||||
| 			if highlightAddrs[a] then |  | ||||||
| 				lg.line(lx, ly, lx, ly+11) |  | ||||||
| 				lg.line(lx-1, ly, lx+15, ly) |  | ||||||
| 				lg.line(lx-1, ly+11, lx+15, ly+11) |  | ||||||
| 				lg.print(highlightAddrs[a], lx-cw, ly) |  | ||||||
| 			end |  | ||||||
| 			if mem.c.writes[a] > tickDraw then |  | ||||||
| 				lg.rectangle("fill",lx-1,ly,cw*2+2,11) |  | ||||||
| 				lg.setColor(0,0,0) |  | ||||||
| 			end |  | ||||||
| 			lg.print(string.format("%02X", v), lx, ly) |  | ||||||
| 			lg.setColor(1,1,1) |  | ||||||
| 			if mem.c.reads[a] > tickDraw then |  | ||||||
| 				lg.rectangle("line", lx-1, ly, cw*2+2+1, 11+1) |  | ||||||
| 			end |  | ||||||
| 			lx = lx+(cw*3) |  | ||||||
| 			if x%md.columnSpace==0 then lx = lx+cw end |  | ||||||
| 		end |  | ||||||
| 		if md.showAscii then |  | ||||||
| 			lg.print("|", lx, ly) |  | ||||||
| 			lx = lx+cw |  | ||||||
| 		end |  | ||||||
| 		if md.showAscii then |  | ||||||
| 			for x = 1, md.columns do |  | ||||||
| 				local a = addr + (x-1) |  | ||||||
| 				local v = ReadMemory(mem, a) |  | ||||||
| 				if v>=128 then v = 0 end |  | ||||||
| 				local c = string.char(v) |  | ||||||
| 				lg.print(c, md.scrX+lx+((x-1)*cw), md.scrY+8+(12*(l-1))) |  | ||||||
| 			end |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local ProgramDisplay = { |  | ||||||
| 	scrX = 8+384+8+128+8, scrY = 32+8, |  | ||||||
| 	fontHeight = 12, |  | ||||||
| 	numLines = 34, |  | ||||||
| 	highlightTime = 8, |  | ||||||
| } |  | ||||||
| local function pdLinesFromDasm(dasm) |  | ||||||
| 	local lines, addrLines, lineAddrs = {}, {}, {} |  | ||||||
| 	for line in dasm:gmatch("[^\n]+") do |  | ||||||
| 		if line~="..." then |  | ||||||
| 			local addrh, datah, rest = line:match("^(.+) | (.+) | +(.+)$") |  | ||||||
| 			local text = rest |  | ||||||
| 			local label = nil |  | ||||||
| 			if rest:find(":") then label, text = rest:match("^(.+): (.+)$") end |  | ||||||
| 			local addr = tonumber(addrh, 16) |  | ||||||
| 			 |  | ||||||
| 			if label then |  | ||||||
| 				--table.insert(lines, "     | "..label..":") |  | ||||||
| 				table.insert(lines, "                | "..label..":") |  | ||||||
| 				lineidx = #lines |  | ||||||
| 			end |  | ||||||
| 			--table.insert(lines, addrh.." | "..text) |  | ||||||
| 			table.insert(lines, addrh.." | "..datah.." | "..text) |  | ||||||
| 			 |  | ||||||
| 			local lineidx = #lines |  | ||||||
| 			local len = 0; for _ in datah:gfind("[0-9a-fA-F][0-9a-fA-F]") do len = len+1 end; |  | ||||||
| 			for i = 1, len do addrLines[addr+i-1] = lineidx end |  | ||||||
| 			lineAddrs[lineidx] = addr |  | ||||||
| 		else |  | ||||||
| 			table.insert(lines, "") |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	return lines, addrLines, lineAddrs |  | ||||||
| end |  | ||||||
| local function InitProgramDisplay(pd, data, code, arch) |  | ||||||
| 	pd.width = 256 |  | ||||||
| 	pd.height = 12+pd.fontHeight*pd.numLines-3 |  | ||||||
| 	lg.print("Program", pd.scrX, pd.scrY-16) |  | ||||||
| 	lg.rectangle("line", pd.scrX, pd.scrY, pd.width, pd.height) |  | ||||||
| 	pd.firstLine = 1 |  | ||||||
| 	pd.data = data |  | ||||||
| 	pd.code = code |  | ||||||
| 	local dasm = asm.disassembleMemory(data, code, arch) |  | ||||||
| 	pd.lines, pd.addrLines, pd.lineAddrs = pdLinesFromDasm(dasm) |  | ||||||
| 	pd.midLine = math.floor(pd.numLines/2) |  | ||||||
| end |  | ||||||
| local function RedrawProgramDisplay(pd, cpu, mem) |  | ||||||
| 	lg.setColor(0,0,0) |  | ||||||
| 	lg.rectangle("fill", pd.scrX, pd.scrY, pd.width-1, pd.height-1) |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| 	 |  | ||||||
| 	local rectwidth = pd.width-18 |  | ||||||
| 	local rectheight = pd.fontHeight-1 |  | ||||||
| 	local tickDraw = cpu.c.frame-pd.highlightTime |  | ||||||
| 	 |  | ||||||
| 	local instrAddr = (cpu.c.i-1)%65536 |  | ||||||
| 	local instrLine = pd.addrLines[instrAddr] |  | ||||||
| 	if instrLine then |  | ||||||
| 		if pd.firstLine > instrLine then pd.firstLine = math.max(instrLine-pd.midLine, 1) |  | ||||||
| 		elseif pd.firstLine+pd.numLines-1 < instrLine then pd.firstLine = math.min(instrLine-pd.numLines+pd.midLine, #pd.lines-pd.numLines+1) |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	local screenlineidx = 0 |  | ||||||
| 	for lineidx = pd.firstLine, pd.firstLine+pd.numLines-1 do |  | ||||||
| 		local line = pd.lines[lineidx] |  | ||||||
| 		local lineaddr = pd.lineAddrs[lineidx] |  | ||||||
| 		if line then |  | ||||||
| 			local x, y = pd.scrX+8, pd.scrY+4+screenlineidx*pd.fontHeight |  | ||||||
| 			if lineaddr and mem.c.reads[lineaddr] > tickDraw then |  | ||||||
| 				lg.rectangle("line", x, y, rectwidth, rectheight) |  | ||||||
| 			end |  | ||||||
| 			if instrLine==lineidx then |  | ||||||
| 				lg.rectangle("fill", x, y, rectwidth, rectheight) |  | ||||||
| 				lg.setColor(0,0,0) |  | ||||||
| 			end |  | ||||||
| 			lg.print(line, x, y) |  | ||||||
| 			lg.setColor(1,1,1) |  | ||||||
| 		end |  | ||||||
| 		screenlineidx = screenlineidx + 1 |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local VideoDisplay = { |  | ||||||
| 	width = 256, height = 128, |  | ||||||
| 	scrX = 8, scrY = 256, |  | ||||||
| 	addr = 0x8000, |  | ||||||
| } |  | ||||||
| local function InitVideoDisplay(vd) |  | ||||||
| 	lg.print("Video Display", vd.scrX, vd.scrY-16) |  | ||||||
| 	vd.imageData = li.newImageData(vd.width, vd.height) |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| 	lg.rectangle("line", vd.scrX, vd.scrY, vd.width+1, vd.height+1) |  | ||||||
| end |  | ||||||
| local CharDisplay = { |  | ||||||
| 	width = 64*6, height = 16*12, |  | ||||||
| 	rows = 16, cols = 64, |  | ||||||
| 	fontWidth = 6, fontHeight = 12, |  | ||||||
| 	scrX = 8, scrY = 32+8, |  | ||||||
| 	addrChar = 0x0800, |  | ||||||
| 	addrColor = 0x0C00, |  | ||||||
| } |  | ||||||
| local function InitCharDisplay(cd) |  | ||||||
| 	lg.print("Char Display", cd.scrX, cd.scrY-16) |  | ||||||
| 	cd.font = lg.newFont("consola.ttf", cd.fontHeight-1, "mono") |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local Keyboard = { |  | ||||||
| 	addrRange = {0x0500, 0x05FF}, |  | ||||||
| 	queueSize = 16, |  | ||||||
| 	queue = {}, |  | ||||||
| 	interrupts = false, |  | ||||||
| 	queueEmpty = true, |  | ||||||
| } |  | ||||||
| local function kbSetNext(kb, cpu, mem) |  | ||||||
| 	local newval = kb.queue[1] or 0 |  | ||||||
| 	if mem.c.data[kb.addrRange[1]] ~= newval then |  | ||||||
| 		for a = kb.addrRange[1], kb.addrRange[2] do |  | ||||||
| 			mem.c.data[a] = newval |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| local function KeyboardOnRead(addr, cpu, mem, kb) |  | ||||||
| 	table.remove(kb.queue, 1) |  | ||||||
| 	kbSetNext(kb, cpu, mem) |  | ||||||
| end |  | ||||||
| local function KeyboardOnWrite(addr, cpu, mem, kb) |  | ||||||
| 	local val = mem.c.data[addr] |  | ||||||
| 	kb.interrupts = val~=0 |  | ||||||
| 	mem.c.data[addr] = kb.queue[1] or 0 |  | ||||||
| end |  | ||||||
| local keycodes = require("keycodes") |  | ||||||
| local CPURequestInterrupt |  | ||||||
| local function KeyboardOnKey(kb, key, press, cpu, mem) |  | ||||||
| 	local code = keycodes[key] or keycodes["invalid"] |  | ||||||
| 	if code==0x7F then print("invalid key: "..key) end |  | ||||||
| 	table.insert(kb.queue, code + (press and 128 or 0)) |  | ||||||
| 	if #kb.queue > kb.queueSize then table.remove(kb.queue, 1) end |  | ||||||
| 	kb.queueEmpty = false |  | ||||||
| 	kbSetNext(kb, cpu, mem) |  | ||||||
| 	if kb.interrupts then CPURequestInterrupt(cpu) end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local function RedrawFPSCounter(x, y) |  | ||||||
| 	lg.setColor(0,0,0) |  | ||||||
| 	lg.rectangle("fill",x,y,64,12) |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| 	lg.print("FPS: "..lt.getFPS(), x,y) |  | ||||||
| end |  | ||||||
| local function printHighlight(s, o, h, x, y) |  | ||||||
| 	x = x+o*7 |  | ||||||
| 	local w = 7*#s |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| 	if h then |  | ||||||
| 		lg.rectangle("fill", x, y, w, 12) |  | ||||||
| 		lg.setColor(0,0,0) |  | ||||||
| 	end |  | ||||||
| 	lg.print(s, x, y) |  | ||||||
| end |  | ||||||
| local function RedrawKeyInfo(x, y, uk, run) |  | ||||||
| 	lg.setColor(0,0,0) |  | ||||||
| 	lg.rectangle("fill",x,y,768,12) |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| 	printHighlight("[F4] Toggle keyboard", 0, lk.isDown("f4"), x, y) |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| 	if uk then |  | ||||||
| 		printHighlight("Keystrokes passed to device", 23, false, x, y) |  | ||||||
| 	else |  | ||||||
| 		printHighlight("[R] "..(run and "Stop" or "Run "), 23, lk.isDown("r"), x, y) |  | ||||||
| 		printHighlight("[T] Tick once", 33, lk.isDown("t"), x, y) |  | ||||||
| 		printHighlight("[S] Step once", 48, lk.isDown("s"), x, y) |  | ||||||
| 		printHighlight("[Q] Quit", 63, lk.isDown("q"), x, y) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local GPIO = {} |  | ||||||
| local function InitGPIO(gpio) |  | ||||||
| 	gpio.mulLeft = 0 |  | ||||||
| 	gpio.mulRight = 0 |  | ||||||
| 	gpio.divLeft = 0 |  | ||||||
| 	gpio.divRight = 0 |  | ||||||
| 	gpio.intQueued = false |  | ||||||
| end |  | ||||||
| local function UpdateGPIO(gpio, cpu, mem) |  | ||||||
| 	if gpio.intQueued then |  | ||||||
| 		gpio.intQueued = false |  | ||||||
| 		CPURequestInterrupt(cpu) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| local function gpioSetValue(name, func) |  | ||||||
| 	return function(addr, cpu, mem, gpio) |  | ||||||
| 		gpio[name] = ReadMemory(mem, addr) |  | ||||||
| 		func(addr, cpu, mem, gpio) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| local function gpioMul(addr, cpu, mem, gpio) |  | ||||||
| 	local base = math.floor(addr/256)*256 |  | ||||||
| 	local res = gpio.mulLeft*gpio.mulRight |  | ||||||
| 	WriteMemory(mem, base+0x00, math.floor(res/256)) |  | ||||||
| 	WriteMemory(mem, base+0x01, res%256) |  | ||||||
| end |  | ||||||
| local function gpioDiv(addr, cpu, mem, gpio) |  | ||||||
| 	local base = math.floor(addr/256)*256 |  | ||||||
| 	WriteMemory(mem, base+0x02, math.floor(gpio.divLeft/gpio.divRight)) |  | ||||||
| 	WriteMemory(mem, base+0x03, gpio.divLeft%gpio.divRight) |  | ||||||
| end |  | ||||||
| local gpioFunctions = { |  | ||||||
| 	[0x00] = gpioSetValue("mulLeft" , gpioMul), |  | ||||||
| 	[0x01] = gpioSetValue("mulRight", gpioMul), |  | ||||||
| 	[0x02] = gpioSetValue("divLeft" , gpioDiv), |  | ||||||
| 	[0x03] = gpioSetValue("divRight", gpioDiv), |  | ||||||
| 	[0x04] = function(addr, cpu, mem, gpio) WriteMemory(mem, addr, gpioPopcount(readMemory(mem, addr))) end, |  | ||||||
| 	[0x05] = function(addr, cpu, mem, gpio) gpio.intQueued = true; WriteMemory(mem, addr, 0); end |  | ||||||
| } |  | ||||||
| local function GPIOOnWrite(addr, cpu, mem, gpio) |  | ||||||
| 	local offset = addr%256 |  | ||||||
| 	local func = gpioFunctions[offset] |  | ||||||
| 	if func then |  | ||||||
| 		func(addr, cpu, mem, gpio) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local peripherals = { |  | ||||||
| 	CharDisplay  = { range = {0x0800, 0x0FFF}, write = true  }, |  | ||||||
| 	BootROM      = { range = {0x0000, 0x03FF}, write = false }, |  | ||||||
| 	SystemRAM    = { range = {0x1000, 0x1FFF}, write = true  }, |  | ||||||
| 	UserROM      = { range = {0x2000, 0x2FFF}, write = false }, |  | ||||||
| 	UserRAM      = { range = {0x3000, 0x3FFF}, write = true  }, |  | ||||||
| 	VideoDisplay = { range = {0x8000, 0xFFFF}, write = true  }, |  | ||||||
| 	Keyboard     = { range = {0x0500, 0x05FF}, write = true, |  | ||||||
| 		onread  = function(addr, cpu, mem) KeyboardOnRead (addr, cpu, mem, Keyboard) end, |  | ||||||
| 		onwrite = function(addr, cpu, mem) KeyboardOnWrite(addr, cpu, mem, Keyboard) end, |  | ||||||
| 	}, |  | ||||||
| 	GPIO         = { range = {0x0400, 0x04FF}, write = true, |  | ||||||
| 		onwrite = function(addr, cpu, mem) GPIOOnWrite(addr, cpu, mem, GPIO) end, |  | ||||||
| 	}, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ---- |  | ||||||
| ffi.cdef [[ |  | ||||||
| struct Event { |  | ||||||
| 	int id; |  | ||||||
| 	int addr; |  | ||||||
| }; |  | ||||||
| struct Memory { |  | ||||||
| 	int data[65536]; |  | ||||||
| 	int canwrite[65536]; |  | ||||||
| 	int writes[65536]; |  | ||||||
| 	int reads[65536]; |  | ||||||
| 	int onread[65536]; |  | ||||||
| 	int onwrite[65536]; |  | ||||||
| 	struct Event events[4096]; |  | ||||||
| 	int numevents; |  | ||||||
| }; |  | ||||||
| ]] |  | ||||||
| local Memory = { |  | ||||||
| 	c = ffi.new("struct Memory"), |  | ||||||
| } |  | ||||||
| local function InitMemory(mem, pers) |  | ||||||
| 	for i = 0, 65535 do |  | ||||||
| 		mem.c.data[i] = 0 |  | ||||||
| 		mem.c.canwrite[i] = 0 |  | ||||||
| 		mem.c.writes[i] = 0 |  | ||||||
| 		mem.c.reads[i] = 0 |  | ||||||
| 		mem.c.onread[i] = 0 |  | ||||||
| 		mem.c.onwrite[i] = 0 |  | ||||||
| 	end |  | ||||||
| 	for k, per in pairs(pers) do |  | ||||||
| 		if per.onread  then registerEvent(mem, per.range[1], per.range[2], true , false, per.onread ) end |  | ||||||
| 		if per.onwrite then registerEvent(mem, per.range[1], per.range[2], false, true , per.onwrite) end |  | ||||||
| 		for a = per.range[1], per.range[2] do |  | ||||||
| 			mem.c.canwrite[a] = (per.write and 1 or 0) |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| ReadMemory = function(mem, addr) |  | ||||||
| 	return mem.c.data[addr%65536]%256 |  | ||||||
| end |  | ||||||
| WriteMemory = function(mem, addr, val) |  | ||||||
| 	if mem.c.canwrite[addr%65536]~=0 then |  | ||||||
| 		mem.c.data[addr%65536] = val%256 |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| local function AssembleToMemory(mem, fn, arch) |  | ||||||
| 	local data, code = asm.assembleFile(fn, arch) |  | ||||||
| 	for addr = 0, 65535 do |  | ||||||
| 		if data[addr] then |  | ||||||
| 			mem.c.data[addr] = data[addr] |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	return data, code |  | ||||||
| end |  | ||||||
|  |  | ||||||
| ffi.cdef [[ |  | ||||||
| struct CPU { |  | ||||||
| 	int a; |  | ||||||
| 	int b; |  | ||||||
| 	int c; |  | ||||||
| 	int u; |  | ||||||
| 	int t; |  | ||||||
| 	int p; |  | ||||||
| 	int q; |  | ||||||
| 	int s; |  | ||||||
| 	int v; |  | ||||||
| 	int i; |  | ||||||
| 	int cf; |  | ||||||
| 	int nz; |  | ||||||
| 	int irq; |  | ||||||
| 	int ifg; |  | ||||||
| 	int rfg; |  | ||||||
| 	int ien; |  | ||||||
| 	int instr; |  | ||||||
| 	int cycle; |  | ||||||
| 	int instrpre; |  | ||||||
| 	int frame; |  | ||||||
| }; |  | ||||||
| int TickCPU(struct CPU* const cpu, struct Memory* const mem, const int count, const int countinstrs, const int breakaddr); |  | ||||||
| ]] |  | ||||||
| local CPU = { |  | ||||||
| 	c = ffi.new("struct CPU"), |  | ||||||
| } |  | ||||||
| local cpuDll = ffi.load("8608emulator.dll") |  | ||||||
| local function TickCPU(cpu, mem, count, countinstrs, breakaddr) |  | ||||||
| 	local countleft = count |  | ||||||
| 	while countleft>0 do |  | ||||||
| 		countleft = cpuDll.TickCPU(cpu.c, mem.c, countleft, countinstrs and 1 or 0, breakaddr or 0xFFFFFFFF) |  | ||||||
| 		handleEvents(cpu, mem) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| local function InitCPU(cpu) |  | ||||||
| 	cpu.c.rfg = 1; |  | ||||||
| end |  | ||||||
| CPURequestInterrupt = function(cpu) |  | ||||||
| 	cpu.c.irq = 1; |  | ||||||
| end |  | ||||||
|  |  | ||||||
| function RunToNextInstr(cpu) |  | ||||||
| 	 |  | ||||||
| end |  | ||||||
|  |  | ||||||
| ---- |  | ||||||
|  |  | ||||||
| local function RedrawVideoDisplay(vd, mem) |  | ||||||
| 	local vd = VideoDisplay |  | ||||||
| 	for y = 0, vd.height-1 do |  | ||||||
| 		for x = 0, vd.width-1 do |  | ||||||
| 			local a = vd.addr + y*vd.width + x |  | ||||||
| 			local colorid = ReadMemory(mem, a)%64 |  | ||||||
| 			local color = ColorSet[colorid] |  | ||||||
| 			vd.imageData:setPixel(x, y, color[1], color[2], color[3]) |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	local img = lg.newImage(vd.imageData) |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| 	lg.draw(img, vd.scrX, vd.scrY) |  | ||||||
| end |  | ||||||
| local function RedrawCharDisplay(cd, mem) |  | ||||||
| 	lg.rectangle("line", cd.scrX, cd.scrY, cd.width+1, cd.height+1) |  | ||||||
| 	lg.setColor(0,0,0) |  | ||||||
| 	lg.rectangle("fill", cd.scrX, cd.scrY, cd.width, cd.height) |  | ||||||
| 	lg.setFont(cd.font) |  | ||||||
| 	local cd = CharDisplay |  | ||||||
| 	for cy = 0, cd.rows-1 do |  | ||||||
| 		for cx = 0, cd.cols-1 do |  | ||||||
| 			local abase = cy*cd.cols + cx |  | ||||||
| 			local achar = cd.addrChar + abase |  | ||||||
| 			local acolor = cd.addrColor + abase |  | ||||||
| 			local colormem = ReadMemory(mem, acolor) |  | ||||||
| 			local colorid = colormem%64 |  | ||||||
| 			local highlight = colormem>=128 |  | ||||||
| 			lg.setColor(ColorSet[colorid]) |  | ||||||
| 			if highlight then |  | ||||||
| 				lg.rectangle("fill", cd.scrX + cx*cd.fontWidth, cd.scrY + cy*cd.fontHeight, cd.fontWidth, cd.fontHeight) |  | ||||||
| 				lg.setColor(0, 0, 0) |  | ||||||
| 			end |  | ||||||
| 			local val = ReadMemory(mem, achar)%128 |  | ||||||
| 			if val>=32 then |  | ||||||
| 				local char = string.char(val) |  | ||||||
| 				lg.print(char, cd.scrX + cx*cd.fontWidth, cd.scrY + cy*cd.fontHeight) |  | ||||||
| 			elseif val>=16 and val<=31 then |  | ||||||
| 				local r, g, b = math.floor(val/4)%2, math.floor(val/2)%2, val%2 |  | ||||||
| 				lg.setColor(r, g, b) |  | ||||||
| 				lg.rectangle("fill", cd.scrX + cx*cd.fontWidth, cd.scrY + cy*cd.fontHeight, cd.fontWidth, cd.fontHeight) |  | ||||||
| 			end |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| 	lg.setFont(InfoFont) |  | ||||||
| end |  | ||||||
| local function InitWindowCanvas() |  | ||||||
| 	WindowCanvas = lg.newCanvas(WindowX, WindowY) |  | ||||||
| 	lg.setCanvas(WindowCanvas) |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| 	lg.setFont(InfoFont) |  | ||||||
| 	lg.print("8608 CPU Emulator", 4, 4) |  | ||||||
| end |  | ||||||
| local function RedrawWindow(usekeyboard, runcpu) |  | ||||||
| 	lg.setCanvas(WindowCanvas) |  | ||||||
| 	lg.setFont(InfoFont) |  | ||||||
| 	RedrawCharDisplay(CharDisplay, Memory) |  | ||||||
| 	--RedrawVideoDisplay(VideoDisplay, Memory) |  | ||||||
| 	RedrawRegDisplay(RegDisplay, CPU, Memory) |  | ||||||
| 	RedrawStackDisplay(StackDisplay, CPU, Memory) |  | ||||||
| 	RedrawProgramDisplay(ProgramDisplay, CPU, Memory) |  | ||||||
| 	for _, md in ipairs(MemoryDisplays) do RedrawMemoryDisplay(md, CPU, Memory) end |  | ||||||
| 	RedrawFPSCounter(128+32, 4) |  | ||||||
| 	RedrawKeyInfo(128+32+64+16, 4, usekeyboard, runcpu) |  | ||||||
| 	 |  | ||||||
| 	lg.setCanvas() |  | ||||||
| end |  | ||||||
|  |  | ||||||
| function love.load() |  | ||||||
| 	InitColorset() |  | ||||||
| 	lg.setDefaultFilter("nearest", "nearest") |  | ||||||
| 	lg.setLineWidth(1) |  | ||||||
| 	lg.setLineStyle("rough") |  | ||||||
| 	InfoFont = lg.newFont("consola.ttf", 12, "mono") |  | ||||||
| 	InitMemory(Memory, peripherals) |  | ||||||
| 	InitWindowCanvas() |  | ||||||
| 	InitCPU(CPU) |  | ||||||
| 	InitGPIO(GPIO) |  | ||||||
| 	--InitVideoDisplay(VideoDisplay) |  | ||||||
| 	InitCharDisplay(CharDisplay) |  | ||||||
| 	InitRegDisplay(RegDisplay) |  | ||||||
| 	InitStackDisplay(StackDisplay) |  | ||||||
| 	local data, code = AssembleToMemory(Memory, arg[2] or "../../8608programs/emutest.asm", Arch) |  | ||||||
| 	InitProgramDisplay(ProgramDisplay, data, code, Arch) |  | ||||||
| 	for _, md in ipairs(MemoryDisplays) do InitMemoryDisplay(md) end |  | ||||||
| 	RedrawWindow() |  | ||||||
| 	lg.setCanvas() |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local RunCPU = false |  | ||||||
| local CPUSpeed = 4999 |  | ||||||
| local UseKeyboard = false |  | ||||||
| function love.draw() |  | ||||||
| 	UpdateGPIO(GPIO, CPU, Memory) |  | ||||||
| 	 |  | ||||||
| 	CPU.c.frame = CPU.c.frame + 1 |  | ||||||
| 	if RunCPU then |  | ||||||
| 		TickCPU(CPU, Memory, CPUSpeed, false, nil) |  | ||||||
| 	end |  | ||||||
| 	 |  | ||||||
| 	RedrawWindow(UseKeyboard, RunCPU) |  | ||||||
| 	 |  | ||||||
| 	lg.setColor(1,1,1) |  | ||||||
| 	lg.draw(WindowCanvas, 0, 0, 0, 2, 2) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| function love.keypressed(k) |  | ||||||
| 	if k=="f4" then |  | ||||||
| 		UseKeyboard = not UseKeyboard |  | ||||||
| 	else |  | ||||||
| 		if UseKeyboard then |  | ||||||
| 			KeyboardOnKey(Keyboard, k, true, CPU, Memory) |  | ||||||
| 		else |  | ||||||
| 			    if k=="q" then le.quit() |  | ||||||
| 			elseif k=="s" then TickCPU(CPU, Memory, 1, true , nil) |  | ||||||
| 			elseif k=="t" then TickCPU(CPU, Memory, 1, false, nil) |  | ||||||
| 			elseif k=="o" then RunToNextInstr(cpu) |  | ||||||
| 			elseif k=="r" then RunCPU = not RunCPU |  | ||||||
| 			elseif k=="i" then CPU.c.irq = 1 |  | ||||||
| 			elseif k=="u" then CPU.c.rfg = 1 |  | ||||||
| 			end |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
| function love.keyreleased(k) |  | ||||||
| 	if k~="f4" and UseKeyboard then KeyboardOnKey(Keyboard, k, false, CPU, Memory) end |  | ||||||
| end |  | ||||||
| @@ -1,74 +0,0 @@ | |||||||
|  |  | ||||||
| ColorSet = { |  | ||||||
| 	{222,52,52,255}, |  | ||||||
| 	{166,65,65,255}, |  | ||||||
| 	{220,215,144,255}, |  | ||||||
| 	{231,193,110,255}, |  | ||||||
| 	{57,180,74,255}, |  | ||||||
| 	{0,128,64,255}, |  | ||||||
| 	{50,105,227,255}, |  | ||||||
| 	{49,79,145,255}, |  | ||||||
| 	 |  | ||||||
| 	{196,17,14,255}, |  | ||||||
| 	{112,17,10,255}, |  | ||||||
| 	{255,191,0,255}, |  | ||||||
| 	{168,98,0,255}, |  | ||||||
| 	{38,107,22,255}, |  | ||||||
| 	{28,82,17,255}, |  | ||||||
| 	{165,189,210,255}, |  | ||||||
| 	{105,145,170,255}, |  | ||||||
| 	 |  | ||||||
| 	{198,105,156,255}, |  | ||||||
| 	{145,68,92,255}, |  | ||||||
| 	{239,202,217,255}, |  | ||||||
| 	{225,175,153,255}, |  | ||||||
| 	{255,125,64,255}, |  | ||||||
| 	{160,66,22,255}, |  | ||||||
| 	{165,234,240,255}, |  | ||||||
| 	{85,175,205,255}, |  | ||||||
| 	 |  | ||||||
| 	{178,169,231,255}, |  | ||||||
| 	{139,90,176,255}, |  | ||||||
| 	{229,175,121,255}, |  | ||||||
| 	{100,50,0,255}, |  | ||||||
| 	{232,114,0,255}, |  | ||||||
| 	{191,54,0,255}, |  | ||||||
| 	{138,178,141,255}, |  | ||||||
| 	{37,69,69,255}, |  | ||||||
| 	 |  | ||||||
| 	{240,239,235,255}, |  | ||||||
| 	{221,216,214,255}, |  | ||||||
| 	{188,184,182,255}, |  | ||||||
| 	{163,158,153,255}, |  | ||||||
| 	{124,124,117,255}, |  | ||||||
| 	{87,86,80,255}, |  | ||||||
| 	{45,45,42,255}, |  | ||||||
| 	{17,17,14,255}, |  | ||||||
| 	 |  | ||||||
| 	{207,175,144,255}, |  | ||||||
| 	{189,158,121,255}, |  | ||||||
| 	{177,138,102,255}, |  | ||||||
| 	{154,112,79,255}, |  | ||||||
| 	{119,82,56,255}, |  | ||||||
| 	{87,59,35,255}, |  | ||||||
| 	{61,36,14,255}, |  | ||||||
| 	{40,23,8,255}, |  | ||||||
| 	 |  | ||||||
| 	{127,52,52,190}, |  | ||||||
| 	{196,136,52,190}, |  | ||||||
| 	{55,90,25,190}, |  | ||||||
| 	{160,180,255,180}, |  | ||||||
| 	{10,45,80,180}, |  | ||||||
| 	{31,22,8,200}, |  | ||||||
| 	{230,228,225,150}, |  | ||||||
| 	{18,18,18,150}, |  | ||||||
| 	 |  | ||||||
| 	{199,178,156,255}, |  | ||||||
| 	{150,135,120,255}, |  | ||||||
| 	{115,99,87,255}, |  | ||||||
| 	{85,70,65,255}, |  | ||||||
| 	{54,47,45,255}, |  | ||||||
| 	{255,255,255,255}, |  | ||||||
| 	{0,0,0,255}, |  | ||||||
| 	{255,255,255,50}, |  | ||||||
| } |  | ||||||
| @@ -1,10 +0,0 @@ | |||||||
|  |  | ||||||
| WindowScale = 2 |  | ||||||
| WindowX = 800 |  | ||||||
| WindowY = 480 |  | ||||||
|  |  | ||||||
| function love.conf(t) |  | ||||||
| 	t.console = true |  | ||||||
| 	t.window.width = WindowX*WindowScale |  | ||||||
| 	t.window.height = WindowY*WindowScale |  | ||||||
| end |  | ||||||
										
											Binary file not shown.
										
									
								
							| @@ -1,66 +0,0 @@ | |||||||
|  |  | ||||||
| local function fixCode(code) |  | ||||||
| 	code = code:gsub("cpu%.", "cpu%->") |  | ||||||
| 	if |  | ||||||
| 		not code:find("lni") and |  | ||||||
| 		not code:find("instrloadpre") and |  | ||||||
| 		not code:find("jmp") and |  | ||||||
| 		not code:find("ldi") |  | ||||||
| 	then code = code.." cpu->cycle++;" end |  | ||||||
| 	return code |  | ||||||
| end |  | ||||||
| local function lineFromInstr(instr) |  | ||||||
| 	local cycleLines = {} |  | ||||||
| 	for cycle = 0, 7 do |  | ||||||
| 		if instr and instr.ccode[cycle+1] then |  | ||||||
| 			cycleLines[cycle+1] = string.format("cpu_instr_%i_%i", instr.opcode, cycle) |  | ||||||
| 		else |  | ||||||
| 			cycleLines[cycle+1] = 0 |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	return string.format("{%s},", table.concat(cycleLines, ",")) |  | ||||||
| end |  | ||||||
| local function codeFromInstr(instr, lines) |  | ||||||
| 	for i, code in ipairs(instr.ccode) do |  | ||||||
| 		local cycle = i-1 |  | ||||||
| 		local line = string.format( |  | ||||||
| 			"void cpu_instr_%i_%i(struct CPU* const cpu, struct Memory* const mem) { %s }", |  | ||||||
| 			instr.opcode, cycle, |  | ||||||
| 			fixCode(code) |  | ||||||
| 		) |  | ||||||
| 		table.insert(lines, line) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local ccode = [[ |  | ||||||
| // Auto-generated by gendefs.lua |  | ||||||
|  |  | ||||||
| %s |  | ||||||
|  |  | ||||||
| CPUInstruction CPUInstructions[256][8] = { |  | ||||||
| 	%s |  | ||||||
| }; |  | ||||||
| ]] |  | ||||||
| local function ccodeFromArch(arch) |  | ||||||
| 	local instrsByOpcode = {} |  | ||||||
| 	for i, instr in ipairs(arch.instructions) do |  | ||||||
| 		if instr.opcode then instrsByOpcode[instr.opcode] = instr end |  | ||||||
| 	end |  | ||||||
| 	 |  | ||||||
| 	local instrLines = {} |  | ||||||
| 	local funcLines = {} |  | ||||||
| 	for opcode = 0, 255 do |  | ||||||
| 		local instr = instrsByOpcode[opcode] |  | ||||||
| 		instrLines[opcode+1] = lineFromInstr(instr) |  | ||||||
| 		if instr then codeFromInstr(instr, funcLines) end |  | ||||||
| 	end |  | ||||||
| 	return string.format(ccode, |  | ||||||
| 		table.concat(funcLines, "\n"), |  | ||||||
| 		table.concat(instrLines, "\n\t") |  | ||||||
| 	) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local arch = dofile("../rom-8608-defs.lua") |  | ||||||
| local fo = io.open("instructions_gen.c", "w") |  | ||||||
| fo:write(ccodeFromArch(arch)) |  | ||||||
| fo:close() |  | ||||||
| @@ -1,709 +0,0 @@ | |||||||
| // Auto-generated by gendefs.lua |  | ||||||
|  |  | ||||||
| void cpu_instr_0_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=0; cpu->b=0; cpu->c=0; cpu->u=0; cpu->t=0; cpu->p=0; cpu->q=0; cpu->s=0; cpu->v=0; cpu->i=0; cpu->cf=0; cpu->nz=0; cpu->irq=0; cpu->ifg=0; cpu->rfg=1; cpu->ien=0; lni; } |  | ||||||
| void cpu_instr_16_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a, 1    ); lni; } |  | ||||||
| void cpu_instr_17_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-1    ); lni; } |  | ||||||
| void cpu_instr_18_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p++; lni; } |  | ||||||
| void cpu_instr_19_0(struct CPU* const cpu, struct Memory* const mem) { cpu->q++; lni; } |  | ||||||
| void cpu_instr_20_0(struct CPU* const cpu, struct Memory* const mem) { tst(cpu->a); lni; } |  | ||||||
| void cpu_instr_21_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p--; lni; } |  | ||||||
| void cpu_instr_22_0(struct CPU* const cpu, struct Memory* const mem) { cpu->q--; lni; } |  | ||||||
| void cpu_instr_23_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c, 1    ); lni; } |  | ||||||
| void cpu_instr_24_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,-1    ); lni; } |  | ||||||
| void cpu_instr_25_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b, 1    ); lni; } |  | ||||||
| void cpu_instr_26_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,-1    ); lni; } |  | ||||||
| void cpu_instr_27_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->cf); lni; } |  | ||||||
| void cpu_instr_28_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,cpu->cf); lni; } |  | ||||||
| void cpu_instr_29_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,cpu->cf); lni; } |  | ||||||
| void cpu_instr_30_0(struct CPU* const cpu, struct Memory* const mem) { tst(cpu->b); lni; } |  | ||||||
| void cpu_instr_31_0(struct CPU* const cpu, struct Memory* const mem) { tst(cpu->c); lni; } |  | ||||||
| void cpu_instr_32_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadimmed; setzf(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_32_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_33_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_33_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_33_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } |  | ||||||
| void cpu_instr_34_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_34_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_34_2(struct CPU* const cpu, struct Memory* const mem) { cpu->v=wordut; lni; } |  | ||||||
| void cpu_instr_35_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_35_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_35_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } |  | ||||||
| void cpu_instr_36_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_36_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->t); lni; } |  | ||||||
| void cpu_instr_37_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_37_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_37_2(struct CPU* const cpu, struct Memory* const mem) { cpu->s=wordut; lni; } |  | ||||||
| void cpu_instr_38_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadimmed; setzf(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_38_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_39_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadimmed; setzf(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_39_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_40_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; } |  | ||||||
| void cpu_instr_40_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadstackrel; setzf(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_40_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_41_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; } |  | ||||||
| void cpu_instr_41_1(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadstackrel; setzf(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_41_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_42_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; } |  | ||||||
| void cpu_instr_42_1(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadstackrel; setzf(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_42_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_43_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_43_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_43_2(struct CPU* const cpu, struct Memory* const mem) { instrpreload; addf(cpu->u, 1    ); cpu->cycle++; } |  | ||||||
| void cpu_instr_43_3(struct CPU* const cpu, struct Memory* const mem) { instrloadpre } |  | ||||||
| void cpu_instr_44_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_44_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_44_2(struct CPU* const cpu, struct Memory* const mem) { instrpreload; addf(cpu->u,-1    ); cpu->cycle++; } |  | ||||||
| void cpu_instr_44_3(struct CPU* const cpu, struct Memory* const mem) { instrloadpre } |  | ||||||
| void cpu_instr_45_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_45_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_45_2(struct CPU* const cpu, struct Memory* const mem) { instrpreload; addf(cpu->u,cpu->cf); cpu->cycle++; } |  | ||||||
| void cpu_instr_45_3(struct CPU* const cpu, struct Memory* const mem) { instrloadpre } |  | ||||||
| void cpu_instr_46_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_46_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_46_2(struct CPU* const cpu, struct Memory* const mem) { tst(cpu->u); lni; } |  | ||||||
| void cpu_instr_47_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=sra(cpu->a,cpu->c); setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_48_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_48_1(struct CPU* const cpu, struct Memory* const mem) { if( cpu->nz               ) { jmprelt } else { lni } } |  | ||||||
| void cpu_instr_49_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_49_1(struct CPU* const cpu, struct Memory* const mem) { jmprelt } |  | ||||||
| void cpu_instr_50_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_50_1(struct CPU* const cpu, struct Memory* const mem) { if(!cpu->nz               ) { jmprelt } else { lni } } |  | ||||||
| void cpu_instr_51_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_51_1(struct CPU* const cpu, struct Memory* const mem) { if(!cpu->cf               ) { jmprelt } else { lni } } |  | ||||||
| void cpu_instr_52_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_52_1(struct CPU* const cpu, struct Memory* const mem) { if( cpu->cf               ) { jmprelt } else { lni } } |  | ||||||
| void cpu_instr_53_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_53_1(struct CPU* const cpu, struct Memory* const mem) { if(  cpu->nz &&    cpu->cf ) { jmprelt } else { lni } } |  | ||||||
| void cpu_instr_54_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_54_1(struct CPU* const cpu, struct Memory* const mem) { if((!cpu->nz) || (!cpu->cf)) { jmprelt } else { lni } } |  | ||||||
| void cpu_instr_55_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=lobyte(cpu->p); lni; } |  | ||||||
| void cpu_instr_56_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=hibyte(cpu->p); lni; } |  | ||||||
| void cpu_instr_57_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=lobyte(cpu->q); lni; } |  | ||||||
| void cpu_instr_58_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=hibyte(cpu->q); lni; } |  | ||||||
| void cpu_instr_59_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; } |  | ||||||
| void cpu_instr_59_1(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->t); cpu->cycle++; } |  | ||||||
| void cpu_instr_59_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_60_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_60_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_60_2(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->u); cpu->cycle++; } |  | ||||||
| void cpu_instr_60_3(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->t); cpu->cycle++; } |  | ||||||
| void cpu_instr_60_4(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_62_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=rol(cpu->a,cpu->c); setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_63_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=ror(cpu->a,cpu->c); setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_64_0(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_64_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_65_0(struct CPU* const cpu, struct Memory* const mem) { push161(cpu->p); cpu->cycle++; } |  | ||||||
| void cpu_instr_65_1(struct CPU* const cpu, struct Memory* const mem) { push162(cpu->p); cpu->cycle++; } |  | ||||||
| void cpu_instr_65_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_66_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=popbyte; cpu->cycle++; } |  | ||||||
| void cpu_instr_66_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_67_0(struct CPU* const cpu, struct Memory* const mem) { pop161 cpu->cycle++; } |  | ||||||
| void cpu_instr_67_1(struct CPU* const cpu, struct Memory* const mem) { pop162 cpu->cycle++; } |  | ||||||
| void cpu_instr_67_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } |  | ||||||
| void cpu_instr_68_0(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_68_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_69_0(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_69_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_70_0(struct CPU* const cpu, struct Memory* const mem) { push161(cpu->q); cpu->cycle++; } |  | ||||||
| void cpu_instr_70_1(struct CPU* const cpu, struct Memory* const mem) { push162(cpu->q); cpu->cycle++; } |  | ||||||
| void cpu_instr_70_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_71_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=popbyte; cpu->cycle++; } |  | ||||||
| void cpu_instr_71_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_72_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=popbyte; cpu->cycle++; } |  | ||||||
| void cpu_instr_72_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_73_0(struct CPU* const cpu, struct Memory* const mem) { pop161 cpu->cycle++; } |  | ||||||
| void cpu_instr_73_1(struct CPU* const cpu, struct Memory* const mem) { pop162 cpu->cycle++; } |  | ||||||
| void cpu_instr_73_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } |  | ||||||
| void cpu_instr_74_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_74_1(struct CPU* const cpu, struct Memory* const mem) { cpu->p+=signed8(cpu->t); lni; } |  | ||||||
| void cpu_instr_75_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_75_1(struct CPU* const cpu, struct Memory* const mem) { cpu->q+=signed8(cpu->t); lni; } |  | ||||||
| void cpu_instr_76_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_76_1(struct CPU* const cpu, struct Memory* const mem) { cpu->s+=signed8(cpu->t); lni; } |  | ||||||
| void cpu_instr_77_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a>>=cpu->c; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_78_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,cpu->a); lni; } |  | ||||||
| void cpu_instr_79_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->c,cpu->a); lni; } |  | ||||||
| void cpu_instr_80_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_80_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_80_2(struct CPU* const cpu, struct Memory* const mem) { storeut(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_80_3(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_81_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_81_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_81_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadut; setzf(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_81_3(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_82_0(struct CPU* const cpu, struct Memory* const mem) { storep(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_82_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_83_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadp; setzf(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_83_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_84_0(struct CPU* const cpu, struct Memory* const mem) { storeq(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_84_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_85_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadq; setzf(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_85_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_86_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_86_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_86_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadut; setzf(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_86_3(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_87_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_87_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_87_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadut; setzf(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_87_3(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_88_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_88_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_88_2(struct CPU* const cpu, struct Memory* const mem) { storeut(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_88_3(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_89_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_89_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_89_2(struct CPU* const cpu, struct Memory* const mem) { storeut(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_89_3(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_90_0(struct CPU* const cpu, struct Memory* const mem) { storep(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_90_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_91_0(struct CPU* const cpu, struct Memory* const mem) { storep(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_91_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_92_0(struct CPU* const cpu, struct Memory* const mem) { storeq(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_92_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_93_0(struct CPU* const cpu, struct Memory* const mem) { storeq(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_93_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_94_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadp; setzf(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_94_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_95_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadp; setzf(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_95_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_96_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_96_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_96_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsut } |  | ||||||
| void cpu_instr_97_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadq; setzf(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_97_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_98_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadq; setzf(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_98_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_99_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_99_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_99_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsut saveretaddr } |  | ||||||
| void cpu_instr_100_0(struct CPU* const cpu, struct Memory* const mem) { jmpabsp } |  | ||||||
| void cpu_instr_101_0(struct CPU* const cpu, struct Memory* const mem) { jmpabsp } |  | ||||||
| void cpu_instr_101_1(struct CPU* const cpu, struct Memory* const mem) { saveretaddr cpu->cycle++; } |  | ||||||
| void cpu_instr_102_0(struct CPU* const cpu, struct Memory* const mem) { jmpabsq } |  | ||||||
| void cpu_instr_103_0(struct CPU* const cpu, struct Memory* const mem) { jmpabsq } |  | ||||||
| void cpu_instr_103_1(struct CPU* const cpu, struct Memory* const mem) { saveretaddr cpu->cycle++; } |  | ||||||
| void cpu_instr_104_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_104_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_104_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; } |  | ||||||
| void cpu_instr_104_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; } |  | ||||||
| void cpu_instr_104_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } |  | ||||||
| void cpu_instr_106_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_106_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_106_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; } |  | ||||||
| void cpu_instr_106_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; } |  | ||||||
| void cpu_instr_106_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } |  | ||||||
| void cpu_instr_108_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_108_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_108_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->p)); cpu->cycle++; } |  | ||||||
| void cpu_instr_108_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->p)); cpu->cycle++; } |  | ||||||
| void cpu_instr_108_4(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_110_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_110_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_110_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->q)); cpu->cycle++; } |  | ||||||
| void cpu_instr_110_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->q)); cpu->cycle++; } |  | ||||||
| void cpu_instr_110_4(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_112_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_112_1(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->t); lni; } |  | ||||||
| void cpu_instr_113_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_113_1(struct CPU* const cpu, struct Memory* const mem) { cmpf(cpu->a,cpu->t); lni; } |  | ||||||
| void cpu_instr_114_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_114_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,cpu->t); lni; } |  | ||||||
| void cpu_instr_115_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_115_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,cpu->t); lni; } |  | ||||||
| void cpu_instr_116_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_116_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=cpu->t; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_117_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_117_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a|=cpu->t; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_118_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_118_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a^=cpu->t; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_119_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_119_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=~cpu->t; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_120_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_120_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->t+cpu->cf); lni; } |  | ||||||
| void cpu_instr_121_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_121_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->t+cpu->cf); lni; } |  | ||||||
| void cpu_instr_122_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_122_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrel161 cpu->cycle++; } |  | ||||||
| void cpu_instr_122_2(struct CPU* const cpu, struct Memory* const mem) { loadstackrel162 cpu->cycle++; } |  | ||||||
| void cpu_instr_122_3(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } |  | ||||||
| void cpu_instr_123_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_123_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrel161 cpu->cycle++; } |  | ||||||
| void cpu_instr_123_2(struct CPU* const cpu, struct Memory* const mem) { loadstackrel162 cpu->cycle++; } |  | ||||||
| void cpu_instr_123_3(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } |  | ||||||
| void cpu_instr_124_0(struct CPU* const cpu, struct Memory* const mem) { storeq(hibyte(cpu->p)); cpu->cycle++; } |  | ||||||
| void cpu_instr_124_1(struct CPU* const cpu, struct Memory* const mem) { storeqp1(lobyte(cpu->p)); cpu->cycle++; } |  | ||||||
| void cpu_instr_124_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_125_0(struct CPU* const cpu, struct Memory* const mem) { storep(hibyte(cpu->q)); cpu->cycle++; } |  | ||||||
| void cpu_instr_125_1(struct CPU* const cpu, struct Memory* const mem) { storepp1(lobyte(cpu->q)); cpu->cycle++; } |  | ||||||
| void cpu_instr_125_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_126_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_126_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel161(cpu->p); cpu->cycle++; } |  | ||||||
| void cpu_instr_126_2(struct CPU* const cpu, struct Memory* const mem) { storestackrel162(cpu->p); cpu->cycle++; } |  | ||||||
| void cpu_instr_126_3(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_127_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_127_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel161(cpu->q); cpu->cycle++; } |  | ||||||
| void cpu_instr_127_2(struct CPU* const cpu, struct Memory* const mem) { storestackrel162(cpu->q); cpu->cycle++; } |  | ||||||
| void cpu_instr_127_3(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_128_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=cpu->b; lni; } |  | ||||||
| void cpu_instr_129_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=cpu->c; lni; } |  | ||||||
| void cpu_instr_130_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=cpu->a; lni; } |  | ||||||
| void cpu_instr_131_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=cpu->c; lni; } |  | ||||||
| void cpu_instr_132_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=cpu->a; lni; } |  | ||||||
| void cpu_instr_133_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=cpu->b; lni; } |  | ||||||
| void cpu_instr_134_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=lobyte(cpu->p); lni; } |  | ||||||
| void cpu_instr_135_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=hibyte(cpu->p); lni; } |  | ||||||
| void cpu_instr_136_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=lobyte(cpu->q); lni; } |  | ||||||
| void cpu_instr_137_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=hibyte(cpu->q); lni; } |  | ||||||
| void cpu_instr_138_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=cpu->q; lni; } |  | ||||||
| void cpu_instr_139_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=cpu->s; lni; } |  | ||||||
| void cpu_instr_140_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=cpu->v; lni; } |  | ||||||
| void cpu_instr_141_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=cpu->i; lni; } |  | ||||||
| void cpu_instr_142_0(struct CPU* const cpu, struct Memory* const mem) { cpu->q=cpu->p; lni; } |  | ||||||
| void cpu_instr_143_0(struct CPU* const cpu, struct Memory* const mem) { cpu->s=cpu->p; lni; } |  | ||||||
| void cpu_instr_144_0(struct CPU* const cpu, struct Memory* const mem) { cpu->v=cpu->p; lni; } |  | ||||||
| void cpu_instr_145_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordcb; lni; } |  | ||||||
| void cpu_instr_146_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadp; cpu->cycle++; } |  | ||||||
| void cpu_instr_146_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; } |  | ||||||
| void cpu_instr_146_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } |  | ||||||
| void cpu_instr_147_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadp; cpu->cycle++; } |  | ||||||
| void cpu_instr_147_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; } |  | ||||||
| void cpu_instr_147_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } |  | ||||||
| void cpu_instr_148_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadq; cpu->cycle++; } |  | ||||||
| void cpu_instr_148_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; } |  | ||||||
| void cpu_instr_148_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } |  | ||||||
| void cpu_instr_149_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadq; cpu->cycle++; } |  | ||||||
| void cpu_instr_149_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; } |  | ||||||
| void cpu_instr_149_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } |  | ||||||
| void cpu_instr_150_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; } |  | ||||||
| void cpu_instr_150_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_150_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_151_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; } |  | ||||||
| void cpu_instr_151_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_151_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_152_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; } |  | ||||||
| void cpu_instr_152_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_152_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_153_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_153_1(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->b,cpu->t); lni; } |  | ||||||
| void cpu_instr_154_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_154_1(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->c,cpu->t); lni; } |  | ||||||
| void cpu_instr_155_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_155_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_155_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,cpu->u); lni; } |  | ||||||
| void cpu_instr_156_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_156_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_156_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,cpu->u); lni; } |  | ||||||
| void cpu_instr_157_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_157_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_157_2(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->b,cpu->u); lni; } |  | ||||||
| void cpu_instr_158_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_158_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_158_2(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->c,cpu->u); lni; } |  | ||||||
| void cpu_instr_159_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,cpu->b); lni; } |  | ||||||
| void cpu_instr_160_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->b); lni; } |  | ||||||
| void cpu_instr_161_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->b); lni; } |  | ||||||
| void cpu_instr_162_0(struct CPU* const cpu, struct Memory* const mem) { cmpf(cpu->a,cpu->b); lni; } |  | ||||||
| void cpu_instr_163_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=cpu->b; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_164_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a|=cpu->b; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_165_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a^=cpu->b; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_166_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=~cpu->b; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_167_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->c); lni; } |  | ||||||
| void cpu_instr_168_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->c); lni; } |  | ||||||
| void cpu_instr_169_0(struct CPU* const cpu, struct Memory* const mem) { cmpf(cpu->a,cpu->c); lni; } |  | ||||||
| void cpu_instr_170_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=cpu->c; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_171_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a|=cpu->c; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_172_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a^=cpu->c; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_173_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=~cpu->c; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_174_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_174_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_174_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->u); lni; } |  | ||||||
| void cpu_instr_175_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_175_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_175_2(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->u); lni; } |  | ||||||
| void cpu_instr_176_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_176_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_176_2(struct CPU* const cpu, struct Memory* const mem) { cmpf(cpu->a,cpu->u); lni; } |  | ||||||
| void cpu_instr_177_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_177_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_177_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=cpu->u; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_178_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_178_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_178_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a|=cpu->u; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_179_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_179_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_179_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a^=cpu->u; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_180_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_180_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_180_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=~cpu->u; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_181_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_181_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_181_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->u+cpu->cf); lni; } |  | ||||||
| void cpu_instr_182_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->c,cpu->b); lni; } |  | ||||||
| void cpu_instr_183_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_183_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_183_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->u+cpu->cf); lni; } |  | ||||||
| void cpu_instr_184_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->b+cpu->cf); lni; } |  | ||||||
| void cpu_instr_185_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->b+cpu->cf); lni; } |  | ||||||
| void cpu_instr_186_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->c+cpu->cf); lni; } |  | ||||||
| void cpu_instr_187_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->c+cpu->cf); lni; } |  | ||||||
| void cpu_instr_188_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->b,cpu->c); lni; } |  | ||||||
| void cpu_instr_189_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,cpu->c); lni; } |  | ||||||
| void cpu_instr_190_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,cpu->a); lni; } |  | ||||||
| void cpu_instr_191_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->b,cpu->a); lni; } |  | ||||||
| void cpu_instr_192_0(struct CPU* const cpu, struct Memory* const mem) { storepinc(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_192_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_193_0(struct CPU* const cpu, struct Memory* const mem) { storepinc(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_193_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_194_0(struct CPU* const cpu, struct Memory* const mem) { storepinc(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_194_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_195_0(struct CPU* const cpu, struct Memory* const mem) { storeqinc(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_195_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_196_0(struct CPU* const cpu, struct Memory* const mem) { storeqinc(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_196_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_197_0(struct CPU* const cpu, struct Memory* const mem) { storeqinc(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_197_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_198_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadpinc; setzf(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_198_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_199_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadpinc; setzf(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_199_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_200_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadpinc; setzf(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_200_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_201_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadqinc; setzf(cpu->a); cpu->cycle++; } |  | ||||||
| void cpu_instr_201_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_202_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadqinc; setzf(cpu->b); cpu->cycle++; } |  | ||||||
| void cpu_instr_202_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_203_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadqinc; setzf(cpu->c); cpu->cycle++; } |  | ||||||
| void cpu_instr_203_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_204_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadpinc; cpu->cycle++; } |  | ||||||
| void cpu_instr_204_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpinc; cpu->cycle++; } |  | ||||||
| void cpu_instr_204_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } |  | ||||||
| void cpu_instr_205_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadqinc; cpu->cycle++; } |  | ||||||
| void cpu_instr_205_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqinc; cpu->cycle++; } |  | ||||||
| void cpu_instr_205_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } |  | ||||||
| void cpu_instr_206_0(struct CPU* const cpu, struct Memory* const mem) { storeqinc(hibyte(cpu->p)); cpu->cycle++; } |  | ||||||
| void cpu_instr_206_1(struct CPU* const cpu, struct Memory* const mem) { storeqinc(lobyte(cpu->p)); cpu->cycle++; } |  | ||||||
| void cpu_instr_206_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_207_0(struct CPU* const cpu, struct Memory* const mem) { storepinc(hibyte(cpu->q)); cpu->cycle++; } |  | ||||||
| void cpu_instr_207_1(struct CPU* const cpu, struct Memory* const mem) { storepinc(lobyte(cpu->q)); cpu->cycle++; } |  | ||||||
| void cpu_instr_207_2(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_208_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_208_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a<<=cpu->t; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_209_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_209_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a>>=cpu->t; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_210_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_210_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a=rol(cpu->a,cpu->t); setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_211_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_211_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a=ror(cpu->a,cpu->t); setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_212_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_212_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a=sra(cpu->a,cpu->t); setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_213_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_213_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_213_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a<<=cpu->u; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_214_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_214_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_214_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a>>=cpu->u; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_215_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_215_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_215_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=rol(cpu->a,cpu->u); setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_216_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_216_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_216_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=ror(cpu->a,cpu->u); setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_217_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } |  | ||||||
| void cpu_instr_217_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } |  | ||||||
| void cpu_instr_217_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=sra(cpu->a,cpu->u); setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_218_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a<<=cpu->b; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_219_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a>>=cpu->b; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_220_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=rol(cpu->a,cpu->b); setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_221_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=ror(cpu->a,cpu->b); setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_222_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=sra(cpu->a,cpu->b); setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_223_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a<<=cpu->c; setzf(cpu->a); lni; } |  | ||||||
| void cpu_instr_224_0(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordcb; lni; } |  | ||||||
| void cpu_instr_225_0(struct CPU* const cpu, struct Memory* const mem) { pop161 cpu->cycle++; } |  | ||||||
| void cpu_instr_225_1(struct CPU* const cpu, struct Memory* const mem) { pop162 cpu->cycle++; } |  | ||||||
| void cpu_instr_225_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsutplus1 } |  | ||||||
| void cpu_instr_226_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } |  | ||||||
| void cpu_instr_226_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } |  | ||||||
| void cpu_instr_226_2(struct CPU* const cpu, struct Memory* const mem) { pushretaddr1 cpu->cycle++; } |  | ||||||
| void cpu_instr_226_3(struct CPU* const cpu, struct Memory* const mem) { pushretaddr2 cpu->cycle++; } |  | ||||||
| void cpu_instr_226_4(struct CPU* const cpu, struct Memory* const mem) { jmpabsut } |  | ||||||
| void cpu_instr_228_0(struct CPU* const cpu, struct Memory* const mem) { pushretaddr1 cpu->cycle++; } |  | ||||||
| void cpu_instr_228_1(struct CPU* const cpu, struct Memory* const mem) { pushretaddr2 cpu->cycle++; } |  | ||||||
| void cpu_instr_228_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsp } |  | ||||||
| void cpu_instr_229_0(struct CPU* const cpu, struct Memory* const mem) { pushretaddr1 cpu->cycle++; } |  | ||||||
| void cpu_instr_229_1(struct CPU* const cpu, struct Memory* const mem) { pushretaddr2 cpu->cycle++; } |  | ||||||
| void cpu_instr_229_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsq } |  | ||||||
| void cpu_instr_230_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p+=signed8(cpu->b); lni; } |  | ||||||
| void cpu_instr_231_0(struct CPU* const cpu, struct Memory* const mem) { cpu->q+=signed8(cpu->b); lni; } |  | ||||||
| void cpu_instr_232_0(struct CPU* const cpu, struct Memory* const mem) { cpu->s+=signed8(cpu->b); lni; } |  | ||||||
| void cpu_instr_233_0(struct CPU* const cpu, struct Memory* const mem) { int f = cpu->nz | (cpu->cf<<1); pushbyte(f); cpu->cycle++; } |  | ||||||
| void cpu_instr_233_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_234_0(struct CPU* const cpu, struct Memory* const mem) { int f=popbyte; cpu->nz = f&1; cpu->cf = (f>>1)&1; cpu->cycle++; } |  | ||||||
| void cpu_instr_234_1(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
| void cpu_instr_240_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=0; lni; } |  | ||||||
| void cpu_instr_241_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=1; lni; } |  | ||||||
| void cpu_instr_242_0(struct CPU* const cpu, struct Memory* const mem) { cpu->irq=0; cpu->ifg=1; int t=cpu->i; cpu->i=cpu->v; cpu->v=(t-1)%65536; lni; } |  | ||||||
| void cpu_instr_243_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg=1; int t=cpu->i; cpu->i=cpu->v; cpu->v=t; lni; } |  | ||||||
| void cpu_instr_244_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg=0; int t=cpu->i; cpu->i=cpu->v; cpu->v=t; lni; } |  | ||||||
| void cpu_instr_245_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=1; lni; } |  | ||||||
| void cpu_instr_246_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=0; lni; } |  | ||||||
| void cpu_instr_255_0(struct CPU* const cpu, struct Memory* const mem) { lni; } |  | ||||||
|  |  | ||||||
| CPUInstruction CPUInstructions[256][8] = { |  | ||||||
| 	{cpu_instr_0_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_16_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_17_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_18_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_19_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_20_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_21_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_22_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_23_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_24_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_25_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_26_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_27_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_28_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_29_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_30_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_31_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_32_0,cpu_instr_32_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_33_0,cpu_instr_33_1,cpu_instr_33_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_34_0,cpu_instr_34_1,cpu_instr_34_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_35_0,cpu_instr_35_1,cpu_instr_35_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_36_0,cpu_instr_36_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_37_0,cpu_instr_37_1,cpu_instr_37_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_38_0,cpu_instr_38_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_39_0,cpu_instr_39_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_40_0,cpu_instr_40_1,cpu_instr_40_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_41_0,cpu_instr_41_1,cpu_instr_41_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_42_0,cpu_instr_42_1,cpu_instr_42_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_43_0,cpu_instr_43_1,cpu_instr_43_2,cpu_instr_43_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_44_0,cpu_instr_44_1,cpu_instr_44_2,cpu_instr_44_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_45_0,cpu_instr_45_1,cpu_instr_45_2,cpu_instr_45_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_46_0,cpu_instr_46_1,cpu_instr_46_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_47_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_48_0,cpu_instr_48_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_49_0,cpu_instr_49_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_50_0,cpu_instr_50_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_51_0,cpu_instr_51_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_52_0,cpu_instr_52_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_53_0,cpu_instr_53_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_54_0,cpu_instr_54_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_55_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_56_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_57_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_58_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_59_0,cpu_instr_59_1,cpu_instr_59_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_60_0,cpu_instr_60_1,cpu_instr_60_2,cpu_instr_60_3,cpu_instr_60_4,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_62_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_63_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_64_0,cpu_instr_64_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_65_0,cpu_instr_65_1,cpu_instr_65_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_66_0,cpu_instr_66_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_67_0,cpu_instr_67_1,cpu_instr_67_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_68_0,cpu_instr_68_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_69_0,cpu_instr_69_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_70_0,cpu_instr_70_1,cpu_instr_70_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_71_0,cpu_instr_71_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_72_0,cpu_instr_72_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_73_0,cpu_instr_73_1,cpu_instr_73_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_74_0,cpu_instr_74_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_75_0,cpu_instr_75_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_76_0,cpu_instr_76_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_77_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_78_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_79_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_80_0,cpu_instr_80_1,cpu_instr_80_2,cpu_instr_80_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_81_0,cpu_instr_81_1,cpu_instr_81_2,cpu_instr_81_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_82_0,cpu_instr_82_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_83_0,cpu_instr_83_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_84_0,cpu_instr_84_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_85_0,cpu_instr_85_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_86_0,cpu_instr_86_1,cpu_instr_86_2,cpu_instr_86_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_87_0,cpu_instr_87_1,cpu_instr_87_2,cpu_instr_87_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_88_0,cpu_instr_88_1,cpu_instr_88_2,cpu_instr_88_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_89_0,cpu_instr_89_1,cpu_instr_89_2,cpu_instr_89_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_90_0,cpu_instr_90_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_91_0,cpu_instr_91_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_92_0,cpu_instr_92_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_93_0,cpu_instr_93_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_94_0,cpu_instr_94_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_95_0,cpu_instr_95_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_96_0,cpu_instr_96_1,cpu_instr_96_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_97_0,cpu_instr_97_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_98_0,cpu_instr_98_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_99_0,cpu_instr_99_1,cpu_instr_99_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_100_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_101_0,cpu_instr_101_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_102_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_103_0,cpu_instr_103_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_104_0,cpu_instr_104_1,cpu_instr_104_2,cpu_instr_104_3,cpu_instr_104_4,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_106_0,cpu_instr_106_1,cpu_instr_106_2,cpu_instr_106_3,cpu_instr_106_4,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_108_0,cpu_instr_108_1,cpu_instr_108_2,cpu_instr_108_3,cpu_instr_108_4,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_110_0,cpu_instr_110_1,cpu_instr_110_2,cpu_instr_110_3,cpu_instr_110_4,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_112_0,cpu_instr_112_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_113_0,cpu_instr_113_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_114_0,cpu_instr_114_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_115_0,cpu_instr_115_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_116_0,cpu_instr_116_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_117_0,cpu_instr_117_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_118_0,cpu_instr_118_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_119_0,cpu_instr_119_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_120_0,cpu_instr_120_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_121_0,cpu_instr_121_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_122_0,cpu_instr_122_1,cpu_instr_122_2,cpu_instr_122_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_123_0,cpu_instr_123_1,cpu_instr_123_2,cpu_instr_123_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_124_0,cpu_instr_124_1,cpu_instr_124_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_125_0,cpu_instr_125_1,cpu_instr_125_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_126_0,cpu_instr_126_1,cpu_instr_126_2,cpu_instr_126_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_127_0,cpu_instr_127_1,cpu_instr_127_2,cpu_instr_127_3,0,0,0,0}, |  | ||||||
| 	{cpu_instr_128_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_129_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_130_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_131_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_132_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_133_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_134_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_135_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_136_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_137_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_138_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_139_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_140_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_141_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_142_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_143_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_144_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_145_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_146_0,cpu_instr_146_1,cpu_instr_146_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_147_0,cpu_instr_147_1,cpu_instr_147_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_148_0,cpu_instr_148_1,cpu_instr_148_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_149_0,cpu_instr_149_1,cpu_instr_149_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_150_0,cpu_instr_150_1,cpu_instr_150_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_151_0,cpu_instr_151_1,cpu_instr_151_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_152_0,cpu_instr_152_1,cpu_instr_152_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_153_0,cpu_instr_153_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_154_0,cpu_instr_154_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_155_0,cpu_instr_155_1,cpu_instr_155_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_156_0,cpu_instr_156_1,cpu_instr_156_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_157_0,cpu_instr_157_1,cpu_instr_157_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_158_0,cpu_instr_158_1,cpu_instr_158_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_159_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_160_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_161_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_162_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_163_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_164_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_165_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_166_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_167_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_168_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_169_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_170_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_171_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_172_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_173_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_174_0,cpu_instr_174_1,cpu_instr_174_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_175_0,cpu_instr_175_1,cpu_instr_175_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_176_0,cpu_instr_176_1,cpu_instr_176_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_177_0,cpu_instr_177_1,cpu_instr_177_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_178_0,cpu_instr_178_1,cpu_instr_178_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_179_0,cpu_instr_179_1,cpu_instr_179_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_180_0,cpu_instr_180_1,cpu_instr_180_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_181_0,cpu_instr_181_1,cpu_instr_181_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_182_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_183_0,cpu_instr_183_1,cpu_instr_183_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_184_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_185_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_186_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_187_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_188_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_189_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_190_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_191_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_192_0,cpu_instr_192_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_193_0,cpu_instr_193_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_194_0,cpu_instr_194_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_195_0,cpu_instr_195_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_196_0,cpu_instr_196_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_197_0,cpu_instr_197_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_198_0,cpu_instr_198_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_199_0,cpu_instr_199_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_200_0,cpu_instr_200_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_201_0,cpu_instr_201_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_202_0,cpu_instr_202_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_203_0,cpu_instr_203_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_204_0,cpu_instr_204_1,cpu_instr_204_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_205_0,cpu_instr_205_1,cpu_instr_205_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_206_0,cpu_instr_206_1,cpu_instr_206_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_207_0,cpu_instr_207_1,cpu_instr_207_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_208_0,cpu_instr_208_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_209_0,cpu_instr_209_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_210_0,cpu_instr_210_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_211_0,cpu_instr_211_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_212_0,cpu_instr_212_1,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_213_0,cpu_instr_213_1,cpu_instr_213_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_214_0,cpu_instr_214_1,cpu_instr_214_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_215_0,cpu_instr_215_1,cpu_instr_215_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_216_0,cpu_instr_216_1,cpu_instr_216_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_217_0,cpu_instr_217_1,cpu_instr_217_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_218_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_219_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_220_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_221_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_222_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_223_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_224_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_225_0,cpu_instr_225_1,cpu_instr_225_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_226_0,cpu_instr_226_1,cpu_instr_226_2,cpu_instr_226_3,cpu_instr_226_4,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_228_0,cpu_instr_228_1,cpu_instr_228_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_229_0,cpu_instr_229_1,cpu_instr_229_2,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_230_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_231_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_232_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,cpu_instr_234_1,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_240_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_241_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_242_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_243_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_244_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_245_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_246_0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{0,0,0,0,0,0,0,0}, |  | ||||||
| 	{cpu_instr_255_0,0,0,0,0,0,0,0}, |  | ||||||
| }; |  | ||||||
| @@ -1,112 +0,0 @@ | |||||||
|  |  | ||||||
| return { |  | ||||||
| 	["backspace"]     = 8, |  | ||||||
| 	["tab"]           = 9, |  | ||||||
| 	["return"]        = 13, |  | ||||||
| 	 |  | ||||||
| 	["lshift"]        = 16, |  | ||||||
| 	["lctrl"]         = 17, --["lcontrol"]      = 17, |  | ||||||
| 	["lalt"]          = 18, |  | ||||||
| 	 |  | ||||||
| 	-- this block does not match vkey codes |  | ||||||
| 	["rshift"]        = 20, |  | ||||||
| 	["rctrl"]         = 21, --["rcontrol"]      = 21, |  | ||||||
| 	["ralt"]          = 22, |  | ||||||
| 	 |  | ||||||
| 	-- this block does not match vkey codes |  | ||||||
| 	[";"]             = 24, |  | ||||||
| 	["="]             = 25, |  | ||||||
| 	[","]             = 26, |  | ||||||
| 	["."]             = 27, |  | ||||||
| 	["-"]             = 28, -- not in bl |  | ||||||
| 	["/"]             = 29, |  | ||||||
| 	["`"]             = 30, |  | ||||||
| 	 |  | ||||||
| 	["space"]         = 32, |  | ||||||
| 	["pageup"]        = 33, |  | ||||||
| 	["pagedown"]      = 34, |  | ||||||
| 	["end"]           = 35, |  | ||||||
| 	["home"]          = 36, |  | ||||||
| 	["left"]          = 37, |  | ||||||
| 	["up"]            = 38, |  | ||||||
| 	["right"]         = 39, |  | ||||||
| 	["down"]          = 40, |  | ||||||
| 	["insert"]        = 45, |  | ||||||
| 	["delete"]        = 46, |  | ||||||
| 	 |  | ||||||
| 	["0"]             = 48, |  | ||||||
| 	["1"]             = 49, |  | ||||||
| 	["2"]             = 50, |  | ||||||
| 	["3"]             = 51, |  | ||||||
| 	["4"]             = 52, |  | ||||||
| 	["5"]             = 53, |  | ||||||
| 	["6"]             = 54, |  | ||||||
| 	["7"]             = 55, |  | ||||||
| 	["8"]             = 56, |  | ||||||
| 	["9"]             = 57, |  | ||||||
| 	 |  | ||||||
| 	-- this block does not match vkey codes |  | ||||||
| 	["["]             = 60, |  | ||||||
| 	["\\"]            = 61, |  | ||||||
| 	["]"]             = 62, |  | ||||||
| 	["\'"]            = 63, --["apostrophe"]    = 63, |  | ||||||
| 	 |  | ||||||
| 	["a"]             = 65, |  | ||||||
| 	["b"]             = 66, |  | ||||||
| 	["c"]             = 67, |  | ||||||
| 	["d"]             = 68, |  | ||||||
| 	["e"]             = 69, |  | ||||||
| 	["f"]             = 70, |  | ||||||
| 	["g"]             = 71, |  | ||||||
| 	["h"]             = 72, |  | ||||||
| 	["i"]             = 73, |  | ||||||
| 	["j"]             = 74, |  | ||||||
| 	["k"]             = 75, |  | ||||||
| 	["l"]             = 76, |  | ||||||
| 	["m"]             = 77, |  | ||||||
| 	["n"]             = 78, |  | ||||||
| 	["o"]             = 79, |  | ||||||
| 	["p"]             = 80, |  | ||||||
| 	["q"]             = 81, |  | ||||||
| 	["r"]             = 82, |  | ||||||
| 	["s"]             = 83, |  | ||||||
| 	["t"]             = 84, |  | ||||||
| 	["u"]             = 85, |  | ||||||
| 	["v"]             = 86, |  | ||||||
| 	["w"]             = 87, |  | ||||||
| 	["x"]             = 88, |  | ||||||
| 	["y"]             = 89, |  | ||||||
| 	["z"]             = 90, |  | ||||||
| 	 |  | ||||||
| 	["kp0"]           = 96,  --["numpad0"]       = 96, |  | ||||||
| 	["kp1"]           = 97,  --["numpad1"]       = 97, |  | ||||||
| 	["kp2"]           = 98,  --["numpad2"]       = 98, |  | ||||||
| 	["kp3"]           = 99,  --["numpad3"]       = 99, |  | ||||||
| 	["kp4"]           = 100, --["numpad4"]       = 100, |  | ||||||
| 	["kp5"]           = 101, --["numpad5"]       = 101, |  | ||||||
| 	["kp6"]           = 102, --["numpad6"]       = 102, |  | ||||||
| 	["kp7"]           = 103, --["numpad7"]       = 103, |  | ||||||
| 	["kp8"]           = 104, --["numpad8"]       = 104, |  | ||||||
| 	["kp9"]           = 105, --["numpad9"]       = 105, |  | ||||||
| 	["kp*"]           = 106, --["*"]             = 106, |  | ||||||
| 	["kp+"]           = 107, --["+"]             = 107, |  | ||||||
| 	["kpenter"]       = 108, --["numpadenter"]   = 108, |  | ||||||
| 	["kp-"]           = 109, --["minus"]         = 109, |  | ||||||
| 	["kp."]           = 110, --["numpaddecimal"] = 110, |  | ||||||
| 	["kp/"]           = 111, --["/"]             = 111, |  | ||||||
| 	 |  | ||||||
| 	["f1"]            = 112, |  | ||||||
| 	["f2"]            = 113, |  | ||||||
| 	["f3"]            = 114, |  | ||||||
| 	["f4"]            = 115, |  | ||||||
| 	["f5"]            = 116, |  | ||||||
| 	["f6"]            = 117, |  | ||||||
| 	["f7"]            = 118, |  | ||||||
| 	["f8"]            = 119, |  | ||||||
| 	["f9"]            = 120, |  | ||||||
| 	["f10"]           = 121, |  | ||||||
| 	["f11"]           = 122, |  | ||||||
| 	["f12"]           = 123, |  | ||||||
| 	 |  | ||||||
| 	["invalid"]       = 127, |  | ||||||
| } |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| require("8608emulator") |  | ||||||
| @@ -1,30 +0,0 @@ | |||||||
| .include _hwdefs.asm |  | ||||||
| .include _clrdefs.asm |  | ||||||
|  |  | ||||||
| ;; Variables |  | ||||||
| .org SYSRAM |  | ||||||
| stack: byte[128] |  | ||||||
|  |  | ||||||
| ;; Main |  | ||||||
| .org SYSROM |  | ||||||
| lds stack |  | ||||||
| jss cls |  | ||||||
|  |  | ||||||
| hlt |  | ||||||
|  |  | ||||||
| ;; Clear the screen |  | ||||||
| FUNC cls: |  | ||||||
|   ldp screen.char |  | ||||||
|   ldc $00 ;; Blank |  | ||||||
|   ldq screen.color |  | ||||||
|   ldb CLR_BLACK ;; Black |  | ||||||
|   .cls_loop: { |  | ||||||
|     stc *p++ |  | ||||||
|     stb *q++ |  | ||||||
|     lda pl |  | ||||||
|     cmp (lo(COLOR)) |  | ||||||
|     jnz .cls_loop |  | ||||||
|     lda ph |  | ||||||
|     cmp (hi(COLOR)) |  | ||||||
|   jnz } |  | ||||||
| rts |  | ||||||
| @@ -1,8 +0,0 @@ | |||||||
| lda 1 |  | ||||||
| ldb 0 |  | ||||||
|  |  | ||||||
| fib_loop: |  | ||||||
| ldc b |  | ||||||
| ldb a |  | ||||||
| add c |  | ||||||
| jlt fib_loop ; Stop when carry flag is set |  | ||||||
| @@ -1,50 +0,0 @@ | |||||||
| .include _hwdefs.asm |  | ||||||
| .include _clrdefs.asm |  | ||||||
|  |  | ||||||
| ;; Defines |  | ||||||
| .define VARS $0100 |  | ||||||
|  |  | ||||||
| ;; Variables |  | ||||||
| .org SYSRAM |  | ||||||
| stack: byte[128] |  | ||||||
|  |  | ||||||
| .org VARS |  | ||||||
| hello_str: "Hello world!\0" |  | ||||||
|  |  | ||||||
| ;; Main |  | ||||||
| .org SYSROM |  | ||||||
| lds stack |  | ||||||
|  |  | ||||||
| jss cls |  | ||||||
|  |  | ||||||
| ldp screen.char |  | ||||||
| ldq hello_str |  | ||||||
| jss print |  | ||||||
|  |  | ||||||
| hlt |  | ||||||
|  |  | ||||||
| ;; Clear the screen |  | ||||||
| FUNC cls: |  | ||||||
|   ldp screen.char |  | ||||||
|   ldc $00 ;; Blank |  | ||||||
|   ldq screen.color |  | ||||||
|   ldb CLR_BLACK ;; Black |  | ||||||
|   .cls_loop: { |  | ||||||
|     stc *p++ |  | ||||||
|     stb *q++ |  | ||||||
|     lda pl |  | ||||||
|     cmp (lo(COLOR)) |  | ||||||
|     jnz .cls_loop |  | ||||||
|     lda ph |  | ||||||
|     cmp (hi(COLOR)) |  | ||||||
|   jnz } |  | ||||||
| rts |  | ||||||
|  |  | ||||||
| ;; Print string (Q) to the current screen cursor (P) |  | ||||||
| FUNC print: |  | ||||||
|   lda *q++ |  | ||||||
|   jpz .print_end |  | ||||||
|   sta *p++ |  | ||||||
|   jmp print |  | ||||||
|   .print_end: |  | ||||||
| rts |  | ||||||
| @@ -1,16 +0,0 @@ | |||||||
| .org $0100  ; Static data |  | ||||||
| hello_str: |  | ||||||
| "Hello world\0" |  | ||||||
|  |  | ||||||
| .org $0000  ; Program must start at $0000 |  | ||||||
| ldp $0800   ; Char display |  | ||||||
| ldq hello_str |  | ||||||
|  |  | ||||||
| print: |  | ||||||
| lda *q++ |  | ||||||
| jpz print_end |  | ||||||
| sta *p++ |  | ||||||
| jmp print |  | ||||||
|  |  | ||||||
| print_end: |  | ||||||
| hlt |  | ||||||
| @@ -1,8 +0,0 @@ | |||||||
| ; This program adds 1 to register A until it equals 64, then halts. |  | ||||||
|  |  | ||||||
| loop: |  | ||||||
| inc a |  | ||||||
| cmp 64 |  | ||||||
| jnz loop |  | ||||||
|  |  | ||||||
| hlt |  | ||||||
| @@ -1,3 +1,6 @@ | |||||||
|  | -- generate-architecture.lua | ||||||
|  | -- This program uses the definitions in 8608-definition.lua to generate the assembler definitions, instruction list, and microcode. | ||||||
|  | -- Also see 8608-definition.lua | ||||||
| 
 | 
 | ||||||
| local debugInfo = {} | local debugInfo = {} | ||||||
| local function getDebugInfo() | local function getDebugInfo() | ||||||
| @@ -70,6 +73,84 @@ local function sigsFromRoms(roms) | |||||||
| 	return sigs | 	return sigs | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  | local relJmpStr = [[ | ||||||
|  | %s {addr} => { | ||||||
|  | 		reladdr = addr - $ - 2 | ||||||
|  | 		assert(reladdr <=  127, "%s: Relative jump target is too far away") | ||||||
|  | 		assert(reladdr >= -128, "%s: Relative jump target is too far away") | ||||||
|  | 		%s @ reladdr`8 | ||||||
|  | 	}]] | ||||||
|  | local wordRelStr = [[ | ||||||
|  | %s+{value: i%i} => { | ||||||
|  | 		assert(value <= %i, "Relative address is too far away") | ||||||
|  | 		assert(value >= %i, "Relative address is too far away") | ||||||
|  | 		%s @ value`%i | ||||||
|  | 	} | ||||||
|  | 	%s-{value: i%i} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		assert(mvalue <= %i, "Relative address is too far away") | ||||||
|  | 		assert(mvalue >= %i, "Relative address is too far away") | ||||||
|  | 		%s @ mvalue`%i | ||||||
|  | 	}]] | ||||||
|  | local byteNegStr = [[ | ||||||
|  | %s {value:i8} => { | ||||||
|  | 		mvalue = -value | ||||||
|  | 		%s @ mvalue`8 | ||||||
|  | 	} | ||||||
|  | ]] | ||||||
|  | 
 | ||||||
|  | local function getAsmCode(mnem, instr) | ||||||
|  | 	local reljmp = instr.jmp and instr.rel | ||||||
|  | 	local opcodeS = string.format("$%02X", instr.opcode) | ||||||
|  | 	 | ||||||
|  | 	if reljmp then | ||||||
|  | 		assert(mnem:find("imm8"), "relative jump without imm8") | ||||||
|  | 		local mnemPart = mnem:gsub(" imm8", "") | ||||||
|  | 		return string.format(relJmpStr, | ||||||
|  | 			mnemPart, mnemPart, mnemPart, | ||||||
|  | 			opcodeS | ||||||
|  | 		) | ||||||
|  | 	elseif mnem:find("%+imm") then | ||||||
|  | 		local mnemPart, bitsS = mnem:match("^([^%+]+)%+imm([0-9]+)$") | ||||||
|  | 		local bits = tonumber(bitsS) | ||||||
|  | 		local maxVal =  math.pow(2, bits-1)-1 | ||||||
|  | 		local minVal = -math.pow(2, bits-1) | ||||||
|  | 		return string.format(wordRelStr, | ||||||
|  | 			mnemPart, bits, maxVal, minVal, opcodeS, bits, | ||||||
|  | 			mnemPart, bits, maxVal, minVal, opcodeS, bits | ||||||
|  | 		) | ||||||
|  | 	elseif mnem:find("imm8neg") then | ||||||
|  | 		mnemPart = mnem:match("^([^ ]+) imm8neg$") | ||||||
|  | 		return string.format(byteNegStr, mnemPart, opcodeS) | ||||||
|  | 	elseif mnem:find("imm8") then | ||||||
|  | 		mnem = mnem:gsub("imm8", "{value: i8}") | ||||||
|  | 		return mnem.." => "..opcodeS.." @ value" | ||||||
|  | 	elseif mnem:find("imm16") then | ||||||
|  | 		mnem = mnem:gsub("imm16", "{value: i16}") | ||||||
|  | 		return mnem.." => "..opcodeS.." @ value" | ||||||
|  | 	else | ||||||
|  | 		return mnem.." => "..opcodeS | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  | local function getAsmsFromInstr(instr, aliases) | ||||||
|  | 	local mnem = instr.mnem | ||||||
|  | 	local t = {} | ||||||
|  | 	if mnem then | ||||||
|  | 		table.insert(t, getAsmCode(mnem, instr)) | ||||||
|  | 		if aliases[mnem] then | ||||||
|  | 			for _, mnem2 in ipairs(aliases[mnem]) do | ||||||
|  | 				table.insert(t, getAsmCode(mnem2, instr)) | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	return t | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | local asmDataStr = [[ | ||||||
|  | #ruledef { | ||||||
|  | 	%s | ||||||
|  | } | ||||||
|  | ]] | ||||||
| local function archToUcode(arch) | local function archToUcode(arch) | ||||||
| 	local sigs = sigsFromRoms(arch.roms) | 	local sigs = sigsFromRoms(arch.roms) | ||||||
| 	local ops = arch.operations | 	local ops = arch.operations | ||||||
| @@ -78,6 +159,7 @@ local function archToUcode(arch) | |||||||
| 	local opcodesUsed = {} | 	local opcodesUsed = {} | ||||||
| 	local numOpcodesUsed = 0 | 	local numOpcodesUsed = 0 | ||||||
| 	local infolines = {} | 	local infolines = {} | ||||||
|  | 	local asmlines = {} | ||||||
| 	local catlet = "X" | 	local catlet = "X" | ||||||
| 	for _, instr in ipairs(arch.instructions) do | 	for _, instr in ipairs(arch.instructions) do | ||||||
| 		if instr.category then | 		if instr.category then | ||||||
| @@ -105,6 +187,9 @@ local function archToUcode(arch) | |||||||
| 			if instr.desc then | 			if instr.desc then | ||||||
| 				table.insert(infolines, mnem..(" "):rep(13-#mnem)..hex(opcode).."  "..ncycles.."  "..instr.desc.."\n") | 				table.insert(infolines, mnem..(" "):rep(13-#mnem)..hex(opcode).."  "..ncycles.."  "..instr.desc.."\n") | ||||||
| 			end | 			end | ||||||
|  | 			 | ||||||
|  | 			local asms = getAsmsFromInstr(instr, arch.aliases) | ||||||
|  | 			for _, a in ipairs(asms) do table.insert(asmlines, a) end | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 	 | 	 | ||||||
| @@ -120,13 +205,28 @@ local function archToUcode(arch) | |||||||
| 		table.insert(lt, "\n") | 		table.insert(lt, "\n") | ||||||
| 	end | 	end | ||||||
| 	 | 	 | ||||||
| 	local info = table.concat(infolines).."\n"..table.concat(lt) | 	local writeFiles = true | ||||||
| 	print(info) | 	if writeFiles then | ||||||
| 	 | 		-- Output instruction list | ||||||
| 	local fo = io.open("instructionList.txt", "w") | 		local info = arch.instructionListHeader..table.concat(infolines).."\n"..table.concat(lt) | ||||||
|  | 		--print(info) | ||||||
|  | 		local fo = io.open(arch.instructionListFile, "w") | ||||||
| 		if fo then | 		if fo then | ||||||
| 			fo:write(info) | 			fo:write(info) | ||||||
| 			fo:close() | 			fo:close() | ||||||
|  | 		else | ||||||
|  | 			print("Could not open \""..arch.instructionListFile.."\" for write") | ||||||
|  | 		end | ||||||
|  | 		 | ||||||
|  | 		-- Output customASM definitions | ||||||
|  | 		local asmTable = arch.assemblerDefsHeader..string.format(asmDataStr, table.concat(asmlines, "\n\t")) | ||||||
|  | 		local fo = io.open(arch.assemblerDefsFile, "w") | ||||||
|  | 		if fo then | ||||||
|  | 			fo:write(asmTable) | ||||||
|  | 			fo:close() | ||||||
|  | 		else | ||||||
|  | 			print("Could not open \""..arch.assemblerDefsFile.."\" for write") | ||||||
|  | 		end | ||||||
| 	end | 	end | ||||||
| 	 | 	 | ||||||
| 	return ucode | 	return ucode | ||||||
| @@ -183,5 +283,5 @@ local function buildArch(arch) | |||||||
| 	buildBricks(bricks) | 	buildBricks(bricks) | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| local arch = require("rom-8608-defs") | local arch = require("8608-definition") | ||||||
| buildArch(arch) | buildArch(arch) | ||||||
| @@ -1,3 +1,10 @@ | |||||||
|  | instructionList.txt | ||||||
|  | List of all instructions in the 8608 architecture. | ||||||
|  |  | ||||||
|  | Instructions are encoded as the opcode, followed by any immediate values. | ||||||
|  | 16-bit immediates are encoded in big-endian byte order. | ||||||
|  |  | ||||||
|  | Each instruction is described in order of: Mnemonic, Opcode, Clock cycles, Description | ||||||
|  |  | ||||||
| Control (C): | Control (C): | ||||||
| rst          00  1  Clear all registers and set I=0 | rst          00  1  Clear all registers and set I=0 | ||||||
| @@ -45,16 +52,11 @@ ads b        E8  1  S+=B signed | |||||||
| add imm8     24  2  A+=imm8, set flags | add imm8     24  2  A+=imm8, set flags | ||||||
| adb imm8     72  2  B+=imm8, set flags | adb imm8     72  2  B+=imm8, set flags | ||||||
| adc imm8     73  2  C+=imm8, set flags | adc imm8     73  2  C+=imm8, set flags | ||||||
| sub imm8     70  2  A-=imm8, set flags |  | ||||||
| sbb imm8     99  2  B-=imm8, set flags |  | ||||||
| sbc imm8     9A  2  C-=imm8, set flags |  | ||||||
| acc imm8     78  2  A+=imm8+CF, set flags | acc imm8     78  2  A+=imm8+CF, set flags | ||||||
| scc imm8     79  2  A-=imm8+CF, set flags |  | ||||||
| cmp imm8     71  2  set flags according to A-imm8 | cmp imm8     71  2  set flags according to A-imm8 | ||||||
| and imm8     74  2  A&=imm8, set zero flag | and imm8     74  2  A&=imm8, set zero flag | ||||||
| ior imm8     75  2  A|=imm8, set zero flag | ior imm8     75  2  A|=imm8, set zero flag | ||||||
| xor imm8     76  2  A^=imm8, set zero flag | xor imm8     76  2  A^=imm8, set zero flag | ||||||
| ann imm8     77  2  A&=~imm8, set zero flag |  | ||||||
| shl imm8     D0  2  A<<=imm8, set zero flag | shl imm8     D0  2  A<<=imm8, set zero flag | ||||||
| shr imm8     D1  2  A>>=imm8, set zero flag | shr imm8     D1  2  A>>=imm8, set zero flag | ||||||
| rol imm8     D2  2  A<<<=imm8, set zero flag | rol imm8     D2  2  A<<<=imm8, set zero flag | ||||||
| @@ -72,7 +74,6 @@ cmp *s+imm8  B0  3  set flags according to A-*(S+imm8) | |||||||
| and *s+imm8  B1  3  A&=*(S+imm8), set zero flag | and *s+imm8  B1  3  A&=*(S+imm8), set zero flag | ||||||
| ior *s+imm8  B2  3  A|=*(S+imm8), set zero flag | ior *s+imm8  B2  3  A|=*(S+imm8), set zero flag | ||||||
| xor *s+imm8  B3  3  A^=*(S+imm8), set zero flag | xor *s+imm8  B3  3  A^=*(S+imm8), set zero flag | ||||||
| ann *s+imm8  B4  3  A&=~*(S+imm8), set zero flag |  | ||||||
| shl *s+imm8  D5  3  A<<=*(S+imm8), set zero flag | shl *s+imm8  D5  3  A<<=*(S+imm8), set zero flag | ||||||
| shr *s+imm8  D6  3  A<<=*(S+imm8), set zero flag | shr *s+imm8  D6  3  A<<=*(S+imm8), set zero flag | ||||||
| rol *s+imm8  D7  3  A<<<=*(S+imm8), set zero flag | rol *s+imm8  D7  3  A<<<=*(S+imm8), set zero flag | ||||||
| @@ -88,7 +89,6 @@ cmp b        A2  1  set flags according to A-B | |||||||
| and b        A3  1  A&=B, set zero flag | and b        A3  1  A&=B, set zero flag | ||||||
| ior b        A4  1  A|=B, set zero flag | ior b        A4  1  A|=B, set zero flag | ||||||
| xor b        A5  1  A^=B, set zero flag | xor b        A5  1  A^=B, set zero flag | ||||||
| ann b        A6  1  A&=~B, set zero flag |  | ||||||
| shl b        DA  1  A<<=B, set zero flag | shl b        DA  1  A<<=B, set zero flag | ||||||
| shr b        DB  1  A>>=B, set zero flag | shr b        DB  1  A>>=B, set zero flag | ||||||
| rol b        DC  1  A<<<=B, set zero flag | rol b        DC  1  A<<<=B, set zero flag | ||||||
| @@ -104,7 +104,6 @@ cmp c        A9  1  set flags according to A-C | |||||||
| and c        AA  1  A&=C, set zero flag | and c        AA  1  A&=C, set zero flag | ||||||
| ior c        AB  1  A|=C, set zero flag | ior c        AB  1  A|=C, set zero flag | ||||||
| xor c        AC  1  A^=C, set zero flag | xor c        AC  1  A^=C, set zero flag | ||||||
| ann c        AD  1  A&=~C, set zero flag |  | ||||||
| shl c        DF  1  A<<=C, set zero flag | shl c        DF  1  A<<=C, set zero flag | ||||||
| shr c        4D  1  A>>=C, set zero flag | shr c        4D  1  A>>=C, set zero flag | ||||||
| rol c        3E  1  A<<<=C, set zero flag | rol c        3E  1  A<<<=C, set zero flag | ||||||
| @@ -129,10 +128,10 @@ rts          E1  3  I=*(----S)+1 | |||||||
| jpr imm8     31  2  I+=imm8 | jpr imm8     31  2  I+=imm8 | ||||||
| jnz imm8     30  2  I+=imm8 if !Zero | jnz imm8     30  2  I+=imm8 if !Zero | ||||||
| jpz imm8     32  2  I+=imm8 if Zero | jpz imm8     32  2  I+=imm8 if Zero | ||||||
| jge imm8     33  2  I+=imm8 if !Carry | jlt imm8     33  2  I+=imm8 if !Carry | ||||||
| jlt imm8     34  2  I+=imm8 if Carry | jge imm8     34  2  I+=imm8 if Carry | ||||||
| jgt imm8     35  2  I+=imm8 if !Zero & !Carry | jgt imm8     35  2  I+=imm8 if !Zero & Carry | ||||||
| jle imm8     36  2  I+=imm8 if Zero | Carry | jle imm8     36  2  I+=imm8 if Zero | !Carry | ||||||
|  |  | ||||||
| Stack (S): | Stack (S): | ||||||
| psh a        40  2  *(S++)=A | psh a        40  2  *(S++)=A | ||||||
| @@ -166,30 +165,42 @@ ldc *imm16   57  4  C=*imm16, update zero flag | |||||||
| sta *imm16   50  4  *imm16=A | sta *imm16   50  4  *imm16=A | ||||||
| stb *imm16   58  4  *imm16=B | stb *imm16   58  4  *imm16=B | ||||||
| stc *imm16   59  4  *imm16=C | stc *imm16   59  4  *imm16=C | ||||||
| sta *p       52  2  *P=A | lda *p+imm16 01  4  A=*P+imm16, update zero flag | ||||||
| stb *p       5A  2  *P=B | ldb *p+imm16 F7  4  B=*P+imm16, update zero flag | ||||||
| stc *p       5B  2  *P=C | ldc *p+imm16 FE  4  C=*P+imm16, update zero flag | ||||||
| sta *q       54  2  *Q=A | lda *q+imm16 EB  4  A=*Q+imm16, update zero flag | ||||||
| stb *q       5C  2  *Q=B | ldb *q+imm16 08  4  B=*Q+imm16, update zero flag | ||||||
| stc *q       5D  2  *Q=C | ldc *q+imm16 09  4  C=*Q+imm16, update zero flag | ||||||
|  | sta *p+imm16 0A  4  *P+imm16=A | ||||||
|  | stb *p+imm16 0B  4  *P+imm16=B | ||||||
|  | stc *p+imm16 0C  4  *P+imm16=C | ||||||
|  | sta *q+imm16 0D  4  *Q+imm16=A | ||||||
|  | stb *q+imm16 0E  4  *Q+imm16=B | ||||||
|  | stc *q+imm16 0F  4  *Q+imm16=C | ||||||
| lda *p       53  2  A=*P, update zero flag | lda *p       53  2  A=*P, update zero flag | ||||||
| ldb *p       5E  2  B=*P, update zero flag | ldb *p       5E  2  B=*P, update zero flag | ||||||
| ldc *p       5F  2  C=*P, update zero flag | ldc *p       5F  2  C=*P, update zero flag | ||||||
| lda *q       55  2  A=*Q, update zero flag | lda *q       55  2  A=*Q, update zero flag | ||||||
| ldb *q       61  2  B=*Q, update zero flag | ldb *q       61  2  B=*Q, update zero flag | ||||||
| ldc *q       62  2  C=*Q, update zero flag | ldc *q       62  2  C=*Q, update zero flag | ||||||
| sta *p++     C0  2  *P++=A | sta *p       52  2  *P=A | ||||||
| stb *p++     C1  2  *P++=B | stb *p       5A  2  *P=B | ||||||
| stc *p++     C2  2  *P++=C | stc *p       5B  2  *P=C | ||||||
| sta *q++     C3  2  *Q++=A | sta *q       54  2  *Q=A | ||||||
| stb *q++     C4  2  *Q++=B | stb *q       5C  2  *Q=B | ||||||
| stc *q++     C5  2  *Q++=C | stc *q       5D  2  *Q=C | ||||||
| lda *p++     C6  2  A=*P++, update zero flag | lda *p++     C6  2  A=*P++, update zero flag | ||||||
| ldb *p++     C7  2  B=*P++, update zero flag | ldb *p++     C7  2  B=*P++, update zero flag | ||||||
| ldc *p++     C8  2  C=*P++, update zero flag | ldc *p++     C8  2  C=*P++, update zero flag | ||||||
| lda *q++     C9  2  A=*Q++, update zero flag | lda *q++     C9  2  A=*Q++, update zero flag | ||||||
| ldb *q++     CA  2  B=*Q++, update zero flag | ldb *q++     CA  2  B=*Q++, update zero flag | ||||||
| ldc *q++     CB  2  C=*Q++, update zero flag | ldc *q++     CB  2  C=*Q++, update zero flag | ||||||
|  | sta *p++     C0  2  *P++=A | ||||||
|  | stb *p++     C1  2  *P++=B | ||||||
|  | stc *p++     C2  2  *P++=C | ||||||
|  | sta *q++     C3  2  *Q++=A | ||||||
|  | stb *q++     C4  2  *Q++=B | ||||||
|  | stc *q++     C5  2  *Q++=C | ||||||
|  |  | ||||||
| 16-bit Load/Store (W): | 16-bit Load/Store (W): | ||||||
| ldp imm16    21  3  P=imm16 | ldp imm16    21  3  P=imm16 | ||||||
| @@ -204,6 +215,12 @@ ldp *imm16   68  5  P=*imm16 | |||||||
| ldq *imm16   6A  5  Q=*imm16 | ldq *imm16   6A  5  Q=*imm16 | ||||||
| stp *imm16   6C  5  *imm16=P | stp *imm16   6C  5  *imm16=P | ||||||
| stq *imm16   6E  5  *imm16=Q | stq *imm16   6E  5  *imm16=Q | ||||||
|  | ldp *p+imm16 EC  5  P=*P+imm16 | ||||||
|  | ldq *p+imm16 EE  5  Q=*P+imm16 | ||||||
|  | ldp *q+imm16 F8  5  P=*Q+imm16 | ||||||
|  | ldq *q+imm16 FA  5  Q=*Q+imm16 | ||||||
|  | stq *p+imm16 06  5  *P+imm16=Q | ||||||
|  | stp *q+imm16 FC  5  *Q+imm16=P | ||||||
| ldp *p       92  3  P=*P | ldp *p       92  3  P=*P | ||||||
| ldq *p       93  3  Q=*P | ldq *p       93  3  Q=*P | ||||||
| ldp *q       94  3  P=*Q | ldp *q       94  3  P=*Q | ||||||
| @@ -240,21 +257,21 @@ ldq p        8E  1  Q=P | |||||||
| lds p        8F  1  S=P | lds p        8F  1  S=P | ||||||
| ldv p        90  1  V=P | ldv p        90  1  V=P | ||||||
|  |  | ||||||
| Opcodes used: 228/255 | Opcodes used: 244/255 | ||||||
|      0123456789ABCDEF |      0123456789ABCDEF | ||||||
| 00 | C--------------- | 00 | CB----WWBBBBBBBB | ||||||
| 10 | UUIIUIIUUUUUUUUU | 10 | UUIIUIIUUUUUUUUU | ||||||
| 20 | BWWWAWBBBBBUUUUA | 20 | BWWWAWBBBBBUUUUA | ||||||
| 30 | JJJJJJJMMMMSSSAA | 30 | JJJJJJJMMMMSSSAA | ||||||
| 40 | SSSSSSSSSSXXXAAA | 40 | SSSSSSSSSSXXXAAA | ||||||
| 50 | BBBBBBBBBBBBBBBB | 50 | BBBBBBBBBBBBBBBB | ||||||
| 60 | JBBJJJJJWWWWWWWW | 60 | JBBJJJJJWWWWWWWW | ||||||
| 70 | AAAAAAAAAAWWWWWW | 70 | -AAAAAA-A-WWWWWW | ||||||
| 80 | MMMMMMMMMMMMMMMM | 80 | MMMMMMMMMMMMMMMM | ||||||
| 90 | MMWWWWBBBAAAAAAA | 90 | MMWWWWBBB--AAAAA | ||||||
| A0 | AAAAAAAAAAAAAAAA | A0 | AAAAAA-AAAAAA-AA | ||||||
| B0 | AAAAAAAAAAAAAAAA | B0 | AAAA-AAAAAAAAAAA | ||||||
| C0 | BBBBBBBBBBBBWWWW | C0 | BBBBBBBBBBBBWWWW | ||||||
| D0 | AAAAAAAAAAAAAAAA | D0 | AAAAAAAAAAAAAAAA | ||||||
| E0 | MJJJJJXXXSS----- | E0 | MJJJJJXXXSSBWWWW | ||||||
| F0 | CCCCCCC--------C | F0 | CCCCCCCBWWWWWWBC | ||||||
|   | |||||||
							
								
								
									
										75
									
								
								memoryMap.md
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								memoryMap.md
									
									
									
									
									
								
							| @@ -1,45 +1,48 @@ | |||||||
| ## Boot ROM |  | ||||||
| Execution starts here, at address `$0000`.<br> | ## Main RAM | ||||||
| The main program is located here, or the OS bootloader if an OS is present. | 8 KiB of random-access memory.<br> | ||||||
|  | Located at addresses `$8000` to `$9FFF`.<br> | ||||||
|  | Programs can write data to these addresses, and retrieve the data at a later time.<br> | ||||||
|  | Machine code can also be stored here and executed. | ||||||
|  |  | ||||||
|  | ## Text Display | ||||||
|  | Write ASCII values to addresses `$2000` to `$27FF` to display characters at certain positions on the screen.<br> | ||||||
|  | `$2000` is the top left, `$27FF` is the bottom right.<br> | ||||||
|  | Rows are 64 bytes long.<br> | ||||||
|  | For example, `$2040` would be the first character of the second row from the top.<br> | ||||||
|  | Values can also be read back out of the display memory, as if it were RAM. | ||||||
|  |  | ||||||
|  | ## Text Display Color | ||||||
|  | Write 6-bit color IDs to addresses `$0C00` to `$0FFF` to set the color of characters on the screen.<br> | ||||||
|  | If the most significant bit is 1, the character and background colors will be inverted, i.e. highlighted.<br> | ||||||
|  | Values can also be read back out of the display color memory, as if it were RAM. | ||||||
|  |  | ||||||
|  | ## Main ROM | ||||||
|  | 1 KiB of read-only memory.<br> | ||||||
|  | Located at addresses `$0000` to `$03FF`.<br> | ||||||
|  | When the CPU is first turned on, or is reset, it will start executing code from here, starting at address `$0000`.<br> | ||||||
|  | Bricks can be physically placed on top of the ROM brick to set bits within the ROM.<br> | ||||||
|  | A bootloader, operating system, or hex monitor may be loaded here. | ||||||
|  |  | ||||||
| ## GPIO | ## GPIO | ||||||
| Contains hardware multiplication (`$0400 * $0401 -> $0400`) and division (`$0402 / $0403 -> $0402 r $0403`), popcount (`$0404 -> $0404`), and a timer (`$0405`).<br> | Contains hardware multiplication, division, popcount, and a timer.<br> | ||||||
| Value written to timer register = number of game ticks (32 ms) between interrupt triggers.<br> | When two 8-bit values are written to the multiplier registers `$0400` and `$0401`, the result will be available as a big-endian 16-bit value at `$0400`. Read from `$0401` to retrieve an 8-bit result.<br> | ||||||
| Write 0 to disable. | When two 8-bit values are written to the divider registers `$0402` and `$0403`, the quotient can be read from `$0402` and the remainder from `$0403`<br> | ||||||
|  | When any 8-bit value is written to the timer register `$0404`, the popcount of that value (The number of bits that are 1) can be read from the same location. | ||||||
|  | When any value is written to the timer register at `$0405`, an interrupt will be triggered after 32 milliseconds. | ||||||
|  |  | ||||||
| ## Keyboard | ## Keyboard | ||||||
| Read address `$0500` to get the next key event<br> | Read address `$0500` to get the next keycode from the buffer.<br> | ||||||
| 7-bit Windows VKey code, MSB 1 = press, 0 = release<br> | Keycodes are 7-bit Windows VKey codes, plus a press/release bit. If the MSB is 1, the event is a key press; if 0, a release.<br> | ||||||
| Returns 0 if buffer is empty. | Result will be 0 if the buffer is empty.<br> | ||||||
| Write 1 to `$0500` to enable keyboard interrupts, 0 to disable. | If 1 is written to `$0500`, an interrupt will be triggered whenever a key event is available. Write 0 to disable again. | ||||||
|  |  | ||||||
| ## Serial Peripheral Interface | ## Serial Peripheral Interface | ||||||
| Not yet implemented. | Not yet implemented. | ||||||
|  |  | ||||||
| ## Robot Controller | ## Robot Controller | ||||||
| Write to `$0701` to control the robot. Each bit is an action - MSB to LSB: Plant brick, destroy brick, move forward, backward, left, right, up, down.<br> | Write to `$0701` to control a 1x1f-sized "robot" that can place and destroy bricks.<br> | ||||||
| Write a 6-bit color ID to `$0700` to set the color of the bricks the robot plants.<br> | Each bit indicates an action; if that bit is set, that action will be taken. From MSB to LSB: Plant brick, destroy brick, move forward, backward, left, right, up, down.<br> | ||||||
| Read `$0700` to get the color of the brick the robot is on. MSB = brick exists. Returns 0 if no brick. | Write a 6-bit color ID to `$0700` to set the color of the bricks the robot will plant.<br> | ||||||
|  | Read `$0700` to get the color of the brick the robot is currently overlapping. If the MSB is 1, a brick exists at this location. Result will be 0 if no brick is present.<br> | ||||||
|  | The robot should only be given new actions once per game tick. The timer at `$0405` can be used for this purpose. | ||||||
| ## Text Display |  | ||||||
| Write ASCII values to `$0800` to `$0BFF` to display characters at certain positions on screen.<br> |  | ||||||
| `$0800` is top left, `$0BFF` is bottom right, rows are 64 bytes. |  | ||||||
|  |  | ||||||
| ## Text Display Color |  | ||||||
| Write 6-bit color IDs to `$0C00` to `$0FFF` to set the color of characters on screen.<br> |  | ||||||
| MSB = whether to invert character mask (i.e. for highlighting). |  | ||||||
|  |  | ||||||
| ## System RAM |  | ||||||
| The OS may use this memory for the stack, system variables, etc.<br> |  | ||||||
| If no OS is present, this memory can be used for any purpose, etc.<br> |  | ||||||
| Located at `$1000` to `$1FFF`. |  | ||||||
|  |  | ||||||
| ## User ROM |  | ||||||
| User program and data can go here.<br> |  | ||||||
| If no OS is present, the boot ROM will need to jump into this code.<br> |  | ||||||
| Located at `$2000` to `$2FFF`. |  | ||||||
|  |  | ||||||
| ## User RAM |  | ||||||
| Your code can use this memory for variables, arrays, a heap, etc.<br> |  | ||||||
| Located at `$3000` to `$3FFF`. |  | ||||||
|   | |||||||
							
								
								
									
										32
									
								
								readme.md
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								readme.md
									
									
									
									
									
								
							| @@ -1,31 +1,9 @@ | |||||||
| # 8608 - An 8-bit data, 16-bit address, CISC architecture. | # 8608 - An 8-bit data, 16-bit address, CISC architecture. | ||||||
|  |  | ||||||
| For a list of instructions, see [instructionList.txt](instructionList.txt). | For a description of the architecture and a list of instructions, see [instructionList.txt](instructionList.txt). | ||||||
|  |  | ||||||
| ## How to use the assembler: | For a memory map of the 8608-based computer, see [memoryMap.md](memoryMap.md). | ||||||
| 1. Install `bllua3` from [https://notabug.org/redo/bllua3](https://notabug.org/redo/bllua3) |  | ||||||
| 2. Download this repo into `Add-Ons/8608` or anywhere within one of Blockland's main directories. |  | ||||||
| 3. In BL console, execute: |  | ||||||
|     ``` |  | ||||||
|     luaexec("Add-Ons/8608/assembler-8608.lua"); |  | ||||||
|     ``` |  | ||||||
| 4. To assemble a program, place a 1x1f ghost brick on the top-left corner of the ROM, face forward, and in BL console do: |  | ||||||
|     ``` |  | ||||||
|     AssembleBuildFile("Add-Ons/8608/examples/program.asm", "RomX RomY RomZ"); |  | ||||||
|     ``` |  | ||||||
|     where `RomX` is the width of the ROM, `RomY` is the depth front to back, and `RomZ` is the height in bits, i.e., "16 16 8". |  | ||||||
|  |  | ||||||
|     You can also run the assembler from the command line to get a memory dump and disassembly in stdout, if you have lua installed: | To assemble programs, use CustomAsm: [https://github.com/hlorenzi/customasm](https://github.com/hlorenzi/customasm)<br> | ||||||
|     ``` | Simply include the 8608 architecture file into your program: [8608.asm](8608.asm).<br> | ||||||
|     luajit "Add-Ons/8608/assembler-8608.lua" "Add-Ons/8608/examples/program.asm" | `#include "8608/8608.asm"` | ||||||
|     ``` |  | ||||||
|  |  | ||||||
| ## How to use the emulator: |  | ||||||
| 1. Install love2d from [https://love2d.org](https://love2d.org) |  | ||||||
| 2. Open a command prompt in the "emulator" folder and run: |  | ||||||
|     ``` |  | ||||||
|     love . C:/path/filename.asm |  | ||||||
|     ``` |  | ||||||
|  |  | ||||||
| ## Memory Map |  | ||||||
| [memory map](memoryMap.md) |  | ||||||
|   | |||||||
| @@ -1,381 +0,0 @@ | |||||||
|  |  | ||||||
| return { |  | ||||||
|  |  | ||||||
| roms = { |  | ||||||
| 	{ pos = {0, 0, 0}, size = {64, 16, 64}, signals = { |  | ||||||
| 		"alulU", "alulT", "alulC", "alulB", "alulA", "alurIL", "alurIH", "alurVL", |  | ||||||
| 		"alurVH", "alurSL", "alurSH", "alurQL", "alurQH", "alurPL", "alurPH", "alurU", |  | ||||||
| 		"alurT", "alurC", "alurB", "alurA", "alur1", "alur2", "alurm1", "alurm2", |  | ||||||
| 		"adrrhU", "adrrhC", "adrrlT", "adrrTX", "adrrlB", "adrrBX", "adwrhU", "adwrhC", |  | ||||||
| 		"adwrlT", "adwrTX", "adwrlB", "adwrBX", "adwlI", "adwlV", "adwlS", "adwlQ", |  | ||||||
| 		"adwlP", "adrlI", "adrlV", "adrlS", "adrlQ", "adrlP", "aluAdd", "adwSaveV", |  | ||||||
| 		"aluRun", "aluRInv", "aluCinOn", "aluCinC", "memWriteAlur", "adrInc", "adwInc", "aluXor", |  | ||||||
| 		"aluIor", "aluAnd", "memWriteAlur", "adrOut", "adrSaveI", "adwSaveP", "adwSaveQ", "adwSaveS", |  | ||||||
| 	} }, |  | ||||||
| 	{ pos = {-34, 16, 0}, size = {32, 32, 8}, signals = { |  | ||||||
| 		"aluSaveU", "aluSaveT", "aluSaveC", "aluSaveB", "aluSaveA", "aluSaveCarry", "aluSaveNZ", "always1", |  | ||||||
| 	} }, |  | ||||||
| 	{ pos = {-34, 16, 17}, size = {32, 32, 32}, signals = { |  | ||||||
| 		"_", "_", "_", "_", "_", "_", "_", "_", |  | ||||||
| 		"_", "memSaveF", "memSaveNZ", "instrPre", "instrLoadPre", "always1", "instrLoadSel", "adrOut", |  | ||||||
| 		"memWriteAlur", "memSave", "instrNext0NZ", "instrNext0Z", "instrNext0NC", "instrNext0C", "instrLoadSub", "instrLoad", |  | ||||||
| 		"instrNext2", "instrNext1", "instrNext0", "memSaveU", "memSaveT", "memSaveC", "memSaveB", "memSaveA", |  | ||||||
| 	} }, |  | ||||||
| 	{ pos = {66, 16, 0}, size = {32, 32, 32}, signals = { |  | ||||||
| 		"adrr1", "adrrm1", "adrrm2", "adrr2", "adwrm1", "adwrm2", "adwr2", "adwr1", |  | ||||||
| 		"memRead", "memWrite", "runFlgVal", "runFlgClk", "intFlgVal", "intFlgClk", "irqFlgClk", "always1", |  | ||||||
| 		"aluShiftArith", "aluShiftRoll", "aluShiftRight", "aluShift", "alurF", "_", "_", "_", |  | ||||||
| 		"_", "_", "_", "_", "_", "_", "_", "_", |  | ||||||
| 	} }, |  | ||||||
| }, |  | ||||||
|  |  | ||||||
| operations = { |  | ||||||
| 	base = {"always1"}, |  | ||||||
| 	 |  | ||||||
| 	instrNext = {"base","adrlI","adrInc","adrSaveI","loadInstr"}, |  | ||||||
| 	instrSub1 = {"base","instrLoadSub",                          "instrNext0"}, |  | ||||||
| 	instrSub2 = {"base","instrLoadSub",             "instrNext1",            }, |  | ||||||
| 	instrSub3 = {"base","instrLoadSub",             "instrNext1","instrNext0"}, |  | ||||||
| 	instrSub4 = {"base","instrLoadSub","instrNext2",                         }, |  | ||||||
| 	instrSub5 = {"base","instrLoadSub","instrNext2",             "instrNext0"}, |  | ||||||
| 	instrSub6 = {"base","instrLoadSub","instrNext2","instrNext1",            }, |  | ||||||
| 	instrSub7 = {"base","instrLoadSub","instrNext2","instrNext1","instrNext0"}, |  | ||||||
| 	instrSub23Cond = {"base","instrLoadSub","instrNext1"}, |  | ||||||
| 	instrSwapIV = {"base","adwlI","adwSaveV","adrlV","adrSaveI","loadInstr"}, |  | ||||||
| 	instrPreload = {"adrlI","adrInc","adrSaveI","adrOut","memRead","instrLoadSel","instrLoadPre"}, |  | ||||||
| 	instrNextPre = {"base","instrPre","instrLoad","instrLoadSub"}, |  | ||||||
| 	 |  | ||||||
| 	loadInstr = {"adrOut","memRead","instrLoadSel","instrLoad","instrLoadSub"}, |  | ||||||
| 	loadReg = {"adrOut","memRead","memSave"}, |  | ||||||
| 	storeReg = {"adrOut","memWrite","memWriteAlur"}, |  | ||||||
| 	loadRegT = {"loadReg","memSaveT"}, |  | ||||||
| 	 |  | ||||||
| 	pushReg = {"storeReg","adrlS","adwlS","adwInc","adwSaveS"}, |  | ||||||
| 	popReg = {"loadReg","adrlS","adrrm1","adwlS","adwrm1","adwSaveS"}, |  | ||||||
| 	pop161 = {"popReg","memSaveT"}, |  | ||||||
| 	pop162 = {"popReg","memSaveU"}, |  | ||||||
| 	 |  | ||||||
| 	loadImmed = {"adrlI","adrInc","adrSaveI","loadReg"}, |  | ||||||
| 	loadImmedT = {"loadImmed","memSaveT"}, |  | ||||||
| 	loadImm161 = {"loadImmed","memSaveU"}, |  | ||||||
| 	loadImm162 = {"loadImmed","memSaveT"}, |  | ||||||
| 	loadStackRel = {"adrlS","adrrTX","loadReg"}, |  | ||||||
| 	loadStackRelT = {"loadStackRel","memSaveT"}, |  | ||||||
| 	loadStackRelU = {"loadStackRel","memSaveU"}, |  | ||||||
| 	loadStackRel161 = {"loadStackRel",         "memSaveU"}, |  | ||||||
| 	loadStackRel162 = {"loadStackRel","adrInc","memSaveT"}, |  | ||||||
| 	storeStackRel = {"adrlS","adrrTX","storeReg"}, |  | ||||||
| 	storeStackRel161 = {"storeStackRel"         }, |  | ||||||
| 	storeStackRel162 = {"storeStackRel","adrInc"}, |  | ||||||
| 	storeStackRelU = {"storeStackRel","alurU"}, |  | ||||||
| 	load161 = {         "loadReg","memSaveU"}, |  | ||||||
| 	load162 = {"adrInc","loadReg","memSaveT"}, |  | ||||||
| 	store161 = {         "storeReg"}, |  | ||||||
| 	store162 = {"adrInc","storeReg"}, |  | ||||||
| 	loadUTU = {"adrrUT","loadReg","memSaveU"}, |  | ||||||
| 	storeUT = {"adrrUT","storeReg"}, |  | ||||||
| 	memSaveFlags = {"memSaveNZ"}, |  | ||||||
| 	 |  | ||||||
| 	adwrUT = {"adwrhU","adwrlT"}, |  | ||||||
| 	adrrUT = {"adrrhU","adrrlT"}, |  | ||||||
| 	adwrCB = {"adwrhC","adwrlB"}, |  | ||||||
| 	adwIncUT = {"adwrUT","adwInc"}, |  | ||||||
| 	adwP = {"adwlP","adwSaveP"}, |  | ||||||
| 	adwQ = {"adwlQ","adwSaveQ"}, |  | ||||||
| 	adwS = {"adwlS","adwSaveS"}, |  | ||||||
| 	incP  = {"adwP","adwInc"}, |  | ||||||
| 	incQ  = {"adwQ","adwInc"}, |  | ||||||
| 	incP2 = {"adwP","adwr2"}, |  | ||||||
| 	incQ2 = {"adwP","adwr2"}, |  | ||||||
| 	 |  | ||||||
| 	jmpRelT = {"instrNext","adrrTX"}, |  | ||||||
| 	jmpAbs = {"base","loadInstr","adrSaveI"}, |  | ||||||
| 	jmpAbsUT = {"jmpAbs","adrrUT"}, |  | ||||||
| 	jmpAbsP = {"jmpAbs","adrlP"}, |  | ||||||
| 	jmpAbsQ = {"jmpAbs","adrlQ"}, |  | ||||||
| 	saveRetAddr = {"adwlI","adwInc","adwSaveQ"}, |  | ||||||
| 	pushRetAddr1 = {"alurIH","pushReg"}, |  | ||||||
| 	pushRetAddr2 = {"alurIL","pushReg"}, |  | ||||||
| 	 |  | ||||||
| 	aluA = {"alulA","aluSaveA"}, |  | ||||||
| 	aluB = {"alulB","aluSaveB"}, |  | ||||||
| 	aluC = {"alulC","aluSaveC"}, |  | ||||||
| 	aluT = {"alulT","aluSaveT"}, |  | ||||||
| 	aluU = {"alulU","aluSaveU"}, |  | ||||||
| 	aluOpAdd = {"aluRun","aluAdd","aluSaveCarry","aluSaveNZ"                     }, |  | ||||||
| 	aluOpAddC= {"aluRun","aluAdd","aluSaveCarry","aluSaveNZ",          "aluCinC" }, |  | ||||||
| 	aluOpSub = {"aluRun","aluAdd","aluSaveCarry","aluSaveNZ","aluRInv","aluCinOn"}, |  | ||||||
| 	aluOpSubC= {"aluRun","aluAdd","aluSaveCarry","aluSaveNZ","aluRInv","aluCinC" }, |  | ||||||
| 	aluOpAnd = {"aluRun","aluAnd"          , "aluSaveNZ"}, |  | ||||||
| 	aluOpIor = {"aluRun","aluIor"          , "aluSaveNZ"}, |  | ||||||
| 	aluOpXor = {"aluRun","aluXor"          , "aluSaveNZ"}, |  | ||||||
| 	aluOpAnn = {"aluRun","aluAnd","aluRInv", "aluSaveNZ"}, |  | ||||||
| 	aluOpCmp = {"aluOpSub"}, |  | ||||||
| 	aluOpInc = {"aluOpAdd","aluCinOn"}, |  | ||||||
| 	aluOpDec = {"aluOpAdd","aluRInv"}, |  | ||||||
| 	aluOpMov = {"aluAdd","aluSaveNZ"}, |  | ||||||
| 	aluOpShl = {"aluRun", "aluShift"                                               ,"aluSaveNZ"}, |  | ||||||
| 	aluOpShr = {"aluRun", "aluShift","aluShiftRight"                               ,"aluSaveNZ"}, |  | ||||||
| 	aluOpRol = {"aluRun", "aluShift",                "aluShiftRoll"                ,"aluSaveNZ"}, |  | ||||||
| 	aluOpRor = {"aluRun", "aluShift","aluShiftRight","aluShiftRoll"                ,"aluSaveNZ"}, |  | ||||||
| 	aluOpSra = {"aluRun", "aluShift","aluShiftRight",               "aluShiftArith","aluSaveNZ"}, |  | ||||||
| 	 |  | ||||||
| 	clearRegs = { |  | ||||||
| 		"aluSaveA","aluSaveB","aluSaveC","aluSaveU","aluSaveT", |  | ||||||
| 		"adwSaveP","adwSaveQ","adwSaveS","adwSaveV", |  | ||||||
| 		"adrSaveI", |  | ||||||
| 		"aluSaveNZ","aluSaveCarry", |  | ||||||
| 	} |  | ||||||
| }, |  | ||||||
|  |  | ||||||
| instructions = { |  | ||||||
| 	{ category = "Control", catlet="C" }, |  | ||||||
| 	{ mnem="rst"        , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","clearRegs","loadInstr"}, desc="Clear all registers and set I=0", ccode={"cpu.a=0; cpu.b=0; cpu.c=0; cpu.u=0; cpu.t=0; cpu.p=0; cpu.q=0; cpu.s=0; cpu.v=0; cpu.i=0; cpu.cf=0; cpu.nz=0; cpu.irq=0; cpu.ifg=0; cpu.rfg=1; cpu.ien=0; lni;"} }, |  | ||||||
| 	{ mnem="hlt"        , opcode=0xF0, {"runFlgClk","instrNext"}, desc="Halt non-interrupt execution", ccode={"cpu.rfg=0; lni;"} }, |  | ||||||
| 	{ mnem="run"        , opcode=0xF1, {"runFlgClk","runFlgVal","instrNext"}, desc ="Resume non-interrupt execution", ccode={"cpu.rfg=1; lni;"} }, |  | ||||||
| 	{ mnem="int"        , opcode=0xF2, {"instrSwapIV","intFlgVal","intFlgClk","irqFlgClk"}, ccode={"cpu.irq=0; cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=(t-1)%65536; lni;"} }, |  | ||||||
| 	{ mnem="brk"        , opcode=0xF3, {"instrSwapIV","adwInc","intFlgVal","intFlgClk"}, desc="Trigger interrupt", ccode={"cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} }, |  | ||||||
| 	{ mnem="irt"        , opcode=0xF4, {"instrSwapIV","adwInc","intFlgClk"}, desc="Return from interrupt", ccode={"cpu.ifg=0; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} }, |  | ||||||
| 	{ mnem="nop"        , opcode=0xFF, {"instrNext"}, desc="Do nothing", ccode={"lni;"}, }, |  | ||||||
| 	{ mnem="ien"        , opcode=0xF5, {"instrNext"}, desc="Enbale interrupts", ccode={"cpu.ien=1; lni;"}, }, -- todo |  | ||||||
| 	{ mnem="idi"        , opcode=0xF6, {"instrNext"}, desc="Disable interrupts", ccode={"cpu.ien=0; lni;"}, }, -- todo |  | ||||||
| 	 |  | ||||||
| 	{ category = "16-bit Inc/Dec", catlet="I" }, |  | ||||||
| 	{ mnem="inc p"      , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++", ccode={"cpu.p++; lni;"} }, |  | ||||||
| 	{ mnem="dec p"      , opcode=0x15, {"adwlP","adwrm1","adwSaveP","instrNext"}, desc="P--", ccode={"cpu.p--; lni;"} }, |  | ||||||
| 	{ mnem="inc q"      , opcode=0x13, {"adwlQ","adwInc","adwSaveQ","instrNext"}, desc="Q++", ccode={"cpu.q++; lni;"} }, |  | ||||||
| 	{ mnem="dec q"      , opcode=0x16, {"adwlQ","adwrm1","adwSaveQ","instrNext"}, desc="Q--", ccode={"cpu.q--; lni;"} }, |  | ||||||
| 	 |  | ||||||
| 	{ category = "8-bit Unary", catlet="U" }, |  | ||||||
| 	{ mnem="inc a"      , opcode=0x10,                                                            {"aluA","alur1" ,"aluOpAdd" ,"instrNext"}, desc="A++, set flags"  , ccode={"addf(cpu.a, 1    ); lni;"} }, |  | ||||||
| 	{ mnem="dec a"      , opcode=0x11,                                                            {"aluA","alurm1","aluOpAdd" ,"instrNext"}, desc="A--, set flags"  , ccode={"addf(cpu.a,-1    ); lni;"} }, |  | ||||||
| 	{ mnem="icc a"      , opcode=0x1B,                                                            {"aluA",         "aluOpAddC","instrNext"}, desc="A+=CF, set flags", ccode={"addf(cpu.a,cpu.cf); lni;"} }, |  | ||||||
| 	{ mnem="inc b"      , opcode=0x19,                                                            {"aluB","alur1" ,"aluOpAdd" ,"instrNext"}, desc="B++, set flags"  , ccode={"addf(cpu.b, 1    ); lni;"} }, |  | ||||||
| 	{ mnem="dec b"      , opcode=0x1A,                                                            {"aluB","alurm1","aluOpAdd" ,"instrNext"}, desc="B--, set flags"  , ccode={"addf(cpu.b,-1    ); lni;"} }, |  | ||||||
| 	{ mnem="icc b"      , opcode=0x1C,                                                            {"aluB",         "aluOpAddC","instrNext"}, desc="B+=CF, set flags", ccode={"addf(cpu.b,cpu.cf); lni;"} }, |  | ||||||
| 	{ mnem="inc c"      , opcode=0x17,                                                            {"aluC","alur1" ,"aluOpAdd" ,"instrNext"}, desc="C++, set flags"  , ccode={"addf(cpu.c, 1    ); lni;"} }, |  | ||||||
| 	{ mnem="dec c"      , opcode=0x18,                                                            {"aluC","alurm1","aluOpAdd" ,"instrNext"}, desc="C--, set flags"  , ccode={"addf(cpu.c,-1    ); lni;"} }, |  | ||||||
| 	{ mnem="icc c"      , opcode=0x1D,                                                            {"aluC",         "aluOpAddC","instrNext"}, desc="C+=CF, set flags", ccode={"addf(cpu.c,cpu.cf); lni;"} }, |  | ||||||
| 	{ mnem="tst a"      , opcode=0x14,                                                            {"alulA",        "aluOpCmp" ,"instrNext"}, desc="Set flags according to A-0", ccode={"tst(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="tst b"      , opcode=0x1E,                                                            {"alulB",        "aluOpCmp" ,"instrNext"}, desc="Set flags according to B-0", ccode={"tst(cpu.b); lni;"} }, |  | ||||||
| 	{ mnem="tst c"      , opcode=0x1F,                                                            {"alulC",        "aluOpCmp" ,"instrNext"}, desc="Set flags according to C-0", ccode={"tst(cpu.c); lni;"} }, |  | ||||||
| 	{ mnem="inc *s+imm8", opcode=0x2B, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alur1" ,"aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)++, set flags"  , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u, 1    );","instrloadpre"} }, |  | ||||||
| 	{ mnem="dec *s+imm8", opcode=0x2C, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alurm1","aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)--, set flags"  , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,-1    );","instrloadpre"} }, |  | ||||||
| 	{ mnem="icc *s+imm8", opcode=0x2D, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU",         "aluOpAddC","instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)+=CF, set flags", ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,cpu.cf);","instrloadpre"} }, |  | ||||||
| 	{ mnem="tst *s+imm8", opcode=0x2E, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"alulU",        "aluOpCmp" ,"instrNext"},                                                   desc="Set flags according to *(S+imm8)-0", ccode={"loadimmedt","loadstackrelu","tst(cpu.u); lni;"} }, |  | ||||||
| 	 |  | ||||||
| 	{ category = "16-bit Arithmetic", catlet = "X"}, |  | ||||||
| 	{ mnem="adp imm8"   , opcode=0x4A, {"loadImmedT","instrSub1"}, {"adwP","adwrTX","instrNext"}, desc="P+=imm8 signed", ccode={"loadimmedt","cpu.p+=signed8(cpu.t); lni;"} }, |  | ||||||
| 	{ mnem="adq imm8"   , opcode=0x4B, {"loadImmedT","instrSub1"}, {"adwQ","adwrTX","instrNext"}, desc="Q+=imm8 signed", ccode={"loadimmedt","cpu.q+=signed8(cpu.t); lni;"} }, |  | ||||||
| 	{ mnem="ads imm8"   , opcode=0x4C, {"loadImmedT","instrSub1"}, {"adwS","adwrTX","instrNext"}, desc="S+=imm8 signed", ccode={"loadimmedt","cpu.s+=signed8(cpu.t); lni;"} }, |  | ||||||
| 	{ mnem="adp b"      , opcode=0xE6, {"adwP","adwrBX","instrNext"}, desc="P+=B signed", ccode={"cpu.p+=signed8(cpu.b); lni;"} }, |  | ||||||
| 	{ mnem="adq b"      , opcode=0xE7, {"adwQ","adwrBX","instrNext"}, desc="Q+=B signed", ccode={"cpu.q+=signed8(cpu.b); lni;"} }, |  | ||||||
| 	{ mnem="ads b"      , opcode=0xE8, {"adwS","adwrBX","instrNext"}, desc="S+=B signed", ccode={"cpu.s+=signed8(cpu.b); lni;"} }, |  | ||||||
| 	 |  | ||||||
| 	{ category = "8-bit Arithmetic/Logic", catlet="A" }, |  | ||||||
| 	{ mnem="add imm8"   , opcode=0x24, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=imm8, set flags"                , ccode={"loadimmedt","addf(cpu.a,cpu.t); lni;"} }, |  | ||||||
| 	{ mnem="adb imm8"   , opcode=0x72, {"loadImmedT","instrSub1"},                                {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=imm8, set flags"                , ccode={"loadimmedt","addf(cpu.b,cpu.t); lni;"} }, |  | ||||||
| 	{ mnem="adc imm8"   , opcode=0x73, {"loadImmedT","instrSub1"},                                {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=imm8, set flags"                , ccode={"loadimmedt","addf(cpu.c,cpu.t); lni;"} }, |  | ||||||
| 	{ mnem="sub imm8"   , opcode=0x70, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=imm8, set flags"                , ccode={"loadimmedt","subf(cpu.a,cpu.t); lni;"} }, |  | ||||||
| 	{ mnem="sbb imm8"   , opcode=0x99, {"loadImmedT","instrSub1"},                                {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=imm8, set flags"                , ccode={"loadimmedt","subf(cpu.b,cpu.t); lni;"} }, |  | ||||||
| 	{ mnem="sbc imm8"   , opcode=0x9A, {"loadImmedT","instrSub1"},                                {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=imm8, set flags"                , ccode={"loadimmedt","subf(cpu.c,cpu.t); lni;"} }, |  | ||||||
| 	{ mnem="acc imm8"   , opcode=0x78, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=imm8+CF, set flags"             , ccode={"loadimmedt","addf(cpu.a,cpu.t+cpu.cf); lni;"} }, |  | ||||||
| 	{ mnem="scc imm8"   , opcode=0x79, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=imm8+CF, set flags"             , ccode={"loadimmedt","addf(cpu.a,-cpu.t+cpu.cf); lni;"} }, |  | ||||||
| 	{ mnem="cmp imm8"   , opcode=0x71, {"loadImmedT","instrSub1"},                                {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-imm8"     , ccode={"loadimmedt","cmpf(cpu.a,cpu.t); lni;"} }, |  | ||||||
| 	{ mnem="and imm8"   , opcode=0x74, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=imm8, set zero flag"            , ccode={"loadimmedt","cpu.a&=cpu.t; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="ior imm8"   , opcode=0x75, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=imm8, set zero flag"            , ccode={"loadimmedt","cpu.a|=cpu.t; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="xor imm8"   , opcode=0x76, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=imm8, set zero flag"            , ccode={"loadimmedt","cpu.a^=cpu.t; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="ann imm8"   , opcode=0x77, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpAnn" ,"instrNext"}, desc="A&=~imm8, set zero flag"           , ccode={"loadimmedt","cpu.a&=~cpu.t; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="shl imm8"   , opcode=0xD0, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=imm8, set zero flag"           , ccode={"loadimmedt","cpu.a<<=cpu.t; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="shr imm8"   , opcode=0xD1, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A>>=imm8, set zero flag"           , ccode={"loadimmedt","cpu.a>>=cpu.t; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="rol imm8"   , opcode=0xD2, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=imm8, set zero flag"          , ccode={"loadimmedt","cpu.a=rol(cpu.a,cpu.t); setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="ror imm8"   , opcode=0xD3, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=imm8, set zero flag"          , ccode={"loadimmedt","cpu.a=ror(cpu.a,cpu.t); setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="sra imm8"   , opcode=0xD4, {"loadImmedT","instrSub1"},                                {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=imm8, set zero flag"          , ccode={"loadimmedt","cpu.a=sra(cpu.a,cpu.t); setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="add *s+imm8", opcode=0xAE, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u); lni;"} }, |  | ||||||
| 	{ mnem="adb *s+imm8", opcode=0x9B, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","addf(cpu.b,cpu.u); lni;"} }, |  | ||||||
| 	{ mnem="adc *s+imm8", opcode=0x9C, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","addf(cpu.c,cpu.u); lni;"} }, |  | ||||||
| 	{ mnem="sub *s+imm8", opcode=0xAF, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","subf(cpu.a,cpu.u); lni;"} }, |  | ||||||
| 	{ mnem="sbb *s+imm8", opcode=0x9D, {"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 *s+imm8", opcode=0x9E, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=*(S+imm8), set flags"           , ccode={"loadimmedt","loadstackrelu","subf(cpu.c,cpu.u); lni;"} }, |  | ||||||
| 	{ mnem="acc *s+imm8", opcode=0xB5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=*(S+imm8)+CF, set flags"        , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u+cpu.cf); lni;"} }, |  | ||||||
| 	{ mnem="scc *s+imm8", opcode=0xB7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=*(S+imm8)+CF, set flags"        , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,-cpu.u+cpu.cf); lni;"} }, |  | ||||||
| 	{ mnem="cmp *s+imm8", opcode=0xB0, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-*(S+imm8)", ccode={"loadimmedt","loadstackrelu","cmpf(cpu.a,cpu.u); lni;"} }, |  | ||||||
| 	{ mnem="and *s+imm8", opcode=0xB1, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=*(S+imm8), set zero flag"       , ccode={"loadimmedt","loadstackrelu","cpu.a&=cpu.u; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="ior *s+imm8", opcode=0xB2, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=*(S+imm8), set zero flag"       , ccode={"loadimmedt","loadstackrelu","cpu.a|=cpu.u; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="xor *s+imm8", opcode=0xB3, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=*(S+imm8), set zero flag"       , ccode={"loadimmedt","loadstackrelu","cpu.a^=cpu.u; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="ann *s+imm8", opcode=0xB4, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnn" ,"instrNext"}, desc="A&=~*(S+imm8), set zero flag"      , ccode={"loadimmedt","loadstackrelu","cpu.a&=~cpu.u; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="shl *s+imm8", opcode=0xD5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag"      , ccode={"loadimmedt","loadstackrelu","cpu.a<<=cpu.u; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="shr *s+imm8", opcode=0xD6, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag"      , ccode={"loadimmedt","loadstackrelu","cpu.a>>=cpu.u; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="rol *s+imm8", opcode=0xD7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=*(S+imm8), set zero flag"     , ccode={"loadimmedt","loadstackrelu","cpu.a=rol(cpu.a,cpu.u); setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="ror *s+imm8", opcode=0xD8, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=*(S+imm8), set zero flag"     , ccode={"loadimmedt","loadstackrelu","cpu.a=ror(cpu.a,cpu.u); setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="sra *s+imm8", opcode=0xD9, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=*(S+imm8), set zero flag"     , ccode={"loadimmedt","loadstackrelu","cpu.a=sra(cpu.a,cpu.u); setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="add b"      , opcode=0xA0,                                                            {"aluA", "alurB","aluOpAdd" ,"instrNext"}, desc="A+=B, set flags"                   , ccode={"addf(cpu.a,cpu.b); lni;"} }, |  | ||||||
| 	{ mnem="adc b"      , opcode=0x9F,                                                            {"aluC", "alurB","aluOpAdd" ,"instrNext"}, desc="C+=B, set flags"                   , ccode={"addf(cpu.c,cpu.b); lni;"} }, |  | ||||||
| 	{ mnem="sub b"      , opcode=0xA1,                                                            {"aluA", "alurB","aluOpSub" ,"instrNext"}, desc="A-=B, set flags"                   , ccode={"subf(cpu.a,cpu.b); lni;"} }, |  | ||||||
| 	{ mnem="sbc b"      , opcode=0xB6,                                                            {"aluC", "alurB","aluOpSub" ,"instrNext"}, desc="C-=B, set flags"                   , ccode={"subf(cpu.c,cpu.b); lni;"} }, |  | ||||||
| 	{ mnem="acc b"      , opcode=0xB8,                                                            {"aluA", "alurB","aluOpAddC","instrNext"}, desc="A+=B+CF, set flags"                , ccode={"addf(cpu.a,cpu.b+cpu.cf); lni;"} }, |  | ||||||
| 	{ mnem="scc b"      , opcode=0xB9,                                                            {"aluA", "alurB","aluOpSubC","instrNext"}, desc="A-=B+CF, set flags"                , ccode={"addf(cpu.a,-cpu.b+cpu.cf); lni;"} }, |  | ||||||
| 	{ mnem="cmp b"      , opcode=0xA2,                                                            {"alulA","alurB","aluOpSub" ,"instrNext"}, desc="set flags according to A-B"        , ccode={"cmpf(cpu.a,cpu.b); lni;"} }, |  | ||||||
| 	{ mnem="and b"      , opcode=0xA3,                                                            {"aluA", "alurB","aluOpAnd" ,"instrNext"}, desc="A&=B, set zero flag"               , ccode={"cpu.a&=cpu.b; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="ior b"      , opcode=0xA4,                                                            {"aluA", "alurB","aluOpIor" ,"instrNext"}, desc="A|=B, set zero flag"               , ccode={"cpu.a|=cpu.b; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="xor b"      , opcode=0xA5,                                                            {"aluA", "alurB","aluOpXor" ,"instrNext"}, desc="A^=B, set zero flag"               , ccode={"cpu.a^=cpu.b; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="ann b"      , opcode=0xA6,                                                            {"aluA", "alurB","aluOpAnn" ,"instrNext"}, desc="A&=~B, set zero flag"              , ccode={"cpu.a&=~cpu.b; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="shl b"      , opcode=0xDA,                                                            {"aluA", "alurB","aluOpShl" ,"instrNext"}, desc="A<<=B, set zero flag"              , ccode={"cpu.a<<=cpu.b; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="shr b"      , opcode=0xDB,                                                            {"aluA", "alurB","aluOpShr" ,"instrNext"}, desc="A>>=B, set zero flag"              , ccode={"cpu.a>>=cpu.b; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="rol b"      , opcode=0xDC,                                                            {"aluA", "alurB","aluOpRol" ,"instrNext"}, desc="A<<<=B, set zero flag"             , ccode={"cpu.a=rol(cpu.a,cpu.b); setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="ror b"      , opcode=0xDD,                                                            {"aluA", "alurB","aluOpRor" ,"instrNext"}, desc="A>>>=B, set zero flag"             , ccode={"cpu.a=ror(cpu.a,cpu.b); setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="sra b"      , opcode=0xDE,                                                            {"aluA", "alurB","aluOpSra" ,"instrNext"}, desc="A>>a=B, set zero flag"             , ccode={"cpu.a=sra(cpu.a,cpu.b); setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="add c"      , opcode=0xA7,                                                            {"aluA", "alurC","aluOpAdd" ,"instrNext"}, desc="A+=C, set flags"                   , ccode={"addf(cpu.a,cpu.c); lni;"} }, |  | ||||||
| 	{ mnem="adb c"      , opcode=0xBD,                                                            {"aluB", "alurC","aluOpAdd" ,"instrNext"}, desc="B+=C, set flags"                   , ccode={"addf(cpu.b,cpu.c); lni;"} }, |  | ||||||
| 	{ mnem="sub c"      , opcode=0xA8,                                                            {"aluA", "alurC","aluOpSub" ,"instrNext"}, desc="A-=C, set flags"                   , ccode={"subf(cpu.a,cpu.c); lni;"} }, |  | ||||||
| 	{ mnem="sbb c"      , opcode=0xBC,                                                            {"aluB", "alurC","aluOpSub" ,"instrNext"}, desc="B-=C, set flags"                   , ccode={"subf(cpu.b,cpu.c); lni;"} }, |  | ||||||
| 	{ mnem="acc c"      , opcode=0xBA,                                                            {"aluA", "alurC","aluOpAddC","instrNext"}, desc="A+=C+CF, set flags"                , ccode={"addf(cpu.a,cpu.c+cpu.cf); lni;"} }, |  | ||||||
| 	{ mnem="scc c"      , opcode=0xBB,                                                            {"aluA", "alurC","aluOpSubC","instrNext"}, desc="A-=C+CF, set flags"                , ccode={"addf(cpu.a,-cpu.c+cpu.cf); lni;"} }, |  | ||||||
| 	{ mnem="cmp c"      , opcode=0xA9,                                                            {"alulA","alurC","aluOpSub" ,"instrNext"}, desc="set flags according to A-C"        , ccode={"cmpf(cpu.a,cpu.c); lni;"} }, |  | ||||||
| 	{ mnem="and c"      , opcode=0xAA,                                                            {"aluA", "alurC","aluOpAnd" ,"instrNext"}, desc="A&=C, set zero flag"               , ccode={"cpu.a&=cpu.c; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="ior c"      , opcode=0xAB,                                                            {"aluA", "alurC","aluOpIor" ,"instrNext"}, desc="A|=C, set zero flag"               , ccode={"cpu.a|=cpu.c; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="xor c"      , opcode=0xAC,                                                            {"aluA", "alurC","aluOpXor" ,"instrNext"}, desc="A^=C, set zero flag"               , ccode={"cpu.a^=cpu.c; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="ann c"      , opcode=0xAD,                                                            {"aluA", "alurC","aluOpAnn" ,"instrNext"}, desc="A&=~C, set zero flag"              , ccode={"cpu.a&=~cpu.c; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="shl c"      , opcode=0xDF,                                                            {"aluA", "alurC","aluOpShl" ,"instrNext"}, desc="A<<=C, set zero flag"              , ccode={"cpu.a<<=cpu.c; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="shr c"      , opcode=0x4D,                                                            {"aluA", "alurC","aluOpShr" ,"instrNext"}, desc="A>>=C, set zero flag"              , ccode={"cpu.a>>=cpu.c; setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="rol c"      , opcode=0x3E,                                                            {"aluA", "alurC","aluOpRol" ,"instrNext"}, desc="A<<<=C, set zero flag"             , ccode={"cpu.a=rol(cpu.a,cpu.c); setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="ror c"      , opcode=0x3F,                                                            {"aluA", "alurC","aluOpRor" ,"instrNext"}, desc="A>>>=C, set zero flag"             , ccode={"cpu.a=ror(cpu.a,cpu.c); setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="sra c"      , opcode=0x2F,                                                            {"aluA", "alurC","aluOpSra" ,"instrNext"}, desc="A>>a=C, set zero flag"             , ccode={"cpu.a=sra(cpu.a,cpu.c); setzf(cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="adb a"      , opcode=0xBE,                                                            {"aluB", "alurA","aluOpAdd" ,"instrNext"}, desc="B+=A, set flags"                   , ccode={"addf(cpu.b,cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="sbb a"      , opcode=0xBF,                                                            {"aluB", "alurA","aluOpSub" ,"instrNext"}, desc="B-=A, set flags"                   , ccode={"subf(cpu.b,cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="adc a"      , opcode=0x4E,                                                            {"aluC", "alurA","aluOpAdd" ,"instrNext"}, desc="C+=A, set flags"                   , ccode={"addf(cpu.c,cpu.a); lni;"} }, |  | ||||||
| 	{ mnem="sbc a"      , opcode=0x4F,                                                            {"aluC", "alurA","aluOpSub" ,"instrNext"}, desc="C-=A, set flags"                   , ccode={"subf(cpu.c,cpu.a); lni;"} }, |  | ||||||
| 	 |  | ||||||
| 	{ category = "Jumps", catlet="J" }, |  | ||||||
| 	{ mnem="jmp imm16"  , opcode=0x60, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT"              }, desc="I=imm16"     , ccode={"loadimm161","loadimm162","jmpabsut"} }, |  | ||||||
| 	{ mnem="jsr imm16"  , opcode=0x63, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT","saveRetAddr"}, desc="I=imm16, Q=I", ccode={"loadimm161","loadimm162","jmpabsut saveretaddr"} }, |  | ||||||
| 	{ mnem="jss imm16"  , opcode=0xE2, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushRetAddr1","instrSub3"}, {"pushRetAddr2","instrSub4"}, {"jmpAbsUT"}, desc="I=imm16, *(S++++)=I-1", ccode={"loadimm161","loadimm162","pushretaddr1","pushretaddr2","jmpabsut"} }, |  | ||||||
| 	{ mnem="jmp p"      , opcode=0x64, {"jmpAbsP"              }, desc="I=P"     , ccode={"jmpabsp"} }, |  | ||||||
| 	{ mnem="jmp q"      , opcode=0x66, {"jmpAbsQ"              }, desc="I=Q"     , ccode={"jmpabsq"} }, |  | ||||||
| 	{ mnem="jsr p"      , opcode=0x65, {"jmpAbsP","saveRetAddr"}, desc="I=P, Q=I", ccode={"jmpabsp","saveretaddr"} }, |  | ||||||
| 	{ mnem="jsr q"      , opcode=0x67, {"jmpAbsQ","saveRetAddr"}, desc="I=Q, Q=I", ccode={"jmpabsq","saveretaddr"} }, |  | ||||||
| 	{ mnem="jss p"      , opcode=0xE4, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsP"}, desc="I=P, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsp"} }, |  | ||||||
| 	{ mnem="jss q"      , opcode=0xE5, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsQ"}, desc="I=Q, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsq"} }, |  | ||||||
| 	{ mnem="rts"        , opcode=0xE1, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"jmpAbsUT","adrInc"}, desc="I=*(----S)+1", ccode={"pop161","pop162","jmpabsutplus1"} }, |  | ||||||
| 	{ mnem="jpr imm8"   , opcode=0x31, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub1"}, {"jmpRelT"}, desc="I+=imm8", ccode={"loadimmedt","jmprelt"} }, |  | ||||||
| 	{ mnem="jnz imm8"   , opcode=0x30, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NZ"               }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Zero"       , ccode={"loadimmedt","if( cpu.nz               ) { jmprelt } else { lni }"} }, |  | ||||||
| 	{ mnem="jpz imm8"   , opcode=0x32, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0Z"                }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero"        , ccode={"loadimmedt","if(!cpu.nz               ) { jmprelt } else { lni }"} }, |  | ||||||
| 	{ mnem="jlt imm8"   , opcode=0x33, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC"               }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Carry"      , ccode={"loadimmedt","if(!cpu.cf               ) { jmprelt } else { lni }"} }, |  | ||||||
| 	{ mnem="jge imm8"   , opcode=0x34, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C"                }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Carry"       , ccode={"loadimmedt","if( cpu.cf               ) { jmprelt } else { lni }"} }, |  | ||||||
| 	{ mnem="jgt imm8"   , opcode=0x35, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if(  cpu.nz &&    cpu.cf ) { jmprelt } else { lni }"} }, |  | ||||||
| 	{ mnem="jle imm8"   , opcode=0x36, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry", ccode={"loadimmedt","if((!cpu.nz) || (!cpu.cf)) { jmprelt } else { lni }"} }, |  | ||||||
| 	 |  | ||||||
| 	{ category = "Stack", catlet="S" }, |  | ||||||
| 	{ mnem="psh a"      , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A", ccode={"pushbyte(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="psh b"      , opcode=0x44, {"pushReg","alurB","instrSub1"}, {"instrNext"}, desc="*(S++)=B", ccode={"pushbyte(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="psh c"      , opcode=0x45, {"pushReg","alurC","instrSub1"}, {"instrNext"}, desc="*(S++)=C", ccode={"pushbyte(cpu.c);","lni;"} }, |  | ||||||
| 	{ mnem="psh f"      , opcode=0xE9, {"pushReg","alurF","instrSub1"}, {"instrNext"}, desc="*(S++)=F", ccode={"int f = cpu.nz | (cpu.cf<<1); pushbyte(f);","lni;"} }, |  | ||||||
| 	{ mnem="psh p"      , opcode=0x41, {"pushReg","alurPH","instrSub1"}, {"pushReg","alurPL","instrSub2"}, {"instrNext"}, desc="*(S++++)=P", ccode={"push161(cpu.p);","push162(cpu.p);","lni;"} }, |  | ||||||
| 	{ mnem="psh q"      , opcode=0x46, {"pushReg","alurQH","instrSub1"}, {"pushReg","alurQL","instrSub2"}, {"instrNext"}, desc="*(S++++)=Q", ccode={"push161(cpu.q);","push162(cpu.q);","lni;"} }, |  | ||||||
| 	{ mnem="pop a"      , opcode=0x42, {"popReg","memSaveA","instrSub1"}, {"instrNext"}, desc="A=*(--S)", ccode={"cpu.a=popbyte;","lni;"} }, |  | ||||||
| 	{ mnem="pop b"      , opcode=0x47, {"popReg","memSaveB","instrSub1"}, {"instrNext"}, desc="B=*(--S)", ccode={"cpu.b=popbyte;","lni;"} }, |  | ||||||
| 	{ mnem="pop c"      , opcode=0x48, {"popReg","memSaveC","instrSub1"}, {"instrNext"}, desc="C=*(--S)", ccode={"cpu.c=popbyte;","lni;"} }, |  | ||||||
| 	{ mnem="pop f"      , opcode=0xEA, {"popReg","memSaveF","instrSub1"}, {"instrNext"}, desc="F=*(--S)", ccode={"int f=popbyte; cpu.nz = f&1; cpu.cf = (f>>1)&1;","lni;"} }, |  | ||||||
| 	{ mnem="pop p"      , opcode=0x43, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*(----S)", ccode={"pop161","pop162","cpu.p=wordut; lni;"} }, |  | ||||||
| 	{ mnem="pop q"      , opcode=0x49, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*(----S)", ccode={"pop161","pop162","cpu.q=wordut; lni;"} }, |  | ||||||
| 	{ mnem="psh imm8"   , opcode=0x3B, {"loadImmedT","instrSub1"}, {"pushReg","alurT","instrSub2"}, {"instrNext"}, desc="*(S++)=imm8", ccode={"loadimmedt;","pushbyte(cpu.t);","lni;"} }, |  | ||||||
| 	{ mnem="phw imm16"  , opcode=0x3C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushReg","alurU","instrSub3"}, {"pushReg","alurT","instrSub4"}, {"instrNext"}, desc="*(S++++)=imm16", ccode={"loadimm161","loadimm162","pushbyte(cpu.u);","pushbyte(cpu.t);","lni;"} }, -- 0x3D |  | ||||||
| 	 |  | ||||||
| 	{ category = "8-bit Load/Store", catlet="B" }, |  | ||||||
| 	{ mnem="lda imm8"   , opcode=0x20,                             {"loadImmed",   "memSaveA","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=imm8, update zero flag", ccode={"cpu.a=loadimmed; setzf(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="ldb imm8"   , opcode=0x26,                             {"loadImmed",   "memSaveB","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=imm8, update zero flag", ccode={"cpu.b=loadimmed; setzf(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="ldc imm8"   , opcode=0x27,                             {"loadImmed",   "memSaveC","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=imm8, update zero flag", ccode={"cpu.c=loadimmed; setzf(cpu.c);","lni;"} }, |  | ||||||
| 	{ mnem="lda *s+imm8", opcode=0x28, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveA","memSaveFlags","instrSub2"}, {"instrNext"}, desc="A=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.a=loadstackrel; setzf(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="ldb *s+imm8", opcode=0x29, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveB","memSaveFlags","instrSub2"}, {"instrNext"}, desc="B=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.b=loadstackrel; setzf(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="ldc *s+imm8", opcode=0x2A, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveC","memSaveFlags","instrSub2"}, {"instrNext"}, desc="C=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.c=loadstackrel; setzf(cpu.c);","lni;"} }, |  | ||||||
| 	{ mnem="sta *s+imm8", opcode=0x96, {"loadImmedT","instrSub1"}, {"storeStackRel","alurA","instrSub2"}, {"instrNext"}, desc="*s+imm8=A", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="stb *s+imm8", opcode=0x97, {"loadImmedT","instrSub1"}, {"storeStackRel","alurB","instrSub2"}, {"instrNext"}, desc="*s+imm8=B", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="stc *s+imm8", opcode=0x98, {"loadImmedT","instrSub1"}, {"storeStackRel","alurC","instrSub2"}, {"instrNext"}, desc="*s+imm8=C", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="lda *imm16" , opcode=0x51, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","loadReg","memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadut; setzf(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="ldb *imm16" , opcode=0x56, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","loadReg","memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadut; setzf(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="ldc *imm16" , opcode=0x57, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","loadReg","memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadut; setzf(cpu.c);","lni;"} }, |  | ||||||
| 	{ mnem="sta *imm16" , opcode=0x50, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","storeReg","alurA","instrSub3"}, {"instrNext"}, desc="*imm16=A", ccode={"loadimm161","loadimm162","storeut(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="stb *imm16" , opcode=0x58, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","storeReg","alurB","instrSub3"}, {"instrNext"}, desc="*imm16=B", ccode={"loadimm161","loadimm162","storeut(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="stc *imm16" , opcode=0x59, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2",}, {"adrrUT","storeReg","alurC","instrSub3"}, {"instrNext"}, desc="*imm16=C", ccode={"loadimm161","loadimm162","storeut(cpu.c);","lni;"} }, |  | ||||||
| 	{ mnem="sta *p"     , opcode=0x52, {"adrlP","storeReg","alurA",         "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P=A", ccode={"storep(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="stb *p"     , opcode=0x5A, {"adrlP","storeReg","alurB",         "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P=B", ccode={"storep(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="stc *p"     , opcode=0x5B, {"adrlP","storeReg","alurC",         "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P=C", ccode={"storep(cpu.c);","lni;"} }, |  | ||||||
| 	{ mnem="sta *q"     , opcode=0x54, {"adrlQ","storeReg","alurA",         "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q=A", ccode={"storeq(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="stb *q"     , opcode=0x5C, {"adrlQ","storeReg","alurB",         "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q=B", ccode={"storeq(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="stc *q"     , opcode=0x5D, {"adrlQ","storeReg","alurC",         "memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q=C", ccode={"storeq(cpu.c);","lni;"} }, |  | ||||||
| 	{ mnem="lda *p"     , opcode=0x53, {"adrlP","loadReg","memSaveA",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P, update zero flag", ccode={"cpu.a=loadp; setzf(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="ldb *p"     , opcode=0x5E, {"adrlP","loadReg","memSaveB",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P, update zero flag", ccode={"cpu.b=loadp; setzf(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="ldc *p"     , opcode=0x5F, {"adrlP","loadReg","memSaveC",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P, update zero flag", ccode={"cpu.c=loadp; setzf(cpu.c);","lni;"} }, |  | ||||||
| 	{ mnem="lda *q"     , opcode=0x55, {"adrlQ","loadReg","memSaveA",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q, update zero flag", ccode={"cpu.a=loadq; setzf(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="ldb *q"     , opcode=0x61, {"adrlQ","loadReg","memSaveB",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q, update zero flag", ccode={"cpu.b=loadq; setzf(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="ldc *q"     , opcode=0x62, {"adrlQ","loadReg","memSaveC",       "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q, update zero flag", ccode={"cpu.c=loadq; setzf(cpu.c);","lni;"} }, |  | ||||||
| 	{ mnem="sta *p++"   , opcode=0xC0, {"adrlP","storeReg","alurA",  "incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P++=A", ccode={"storepinc(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="stb *p++"   , opcode=0xC1, {"adrlP","storeReg","alurB",  "incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P++=B", ccode={"storepinc(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="stc *p++"   , opcode=0xC2, {"adrlP","storeReg","alurC",  "incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*P++=C", ccode={"storepinc(cpu.c);","lni;"} }, |  | ||||||
| 	{ mnem="sta *q++"   , opcode=0xC3, {"adrlQ","storeReg","alurA",  "incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q++=A", ccode={"storeqinc(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="stb *q++"   , opcode=0xC4, {"adrlQ","storeReg","alurB",  "incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q++=B", ccode={"storeqinc(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="stc *q++"   , opcode=0xC5, {"adrlQ","storeReg","alurC",  "incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="*Q++=C", ccode={"storeqinc(cpu.c);","lni;"} }, |  | ||||||
| 	{ mnem="lda *p++"   , opcode=0xC6, {"adrlP","loadReg","memSaveA","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P++, update zero flag", ccode={"cpu.a=loadpinc; setzf(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="ldb *p++"   , opcode=0xC7, {"adrlP","loadReg","memSaveB","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P++, update zero flag", ccode={"cpu.b=loadpinc; setzf(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="ldc *p++"   , opcode=0xC8, {"adrlP","loadReg","memSaveC","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P++, update zero flag", ccode={"cpu.c=loadpinc; setzf(cpu.c);","lni;"} }, |  | ||||||
| 	{ mnem="lda *q++"   , opcode=0xC9, {"adrlQ","loadReg","memSaveA","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q++, update zero flag", ccode={"cpu.a=loadqinc; setzf(cpu.a);","lni;"} }, |  | ||||||
| 	{ mnem="ldb *q++"   , opcode=0xCA, {"adrlQ","loadReg","memSaveB","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q++, update zero flag", ccode={"cpu.b=loadqinc; setzf(cpu.b);","lni;"} }, |  | ||||||
| 	{ mnem="ldc *q++"   , opcode=0xCB, {"adrlQ","loadReg","memSaveC","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q++, update zero flag", ccode={"cpu.c=loadqinc; setzf(cpu.c);","lni;"} }, |  | ||||||
| 	 |  | ||||||
| 	{ category = "16-bit Load/Store", catlet="W" }, |  | ||||||
| 	{ mnem="ldp imm16"  , opcode=0x21, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; lni;"} }, |  | ||||||
| 	{ mnem="ldq imm16"  , opcode=0x23, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; lni;"} }, |  | ||||||
| 	{ mnem="lds imm16"  , opcode=0x25, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveS","instrNext"}, desc="S=imm16", ccode={"loadimm161","loadimm162","cpu.s=wordut; lni;"} }, |  | ||||||
| 	{ mnem="ldv imm16"  , opcode=0x22, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveV","instrNext"}, desc="V=imm16", ccode={"loadimm161","loadimm162","cpu.v=wordut; lni;"} }, |  | ||||||
| 	{ mnem="ldp *s+imm8", opcode=0x7A, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} }, |  | ||||||
| 	{ mnem="ldq *s+imm8", opcode=0x7B, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} }, |  | ||||||
| 	{ mnem="stp *s+imm8", opcode=0x7E, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurPH","instrSub2"}, {"storeStackRel162","alurPL","instrSub3"}, {"instrNext"}, desc="*S+imm8=P", ccode={"loadimmedt","storestackrel161(cpu.p);","storestackrel162(cpu.p);","lni;"} }, |  | ||||||
| 	{ mnem="stq *s+imm8", opcode=0x7F, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurQH","instrSub2"}, {"storeStackRel162","alurQL","instrSub3"}, {"instrNext"}, desc="*S+imm8=Q", ccode={"loadimmedt","storestackrel161(cpu.q);","storestackrel162(cpu.q);","lni;"} }, |  | ||||||
| 	{ mnem="ldp *imm16" , opcode=0x68, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU","adwIncUT","adwSaveP","instrSub3"}, {"adrlP","loadRegT","instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0x69 |  | ||||||
| 	{ mnem="ldq *imm16" , opcode=0x6A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU","adwIncUT","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT","instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0x6B |  | ||||||
| 	{ mnem="stp *imm16" , opcode=0x6C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT","alurPH","instrSub3"}, {"storeUT","adrInc","alurPL","instrSub4"}, {"instrNext"}, desc="*imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;"} }, -- 0x6D |  | ||||||
| 	{ mnem="stq *imm16" , opcode=0x6E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT","alurQH","instrSub3"}, {"storeUT","adrInc","alurQL","instrSub4"}, {"instrNext"}, desc="*imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;"} }, -- 0x6F |  | ||||||
| 	{ mnem="ldp *p"     , opcode=0x92, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, |  | ||||||
| 	{ mnem="ldq *p"     , opcode=0x93, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.q=wordut; lni;"} }, |  | ||||||
| 	{ mnem="ldp *q"     , opcode=0x94, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.p=wordut; lni;"} }, |  | ||||||
| 	{ mnem="ldq *q"     , opcode=0x95, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, |  | ||||||
| 	{ mnem="stp *q"     , opcode=0x7C, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2"}, {"instrNext"}, desc="*Q=P", ccode={"storeq(hibyte(cpu.p));","storeqp1(lobyte(cpu.p));","lni;"} }, |  | ||||||
| 	{ mnem="stq *p"     , opcode=0x7D, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2"}, {"instrNext"}, desc="*P=Q", ccode={"storep(hibyte(cpu.q));","storepp1(lobyte(cpu.q));","lni;"} }, |  | ||||||
| 	{ mnem="ldq *p++"   , opcode=0xCC, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2","incP2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P++++", ccode={"cpu.u=loadpinc;","cpu.t=loadpinc;","cpu.q=wordut; lni;"} }, |  | ||||||
| 	{ mnem="ldp *q++"   , opcode=0xCD, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2","incQ2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q++++", ccode={"cpu.u=loadqinc;","cpu.t=loadqinc;","cpu.p=wordut; lni;"} }, |  | ||||||
| 	{ mnem="stp *q++"   , opcode=0xCE, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2","incQ2"}, {"instrNext"}, desc="*Q++++=P", ccode={"storeqinc(hibyte(cpu.p));","storeqinc(lobyte(cpu.p));","lni;"} }, |  | ||||||
| 	{ mnem="stq *p++"   , opcode=0xCF, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2","incP2"}, {"instrNext"}, desc="*P++++=Q", ccode={"storepinc(hibyte(cpu.q));","storepinc(lobyte(cpu.q));","lni;"} }, |  | ||||||
| 	 |  | ||||||
| 	{ category = "Moves", catlet="M" }, |  | ||||||
| 	{ mnem="lda b"      , opcode=0x80, {"alurB" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=B", ccode={"cpu.a=cpu.b; lni;"} }, |  | ||||||
| 	{ mnem="lda c"      , opcode=0x81, {"alurC" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=C", ccode={"cpu.a=cpu.c; lni;"} }, |  | ||||||
| 	{ mnem="ldb a"      , opcode=0x82, {"alurA" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=A", ccode={"cpu.b=cpu.a; lni;"} }, |  | ||||||
| 	{ mnem="ldb c"      , opcode=0x83, {"alurC" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=C", ccode={"cpu.b=cpu.c; lni;"} }, |  | ||||||
| 	{ mnem="ldc a"      , opcode=0x84, {"alurA" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=A", ccode={"cpu.c=cpu.a; lni;"} }, |  | ||||||
| 	{ mnem="ldc b"      , opcode=0x85, {"alurB" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=B", ccode={"cpu.c=cpu.b; lni;"} }, |  | ||||||
| 	{ mnem="lda pl"     , opcode=0x86, {"alurPL","aluOpMov","aluSaveA","instrNext"}, desc="A=P&FF", ccode={"cpu.a=lobyte(cpu.p); lni;"} }, |  | ||||||
| 	{ mnem="lda ph"     , opcode=0x87, {"alurPH","aluOpMov","aluSaveA","instrNext"}, desc="A=P>>8", ccode={"cpu.a=hibyte(cpu.p); lni;"} }, |  | ||||||
| 	{ mnem="lda ql"     , opcode=0x88, {"alurQL","aluOpMov","aluSaveA","instrNext"}, desc="A=Q&FF", ccode={"cpu.a=lobyte(cpu.q); lni;"} }, |  | ||||||
| 	{ mnem="lda qh"     , opcode=0x89, {"alurQH","aluOpMov","aluSaveA","instrNext"}, desc="A=Q>>8", ccode={"cpu.a=hibyte(cpu.q); lni;"} }, |  | ||||||
| 	{ mnem="ldb pl"     , opcode=0x37, {"alurPL","aluOpMov","aluSaveB","instrNext"}, desc="B=P&FF", ccode={"cpu.b=lobyte(cpu.p); lni;"} }, |  | ||||||
| 	{ mnem="ldc ph"     , opcode=0x38, {"alurPH","aluOpMov","aluSaveC","instrNext"}, desc="C=P>>8", ccode={"cpu.c=hibyte(cpu.p); lni;"} }, |  | ||||||
| 	{ mnem="ldb ql"     , opcode=0x39, {"alurQL","aluOpMov","aluSaveB","instrNext"}, desc="B=Q&FF", ccode={"cpu.b=lobyte(cpu.q); lni;"} }, |  | ||||||
| 	{ mnem="ldc qh"     , opcode=0x3A, {"alurQH","aluOpMov","aluSaveC","instrNext"}, desc="C=Q>>8", ccode={"cpu.c=hibyte(cpu.q); lni;"} }, |  | ||||||
| 	{ mnem="ldp q"      , opcode=0x8A, {"adwlQ" ,           "adwSaveP","instrNext"}, desc="P=Q", ccode={"cpu.p=cpu.q; lni;"} }, |  | ||||||
| 	{ mnem="ldp s"      , opcode=0x8B, {"adwlS" ,           "adwSaveP","instrNext"}, desc="P=S", ccode={"cpu.p=cpu.s; lni;"} }, |  | ||||||
| 	{ mnem="ldp v"      , opcode=0x8C, {"adwlV" ,           "adwSaveP","instrNext"}, desc="P=V", ccode={"cpu.p=cpu.v; lni;"} }, |  | ||||||
| 	{ mnem="ldp i"      , opcode=0x8D, {"adwlI" ,           "adwSaveP","instrNext"}, desc="P=I", ccode={"cpu.p=cpu.i; lni;"} }, |  | ||||||
| 	{ mnem="ldp cb"     , opcode=0x91, {"adwrCB",           "adwSaveP","instrNext"}, desc="P=(C<<8)+B", ccode={"cpu.p=wordcb; lni;"} }, |  | ||||||
| 	{ mnem="ldq cb"     , opcode=0xE0, {"adwrCB",           "adwSaveQ","instrNext"}, desc="Q=(C<<8)+B", ccode={"cpu.q=wordcb; lni;"} }, |  | ||||||
| 	{ mnem="ldq p"      , opcode=0x8E, {"adwlP" ,           "adwSaveQ","instrNext"}, desc="Q=P", ccode={"cpu.q=cpu.p; lni;"} }, |  | ||||||
| 	{ mnem="lds p"      , opcode=0x8F, {"adwlP" ,           "adwSaveS","instrNext"}, desc="S=P", ccode={"cpu.s=cpu.p; lni;"} }, |  | ||||||
| 	{ mnem="ldv p"      , opcode=0x90, {"adwlP" ,           "adwSaveV","instrNext"}, desc="V=P", ccode={"cpu.v=cpu.p; lni;"} }, |  | ||||||
| }, |  | ||||||
|  |  | ||||||
| aliases = { |  | ||||||
| 	["jpz imm8"] = {"jeq imm8"}, |  | ||||||
| 	["jnz imm8"] = {"jne imm8"}, |  | ||||||
| 	["jmp q"   ] = {"ret"     }, |  | ||||||
| }, |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,88 +0,0 @@ | |||||||
| 。 A1 |  | ||||||
| 「 A2 |  | ||||||
| 」 A3 |  | ||||||
| 、 A4 |  | ||||||
| ・ A5 |  | ||||||
| ヲ A6 |  | ||||||
| ァ A7 |  | ||||||
| ィ A8 |  | ||||||
| ゥ A9 |  | ||||||
| ェ AA |  | ||||||
| ォ AB |  | ||||||
| ャ AC |  | ||||||
| ュ AD |  | ||||||
| ョ AE |  | ||||||
| ッ AF |  | ||||||
| ー B0 |  | ||||||
| ア B1 |  | ||||||
| イ B2 |  | ||||||
| ウ B3 |  | ||||||
| エ B4 |  | ||||||
| オ B5 |  | ||||||
| カ B6 |  | ||||||
| キ B7 |  | ||||||
| ク B8 |  | ||||||
| ケ B9 |  | ||||||
| コ BA |  | ||||||
| サ BB |  | ||||||
| シ BC |  | ||||||
| ス BD |  | ||||||
| セ BE |  | ||||||
| ソ BF |  | ||||||
| タ C0 |  | ||||||
| チ C1 |  | ||||||
| ツ C2 |  | ||||||
| テ C3 |  | ||||||
| ト C4 |  | ||||||
| ナ C5 |  | ||||||
| ニ C6 |  | ||||||
| ヌ C7 |  | ||||||
| ネ C8 |  | ||||||
| ノ C9 |  | ||||||
| ハ CA |  | ||||||
| ヒ CB |  | ||||||
| フ CC |  | ||||||
| ヘ CD |  | ||||||
| ホ CE |  | ||||||
| マ CF |  | ||||||
| ミ D0 |  | ||||||
| ム D1 |  | ||||||
| メ D2 |  | ||||||
| モ D3 |  | ||||||
| ヤ D4 |  | ||||||
| ユ D5 |  | ||||||
| ヨ D6 |  | ||||||
| ラ D7 |  | ||||||
| リ D8 |  | ||||||
| ル D9 |  | ||||||
| レ DA |  | ||||||
| ロ DB |  | ||||||
| ワ DC |  | ||||||
| ン DD |  | ||||||
| ゛ DE |  | ||||||
| ゜ DF |  | ||||||
| ガ B6 DE |  | ||||||
| ギ B7 DE |  | ||||||
| グ B8 DE |  | ||||||
| ゲ B9 DE |  | ||||||
| ゴ BA DE |  | ||||||
| ザ BB DE |  | ||||||
| ジ BC DE |  | ||||||
| ズ BD DE |  | ||||||
| ゼ BE DE |  | ||||||
| ゾ BF DE |  | ||||||
| ダ C0 DE |  | ||||||
| ヂ C1 DE |  | ||||||
| ヅ C2 DE |  | ||||||
| デ C3 DE |  | ||||||
| ド C4 DE |  | ||||||
| バ CA DE |  | ||||||
| ビ CB DE |  | ||||||
| ブ CC DE |  | ||||||
| ベ CD DE |  | ||||||
| ボ CE DE |  | ||||||
| パ CA DF |  | ||||||
| ピ CB DF |  | ||||||
| プ CC DF |  | ||||||
| ペ CD DF |  | ||||||
| ポ CE DF |  | ||||||
		Reference in New Issue
	
	Block a user