diff --git a/firmware/source/buffer.c b/firmware/source/buffer.c index 3edf73c..778e1ae 100644 --- a/firmware/source/buffer.c +++ b/firmware/source/buffer.c @@ -333,12 +333,14 @@ uint8_t * buffer_payload( setup_packet *spacket, buffer *buff, uint8_t hostsetbu operation = PROBLEM; } } else {//writes - //cur_usb_load_buff = &buff0; - cur_usb_load_buff = cur_buff; - //buff0.status = USB_LOADING; - cur_buff->status = USB_LOADING; + if ( cur_buff->status == EMPTY ) { + //send cur_buff to usbFunctionWrite to be filled + cur_usb_load_buff = cur_buff; + cur_buff->status = USB_LOADING; + } else { + operation = PROBLEM; + } } - //buff0.cur_byte = 0; cur_buff->cur_byte = 0; } else { //host determined the buffer to use @@ -592,6 +594,7 @@ void update_buffers() { uint8_t result = 0; static uint8_t num_buff; + buffer *last_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 @@ -615,23 +618,10 @@ void update_buffers() //we always start with buff0 cur_buff = &buff0; //now we can get_next_buff by passing cur_buff + } if (operation == STARTDUMP) { //prepare both buffers to dump -// cur_buff->cur_byte = 0; -// cur_buff->status = DUMPING; -// //send first buffer off to dump -// result = dump_page( cur_buff ); -// if (result != SUCCESS) { -// cur_buff->status = PROBLEM; -// } else { -// cur_buff->status = DUMPED; -// //increment page_num so everything is ready for next dump -// cur_buff->page_num += cur_buff->reload; -// } - //now it's ready and just waiting for IN transfer - //pretend the last buffer is in USB transfer and - //we're waiting to have that dump until the first buffer starts USB transfer //do all the same things that would happen between buffers to start things moving //pretend the last buffer is unloading via USB right now @@ -651,6 +641,16 @@ void update_buffers() //don't want to reenter start initialiation again operation = FLASHING; + //not much else to do, just waiting on payload OUT transfer + //current buffer prepared to be sent to usbFunctionWrite + cur_buff->status = EMPTY; + + //TODO + //perhaps this is where the mapper registers should be initialized as needed + //for all buffer writes. + //but this will bloat firmware code with each mapper.. + //so prob best for host to handle this with series of single byte write opcodes + } //this will get entered on first and all successive calls @@ -668,7 +668,7 @@ void update_buffers() cur_buff->cur_byte = 0; cur_buff->status = DUMPING; //send buffer off to dump - result = dump_page( cur_buff ); + result = dump_buff( cur_buff ); if (result != SUCCESS) { cur_buff->status = result; } else { @@ -681,6 +681,33 @@ void update_buffers() } + if ( operation == FLASHING ) { + //cur_buff will get sent to usbFunctionWrite on next payload OUT transfer + //All we need to do here is monitor usbFWr's status via incoming_bytes_remain + //which gets set to 254 on wr transfers once gets to zero buffer is filled + if ( incoming_bytes_remain == 0 ) { + incoming_bytes_remain--; //don't want to re-enter + + //buffer full, send to flash routine + last_buff = cur_buff; + //but first want to update cur_buff to next buffer so it can + //start loading on next OUT transfer + cur_buff = get_next_buff( cur_buff, num_buff ); + cur_buff->status = EMPTY; + + last_buff->status = FLASHING; + result = flash_buff( last_buff ); + if (result != SUCCESS) { + last_buff->status = result; + } else { + last_buff->status = FLASHED; + cur_buff->page_num += cur_buff->reload; + } + //page should be flashed to memory now + //the next buffer should be in process of getting filled + //once full we'll end up back here again + } + } //to start let's sense dumping operation by buffer status //host updates status of buffer, then we go off and dump as appropriate diff --git a/firmware/source/dump.c b/firmware/source/dump.c index 321c884..c2641b5 100644 --- a/firmware/source/dump.c +++ b/firmware/source/dump.c @@ -6,7 +6,7 @@ * Post:page dumped from cart memory to buffer. * Rtn: SUCCESS or ERROR# depending on if there were errors. */ -uint8_t dump_page( buffer *buff ) { +uint8_t dump_buff( buffer *buff ) { uint8_t addrH = buff->page_num; //A15:8 while accessing page //warn uint8_t addrX; //A23:16 while accessing page diff --git a/firmware/source/dump.h b/firmware/source/dump.h index 703d0f5..f2c098b 100644 --- a/firmware/source/dump.h +++ b/firmware/source/dump.h @@ -11,6 +11,6 @@ #include "shared_errors.h" #include "shared_enums.h" -uint8_t dump_page( buffer *buff ) ; +uint8_t dump_buff( buffer *buff ) ; #endif diff --git a/firmware/source/flash.c b/firmware/source/flash.c index 2761d1b..c7364b4 100644 --- a/firmware/source/flash.c +++ b/firmware/source/flash.c @@ -1,48 +1,84 @@ #include "flash.h" -/* Desc:Programs buffer's data onto cart memory - * Pre: Sector/Chip must be erased if required - * buffer elements must be updated to designate how to program - * Post:page flashed/programmed to designated memory. - * Rtn: SUCCESS or ERROR# depending on if there were errors. - */ -uint8_t flash_page( buffer *buff ) { - - uint8_t addrH = (buff->page_num | 0x80); //or in $8000 to set equiv CPU address +uint8_t write_page( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr wr_func, read_funcptr rd_func ) +{ + uint8_t i = buff->cur_byte; uint8_t read; - //lets start just reading first page of PRG-ROM then get fancy - while (buff->cur_byte < buff->last_idx) { + do { + //write unlock sequence + wr_func( 0x55, 0x55, 0xAA ); + wr_func( 0x2A, 0xAA, 0x55 ); + wr_func( 0x55, 0x55, 0xA0 ); + wr_func( addrH, i, buff->data[i] ); + + do { + usbPoll(); + read = rd_func( addrH, i ); + + } while( read != rd_func( addrH, i) ); - //write unlock sequence first - discrete_exp0_prgrom_wr( 0x55, 0x55, 0xAA ); - discrete_exp0_prgrom_wr( 0x2A, 0xAA, 0x55 ); - discrete_exp0_prgrom_wr( 0x55, 0x55, 0xA0 ); - - //then flash byte - discrete_exp0_prgrom_wr( addrH, buff->cur_byte, buff->data[buff->cur_byte] ); - - //then spin until write finished - read = nes_cpu_rd(addrH,buff->cur_byte); - while ( read != nes_cpu_rd(addrH,buff->cur_byte) ) { - read = nes_cpu_rd(addrH,buff->cur_byte); - } - - //byte stable, now verify proper value - if ( read == buff->data[buff->cur_byte] ) { - buff->cur_byte++; - _LED_OFF(); - } else {//don't increment, retry - _LED_OP(); - _LED_ON(); - } - } + //move on to next byte + i++; + } while ( i != buff->last_idx ); return SUCCESS; +} +/* Desc:Flash buffer contents on to cartridge memory + * Pre: buffer elements must be updated to designate how/where to flash + * buffer's cur_byte must be cleared or set to where to start flashing + * mapper registers must be initialized + * Post:buffer page flashed/programmed to memory. + * Rtn: SUCCESS or ERROR# depending on if there were errors. + */ +uint8_t flash_buff( buffer *buff ) { + + uint8_t addrH = buff->page_num; //A15:8 while accessing page + + //First need to initialize mapper register bits + //Perhaps this only needs to be done on first buffer though..? + //Actually think this is best handled from buffer.c in operation == STARTFLASH + + //TODO use mapper to set mapper controlled address bits + + //need to calculate current bank and addrH + + //TODO set unlock addresses based on what works for that mapper and how it's banks are initialized + + //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: //$8000 + write_page( 0, (0x80 | addrH), buff, discrete_exp0_prgrom_wr, nes_cpu_rd ); + break; + case CHRROM: //$0000 + write_page( 0, addrH, buff, nes_ppu_wr, nes_ppu_rd ); + break; + case PRGRAM: + //addrH |= 0x60; //$6000 + //buff->cur_byte = nes_cpu_page_wr_poll( buff->data, addrH, buff->id, + // buff->last_idx, ~FALSE ); + break; + case SNESROM: + case SNESRAM: +//warn 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++; +// } + + return SUCCESS; } - - diff --git a/firmware/source/flash.h b/firmware/source/flash.h index 3b80c75..2d81ac1 100644 --- a/firmware/source/flash.h +++ b/firmware/source/flash.h @@ -2,12 +2,15 @@ #define _flash_h #include +#include "usbdrv.h" #include "types.h" #include "logic.h" #include "usb.h" +#include "nes.h" #include "shared_dictionaries.h" #include "shared_errors.h" +#include "shared_enums.h" -uint8_t flash_page( buffer *buff ) ; +uint8_t flash_buff( buffer *buff ) ; #endif diff --git a/firmware/source/temp b/firmware/source/temp deleted file mode 100644 index 5cd31c1..0000000 --- a/firmware/source/temp +++ /dev/null @@ -1,20 +0,0 @@ -AVR Memory Usage ----------------- -Device: atmega164a - -Program: 5486 bytes (33.5% Full) -(.text + .data + .bootloader) - -Data: 653 bytes (63.8% Full) -(.data + .bss + .noinit) - -AVR Memory Usage ----------------- -Device: atmega164a - -Program: 5498 bytes (33.6% Full) -(.text + .data + .bootloader) - -Data: 653 bytes (63.8% Full) -(.data + .bss + .noinit) - diff --git a/firmware/source/types.h b/firmware/source/types.h index 90da8c9..08b9d64 100644 --- a/firmware/source/types.h +++ b/firmware/source/types.h @@ -37,4 +37,8 @@ typedef struct buffer { uint8_t function; //function "pointer" for flash/dump operation control }buffer; +//write function pointers +typedef void (*write_funcptr) ( uint8_t addrH, uint8_t addrL, uint8_t data ); +typedef uint8_t (*read_funcptr) ( uint8_t addrH, uint8_t addrL ); + #endif diff --git a/host/source/buffer.c b/host/source/buffer.c index a5414b8..e20c4b5 100644 --- a/host/source/buffer.c +++ b/host/source/buffer.c @@ -30,6 +30,9 @@ int allocate_buffers( USBtransfer *transfer, int num_buffers, int buff_size ) { int buff1id = 0; int buff1basebank = 0; int numbanks= 0; + int reload = 0; + int buff0_firstpage = 0; + int buff1_firstpage = 0; //want to allocate buffers as makes sense based on num and size //Ideally a buffer will be 256Bytes which equals a page size @@ -38,46 +41,69 @@ int allocate_buffers( USBtransfer *transfer, int num_buffers, int buff_size ) { //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. + + buff0basebank = 0; + numbanks= buff_size/RAW_BANK_SIZE; + buff1basebank= numbanks; //buff1 starts right after buff0 + if( (num_buffers == 2) && (buff_size == 128)) { + //buff0 dumps first half of page, buff1 dumps second half, repeat //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 - //allocate buffer0 - rv = dictionary_call( 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( 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; - } + //set reload (value added to page_num after each load/dump to sum of buffers + // 2 * 128 = 256 -> reload = 1 + reload = 0x01; + //set first page + buff0_firstpage = 0x0000; + buff1_firstpage = 0x0000; - //set reload (value added to page_num after each load/dump to sum of buffers - // 2 * 128 = 256 -> reload = 1 - //set buffer0 - dictionary_call( transfer, DICT_BUFFER, SET_RELOAD_PAGENUM0, 0x0000, 0x01, - USB_IN, NULL, 1); - //set buffer1 - dictionary_call( transfer, DICT_BUFFER, SET_RELOAD_PAGENUM1, 0x0000, 0x01, - USB_IN, NULL, 1); - + } else if( (num_buffers == 2) && (buff_size == 256)) { + //buff0 dumps even pages, buff1 dumps odd pages + //buffer id not used for addressing both id zero for now.. + buff0id = 0x00; + buff1id = 0x00; + + //set reload (value added to page_num after each load/dump to sum of buffers + // 2 * 256 = 512 -> reload = 2 + reload = 0x02; + //set first page of each buffer + buff0_firstpage = 0x0000; + buff1_firstpage = 0x0001; } else { + //don't continue sentinel("Not setup to handle this buffer config"); } + //allocate buffer0 + rv = dictionary_call( 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( 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; + } + + //set first page and reload (value added to page_num after each load/dump to sum of buffers + //set buffer0 + dictionary_call( transfer, DICT_BUFFER, SET_RELOAD_PAGENUM0, buff0_firstpage, reload, + USB_IN, NULL, 1); + //set buffer1 + dictionary_call( transfer, DICT_BUFFER, SET_RELOAD_PAGENUM1, buff1_firstpage, reload, + USB_IN, NULL, 1); + + return SUCCESS; error: return ~SUCCESS; @@ -128,6 +154,29 @@ int payload_in( USBtransfer *transfer, uint8_t *data, int length ) USB_IN, data, length); } +/* Desc:Payload OUT transfer + * Pre: buffers are allocated operation started + * Post:payload of length transfered to USB device + * Rtn: SUCCESS if no errors + */ +int payload_out( USBtransfer *transfer, uint8_t *data, int length ) +{ + check( length < MAX_VUSB+3, "can't transfer more than %d bytes per transfer", MAX_VUSB+2 ); + //if over 254 bytes, must stuff first two bytes in setup packet + if ( length > MAX_VUSB ) { + return dictionary_call( transfer, DICT_BUFFER, BUFF_OUT_PAYLOAD_2B_INSP, + //byte0, byte1, bytes3-254 + data[0], data[1], USB_OUT, &data[2], length-2); + } else { + return dictionary_call( transfer, DICT_BUFFER, BUFF_PAYLOAD, + NILL, NILL, USB_OUT, data, length); + } + +error: + return ~SUCCESS; +} + + /* Desc:Get buffer elements and print them * Pre: buffers are allocated * Post: diff --git a/host/source/buffer.h b/host/source/buffer.h index 1fcbad8..a7b51c7 100644 --- a/host/source/buffer.h +++ b/host/source/buffer.h @@ -27,6 +27,7 @@ int set_mem_n_part( USBtransfer *transfer, int buff_num, int mem_type, int part_ int set_map_n_mapvar( USBtransfer *transfer, int buff_num, int mapper, int map_var ); int set_buff_operation( USBtransfer *transfer, int operation ); int payload_in( USBtransfer *transfer, uint8_t *data, int length ); +int payload_out( USBtransfer *transfer, uint8_t *data, int length ); int get_buff_elements( USBtransfer *transfer, int buff_num ); int get_buff_operation( USBtransfer *transfer ); diff --git a/host/source/file.c b/host/source/file.c index f499774..26f81ef 100644 --- a/host/source/file.c +++ b/host/source/file.c @@ -49,7 +49,7 @@ int detect_file( rom_image *rom ) //size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); rv = fread( header, sizeof(header[0]), (sizeof(header)/sizeof(header[0])), rom->fileptr); - check( rv = sizeof(header), "Unable to read NES header"); + check( rv == sizeof(header), "Unable to read NES header"); //0-3: Constant $4E $45 $53 $1A ("NES" followed by MS-DOS end-of-file) if ( (header[0]=='N') && (header[1]=='E') && (header[2]=='S') && (header[3]==0x1A) ) { @@ -133,3 +133,22 @@ int append_to_file( rom_image *rom, uint8_t *data, int length ) error: return -1; } + +/* Desc:Read data from file + * Pre: file opened and current position set to desired location + * Post:data filled with length amount of data from file + * file still open + * Rtn: SUCCESS if no errors + */ +int read_from_file( rom_image *rom, uint8_t *data, int length ) +{ + int rv = 0; + //size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); + rv = fread( data, sizeof(data[0]), length, rom->fileptr ); + + check( (rv == length), "Error reading from file, %dB read when trying to read %d", rv, length); + + return SUCCESS; +error: + return -1; +} diff --git a/host/source/file.h b/host/source/file.h index f2c9b17..087d04f 100644 --- a/host/source/file.h +++ b/host/source/file.h @@ -39,6 +39,7 @@ int open_rom( rom_image *rom, char *filename ); int detect_file( rom_image *rom ); int create_file( rom_image *rom, char *filename ); int append_to_file( rom_image *rom, uint8_t *data, int length ); +int read_from_file( rom_image *rom, uint8_t *data, int length ); int close_rom( rom_image *rom ); #endif diff --git a/host/source/flash.c b/host/source/flash.c new file mode 100644 index 0000000..2a23bf1 --- /dev/null +++ b/host/source/flash.c @@ -0,0 +1,172 @@ +#include "flash.h" + +/* Desc: + * Pre: + * Post: + * Rtn: + */ +//should know what mapper the board is by the time we get here +//might be hard to tell if all flash is addressable until start writing data though +int flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart ) +{ + //make some checks to ensure rom is compatible with cart + + //first do some checks like ensuring proper areas or sectors are blank + + //erase sectors or chip as needed + + //reset, allocate, and initialize device buffers + + //initialize mapper registers as needed for memory being programmed + + //set device operation to STARTFLASH + + //send payload data + + //run checksums to verify successful flash operation + + int num_buffers = 2; + int buff_size = 256; + int buff0 = 0; + int buff1 = 1; + int i; + uint8_t data[buff_size]; + + + debug("flashing 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"); + } + + //start with reset and init + io_reset( transfer ); + nes_init( transfer ); + //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 flashing + //2x 256Byte buffers + check(! allocate_buffers( transfer, num_buffers, buff_size ), "Unable to allocate buffers"); + + //set mem_type and part_num to designate how to get/write data + check(! set_mem_n_part( transfer, buff0, PRGROM, SST_MANF_ID ), "Unable to set mem_type and part"); + check(! set_mem_n_part( transfer, buff1, PRGROM, SST_MANF_ID ), "Unable to set mem_type and part"); + //set multiple and add_mult only when flashing + //TODO + //set mapper, map_var, and function to designate read/write algo + + //just dump visible NROM memory to start + check(! set_map_n_mapvar( transfer, buff0, NROM, NILL ), "Unable to set mapper and map_var"); + check(! set_map_n_mapvar( transfer, buff1, NROM, NILL ), "Unable to set mapper and map_var"); + + //tell buffers what function to use for flashing + //TODO when start implementing other mappers + + //debugging print out buffer elements + get_buff_operation( transfer ); + get_buff_elements( transfer, buff0 ); + get_buff_elements( transfer, buff1 ); + + debug("\n\nsetting operation STARTFLASH"); + //inform buffer manager to start dumping operation now that buffers are initialized + check(! set_buff_operation( transfer, STARTFLASH ), "Unable to set buffer operation"); + +// get_buff_operation( transfer ); +// get_buff_elements( transfer, buff0 ); +// get_buff_elements( transfer, buff1 ); +// //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 +// +// debug("first payload"); +// check(! read_from_file( rom, data, buff_size ), "Error with file read"); +// //check(! payload_out( transfer, data, buff_size ), "Error with payload OUT"); +// payload_out( transfer, data, buff_size ); +// get_buff_operation( transfer ); +// get_buff_elements( transfer, buff0 ); +// get_buff_elements( transfer, buff1 ); +// +// debug("first payload done"); +//// get_buff_operation( transfer ); +//// get_buff_elements( transfer, buff0 ); +//// get_buff_elements( transfer, buff1 ); +//// +// debug("second payload"); +// check(! read_from_file( rom, data, buff_size ), "Error with file read"); +// check(! payload_out( transfer, data, buff_size ), "Error with payload OUT"); + +// get_buff_operation( transfer ); +// get_buff_elements( transfer, buff0 ); +// get_buff_elements( transfer, buff1 ); + + clock_t tstart, tstop; + tstart = clock(); + + //now just need to call series of payload IN transfers to retrieve data + //for( i=0; i<(512*KByte/buff_size); i++) { + for( i=0; i<(32*KByte/buff_size); i++) { + //for( i=0; i<(8*KByte/buff_size); i++) { + check(! read_from_file( rom, data, buff_size ), "Error with file read"); + check(! payload_out( transfer, data, buff_size ), "Error with payload OUT"); + //if ( i % 256 == 0 ) debug("payload in #%d", i); + if ( i % 32 == 0 ) debug("payload out #%d", i); + } + debug("payload done"); + //need to delay further USB commands until last buffer is flashed + //TODO spin while buff1 status == FLASHING + //currently this takes about as long as two get elements + get_buff_elements( transfer, buff1 ); + get_buff_elements( transfer, buff1 ); + get_buff_elements( transfer, buff1 ); + + tstop = clock(); + float timediff = ( (float)(tstop-tstart) / CLOCKS_PER_SEC); + printf("total time: %fsec, speed: %fKBps\n", timediff, (512/timediff)); + //TODO flush file from time to time..? + + + //tell buffer manager when to stop + // or not..? just reset buffers and start next memory or quit + //reset buffers and setup to dump CHR-ROM + + check(! reset_buffers( transfer ), "Unable to reset device buffers"); + check(! allocate_buffers( transfer, num_buffers, buff_size ), "Unable to allocate buffers"); + check(! set_mem_n_part( transfer, buff0, CHRROM, SST_MANF_ID ), "Unable to set mem_type and part"); + check(! set_mem_n_part( transfer, buff1, CHRROM, SST_MANF_ID ), "Unable to set mem_type and part"); + check(! set_map_n_mapvar( transfer, buff0, NROM, NILL ), "Unable to set mapper and map_var"); + check(! set_map_n_mapvar( transfer, buff1, NROM, NILL ), "Unable to set mapper and map_var"); + + debug("\n\nsetting operation STARTFLASH"); + //inform buffer manager to start dumping operation now that buffers are initialized + check(! set_buff_operation( transfer, STARTFLASH ), "Unable to set buffer operation"); + + for( i=0; i<(8*KByte/buff_size); i++) { + check(! read_from_file( rom, data, buff_size ), "Error with file read"); + check(! payload_out( transfer, data, buff_size ), "Error with payload OUT"); + //if ( i % 256 == 0 ) debug("payload in #%d", i); + if ( i % 32 == 0 ) debug("payload out #%d", i); + } + debug("payload done"); + + //close file in main + + //reset io at end + io_reset( transfer ); + + return SUCCESS; +error: + return ~SUCCESS; +} diff --git a/host/source/flash.h b/host/source/flash.h new file mode 100644 index 0000000..2a141d0 --- /dev/null +++ b/host/source/flash.h @@ -0,0 +1,34 @@ +#ifndef _flash_h +#define _flash_h + +#include +#include +#include +#include +#include + +//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 flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart ); + + +#endif diff --git a/host/source/inlprog.c b/host/source/inlprog.c index 96e07c6..72a4a33 100644 --- a/host/source/inlprog.c +++ b/host/source/inlprog.c @@ -20,6 +20,7 @@ #include "cartridge.h" #include "file.h" #include "dump.h" +#include "flash.h" #include "shared_enums.h" @@ -274,6 +275,13 @@ int main(int argc, char *argv[]) //program file provided at commandline check( !open_rom( rom, p_value ), "Problem opening file %s", p_value); detect_file( rom ); + + check( !flash_cart( transfer, rom, cart ), "Error while flashing cart"); + debug("done flashing, closing"); + + check(! close_rom( rom ), "Problem closing file"); + rom->fileptr = NULL; + debug("closed"); } //if flashing, determine if erasures are necessary and where