Allow specifying rom size in kilobytes via CLI, do related plumbing to keep Kb as internal representation w/o breaking support for also accepting size in megabits. Cleanup gb scripts to remove unreachable code that was left around from their origin as nes scripts, migrate process()'s to be table driven, add support for gb in inlretro2.lua

This commit is contained in:
beyondcoast 2019-01-14 07:14:15 -06:00
parent a11940f93d
commit f899518989
8 changed files with 130 additions and 426 deletions

View File

@ -8,47 +8,14 @@ local dump = require "scripts.app.dump"
local flash = require "scripts.app.flash" local flash = require "scripts.app.flash"
-- file constants -- file constants
local mapname = "ROMONLY" local mapname = "MBC1"
-- local functions -- local functions
--read PRG-ROM flash ID local function unsupported(operation)
local function rom_manf_id( debug ) print("\nUNSUPPORTED OPERATION: \"" .. operation .. "\" not implemented yet for Gameboy - ".. mapname .. "\n")
--init_mapper()
if debug then print("reading PRG-ROM manf ID") end
--enter software mode
--ROMSEL controls PRG-ROM /OE which needs to be low for flash writes
--So unlock commands need to be addressed below $8000
--DISCRETE_EXP0_PRGROM_WR doesn't toggle /ROMSEL by definition though, so A15 is unused
-- 15 14 13 12
-- 0x5 = 0b 0 1 0 1 -> $5555
-- 0x2 = 0b 0 0 1 0 -> $2AAA
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0xAA)
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x2AAA, 0x55)
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0x90)
--read manf ID
local rv = dict.nes("NES_CPU_RD", 0x8000)
if debug then print("attempted read PRG-ROM manf ID:", string.format("%X", rv)) end
--read prod ID
rv = dict.nes("NES_CPU_RD", 0x8001)
if debug then print("attempted read PRG-ROM prod ID:", string.format("%X", rv)) end
--exit software
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x8000, 0xF0)
--verify exited
-- rv = dict.nes("NES_CPU_RD", 0x8001)
-- if debug then print("attempted read PRG-ROM prod ID:", string.format("%X", rv)) end
end end
--dump the ROM --dump the ROM
local function dump_rom( file, rom_size_KB, debug ) local function dump_rom( file, rom_size_KB, debug )
@ -88,194 +55,60 @@ local function dump_rom( file, rom_size_KB, debug )
end end
--write a single byte to ROM flash
local function wr_flash_byte(addr, value, debug)
if (addr < 0x8000 or addr > 0xFFFF) then
print("\n ERROR! flash write to PRG-ROM", string.format("$%X", addr), "must be $8000-FFFF \n\n")
return
end
--send unlock command and write byte
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0xAA)
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x2AAA, 0x55)
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0xA0)
dict.nes("DISCRETE_EXP0_PRGROM_WR", addr, value)
local rv = dict.nes("NES_CPU_RD", addr)
local i = 0
while ( rv ~= value ) do
rv = dict.nes("NES_CPU_RD", addr)
i = i + 1
end
if debug then print(i, "naks, done writing byte.") end
--TODO handle timeout for problems
--TODO return pass/fail/info
end
--fast host flash one bank at a time...
--this is controlled from the host side one bank at a time
--but requires specific firmware MMC3 flashing functions
--there is super slow version commented out that doesn't require MMC3 specific firmware code
local function flash_rom(file, rom_size_KB, debug)
--init_mapper()
--test some bytes
--wr_flash_byte(0x8000, 0xA5, true)
--wr_flash_byte(0xFFFF, 0x5A, true)
print("\nProgramming PRG-ROM flash")
--most of this is overkill for NROM, but it's how we want to handle things for bigger mappers
local base_addr = 0x8000 --writes occur $8000-9FFF
local bank_size = 32*1024 --MMC3 8KByte per PRG bank
local buff_size = 1 --number of bytes to write at a time
local cur_bank = 0
local total_banks = rom_size_KB*1024/bank_size
local byte_num --byte number gets reset for each bank
local byte_str, data, readdata
while cur_bank < total_banks do
if (cur_bank %8 == 0) then
print("writting PRG bank: ", cur_bank, " of ", total_banks-1)
end
--program the entire bank's worth of data
flash.write_file( file, 32, mapname, "PRGROM", false )
cur_bank = cur_bank + 1
end
print("Done Programming PRG-ROM flash")
end
-- Cart should be in reset state upon calling this function -- Cart should be in reset state upon calling this function
-- this function processes all user requests for this specific board/mapper -- 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 rv = nil
local file local file
local rom_size = 256
local ram_size = 0
--initialize device i/o for NES -- Initialize device i/o for Gameboy
dict.io("IO_RESET") dict.io("IO_RESET")
dict.io("GAMEBOY_INIT") dict.io("GAMEBOY_INIT")
dict.io("GB_POWER_5V") --gameboy carts prob run fine at 3v if want to be safe dict.io("GB_POWER_5V") -- Gameboy carts prob run fine at 3v if want to be safe
--test the cart -- TODO: test the cart
if test then if process_opts["test"] then
-- print("Testing ", mapname) unsupported("test")
-- nes.detect_mapper_mirroring(true)
-- print("EXP0 pull-up test:", dict.io("EXP0_PULLUP_TEST"))
-- --nes.read_flashID_prgrom_exp0(true)
-- rom_manf_id(true)
-- --nes.read_flashID_chrrom_8K(true)
-- chrrom_manf_id(true)
end end
--dump the cart to dumpfile -- Dump the cart to dumpfile
if read then if process_opts["read"] then
print("\nDumping ROM...") print("\nDumping ROM...")
--init_mapper() file = assert(io.open(process_opts["dump_filename"], "wb"))
file = assert(io.open(dumpfile, "wb")) -- Dump cart into file
dump_rom(file, console_opts["rom_size_kbyte"], false)
--dump cart into file -- Close file
dump_rom(file, rom_size, false)
--close file
assert(file:close()) assert(file:close())
print("DONE Dumping ROM") print("DONE Dumping ROM")
end end
--erase the cart -- TODO: erase the cart
if erase then if process_opts["erase"] then
unsupported("erase")
-- print("\nErasing ", mapname);
--
-- --init_mapper()
--
-- print("erasing PRG-ROM");
-- dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0xAA)
-- dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x2AAA, 0x55)
-- dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0x80)
-- dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0xAA)
-- dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x2AAA, 0x55)
-- dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0x10)
-- rv = dict.nes("NES_CPU_RD", 0x8000)
--
-- local i = 0
--
-- --TODO create some function to pass the read value
-- --that's smart enough to figure out if the board is actually erasing or not
-- while ( rv ~= 0xFF ) do
-- rv = dict.nes("NES_CPU_RD", 0x8000)
-- i = i + 1
-- end
-- print(i, "naks, done erasing prg.");
--
-- print("erasing CHR-ROM");
-- dict.nes("NES_PPU_WR", 0x1555, 0xAA)
-- dict.nes("NES_PPU_WR", 0x0AAA, 0x55)
-- dict.nes("NES_PPU_WR", 0x1555, 0x80)
-- dict.nes("NES_PPU_WR", 0x1555, 0xAA)
-- dict.nes("NES_PPU_WR", 0x0AAA, 0x55)
-- dict.nes("NES_PPU_WR", 0x1555, 0x10)
-- rv = dict.nes("NES_PPU_RD", 0x0000)
--
-- i = 0
-- while ( rv ~= 0xFF ) do
-- rv = dict.nes("NES_PPU_RD", 0x0000)
-- i = i + 1
-- end
-- print(i, "naks, done erasing chr.\n");
end end
--program flashfile to the cart -- TODO: program flashfile to the cart
if program then if process_opts["program"] then
-- --open file unsupported("program")
-- file = assert(io.open(flashfile, "rb"))
-- --determine if auto-doubling, deinterleaving, etc,
-- --needs done to make board compatible with rom
-- --flash cart
-- flash_rom(file, rom_size, true)
-- --close file
-- assert(file:close())
--
end end
--verify flashfile is on the cart -- Verify flashfile is on the cart
if verify then -- (This is sort of pointless until "program" is supported)
if process_opts["verify"] then
--for now let's just dump the file and verify manually --for now let's just dump the file and verify manually
print("\nPost dumping ROM...") print("\nPost dumping ROM...")
--init_mapper() file = assert(io.open(process_opts["verify_filename"], "wb"))
file = assert(io.open(verifyfile, "wb"))
--dump cart into file --dump cart into file
dump_rom(file, rom_size, false) dump_rom(file, console_opts["rom_size_kbyte"], false)
--close file --close file
assert(file:close()) assert(file:close())
@ -286,12 +119,11 @@ local function process( test, read, erase, program, verify, dumpfile, flashfile,
dict.io("IO_RESET") dict.io("IO_RESET")
end end
-- global variables so other modules can use them -- global variables so other modules can use them
-- NONE
-- call functions desired to run when script is called/imported -- call functions desired to run when script is called/imported
-- NONE
-- functions other modules are able to call -- functions other modules are able to call
mbc1.process = process mbc1.process = process

View File

@ -1,54 +1,18 @@
-- create the module's table -- create the module's table
local romonly = {} local romonly = {}
-- import required modules -- import required modules
local dict = require "scripts.app.dict" local dict = require "scripts.app.dict"
local dump = require "scripts.app.dump" local dump = require "scripts.app.dump"
local flash = require "scripts.app.flash"
-- file constants -- file constants
local mapname = "ROMONLY" local mapname = "ROMONLY"
-- local functions -- local functions
local function unsupported(operation)
--read PRG-ROM flash ID print("\nUNSUPPORTED OPERATION: \"" .. operation .. "\" not implemented yet for Gameboy - ".. mapname .. "\n")
local function rom_manf_id( debug )
--init_mapper()
if debug then print("reading PRG-ROM manf ID") end
--enter software mode
--ROMSEL controls PRG-ROM /OE which needs to be low for flash writes
--So unlock commands need to be addressed below $8000
--DISCRETE_EXP0_PRGROM_WR doesn't toggle /ROMSEL by definition though, so A15 is unused
-- 15 14 13 12
-- 0x5 = 0b 0 1 0 1 -> $5555
-- 0x2 = 0b 0 0 1 0 -> $2AAA
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0xAA)
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x2AAA, 0x55)
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0x90)
--read manf ID
local rv = dict.nes("NES_CPU_RD", 0x8000)
if debug then print("attempted read PRG-ROM manf ID:", string.format("%X", rv)) end
--read prod ID
rv = dict.nes("NES_CPU_RD", 0x8001)
if debug then print("attempted read PRG-ROM prod ID:", string.format("%X", rv)) end
--exit software
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x8000, 0xF0)
--verify exited
-- rv = dict.nes("NES_CPU_RD", 0x8001)
-- if debug then print("attempted read PRG-ROM prod ID:", string.format("%X", rv)) end
end end
-- dump the ROM -- dump the ROM
local function dump_rom(file, rom_size_KB, debug) local function dump_rom(file, rom_size_KB, debug)
@ -70,198 +34,60 @@ local function dump_rom( file, rom_size_KB, debug )
end end
--write a single byte to ROM flash
local function wr_flash_byte(addr, value, debug)
if (addr < 0x8000 or addr > 0xFFFF) then
print("\n ERROR! flash write to PRG-ROM", string.format("$%X", addr), "must be $8000-FFFF \n\n")
return
end
--send unlock command and write byte
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0xAA)
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x2AAA, 0x55)
dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0xA0)
dict.nes("DISCRETE_EXP0_PRGROM_WR", addr, value)
local rv = dict.nes("NES_CPU_RD", addr)
local i = 0
while ( rv ~= value ) do
rv = dict.nes("NES_CPU_RD", addr)
i = i + 1
end
if debug then print(i, "naks, done writing byte.") end
--TODO handle timeout for problems
--TODO return pass/fail/info
end
--fast host flash one bank at a time...
--this is controlled from the host side one bank at a time
--but requires specific firmware MMC3 flashing functions
--there is super slow version commented out that doesn't require MMC3 specific firmware code
local function flash_rom(file, rom_size_KB, debug)
--init_mapper()
--test some bytes
--wr_flash_byte(0x8000, 0xA5, true)
--wr_flash_byte(0xFFFF, 0x5A, true)
print("\nProgramming PRG-ROM flash")
--most of this is overkill for NROM, but it's how we want to handle things for bigger mappers
local base_addr = 0x8000 --writes occur $8000-9FFF
local bank_size = 32*1024 --MMC3 8KByte per PRG bank
local buff_size = 1 --number of bytes to write at a time
local cur_bank = 0
local total_banks = rom_size_KB*1024/bank_size
local byte_num --byte number gets reset for each bank
local byte_str, data, readdata
while cur_bank < total_banks do
if (cur_bank %8 == 0) then
print("writting PRG bank: ", cur_bank, " of ", total_banks-1)
end
--program the entire bank's worth of data
flash.write_file( file, 32, mapname, "PRGROM", false )
cur_bank = cur_bank + 1
end
print("Done Programming PRG-ROM flash")
end
-- Cart should be in reset state upon calling this function -- Cart should be in reset state upon calling this function
-- this function processes all user requests for this specific board/mapper -- 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 rv = nil
local file local file
local rom_size = 32
local ram_size = 0
--initialize device i/o for NES -- initialize device i/o for Gameboy
dict.io("IO_RESET") dict.io("IO_RESET")
dict.io("GAMEBOY_INIT") dict.io("GAMEBOY_INIT")
dict.io("GB_POWER_5V") --gameboy carts prob run fine at 3v if want to be safe dict.io("GB_POWER_5V") --gameboy carts prob run fine at 3v if want to be safe
-- test the cart -- test the cart
if test then if process_opts["test"] then
-- print("Testing ", mapname) unsupported("test")
-- nes.detect_mapper_mirroring(true)
-- print("EXP0 pull-up test:", dict.io("EXP0_PULLUP_TEST"))
-- --nes.read_flashID_prgrom_exp0(true)
-- rom_manf_id(true)
-- --nes.read_flashID_chrrom_8K(true)
-- chrrom_manf_id(true)
end end
-- dump the cart to dumpfile -- dump the cart to dumpfile
if read then if process_opts["read"] then
print("\nDumping ROM...") print("\nDumping ROM...")
--init_mapper() file = assert(io.open(process_opts["dump_filename"], "wb"))
file = assert(io.open(dumpfile, "wb"))
-- dump cart into file -- dump cart into file
dump_rom(file, rom_size, false) dump_rom(file, console_opts["rom_size_kbyte"], false)
-- close file -- close file
assert(file:close()) assert(file:close())
print("DONE Dumping ROM") print("DONE Dumping ROM")
end end
-- TODO: Erase the cart
--erase the cart if process_opts["erase"] then
if erase then unsupported("erase")
-- print("\nErasing ", mapname);
--
-- --init_mapper()
--
-- print("erasing PRG-ROM");
-- dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0xAA)
-- dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x2AAA, 0x55)
-- dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0x80)
-- dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0xAA)
-- dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x2AAA, 0x55)
-- dict.nes("DISCRETE_EXP0_PRGROM_WR", 0x5555, 0x10)
-- rv = dict.nes("NES_CPU_RD", 0x8000)
--
-- local i = 0
--
-- --TODO create some function to pass the read value
-- --that's smart enough to figure out if the board is actually erasing or not
-- while ( rv ~= 0xFF ) do
-- rv = dict.nes("NES_CPU_RD", 0x8000)
-- i = i + 1
-- end
-- print(i, "naks, done erasing prg.");
--
-- print("erasing CHR-ROM");
-- dict.nes("NES_PPU_WR", 0x1555, 0xAA)
-- dict.nes("NES_PPU_WR", 0x0AAA, 0x55)
-- dict.nes("NES_PPU_WR", 0x1555, 0x80)
-- dict.nes("NES_PPU_WR", 0x1555, 0xAA)
-- dict.nes("NES_PPU_WR", 0x0AAA, 0x55)
-- dict.nes("NES_PPU_WR", 0x1555, 0x10)
-- rv = dict.nes("NES_PPU_RD", 0x0000)
--
-- i = 0
-- while ( rv ~= 0xFF ) do
-- rv = dict.nes("NES_PPU_RD", 0x0000)
-- i = i + 1
-- end
-- print(i, "naks, done erasing chr.\n");
end end
--program flashfile to the cart -- TODO: program flashfile to the cart
if program then if process_opts["program"] then
-- --open file unsupported("program")
-- file = assert(io.open(flashfile, "rb"))
-- --determine if auto-doubling, deinterleaving, etc,
-- --needs done to make board compatible with rom
-- --flash cart
-- flash_rom(file, rom_size, true)
-- --close file
-- assert(file:close())
--
end end
--verify flashfile is on the cart -- Verify flashfile is on the cart
if verify then -- (This is sort of pointless until "program" is supported)
if process_opts["verify"] then
--for now let's just dump the file and verify manually --for now let's just dump the file and verify manually
print("\nPost dumping ROM...") print("\nPost dumping ROM...")
--init_mapper() file = assert(io.open(process_opts["verify_filename"], "wb"))
file = assert(io.open(verifyfile, "wb"))
--dump cart into file --dump cart into file
dump_rom(file, rom_size, false) dump_rom(file, console_opts["rom_size_kbyte"], false)
--close file --close file
assert(file:close()) assert(file:close())
print("DONE post dumping ROM") print("DONE post dumping ROM")
end end
@ -270,10 +96,10 @@ end
-- global variables so other modules can use them -- global variables so other modules can use them
-- NONE
-- call functions desired to run when script is called/imported -- call functions desired to run when script is called/imported
-- NONE
-- functions other modules are able to call -- functions other modules are able to call
romonly.process = process romonly.process = process

