Big overdue commit of past few days effort..

Detecting mirroring code working and tested
Started working on buffer operations from host
Current code compiles but not yet at point where can start testing
Adding cpu page read to nes.c to have faster dumping operations.
moving enums to shared as gets used quite a bit communicating between device and host.
This commit is contained in:
paul eeepc 2016-12-11 01:06:41 -06:00
parent dff396a1c2
commit 4db2929c3b
24 changed files with 667 additions and 153 deletions

View File

@ -8,6 +8,9 @@ buffer *cur_usb_load_buff;
//uint16_t incoming_bytes_remain;
uint8_t incoming_bytes_remain;
//host means of communicating to buffer manager
uint8_t operation;
//min define of two buffers
static buffer buff0;
static buffer buff1;
@ -176,6 +179,9 @@ uint8_t buffer_opcode_no_return( uint8_t opcode, buffer *buff,
case RAW_BUFFER_RESET:
raw_buffer_reset();
break;
case SET_BUFFER_OPERATION:
operation = operLSB;
break;
case SET_MEM_N_PART:
buff->mem_type = operMSB;
buff->part_num = operLSB;
@ -470,50 +476,165 @@ uint8_t allocate_buffer( buffer *buff, uint8_t new_id, uint8_t base_bank, uint8_
}
//used to determine how many buffers are in use at start of new operation
//assume buffers are instantiated in order starting with zero.
uint8_t num_alloc_buffers( void )
{
uint8_t rv = 0;
if ( buff0.status != UNALLOC ) rv = 1;
if ( buff1.status != UNALLOC ) rv = 2;
#if ( defined(NUM_BUFFERS_4) || (defined(NUM_BUFFERS_8)) )
if ( buff2.status != UNALLOC ) rv = 3;
if ( buff3.status != UNALLOC ) rv = 4;
#endif
#ifdef NUM_BUFFERS_8
if ( buff4.status != UNALLOC ) rv = 5;
if ( buff5.status != UNALLOC ) rv = 6;
if ( buff6.status != UNALLOC ) rv = 7;
if ( buff7.status != UNALLOC ) rv = 8;
#endif
return rv;
}
//get next buffer provide a buffer pointer and number of buffers in use
//return pointer to next buffer in sequence
buffer * get_next_buff( buffer *buff, uint8_t num )
{
//if there's 2 buffers need to toggle between 0 & 1
if ( num == 2 ) {
if ( buff == &buff0 ) return &buff1;
if ( buff == &buff1 ) return &buff0;
}
#if ( defined(NUM_BUFFERS_4) || (defined(NUM_BUFFERS_8)) )
//if there's 3-4 buffers cycle through
if ( num == 3 ) {
if ( buff == &buff0 ) return &buff1;
if ( buff == &buff1 ) return &buff2;
if ( buff == &buff2 ) return &buff0;
}
if ( num == 4 ) {
if ( buff == &buff0 ) return &buff1;
if ( buff == &buff1 ) return &buff2;
if ( buff == &buff2 ) return &buff3;
if ( buff == &buff3 ) return &buff0;
}
#endif
#ifdef NUM_BUFFERS_8
if ( num == 5 ) {
if ( buff == &buff0 ) return &buff1;
if ( buff == &buff1 ) return &buff2;
if ( buff == &buff2 ) return &buff3;
if ( buff == &buff3 ) return &buff4;
if ( buff == &buff4 ) return &buff0;
}
if ( num == 6 ) {
if ( buff == &buff0 ) return &buff1;
if ( buff == &buff1 ) return &buff2;
if ( buff == &buff2 ) return &buff3;
if ( buff == &buff3 ) return &buff4;
if ( buff == &buff4 ) return &buff5;
if ( buff == &buff5 ) return &buff0;
}
if ( num == 7 ) {
if ( buff == &buff0 ) return &buff1;
if ( buff == &buff1 ) return &buff2;
if ( buff == &buff2 ) return &buff3;
if ( buff == &buff3 ) return &buff4;
if ( buff == &buff4 ) return &buff5;
if ( buff == &buff5 ) return &buff6;
if ( buff == &buff6 ) return &buff0;
}
if ( num == 8 ) {
if ( buff == &buff0 ) return &buff1;
if ( buff == &buff1 ) return &buff2;
if ( buff == &buff2 ) return &buff3;
if ( buff == &buff3 ) return &buff4;
if ( buff == &buff4 ) return &buff5;
if ( buff == &buff5 ) return &buff6;
if ( buff == &buff6 ) return &buff7;
if ( buff == &buff7 ) return &buff0;
}
#endif
//if there's only one buffer, or if some other error, just return sent buffer ptr
//if ( num == 1 ) return buff;
return buff;
}
//check buffer status' and instruct them to
//flash/dump as needed to keep data moving
void update_buffers()
{
uint8_t result = 0;
buffer *buff = &buff0;
static uint8_t num_buff;
static buffer *cur_buff;
//when dumping we don't actually know when the buffer has been fully
//read back through USB IN transfer. But we know when the next buffer
//is requested to read back, so we'll dump the second page into the second buffer
//after the first page has been requested for IN transfer
//need to get data dumped before in transfer..
//operations start by host resetting and initializing buffers
//this buffer manager is blind to the size of buffers and other such details
//this manager only needs to know which buffers are active
//but the host sets operation when it wants this manager to send
//little buffers out to start dumping/flashing
if ( (operation == STARTDUMP) || (operation == STARTFLASH ) ) {
//only want to do this once per operation at the start
//figure out how many buffers are in operation
//assume buff0 is first and follows 1, 2, etc
num_buff = num_alloc_buffers();
//now that we know how many buffers there are in use
//we always start with buff0
cur_buff = &buff0;
//now we can get_next_buff by passing cur_buff
}
if (operation == STARTDUMP) {
//don't want to reenter start initialiation again
operation = DUMPING;
}
if (operation == STARTFLASH) {
//don't want to reenter start initialiation again
operation = FLASHING;
}
//to start let's sense dumping operation by buffer status
//host updates status of buffer, then we go off and dump as appropriate
//might be best to add some opcode to kick things off.
if ( buff->function == DUMPING ) {
// if ( buff->function == DUMPING ) {
buff->cur_byte = 0;
//to start lets just dump the first page of PRG-ROM
result = dump_page( buff );
if (result == SUCCESS) {
buff->status = DUMPED;
}
//now it can be read back in next IN transfer
}
// buff->cur_byte = 0;
// //to start lets just dump the first page of PRG-ROM
// result = dump_page( buff );
//
// if (result == SUCCESS) {
// buff->status = DUMPED;
// }
//
// //now it can be read back in next IN transfer
// }
//for now lets use one buffer to flash a cartridge
//later try a second one to double buffer, might not actually matter much..
// buffer *buff = &buff0;
//check if buffer is full and update status accordingly
if (cur_usb_load_buff->last_idx == cur_usb_load_buff->cur_byte) {
cur_usb_load_buff->status = USB_FULL;
//update other buffer so it can be filled by incoming USB data now
//if buffer size is smaller than data transfer lengths this must be done quickly
//enough for usbFunction write to not notice
} else {
//if there are no full buffers yet simply exit
//return;
}
// if (cur_usb_load_buff->last_idx == cur_usb_load_buff->cur_byte) {
// cur_usb_load_buff->status = USB_FULL;
//
// //update other buffer so it can be filled by incoming USB data now
// //if buffer size is smaller than data transfer lengths this must be done quickly
// //enough for usbFunction write to not notice
// } else {
// //if there are no full buffers yet simply exit
// //return;
// }
//found a buffer that's full and ready to flash onto cart
@ -523,19 +644,21 @@ void update_buffers()
//update any other necessary elements
//send it off to it's flashing routine
if ( buff->function == FLASHING ) {
buff->cur_byte = 0;
//to start lets just dump the first page of PRG-ROM
result = flash_page( buff );
if (result == SUCCESS) {
buff->status = DUMPED;
}
//now it can be read back in next IN transfer
}
// if ( buff->function == FLASHING ) {
//
//
// buff->cur_byte = 0;
// //to start lets just dump the first page of PRG-ROM
// result = flash_page( buff );
//
// if (result == SUCCESS) {
// buff->status = FLASHED;
// } else {
// buff->status = PROBLEM;
// }
//
// //now it can be read back in next IN transfer
// }
//now that it's flashed perform verifications if needed

View File

@ -1,8 +1,5 @@
#include "dump.h"
/* Desc:Dump cart memory into buffer's data array
* Pre: buffer elements must be updated to designate how/where to dump
* buffer's cur_byte must be cleared or set to where to start dumping
@ -11,15 +8,46 @@
*/
uint8_t dump_page( buffer *buff ) {
uint8_t addrH = (buff->page_num | 0x80); //or in $8000 to set equiv CPU address
uint8_t addrH = buff->page_num; //A15:8 while accessing page
uint8_t addrX; //A23:16 while accessing page
//TODO use mapper to set mapper controlled address bits
//use mem_type to set addrH/X as needed for dump loop
//also use to get read function pointer
switch ( buff->mem_type ) {
case PRGROM:
addrH |= 0x80; //$8000
//uint8_t nes_cpu_page_rd( uint8_t *data, uint8_t addrH, uint8_t first, uint8_t last )
buff->cur_byte = nes_cpu_page_rd( buff->data, addrH, buff->id,
//id contains MSb of page when <256B buffer
(buff->last_idx | buff->id) );
break;
case CHRROM: //$0000
//buff->cur_byte = nes_ppu_page_rd( buff->data, addrH, buff->id,
// (buff->last_idx | buff->id) );
break;
case PRGRAM:
addrH |= 0x60; //$6000
buff->cur_byte = nes_cpu_page_rd( buff->data, addrH, buff->id,
(buff->last_idx | buff->id) );
break;
case SNESROM:
case SNESRAM:
addrX = ((buff->page_num)>>8);
break;
default:
return ERR_BUFF_UNSUP_MEM_TYPE;
}
//lets start just reading first page of PRG-ROM then get fancy
while (buff->cur_byte < buff->last_idx) {
//might be faster to put some of these in new pointers, but not sure..
buff->data[buff->cur_byte] = nes_cpu_rd( addrH, buff->cur_byte );
buff->cur_byte++;
}
// while (buff->cur_byte < buff->last_idx) {
//
// //might be faster to put some of these in new pointers, but not sure..
// buff->data[buff->cur_byte] = nes_cpu_rd( addrH, buff->cur_byte );
// buff->cur_byte++;
// }
return SUCCESS;
}

View File

@ -8,6 +8,7 @@
#include "nes.h"
#include "shared_dictionaries.h"
#include "shared_errors.h"
#include "shared_enums.h"
uint8_t dump_page( buffer *buff ) ;

View File

@ -150,11 +150,6 @@ void nes_init()
_DATA_IP();
_DATA_HI();
//turn LED off
_LED_OFF();
//set as OP for future commands to utilize
_LED_OP();
}
@ -208,11 +203,6 @@ void snes_init()
_DATA_IP();
_DATA_HI();
//turn LED off
_LED_OFF();
//set as OP for future commands to utilize
_LED_OP();
}
//Test starts by verifying EXP0 can be driven low, if not, will return one byte of AUX_PIN

