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:
parent
a11940f93d
commit
f899518989
|
|
@ -8,47 +8,14 @@ local dump = require "scripts.app.dump"
|
|||
local flash = require "scripts.app.flash"
|
||||
|
||||
-- file constants
|
||||
local mapname = "ROMONLY"
|
||||
local mapname = "MBC1"
|
||||
|
||||
-- local functions
|
||||
|
||||
--read PRG-ROM flash ID
|
||||
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
|
||||
|
||||
local function unsupported(operation)
|
||||
print("\nUNSUPPORTED OPERATION: \"" .. operation .. "\" not implemented yet for Gameboy - ".. mapname .. "\n")
|
||||
end
|
||||
|
||||
|
||||
|
||||
--dump the ROM
|
||||
local function dump_rom( file, rom_size_KB, debug )
|
||||
|
||||
|
|
@ -88,194 +55,60 @@ local function dump_rom( file, rom_size_KB, debug )
|
|||
|
||||
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
|
||||
--this function processes all user requests for this specific board/mapper
|
||||
local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile, mirror)
|
||||
|
||||
local rv = nil
|
||||
-- Cart should be in reset state upon calling this function
|
||||
-- this function processes all user requests for this specific board/mapper
|
||||
local function process(process_opts, console_opts)
|
||||
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("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
|
||||
if test then
|
||||
-- print("Testing ", mapname)
|
||||
|
||||
-- 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)
|
||||
-- TODO: test the cart
|
||||
if process_opts["test"] then
|
||||
unsupported("test")
|
||||
end
|
||||
|
||||
--dump the cart to dumpfile
|
||||
if read then
|
||||
-- Dump the cart to dumpfile
|
||||
if process_opts["read"] then
|
||||
|
||||
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
|
||||
dump_rom(file, rom_size, false)
|
||||
|
||||
--close file
|
||||
-- Close file
|
||||
assert(file:close())
|
||||
print("DONE Dumping ROM")
|
||||
end
|
||||
|
||||
|
||||
--erase the cart
|
||||
if erase then
|
||||
|
||||
-- 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");
|
||||
-- TODO: erase the cart
|
||||
if process_opts["erase"] then
|
||||
unsupported("erase")
|
||||
end
|
||||
|
||||
|
||||
--program flashfile to the cart
|
||||
if program then
|
||||
-- --open file
|
||||
-- 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())
|
||||
--
|
||||
-- TODO: program flashfile to the cart
|
||||
if process_opts["program"] then
|
||||
unsupported("program")
|
||||
end
|
||||
|
||||
--verify flashfile is on the cart
|
||||
if verify then
|
||||
-- Verify flashfile is on the cart
|
||||
-- (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
|
||||
print("\nPost dumping ROM...")
|
||||
|
||||
--init_mapper()
|
||||
|
||||
file = assert(io.open(verifyfile, "wb"))
|
||||
file = assert(io.open(process_opts["verify_filename"], "wb"))
|
||||
|
||||
--dump cart into file
|
||||
dump_rom(file, rom_size, false)
|
||||
dump_rom(file, console_opts["rom_size_kbyte"], false)
|
||||
|
||||
--close file
|
||||
assert(file:close())
|
||||
|
|
@ -286,12 +119,11 @@ local function process( test, read, erase, program, verify, dumpfile, flashfile,
|
|||
dict.io("IO_RESET")
|
||||
end
|
||||
|
||||
|
||||
-- global variables so other modules can use them
|
||||
|
||||
-- NONE
|
||||
|
||||
-- call functions desired to run when script is called/imported
|
||||
|
||||
-- NONE
|
||||
|
||||
-- functions other modules are able to call
|
||||
mbc1.process = process
|
||||
|
|
|
|||
|
|
@ -1,56 +1,20 @@
|
|||
|
||||
-- create the module's table
|
||||
local romonly = {}
|
||||
|
||||
-- import required modules
|
||||
local dict = require "scripts.app.dict"
|
||||
local dump = require "scripts.app.dump"
|
||||
local flash = require "scripts.app.flash"
|
||||
|
||||
-- file constants
|
||||
local mapname = "ROMONLY"
|
||||
|
||||
-- local functions
|
||||
|
||||
--read PRG-ROM flash ID
|
||||
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
|
||||
|
||||
local function unsupported(operation)
|
||||
print("\nUNSUPPORTED OPERATION: \"" .. operation .. "\" not implemented yet for Gameboy - ".. mapname .. "\n")
|
||||
end
|
||||
|
||||
|
||||
|
||||
--dump the ROM
|
||||
local function dump_rom( file, rom_size_KB, debug )
|
||||
-- dump the ROM
|
||||
local function dump_rom(file, rom_size_KB, debug)
|
||||
|
||||
--ROM ONLY dump all 32KB, most of this code is overkill for no MBC.
|
||||
-- but follows same format as MBC's
|
||||
|
|
@ -59,209 +23,71 @@ local function dump_rom( file, rom_size_KB, debug )
|
|||
local read_count = 0
|
||||
local addr_base = 0x00 -- $0000 base address for ROM
|
||||
|
||||
while ( read_count < num_reads ) do
|
||||
while (read_count < num_reads) do
|
||||
|
||||
if debug then print( "dump ROM part ", read_count, " of ", num_reads) end
|
||||
if debug then print("dump ROM part ", read_count, " of ", num_reads) end
|
||||
|
||||
dump.dumptofile( file, KB_per_read, addr_base, "GAMEBOY_PAGE", false )
|
||||
dump.dumptofile(file, KB_per_read, addr_base, "GAMEBOY_PAGE", false)
|
||||
|
||||
read_count = read_count + 1
|
||||
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
|
||||
--this function processes all user requests for this specific board/mapper
|
||||
local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile, mirror)
|
||||
|
||||
local rv = nil
|
||||
-- Cart should be in reset state upon calling this function
|
||||
-- this function processes all user requests for this specific board/mapper
|
||||
local function process(process_opts, console_opts)
|
||||
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("GAMEBOY_INIT")
|
||||
|
||||
dict.io("GB_POWER_5V") --gameboy carts prob run fine at 3v if want to be safe
|
||||
|
||||
--test the cart
|
||||
if test then
|
||||
-- print("Testing ", mapname)
|
||||
|
||||
-- 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)
|
||||
-- test the cart
|
||||
if process_opts["test"] then
|
||||
unsupported("test")
|
||||
end
|
||||
|
||||
--dump the cart to dumpfile
|
||||
if read then
|
||||
-- dump the cart to dumpfile
|
||||
if process_opts["read"] then
|
||||
|
||||
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
|
||||
dump_rom(file, rom_size, false)
|
||||
|
||||
--close file
|
||||
-- close file
|
||||
assert(file:close())
|
||||
print("DONE Dumping ROM")
|
||||
end
|
||||
|
||||
|
||||
--erase the cart
|
||||
if erase then
|
||||
|
||||
-- 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");
|
||||
-- TODO: Erase the cart
|
||||
if process_opts["erase"] then
|
||||
unsupported("erase")
|
||||
end
|
||||
|
||||
|
||||
--program flashfile to the cart
|
||||
if program then
|
||||
-- --open file
|
||||
-- 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())
|
||||
--
|
||||
-- TODO: program flashfile to the cart
|
||||
if process_opts["program"] then
|
||||
unsupported("program")
|
||||
end
|
||||
|
||||
--verify flashfile is on the cart
|
||||
if verify then
|
||||
-- Verify flashfile is on the cart
|
||||
-- (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
|
||||
print("\nPost dumping ROM...")
|
||||
|
||||
--init_mapper()
|
||||
|
||||
file = assert(io.open(verifyfile, "wb"))
|
||||
file = assert(io.open(process_opts["verify_filename"], "wb"))
|
||||
|
||||
--dump cart into file
|
||||
dump_rom(file, rom_size, false)
|
||||
dump_rom(file, console_opts["rom_size_kbyte"], false)
|
||||
|
||||
--close file
|
||||
assert(file:close())
|
||||
|
||||
print("DONE post dumping ROM")
|
||||
end
|
||||
|
||||
|
|
@ -270,10 +96,10 @@ end
|
|||
|
||||
|
||||
-- global variables so other modules can use them
|
||||
|
||||
-- NONE
|
||||
|
||||
-- call functions desired to run when script is called/imported
|
||||
|
||||
-- NONE
|
||||
|
||||
-- functions other modules are able to call
|
||||
romonly.process = process
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ local function process(process_opts, console_opts)
|
|||
|
||||
local rv = nil
|
||||
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 mirror = console_opts["mirror"]
|
||||
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ function main ()
|
|||
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
|
||||
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")
|
||||
|
||||
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
|
||||
dict.io("GB_POWER_3V")
|
||||
print("GBP high 3v GBA")
|
||||
|
|
|
|||
|
|
@ -11,12 +11,32 @@ end
|
|||
function default_exec(process_opts, console_opts)
|
||||
-- Defensively filter out any console options that aren't standard.
|
||||
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"],
|
||||
}
|
||||
console_opts["console_process_script"].process(process_opts, default_opts)
|
||||
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.
|
||||
function nes_exec(process_opts, console_opts)
|
||||
local dict = require "scripts.app.dict"
|
||||
|
|
@ -69,15 +89,17 @@ end
|
|||
function main()
|
||||
|
||||
-- Globals passed in from C:
|
||||
-- console_name: string, name of console.
|
||||
-- mapper_name: string, name of mapper.
|
||||
-- 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.
|
||||
-- console_name: string, name of console.
|
||||
-- mapper_name: string, name of mapper.
|
||||
-- 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.
|
||||
-- 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_chr_rom_size_kb: int, size of cartridge CHR-ROM 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: 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?
|
||||
local consoles = {
|
||||
dmg = gb_exec,
|
||||
gb = gb_exec, -- Support two names for gameboy
|
||||
gba = default_exec,
|
||||
genesis = default_exec,
|
||||
n64 = default_exec,
|
||||
|
|
@ -139,7 +163,7 @@ function main()
|
|||
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,
|
||||
rom_size_mbit = rom_size_mbit,
|
||||
rom_size_kbyte = rom_size_kbyte,
|
||||
console_process_script = console_process_script,
|
||||
mapper = mapper_name,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ local function process(process_opts, console_opts)
|
|||
|
||||
local rv = nil
|
||||
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 mirror = console_opts["mirror"]
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ end
|
|||
--this function processes all user requests for this specific board/mapper
|
||||
local function process(process_opts, console_opts)
|
||||
local file
|
||||
local rom_size = console_opts["rom_size_mbit"] * 128
|
||||
|
||||
-- Initialize device i/o for SEGA
|
||||
dict.io("IO_RESET")
|
||||
|
|
@ -73,7 +72,7 @@ local function process(process_opts, console_opts)
|
|||
file = assert(io.open(process_opts["dump_filename"], "wb"))
|
||||
|
||||
--dump cart into file
|
||||
dump_rom(file, rom_size, false)
|
||||
dump_rom(file, console_opts["rom_size_kbyte"], false)
|
||||
|
||||
--close file
|
||||
assert(file:close())
|
||||
|
|
|
|||
|
|
@ -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"\
|
||||
" --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"\
|
||||
" --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"\
|
||||
" --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"\
|
||||
|
|
@ -50,7 +51,7 @@ typedef struct {
|
|||
int wram_size_kb;
|
||||
|
||||
// General Functionality
|
||||
int rom_size_mbit;
|
||||
int rom_size_kbyte;
|
||||
char *dump_filename;
|
||||
char *program_filename;
|
||||
char *ramdump_filename;
|
||||
|
|
@ -90,6 +91,7 @@ INLOptions* parseOptions(int argc, char *argv[]) {
|
|||
{"nes_prg_rom_size_kbyte", optional_argument, NULL, 'x'},
|
||||
{"nes_chr_rom_size_kbyte", optional_argument, NULL, 'y'},
|
||||
{"wram_size_kbyte", optional_argument, NULL, 'w'},
|
||||
{"rom_size_kbyte", optional_argument, NULL, 'k'},
|
||||
{"rom_size_mbit", optional_argument, NULL, 'z'},
|
||||
{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:";
|
||||
int index = 0;
|
||||
int rv = 0;
|
||||
int kbyte = 0;
|
||||
opterr = 0;
|
||||
|
||||
// Create options struct.
|
||||
|
|
@ -123,6 +126,7 @@ INLOptions* parseOptions(int argc, char *argv[]) {
|
|||
case 'h': opts->display_help = 1; break;
|
||||
case 'c': opts->console_name = 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 'p': opts->program_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 'x': opts->prg_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 '?':
|
||||
if(
|
||||
( optopt == 'c' )
|
||||
|
|
@ -232,8 +242,8 @@ lua_State *lua_init(INLOptions *opts) {
|
|||
lua_pushstring(L, opts->ramwrite_filename);
|
||||
lua_setglobal(L, "ramwrite_filename");
|
||||
|
||||
lua_pushinteger(L, opts->rom_size_mbit);
|
||||
lua_setglobal(L, "rom_size_mbit");
|
||||
lua_pushinteger(L, opts->rom_size_kbyte);
|
||||
lua_setglobal(L, "rom_size_kbyte");
|
||||
|
||||
lua_pushinteger(L, opts->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.
|
||||
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.
|
||||
if (!isValidROMSize(opts->prg_rom_size_kb, 16)) {
|
||||
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.
|
||||
L = lua_init(opts);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue