Have BNROM, and action53 working in PLCC and TSSOP.
Also added swim reading of stack bottom for CICOp signature. Starting to add scripts for different mappers. Need to clean things up quite a bit as everything was a bit of a hack just so I could start building lizards and A53. Need to add back NROM, and add UNROM as well. Need to have program find bank table for itself both in the program and in a cartridge. Having problems with SWIM on new discrete NES boards for some reason. Some boards are flakey and I march right in and start writting to config bytes which will brick the device if communications are failing (and there's no reset pin...) as is with the stm8s001
This commit is contained in:
parent
c208924e45
commit
223007187b
|
|
@ -20,12 +20,24 @@ uint8_t dump_buff( buffer *buff ) {
|
|||
case PRGROM:
|
||||
addrH |= 0x80; //$8000
|
||||
if (buff->mapper == BxROM) {
|
||||
bank = (buff->page_num)>>7;
|
||||
//write bank value to bank table
|
||||
//page_num shift by 6 bits A15 >> A8(0)
|
||||
//page_num shift by 7 bits A15 >> A8(0)
|
||||
bank = (buff->page_num)>>7;
|
||||
//Lizard bank table @ FF94
|
||||
nes_cpu_wr( (0xFF94+bank), bank );
|
||||
}
|
||||
if (buff->mapper == A53) {
|
||||
//write bank value to bank table
|
||||
//page_num shift by 7 bits A15 >> A8(0)
|
||||
bank = (buff->page_num)>>7;
|
||||
//Setup as CNROM, then scroll through outer banks.
|
||||
//cpu_wr(0x5000, 0x80); //reg select mode
|
||||
// xxSSPPMM SS-size: 0-32KB, PP-prg mode: 0,1 32KB, MM-mirror
|
||||
//cpu_wr(0x8000, 0b00000000); //reg value 256KB inner, 32KB banks
|
||||
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
|
||||
}
|
||||
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 );
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ uint8_t write_page( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr wr_
|
|||
uint8_t n = buff->cur_byte;
|
||||
uint8_t read;
|
||||
// extern operation_info *oper_info;
|
||||
//
|
||||
|
||||
while ( cur <= buff->last_idx ) {
|
||||
//write unlock sequence
|
||||
|
|
@ -26,11 +27,14 @@ uint8_t write_page( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr wr_
|
|||
// 4KB banking A11-0 NES ctl, A12+ mapper ctl "bank" ezNSF
|
||||
//addrH_dmask = 0b0000 1111
|
||||
//page2bankshft = A11->A8 = 4 shifts
|
||||
wr_func( 0x5555, 0xAA );
|
||||
//wr_func( 0x5555, 0xAA );
|
||||
wr_func( 0xD555, 0xAA );
|
||||
// wr_func( oper_info->unlock1_AH, oper_info->unlock1_AL, oper_info->unlock1_data );
|
||||
wr_func( 0x2AAA, 0x55 );
|
||||
//wr_func( 0x2AAA, 0x55 );
|
||||
wr_func( 0xAAAA, 0x55 );
|
||||
// wr_func( oper_info->unlock2_AH, oper_info->unlock2_AL, oper_info->unlock2_data );
|
||||
wr_func( 0x5555, 0xA0 );
|
||||
//wr_func( 0x5555, 0xA0 );
|
||||
wr_func( 0xD555, 0xA0 );
|
||||
// wr_func( oper_info->command_AH, oper_info->command_AL, oper_info->command1_data );
|
||||
wr_func( ((addrH<<8)| n), buff->data[n] );
|
||||
|
||||
|
|
@ -42,15 +46,18 @@ uint8_t write_page( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr wr_
|
|||
|
||||
//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 {
|
||||
LED_OP();
|
||||
LED_HI();
|
||||
}
|
||||
// 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();
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -60,6 +67,90 @@ uint8_t write_page( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr wr_
|
|||
|
||||
}
|
||||
|
||||
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;
|
||||
uint8_t n = buff->cur_byte;
|
||||
uint8_t read;
|
||||
// extern operation_info *oper_info;
|
||||
//
|
||||
|
||||
//enter unlock bypass mode
|
||||
wr_func( 0x8AAA, 0xAA );
|
||||
wr_func( 0x8555, 0x55 );
|
||||
wr_func( 0x8AAA, 0x20 );
|
||||
|
||||
while ( cur <= buff->last_idx ) {
|
||||
//write unlock sequence
|
||||
//need to make address and unlock data variable
|
||||
//best for host to communcate these values
|
||||
//actual value is part mapper dependent and part flash dependent
|
||||
//mapper controlled address bits dictate where split is
|
||||
//32KB banking A14-0 NES ctl, A15+ mapper ctl "bank" NROM, BNROM, ANROM
|
||||
//addrH_dmask = 0b0111 1111 directly addressable addrH bits
|
||||
//page2bankshft = A14->A8 = 7 shifts (equal to number of set bits in addrH_mask
|
||||
//16KB banking A13-0 NES ctl, A14+ mapper ctl "bank" UxROM, MMC1
|
||||
//addrH_dmask = 0b0011 1111
|
||||
//page2bankshft = A13->A8 = 6 shifts
|
||||
// 8KB banking A12-0 NES ctl, A13+ mapper ctl "bank" MMC3, FME7
|
||||
//addrH_dmask = 0b0001 1111
|
||||
//page2bankshft = A12->A8 = 5 shifts
|
||||
// 4KB banking A11-0 NES ctl, A12+ mapper ctl "bank" ezNSF
|
||||
//addrH_dmask = 0b0000 1111
|
||||
//page2bankshft = A11->A8 = 4 shifts
|
||||
//wr_func( 0x5555, 0xAA );
|
||||
// wr_func( 0x8AAA, 0xAA );
|
||||
//// wr_func( oper_info->unlock1_AH, oper_info->unlock1_AL, oper_info->unlock1_data );
|
||||
// //wr_func( 0x2AAA, 0x55 );
|
||||
// wr_func( 0x8555, 0x55 );
|
||||
//// wr_func( oper_info->unlock2_AH, oper_info->unlock2_AL, oper_info->unlock2_data );
|
||||
// //wr_func( 0x5555, 0xA0 );
|
||||
// wr_func( 0x8AAA, 0xA0 );
|
||||
//// wr_func( oper_info->command_AH, oper_info->command_AL, oper_info->command1_data );
|
||||
// wr_func( ((addrH<<8)| n), buff->data[n] );
|
||||
|
||||
|
||||
// curaddresswrite( 0xA0 ); //gained ~3KBps (59.13KBps) inl6 with v3.0 proto
|
||||
wr_func( ((addrH<<8)| n), 0xA0 );
|
||||
|
||||
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;
|
||||
|
||||
//exit unlock bypass mode
|
||||
wr_func( 0x8000, 0x90 );
|
||||
wr_func( 0x8000, 0x00 );
|
||||
//reset the flash chip, supposed to exit too
|
||||
wr_func( 0x8000, 0xF0 );
|
||||
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
uint8_t write_page_chr( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr wr_func, read_funcptr rd_func )
|
||||
{
|
||||
uint16_t cur = buff->cur_byte;
|
||||
|
|
@ -364,7 +455,28 @@ uint8_t flash_buff( buffer *buff ) {
|
|||
//Lizard banktable location
|
||||
nes_cpu_wr( (0xFF94+bank), bank );
|
||||
}
|
||||
write_page( 0, (0x80 | addrH), buff, discrete_exp0_prgrom_wr, nes_cpu_rd );
|
||||
if (buff->mapper == A53) {
|
||||
//write bank value to bank table
|
||||
//page_num shift by 7 bits A15 >> A8(0)
|
||||
bank = (buff->page_num)>>7;
|
||||
//Setup as CNROM, then scroll through outer banks.
|
||||
//cpu_wr(0x5000, 0x80); //reg select mode
|
||||
// xxSSPPMM SS-size: 0-32KB, PP-prg mode: 0,1 32KB, MM-mirror
|
||||
//cpu_wr(0x8000, 0b00000000); //reg value 256KB inner, 32KB banks
|
||||
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
|
||||
|
||||
//need to use standard CPU writes
|
||||
//write_page( 0, (0x80 | addrH), buff, nes_cpu_wr, nes_cpu_rd );
|
||||
//break;
|
||||
}
|
||||
//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 );
|
||||
|
|
|
|||
|
|
@ -312,6 +312,36 @@ local function swim_test()
|
|||
end
|
||||
|
||||
|
||||
local function read_stack()
|
||||
|
||||
--STM8 stack starts at $0200 which is where the CIC version
|
||||
--and other special data is placed starting with v2.0
|
||||
local stack_start = 0x0200
|
||||
local last_char = 73
|
||||
local ack
|
||||
local data = {}
|
||||
|
||||
--read
|
||||
for i = 0, last_char do
|
||||
ack, data[i+1] = rotf(stack_start+i, true, false)
|
||||
end
|
||||
|
||||
print("\n")
|
||||
|
||||
local j = 1
|
||||
while data[j] do
|
||||
io.write(string.char(data[j]))
|
||||
j = j+1
|
||||
end
|
||||
print("\n")
|
||||
|
||||
-- print("rotf :", string.format("%X %X", dict.swim("ROTF_HS", 0x0000)))
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function start( debug )
|
||||
|
||||
--dict.io("IO_RESET")
|
||||
|
|
@ -570,6 +600,7 @@ swim.printCSR = printCSR
|
|||
swim.wotf = wotf
|
||||
swim.rotf = rotf
|
||||
swim.swim_test = swim_test
|
||||
swim.read_stack = read_stack
|
||||
swim.snes_v3_prgm = snes_v3_prgm
|
||||
swim.snes_v3_play = snes_v3_play
|
||||
swim.stop_and_reset = stop_and_reset
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ function main ()
|
|||
--cart/mapper specific scripts
|
||||
--local curcart = require "scripts.nes.nrom"
|
||||
local curcart = require "scripts.nes.bnrom"
|
||||
--local curcart = require "scripts.nes.action53"
|
||||
--local curcart = require "scripts.nes.action53_tsop"
|
||||
|
||||
local rv
|
||||
-- rv = dict.pinport( "DATA_SET", 0xAA )
|
||||
|
|
@ -55,7 +57,7 @@ function main ()
|
|||
dict.io("IO_RESET")
|
||||
dict.io("NES_INIT")
|
||||
|
||||
---[[
|
||||
--[[
|
||||
--NES detect mirroring to gain mapper info
|
||||
nes.detect_mapper_mirroring(true)
|
||||
--NES detect memories to gain more mapper/board info
|
||||
|
|
@ -88,11 +90,12 @@ function main ()
|
|||
print("start swim")
|
||||
|
||||
dict.io("SWIM_INIT", "SWIM_ON_A0")
|
||||
----[[
|
||||
if swim.start(true) then
|
||||
--SWIM is now established and running at HIGH SPEED
|
||||
snes_swimcart = false --don't want to use SWIM pin to control flash /OE, use SNES RESET (EXP0) instead
|
||||
|
||||
-- swim.swim_test()
|
||||
swim.swim_test()
|
||||
|
||||
--swim.write_optn_bytes( true, true ) -- enable ROP, debug
|
||||
|
||||
|
|
@ -101,10 +104,11 @@ function main ()
|
|||
swim.disable_ROP_erase(true)
|
||||
|
||||
--open CIC file
|
||||
--local cic_file = assert(io.open("stm8_8KB_zero.bin", "rb"))
|
||||
local cic_file = assert(io.open("stm8_8KB_zero.bin", "rb"))
|
||||
--local cic_file = assert(io.open("stm8_8KB_0xff.bin", "rb"))
|
||||
--local cic_file = assert(io.open("stm8_8KB_testpattern.bin", "rb"))
|
||||
local cic_file = assert(io.open("NESCIC.bin", "rb"))
|
||||
--local cic_file = assert(io.open("NESCIC.bin", "rb"))
|
||||
--local cic_file = assert(io.open("LIZv1.bin", "rb"))
|
||||
|
||||
--write CIC file
|
||||
swim.write_flash( cic_file )
|
||||
|
|
@ -113,7 +117,7 @@ function main ()
|
|||
assert(cic_file:close())
|
||||
|
||||
--set ROP & AFR0
|
||||
swim.write_optn_bytes( false, true ) -- ROP not set, debug set
|
||||
swim.write_optn_bytes( true, true ) -- ROP not set, debug set
|
||||
|
||||
-- reset STM8 CIC and end SWIM comms to it can execute what we just flashed
|
||||
swim.stop_and_reset()
|
||||
|
|
@ -124,6 +128,23 @@ function main ()
|
|||
print("done flashing STM8 on A0")
|
||||
|
||||
dict.io("IO_RESET")
|
||||
|
||||
--]]
|
||||
|
||||
---[[
|
||||
--test reading back CIC version
|
||||
dict.io("SWIM_INIT", "SWIM_ON_A0")
|
||||
if swim.start(true) then
|
||||
|
||||
swim.read_stack()
|
||||
|
||||
else
|
||||
print("ERROR trying to read back CIC signature stack data")
|
||||
end
|
||||
|
||||
print("done flashing STM8 on A0")
|
||||
|
||||
dict.io("IO_RESET")
|
||||
--]]
|
||||
|
||||
|
||||
|
|
@ -132,8 +153,13 @@ function main ()
|
|||
--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, true, "ignore/dump.bin", "ignore/lizard_v1.bin", "ignore/verifyout.bin")
|
||||
--curcart.process( true, false, false, false, "ignore/dump.bin", "ignore/lizard_v1.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")
|
||||
--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")
|
||||
|
||||
|
||||
--[[
|
||||
|
|
|
|||
|
|
@ -0,0 +1,189 @@
|
|||
|
||||
-- create the module's table
|
||||
local action53 = {}
|
||||
|
||||
-- import required modules
|
||||
local dict = require "scripts.app.dict"
|
||||
local dump = require "scripts.app.dump"
|
||||
local flash = require "scripts.app.flash"
|
||||
|
||||
-- file constants
|
||||
|
||||
-- local functions
|
||||
|
||||
--local function wr_flash_byte(addr, value, debug)
|
||||
|
||||
--base is the actual NES CPU address, not the rom offset (ie $FFF0, not $7FF0)
|
||||
--local function wr_bank_table(base, entries)
|
||||
--Action53 not susceptible to bus conflicts, no banktable needed
|
||||
|
||||
|
||||
|
||||
--initialize mapper for dump/flash routines
|
||||
local function init_mapper( debug )
|
||||
|
||||
--//Setup as CNROM, then scroll through outer banks.
|
||||
--cpu_wr(0x5000, 0x80); //reg select mode
|
||||
dict.nes("NES_CPU_WR", 0x5000, 0x80)
|
||||
|
||||
--// xxSSPPMM SS-size: 0-32KB, PP-prg mode: 0,1 32KB, MM-mirror
|
||||
--cpu_wr(0x8000, 0b00000000); //reg value 256KB inner, 32KB banks
|
||||
dict.nes("NES_CPU_WR", 0x8000, 0x00)
|
||||
--cpu_wr(0x5000, 0x81); //outer reg select mode
|
||||
dict.nes("NES_CPU_WR", 0x5000, 0x81)
|
||||
--cpu_wr(0x8000, 0x00); //first 32KB bank
|
||||
dict.nes("NES_CPU_WR", 0x8000, 0x00)
|
||||
--
|
||||
--cpu_wr(0x5000, 0x01); //inner prg reg select
|
||||
dict.nes("NES_CPU_WR", 0x5000, 0x01)
|
||||
--cpu_wr(0x8000, 0x00); //controls nothing in this size
|
||||
dict.nes("NES_CPU_WR", 0x8000, 0x00)
|
||||
--cpu_wr(0x5000, 0x00); //chr reg select
|
||||
dict.nes("NES_CPU_WR", 0x5000, 0x00)
|
||||
--cpu_wr(0x8000, 0x00); //first chr bank
|
||||
dict.nes("NES_CPU_WR", 0x8000, 0x00)
|
||||
--selecting CNROM means that mapper writes to $8000-FFFF will only change the CHR-RAM bank which
|
||||
--doesn't affect anything we're concerned about
|
||||
|
||||
end
|
||||
|
||||
|
||||
--read PRG-ROM flash ID
|
||||
local function prgrom_manf_id( debug )
|
||||
|
||||
init_mapper()
|
||||
|
||||
if debug then print("reading PRG-ROM manf ID") end
|
||||
--A0-A14 are all directly addressable in CNROM mode
|
||||
--and mapper writes don't affect PRG banking
|
||||
dict.nes("NES_CPU_WR", 0xD555, 0xAA)
|
||||
dict.nes("NES_CPU_WR", 0xAAAA, 0x55)
|
||||
dict.nes("NES_CPU_WR", 0xD555, 0x90)
|
||||
rv = dict.nes("NES_CPU_RD", 0x8000)
|
||||
if debug then print("attempted read PRG-ROM manf ID:", string.format("%X", rv)) end
|
||||
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("NES_CPU_WR", 0x8000, 0xF0)
|
||||
|
||||
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
|
||||
prgrom_manf_id(true)
|
||||
end
|
||||
|
||||
|
||||
--dump the cart to dumpfile
|
||||
if read then
|
||||
--initialize the mapper for dumping
|
||||
init_mapper(debug)
|
||||
|
||||
file = assert(io.open(dumpfile, "wb"))
|
||||
|
||||
--TODO find bank table to avoid bus conflicts!
|
||||
--dump cart into file
|
||||
dump.dumptofile( file, 512, "A53", "PRGROM", true )
|
||||
|
||||
--close file
|
||||
assert(file:close())
|
||||
end
|
||||
|
||||
--erase the cart
|
||||
if erase then
|
||||
|
||||
--initialize the mapper for erasing
|
||||
init_mapper(debug)
|
||||
|
||||
print("\nerasing action53");
|
||||
|
||||
print("erasing PRG-ROM");
|
||||
--A0-A14 are all directly addressable in CNROM mode
|
||||
--and mapper writes don't affect PRG banking
|
||||
dict.nes("NES_CPU_WR", 0xD555, 0xAA)
|
||||
dict.nes("NES_CPU_WR", 0xAAAA, 0x55)
|
||||
dict.nes("NES_CPU_WR", 0xD555, 0x80)
|
||||
dict.nes("NES_CPU_WR", 0xD555, 0xAA)
|
||||
dict.nes("NES_CPU_WR", 0xAAAA, 0x55)
|
||||
dict.nes("NES_CPU_WR", 0xD555, 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
|
||||
|
||||
--initialize the mapper for dumping
|
||||
init_mapper(debug)
|
||||
|
||||
--open file
|
||||
file = assert(io.open(flashfile, "rb"))
|
||||
--determine if auto-doubling, deinterleaving, etc,
|
||||
--needs done to make board compatible with rom
|
||||
|
||||
--not susceptible to bus conflicts
|
||||
|
||||
--flash cart
|
||||
flash.write_file( file, 512, "A53", "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
|
||||
|
||||
--initialize the mapper for dumping
|
||||
init_mapper(debug)
|
||||
|
||||
file = assert(io.open(verifyfile, "wb"))
|
||||
|
||||
--dump cart into file
|
||||
dump.dumptofile( file, 512, "A53", "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
|
||||
action53.process = process
|
||||
|
||||
-- return the module's table
|
||||
return action53
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
|
||||
-- create the module's table
|
||||
local action53_tsop = {}
|
||||
|
||||
-- import required modules
|
||||
local dict = require "scripts.app.dict"
|
||||
local dump = require "scripts.app.dump"
|
||||
local flash = require "scripts.app.flash"
|
||||
|
||||
-- file constants
|
||||
|
||||
-- local functions
|
||||
|
||||
--local function wr_flash_byte(addr, value, debug)
|
||||
|
||||
--base is the actual NES CPU address, not the rom offset (ie $FFF0, not $7FF0)
|
||||
--local function wr_bank_table(base, entries)
|
||||
--Action53 not susceptible to bus conflicts, no banktable needed
|
||||
|
||||
|
||||
|
||||
--initialize mapper for dump/flash routines
|
||||
local function init_mapper( debug )
|
||||
|
||||
--//Setup as CNROM, then scroll through outer banks.
|
||||
--cpu_wr(0x5000, 0x80); //reg select mode
|
||||
dict.nes("NES_CPU_WR", 0x5000, 0x80)
|
||||
|
||||
--// xxSSPPMM SS-size: 0-32KB, PP-prg mode: 0,1 32KB, MM-mirror
|
||||
--cpu_wr(0x8000, 0b00000000); //reg value 256KB inner, 32KB banks
|
||||
dict.nes("NES_CPU_WR", 0x8000, 0x00)
|
||||
--cpu_wr(0x5000, 0x81); //outer reg select mode
|
||||
dict.nes("NES_CPU_WR", 0x5000, 0x81)
|
||||
--cpu_wr(0x8000, 0x00); //first 32KB bank
|
||||
dict.nes("NES_CPU_WR", 0x8000, 0x00)
|
||||
--
|
||||
--cpu_wr(0x5000, 0x01); //inner prg reg select
|
||||
dict.nes("NES_CPU_WR", 0x5000, 0x01)
|
||||
--cpu_wr(0x8000, 0x00); //controls nothing in this size
|
||||
dict.nes("NES_CPU_WR", 0x8000, 0x00)
|
||||
--cpu_wr(0x5000, 0x00); //chr reg select
|
||||
dict.nes("NES_CPU_WR", 0x5000, 0x00)
|
||||
--cpu_wr(0x8000, 0x00); //first chr bank
|
||||
dict.nes("NES_CPU_WR", 0x8000, 0x00)
|
||||
--selecting CNROM means that mapper writes to $8000-FFFF will only change the CHR-RAM bank which
|
||||
--doesn't affect anything we're concerned about
|
||||
|
||||
--enable flash writes $5000 set to 0b0 101 010 0
|
||||
dict.nes("NES_CPU_WR", 0x5000, 0x54)
|
||||
|
||||
end
|
||||
|
||||
|
||||
--read PRG-ROM flash ID
|
||||
local function prgrom_manf_id( debug )
|
||||
|
||||
init_mapper()
|
||||
|
||||
if debug then print("reading PRG-ROM manf ID") end
|
||||
--A0-A14 are all directly addressable in CNROM mode
|
||||
--and mapper writes don't affect PRG banking
|
||||
dict.nes("NES_CPU_WR", 0x8AAA, 0xAA)
|
||||
dict.nes("NES_CPU_WR", 0x8555, 0x55)
|
||||
dict.nes("NES_CPU_WR", 0x8AAA, 0x90)
|
||||
rv = dict.nes("NES_CPU_RD", 0x8000)
|
||||
if debug then print("attempted read PRG-ROM manf ID:", string.format("%X", rv)) end --0x01
|
||||
rv = dict.nes("NES_CPU_RD", 0x8002)
|
||||
if debug then print("attempted read PRG-ROM prod ID:", string.format("%X", rv)) end --0xDA(top), 0x5B(bot)
|
||||
-- rv = dict.nes("NES_CPU_RD", 0x801C)
|
||||
-- if debug then print("attempted read PRG-ROM density ID:", string.format("%X", rv)) end
|
||||
-- rv = dict.nes("NES_CPU_RD", 0x801E)
|
||||
-- if debug then print("attempted read PRG-ROM bootsect ID:", string.format("%X", rv)) end
|
||||
|
||||
--exit software
|
||||
dict.nes("NES_CPU_WR", 0x8000, 0xF0)
|
||||
|
||||
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
|
||||
prgrom_manf_id(true)
|
||||
end
|
||||
|
||||
--dump the cart to dumpfile
|
||||
if read then
|
||||
--initialize the mapper for dumping
|
||||
init_mapper(debug)
|
||||
|
||||
file = assert(io.open(dumpfile, "wb"))
|
||||
|
||||
--TODO find bank table to avoid bus conflicts!
|
||||
--dump cart into file
|
||||
dump.dumptofile( file, 1024, "A53", "PRGROM", true )
|
||||
|
||||
--close file
|
||||
assert(file:close())
|
||||
end
|
||||
|
||||
--erase the cart
|
||||
if erase then
|
||||
|
||||
--initialize the mapper for erasing
|
||||
init_mapper(debug)
|
||||
|
||||
print("\nerasing action53 tsop takes ~30sec");
|
||||
|
||||
print("erasing PRG-ROM");
|
||||
--A0-A14 are all directly addressable in CNROM mode
|
||||
--only A0-A11 are required to be valid for tsop-48
|
||||
--and mapper writes don't affect PRG banking
|
||||
dict.nes("NES_CPU_WR", 0x8AAA, 0xAA)
|
||||
dict.nes("NES_CPU_WR", 0x8555, 0x55)
|
||||
dict.nes("NES_CPU_WR", 0x8AAA, 0x80)
|
||||
dict.nes("NES_CPU_WR", 0x8AAA, 0xAA)
|
||||
dict.nes("NES_CPU_WR", 0x8555, 0x55)
|
||||
dict.nes("NES_CPU_WR", 0x8AAA, 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
|
||||
|
||||
--initialize the mapper for dumping
|
||||
init_mapper(debug)
|
||||
|
||||
--open file
|
||||
file = assert(io.open(flashfile, "rb"))
|
||||
--determine if auto-doubling, deinterleaving, etc,
|
||||
--needs done to make board compatible with rom
|
||||
|
||||
--not susceptible to bus conflicts
|
||||
|
||||
--flash cart
|
||||
flash.write_file( file, 1024, "A53", "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
|
||||
|
||||
--initialize the mapper for dumping
|
||||
init_mapper(debug)
|
||||
|
||||
file = assert(io.open(verifyfile, "wb"))
|
||||
|
||||
--dump cart into file
|
||||
dump.dumptofile( file, 1024, "A53", "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
|
||||
action53_tsop.process = process
|
||||
|
||||
-- return the module's table
|
||||
return action53_tsop
|
||||
|
|
@ -66,7 +66,7 @@ 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
|
||||
|
|
@ -75,6 +75,10 @@ local function process( read, erase, program, verify, dumpfile, flashfile, verif
|
|||
dict.io("IO_RESET")
|
||||
dict.io("NES_INIT")
|
||||
|
||||
--test cart by reading manf/prod ID
|
||||
if test then
|
||||
-- prgrom_manf_id(true)
|
||||
end
|
||||
|
||||
--dump the cart to dumpfile
|
||||
if read then
|
||||
|
|
|
|||
Loading…
Reference in New Issue