View File

@ -59,6 +59,9 @@ uint8_t nes_opcode_16b_operand_8b_return( uint8_t opcode, uint8_t addrH, uint8_t
case NES_PPU_RD:
*data = nes_ppu_rd( addrH, addrL );
break;
case CIRAM_A10_MIRROR:
*data = ciram_a10_mirroring( );
break;
default:
//macro doesn't exist
return ERR_UNKN_NES_OPCODE_16BOP_8BRV;
@ -342,3 +345,97 @@ void nes_ppu_wr( uint8_t addrH, uint8_t addrL, uint8_t data )
_DATA_IP();
}
/* Desc:PPU CIRAM A10 NT arrangement sense
* Toggle A11 and A10 and read back CIRAM A10
* report back if vert/horiz/1scnA/1scnB
* reports nesdev defined mirroring
* does not report Nintendo's "Name Table Arrangement"
* Pre: nes_init() setup of io pins
* Post:address left on bus
* Rtn: MIR_VERT, MIR_HORIZ, MIR_1SCNA, MIR_1SCNB
* errors not really possible since all combinations
* of CIRAM A10 level designate something valid
*/
uint8_t ciram_a10_mirroring( void )
{
uint8_t readV, readH;
//will need output majority of function
_DATA_OP();
//set A10, clear A11
DATA_OUT = A10;
_AHL_CLK();
readV = AUX_IN & (1<<CIA10);
//set A11, clear A10
DATA_OUT = A11;
_AHL_CLK();
readH = AUX_IN & (1<<CIA10);
//return data bus clear
_DATA_IP();
//if CIRAM A10 was always low -> 1 screen A
if ((readV==0) & (readH==0)) return MIR_1SCNA;
//if CIRAM A10 was always hight -> 1screen B
if ((readV!=0) & (readH!=0)) return MIR_1SCNB;
//if CIRAM A10 toggled with A10 -> Vertical mirroring, horizontal arrangement
if ((readV!=0) & (readH==0)) return MIR_VERT;
//if CIRAM A10 toggled with A11 -> Horizontal mirroring, vertical arrangement
if ((readV==0) & (readH!=0)) return MIR_HORIZ;
//shouldn't be here...
return UNKNOWN;
}
/* Desc:NES CPU Page Read
* decode A15 from addrH to set /ROMSEL as expected
* float EXP0
* toggle M2 as NES would
* Pre: nes_init() setup of io pins
* num_bytes can't exceed 256B page boundary
* Post:address left on bus
* data bus left clear
* EXP0 left floating
* data buffer filled starting at first to last
* Rtn: Index of last byte read
*/
uint8_t nes_cpu_page_rd( uint8_t *data, uint8_t addrH, uint8_t first, uint8_t last )
{
uint8_t i;
//set address bus
_ADDRH_SET(addrH);
//set M2 and /ROMSEL
_M2_HI();
if( addrH >= 0x80 ) { //addressing cart rom space
_ROMSEL_LO(); //romsel trails M2 during CPU operations
}
ADDR_OUT = first; //doing this prior to entry and right after latching
//gives longest delay between address out and latching data
for( i=0; i<=last; i++ ) {
//set lower address bits
//couple more NOP's waiting for data
//zero nop's returned previous databus value
NOP(); //one nop got most of the bits right
NOP(); //two nop got all the bits right
NOP(); //add third nop for some extra
//might need to wait longer for some carts...
//latch data
data[i] = DATA_IN;
ADDR_OUT = ++first;
}
//return bus to default
_M2_LO();
_ROMSEL_HI();
//return index of last byte read
return i;
}

