diff --git a/host/scripts/inlretro.lua b/host/scripts/inlretro.lua index 25d3b87..60dd98d 100644 --- a/host/scripts/inlretro.lua +++ b/host/scripts/inlretro.lua @@ -97,6 +97,37 @@ function main () --local cart_console = "GBA" --local cart_console = "SMS" +-- ===================================================== +-- USERS: Change process options to define interactions with cartridge. +-- +-- Note: RAM is not present in all carts, related settings +-- will be ignored by mappers that don't support RAM. +-- ===================================================== + local process_opts = { + test = true, + read = true, + erase = false, + program = false, + verify = false, + dumpram = false, + writeram = false, + dumpfile = "ignore/dump.bin", + flashfile = "", + verifyfile = "", + dumpram_filename = "", + writeram_filename = "", + } +-- ===================================================== +-- USERS: Change console options to define interactions with cartridge. +-- These options can vary from cartridge to cartridge depending on specific hardware it contains. +-- ===================================================== + local console_opts = { + mirror = "V", -- Only used by NROM, also possible to set to "H" + prg_rom_size_kb = 128, -- Size of NES PRG-ROM in kb + chr_rom_size_kb = 128, -- Size of NES CHR-ROM in kb + wram_size_kb = 0, -- Size of NES wram in kb + } + local rv -- rv = dict.pinport( "DATA_SET", 0xAA ) -- rv = dict.pinport( "DATA_RD" ) @@ -291,101 +322,10 @@ function main () --set rom types and sizes --perform desired operation --CART and programmer should be in a RESET condition upon calling the specific script - - --DUALPORT - --curcart.process( true, false, false, false, false, "ignore/dump.bin", "ignore/ddug2.bin", "ignore/verifyout.bin") - --MM2 - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/mm2_i0.prg", "ignore/verifyout.bin") - --curcart.process( true, true, false, false, false, "ignore/dump.bin", "ignore/mm2_i0.prg", "ignore/verifyout.bin") - - --UNROM512 mapper 30 - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/BBC_nonJW.bin", "ignore/verifyout.bin") - --curcart.process( true, false, false, false, false, "ignore/dump.bin", "ignore/MysticOrigins.prg", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/NESmaker.nes", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/tb_map30.prg", "ignore/verifyout.bin") - - - --COLOR NINJA - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/ninja.bin", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/alfonzo.bin", "ignore/verifyout.bin") - --A53 PLCC - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/a53v1_SBR2.prg", "ignore/verifyout.bin") - --A53 tssop - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/a53vol3.prg", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/2a03puritans_RE.prg", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/a53vol3_giftmsg_0xFF.prg", "ignore/verifyout.bin") - --curcart.process( true, false, false, false, false, "ignore/dump.bin", "ignore/writethe actual message.prg", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/mappertests/test28-8Mbit.prg", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/mappertests/M28_P1M_CR32K.prg", "ignore/verifyout.bin") - - --easy NSF tssop - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/2a03puritans_RE.prg", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/rndm2_1MB.prg", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/pico2015_RELEASE_1MB.prg", "ignore/verifyout.bin") - - - - - --later scripts which don't require specific firmware functions - --goal is to convert scripts above to be more like the ones below now that - --have a better idea of what works best and minimizing firmware compilation and updates - - --NROM - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/M0_P32K_C8K.bin", "ignore/verifyout.bin") - --curcart.process( true, true, true, true, true, "ignore/dump.bin", "ignore/ddug2.bin", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/NTB_RE.bin", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/MM_demo.bin", "ignore/verifyout.bin") - --curcart.process( true, true, true, true, true, "ignore/dump.bin", "ignore/NnD.bin", "ignore/verifyout.bin", "V") - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/DEMO.bin", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/NES_hb_present.bin", "ignore/verifyout.bin") - - --MMC1 - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/P256K.bin", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/BB_sgrom.prg", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/Zelda2.bin", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/Zelda2_doubleprg.bin", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/alfonzoMMC1.bin", "ignore/verifyout.bin") - --curcart.process( true, false, false, false, false, nil, nil, nil, true, false, "ignore/ramdump.bin", "ignore/zelda2_pauliscool.bin") - - - --UxROM - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/AFB_128.prg", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/nomolosFINAL.prg", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/owlia_revb.prg", "ignore/verifyout.bin") - --curcart.process( true, false, false, false, false, "ignore/dump.bin", "ignore/rushnattack.prg", "ignore/verifyout.bin") - --curcart.process( true, false, false, false, false, "ignore/dump.bin", "ignore/TDfix.prg", "ignore/verifyout.bin") - - --CNROM - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/galf.bin", "ignore/verifyout.bin") - - --MMC3 - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/P512K_C256K.bin", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/P256K_C128K.bin", "ignore/verifyout.bin") - --curcart.process( true, true, true, false, true, "ignore/dump.bin", "ignore/kirby.nes", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/kirby.bin", "ignore/verifyout.bin", false, false, "ignore/ramdump.bin", "ignore/ramwrite.bin") - --curcart.process( true, false, false, false, false, "ignore/dump.bin", "ignore/kirby.bin", "ignore/verifyout.bin", true, true, "ignore/ramdump.bin", "ignore/kirby3xSave.bin") - - --MMC2 - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/punchout.bin", "ignore/verifyout.bin") - --curcart.process( true, false, false, false, false, "ignore/dump.bin", "ignore/P256K_C128K.bin", "ignore/verifyout.bin") - --MMC4 - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/fe.bin", "ignore/verifyout.bin") - - --COLOR DREAMS - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/multicart_mojontalesFINAL.prg", "ignore/verifyout.bin") - - --BNROM - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/lizard_PG.prg", "ignore/verifyout.bin") - curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/lizard_v2.prg", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/hh85.prg", "ignore/verifyout.bin") - - --FME7 - --curcart.process( true, false, true, true, false, "ignore/dump.bin", "ignore/P256K_C256K.bin", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/gimmick.bin", "ignore/verifyout.bin") - --curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/barcode_prgx2.bin", "ignore/verifyout.bin") - - --curcart.process( true, false, false, false, false, nil, nil, nil, true, true, "ignore/ramdump.bin", "ignore/kirby3xSave.bin") + -- Perform requested operations with provided options. + curcart.process(process_opts, console_opts) + --[[ --FLASHING: --erase cart diff --git a/host/scripts/inlretro2.lua b/host/scripts/inlretro2.lua index 3706484..63d79f3 100644 --- a/host/scripts/inlretro2.lua +++ b/host/scripts/inlretro2.lua @@ -9,10 +9,13 @@ end -- Wrapper for managing NES/Famicom operations. -function nes_exec(mapper, dump_filename, flash_filename, verify_filename) +function nes_exec(mapper, dump_filename, flash_filename, verify_filename, ramdump_filename, ramwrite_filename, console_opts) local dict = require "scripts.app.dict" local nes = require "scripts.app.nes" + -- TODO: This should probably be one level up. + -- TODO: Ram probably needs a verify file as well? + -- Always test! local do_test = true @@ -27,10 +30,48 @@ function nes_exec(mapper, dump_filename, flash_filename, verify_filename) -- If a verify_filename was provided, dump data from cartridge after flash to a file. local do_verify = not isempty(verify_filename) - -- TODO: Add other mappers. + local do_dumpram = not isempty(ramdump_filename) + local do_writeram = not isempty(ramwrite_filename) + + -- Pack main process state into table. + local process_opts = { + test = do_test, + read = do_read, + dump_filename = dump_filename, + erase = do_erase, + program = do_program, + program_filename = flash_filename, + verify = do_verify, + verify_filename = verify_filename, + dumpram = do_dumpram, + dumpram_filename = ramdump_filename, + writeram = do_writeram, + writeram_filename = ramwrite_filename, + } + + -- Defensively filter out any console options that are irrelevant to NES support. + -- This will matter more when software support exists for other consoles. + local nes_opts = { + wram_size_kb = console_opts["wram_size_kb"], + prg_rom_size_kb = console_opts["prg_rom_size_kb"], + chr_rom_size_kb = console_opts["chr_rom_size_kb"], + mirror = nil -- Used by NROM mapper only, "H" or "V". + } + local mappers = { + action53_tsop = require "scripts.nes.action53_tsop", + action53 = require "scripts.nes.action53", + bnrom = require "scripts.nes.bnrom", + cdream = require "scripts.nes.cdream", + cninja = require "scripts.nes.cninja", + cnrom = require "scripts.nes.cnrom", + dualport = require "scripts.nes.dualport", + easynsf = require "scripts.nes.easyNSF", + fme7 = require "scripts.nes.fme7", + mapper30 = require "scripts.nes.mapper30", mmc1 = require "scripts.nes.mmc1", mmc3 = require "scripts.nes.mmc3", + mmc4 = require "scripts.nes.mmc4", nrom = require "scripts.nes.nrom", unrom = require "scripts.nes.unrom" } @@ -46,7 +87,7 @@ function nes_exec(mapper, dump_filename, flash_filename, verify_filename) -- Attempt requested operations with hardware! -- TODO: Do plumbing for interacting with RAM. - m.process(do_test, do_read, do_erase, do_program, do_verify, dump_filename, flash_filename, verify_filename) + m.process(process_opts, console_opts) end end @@ -59,6 +100,9 @@ function main() -- dump_filename: string, filename used for writing dumped data. -- flash_filename: string, filename containing data to write cartridge. -- verify_filename: string, filename used for writing back data written to cartridge for verification. + -- nes_prg_rom_size_kb: int, size of cartridge PRG-ROM in kb. + -- nes_chr_rom_size_kb: int, size of cartridge CHR-ROM in kb. + -- nes_wram_size_kb: int, size of cartridge WRAM in kb. -- TODO: Add SNES support, as it appears to be currently usable? local consoles = { @@ -68,7 +112,14 @@ function main() if f == nil then print("UNSUPPORTED CONSOLE") else - f(mapper_name, dump_filename, flash_filename, verify_filename) + -- TODO: Make anything console specific a dict to make function signatures less terrible. + local console_opts = { + wram_size_kb = nes_wram_size_kb, + prg_rom_size_kb = nes_prg_rom_size_kb, + chr_rom_size_kb = nes_chr_rom_size_kb + } + + f(mapper_name, dump_filename, flash_filename, verify_filename, ramdump_filename, ramwrite_filename, console_opts) end end diff --git a/host/scripts/nes/action53.lua b/host/scripts/nes/action53.lua index 28f6cf6..3c14a7c 100644 --- a/host/scripts/nes/action53.lua +++ b/host/scripts/nes/action53.lua @@ -72,11 +72,19 @@ end --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile) +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] local rv = nil local file - + -- TODO: Handle variable ROM sizes. --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/action53_tsop.lua b/host/scripts/nes/action53_tsop.lua index 6b8e064..092ee0a 100644 --- a/host/scripts/nes/action53_tsop.lua +++ b/host/scripts/nes/action53_tsop.lua @@ -199,11 +199,19 @@ end --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile) +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] local rv = nil local file - + -- TODO: Handle variable ROM sizes. --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/bnrom.lua b/host/scripts/nes/bnrom.lua index d36aa40..fc6c1e2 100644 --- a/host/scripts/nes/bnrom.lua +++ b/host/scripts/nes/bnrom.lua @@ -210,13 +210,22 @@ end --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile) +--local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile) +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] local rv = nil local file - local prg_size = 512 - local chr_size = 0 - local wram_size = 0 + local prg_size = console_opts["prg_rom_size_kb"] + local chr_size = console_opts["chr_rom_size_kb"] + local wram_size = console_opts["wram_size_kb"] --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/cdream.lua b/host/scripts/nes/cdream.lua index 72a8103..0bd1e9e 100644 --- a/host/scripts/nes/cdream.lua +++ b/host/scripts/nes/cdream.lua @@ -453,13 +453,21 @@ end --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile) +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] local rv = nil local file - local prg_size = 512 - local chr_size = 128 - local wram_size = 0 + local prg_size = console_opts["prg_rom_size_kb"] + local chr_size = console_opts["chr_rom_size_kb"] + local wram_size = console_opts["wram_size_kb"] --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/cninja.lua b/host/scripts/nes/cninja.lua index c70f8c1..10bcb84 100644 --- a/host/scripts/nes/cninja.lua +++ b/host/scripts/nes/cninja.lua @@ -68,10 +68,19 @@ end --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile) +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] local rv = nil local file + -- TODO: Support variable ROM sizes. --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/cnrom.lua b/host/scripts/nes/cnrom.lua index be489ba..0d23d11 100644 --- a/host/scripts/nes/cnrom.lua +++ b/host/scripts/nes/cnrom.lua @@ -360,13 +360,21 @@ end --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile) +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] local rv = nil local file - local prg_size = 32 - local chr_size = 32 - local wram_size = 0 + local prg_size = console_opts["prg_rom_size_kb"] + local chr_size = console_opts["chr_rom_size_kb"] + local wram_size = console_opts["wram_size_kb"] --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/dualport.lua b/host/scripts/nes/dualport.lua index 9f2eb8d..77132a3 100644 --- a/host/scripts/nes/dualport.lua +++ b/host/scripts/nes/dualport.lua @@ -151,10 +151,19 @@ end --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile) - +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] + local rv = nil local file + -- TODO: Handle variable rom sizes. --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/easyNSF.lua b/host/scripts/nes/easyNSF.lua index b343caa..b35745e 100644 --- a/host/scripts/nes/easyNSF.lua +++ b/host/scripts/nes/easyNSF.lua @@ -71,11 +71,19 @@ end --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile) +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] local rv = nil local file - + -- TODO: Handle variable rom sizes. --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/fme7.lua b/host/scripts/nes/fme7.lua index d296899..ff79516 100644 --- a/host/scripts/nes/fme7.lua +++ b/host/scripts/nes/fme7.lua @@ -520,13 +520,26 @@ end --Cart should be in reset state upon calling this function -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile, dumpram, writeram, ramdumpfile, ramwritefile) +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] + -- FME7 has RAM capability present in some carts. + local dumpram = process_opts["dumpram"] + local ramdump_filename = process_opts["dumpram_filename"] + local writeram = process_opts["writeram"] + local ramwrite_filename = process_opts["writeram_filename"] local rv = nil local file - local prg_size = 256 - local chr_size = 256 - local wram_size = 8 + local prg_size = console_opts["prg_rom_size_kb"] + local chr_size = console_opts["chr_rom_size_kb"] + local wram_size = console_opts["wram_size_kb"] --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/mapper30.lua b/host/scripts/nes/mapper30.lua index 9c3b4b3..5a59ec6 100644 --- a/host/scripts/nes/mapper30.lua +++ b/host/scripts/nes/mapper30.lua @@ -47,11 +47,20 @@ end --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile) - +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] + local rv = nil - local file - local size = 512 + local file + -- TODO: Cleanup needed here, support chrrom, make this look more like other mapper scripts. + local size = console_opts["prg_rom_size_kb"] --local filetype = "nes" local filetype = "bin" diff --git a/host/scripts/nes/mmc1.lua b/host/scripts/nes/mmc1.lua index 049e02a..2377d7e 100644 --- a/host/scripts/nes/mmc1.lua +++ b/host/scripts/nes/mmc1.lua @@ -490,13 +490,26 @@ end --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile, dumpram, writeram, ramdumpfile, ramwritefile) +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] + -- MMC1 has RAM capability present in some carts. + local dumpram = process_opts["dumpram"] + local ramdump_filename = process_opts["dumpram_filename"] + local writeram = process_opts["writeram"] + local ramwrite_filename = process_opts["writeram_filename"] local rv = nil local file - local prg_size = 256 - local chr_size = 128 - local wram_size = 8 + local prg_size = console_opts["prg_rom_size_kb"] + local chr_size = console_opts["chr_rom_size_kb"] + local wram_size = console_opts["wram_size_kb"] --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/mmc3.lua b/host/scripts/nes/mmc3.lua index cea5351..327eda1 100644 --- a/host/scripts/nes/mmc3.lua +++ b/host/scripts/nes/mmc3.lua @@ -504,13 +504,26 @@ end --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile, dumpram, writeram, ramdumpfile, ramwritefile) +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] + -- MMC3 has RAM capability present in some carts. + local dumpram = process_opts["dumpram"] + local ramdump_filename = process_opts["dumpram_filename"] + local writeram = process_opts["writeram"] + local ramwrite_filename = process_opts["writeram_filename"] local rv = nil local file - local prg_size = 512 - local chr_size = 256 - local wram_size = 8 + local prg_size = console_opts["prg_rom_size_kb"] + local chr_size = console_opts["chr_rom_size_kb"] + local wram_size = console_opts["wram_size_kb"] --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/mmc4.lua b/host/scripts/nes/mmc4.lua index 7d6d93a..f965dd1 100644 --- a/host/scripts/nes/mmc4.lua +++ b/host/scripts/nes/mmc4.lua @@ -446,13 +446,26 @@ end --Cart should be in reset state upon calling this function -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile, dumpram, writeram, ramdumpfile, ramwritefile) +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] + -- MMC4 has RAM capability present in some carts. + local dumpram = process_opts["dumpram"] + local ramdump_filename = process_opts["dumpram_filename"] + local writeram = process_opts["writeram"] + local ramwrite_filename = process_opts["writeram_filename"] local rv = nil local file - local prg_size = 256 - local chr_size = 128 - local wram_size = 8 + local prg_size = console_opts["prg_rom_size_kb"] + local chr_size = console_opts["chr_rom_size_kb"] + local wram_size = console_opts["wram_size_kb"] --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/nrom.lua b/host/scripts/nes/nrom.lua index c2f6835..012b9ec 100644 --- a/host/scripts/nes/nrom.lua +++ b/host/scripts/nes/nrom.lua @@ -270,17 +270,24 @@ end - - --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile, mirror) +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] local rv = nil local file - local prg_size = 32 - local chr_size = 8 - local wram_size = 0 + local prg_size = console_opts["prg_rom_size_kb"] + local chr_size = console_opts["chr_rom_size_kb"] + local wram_size = console_opts["wram_size_kb"] + local mirror = console_opts["mirror"] --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/scripts/nes/unrom.lua b/host/scripts/nes/unrom.lua index 7f2cf5f..3e80da2 100644 --- a/host/scripts/nes/unrom.lua +++ b/host/scripts/nes/unrom.lua @@ -280,13 +280,21 @@ end --Cart should be in reset state upon calling this function --this function processes all user requests for this specific board/mapper -local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile) - +local function process(process_opts, console_opts) + local test = process_opts["test"] + local read = process_opts["read"] + local erase = process_opts["erase"] + local program = process_opts["program"] + local verify = process_opts["verify"] + local dumpfile = process_opts["dump_filename"] + local flashfile = process_opts["flash_filename"] + local verifyfile = process_opts["verify_filename"] + local rv = nil local file - local prg_size = 512 - local chr_size = 0 - local wram_size = 0 + local prg_size = console_opts["prg_rom_size_kb"] + local chr_size = console_opts["chr_rom_size_kb"] + local wram_size = console_opts["wram_size_kb"] --initialize device i/o for NES dict.io("IO_RESET") diff --git a/host/source/inlprog.c b/host/source/inlprog.c index b5ad550..d2c3809 100644 --- a/host/source/inlprog.c +++ b/host/source/inlprog.c @@ -31,15 +31,22 @@ // TODO: Finish HELP for all currently supported options. +// TODO: Migrate to argp for more descriptive flags. const char *HELP = "Usage: inlretro [options]\n\n"\ "Options:\n"\ + " -a [dumpram_filename]\tIf provided write ram to this filename\n"\ + " -b [writeram_filename]If provided write this file's contents to ram\n"\ " -c [console]\t\tConsole port, {NES}\n"\ " -d [dump_filename]\tIf provided, dump cartridge ROMs to this filename\n"\ + " -h\t\t\tDisplays this message.\n"\ " -m [mapper]\t\tNES console only, mapper ASIC on cartridge\n"\ " \t\t\t{mmc1,mmc3,nrom}\n"\ " -p [program_filename]\tIf provided, write this data to cartridge\n"\ " -s [lua_script]\tIf provided, use this script for main application logic\n"\ - " -h\t\t\tDisplays this message.\n"; + " -v [verify_filename]\tIf provided, writeback written rom to this filename\n" + " -w [wram_size_kb]\tNES-only, size of WRAM in kb\n"\ + " -x [prg_rom_size_kb]\tNES-only, size of PRG-ROM in kb\n"\ + " -y [chr_rom_size_kb]\tNES-only, size of CHR-ROM in kb\n"; // Struct used to control functionality. typedef struct { @@ -47,16 +54,31 @@ typedef struct { char *mapper_name; int display_help; + // NES Functionality + int chr_rom_size_kb; + int prg_rom_size_kb; + int wram_size_kb; + char *dump_filename; char *program_filename; + char *ramdump_filename; + char *ramwrite_filename; + char *verify_filename; + char *lua_filename; } INLOptions; +// Returns true if given number is a power of 2, and at least minimum size. +int isValidROMSize(int x, int min) { + return ((x & (x - 1)) == 0) && x >= min; +} + + // Parse options and flags, create struct to drive program. INLOptions* parseOptions(int argc, char *argv[]) { // lower case flags suggested for average user - const char *FLAG_FORMAT = "hc:d:m:p:s:"; + const char *FLAG_FORMAT = "a:b:hc:d:m:p:s:v:w:x:y:"; int index = 0; int rv = 0; // opterr = 0; @@ -97,6 +119,8 @@ INLOptions* parseOptions(int argc, char *argv[]) { // case 'n': n_flag = 1; break; // case 'e': e_flag = 1; break; // case 'f': f_flag = 1; break; + case 'a': opts->ramdump_filename = optarg; break; + case 'b': opts->ramwrite_filename = optarg; break; case 'h': opts->display_help = 1; break; // case 'i': i_flag = 1; break; // case 't': t_flag = 1; break; @@ -110,6 +134,10 @@ INLOptions* parseOptions(int argc, char *argv[]) { case 'm': opts->mapper_name = optarg; break; case 'p': opts->program_filename = optarg; break; case 's': opts->lua_filename = optarg; break; + case 'v': opts->verify_filename = optarg; break; + case 'w': opts->wram_size_kb = atoi(optarg); break; + case 'x': opts->prg_rom_size_kb = atoi(optarg); break; + case 'y': opts->chr_rom_size_kb = atoi(optarg); break; // case 'v': v_value = optarg; break; // case 'C': C_value = optarg; break; // case 'L': L_value = optarg; break; @@ -276,6 +304,27 @@ int main(int argc, char *argv[]) return 1; } + // Check for sane user input. + if (strcmp("NES", opts->console_name) == 0) { + // ROM sizes must be non-zero, power of 2, and greater than 16. + if (isValidROMSize(opts->prg_rom_size_kb, 16)) { + printf("PRG-ROM must be non-zero power of 2, 16kb or greater.\n"); + return 1; + } + // Not having CHR-ROM is normal for certain types of carts. + // TODO: Update these checks with known info about mappers/carts. + if (isValidROMSize(opts->chr_rom_size_kb, 8) || opts->chr_rom_size_kb == 0) { + printf("CHR-ROM must be zero or power of 2, 8kb or greater.\n"); + return 1; + } + + // Not having WRAM is very normal. + if (isValidROMSize(opts->wram_size_kb, 8) || opts->wram_size_kb == 0) { + printf("WRAM must be zero or power of 2, 8kb or greater.\n"); + return 1; + } + } + //Start up Lua L = lua_init(); @@ -343,6 +392,24 @@ int main(int argc, char *argv[]) lua_pushstring(L, opts->program_filename); lua_setglobal(L, "flash_filename"); + lua_pushstring(L, opts->verify_filename); + lua_setglobal(L, "verify_filename"); + + lua_pushstring(L, opts->ramdump_filename); + lua_setglobal(L, "ramdump_filename"); + + lua_pushstring(L, opts->ramwrite_filename); + lua_setglobal(L, "ramwrite_filename"); + + lua_pushinteger(L, opts->wram_size_kb); + lua_setglobal(L, "nes_wram_size_kb"); + + lua_pushinteger(L, opts->prg_rom_size_kb); + lua_setglobal(L, "nes_prg_rom_size_kb"); + + lua_pushinteger(L, opts->chr_rom_size_kb); + lua_setglobal(L, "nes_chr_rom_size_kb"); + // USB device is open, pass args and control over to Lua. // If lua_filename isn't set from args, use default script. char *DEFAULT_SCRIPT = "scripts/inlretro.lua";