Some early dumping functionality working.
buffer opcode updates to transfer payloads including stuffing two bytes of write transfers in setup packet. Calling specific buffers with miscdata or opcode. new dump and flash modules for firmware. new buffer function update_buffers called during main to monitor and manage buffer objects when not being loaded/unloaded from USB.
This commit is contained in:
parent
8cdeecdd77
commit
937435220a
|
|
@ -38,50 +38,65 @@ static uint8_t raw_bank_status[NUM_RAW_BANKS];
|
||||||
* rv buffer filled with return data for small data requests
|
* rv buffer filled with return data for small data requests
|
||||||
* Rtn: pointer to ram buffer to be returned over USB
|
* Rtn: pointer to ram buffer to be returned over USB
|
||||||
*/
|
*/
|
||||||
uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint16_t *rlen)
|
//uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint16_t *rlen)
|
||||||
|
uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint8_t *rlen)
|
||||||
{
|
{
|
||||||
buffer *called_buff = &buff0; //used to point to buffer that was called based on opcode
|
buffer *called_buff = &buff0; //used to point to buffer that was called based on opcode
|
||||||
uint8_t *rptr = rv; //used for return pointer set to small rv buffer by default
|
uint8_t *rptr = rv; //used for return pointer set to small rv buffer by default
|
||||||
|
|
||||||
|
//some opcodes place buffer number in misc/data
|
||||||
|
if ( (spacket->opcode > BUFFN_INMISC_MIN) && (spacket->opcode < BUFFN_INMISC_MAX) ) {
|
||||||
|
switch ( spacket->miscdata ) {
|
||||||
|
//2 buffers minimum support
|
||||||
|
case 0: called_buff = &buff0; break;
|
||||||
|
case 1: called_buff = &buff1; break;
|
||||||
|
# if ( defined(NUM_BUFFERS_4) || (defined(NUM_BUFFERS_8)) )
|
||||||
|
//4-8 buffers
|
||||||
|
case 2: called_buff = &buff2; break;
|
||||||
|
case 3: called_buff = &buff3; break;
|
||||||
|
# endif
|
||||||
|
# ifdef NUM_BUFFERS_8
|
||||||
|
//8 buffers
|
||||||
|
case 4: called_buff = &buff4; break;
|
||||||
|
case 5: called_buff = &buff5; break;
|
||||||
|
case 6: called_buff = &buff6; break;
|
||||||
|
case 7: called_buff = &buff7; break;
|
||||||
|
# endif
|
||||||
|
default: //opcode sent for non-existent buffer
|
||||||
|
rv[RV_ERR_IDX] = ERR_BUFN_DOES_NOT_EXIST;
|
||||||
|
//don't decode opcode, just return error to host
|
||||||
|
*rlen = 1;
|
||||||
|
return rptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (spacket->opcode) {
|
switch (spacket->opcode) {
|
||||||
|
|
||||||
//some opcodes place buffer number in misc/data
|
|
||||||
if ( (spacket->opcode > BUFFN_INMISC_MIN) && (spacket->opcode < BUFFN_INMISC_MAX) ) {
|
|
||||||
switch ( spacket->miscdata ) {
|
|
||||||
//2 buffers minimum support
|
|
||||||
case 0: called_buff = &buff0; break;
|
|
||||||
case 1: called_buff = &buff1; break;
|
|
||||||
# if ( defined(NUM_BUFFERS_4) || (defined(NUM_BUFFERS_8)) )
|
|
||||||
//4-8 buffers
|
|
||||||
case 2: called_buff = &buff2; break;
|
|
||||||
case 3: called_buff = &buff3; break;
|
|
||||||
# endif
|
|
||||||
# ifdef NUM_BUFFERS_8
|
|
||||||
//8 buffers
|
|
||||||
case 4: called_buff = &buff4; break;
|
|
||||||
case 5: called_buff = &buff5; break;
|
|
||||||
case 6: called_buff = &buff6; break;
|
|
||||||
case 7: called_buff = &buff7; break;
|
|
||||||
# endif
|
|
||||||
default: //opcode sent for non-existent buffer
|
|
||||||
rv[RV_ERR_IDX] = ERR_BUFN_DOES_NOT_EXIST;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//now that buffer obtained, decode opcode and make call with called_buff if needed.
|
//now that buffer obtained, decode opcode and make call with called_buff if needed.
|
||||||
case BUFF_OPCODE_NRV_MIN ... BUFF_OPCODE_NRV_MAX:
|
case BUFF_OPCODE_NRV_MIN ... BUFF_OPCODE_NRV_MAX:
|
||||||
rv[RV_ERR_IDX] = buffer_opcode_no_return( spacket->opcode, called_buff,
|
rv[RV_ERR_IDX] = buffer_opcode_no_return( spacket->opcode, called_buff,
|
||||||
spacket->operandMSB, spacket->operandLSB, spacket->miscdata );
|
spacket->operandMSB, spacket->operandLSB, spacket->miscdata );
|
||||||
*rlen = 1;
|
*rlen = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BUFF_PAYLOADN_MIN ... BUFF_PAYLOADN_MAX:
|
||||||
|
//designate what buffer to fill with miscdata byte
|
||||||
|
rptr = buffer_payload( spacket, called_buff, TRUE, rlen);
|
||||||
|
//TODO
|
||||||
|
break;
|
||||||
|
|
||||||
case BUFF_OPCODE_RV_MIN ... BUFF_OPCODE_RV_MAX:
|
case BUFF_OPCODE_RV_MIN ... BUFF_OPCODE_RV_MAX:
|
||||||
rv[RV_ERR_IDX] = buffer_opcode_return( spacket->opcode, called_buff,
|
rv[RV_ERR_IDX] = buffer_opcode_return( spacket->opcode, called_buff,
|
||||||
spacket->operandMSB, spacket->operandLSB, spacket->miscdata,
|
spacket->operandMSB, spacket->operandLSB, spacket->miscdata,
|
||||||
&rv[RV_DATA0_IDX], rlen );
|
&rv[RV_DATA0_IDX], rlen );
|
||||||
// set *rlen in function depending on opcode
|
// set *rlen in function depending on opcode
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BUFF_PAYLOAD_MIN ... BUFF_PAYLOAD_MAX:
|
||||||
|
//let buffer.c decide what buffer to fill
|
||||||
|
rptr = buffer_payload( spacket, called_buff, ~TRUE, rlen);
|
||||||
|
//TODO
|
||||||
|
break;
|
||||||
|
|
||||||
//opcodes which include designation of which buffer is being called in lower bits of opcode
|
//opcodes which include designation of which buffer is being called in lower bits of opcode
|
||||||
case BUFF_OPCODE_BUFN_MIN ... BUFF_OPCODE_BUFN_MAX:
|
case BUFF_OPCODE_BUFN_MIN ... BUFF_OPCODE_BUFN_MAX:
|
||||||
|
|
@ -104,6 +119,9 @@ uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint16_t *rlen)
|
||||||
# endif
|
# endif
|
||||||
default: //opcode sent for non-existent buffer
|
default: //opcode sent for non-existent buffer
|
||||||
rv[RV_ERR_IDX] = ERR_BUFN_DOES_NOT_EXIST;
|
rv[RV_ERR_IDX] = ERR_BUFN_DOES_NOT_EXIST;
|
||||||
|
//don't decode opcode, just return error to host
|
||||||
|
*rlen = 1;
|
||||||
|
return rptr;
|
||||||
}
|
}
|
||||||
//now that we have pointer to buffer object call associated function
|
//now that we have pointer to buffer object call associated function
|
||||||
switch ( spacket->opcode ) {
|
switch ( spacket->opcode ) {
|
||||||
|
|
@ -120,27 +138,12 @@ uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint16_t *rlen)
|
||||||
*rlen = (spacket->wLength);
|
*rlen = (spacket->wLength);
|
||||||
break;
|
break;
|
||||||
case BUFF_PAYLOAD0 ... BUFF_PAYLOAD7:
|
case BUFF_PAYLOAD0 ... BUFF_PAYLOAD7:
|
||||||
//for now just read write from designated buffer
|
rptr = buffer_payload( spacket, called_buff, TRUE, rlen);
|
||||||
//TODO make some checks that buffer is allocated/not busy etc
|
|
||||||
//determine endpoint IN/OUT
|
|
||||||
if ((spacket->bmRequestType & ENDPOINT_BIT) & ENDPOINT_IN) {
|
|
||||||
//read/dump from device to host
|
|
||||||
rptr = called_buff->data;
|
|
||||||
*rlen = (spacket->wLength);
|
|
||||||
called_buff->cur_byte = 0;
|
|
||||||
called_buff->status = USB_UNLOADING;
|
|
||||||
} else { //write to device from host
|
|
||||||
cur_usb_load_buff = called_buff;
|
|
||||||
incoming_bytes_remain = (spacket->wLength);
|
|
||||||
called_buff->cur_byte = 0;
|
|
||||||
called_buff->status = USB_LOADING;
|
|
||||||
//return USB_NO_MSG to get usbFunctionWrite
|
|
||||||
//called on incoming packets
|
|
||||||
*rlen = USB_NO_MSG;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
rv[RV_ERR_IDX] = ERR_BAD_BUFF_OP_MINMAX;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: //nes opcode min/max definition error
|
default: //nes opcode min/max definition error
|
||||||
rv[RV_ERR_IDX] = ERR_BAD_BUFF_OP_MINMAX;
|
rv[RV_ERR_IDX] = ERR_BAD_BUFF_OP_MINMAX;
|
||||||
|
|
@ -200,7 +203,8 @@ uint8_t buffer_opcode_no_return( uint8_t opcode, buffer *buff,
|
||||||
*/
|
*/
|
||||||
uint8_t buffer_opcode_return( uint8_t opcode, buffer *buff,
|
uint8_t buffer_opcode_return( uint8_t opcode, buffer *buff,
|
||||||
uint8_t operMSB, uint8_t operLSB, uint8_t miscdata,
|
uint8_t operMSB, uint8_t operLSB, uint8_t miscdata,
|
||||||
uint8_t *rvalue, uint16_t *rlength )
|
//uint8_t *rvalue, uint16_t *rlength )
|
||||||
|
uint8_t *rvalue, uint8_t *rlength )
|
||||||
{
|
{
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case RAW_BANK_STATUS:
|
case RAW_BANK_STATUS:
|
||||||
|
|
@ -208,7 +212,7 @@ uint8_t buffer_opcode_return( uint8_t opcode, buffer *buff,
|
||||||
*rlength += 1;
|
*rlength += 1;
|
||||||
break;
|
break;
|
||||||
case GET_PRI_ELEMENTS:
|
case GET_PRI_ELEMENTS:
|
||||||
rvalue[0] = buff->size;
|
rvalue[0] = buff->last_idx;
|
||||||
rvalue[1] = buff->status;
|
rvalue[1] = buff->status;
|
||||||
rvalue[2] = buff->cur_byte;
|
rvalue[2] = buff->cur_byte;
|
||||||
rvalue[3] = buff->reload;
|
rvalue[3] = buff->reload;
|
||||||
|
|
@ -268,6 +272,71 @@ uint8_t buffer_opcode_buffnum_no_return( uint8_t opcode, buffer *buff,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Desc:
|
||||||
|
* Pre:
|
||||||
|
* Post:
|
||||||
|
* Rtn:
|
||||||
|
*/
|
||||||
|
uint8_t * buffer_payload( setup_packet *spacket, buffer *buff, uint8_t hostsetbuff, uint8_t *rlength )
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8_t *rtnpointer = buff0.data; //default to remove warnings..
|
||||||
|
uint8_t endpoint = (spacket->bmRequestType & ENDPOINT_BIT);
|
||||||
|
|
||||||
|
//return length and incoming_bytes_remain only depends on endpoint direction
|
||||||
|
if ( endpoint == ENDPOINT_IN) {
|
||||||
|
//read/dump from device to host
|
||||||
|
*rlength = (spacket->wLength);
|
||||||
|
} else { //write to device from host
|
||||||
|
//return USB_NO_MSG to get usbFunctionWrite
|
||||||
|
//called on incoming packets
|
||||||
|
*rlength = USB_NO_MSG;
|
||||||
|
incoming_bytes_remain = (spacket->wLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
//buffer in use depends on opcode which was decoded prior to calling into hostsetbuff
|
||||||
|
//if buffer number not designated by host buffer.c gets to decide
|
||||||
|
if ( hostsetbuff != TRUE ) {
|
||||||
|
//buffer.c gets to decide buffer in use
|
||||||
|
//TODO implement some fancy double buffering code
|
||||||
|
//for now just designate buffer 0
|
||||||
|
if ( endpoint == ENDPOINT_IN) {
|
||||||
|
//reads
|
||||||
|
rtnpointer = buff0.data;
|
||||||
|
buff0.status = USB_UNLOADING;
|
||||||
|
} else {//writes
|
||||||
|
cur_usb_load_buff = &buff0;
|
||||||
|
buff0.status = USB_LOADING;
|
||||||
|
}
|
||||||
|
buff0.cur_byte = 0;
|
||||||
|
|
||||||
|
} else { //host determined the buffer to use
|
||||||
|
if ( endpoint == ENDPOINT_IN) {
|
||||||
|
//reads
|
||||||
|
rtnpointer = buff->data;
|
||||||
|
buff->status = USB_UNLOADING;
|
||||||
|
} else {//writes
|
||||||
|
cur_usb_load_buff = buff;
|
||||||
|
buff->status = USB_LOADING;
|
||||||
|
}
|
||||||
|
buff->cur_byte = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//now only thing left to do is stuff 2 bytes from setup packet into the buffer if designated by the opcode
|
||||||
|
if ( (spacket->opcode == BUFF_OUT_PAYLOAD_2B_INSP)
|
||||||
|
||(spacket->opcode == BUFF_OUT_PAYLOADN_2B_INSP) ) {
|
||||||
|
//operandMSB:LSB actually contains first 2 bytes
|
||||||
|
//these two bytes don't count as part of transfer OUT byte count
|
||||||
|
//but they do count as part of buffer's byte count.
|
||||||
|
cur_usb_load_buff->data[0] = spacket->operandMSB;
|
||||||
|
cur_usb_load_buff->data[1] = spacket->operandLSB;
|
||||||
|
cur_usb_load_buff->cur_byte += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtnpointer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Desc:Blindly resets all buffer allocation and values
|
/* Desc:Blindly resets all buffer allocation and values
|
||||||
* Host instructs this to be called.
|
* Host instructs this to be called.
|
||||||
* Pre: static instantitions of raw_buffer, raw_bank_status, and buff0-7
|
* Pre: static instantitions of raw_buffer, raw_bank_status, and buff0-7
|
||||||
|
|
@ -347,7 +416,7 @@ uint8_t allocate_buffer( buffer *buff, uint8_t new_id, uint8_t base_bank, uint8_
|
||||||
}
|
}
|
||||||
if ( (num_banks) == 0 ) {
|
if ( (num_banks) == 0 ) {
|
||||||
//trying to allocate buffer with zero banks
|
//trying to allocate buffer with zero banks
|
||||||
return ERR_BUFF_ALLOC_RANGE;
|
return ERR_BUFF_ALLOC_SIZE_ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check that buffer isn't already allocated
|
//check that buffer isn't already allocated
|
||||||
|
|
@ -368,7 +437,8 @@ uint8_t allocate_buffer( buffer *buff, uint8_t new_id, uint8_t base_bank, uint8_
|
||||||
//seems that buffer and raw are free allocate them as requested
|
//seems that buffer and raw are free allocate them as requested
|
||||||
buff->id = new_id;
|
buff->id = new_id;
|
||||||
buff->status = EMPTY;
|
buff->status = EMPTY;
|
||||||
buff->size = num_banks * RAW_BANK_SIZE;
|
//buff->size = num_banks * RAW_BANK_SIZE; //16bit value (256 = 9bits)
|
||||||
|
buff->last_idx = (num_banks * RAW_BANK_SIZE) - 1; //give the last index of the array
|
||||||
|
|
||||||
//zero out other elements
|
//zero out other elements
|
||||||
buff->cur_byte = 0;
|
buff->cur_byte = 0;
|
||||||
|
|
@ -392,3 +462,80 @@ uint8_t allocate_buffer( buffer *buff, uint8_t new_id, uint8_t base_bank, uint8_
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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;
|
||||||
|
|
||||||
|
//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..
|
||||||
|
|
||||||
|
//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 ) {
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
//lets ignore flashing for now, prob best to dump first so can check results when trying to flash..
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//found a buffer that's full and ready to flash onto cart
|
||||||
|
|
||||||
|
//set it's page number to the proper value
|
||||||
|
//perhaps this should be done after it's flashed as we want to start at zero.
|
||||||
|
|
||||||
|
//update any other necessary elements
|
||||||
|
|
||||||
|
//send it off to it's flashing routine
|
||||||
|
result = flash_page( buff );
|
||||||
|
|
||||||
|
//now that it's flashed perform verifications if needed
|
||||||
|
|
||||||
|
//adjust multiple/page num to program to another location if
|
||||||
|
//buffer is supposed to be flashed to multiple locations
|
||||||
|
|
||||||
|
//send it off to flash again as many times as needed
|
||||||
|
|
||||||
|
//complete any remaining checks desired
|
||||||
|
|
||||||
|
//set it's page number to the proper value
|
||||||
|
//perhaps this should be done after it's flashed as we want to start at zero.
|
||||||
|
|
||||||
|
//update it's status so buffer is ready for reuse.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,17 +5,21 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "logic.h"
|
#include "logic.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
#include "flash.h"
|
||||||
|
#include "dump.h"
|
||||||
#include "shared_dictionaries.h"
|
#include "shared_dictionaries.h"
|
||||||
#include "shared_errors.h"
|
#include "shared_errors.h"
|
||||||
|
|
||||||
|
|
||||||
uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint16_t *rlen);
|
//uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint16_t *rlen);
|
||||||
|
uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint8_t *rlen);
|
||||||
uint8_t buffer_opcode_no_return( uint8_t opcode, buffer *buff,
|
uint8_t buffer_opcode_no_return( uint8_t opcode, buffer *buff,
|
||||||
uint8_t operMSB, uint8_t operLSB, uint8_t miscdata );
|
uint8_t operMSB, uint8_t operLSB, uint8_t miscdata );
|
||||||
|
|
||||||
uint8_t buffer_opcode_return( uint8_t opcode, buffer *buff,
|
uint8_t buffer_opcode_return( uint8_t opcode, buffer *buff,
|
||||||
uint8_t operMSB, uint8_t operLSB, uint8_t miscdata,
|
uint8_t operMSB, uint8_t operLSB, uint8_t miscdata,
|
||||||
uint8_t *rvalue, uint16_t *rlength );
|
//uint8_t *rvalue, uint16_t *rlength );
|
||||||
|
uint8_t *rvalue, uint8_t *rlength );
|
||||||
|
|
||||||
uint8_t buffer_opcode_buffnum_no_return( uint8_t opcode, buffer *buff,
|
uint8_t buffer_opcode_buffnum_no_return( uint8_t opcode, buffer *buff,
|
||||||
uint8_t operMSB, uint8_t operLSB, uint8_t miscdata );
|
uint8_t operMSB, uint8_t operLSB, uint8_t miscdata );
|
||||||
|
|
@ -23,12 +27,16 @@ uint8_t buffer_opcode_buffnum_no_return( uint8_t opcode, buffer *buff,
|
||||||
void raw_buffer_reset( );
|
void raw_buffer_reset( );
|
||||||
uint8_t allocate_buffer( buffer *buff, uint8_t new_id, uint8_t base_bank, uint8_t num_banks );
|
uint8_t allocate_buffer( buffer *buff, uint8_t new_id, uint8_t base_bank, uint8_t num_banks );
|
||||||
|
|
||||||
|
uint8_t * buffer_payload( setup_packet *spacket, buffer *buff, uint8_t hostsetbuff, uint8_t *rlength );
|
||||||
|
|
||||||
|
void update_buffers();
|
||||||
|
|
||||||
//used to communicate to usbFunctionWrite which buffer object
|
//used to communicate to usbFunctionWrite which buffer object
|
||||||
//it should be filling
|
//it should be filling
|
||||||
buffer *cur_usb_load_buff;
|
buffer *cur_usb_load_buff;
|
||||||
//used to determine number of bytes left to finish current
|
//used to determine number of bytes left to finish current
|
||||||
//OUT transfer utilized by usbFunctionWrite
|
//OUT transfer utilized by usbFunctionWrite
|
||||||
uint16_t incoming_bytes_remain;
|
//uint16_t incoming_bytes_remain;
|
||||||
|
uint8_t incoming_bytes_remain;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#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
|
||||||
|
* 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 addrH = (buff->page_num | 0x80); //or in $8000 to set equiv CPU address
|
||||||
|
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef _dump_h
|
||||||
|
#define _dump_h
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include "types.h"
|
||||||
|
#include "logic.h"
|
||||||
|
#include "usb.h"
|
||||||
|
#include "nes.h"
|
||||||
|
#include "shared_dictionaries.h"
|
||||||
|
#include "shared_errors.h"
|
||||||
|
|
||||||
|
uint8_t dump_page( buffer *buff ) ;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#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 ) {
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef _flash_h
|
||||||
|
#define _flash_h
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include "types.h"
|
||||||
|
#include "logic.h"
|
||||||
|
#include "usb.h"
|
||||||
|
#include "shared_dictionaries.h"
|
||||||
|
#include "shared_errors.h"
|
||||||
|
|
||||||
|
uint8_t flash_page( buffer *buff ) ;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include "usbdrv.h"
|
#include "usbdrv.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "pinport.h"
|
#include "pinport.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
|
@ -54,5 +55,18 @@ int main(void)
|
||||||
//must call at regular intervals no longer than 50msec
|
//must call at regular intervals no longer than 50msec
|
||||||
//checks for setup packets from what I understand
|
//checks for setup packets from what I understand
|
||||||
usbPoll();
|
usbPoll();
|
||||||
|
|
||||||
|
//check buffer status' and instruct them to
|
||||||
|
//flash/dump as needed to keep data moving
|
||||||
|
//currently assuming this operation doesn't take longer
|
||||||
|
//than 50msec to meet usbPoll's req't
|
||||||
|
//considering using a timer counter interupt to call
|
||||||
|
//usbPoll more often but going to see how speed is
|
||||||
|
//impacted first..
|
||||||
|
//256Bytes * 20usec Tbp = 5.12msec programming time
|
||||||
|
//+ cpu operations that can't be hid behind flash wait time
|
||||||
|
//another thought would be to call usbPoll mid programming
|
||||||
|
//a few times to prevent incoming data from being delayed too long
|
||||||
|
update_buffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ typedef struct setup_packet{
|
||||||
//~16 bytes per buffer...
|
//~16 bytes per buffer...
|
||||||
typedef struct buffer {
|
typedef struct buffer {
|
||||||
uint8_t *data; //pointer to base buffer's allocated sram
|
uint8_t *data; //pointer to base buffer's allocated sram
|
||||||
uint8_t size; //size of buffer in bytes (max 256 bytes)
|
//uint8_t size; //size of buffer in bytes (max 256 bytes) THIS DOESN'T work 256B = 9bit value
|
||||||
|
uint8_t last_idx; //index of last byte in buffer used to determine when at end of buffer
|
||||||
uint8_t status; //current status of buffer USB load/unload, flashing, waiting, erase
|
uint8_t status; //current status of buffer USB load/unload, flashing, waiting, erase
|
||||||
uint8_t cur_byte; //byte currently being loaded/unloaded/flashed/read
|
uint8_t cur_byte; //byte currently being loaded/unloaded/flashed/read
|
||||||
uint8_t reload; //add this number to page_num for next loading
|
uint8_t reload; //add this number to page_num for next loading
|
||||||
|
|
|
||||||
|
|
@ -71,11 +71,11 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) {
|
||||||
//#if USB_CFG_LONG_TRANSFERS
|
//#if USB_CFG_LONG_TRANSFERS
|
||||||
// //number of bytes to return to host
|
// //number of bytes to return to host
|
||||||
// //16bit meets max possible 16KBytes with V-USB long transfers enabled
|
// //16bit meets max possible 16KBytes with V-USB long transfers enabled
|
||||||
uint16_t rlen = 0; //just go ahead and set to 16bit to be safe
|
//uint16_t rlen = 0; //the speed loss doesn't make long transfers worth it for now
|
||||||
//prob not worth saving a measly byte..
|
|
||||||
//#else
|
//#else
|
||||||
// //8bit is enough for 254 bit non-long xfrs
|
// //8bit is enough for 254 bit non-long xfrs
|
||||||
// uint8_t rlen = 0;
|
// //also gives ~0.7KBps speed up compared to 16bit rlen
|
||||||
|
uint8_t rlen = 0;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//determine endpoint IN/OUT
|
//determine endpoint IN/OUT
|
||||||
|
|
@ -176,7 +176,8 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) {
|
||||||
//if there are future status' to read back may have to create some functions
|
//if there are future status' to read back may have to create some functions
|
||||||
rv[RV_ERR_IDX] = SUCCESS;
|
rv[RV_ERR_IDX] = SUCCESS;
|
||||||
rv[RV_DATA0_IDX] = usbWrite_status;
|
rv[RV_DATA0_IDX] = usbWrite_status;
|
||||||
rlen = 2;
|
rv[RV_DATA0_IDX+1] = cur_usb_load_buff->last_idx;
|
||||||
|
rlen = 3;
|
||||||
break; //end of USB
|
break; //end of USB
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -255,6 +256,14 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) {
|
||||||
* Rtn: message to V-USB driver so it can respond to host
|
* Rtn: message to V-USB driver so it can respond to host
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//removing checks from this function speeds up transfers by ~1KBps
|
||||||
|
//this data is based on doing nothing with data once it arrives
|
||||||
|
//long transfers disabled, and using 254 byte transfers with 2 bytes stuffed in setup packet
|
||||||
|
// with checks: 512KByte = 18.7sec = 27.4KBps
|
||||||
|
// w/o checks: 512KByte = 17.9sec = 28.5KBps
|
||||||
|
// w/o checks: using 8bit rlen = 17.5sec = 29.2KBps
|
||||||
|
// with checks: using 8bit rlen = 18sec = 28.3KBps
|
||||||
|
//#define MAKECHECKS 0
|
||||||
|
|
||||||
USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) {
|
USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) {
|
||||||
|
|
||||||
|
|
@ -262,16 +271,18 @@ USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) {
|
||||||
uint8_t buf_cur = cur_usb_load_buff->cur_byte; //current buffer byte
|
uint8_t buf_cur = cur_usb_load_buff->cur_byte; //current buffer byte
|
||||||
uint8_t *buf_data = cur_usb_load_buff->data; //current buffer data array
|
uint8_t *buf_data = cur_usb_load_buff->data; //current buffer data array
|
||||||
|
|
||||||
|
#ifdef MAKECHECKS
|
||||||
//check that current buffer's status is USB_LOADING
|
//check that current buffer's status is USB_LOADING
|
||||||
if (cur_usb_load_buff->status != USB_LOADING) {
|
if (cur_usb_load_buff->status != USB_LOADING) {
|
||||||
usbWrite_status = ERR_OUT_CURLDBUF_STATUS;
|
usbWrite_status = ERR_OUT_CURLDBUF_STATUS;
|
||||||
return STALL;
|
return STALL;
|
||||||
}
|
}
|
||||||
//check that current buffer's has enough room
|
//check that current buffer's has enough room
|
||||||
if ( ((cur_usb_load_buff->size) - buf_cur) < len ) {
|
if ( ((cur_usb_load_buff->last_idx) + 1 - buf_cur) < len ) {
|
||||||
usbWrite_status = ERR_OUT_CURLDBUF_TO_SMALL;
|
usbWrite_status = ERR_OUT_CURLDBUF_TO_SMALL;
|
||||||
return STALL;
|
return STALL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//copy 1-8bytes of payload into buffer
|
//copy 1-8bytes of payload into buffer
|
||||||
while ( data_cur < len ) {
|
while ( data_cur < len ) {
|
||||||
|
|
@ -285,8 +296,10 @@ USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) {
|
||||||
incoming_bytes_remain -= len;
|
incoming_bytes_remain -= len;
|
||||||
usbWrite_status = SUCCESS;
|
usbWrite_status = SUCCESS;
|
||||||
|
|
||||||
//check if buffer is full and update status accordingly
|
//want this function to be as fast as possible, so buffer.c checks if
|
||||||
if ( (cur_usb_load_buff->size) == buf_cur) {
|
//the buffer is full 'behind the scenes' outside of this function.
|
||||||
|
|
||||||
|
if ( (cur_usb_load_buff->last_idx) == buf_cur) {
|
||||||
//this signals to buffer.c so it can update cur_usb_load_buf
|
//this signals to buffer.c so it can update cur_usb_load_buf
|
||||||
//and start tasking this buffer to programming
|
//and start tasking this buffer to programming
|
||||||
cur_usb_load_buff->status = USB_FULL;
|
cur_usb_load_buff->status = USB_FULL;
|
||||||
|
|
|
||||||
|
|
@ -113,31 +113,16 @@ int dictionary_call( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode,
|
||||||
break; //end of SNES
|
break; //end of SNES
|
||||||
|
|
||||||
case BUFFER: debug("dict: BUFFER");
|
case BUFFER: debug("dict: BUFFER");
|
||||||
transfer->wLength = 1;
|
transfer->wLength = length;
|
||||||
switch (opcode) {
|
if (buffer != NULL) {
|
||||||
case BUFF_OPCODE_NRV_MIN ... BUFF_OPCODE_NRV_MAX:
|
transfer->data = (unsigned char *)buffer;
|
||||||
debug("BUFF_OPCODE_NRV");
|
|
||||||
break;
|
|
||||||
case BUFF_OPCODE_RV_MIN ... BUFF_OPCODE_RV_MAX:
|
|
||||||
debug("BUFF_OPCODE_RV");
|
|
||||||
transfer->wLength = 2;
|
|
||||||
break;
|
|
||||||
case BUFF_OPCODE_BUFN_NRV_MIN ... BUFF_OPCODE_BUFN_NRV_MAX:
|
|
||||||
debug("BUFF_OPCODE_NRV");
|
|
||||||
break;
|
|
||||||
case BUFF_OPCODE_BUFN_RV_MIN ... BUFF_OPCODE_BUFN_RV_MAX:
|
|
||||||
debug("BUFF_OPCODE_RV");
|
|
||||||
break;
|
|
||||||
case BUFF_OPCODE_PAYLOAD_MIN ... BUFF_OPCODE_PAYLOAD_MAX:
|
|
||||||
debug("BUFF_OPCODE_PAYLOAD");
|
|
||||||
transfer->data = (unsigned char *)buffer;
|
|
||||||
transfer->wLength = length;
|
|
||||||
break;
|
|
||||||
default: //snes opcode min/max definition error
|
|
||||||
sentinel("bad BUFFER opcode min/max err:%d",ERR_BAD_BUFF_OP_MINMAX);
|
|
||||||
}
|
}
|
||||||
break; //end of BUFF
|
break; //end of BUFF
|
||||||
|
|
||||||
|
case USB: debug("dict: USB");
|
||||||
|
transfer->wLength = length;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
//request (aka dictionary) is unknown
|
//request (aka dictionary) is unknown
|
||||||
sentinel("unknown DICT err:%d",ERR_UNKN_DICTIONARY);
|
sentinel("unknown DICT err:%d",ERR_UNKN_DICTIONARY);
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,36 @@ int test_function( USBtransfer *transfer )
|
||||||
{
|
{
|
||||||
|
|
||||||
debug("testing");
|
debug("testing");
|
||||||
|
dictionary_call( transfer, IO, IO_RESET, 0, 0, USB_IN, NULL, 1);
|
||||||
|
dictionary_call( transfer, IO, NES_INIT, 0, 0, USB_IN, NULL, 1);
|
||||||
|
dictionary_call( transfer, IO, EXP0_PULLUP_TEST, 0, 0, USB_IN, NULL, 8);
|
||||||
//dict opcode addr/index miscdata endpoint *buffer length
|
//dict opcode addr/index miscdata endpoint *buffer length
|
||||||
debug("reset butters");
|
debug("reset butters");
|
||||||
dictionary_call( transfer, BUFFER, RAW_BUFFER_RESET, 0, 0, USB_IN, NULL, 0);
|
dictionary_call( transfer, BUFFER, RAW_BUFFER_RESET, 0, 0, USB_IN, NULL, 1);
|
||||||
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0, USB_IN, NULL, 0);
|
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0, USB_IN, NULL, 2);
|
||||||
|
debug("get pri"); //id:basebank num32B banks
|
||||||
|
dictionary_call( transfer, BUFFER, GET_PRI_ELEMENTS, 0, 0, USB_IN, NULL, 8);
|
||||||
|
dictionary_call( transfer, BUFFER, GET_PRI_ELEMENTS, 0, 1, USB_IN, NULL, 8);
|
||||||
|
// debug("get nonexistent 7"); //id:basebank num32B banks
|
||||||
|
// dictionary_call( transfer, BUFFER, GET_PRI_ELEMENTS, 0, 7, USB_IN, NULL, 8);
|
||||||
|
// dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x7008, 8, USB_IN, NULL, 1);
|
||||||
|
// debug("get nonexistent 8"); //id:basebank num32B banks
|
||||||
|
// dictionary_call( transfer, BUFFER, GET_PRI_ELEMENTS, 0, 8, USB_IN, NULL, 8);
|
||||||
debug("allocate buff0 256B"); //id:basebank num32B banks
|
debug("allocate buff0 256B"); //id:basebank num32B banks
|
||||||
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER0, 0x1000, 8, USB_IN, NULL, 0);
|
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER0, 0x1000, 8, USB_IN, NULL, 1);
|
||||||
|
debug("allocate buff2 0B"); //id:basebank num32B banks
|
||||||
|
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER1, 0x2008, 0, USB_IN, NULL, 1);
|
||||||
debug("allocate buff1 256B"); //id:basebank num32B banks
|
debug("allocate buff1 256B"); //id:basebank num32B banks
|
||||||
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER1, 0x2008, 8, USB_IN, NULL, 0);
|
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER1, 0x2008, 8, USB_IN, NULL, 1);
|
||||||
debug("status"); //id:basebank num32B banks
|
debug("status"); //id:basebank num32B banks
|
||||||
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0, USB_IN, NULL, 0);
|
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0, USB_IN, NULL, 2);
|
||||||
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 4, 0, USB_IN, NULL, 0);
|
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 8, 0, USB_IN, NULL, 2);
|
||||||
|
debug("get pri"); //id:basebank num32B banks
|
||||||
|
dictionary_call( transfer, BUFFER, GET_PRI_ELEMENTS, 0, 0, USB_IN, NULL, 8);
|
||||||
|
dictionary_call( transfer, BUFFER, GET_PRI_ELEMENTS, 0, 1, USB_IN, NULL, 8);
|
||||||
|
debug("get sec"); //id:basebank num32B banks
|
||||||
|
dictionary_call( transfer, BUFFER, GET_SEC_ELEMENTS, 0, 0, USB_IN, NULL, 8);
|
||||||
|
dictionary_call( transfer, BUFFER, GET_SEC_ELEMENTS, 0, 1, USB_IN, NULL, 8);
|
||||||
|
|
||||||
uint8_t load_in[256];
|
uint8_t load_in[256];
|
||||||
uint8_t load_out[256];
|
uint8_t load_out[256];
|
||||||
|
|
@ -33,13 +52,13 @@ int test_function( USBtransfer *transfer )
|
||||||
|
|
||||||
//print load
|
//print load
|
||||||
printf("load_in data:");
|
printf("load_in data:");
|
||||||
for (i=0; i<256; i++) {
|
for (i=0; i<254; i++) {
|
||||||
printf(" %x",load_in[i]);
|
printf(" %x",load_in[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
//fill load with 0-127
|
//fill load with 0-127
|
||||||
for (i=0; i<256; i++) {
|
for (i=0; i<254; i++) {
|
||||||
load_out[i] = i;
|
load_out[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,22 +77,62 @@ int test_function( USBtransfer *transfer )
|
||||||
|
|
||||||
//print load
|
//print load
|
||||||
printf("load_in data:");
|
printf("load_in data:");
|
||||||
for (i=0; i<256; i++) {
|
for (i=0; i<254; i++) {
|
||||||
printf(" %x",load_in[i]);
|
printf(" %x",load_in[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
clock_t tstart, tstop;
|
dictionary_call( transfer, USB, 0, 0, 0, USB_IN, NULL, 3);
|
||||||
tstart = clock();
|
|
||||||
for ( i = (1024 * 2); i>0; i--) {
|
|
||||||
//for ( i = (1033 * 2); i>0; i--) {
|
|
||||||
dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_OUT, load_out, 254);
|
|
||||||
}
|
|
||||||
tstop = clock();
|
|
||||||
float timediff = ( (float)(tstop-tstart) / CLOCKS_PER_SEC);
|
|
||||||
printf("total time: %fsec, speed: %fKBps", timediff, (512/timediff));
|
|
||||||
//256byte transfers currently clocking in around 21KBps
|
|
||||||
|
|
||||||
|
debug("send payload0");
|
||||||
|
dictionary_call( transfer, BUFFER, BUFF_OUT_PAYLOAD_2B_INSP, 0xA5C3, 0, USB_OUT, &load_out[2], 254);
|
||||||
|
|
||||||
|
debug("read payload0");
|
||||||
|
dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254);
|
||||||
|
|
||||||
|
printf("load_in data:");
|
||||||
|
for (i=0; i<254; i++) {
|
||||||
|
printf(" %x",load_in[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
//clock_t tstart, tstop;
|
||||||
|
//printf("load_in data:");
|
||||||
|
//for (i=0; i<254; i++) {
|
||||||
|
// printf(" %x",load_in[i]);
|
||||||
|
//}
|
||||||
|
//printf("\n");
|
||||||
|
//tstart = clock();
|
||||||
|
//for ( i = (1024 * 2); i>0; i--) {
|
||||||
|
//dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_OUT, load_out, 254);
|
||||||
|
////for ( i = (1033 * 2); i>0; i--) {
|
||||||
|
////dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254);
|
||||||
|
////for ( i = (1024 * 4); i>0; i--) {
|
||||||
|
////dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 128);
|
||||||
|
//}
|
||||||
|
//tstop = clock();
|
||||||
|
//float timediff = ( (float)(tstop-tstart) / CLOCKS_PER_SEC);
|
||||||
|
//printf("total time: %fsec, speed: %fKBps", timediff, (512/timediff));
|
||||||
|
|
||||||
|
//256byte transfers currently clocking in around 21KBps
|
||||||
|
|
||||||
|
//dict opcode addr/index miscdata endpoint *buffer length
|
||||||
|
debug("set func");
|
||||||
|
dictionary_call( transfer, BUFFER, SET_FUNCTION, DUMPING, 0, USB_IN, NULL, 1);
|
||||||
|
debug("get sec");
|
||||||
|
dictionary_call( transfer, BUFFER, GET_SEC_ELEMENTS, 0, 0, USB_IN, NULL, 8);
|
||||||
|
dictionary_call( transfer, BUFFER, GET_SEC_ELEMENTS, 0, 1, USB_IN, NULL, 8);
|
||||||
|
|
||||||
|
debug("read payload0");
|
||||||
|
dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254);
|
||||||
|
|
||||||
|
printf("load_in data:");
|
||||||
|
for (i=0; i<254; i++) {
|
||||||
|
printf(" %x",load_in[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
dictionary_call( transfer, IO, IO_RESET, 0, 0, USB_IN, NULL, 1);
|
||||||
|
|
||||||
// dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER2, 0x3508, 4);
|
// dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER2, 0x3508, 4);
|
||||||
// dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER3, 0x4A0C, 4);
|
// dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER3, 0x4A0C, 4);
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
//to account for multiple bytes could expand further
|
//to account for multiple bytes could expand further
|
||||||
//#define NUM_RAW_BANKS 8 // 8*32 = 256 bytes of buffer
|
//#define NUM_RAW_BANKS 8 // 8*32 = 256 bytes of buffer
|
||||||
#define NUM_RAW_BANKS 16 //16*32 = 512 bytes of buffer
|
#define NUM_RAW_BANKS 16 //16*32 = 512 bytes of buffer
|
||||||
|
//#define NUM_RAW_BANKS 24 //24*32 = 768 DAMN THE TORPEDOS FULL SPEED AHEAD!!!
|
||||||
|
|
||||||
#define RAW_BANK_SIZE 32 //bank size in bytes
|
#define RAW_BANK_SIZE 32 //bank size in bytes
|
||||||
|
|
||||||
|
|
@ -52,7 +53,7 @@
|
||||||
#define USB_FULL 0x98
|
#define USB_FULL 0x98
|
||||||
#define CHECKING 0xC0
|
#define CHECKING 0xC0
|
||||||
#define DUMPING 0xD0
|
#define DUMPING 0xD0
|
||||||
#define DUMP_FULL 0xD8
|
#define DUMPED 0xD8
|
||||||
#define ERASING 0xE0
|
#define ERASING 0xE0
|
||||||
#define FLASHING 0xF0
|
#define FLASHING 0xF0
|
||||||
#define FLASH_WAIT 0xF8
|
#define FLASH_WAIT 0xF8
|
||||||
|
|
@ -62,20 +63,42 @@
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================================
|
//=============================================================================================
|
||||||
// OPCODES with up to 24bit operand and no return value besides SUCCESS/ERROR_CODE
|
// OPCODES with up to 24bit operand and optional return value besides SUCCESS/ERROR_CODE
|
||||||
|
// PAYLOAD options listed as well
|
||||||
//=============================================================================================
|
//=============================================================================================
|
||||||
// Detect this opcode/operand setup with opcode between the following defines:
|
// Detect this opcode/operand setup with opcode between the following defines:
|
||||||
|
//
|
||||||
|
//------------------------------------
|
||||||
#define BUFF_OPCODE_NRV_MIN 0x00
|
#define BUFF_OPCODE_NRV_MIN 0x00
|
||||||
|
//opcodes in this range have NO RETURN besides error code and DON'T contain buff# in miscdata byte
|
||||||
|
// ----------------------------
|
||||||
|
#define BUFFN_INMISC_MIN 0x30 //NOTE OVERLAP!!
|
||||||
|
//opcodes in this range have NO RETURN besides error code and DO contain buff# in miscdata byte
|
||||||
#define BUFF_OPCODE_NRV_MAX 0x3F
|
#define BUFF_OPCODE_NRV_MAX 0x3F
|
||||||
//
|
//------------------------------------
|
||||||
#define BUFFN_INMISC_MIN 0x30 //overlaps above
|
#define BUFF_PAYLOADN_MIN 0x40
|
||||||
#define BUFFN_INMISC_MAX 0x4F //overlaps below
|
//opcodes in this range are PAYLOADS and DO contain buff# in miscdata byte
|
||||||
//
|
#define BUFF_PAYLOADN_MAX 0x4F
|
||||||
#define BUFF_OPCODE_RV_MIN 0x40
|
//------------------------------------
|
||||||
#define BUFF_OPCODE_RV_MAX 0x7F
|
#define BUFF_OPCODE_RV_MIN 0x50
|
||||||
|
//opcodes in this range HAVE RETURN besides error code and DO contain buff# in miscdata byte
|
||||||
|
#define BUFFN_INMISC_MAX 0x5F //NOTE OVERLAP!!
|
||||||
|
// ----------------------------
|
||||||
|
//opcodes in this range HAVE RETURN value plus error code and DON'T contain buff# in miscdata byte
|
||||||
|
#define BUFF_OPCODE_RV_MAX 0x6F
|
||||||
|
//------------------------------------
|
||||||
|
#define BUFF_PAYLOAD_MIN 0x70
|
||||||
|
//opcodes in this range are PAYLOADS and DO NOT contain buff# in miscdata byte
|
||||||
|
#define BUFF_PAYLOAD_MAX 0x7F
|
||||||
//=============================================================================================
|
//=============================================================================================
|
||||||
//=============================================================================================
|
//=============================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
//opcodes in this range have NO RETURN besides error code and DON'T contain buff# in miscdata byte
|
||||||
|
//#define BUFF_OPCODE_NRV_MIN 0x00-2F
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
//blindly clear all allocation of raw buffer space
|
//blindly clear all allocation of raw buffer space
|
||||||
//reset all buffers to unallocated
|
//reset all buffers to unallocated
|
||||||
//no operands no return value
|
//no operands no return value
|
||||||
|
|
@ -83,6 +106,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
//opcodes in this range have NO RETURN besides error code and DO contain buff# in miscdata byte
|
||||||
|
//#define BUFFN_INMISC_MIN 0x30-3F //NOTE OVERLAP!!
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
//SET BUFFER ELEMENTS
|
//SET BUFFER ELEMENTS
|
||||||
|
|
||||||
//memory type and part number
|
//memory type and part number
|
||||||
|
|
@ -110,18 +137,39 @@
|
||||||
#define SET_FUNCTION 0x33
|
#define SET_FUNCTION 0x33
|
||||||
|
|
||||||
|
|
||||||
|
//#define BUFF_OPCODE_NRV_MAX 0x3F
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
//opcodes in this range are PAYLOADS and DO contain buff# in miscdata byte
|
||||||
|
//#define BUFF_PAYLOADN_MIN 0x40-4F
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//designate what buffer to fill with miscdata byte
|
||||||
|
//no return value as it's write OUT only
|
||||||
|
//operandMSB:LSB actually contains first 2 bytes
|
||||||
|
#define BUFF_OUT_PAYLOADN_2B_INSP 0x40
|
||||||
|
|
||||||
|
//designate what buffer to fill with miscdata byte
|
||||||
|
//no return value as it's write OUT only
|
||||||
|
//operandMSB:LSB actually contains first 2 bytes
|
||||||
|
#define BUFF_NODESG_PAYLOAD 0x41
|
||||||
|
|
||||||
|
|
||||||
|
//#define BUFF_PAYLOADN_MAX 0x4F
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
//opcodes in this range HAVE RETURN besides error code and DO contain buff# in miscdata byte
|
||||||
|
//#define BUFF_OPCODE_RV_MIN 0x50-5F
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
//return buffer elements
|
//return buffer elements
|
||||||
//misc/data: buffer number
|
//misc/data: buffer number
|
||||||
//rv0: success/error code
|
//rv0: success/error code
|
||||||
//rv1: size
|
//rv1: last_idx
|
||||||
//rv2: status
|
//rv2: status
|
||||||
//rv3: cur_byte
|
//rv3: cur_byte
|
||||||
//rv4: reload
|
//rv4: reload
|
||||||
//rv5: id
|
//rv5: id
|
||||||
//rv76: page_num
|
//rv76: page_num
|
||||||
#define GET_PRI_ELEMENTS 0x40
|
#define GET_PRI_ELEMENTS 0x50
|
||||||
|
|
||||||
//return buffer elements
|
//return buffer elements
|
||||||
//misc/data: buffer number
|
//misc/data: buffer number
|
||||||
|
|
@ -133,9 +181,14 @@
|
||||||
//rv5: mapper
|
//rv5: mapper
|
||||||
//rv6: mapvar
|
//rv6: mapvar
|
||||||
//rv7: function
|
//rv7: function
|
||||||
#define GET_SEC_ELEMENTS 0x41
|
#define GET_SEC_ELEMENTS 0x51
|
||||||
|
|
||||||
|
|
||||||
|
//#define BUFFN_INMISC_MAX 0x5F //NOTE OVERLAP!!
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
//opcodes in this range HAVE RETURN value plus error code and DON'T contain buff# in miscdata byte
|
||||||
|
// 0x60-6F
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
//send bank number and read back it's status
|
//send bank number and read back it's status
|
||||||
//0xFF-UNALLOC
|
//0xFF-UNALLOC
|
||||||
|
|
@ -143,7 +196,32 @@
|
||||||
//operandMSB/miscdata: unused
|
//operandMSB/miscdata: unused
|
||||||
//operandLSB: raw bank number to retrieve status of
|
//operandLSB: raw bank number to retrieve status of
|
||||||
//return value status of that raw bank (set to bank id if allocated)
|
//return value status of that raw bank (set to bank id if allocated)
|
||||||
#define RAW_BANK_STATUS 0x50
|
#define RAW_BANK_STATUS 0x60
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#define BUFF_OPCODE_RV_MAX 0x6F
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
//opcodes in this range are PAYLOADS and DO NOT contain buff# in miscdata byte
|
||||||
|
//#define BUFF_PAYLOAD_MIN 0x70-7F
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
//does NOT designate what buffer to fill with opcode
|
||||||
|
//endpoint direction determines if read/write
|
||||||
|
//no operands no return value aside from payload for transfer IN
|
||||||
|
//max size for these transfers is 254Bytes for IN and OUT
|
||||||
|
#define BUFF_PAYLOAD 0x70
|
||||||
|
|
||||||
|
//does NOT designate what buffer to fill with opcode
|
||||||
|
//no return value as it's write OUT only
|
||||||
|
//operandMSB:LSB actually contains first 2 bytes
|
||||||
|
#define BUFF_OUT_PAYLOAD_2B_INSP 0x71
|
||||||
|
|
||||||
|
|
||||||
|
//#define BUFF_PAYLOAD_MAX 0x7F
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================================
|
//=============================================================================================
|
||||||
// OPCODES with up to 24bit operand and no return value besides SUCCESS/ERROR_CODE
|
// OPCODES with up to 24bit operand and no return value besides SUCCESS/ERROR_CODE
|
||||||
|
|
@ -153,6 +231,7 @@
|
||||||
#define BUFF_OPCODE_BUFN_MIN 0x80
|
#define BUFF_OPCODE_BUFN_MIN 0x80
|
||||||
#define BUFF_OPCODE_BUFN_MAX 0xFF
|
#define BUFF_OPCODE_BUFN_MAX 0xFF
|
||||||
//
|
//
|
||||||
|
//
|
||||||
// Detect this opcode/operand setup with opcode between the following defines:
|
// Detect this opcode/operand setup with opcode between the following defines:
|
||||||
#define BUFF_OPCODE_BUFN_NRV_MIN 0x80
|
#define BUFF_OPCODE_BUFN_NRV_MIN 0x80
|
||||||
#define BUFF_OPCODE_BUFN_NRV_MAX 0xBF
|
#define BUFF_OPCODE_BUFN_NRV_MAX 0xBF
|
||||||
|
|
@ -164,6 +243,8 @@
|
||||||
#define BUFF_OPCODE_PAYLOAD_MAX 0xFF
|
#define BUFF_OPCODE_PAYLOAD_MAX 0xFF
|
||||||
//=============================================================================================
|
//=============================================================================================
|
||||||
//=============================================================================================
|
//=============================================================================================
|
||||||
|
|
||||||
|
|
||||||
//allocate firmware sram to a buffer
|
//allocate firmware sram to a buffer
|
||||||
//send a buffer number
|
//send a buffer number
|
||||||
//buffer size
|
//buffer size
|
||||||
|
|
@ -174,6 +255,7 @@
|
||||||
// (upper id bits used to set any address bits not covered by page and buff size if needed)
|
// (upper id bits used to set any address bits not covered by page and buff size if needed)
|
||||||
//operLSB: base bank number
|
//operLSB: base bank number
|
||||||
//misc/data: size (number of banks to allocate to buffer)
|
//misc/data: size (number of banks to allocate to buffer)
|
||||||
|
// -size doesn't get stored in buffer, the last_idx does
|
||||||
#define ALLOCATE_BUFFER0 0x80
|
#define ALLOCATE_BUFFER0 0x80
|
||||||
#define ALLOCATE_BUFFER1 0x81
|
#define ALLOCATE_BUFFER1 0x81
|
||||||
#define ALLOCATE_BUFFER2 0x82
|
#define ALLOCATE_BUFFER2 0x82
|
||||||
|
|
@ -202,6 +284,7 @@
|
||||||
//designate what buffer to fill with opcode
|
//designate what buffer to fill with opcode
|
||||||
//endpoint direction determines if read/write
|
//endpoint direction determines if read/write
|
||||||
//no operands no return value aside from payload for transfer IN
|
//no operands no return value aside from payload for transfer IN
|
||||||
|
//DOES NOT STUFF extra bytes in setup packet for write/OUT transfers
|
||||||
#define BUFF_PAYLOAD0 0xF0
|
#define BUFF_PAYLOAD0 0xF0
|
||||||
#define BUFF_PAYLOAD1 0xF1
|
#define BUFF_PAYLOAD1 0xF1
|
||||||
#define BUFF_PAYLOAD2 0xF2
|
#define BUFF_PAYLOAD2 0xF2
|
||||||
|
|
@ -217,7 +300,7 @@
|
||||||
//as initially defined in firmware
|
//as initially defined in firmware
|
||||||
//typedef struct buffer{
|
//typedef struct buffer{
|
||||||
// uint8_t *data; //pointer to base buffer's allocated sram
|
// uint8_t *data; //pointer to base buffer's allocated sram
|
||||||
// uint8_t size; //size of buffer in bytes (max 256 bytes)
|
// uint8_t last_idx; //index of last byte in buffer used to determine when at end of buffer
|
||||||
// uint8_t status; //current status of buffer USB load/unload, flashing, waiting, erase
|
// uint8_t status; //current status of buffer USB load/unload, flashing, waiting, erase
|
||||||
// uint8_t cur_byte; //byte currently being loaded/unloaded/flashed/read
|
// uint8_t cur_byte; //byte currently being loaded/unloaded/flashed/read
|
||||||
// uint8_t reload; //add this number to page_num for next loading
|
// uint8_t reload; //add this number to page_num for next loading
|
||||||
|
|
@ -321,18 +404,24 @@
|
||||||
// 128Byte OUT (write) transfers with long transfers ENABLED: 20.7 sec/512KByte = 24.7 KBps
|
// 128Byte OUT (write) transfers with long transfers ENABLED: 20.7 sec/512KByte = 24.7 KBps
|
||||||
// 256Byte OUT (write) transfers with long transfers ENABLED: 18.56sec/512KByte = 27.6 KBps
|
// 256Byte OUT (write) transfers with long transfers ENABLED: 18.56sec/512KByte = 27.6 KBps
|
||||||
// 254Byte OUT (write) transfers with long transfers DISABLED: 17.9 sec/512KByte = 28.6 KBps (assuming 2 bytes stuffed in setup packet)
|
// 254Byte OUT (write) transfers with long transfers DISABLED: 17.9 sec/512KByte = 28.6 KBps (assuming 2 bytes stuffed in setup packet)
|
||||||
// 254Byte IN (read) with long xfr DISABLED, w/o usbFuncRd: 30.9 sec/512KByte = 16.5 KBps
|
// 128Byte IN (read) with long xfr DISABLED, w/o usbFuncRd: 30.5 sec/512KByte = 16.8 KBps
|
||||||
// 254Byte IN (read) with long xfr DISABLED, w/usbFuncRd: 34.9 sec/512KByte = 14.7 KBps
|
// 128Byte IN (read) with long xfr DISABLED, w/usbFuncRd: 34.9 sec/512KByte = 14.7 KBps
|
||||||
|
// 1033*254Byte IN (read) long xfr DISABLED, w/o usbFuncRd: 28.35sec/512KByte = 18.1 KBps
|
||||||
//
|
//
|
||||||
// These tests did nothing with payload once it arrived, so these are practical maximums of V-usb.
|
// These tests did nothing with payload once it arrived, so these are practical maximums of V-usb.
|
||||||
// Conclusion:
|
// Conclusion:
|
||||||
// -enabling long transfers slows writes (and probably reads)
|
// -enabling long transfers slows writes (and probably reads)
|
||||||
// -reads are much slower than writes.
|
// -reads are much slower than writes.
|
||||||
// -enabling usbFunctionRead is slower compared to using usbFunctionSetup alone.
|
// -enabling usbFunctionRead is slower compared to using usbFunctionSetup alone.
|
||||||
// -using 254B xfrs with 2 bytes stuffed in setup packet gives decent boost.
|
// -using 254B xfrs with 2 bytes stuffed in setup packet gives decent boost for writes.
|
||||||
// this is primarily due to speed up of not having long transfers enabled.
|
// this is primarily due to speed up of not having long transfers enabled.
|
||||||
// -not actually certain enabling long transfers will slow down reads, but it certainly does for writes.
|
// -not actually certain enabling long transfers will slow down reads, but it certainly does for writes.
|
||||||
//
|
// -reads can't stuff 2 bytes in setup packet because data is going opposite direction as setup packet.
|
||||||
|
// -reads do have decent speed boost of ~1.3KBps using 254B * 1033xfrs over 128*2048xfrs
|
||||||
|
// for reads to get this speed boost the missing 2 bytes would have to be accumulated in
|
||||||
|
// separate buffer and sent separately once full.
|
||||||
|
// Only other way without complicating dump algo would be to implement usbFuncRd
|
||||||
|
// but that would slow things down and negate the speed boost..
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@
|
||||||
#define ERR_UNKN_NES_OPCODE_24BOP 160
|
#define ERR_UNKN_NES_OPCODE_24BOP 160
|
||||||
#define ERR_UNKN_NES_OPCODE_16BOP_8BRV 161
|
#define ERR_UNKN_NES_OPCODE_16BOP_8BRV 161
|
||||||
|
|
||||||
|
//reserved libusb erro 165
|
||||||
|
|
||||||
#define ERR_UNKN_SNES_OPCODE_24BOP 170
|
#define ERR_UNKN_SNES_OPCODE_24BOP 170
|
||||||
#define ERR_UNKN_SNES_OPCODE_24BOP_8BRV 171
|
#define ERR_UNKN_SNES_OPCODE_24BOP_8BRV 171
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue