Successful detection of UNROM512 mapper30 PRG-ROM flash

Processing input args to create rom file when dumping
Adding create_rom function in file.c working but need to add check if file already exists
Listing out number of mappers which planning to support
This commit is contained in:
paul eeepc 2016-12-09 01:58:34 -06:00
parent a89caf2454
commit dff396a1c2
10 changed files with 241 additions and 59 deletions

Binary file not shown.

View File

@ -158,7 +158,7 @@ int detect_mirroring( cartridge *cart, USBtransfer *transfer )
//detecting mapper and memories ends up being one big operation
int detect_map_mem( cartridge *cart, USBtransfer *transfer, int oper )
{
debug("detecting mapping");
//debug("detecting mapping");
//always start with resetting i/o
io_reset( transfer );
@ -176,7 +176,7 @@ int detect_map_mem( cartridge *cart, USBtransfer *transfer, int oper )
case FC_CART:
case NES_CART:
nes_init(transfer);
debug("NES cart mapping");
//debug("NES cart mapping");
//gather other helpful info
//result of chr-ram test
@ -184,57 +184,69 @@ int detect_map_mem( cartridge *cart, USBtransfer *transfer, int oper )
debug("CHR-RAM detected @ PPU $0000");
cart->sec_rom->manf = SRAM;
cart->sec_rom->part = SRAM;
} else
//check for CHR-ROM flash
}
//perform WRAM test without corrupting results
//TODO store result in save_mem
//mapper select switch<<<<-------------------------------------------------------------
switch (cart->mirroring) {
case MIR_MMC1:
break;
case MIR_MMC3:
break;
case MIR_FIXED:
//check for CHR-ROM flash
if ( cart->sec_rom->part != SRAM ) {
if ( read_flashID_chrrom_8K( transfer, cart->sec_rom ) == SUCCESS ) {
//8KB bank with no banking operations
debug("8K CHR-ROM flash detected");
cart->sec_rom->size = 8 * KBYTE;
}
//perform WRAM test without corrupting results
//TODO store result in save_mem
}
//exp0 pullup test passes on many INL boards
if ( exp0_pullup_test(transfer) == SUCCESS) {
debug("EXP0 pullup cart mapping");
//if passed exp0 test try 16/32KB bank flash check
//exp0 pullup test passes on many INL boards
if ( exp0_pullup_test(transfer) == SUCCESS) {
debug("EXP0 pullup cart mapping");
//if passed exp0 test try 16/32KB bank flash check
//if 16KB banks writing 0xFF to mapper reg should set A14 bit
//That will cause flash detection to fail.
//TODO handle bus conflicts...?
dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0x8000, 0xFF,
//if 16KB banks writing 0xFF to mapper reg should set A14 bit
//That will cause flash detection to fail.
//TODO handle bus conflicts...?
dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0x8000, 0xFF,
USB_IN, NULL, 1);
//if ID check passes, the should be 32KB PRG-ROM banking
if ( read_flashID_prgrom_exp0( transfer, cart->pri_rom ) == SUCCESS ) {
//32KB bank with EXP0->WE PRG-ROM sensed
debug("32KB banking NES EXP0 enabled flash");
cart->pri_rom->bank_size = 32 * KBYTE;
} else {
//set mapper reg to 0 if present which sets A14 low when needed if 16KB banks
dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0x8000, 0x00,
USB_IN, NULL, 1);
//if ID check passes, the should be 32KB PRG-ROM banking
if ( read_flashID_prgrom_exp0( transfer, cart->pri_rom ) == SUCCESS ) {
//32KB bank with EXP0->WE PRG-ROM sensed
debug("32KB banking NES EXP0 enabled flash");
cart->pri_rom->bank_size = 32 * KBYTE;
} else {
//set mapper reg to 0 if present which sets A14 low when needed if 16KB banks
dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0x8000, 0x00,
USB_IN, NULL, 1);
if ( read_flashID_prgrom_exp0( transfer, cart->pri_rom ) == SUCCESS ){
//16KB bank with EXP0->WE PRG-ROM sensed
debug("16KB banking NES EXP0 enabled flash");
cart->pri_rom->bank_size = 16 * KBYTE;
}
if ( read_flashID_prgrom_exp0( transfer, cart->pri_rom ) == SUCCESS ){
//16KB bank with EXP0->WE PRG-ROM sensed
debug("16KB banking NES EXP0 enabled flash");
cart->pri_rom->bank_size = 16 * KBYTE;
cart->mapper = UxROM;
}
//TODO determine how many banks are present
//best to do this by writing last bank, then see if
//blank banks can be found
}
switch (cart->mirroring) {
case MIR_MMC1:
break;
case MIR_MMC3:
break;
case MIR_FIXED:
break;
default:
sentinel("Problem with mapper detect mirroring switch statement.");
}
//TODO determine how many banks are present
//best to do this by writing last bank, then see if
//blank banks can be found
}
//check for mapper 30 controlled PRG-ROM writes
if ( read_flashID_prgrom_map30( transfer, cart->pri_rom ) == SUCCESS ){
debug("16KB mapper30 flash writes enabled");
cart->pri_rom->bank_size = 16 * KBYTE;
cart->mapper = UNROM512;
}
//TODO check for mapper 31 EZ-NSF
debug("PRG-ROM manfID: %x, prodID: %x", cart->pri_rom->manf, cart->pri_rom->part);
break;
default:
sentinel("Problem with mapper detect mirroring switch statement.");
}
//mapper select switch<<<<-------------------------------------------------------------
break;
//================
// SNES

