-- 8608-definition.lua -- This file contains information about the instruction set and microcode for the 8608 architecture. -- It is used by generate-architecture.lua, alongside the instruction definitions in 8608-instructions.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. local arch8608 = { -- 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", "_", "adrr2A", "adwrhU", "adwrhC", "adwrlT", "adwrTX", "adwrlA", "adwrAX", "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", "adrrm4", "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"}, loadStackRel = {"adrrlT","loadReg"}, loadStackRelT = {"loadStackRel","memSaveT"}, loadStackRelU = {"loadStackRel","memSaveU"}, loadStackRel161 = {"loadStackRel", "memSaveU"}, loadStackRel162 = {"loadStackRel","adrInc","memSaveT"}, --storeStackRel = {"adrlS","adrrTX","storeReg"}, storeStackRel = {"adrrlT","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"}, storeUTP = {"adrrUT","adrlP","storeReg"}, storeUTQ = {"adrrUT","adrlQ","storeReg"}, memSaveFlags = {"memSaveNZ"}, load16FE1 = {"adrrm4","adrr2","load161"}, load16FE2 = {"adrrm4","adrr2","load162"}, load16FC1 = {"adrrm4", "load161"}, load16FC2 = {"adrrm4", "load162"}, 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"}, saveIV = {"adwlI","adwSaveV"}, jmpRelT = {"instrNext","adrrTX"}, jmpAbs = {"base","loadInstr","adrSaveI"}, jmpAbsUT = {"jmpAbs","adrrUT"}, jmpAbsP = {"jmpAbs","adrlP"}, jmpAbsQ = {"jmpAbs","adrlQ"}, jmpAbsV = {"jmpAbs","adrlV"}, 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", "intFlgClk", "irqFlgClk", "runFlgClk","runFlgVal", }, }, -- Shortcuts for instruction descriptions -- These strings will be substituted into instruction descriptions wherever their [key] occurs descShortcuts = { {"%mem", "a value from memory"}, {"%mem16", "a value from memory"}, {"%imm8", "a given 8-bit value"}, {"%imm16", "a given 16-bit value"}, {"%A", "the value in the A register"}, {"%B", "the value in the B register"}, {"%C", "the value in the C register"}, {"%xInc16", "increment the X register by 2 bytes"}, {"%yInc16", "increment the Y register by 2 bytes"}, {"%xInc", "increment the X register"}, {"%yInc", "increment the Y register"}, {"%Xin16", "the 16-bit value in memory at the address in X"}, {"%Yinn16", "the 16-bit value in memory at the address in Y"}, {"%xIn", "the value in memory at the address in X"}, {"%yIn", "the value in memory at the address in Y"}, {"%XofsIn16", "the 16-bit value in memory at the address (X plus a given 8-bit offset)"}, {"%YofsIn16", "the 16-bit value in memory at the address (Y plus a given 8-bit offset)"}, {"%XofsIn", "the value in memory at the address (X plus a given 8-bit offset)"}, {"%YofsIn", "the value in memory at the address (Y plus a given 8-bit offset)"}, {"%Xofs", "the address (X plus a given 8-bit offset)"}, {"%Yofs", "the address (Y plus a given 8-bit offset)"}, {"%X", "the 16-bit value in the X register"}, {"%Y", "the 16-bit value in the Y register"}, {"%adrX", "the address in X"}, {"%adrY", "the address in Y"}, {"%zpgIn16", "the 16-bit value in memory at a given 8-bit address"}, {"%zpgIn", "the value in memory at a given 8-bit address"}, {"%zpg", "an given 8-bit address"}, {"%absIn16", "the 16-bit value in memory at a given 16-bit address"}, {"%absIn", "the value in memory at a given 16-bit address"}, {"%abs", "a given 16-bit address"}, {"%alu", "and store the result in the A register"}, {"%flags", " and set the Carry Flag and Zero Flag according to the result"}, {"%zflag", " and set the Zero Flag according to the result"}, {"%cmp", "Set the Carry Flag and Zero Flag according to the result of subtracting"}, {"%brel", "Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the program"}, {"%brelc", "Otherwise, do nothing"}, {"%if", "If the result of the last math operation was"}, {"%zFlgMem", "and set the Zero Flag according to the value loaded"}, }, -- Aliases for instructions -- Used to generate the assembler definitions. -- imm8neg instead of imm8 means the immediate value will be negated when assembling. transformMnemonic = function(mnem) mnem = mnem:gsub("zpg", "imm8u") mnem = mnem:gsub("ofs", "imm8u") mnem = mnem:gsub("rel", "imm8rel") mnem = mnem:gsub("abs", "imm16") mnem = mnem:gsub("ind", "imm16") mnem = mnem:gsub("#", "#imm8") mnem = mnem:gsub("#imm8#imm8", "#imm16") return mnem end, aliases = { -- ["jmp q" ] = {"ret" }, ["ADD imm8" ] = {"SUB imm8neg"}, -- ["adb imm8" ] = {"sbb imm8neg"}, -- ["adc imm8" ] = {"sbc imm8neg"}, ["ADC imm8" ] = {"SBC 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 ]], } return arch8608