View File

@ -87,7 +87,7 @@ local function process(process_opts, console_opts)
local rv = nil local rv = nil
local file local file
local rom_size = console_opts["rom_size_mbit"] * 128 local rom_size = console_opts["rom_size_kbyte"]
local wram_size = console_opts["wram_size_kb"] local wram_size = console_opts["wram_size_kb"]
local mirror = console_opts["mirror"] local mirror = console_opts["mirror"]

View File

@ -139,7 +139,7 @@ function main ()
prg_rom_size_kb = 256 * 128, -- Size of NES PRG-ROM in KByte prg_rom_size_kb = 256 * 128, -- Size of NES PRG-ROM in KByte
chr_rom_size_kb = 8, -- Size of NES CHR-ROM in KByte chr_rom_size_kb = 8, -- Size of NES CHR-ROM in KByte
wram_size_kb = 0, -- Size of NES PRG-RAM/WRAM in KByte wram_size_kb = 0, -- Size of NES PRG-RAM/WRAM in KByte
rom_size_mbit = 8, -- Size of ROM in Megabits, used for non-NES consoles. rom_size_kbyte = 8 * 128, -- Size of ROM in Megabits, used for non-NES consoles.
} }
@ -231,7 +231,7 @@ function main ()
dict.io("IO_RESET") dict.io("IO_RESET")
curcart.process( true, true, false, false, false, "ignore/dump.bin", "ignore/gameboy.bin", "ignore/verifyout.bin") curcart.process(process_opts, console_opts)
--[[ --TEST GB power --[[ --TEST GB power
dict.io("GB_POWER_3V") dict.io("GB_POWER_3V")
print("GBP high 3v GBA") print("GBP high 3v GBA")

View File

@ -11,12 +11,32 @@ end
function default_exec(process_opts, console_opts) function default_exec(process_opts, console_opts)
-- Defensively filter out any console options that aren't standard. -- Defensively filter out any console options that aren't standard.
local default_opts = { local default_opts = {
rom_size_mbit = console_opts["rom_size_mbit"], rom_size_kbyte = console_opts["rom_size_kbyte"],
wram_size_kb = console_opts["wram_size_kb"], wram_size_kb = console_opts["wram_size_kb"],
} }
console_opts["console_process_script"].process(process_opts, default_opts) console_opts["console_process_script"].process(process_opts, default_opts)
end end
-- Wrapper for managing original Gameboy operations.
function gb_exec(process_opts, console_opts)
-- Defensively filter out any console options that aren't standard.
local gb_opts = {
rom_size_kbyte = console_opts["rom_size_kbyte"],
}
local mappers = {
romonly = require "scripts.gb.romonly",
mbc1 = require "scripts.gb.mbc1",
}
m = mappers[console_opts["mapper"]]
if m == nil then
print("UNSUPPORTED MAPPER: ", console_opts["mapper"])
else
-- Attempt requested operations with hardware!
-- TODO: Do plumbing for interacting with RAM.
m.process(process_opts, console_opts)
end
end
-- Wrapper for managing NES/Famicom operations. -- Wrapper for managing NES/Famicom operations.
function nes_exec(process_opts, console_opts) function nes_exec(process_opts, console_opts)
local dict = require "scripts.app.dict" local dict = require "scripts.app.dict"
@ -74,10 +94,12 @@ function main()
-- dump_filename: string, filename used for writing dumped data. -- dump_filename: string, filename used for writing dumped data.
-- flash_filename: string, filename containing data to write cartridge. -- flash_filename: string, filename containing data to write cartridge.
-- verify_filename: string, filename used for writing back data written to cartridge for verification. -- verify_filename: string, filename used for writing back data written to cartridge for verification.
-- ramdump_filename: string, filename used for writing dumped ram data.
-- ramwrite_filename: string, filename containing data to write to ram on cartridge.
-- nes_prg_rom_size_kb: int, size of cartridge PRG-ROM in kilobytes. -- nes_prg_rom_size_kb: int, size of cartridge PRG-ROM in kilobytes.
-- nes_chr_rom_size_kb: int, size of cartridge CHR-ROM in kilobytes. -- nes_chr_rom_size_kb: int, size of cartridge CHR-ROM in kilobytes.
-- nes_wram_size_kb: int, size of cartridge WRAM in kilobytes. -- nes_wram_size_kb: int, size of cartridge WRAM in kilobytes.
-- rom_size_mbit: int, size of cartridge ROM in megabits. -- rom_size_kbyte: int, size of cartridge ROM in kilobytes.
-- TODO: This should probably be one level up. -- TODO: This should probably be one level up.
-- TODO: Ram probably needs a verify file as well? -- TODO: Ram probably needs a verify file as well?
@ -119,6 +141,8 @@ function main()
-- TODO: Add SNES support, as it appears to be currently usable? -- TODO: Add SNES support, as it appears to be currently usable?
local consoles = { local consoles = {
dmg = gb_exec,
gb = gb_exec, -- Support two names for gameboy
gba = default_exec, gba = default_exec,
genesis = default_exec, genesis = default_exec,
n64 = default_exec, n64 = default_exec,
@ -139,7 +163,7 @@ function main()
wram_size_kb = nes_wram_size_kb, wram_size_kb = nes_wram_size_kb,
prg_rom_size_kb = nes_prg_rom_size_kb, prg_rom_size_kb = nes_prg_rom_size_kb,
chr_rom_size_kb = nes_chr_rom_size_kb, chr_rom_size_kb = nes_chr_rom_size_kb,
rom_size_mbit = rom_size_mbit, rom_size_kbyte = rom_size_kbyte,
console_process_script = console_process_script, console_process_script = console_process_script,
mapper = mapper_name, mapper = mapper_name,
} }

View File

@ -72,7 +72,7 @@ local function process(process_opts, console_opts)
local rv = nil local rv = nil
local file local file
local rom_size = console_opts["rom_size_mbit"] * 128 local rom_size = console_opts["rom_size_kbyte"]
local wram_size = console_opts["wram_size_kb"] local wram_size = console_opts["wram_size_kb"]
local mirror = console_opts["mirror"] local mirror = console_opts["mirror"]

View File

@ -49,7 +49,6 @@ end
--this function processes all user requests for this specific board/mapper --this function processes all user requests for this specific board/mapper
local function process(process_opts, console_opts) local function process(process_opts, console_opts)
local file local file
local rom_size = console_opts["rom_size_mbit"] * 128
-- Initialize device i/o for SEGA -- Initialize device i/o for SEGA
dict.io("IO_RESET") dict.io("IO_RESET")
@ -73,7 +72,7 @@ local function process(process_opts, console_opts)
file = assert(io.open(process_opts["dump_filename"], "wb")) file = assert(io.open(process_opts["dump_filename"], "wb"))
--dump cart into file --dump cart into file
dump_rom(file, rom_size, false) dump_rom(file, console_opts["rom_size_kbyte"], false)
--close file --close file
assert(file:close()) assert(file:close())

View File

@ -32,6 +32,7 @@ const char *HELP = "Usage: inlretro [options]\n\n"\
" \t\t\t\t\t\t mapper30,mmc1,mmc3,mmc4,mmc5,nrom,unrom}\n"\ " \t\t\t\t\t\t mapper30,mmc1,mmc3,mmc4,mmc5,nrom,unrom}\n"\
" --nes_prg_rom_size_kbyte=size, -x size_kbytes\tNES-only, size of PRG-ROM in kilobytes\n"\ " --nes_prg_rom_size_kbyte=size, -x size_kbytes\tNES-only, size of PRG-ROM in kilobytes\n"\
" --nes_chr_rom_size_kbyte=size, -y size_kbytes\tNES-only, size of CHR-ROM in kilobytes\n"\ " --nes_chr_rom_size_kbyte=size, -y size_kbytes\tNES-only, size of CHR-ROM in kilobytes\n"\
" --rom_size_kbyte=size, -k size_kbytes\t\tSize of ROM in kilobytes, non-NES systems.\n"\
" --rom_size_mbit=size, -z size_mbits\t\tSize of ROM in megabits, non-NES systems.\n"\ " --rom_size_mbit=size, -z size_mbits\t\tSize of ROM in megabits, non-NES systems.\n"\
" --verify_filename=filename, -v filename\tIf provided, writeback written rom to this filename\n"\ " --verify_filename=filename, -v filename\tIf provided, writeback written rom to this filename\n"\
" --wram_size_kbyte=size, -w size_kbytes\tNES-only, size of WRAM in kilobytes\n"\ " --wram_size_kbyte=size, -w size_kbytes\tNES-only, size of WRAM in kilobytes\n"\
@ -50,7 +51,7 @@ typedef struct {
int wram_size_kb; int wram_size_kb;
// General Functionality // General Functionality
int rom_size_mbit; int rom_size_kbyte;
char *dump_filename; char *dump_filename;
char *program_filename; char *program_filename;
char *ramdump_filename; char *ramdump_filename;
@ -90,6 +91,7 @@ INLOptions* parseOptions(int argc, char *argv[]) {
{"nes_prg_rom_size_kbyte", optional_argument, NULL, 'x'}, {"nes_prg_rom_size_kbyte", optional_argument, NULL, 'x'},
{"nes_chr_rom_size_kbyte", optional_argument, NULL, 'y'}, {"nes_chr_rom_size_kbyte", optional_argument, NULL, 'y'},
{"wram_size_kbyte", optional_argument, NULL, 'w'}, {"wram_size_kbyte", optional_argument, NULL, 'w'},
{"rom_size_kbyte", optional_argument, NULL, 'k'},
{"rom_size_mbit", optional_argument, NULL, 'z'}, {"rom_size_mbit", optional_argument, NULL, 'z'},
{0, 0, 0, 0} // longopts must end in {0, 0, 0, 0} {0, 0, 0, 0} // longopts must end in {0, 0, 0, 0}
}; };
@ -98,6 +100,7 @@ INLOptions* parseOptions(int argc, char *argv[]) {
const char *FLAG_FORMAT = "a:b:hc:d:m:p:s:v:w:x:y:z:"; const char *FLAG_FORMAT = "a:b:hc:d:m:p:s:v:w:x:y:z:";
int index = 0; int index = 0;
int rv = 0; int rv = 0;
int kbyte = 0;
opterr = 0; opterr = 0;
// Create options struct. // Create options struct.
@ -123,6 +126,7 @@ INLOptions* parseOptions(int argc, char *argv[]) {
case 'h': opts->display_help = 1; break; case 'h': opts->display_help = 1; break;
case 'c': opts->console_name = optarg; break; case 'c': opts->console_name = optarg; break;
case 'd': opts->dump_filename = optarg; break; case 'd': opts->dump_filename = optarg; break;
case 'k': opts->rom_size_kbyte = atoi(optarg); break;
case 'm': opts->mapper_name = optarg; break; case 'm': opts->mapper_name = optarg; break;
case 'p': opts->program_filename = optarg; break; case 'p': opts->program_filename = optarg; break;
case 's': opts->lua_filename = optarg; break; case 's': opts->lua_filename = optarg; break;
@ -130,7 +134,13 @@ INLOptions* parseOptions(int argc, char *argv[]) {
case 'w': opts->wram_size_kb = atoi(optarg); break; case 'w': opts->wram_size_kb = atoi(optarg); break;
case 'x': opts->prg_rom_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 'y': opts->chr_rom_size_kb = atoi(optarg); break;
case 'z': opts->rom_size_mbit = atoi(optarg); break; case 'z':
kbyte = atoi(optarg) * 128;
if (opts->rom_size_kbyte && opts->rom_size_kbyte != kbyte) {
printf("rom_size_mbit disagrees with rom_size_kbyte! Using %d Kb as rom size.\n", kbyte);
}
opts->rom_size_kbyte = kbyte;
break;
case '?': case '?':
if( if(
( optopt == 'c' ) ( optopt == 'c' )
@ -232,8 +242,8 @@ lua_State *lua_init(INLOptions *opts) {
lua_pushstring(L, opts->ramwrite_filename); lua_pushstring(L, opts->ramwrite_filename);
lua_setglobal(L, "ramwrite_filename"); lua_setglobal(L, "ramwrite_filename");
lua_pushinteger(L, opts->rom_size_mbit); lua_pushinteger(L, opts->rom_size_kbyte);
lua_setglobal(L, "rom_size_mbit"); lua_setglobal(L, "rom_size_kbyte");
lua_pushinteger(L, opts->wram_size_kb); lua_pushinteger(L, opts->wram_size_kb);
lua_setglobal(L, "nes_wram_size_kb"); lua_setglobal(L, "nes_wram_size_kb");
@ -297,7 +307,7 @@ int main(int argc, char *argv[])
} }
// Check for sane user input. // Check for sane user input.
if (strcmp("NES", opts->console_name) == 0) { if (strcmp("nes", opts->console_name) == 0) {
// ROM sizes must be non-zero, power of 2, and greater than 16. // ROM sizes must be non-zero, power of 2, and greater than 16.
if (!isValidROMSize(opts->prg_rom_size_kb, 16)) { if (!isValidROMSize(opts->prg_rom_size_kb, 16)) {
printf("PRG-ROM must be non-zero power of 2, 16kb or greater.\n"); printf("PRG-ROM must be non-zero power of 2, 16kb or greater.\n");
@ -317,6 +327,19 @@ int main(int argc, char *argv[])
} }
} }
if ((strcmp("gba", opts->console_name) == 0) ||
(strcmp("genesis", opts->console_name) == 0) ||
(strcmp("n64", opts->console_name) == 0)) {
if (opts->rom_size_kbyte <= 0) {
printf("ROM size must be greater than 0 kilobytes.\n");
return 1;
}
if (opts->rom_size_kbyte % 128) {
printf("ROM size for this system must translate into megabits with no kilobyte remainder.\n");
return 1;
}
}
// Start up Lua. // Start up Lua.
L = lua_init(opts); L = lua_init(opts);