View File

@ -12,8 +12,34 @@
#define SNES_CART 'S'
#define BKWD_CART 'B'
//NES mappers
#define NROM 0
#define MMC1 1
#define CNROM 2
#define UxROM 3
#define MMC3 4
#define MMC5 5
#define AxROM 7
#define MMC2 9
#define MMC4 10
#define CDREAMS 11
#define A53 28
#define UNROM512 30
#define EZNSF 31
#define BxROM 34
#define RAMBO 64
#define H3001 65 //IREM mapper
#define GxROM 66
#define SUN3 67
#define SUN4 68
#define FME7 69 //SUNSOFT-5 with synth
#define HDIVER 78
#define DxROM 205
enum mirroring {
MIR_FIXED = 10,
MIR_VERT,
MIR_HORIZ,
MIR_ANROM,
MIR_MMC1,
MIR_MMC3

View File

@ -1,19 +1,33 @@
#include "file.h"
#define SIZE_NES_HEADER 16
#define SIZE_PRG_BANK 16384
#define SIZE_CHR_BANK 8192
void init_rom_elements( rom_image *rom )
{
rom->console = UNKNOWN;
rom->mapper = UNKNOWN;
rom->submap = UNKNOWN;
rom->mapvariant = UNKNOWN;
rom->prg_size = UNKNOWN;
rom->chr_size = UNKNOWN;
rom->ram_size = UNKNOWN;
rom->battery = UNKNOWN;
rom->mirroring = UNKNOWN;
rom->fileptr = NULL;
}
//Need to pass in pointer to a filepointer to properly pass by reference
//the OS/stdio creates a FILE struct and returns the address of that struct
//so when this function opens a file it's setting the value of a pointer
//for the calling function. To set a pointer we must have a pointer to that pointer..
int open_file( FILE **fptr, char *filename )
//int open_file( FILE **fptr, char *filename )
int open_rom( rom_image *rom, char *filename )
{
//first open file
*fptr = fopen( filename, "rb");
//*fptr = fopen( filename, "rb");
rom->fileptr = fopen( filename, "rb");
//returns file ptr on success, NULL on fail
check( *fptr, "Unable to open file: %s in read binary mode", filename);
//check( *fptr, "Unable to open file: %s in read binary mode", filename);
check( rom->fileptr, "Unable to open file: %s in read binary mode", filename);
return SUCCESS;
error:
@ -78,3 +92,16 @@ int detect_file( rom_image *rom )
error:
return -1;
}
int create_file( rom_image *rom, char *filename )
{
//TODO check if file already exists, if so prompt if user would like to overwrite
rom->fileptr = fopen( filename, "wb+");
check( rom->fileptr, "Unable to create file: %s in read/write binary mode", filename);
return SUCCESS;
error:
return -1;
}

View File

@ -15,6 +15,11 @@
//TODO put defintions in separate project wide .h file
#include "cartridge.h"
#include "enums.h"
#define SIZE_NES_HEADER 16
#define SIZE_PRG_BANK 16384
#define SIZE_CHR_BANK 8192
//cartridge object/struct
typedef struct rom_image{
@ -30,7 +35,9 @@ typedef struct rom_image{
FILE *fileptr;
} rom_image;
int open_file( FILE **fptr, char *filename );
void init_rom_elements(rom_image *rom);
int open_rom( rom_image *rom, char *filename );
int detect_file( rom_image *rom );
int create_file( rom_image *rom, char *filename );
#endif

View File

@ -170,10 +170,10 @@ int main(int argc, char *argv[])
//create file object/struct
rom_image *rom = malloc( sizeof(rom_image));
rom->fileptr = NULL;
check_mem(transfer);
check_mem(rom);
init_rom_elements(rom);
//command line arg L_value to set different LIBUSB debugging options
@ -232,14 +232,37 @@ int main(int argc, char *argv[])
//read in user files/args that glean info about expected board
//for now just assume user file/args are correct
if ( p_value != NULL ) {
//program file provided at commandline
check( !open_file( &rom->fileptr, p_value ), "Problem opening file %s", p_value);
detect_file( rom );
//compare detections to user args and get permission to continue if there are discrepencies
//just dump based on input args for now
if ( d_value ) {
//TODO input arg checking
if ( c_value ) {
if ( strcmp( "NES", c_value ) == 0 ) rom->console = NES_CART;
if ( strcmp( "FC", c_value ) == 0 ) rom->console = FC_CART;
if ( strcmp( "SNES", c_value ) == 0 ) rom->console = SNES_CART;
}
debug("console is: %c", rom->console);
if ( m_value ) rom->mapper = atoi(m_value);
debug("mapper is: %d", rom->mapper);
if ( rom->mapper == NROM ) {
rom->prg_size = 32 * KBYTE;
rom->chr_size = 8 * KBYTE;
//TODO function to check mirroring
rom->mirroring = MIR_VERT;
}
//TODO check if enough input args were provided or can be detected
check( !create_file( rom, d_value ), "Unable to create file %s", d_value);
}
//compare detections to user args and get permission to continue if there are discrepencies
if ( p_value ) {
//program file provided at commandline
check( !open_rom( rom, p_value ), "Problem opening file %s", p_value);
detect_file( rom );
}
//if flashing, determine if erasures are necessary and where

View File

@ -7,6 +7,8 @@ void init_memory_elements( memory *mem )
mem->volatility = UNKNOWN;
mem->size = UNKNOWN;
mem->bank_size = UNKNOWN;
mem->wr_dict = UNKNOWN;
mem->wr_opcode = UNKNOWN;
mem->width = UNKNOWN;
mem->protocol = UNKNOWN;
mem->sector_size = UNKNOWN;

View File

@ -39,6 +39,8 @@ typedef struct memory{
int volatility; //sram no batt vs batt, mask rom, erasability, etc
int size; //size of the max addressable memory grounding addr pins lowers this value
int bank_size; //size of banks/pages of memory created by mapper banking
int wr_dict; //dictionary used to write to rom
int wr_opcode; //opcode used to write to rom
int width; //width of data bus as configured
int protocol; //parallel, SPI, I2C, JTAG, custom etc.
int sector_size; //minimum eraseable size in bytes

View File

@ -179,6 +179,7 @@ int famicom_sound( USBtransfer *transfer )
* if ROM A14 is mapper controlled it must be low when CPU A14 is low
* controlling A14 outside of this function acts as a means of bank size detection
* Post:memory manf/prod ID set to read values if passed
* memory wr_dict and wr_opcode set if successful
* Software mode exited if entered successfully
* Rtn: SUCCESS if flash sensed, GEN_FAIL if not, neg if error
*/
@ -218,6 +219,8 @@ int read_flashID_prgrom_exp0( USBtransfer *transfer, memory *flash ) {
//found expected manf and prod ID
flash->manf = SST_MANF_ID;
flash->part = rv[RV_DATA0_IDX];
flash->wr_dict = DICT_NES;
flash->wr_opcode = DISCRETE_EXP0_PRGROM_WR;
}
//exit software
@ -233,6 +236,82 @@ int read_flashID_prgrom_exp0( USBtransfer *transfer, memory *flash ) {
}
/* Desc:PRG-ROM flash manf/prod ID sense test
* Using mapper 30 defined PRG-ROM flash writes
* Only senses SST flash ID's
* Assumes that isn't getting tricked by having manf/prodID at $8000/8001
* could add check and increment read address to ensure doesn't get tricked..
* Pre: nes_init() been called to setup i/o
* Post:memory manf/prod ID set to read values if passed
* memory wr_dict and wr_opcode set if successful
* Software mode exited if entered successfully
* Rtn: SUCCESS if flash sensed, GEN_FAIL if not, neg if error
*/
int read_flashID_prgrom_map30( USBtransfer *transfer, memory *flash ) {
uint8_t rv[RV_DATA0_IDX];
//enter software mode
//$8000-BFFF writes to flash
//$C000-FFFF writes to mapper
// 15 14 13 12
// 0x5 = 0b 0 1 0 1 -> $9555
// 0x2 = 0b 0 0 1 0 -> $2AAA
//set A14 in mapper reg for $5555 command
dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0xC000, 0x01,
USB_IN, NULL, 1);
//write $5555 0xAA
dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0x9555, 0xAA,
USB_IN, NULL, 1);
//clear A14 in mapper reg for $2AAA command
dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0xC000, 0x00,
USB_IN, NULL, 1);
//write $2AAA 0x55
dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0xAAAA, 0x55,
USB_IN, NULL, 1);
//set A14 in mapper reg for $5555 command
dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0xC000, 0x01,
USB_IN, NULL, 1);
//write $5555 0x90 for software mode
dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0x9555, 0x90,
USB_IN, NULL, 1);
//read manf ID
dictionary_call( transfer, DICT_NES, NES_CPU_RD, 0x8000, NILL,
USB_IN, rv, RV_DATA0_IDX+1);
debug("manf id: %x", rv[RV_DATA0_IDX]);
if ( rv[RV_DATA0_IDX] != SST_MANF_ID ) {
return GEN_FAIL;
//no need for software exit since failed to enter
}
//read prod ID
dictionary_call( transfer, DICT_NES, NES_CPU_RD, 0x8001, NILL,
USB_IN, rv, RV_DATA0_IDX+1);
debug("prod id: %x", rv[RV_DATA0_IDX]);
if ( (rv[RV_DATA0_IDX] == SST_PROD_128)
|| (rv[RV_DATA0_IDX] == SST_PROD_256)
|| (rv[RV_DATA0_IDX] == SST_PROD_512) ) {
//found expected manf and prod ID
flash->manf = SST_MANF_ID;
flash->part = rv[RV_DATA0_IDX];
flash->wr_dict = DICT_NES;
flash->wr_opcode = NES_CPU_WR;
}
//exit software
dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0x8000, 0xF0,
USB_IN, NULL, 1);
//verify exited
dictionary_call( transfer, DICT_NES, NES_CPU_RD, 0x8000, NILL,
USB_IN, rv, RV_DATA0_IDX+1);
debug("prod id: %x", rv[RV_DATA0_IDX]);
return SUCCESS;
}
/* Desc:CHR-ROM flash manf/prod ID sense test
* Only senses SST flash ID's
* Does not make CHR bank writes so A14-A13 must be made valid outside of this funciton
@ -242,6 +321,7 @@ int read_flashID_prgrom_exp0( USBtransfer *transfer, memory *flash ) {
* could add check and increment read address to ensure doesn't get tricked..
* Pre: nes_init() been called to setup i/o
* Post:memory manf/prod ID set to read values if passed
* memory wr_dict and wr_opcode set if successful
* Software mode exited if entered successfully
* Rtn: SUCCESS if flash sensed, GEN_FAIL if not, neg if error
*/
@ -281,6 +361,8 @@ int read_flashID_chrrom_8K( USBtransfer *transfer, memory *flash ) {
//found expected manf and prod ID
flash->manf = SST_MANF_ID;
flash->part = rv[RV_DATA0_IDX];
flash->wr_dict = DICT_NES;
flash->wr_opcode = NES_PPU_WR;
}
//exit software

View File

@ -9,7 +9,7 @@
//include prior to other file includes
//that way DEBUG can be turned on/off for this file alone
//uncomment to DEBUG this file alone
#define DEBUG
//#define DEBUG
//"make debug" to get DEBUG msgs on entire program
#include "dbg.h"
@ -24,6 +24,7 @@ int jumper_ciramce_ppuA13n( USBtransfer *transfer );
int ciramce_inv_ppuA13( USBtransfer *transfer );
int famicom_sound( USBtransfer *transfer );
int read_flashID_prgrom_exp0( USBtransfer *transfer, memory *flash );
int read_flashID_prgrom_map30( USBtransfer *transfer, memory *flash );
int read_flashID_chrrom_8K( USBtransfer *transfer, memory *flash );
int ppu_ram_sense( USBtransfer *transfer, uint16_t addr );