View File

@ -5,6 +5,7 @@
#include "pinport.h"
#include "shared_dictionaries.h"
#include "shared_errors.h"
#include "shared_enums.h"
uint8_t nes_opcode_only( uint8_t opcode );
uint8_t nes_opcode_24b_operand( uint8_t opcode, uint8_t addrH, uint8_t addrL, uint8_t data );
@ -15,5 +16,7 @@ uint8_t nes_cpu_rd( uint8_t addrH, uint8_t addrL );
void nes_cpu_wr( uint8_t addrH, uint8_t addrL, uint8_t data );
uint8_t nes_ppu_rd( uint8_t addrH, uint8_t addrL );
void nes_ppu_wr( uint8_t addrH, uint8_t addrL, uint8_t data );
uint8_t ciram_a10_mirroring( void );
uint8_t nes_cpu_page_rd( uint8_t *data, uint8_t addrH, uint8_t first, uint8_t last );
#endif

View File

@ -434,5 +434,8 @@ void software_AXL_CLK();
//PPU /A13 is ADDRH bit 7
#define PPU_A13N 0x80
//PPU and CPU
#define A10 0x04
#define A11 0x08
#endif

73
host/source/buffer.c Normal file
View File

@ -0,0 +1,73 @@
#include "buffer.h"
/* Desc:Reset buffers on device
* Pre:
* Post:All buffers and raw sram unallocated
* Rtn: SUCCESS if no errors
*/
int reset_buffers( USBtransfer *transfer )
{
return dictionary_call( transfer, DICT_BUFFER, RAW_BUFFER_RESET, NILL, NILL,
USB_IN, NULL, 1);
}
/* Desc:allocate buffers on device
* Pre: buffers must be reset
* Post:All buffers and raw sram unallocated
* Sets id, status to EMPTY, and last_idx.
* All other elements set to zero
* Rtn: SUCCESS if no errors
*/
int allocate_buffers( USBtransfer *transfer, int num_buffers, int buff_size ) {
//TODO verify number of banks doesn't exceed devices' configuration
// uint8_t rv[RV_DATA0_IDX];
// uint8_t rv;
int rv;
int buff0id = 0;
int buff0basebank = 0;
int buff1id = 0;
int buff1basebank = 0;
int numbanks= 0;
//want to allocate buffers as makes sense based on num and size
//Ideally a buffer will be 256Bytes which equals a page size
//256Bytes doesn't work well with dumping though as max xfr size is 254Bytes
//So for simplicity dumping starts with 128B buffers
//But this means a single buffer can't hold a full page
//In this case the missing bits between buffer size and page_num must be contained
//in upper bits of the buffer id.
if( (num_buffers == 2) && (buff_size == 128)) {
//MSB tells buffer value of A7 when operating
buff0id = 0x00;
buff0basebank = 0;
numbanks= buff_size/RAW_BANK_SIZE;
buff1id = 0x80;
buff1basebank= numbanks; //buff1 starts right after buff0
} else {
sentinel("Not setup to handle this buffer config");
}
//allocate buffer0
rv = dictionary_call_debug( transfer, DICT_BUFFER, ALLOCATE_BUFFER0,
( (buff0id<<8)|(buff0basebank) ), numbanks,
USB_IN, NULL, 1);
if ( rv != SUCCESS ){
//failed to allocate pass error code back
return rv;
}
//allocate buffer1
rv = dictionary_call_debug( transfer, DICT_BUFFER, ALLOCATE_BUFFER1,
( (buff1id<<8)|(buff1basebank) ), numbanks,
USB_IN, NULL, 1);
if ( rv != SUCCESS ){
//failed to allocate pass error code back
return rv;
}
return SUCCESS;
error:
return ~SUCCESS;
}

