diff --git a/host/scripts/gb/mbc1.lua b/host/scripts/gb/mbc1.lua index 92d555c..4698a81 100644 --- a/host/scripts/gb/mbc1.lua +++ b/host/scripts/gb/mbc1.lua @@ -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(dumpfile, "wb")) + file = assert(io.open(process_opts["dump_filename"], "wb")) - --dump cart into file - dump_rom(file, rom_size, false) + -- Dump cart into file + dump_rom(file, console_opts["rom_size_kbyte"], 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,15 +119,14 @@ 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 -- return the module's table -return mbc1 +return mbc1 \ No newline at end of file diff --git a/host/scripts/gb/romonly.lua b/host/scripts/gb/romonly.lua index f7c2b9d..7fdd55d 100644 --- a/host/scripts/gb/romonly.lua +++ b/host/scripts/gb/romonly.lua @@ -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(dumpfile, "wb")) + file = assert(io.open(process_opts["dump_filename"], "wb")) - --dump cart into file - dump_rom(file, rom_size, false) + -- dump cart into file + dump_rom(file, console_opts["rom_size_kbyte"], 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,13 +96,13 @@ 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 -- return the module's table -return romonly +return romonly \ No newline at end of file diff --git a/host/scripts/gba/basic.lua b/host/scripts/gba/basic.lua index ac7948f..265912c 100644 --- a/host/scripts/gba/basic.lua +++ b/host/scripts/gba/basic.lua @@ -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"] diff --git a/host/scripts/inlretro.lua b/host/scripts/inlretro.lua index 33ed886..19e3457 100644 --- a/host/scripts/inlretro.lua +++ b/host/scripts/inlretro.lua @@ -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") diff --git a/host/scripts/inlretro2.lua b/host/scripts/inlretro2.lua index 23ececd..7ed7bc6 100644 --- a/host/scripts/inlretro2.lua +++ b/host/scripts/inlretro2.lua @@ -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, } diff --git a/host/scripts/n64/basic.lua b/host/scripts/n64/basic.lua index ac03691..05b6770 100644 --- a/host/scripts/n64/basic.lua +++ b/host/scripts/n64/basic.lua @@ -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"] diff --git a/host/scripts/sega/genesis_v1.lua b/host/scripts/sega/genesis_v1.lua index e2489f3..da6c59b 100644 --- a/host/scripts/sega/genesis_v1.lua +++ b/host/scripts/sega/genesis_v1.lua @@ -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()) diff --git a/host/source/inlprog.c b/host/source/inlprog.c index 253f667..a009701 100644 --- a/host/source/inlprog.c +++ b/host/source/inlprog.c @@ -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);