Have UxROM dumping, erasing, and flashing working now.
Also the current build assumes that the mcu is able to over drive the PRG-ROM output to select bank zero for initial bank table writting. Seems to work, but may need to come up with write that applies to mapper only and doesn't enable the PRG-ROM by keeping EXP0 low. Need to work on having the scripts find the bank table.
This commit is contained in:
parent
223007187b
commit
f7201f44b7
|
|
@ -19,6 +19,20 @@ uint8_t dump_buff( buffer *buff ) {
|
|||
switch ( buff->mem_type ) {
|
||||
case PRGROM:
|
||||
addrH |= 0x80; //$8000
|
||||
if (buff->mapper == UxROM) {
|
||||
//addrH &= 0b1011 1111 A14 must always be low
|
||||
addrH &= 0xBF;
|
||||
//write bank value to bank table
|
||||
//page_num shift by 6 bits A14 >> A8(0)
|
||||
bank = (buff->page_num)>>6;
|
||||
//Nomolos bank table @ CC84
|
||||
nes_cpu_wr( (0xCC84+bank), bank );
|
||||
|
||||
buff->cur_byte = nes_cpu_page_rd_poll( buff->data, addrH, buff->id,
|
||||
//id contains MSb of page when <256B buffer
|
||||
buff->last_idx, ~FALSE );
|
||||
break;
|
||||
}
|
||||
if (buff->mapper == BxROM) {
|
||||
//write bank value to bank table
|
||||
//page_num shift by 7 bits A15 >> A8(0)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "flash.h"
|
||||
|
||||
|
||||
uint8_t write_page( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr wr_func, read_funcptr rd_func )
|
||||
uint8_t write_page( uint8_t bank, uint8_t addrH, uint16_t unlock1, uint16_t unlock2, buffer *buff, write_funcptr wr_func, read_funcptr rd_func )
|
||||
{
|
||||
uint16_t cur = buff->cur_byte;
|
||||
uint8_t n = buff->cur_byte;
|
||||
|
|
@ -28,13 +28,16 @@ uint8_t write_page( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr wr_
|
|||
//addrH_dmask = 0b0000 1111
|
||||
//page2bankshft = A11->A8 = 4 shifts
|
||||
//wr_func( 0x5555, 0xAA );
|
||||
wr_func( 0xD555, 0xAA );
|
||||
//wr_func( 0xD555, 0xAA );
|
||||
wr_func( unlock1, 0xAA );
|
||||
// wr_func( oper_info->unlock1_AH, oper_info->unlock1_AL, oper_info->unlock1_data );
|
||||
//wr_func( 0x2AAA, 0x55 );
|
||||
wr_func( 0xAAAA, 0x55 );
|
||||
//wr_func( 0xAAAA, 0x55 );
|
||||
wr_func( unlock2, 0x55 );
|
||||
// wr_func( oper_info->unlock2_AH, oper_info->unlock2_AL, oper_info->unlock2_data );
|
||||
//wr_func( 0x5555, 0xA0 );
|
||||
wr_func( 0xD555, 0xA0 );
|
||||
//wr_func( 0xD555, 0xA0 );
|
||||
wr_func( unlock1, 0xA0 );
|
||||
// wr_func( oper_info->command_AH, oper_info->command_AL, oper_info->command1_data );
|
||||
wr_func( ((addrH<<8)| n), buff->data[n] );
|
||||
|
||||
|
|
@ -67,6 +70,60 @@ uint8_t write_page( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr wr_
|
|||
|
||||
}
|
||||
|
||||
uint8_t write_page_bank( uint8_t bank, uint8_t addrH, uint16_t unlock1, uint16_t unlock2, buffer *buff, write_funcptr wr_func, read_funcptr rd_func )
|
||||
{
|
||||
uint16_t cur = buff->cur_byte;
|
||||
uint8_t n = buff->cur_byte;
|
||||
uint8_t read;
|
||||
|
||||
while ( cur <= buff->last_idx ) {
|
||||
|
||||
//select first bank for unlock sequence
|
||||
//needs to be written to bank table!
|
||||
nes_cpu_wr( (0xCC84), 0x00 );
|
||||
|
||||
//wr_func( 0x5555, 0xAA );
|
||||
wr_func( unlock1, 0xAA );
|
||||
//wr_func( 0x2AAA, 0x55 );
|
||||
wr_func( unlock2, 0x55 );
|
||||
//wr_func( 0x5555, 0xA0 );
|
||||
wr_func( unlock1, 0xA0 );
|
||||
|
||||
//now need to select bank for the actual write!
|
||||
//but this write can't be applied to the PRG-ROM
|
||||
nes_cpu_wr( (0xCC84+bank), bank );
|
||||
|
||||
wr_func( ((addrH<<8)| n), buff->data[n] );
|
||||
|
||||
do {
|
||||
usbPoll();
|
||||
read = rd_func((addrH<<8)|n);
|
||||
|
||||
} while( read != rd_func((addrH<<8)|n) );
|
||||
|
||||
//retry if write failed
|
||||
//this helped but still seeing similar fails to dumps
|
||||
// if (read == buff->data[n]) {
|
||||
n++;
|
||||
cur++;
|
||||
// LED_IP_PU();
|
||||
// LED_LO();
|
||||
// } else {
|
||||
// nes_cpu_wr(0x5000, 0x81); //outer reg select mode
|
||||
// nes_cpu_wr(0x8000, bank); //outer bank
|
||||
// nes_cpu_wr(0x5000, 0x00); //chr reg select act like CNROM
|
||||
// LED_OP();
|
||||
// LED_HI();
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
buff->cur_byte = n;
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
uint8_t write_page_a53( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr wr_func, read_funcptr rd_func )
|
||||
{
|
||||
uint16_t cur = buff->cur_byte;
|
||||
|
|
@ -110,6 +167,16 @@ uint8_t write_page_a53( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr
|
|||
// wr_func( ((addrH<<8)| n), buff->data[n] );
|
||||
|
||||
|
||||
//TODO FIX THIS! It shouldn't be needed!
|
||||
//but for some reason the mapper is loosing it's setting for $5000 register to
|
||||
//permit flash writes. Many writes go through, but at somepoint it gets lost..
|
||||
//maybe the best fix it to require address to be equal to $5555 to write to flash enable register..
|
||||
//but for now, this rewrite hack solves the issue.
|
||||
nes_cpu_wr(0x5000, 0x54); //chr reg select act like CNROM & enable flash writes
|
||||
//AVR didn't need this patch so maybe is a speed issue
|
||||
//stmadapter didn't have problems either..
|
||||
//added time delay before m2 rising edge and it didn't change anything for stm6
|
||||
|
||||
// curaddresswrite( 0xA0 ); //gained ~3KBps (59.13KBps) inl6 with v3.0 proto
|
||||
wr_func( ((addrH<<8)| n), 0xA0 );
|
||||
|
||||
|
|
@ -124,14 +191,14 @@ uint8_t write_page_a53( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr
|
|||
//retry if write failed
|
||||
//this helped but still seeing similar fails to dumps
|
||||
// if (read == buff->data[n]) {
|
||||
n++;
|
||||
cur++;
|
||||
n++;
|
||||
cur++;
|
||||
// LED_IP_PU();
|
||||
// LED_LO();
|
||||
// } else {
|
||||
// nes_cpu_wr(0x5000, 0x81); //outer reg select mode
|
||||
// nes_cpu_wr(0x8000, bank); //outer bank
|
||||
// nes_cpu_wr(0x5000, 0x00); //chr reg select act like CNROM
|
||||
//// nes_cpu_wr(0x5000, 0x81); //outer reg select mode
|
||||
//// nes_cpu_wr(0x8000, bank); //outer bank
|
||||
//// nes_cpu_wr(0x5000, 0x54); //chr reg select act like CNROM & enable flash writes
|
||||
// LED_OP();
|
||||
// LED_HI();
|
||||
// }
|
||||
|
|
@ -448,12 +515,27 @@ uint8_t flash_buff( buffer *buff ) {
|
|||
//also use to get read function pointer
|
||||
switch ( buff->mem_type ) {
|
||||
case PRGROM: //$8000
|
||||
if (buff->mapper == NROM) {
|
||||
write_page( 0, (0x80 | addrH), 0x5555, 0x2AAA, buff, discrete_exp0_prgrom_wr, nes_cpu_rd );
|
||||
}
|
||||
if (buff->mapper == UxROM) {
|
||||
//addrH &= 0b1011 1111 A14 must always be low
|
||||
addrH &= 0x3F;
|
||||
addrH |= 0x80; //A15 doesn't apply to exp0 write, but needed for read back
|
||||
//write bank value
|
||||
//page_num shift by 6 bits A14 >> A8(0)
|
||||
bank = buff->page_num >> 6;
|
||||
//Nomolos banktable location
|
||||
nes_cpu_wr( (0xCC84+bank), bank );
|
||||
write_page_bank( bank, addrH, 0x5555, 0x2AAA, buff, discrete_exp0_prgrom_wr, nes_cpu_rd );
|
||||
}
|
||||
if (buff->mapper == BxROM) {
|
||||
//write bank value
|
||||
//page_num shift by 7 bits A15 >> A8(0)
|
||||
bank = buff->page_num >> 7;
|
||||
//Lizard banktable location
|
||||
nes_cpu_wr( (0xFF94+bank), bank );
|
||||
write_page( 0, (0x80 | addrH), 0x5555, 0x2AAA, buff, discrete_exp0_prgrom_wr, nes_cpu_rd );
|
||||
}
|
||||
if (buff->mapper == A53) {
|
||||
//write bank value to bank table
|
||||
|
|
@ -470,13 +552,11 @@ uint8_t flash_buff( buffer *buff ) {
|
|||
//need to use standard CPU writes
|
||||
//write_page( 0, (0x80 | addrH), buff, nes_cpu_wr, nes_cpu_rd );
|
||||
//break;
|
||||
//WORKS PLCC Action53:
|
||||
//write_page( bank, (0x80 | addrH), buff, nes_cpu_wr, nes_cpu_rd );
|
||||
//TSSOP-28 action53:
|
||||
write_page_a53( bank, (0x80 | addrH), buff, nes_cpu_wr, nes_cpu_rd );
|
||||
}
|
||||
//discrete:
|
||||
//write_page( 0, (0x80 | addrH), buff, discrete_exp0_prgrom_wr, nes_cpu_rd );
|
||||
//WORKS PLCC Action53:
|
||||
//write_page( bank, (0x80 | addrH), buff, nes_cpu_wr, nes_cpu_rd );
|
||||
//TSSOP-28 action53:
|
||||
write_page_a53( bank, (0x80 | addrH), buff, nes_cpu_wr, nes_cpu_rd );
|
||||
break;
|
||||
case CHRROM: //$0000
|
||||
write_page_chr( 0, addrH, buff, nes_ppu_wr, nes_ppu_rd );
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ function main ()
|
|||
|
||||
--cart/mapper specific scripts
|
||||
--local curcart = require "scripts.nes.nrom"
|
||||
local curcart = require "scripts.nes.bnrom"
|
||||
local curcart = require "scripts.nes.unrom"
|
||||
--local curcart = require "scripts.nes.bnrom"
|
||||
--local curcart = require "scripts.nes.action53"
|
||||
--local curcart = require "scripts.nes.action53_tsop"
|
||||
|
||||
|
|
@ -131,7 +132,7 @@ function main ()
|
|||
|
||||
--]]
|
||||
|
||||
---[[
|
||||
--[[
|
||||
--test reading back CIC version
|
||||
dict.io("SWIM_INIT", "SWIM_ON_A0")
|
||||
if swim.start(true) then
|
||||
|
|
@ -152,14 +153,18 @@ function main ()
|
|||
--set rom types and sizes
|
||||
--perform desired operation
|
||||
--CART and programmer should be in a RESET condition upon calling the specific script
|
||||
--curcart.process( true, true, true, true, "ignore/dump.bin", "ignore/ddug2.bin", "ignore/verifyout.bin")
|
||||
--curcart.process( false, true, true, false, "ignore/dump.bin", "ignore/lizard_v1.bin", "ignore/verifyout.bin")
|
||||
--curcart.process( false, true, true, false, "ignore/dump.bin", "ignore/liz/liz.bin", "ignore/verifyout.bin")
|
||||
curcart.process( false, false, true, true, false, "ignore/dump.bin", "ignore/lizard_v1.bin", "ignore/verifyout.bin")
|
||||
|
||||
--NROM
|
||||
--curcart.process( true, true, true, true, true, "ignore/dump.bin", "ignore/ddug2.bin", "ignore/verifyout.bin")
|
||||
--UxROM
|
||||
curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/nomolosFINAL.prg", "ignore/verifyout.bin")
|
||||
--curcart.process( true, true, true, true, true, "ignore/dump.bin", "ignore/nomolos.bin", "ignore/verifyout.bin")
|
||||
--BNROM
|
||||
--curcart.process( true, true, true, true, true, "ignore/dump.bin", "ignore/lizard_v1.bin", "ignore/verifyout.bin")
|
||||
--A53 PLCC
|
||||
--curcart.process( true, true, true, true, true, "ignore/dump.bin", "ignore/da53v2.prg", "ignore/verifyout.bin")
|
||||
--curcart.process( true, true, true, true, true, "ignore/dump.bin", "ignore/da53v2_x2.prg", "ignore/verifyout.bin")
|
||||
--curcart.process( true, true, true, true, true, "ignore/dump.bin", "ignore/a53part2.prg", "ignore/verifyout.bin")
|
||||
--curcart.process( true, true, true, true, true, "ignore/dump.bin", "ignore/a53vol3.prg", "ignore/verifyout.bin")
|
||||
--A53 tssop
|
||||
--curcart.process( true, false, true, true, true, "ignore/dump.bin", "ignore/a53vol3.prg", "ignore/verifyout.bin")
|
||||
|
||||
|
||||
--[[
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ local bnrom = {}
|
|||
|
||||
-- import required modules
|
||||
local dict = require "scripts.app.dict"
|
||||
local nes = require "scripts.app.nes"
|
||||
local dump = require "scripts.app.dump"
|
||||
local flash = require "scripts.app.flash"
|
||||
|
||||
|
|
@ -31,6 +32,8 @@ end
|
|||
--base is the actual NES CPU address, not the rom offset (ie $FFF0, not $7FF0)
|
||||
local function wr_bank_table(base, entries)
|
||||
|
||||
--BNROM needs to have a bank table present in each and every bank
|
||||
--it should also be at the same location in every bank
|
||||
|
||||
-- --first select the last bank as cartridge should be erased (all 0xFF)
|
||||
-- --go ahead and write the value to where it's supposed to be incase rom isn't erased
|
||||
|
|
@ -77,7 +80,10 @@ local function process( test, read, erase, program, verify, dumpfile, flashfile,
|
|||
|
||||
--test cart by reading manf/prod ID
|
||||
if test then
|
||||
-- prgrom_manf_id(true)
|
||||
nes.detect_mapper_mirroring(true)
|
||||
nes.ppu_ram_sense(0x1000, true)
|
||||
print("EXP0 pull-up test:", dict.io("EXP0_PULLUP_TEST"))
|
||||
nes.read_flashID_prgrom_exp0(true)
|
||||
end
|
||||
|
||||
--dump the cart to dumpfile
|
||||
|
|
|
|||
|
|
@ -4,17 +4,23 @@ local nrom = {}
|
|||
|
||||
-- import required modules
|
||||
local dict = require "scripts.app.dict"
|
||||
local nes = require "scripts.app.nes"
|
||||
local dump = require "scripts.app.dump"
|
||||
local flash = require "scripts.app.flash"
|
||||
|
||||
-- file constants
|
||||
|
||||
-- local functions
|
||||
--read PRG-ROM flash ID
|
||||
local function prgrom_manf_id( debug )
|
||||
|
||||
|
||||
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( read, erase, program, verify, dumpfile, flashfile, verifyfile)
|
||||
local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile)
|
||||
|
||||
local rv = nil
|
||||
local file
|
||||
|
|
@ -23,6 +29,13 @@ local function process( read, erase, program, verify, dumpfile, flashfile, verif
|
|||
dict.io("IO_RESET")
|
||||
dict.io("NES_INIT")
|
||||
|
||||
--test the cart
|
||||
if test then
|
||||
nes.detect_mapper_mirroring(true)
|
||||
nes.read_flashID_chrrom_8K(true)
|
||||
print("EXP0 pull-up test:", dict.io("EXP0_PULLUP_TEST"))
|
||||
nes.read_flashID_prgrom_exp0(true)
|
||||
end
|
||||
|
||||
--dump the cart to dumpfile
|
||||
if read then
|
||||
|
|
|
|||
|
|
@ -0,0 +1,174 @@
|
|||
|
||||
-- create the module's table
|
||||
local unrom = {}
|
||||
|
||||
-- import required modules
|
||||
local dict = require "scripts.app.dict"
|
||||
local nes = require "scripts.app.nes"
|
||||
local dump = require "scripts.app.dump"
|
||||
local flash = require "scripts.app.flash"
|
||||
|
||||
-- file constants
|
||||
|
||||
-- local functions
|
||||
local function init_mapper( debug )
|
||||
--need to select bank0 so PRG-ROM A14 is low when writting to lower bank
|
||||
--TODO this needs to be written to rom where value is 0x00 due to bus conflicts
|
||||
--so need to find the bank table first!
|
||||
--this could present an even larger problem with a blank flash chip
|
||||
--would have to get a byte written to 0x00 first before able to change the bank..
|
||||
--becomes catch 22 situation. Will have to rely on mcu over powering PRG-ROM..
|
||||
--ahh but a way out would be to disable the PRG-ROM with exp0 (/WE) going low
|
||||
--for now the write below seems to be working fine though..
|
||||
dict.nes("NES_CPU_WR", 0x8000, 0x80)
|
||||
end
|
||||
|
||||
local function wr_flash_byte(addr, value, debug)
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
--base is the actual NES CPU address, not the rom offset (ie $FFF0, not $7FF0)
|
||||
local function wr_bank_table(base, entries)
|
||||
|
||||
--UxROM can have a single bank table in $C000-FFFF (assuming this is most likely)
|
||||
--or a bank table in all other banks in $8000-BFFF
|
||||
|
||||
--need to have A14 clear when lower bank enabled
|
||||
init_mapper()
|
||||
|
||||
local i = 0
|
||||
while( i < entries) do
|
||||
wr_flash_byte(base+i, i)
|
||||
i = i+1;
|
||||
end
|
||||
|
||||
--TODO verify the bank table was successfully written before continuing!
|
||||
|
||||
end
|
||||
|
||||
--Cart should be in reset state upon calling this function
|
||||
--this function processes all user requests for this specific board/mapper
|
||||
local function process( test, read, erase, program, verify, dumpfile, flashfile, verifyfile)
|
||||
|
||||
local rv = nil
|
||||
local file
|
||||
|
||||
--initialize device i/o for NES
|
||||
dict.io("IO_RESET")
|
||||
dict.io("NES_INIT")
|
||||
|
||||
--test cart by reading manf/prod ID
|
||||
if test then
|
||||
nes.detect_mapper_mirroring(true)
|
||||
nes.ppu_ram_sense(0x1000, true)
|
||||
print("EXP0 pull-up test:", dict.io("EXP0_PULLUP_TEST"))
|
||||
|
||||
--need to set PRG-ROM A14 low when lower bank selected
|
||||
init_mapper() --this may not succeed due to bus conflicts...
|
||||
nes.read_flashID_prgrom_exp0(true)
|
||||
end
|
||||
|
||||
--dump the cart to dumpfile
|
||||
if read then
|
||||
file = assert(io.open(dumpfile, "wb"))
|
||||
|
||||
--TODO find bank table to avoid bus conflicts!
|
||||
--dump cart into file
|
||||
dump.dumptofile( file, 512, "UxROM", "PRGROM", true )
|
||||
|
||||
--close file
|
||||
assert(file:close())
|
||||
end
|
||||
|
||||
|
||||
--erase the cart
|
||||
if erase then
|
||||
|
||||
init_mapper()
|
||||
|
||||
print("\nerasing UxROM");
|
||||
|
||||
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.");
|
||||
|
||||
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
|
||||
|
||||
--find bank table in the rom
|
||||
--write bank table to all banks of cartridge
|
||||
--Nomolos' bank table is at $CC84 so hard code that for now
|
||||
wr_bank_table(0xCC84, 32)
|
||||
|
||||
--flash cart
|
||||
flash.write_file( file, 512, "UxROM", "PRGROM", true )
|
||||
--close file
|
||||
assert(file:close())
|
||||
|
||||
end
|
||||
|
||||
--verify flashfile is on the cart
|
||||
if verify then
|
||||
--for now let's just dump the file and verify manually
|
||||
|
||||
file = assert(io.open(verifyfile, "wb"))
|
||||
|
||||
--dump cart into file
|
||||
dump.dumptofile( file, 512, "UxROM", "PRGROM", true )
|
||||
|
||||
--close file
|
||||
assert(file:close())
|
||||
end
|
||||
|
||||
dict.io("IO_RESET")
|
||||
end
|
||||
|
||||
|
||||
-- global variables so other modules can use them
|
||||
|
||||
|
||||
-- call functions desired to run when script is called/imported
|
||||
|
||||
|
||||
-- functions other modules are able to call
|
||||
unrom.process = process
|
||||
|
||||
-- return the module's table
|
||||
return unrom
|
||||
Loading…
Reference in New Issue