27
host/source/buffer.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef _buffer_h
#define _buffer_h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
//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
//"make debug" to get DEBUG msgs on entire program
#include "dbg.h"
#include "shared_errors.h"
#include "shared_dictionaries.h"
#include "dictionary.h"
#include "memory.h"
// "cartridge.h" is above the scope of this module don't include
#include "pindef.h"
int reset_buffers( USBtransfer *transfer );
int allocate_buffers( USBtransfer *transfer, int num_buffers, int buff_size );
#endif

View File

@ -133,17 +133,36 @@ error:
//roms are still visible when /RESET low, but SRAM isn't
/* Desc:Run through supported mapper mirroring modes to help detect mapper.
* Pre:
* Post:cart mirroring set to found mirroring
* Rtn: SUCCESS if nothing bad happened, neg if error with kazzo etc
*/
int detect_mirroring( cartridge *cart, USBtransfer *transfer )
{
//always start with resetting i/o
io_reset( transfer );
if ( (cart->console == NES_CART) || (cart->console == FC_CART) ) {
//For now just assume mirroring is fixed until start adding support for other mappers
cart->mirroring = MIR_FIXED;
}
nes_init(transfer);
//TODO call mmc3 detection function
//always end with resetting i/o
//TODO call mmc1 detection function
//fme7 and many other ASIC mappers
//none of ASIC mappers passed, assume fixed/discrete style mirroring
cart->mirroring = ciram_A10_mirroring( transfer );
switch (cart->mirroring) {
case MIR_1SCNA: debug("detected mirroring: 1scnA"); break;
case MIR_1SCNB: debug("detected mirroring: 1scnB"); break;
case MIR_VERT: debug("detected mirroring: Vert"); break;
case MIR_HORIZ: debug("detected mirroring: Horiz"); break;
default: debug("detected mirroring: %x", cart->mirroring);
}
}
//always end with reset
io_reset( transfer );
return SUCCESS;
@ -189,19 +208,24 @@ int detect_map_mem( cartridge *cart, USBtransfer *transfer, int oper )
//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:
case MIR_1SCNA:
case MIR_1SCNB:
break;
case MIR_VERT:
case MIR_HORIZ:
//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;
cart->sec_rom->size = 8 * KByte;
}
}
//exp0 pullup test passes on many INL boards
@ -218,7 +242,7 @@ switch (cart->mirroring) {
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;
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,
@ -226,7 +250,7 @@ switch (cart->mirroring) {
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->pri_rom->bank_size = 16 * KByte;
cart->mapper = UxROM;
}
}
@ -237,14 +261,14 @@ switch (cart->mirroring) {
//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->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.");
sentinel("Problem with map mem detect based on mirroring switch statement.");
}
//mapper select switch<<<<-------------------------------------------------------------
break;
@ -269,3 +293,4 @@ error:
io_reset( transfer );
return -1;
}

View File

@ -18,7 +18,7 @@
#include "shared_errors.h"
#include "shared_dictionaries.h"
#include "dictionary.h"
#include "enums.h"
#include "shared_enums.h"
#include "io.h"
#include "nes.h"
@ -47,6 +47,7 @@ int init_cart_elements( cartridge *cart );
int detect_console( cartridge *cart, USBtransfer *transfer );
int detect_mirroring( cartridge *cart, USBtransfer *transfer );
int detect_map_mem( cartridge *cart, USBtransfer *transfer, int oper );
int detect_mirroring( cartridge *cart, USBtransfer *transfer );
#endif

61
host/source/dump.c Normal file
View File

@ -0,0 +1,61 @@
#include "dump.h"
/* Desc:
* Pre:
* Post:
* Rtn:
*/
//main collected as much data about cart as possible without reading roms
//now it's time to start running CRC's to try and finalize mapper/config
//Once final mapper is known store header data in rom file and start dumping!
int dump_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart )
{
debug("dumping cart");
//TODO provide user arg to force all these checks passed
//first check if any provided args differ from what was detected
check( cart->console != UNKNOWN,
"cartridge not detected, must provide console if autodetection is off");
if ( rom->console != UNKNOWN ) {
check( rom->console == cart->console,
"request system dump doesn't match detected cartridge");
}
if ( (cart->mapper != UNKNOWN) && (rom->mapper != UNKNOWN) ) {
check( rom->mapper == cart->mapper,
"request mapper dump doesn't match detected mapper");
}
//Run some CRC's to determine size of memories
//setup buffers and manager
//reset buffers first
check(! reset_buffers( transfer ), "Unable to reset device buffers");
//need to allocate some buffers for dumping
//2x 128Byte buffers
int num_buffers = 2;
int buff_size = 128;
check(! allocate_buffers( transfer, num_buffers, buff_size ), "Unable to allocate buffers");
//set buffer elements as needed
//set reload which gets added to page_num after each buffer read
//set page_num to non-zero if offset arg sent
//set mem_type and part_num to designate how to get/write data
//set multiple and add_mult only when flashing
//set mapper, map_var, and function to designate read/write algo
//tell buffers what function to use for dumping
//inform buffer manager to start dumping operation now that buffers are initialized
//manager updates buffer status' so they'll start dumping
//once they're full manager prepares them to be read back on USB payloads
//once the next payload request happens manager knows last buffer can start dumping again
//buffer updates it's elements and goes off to dump next page
//tell buffer manager when to stop
//reset buffers and setup to dump CHR-ROM
return SUCCESS;
error:
return ~SUCCESS;
}

