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"
|
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
|
-- Cart should be in reset state upon calling this function
|
||||||
print("\n ERROR! flash write to PRG-ROM", string.format("$%X", addr), "must be $8000-FFFF \n\n")
|
-- this function processes all user requests for this specific board/mapper
|
||||||
return
|
local function process(process_opts, console_opts)
|
||||||
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
|
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,20 @@
|
||||||
|
|
||||||
-- 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
|
||||||
|
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.
|
--ROM ONLY dump all 32KB, most of this code is overkill for no MBC.
|
||||||
-- but follows same format as MBC's
|
-- 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 read_count = 0
|
||||||
local addr_base = 0x00 -- $0000 base address for ROM
|
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
|
read_count = read_count + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--write a single byte to ROM flash
|
-- Cart should be in reset state upon calling this function
|
||||||
local function wr_flash_byte(addr, value, debug)
|
-- this function processes all user requests for this specific board/mapper
|
||||||
|
local function process(process_opts, console_opts)
|
||||||
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
|
|
||||||
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_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
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
|
|
||||||
|
|
@ -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"]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue