8608/emulator/gendefs.lua
2024-08-11 02:39:37 -06:00

72 lines
1.8 KiB
Lua

-- gendefs.lua
-- This code generates instructions_gen.c from the instruction definitions in 8608-instructions.lua.
-- It is executed as part of the compilation process for the 8608 emulator DLL.
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
__ARCH_INCLUDED = true
local arch = dofile("../8608-definition.lua")
arch.instructions = dofile("../8608-instructions.lua")
local fo = io.open("instructions_gen.c", "w")
fo:write(ccodeFromArch(arch))
fo:close()