34
host/source/dump.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef _dump_h
#define _dump_h
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
//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
//"make debug" to get DEBUG msgs on entire program
#include "dbg.h"
#include "usb_operations.h"
#include "shared_errors.h"
#include "shared_dictionaries.h"
#include "dictionary.h"
#include "shared_enums.h"
#include "io.h"
#include "nes.h"
#include "snes.h"
#include "memory.h"
#include "cartridge.h"
#include "file.h"
#include "buffer.h"
int dump_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart );
#endif

View File

@ -1,55 +0,0 @@
#ifndef _enums_h
#define _enums_h
//One concise place to list all enums used for setting cartridge and memory elements
//used to denote when any cartridge element is not known
#define UNKNOWN -1
//console options
#define NES_CART 'N'
#define FC_CART 'F'
#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
};
enum operations {
READ = 10,
WRITE,
CHECK
};
#endif

View File

@ -15,7 +15,7 @@
//TODO put defintions in separate project wide .h file
#include "cartridge.h"
#include "enums.h"
#include "shared_enums.h"
#define SIZE_NES_HEADER 16
#define SIZE_PRG_BANK 16384

View File

@ -19,7 +19,8 @@
#include "test.h"
#include "cartridge.h"
#include "file.h"
#include "enums.h"
#include "dump.h"
#include "shared_enums.h"
int main(int argc, char *argv[])
@ -127,11 +128,11 @@ int main(int argc, char *argv[])
}
debug("flags= o:%d n:%d e:%d f:%d h:%d i:%d t:%d x:%d y:%d T:%d",
o_flag, n_flag, e_flag, f_flag, h_flag, i_flag, t_flag, x_flag, y_flag, T_flag );
debug("args= b:%s c:%s d:%s m:%s p:%s", b_value, c_value, d_value, m_value, p_value);
debug("args= s:%s v:%s C:%s L:%s K:%s", s_value, v_value, C_value, L_value, K_value);
debug("args= O:%s P:%s S:%s W:%s", O_value, P_value, S_value, W_value);
// debug("flags= o:%d n:%d e:%d f:%d h:%d i:%d t:%d x:%d y:%d T:%d",
// o_flag, n_flag, e_flag, f_flag, h_flag, i_flag, t_flag, x_flag, y_flag, T_flag );
// debug("args= b:%s c:%s d:%s m:%s p:%s", b_value, c_value, d_value, m_value, p_value);
// debug("args= s:%s v:%s C:%s L:%s K:%s", s_value, v_value, C_value, L_value, K_value);
// debug("args= O:%s P:%s S:%s W:%s", O_value, P_value, S_value, W_value);
for( index = optind; index < argc; index++) {
log_err("Non-option arguement: %s \n", argv[index]);
@ -143,6 +144,10 @@ int main(int argc, char *argv[])
return 0;
}
if ( O_value || v_value || s_value || b_value || y_flag || t_flag || f_flag ) {
printf("option not currently supported sorry...\n");
}
//Determine overall operation being performed based on user args
//Also don't want to continue if conflicting args are being used
@ -242,20 +247,22 @@ int main(int argc, char *argv[])
if ( strcmp( "FC", c_value ) == 0 ) rom->console = FC_CART;
if ( strcmp( "SNES", c_value ) == 0 ) rom->console = SNES_CART;
}
//TODO interpret provided file extension to determine desired console
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;
rom->prg_size = 32 * KByte;
rom->chr_size = 8 * KByte;
}
//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);
//collected as much info as can dump cart without reading any data
check( !dump_cart( transfer, rom, cart ), "Error while dumping cart");
}
if ( p_value ) {
@ -270,7 +277,7 @@ int main(int argc, char *argv[])
//forced to erase board regardless of current status
if (e_flag || p_value) {
erase_nes( transfer );
// erase_nes( transfer );
}
//if flashing determine auto-doubling for oversized flash
@ -282,7 +289,7 @@ int main(int argc, char *argv[])
//determine if snes input rom needs deinterleaved
//dump or flash data based on user args
//dump or program data based on user args
//find some fun trivia to present to user while waiting for flash operatoin..?

View File

@ -18,7 +18,7 @@
#include "shared_errors.h"
#include "shared_dictionaries.h"
#include "dictionary.h"
#include "enums.h"
#include "shared_enums.h"
//SST 39SF0x0 manf/prod IDs
#define SST_MANF_ID 0xBF
@ -30,7 +30,7 @@
#define SRAM 0xAA
//KByte for easy math
#define KBYTE 1024
#define KByte 1024
//memory object/struct
typedef struct memory{

View File

@ -412,3 +412,20 @@ int ppu_ram_sense( USBtransfer *transfer, uint16_t addr ) {
return SUCCESS;
}
/* Desc:Just calls CIRAM_A10_MIRROR opcode and returns result.
* result will be return value of opcode
* Pre: nes_init() been called to setup i/o
* Post:address bus left assigned
* Rtn: VERT/HORIZ/1SCNA/1SCNB
*/
int ciram_A10_mirroring( USBtransfer *transfer )
{
uint8_t rv[RV_DATA0_IDX];
dictionary_call( transfer, DICT_NES, CIRAM_A10_MIRROR, NILL, NILL,
USB_IN, rv, RV_DATA0_IDX+1);
debug("mirroring detected: %x", rv[RV_DATA0_IDX]);
return rv[RV_DATA0_IDX];
}

View File

@ -17,6 +17,7 @@
#include "shared_dictionaries.h"
#include "dictionary.h"
#include "memory.h"
// "cartridge.h" is above the scope of this module don't include
#include "pindef.h"
@ -27,5 +28,6 @@ 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 );
int ciram_A10_mirroring( USBtransfer *transfer );
#endif

View File

@ -18,6 +18,7 @@
#include "usb_operations.h"
#include "shared_errors.h"
#include "shared_enums.h"
#include "shared_dictionaries.h"
#include "dictionary.h"

View File

@ -44,23 +44,6 @@
#define NUM_BUFFERS_4 4
//#define NUM_BUFFERS_8 8
//defined here so identical to host and firmware
//status values
#define EMPTY 0x00
#define PROBLEM 0x10
#define USB_UNLOADING 0x80
#define USB_LOADING 0x90
#define USB_FULL 0x98
#define CHECKING 0xC0
#define DUMPING 0xD0
#define DUMPED 0xD8
#define ERASING 0xE0
#define FLASHING 0xF0
#define FLASH_WAIT 0xF8
#define UNALLOC 0xFF
//=============================================================================================
// OPCODES with up to 24bit operand and optional return value besides SUCCESS/ERROR_CODE
@ -104,6 +87,10 @@
//no operands no return value
#define RAW_BUFFER_RESET 0x00
//set buffer manager operation value
//lower operand byte sets value
#define SET_BUFFER_OPERATION 0x01
//------------------------------------------------------------------------------------------------

View File

@ -76,4 +76,8 @@
#define NES_PPU_RD 0x82
//doesn't have operands just returns sensed CIRAM A10 mirroring
//returns VERT/HORIZ/1SCNA/1SCNB from shared_enums.h
#define CIRAM_A10_MIRROR 0x83
#endif

84
shared/shared_enums.h Normal file
View File

@ -0,0 +1,84 @@
#ifndef _shared_enums_h
#define _shared_enums_h
//One concise place to list all enums used
//for setting cartridge and memory elements on the host
//which end up getting communicated between device and host
//used to denote when any cartridge element is not known
#define UNKNOWN 0xFF
//console options
#define NES_CART 'N'
#define FC_CART 'F'
#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
// UNKNOWN 255 don't assign to something meaningful
enum mirroring {
MIR_1SCNA = 0x10, //SCNA
MIR_1SCNB = 0x11, //SCNB
MIR_VERT = 0x12, //VERT
MIR_HORIZ = 0x13, //HORIZ
MIR_ANROM,
MIR_MMC1,
MIR_MMC3,
MIR_FME7
};
enum operations {
READ = 10,
WRITE,
CHECK
};
enum buff_mem_type {
PRGROM = 10,
CHRROM,
PRGRAM,
SNESROM,
SNESRAM
};
//buffer status values
#define EMPTY 0x00
#define PROBLEM 0x10
#define USB_UNLOADING 0x80
#define USB_LOADING 0x90
#define USB_FULL 0x98
#define CHECKING 0xC0
#define DUMPING 0xD0
#define STARTDUMP 0xD2
#define DUMPED 0xD8
#define ERASING 0xE0
#define FLASHING 0xF0
#define STARTFLASH 0xF2
#define FLASHED 0xF4
#define FLASH_WAIT 0xF8
#define UNALLOC 0xFF
#endif

View File

@ -42,6 +42,7 @@
#define ERR_BUFF_ID_ALREADY_ALLOC 192
#define ERR_BUFF_RAW_ALREADY_ALLOC 193
#define ERR_BUFF_ALLOC_SIZE_ZERO 194
#define ERR_BUFF_UNSUP_MEM_TYPE 195
#define ERR_OUT_CURLDBUF_STATUS 200
#define ERR_OUT_CURLDBUF_TO_SMALL 201