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:
Paul Black ASUS win7 2018-03-18 14:39:45 -05:00
parent 223007187b
commit f7201f44b7
6 changed files with 318 additions and 26 deletions

View File

@ -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)

View File

@ -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 );

View File

@ -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")
--[[

View File

@ -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

View File

@ -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

174
host/scripts/nes/unrom.lua Normal file
View File

@ -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