diff --git a/firmware/source/dump.c b/firmware/source/dump.c index 42e1792..241f97a 100644 --- a/firmware/source/dump.c +++ b/firmware/source/dump.c @@ -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) diff --git a/firmware/source/flash.c b/firmware/source/flash.c index bb89bd0..2c8fd95 100644 --- a/firmware/source/flash.c +++ b/firmware/source/flash.c @@ -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 ); diff --git a/host/scripts/inlretro.lua b/host/scripts/inlretro.lua index 2332052..756310d 100644 --- a/host/scripts/inlretro.lua +++ b/host/scripts/inlretro.lua @@ -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") --[[ diff --git a/host/scripts/nes/bnrom.lua b/host/scripts/nes/bnrom.lua index 018cb9d..5eda7f0 100644 --- a/host/scripts/nes/bnrom.lua +++ b/host/scripts/nes/bnrom.lua @@ -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 diff --git a/host/scripts/nes/nrom.lua b/host/scripts/nes/nrom.lua index efb1482..61a183a 100644 --- a/host/scripts/nes/nrom.lua +++ b/host/scripts/nes/nrom.lua @@ -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 diff --git a/host/scripts/nes/unrom.lua b/host/scripts/nes/unrom.lua new file mode 100644 index 0000000..59e978c --- /dev/null +++ b/host/scripts/nes/unrom.lua @@ -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