local resolveLabel = function (str) if str == "ft_vibrato_table" then return "VIBRATO" end if str == "ft_note_table_vrc7_l" then return "SNDCHIP_VRC7" end local chip = string.upper(string.match(str, "ft_periods_(.*)")) if chip == "SAWTOOTH" then chip = "VRC6" elseif chip == "NTSC" then chip = "NONE" elseif chip == "PAL" then chip = "2A07" end return "SNDCHIP_" .. chip end local build = function (chip) print("Building NSF driver for " .. chip .. "...") os.execute([[ca65 ../driver.s -l out_]]..chip..[[.lst -D USE_]]..chip..[[ -D PACKAGE]]) os.execute([[ld65 -o c0_]]..chip..[[.bin ../driver.o -C c0.cfg]]) os.execute([[ld65 -o c1_]]..chip..[[.bin ../driver.o -C c1.cfg]]) local adr = {} local pos = {} for str in io.lines("out_"..chip..".lst") do local hex, used, ident, colon = string.match(str, "(......).....(..).*%f[_%w]([_%w]*)(:?).*;; Patch") if hex then hex = tonumber(hex, 16) used = used == "A9" colon = colon == ":" ident = resolveLabel(ident) if colon then -- ASM label; add to frequency table pos[ident] = hex elseif used then -- ASM jump; remove entry from reloc table adr[hex] = ident if ident == "SNDCHIP_VRC7" and chip == "VRC7" or chip == "ALL" then adr[-1] = ident end end end end os.remove("out_"..chip..".lst") local in1 = io.open("c1_"..chip..".bin", "rb") local in2 = io.open("c0_"..chip..".bin", "rb") local relStr = "" local hedStr = "" local tRel, tHed = {}, {} while true do local x, y = in1:read(1), in2:read(1) if not x then break else x, y = string.byte(x), string.byte(y) end if x == y then tHed[#tHed + 1] = string.format("0x%02X,", x) else tHed[#tHed + 1] = string.format("0x%02X,", x - 0xC1) if not adr[in1:seek() - 6] then tRel[#tRel + 1] = string.format("%d,", in1:seek() - 2) end if #tRel == 20 then relStr = relStr .. "\t" .. table.concat(tRel, " ") .. "\n" tRel = {} end end if #tHed == 16 then hedStr = hedStr .. "\t" .. table.concat(tHed, " ") .. "\n" tHed = {} end end if #tRel > 0 then relStr = relStr .. "\t" .. table.concat(tRel, " ") .. "\n" end if #tHed > 0 then hedStr = hedStr .. "\t" .. table.concat(tHed, " ") .. "\n" end local final = io.open("output/drv_" .. string.lower(chip) .. ".h", "w") final:write("const unsigned char DRIVER_", chip, "[] = {\t\t// // //\n") final:write(hedStr) final:write("};\n\nconst int DRIVER_RELOC_WORD_", chip, "[] = {\n") final:write(relStr) final:write("};\n\nconst int DRIVER_FREQ_TABLE_", chip, "[] = {\n") for k, v in pairs(adr) do final:write("\t") final:write(k == -1 and " -1" or string.format("0x%04X", k)) final:write(string.format(", 0x%04X, %s,\n", pos[v], v)) end final:write("};\n\nconst unsigned int VIBRATO_TABLE_LOCATION_", chip, string.format(" = 0x%X;", pos["VIBRATO"])) in1:close() in2:close() final:close() os.remove("c0_"..chip..".bin") os.remove("c1_"..chip..".bin") end for _, v in pairs {"2A03", "VRC6", "VRC7", "MMC5", "FDS", "N163", "S5B", "ALL"} do build(v) end print("All driver headers created in " .. tonumber(os.clock()) .. " seconds.") os.execute("pause")