Creations of operation module and dictionary.

Things appear to be working with some early testing.  Assumption that oper_info elements
are aligned in SRAM linearly appears to hold true.  Researching this I found it probably
was true, but can't be certain esp if gets changed in the future to not be purely 8byte
sized elements.
Still need to provide means to decode function numbers info function pointers.
This commit is contained in:
paul eeepc 2016-12-25 13:48:30 -06:00
parent de9b5d67a4
commit 4b0c340eb1
22 changed files with 696 additions and 73 deletions

View File

@ -12,7 +12,7 @@ buffer *cur_usb_load_buff;
uint8_t incoming_bytes_remain;
//host means of communicating to buffer manager
uint8_t operation;
//uint8_t operation;
//min define of two buffers
buffer buff0;
@ -184,9 +184,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_BUFFER_OPERATION:
// operation = operLSB;
// break;
case SET_MEM_N_PART:
buff->mem_type = operMSB;
buff->part_num = operLSB;
@ -217,7 +217,7 @@ uint8_t buffer_opcode_no_return( uint8_t opcode, buffer *buff,
* Pre: Macros must be defined in firmware pinport.h
* opcode must be defined in shared_dict_buffer.h
* Post:function call complete.
* Rtn: SUCCESS if opcode found, ERR_UNKN_BUFF_OPCODE_NRV if opcode not present.
* Rtn: SUCCESS if opcode found, ERR_UNKN_BUFF_OPCODE_RV if opcode not present.
*/
uint8_t buffer_opcode_return( uint8_t opcode, buffer *buff,
uint8_t operMSB, uint8_t operLSB, uint8_t miscdata,
@ -229,10 +229,10 @@ uint8_t buffer_opcode_return( uint8_t opcode, buffer *buff,
*rvalue = raw_bank_status[operLSB];
*rlength += 1;
break;
case GET_BUFF_OPERATION:
*rvalue = operation;
*rlength += 1;
break;
//case GET_BUFF_OPERATION:
// *rvalue = operation;
// *rlength += 1;
// break;
case GET_PRI_ELEMENTS:
rvalue[0] = buff->last_idx;
rvalue[1] = buff->status;
@ -255,7 +255,7 @@ uint8_t buffer_opcode_return( uint8_t opcode, buffer *buff,
break;
default:
//opcode doesn't exist
return ERR_UNKN_BUFF_OPCODE_NRV;
return ERR_UNKN_BUFF_OPCODE_RV;
}
return SUCCESS;
@ -330,7 +330,8 @@ uint8_t * buffer_payload( setup_packet *spacket, buffer *buff, uint8_t hostsetbu
} else {
//problem, buffers not prepared or initialized
*rlength = USB_NO_MSG;
operation = PROBLEM;
//operation = PROBLEM;
set_operation( PROBLEM );
}
} else {//writes
if ( cur_buff->status == EMPTY ) {
@ -338,7 +339,8 @@ uint8_t * buffer_payload( setup_packet *spacket, buffer *buff, uint8_t hostsetbu
cur_usb_load_buff = cur_buff;
cur_buff->status = USB_LOADING;
} else {
operation = PROBLEM;
//operation = PROBLEM;
set_operation( PROBLEM );
}
}
cur_buff->cur_byte = 0;
@ -412,7 +414,8 @@ void raw_buffer_reset( )
buff7.id = UNALLOC;
#endif
operation = RESET;
//operation = RESET;
set_operation( RESET );
}
@ -500,6 +503,29 @@ uint8_t allocate_buffer( buffer *buff, uint8_t new_id, uint8_t base_bank, uint8_
}
//used to copy contents of buffer to another sram location
void copy_buff0_to_data( uint8_t *data, uint8_t length )
{
uint8_t i;
for ( i=0; i<length; i++ ) {
data[i] = buff0.data[i];
}
}
//used to copy data to buff0 from another location
void copy_data_to_buff0( uint8_t *data, uint8_t length )
{
uint8_t i;
for ( i=0; i<length; i++ ) {
buff0.data[i] = data[i];
}
}
//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 )
@ -608,7 +634,8 @@ void update_buffers()
//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 ) ) {
//if ( (operation == STARTDUMP) || (operation == STARTFLASH ) ) {
if ( (get_operation() == STARTDUMP) || (get_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
@ -620,7 +647,8 @@ void update_buffers()
//now we can get_next_buff by passing cur_buff
}
if (operation == STARTDUMP) {
//if (operation == STARTDUMP) {
if (get_operation() == STARTDUMP) {
//prepare both buffers to dump
//do all the same things that would happen between buffers to start things moving
@ -635,11 +663,14 @@ void update_buffers()
//that will now trigger operation == DUMPING to dump first buffer
//don't want to reenter start initialiation again
operation = DUMPING;
//operation = DUMPING;
set_operation( DUMPING );
}
if (operation == STARTFLASH) {
//if (operation == STARTFLASH) {
if (get_operation() == STARTFLASH) {
//don't want to reenter start initialiation again
operation = FLASHING;
//operation = FLASHING;
set_operation( FLASHING );
//not much else to do, just waiting on payload OUT transfer
//current buffer prepared to be sent to usbFunctionWrite
@ -654,7 +685,8 @@ void update_buffers()
}
//this will get entered on first and all successive calls
if ( operation == DUMPING ) {
//if ( operation == DUMPING ) {
if ( get_operation() == DUMPING ) {
//buffer_payload will pass cur_buff to usb driver on next IN transfer
//on receipt of the IN transfer buffer_payload sets:
// cur_buff->status = USB_UNLOADING;
@ -681,7 +713,8 @@ void update_buffers()
}
if ( operation == FLASHING ) {
//if ( operation == FLASHING ) {
if ( get_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

View File

@ -8,7 +8,9 @@
#include "usb.h"
#include "flash.h"
#include "dump.h"
#include "operation.h"
#include "shared_dictionaries.h"
#include "shared_enums.h"
#include "shared_errors.h"
@ -27,6 +29,8 @@ uint8_t buffer_opcode_buffnum_no_return( uint8_t opcode, buffer *buff,
void raw_buffer_reset( );
uint8_t allocate_buffer( buffer *buff, uint8_t new_id, uint8_t base_bank, uint8_t num_banks );
void copy_buff0_to_data( uint8_t *data, uint8_t length );
void copy_data_to_buff0( uint8_t *data, uint8_t length );
uint8_t * buffer_payload( setup_packet *spacket, buffer *buff, uint8_t hostsetbuff, uint8_t *rlength );

View File

@ -5,12 +5,32 @@ uint8_t write_page( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr wr_
{
uint8_t i = buff->cur_byte;
uint8_t read;
extern operation_info *oper_info;
do {
//write unlock sequence
wr_func( 0x55, 0x55, 0xAA );
wr_func( 0x2A, 0xAA, 0x55 );
wr_func( 0x55, 0x55, 0xA0 );
//need to make address and unlock data variable
//best for host to communcate these values
//actual value is part mapper dependent and part flash dependent
//mapper controlled address bits dictate where split is
//32KB banking A14-0 NES ctl, A15+ mapper ctl "bank" NROM, BNROM, ANROM
//addrH_dmask = 0b0111 1111 directly addressable addrH bits
//page2bankshft = A14->A8 = 7 shifts (equal to number of set bits in addrH_mask
//16KB banking A13-0 NES ctl, A14+ mapper ctl "bank" UxROM, MMC1
//addrH_dmask = 0b0011 1111
//page2bankshft = A13->A8 = 6 shifts
// 8KB banking A12-0 NES ctl, A13+ mapper ctl "bank" MMC3, FME7
//addrH_dmask = 0b0001 1111
//page2bankshft = A12->A8 = 5 shifts
// 4KB banking A11-0 NES ctl, A12+ mapper ctl "bank" ezNSF
//addrH_dmask = 0b0000 1111
//page2bankshft = A11->A8 = 4 shifts
//wr_func( 0x55, 0x55, 0xAA );
wr_func( oper_info->unlock1_AH, oper_info->unlock1_AL, oper_info->unlock1_data );
//wr_func( 0x2A, 0xAA, 0x55 );
wr_func( oper_info->unlock2_AH, oper_info->unlock2_AL, oper_info->unlock2_data );
//wr_func( 0x55, 0x55, 0xA0 );
wr_func( oper_info->command_AH, oper_info->command_AL, oper_info->command1_data );
wr_func( addrH, i, buff->data[i] );
do {
@ -18,7 +38,7 @@ uint8_t write_page( uint8_t bank, uint8_t addrH, buffer *buff, write_funcptr wr_
read = rd_func( addrH, i );
} while( read != rd_func( addrH, i) );
//TODO verify byte is value that was trying to be flashed
//move on to next byte
i++;
} while ( i != buff->last_idx );

151
firmware/source/operation.c Normal file
View File

@ -0,0 +1,151 @@
#include "operation.h"
//struct to hold all operation info
operation_info oper_info_struct;
operation_info *oper_info = &oper_info_struct;
/* Desc:Bridge between usb.c and operation.c functions
* usb.c calls this function providing setup packet info
* usb.c also provides pointer to small 'rv' return value buffer of 8bytes
* and pointer to rlen so operation.c can decide wether to utilize the
* small 8byte generic return buffer or point usbMsgPtr to some larger buffer of sram.
* this function interprets opcode type to call proper opcode switch function
* Pre: opcode must be defined in shared_dict_operation.h
* Post:function call complete.
* rlen updated to lenght of return data
* rv[RV_ERR_IDX] contains SUCCESS/ERROR code
* rv buffer filled with return data for small data requests
* Rtn: pointer to ram buffer to be returned over USB
*/
uint8_t * operation_usb_call( setup_packet *spacket, uint8_t *rv, uint8_t *rlen)
{
uint8_t *rptr = rv; //used for return pointer set to small rv buffer by default
switch (spacket->opcode) {
case OPER_OPCODE_NRV_MIN ... OPER_OPCODE_NRV_MAX:
rv[RV_ERR_IDX] = oper_opcode_no_return( spacket->opcode,
spacket->operandMSB, spacket->operandLSB, spacket->miscdata );
*rlen = RV_ERR_IDX+1;
break;
case OPER_OPCODE_RV_MIN ... OPER_OPCODE_RV_MAX:
rv[RV_ERR_IDX] = oper_opcode_return( spacket->opcode,
spacket->operandMSB, spacket->operandLSB, spacket->miscdata,
&rv[RV_DATA0_IDX], rlen );
break;
default: //nes opcode min/max definition error
rv[RV_ERR_IDX] = ERR_BAD_OPER_OP_MINMAX;
}
return rptr;
}
read_funcptr decode_rdfunc_num( uint8_t func_num ) {
switch( func_num ) {
case NES_CPU_RD: return nes_cpu_rd;
case NES_PPU_RD: return nes_ppu_rd;
case EMULATE_NES_CPU_RD: return emulate_nes_cpu_rd;
default:
return (void*)~SUCCESS;
}
}
write_funcptr decode_wrfunc_num( uint8_t func_num ) {
switch( func_num ) {
case DISCRETE_EXP0_PRGROM_WR:
return discrete_exp0_prgrom_wr;
case NES_CPU_WR:
return nes_cpu_wr;
case NES_PPU_WR:
return nes_ppu_wr;
default:
return (void*)~SUCCESS;
}
}
/* Desc:Function takes an opcode which was transmitted via USB
* then decodes it to call designated function.
* shared_dict_operation.h is used in both host and fw to ensure opcodes/names align
* Pre: Macros must be defined in firmware pinport.h
* opcode must be defined in shared_dict_operation.h
* Post:function call complete.
* Rtn: SUCCESS if opcode found, ERR_UNKN_OPER_OPCODE_NRV if opcode not present.
*/
uint8_t oper_opcode_no_return( uint8_t opcode, uint8_t operMSB, uint8_t operLSB, uint8_t miscdata )
{
switch (opcode) {
case SET_OPERATION:
oper_info->operation = operLSB;
break;
case COPY_BUFF0_TO_ELEMENTS:
//copy over buff0 to oper_info elements
//this should work for all byte variables, but not functions
copy_buff0_to_data( (uint8_t *)oper_info, OPER_DATA_NUM_BYTE_ELEMENTS );
break;
case COPY_ELEMENTS_TO_BUFF0:
copy_data_to_buff0( (uint8_t *)oper_info, OPER_DATA_NUM_BYTE_ELEMENTS );
break;
case SET_OPER_FUNC:
//oper_info->oper_func = decode_opfunc_num( operLSB );
break;
case SET_RD_FUNC:
oper_info->rd_func = decode_rdfunc_num( operLSB );
break;
case SET_WR_MEM_FUNC:
oper_info->wr_mem_func = decode_wrfunc_num( operLSB );
break;
case SET_WR_MAP_FUNC:
oper_info->wr_map_func = decode_wrfunc_num( operLSB );
break;
default:
//opcode doesn't exist
return ERR_UNKN_OPER_OPCODE_NRV;
}
return SUCCESS;
}
/* Desc:Function takes an opcode which was transmitted via USB
* then decodes it to call designated function.
* shared_dict_operation.h is used in both host and fw to ensure opcodes/names align
* Pre: Macros must be defined in firmware pinport.h
* opcode must be defined in shared_dict_operation.h
* Post:function call complete.
* Rtn: SUCCESS if opcode found, ERR_UNKN_OPER_OPCODE_RV if opcode not present.
*/
uint8_t oper_opcode_return( uint8_t opcode, uint8_t operMSB, uint8_t operLSB, uint8_t miscdata,
uint8_t *rvalue, uint8_t *rlength )
{
switch (opcode) {
case GET_OPERATION:
*rvalue = oper_info->operation;
*rlength += 1;
break;
default:
//opcode doesn't exist
return ERR_UNKN_OPER_OPCODE_RV;
}
return SUCCESS;
}
void set_operation( uint8_t op )
{
oper_info->operation = op;
}
uint8_t get_operation( void )
{
return oper_info->operation;
}

View File

@ -0,0 +1,26 @@
#ifndef _operation_h
#define _operation_h
#include <avr/io.h>
#include "usbdrv.h"
#include "types.h"
#include "logic.h"
#include "usb.h"
#include "flash.h"
#include "dump.h"
#include "shared_dictionaries.h"
#include "shared_enums.h"
#include "shared_errors.h"
uint8_t * operation_usb_call( setup_packet *spacket, uint8_t *rv, uint8_t *rlen);
read_funcptr decode_rdfunc_num( uint8_t func_num );
write_funcptr decode_wrfunc_num( uint8_t func_num );
uint8_t oper_opcode_no_return( uint8_t opcode, uint8_t operMSB, uint8_t operLSB, uint8_t miscdata );
uint8_t oper_opcode_return( uint8_t opcode, uint8_t operMSB, uint8_t operLSB, uint8_t miscdata,
uint8_t *rvalue, uint8_t *rlength );
void set_operation( uint8_t op );
uint8_t get_operation( void );
#endif

View File

@ -11,6 +11,10 @@ typedef struct setup_packet{
uint16_t wLength;
}setup_packet;
//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 );
//~16 bytes per buffer...
typedef struct buffer {
uint8_t *data; //pointer to base buffer's allocated sram
@ -37,8 +41,36 @@ 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 );
typedef struct operation_info {
uint8_t operation; //overall type of operation being performed
uint8_t addrH_dmask; //mask page_num lower byte to get directly addressable A15:A8 bits
uint8_t pg2bank_shright; //shift page_num to right this many bits to get cur bank value
uint8_t valid_addr_msb; //most significant bit that must be valid for operation (ie A14 SST) //unlock sequence SST $5555 0xAA
uint8_t unlock1_bank; //unlock sequence #1 bank number for mapper reg
uint8_t unlock1_AH; //unlock sequence #1 A15:A8
uint8_t unlock1_AL; //unlock sequence #1 A7:A0
uint8_t unlock1_data; //unlock sequence #1 D7:D0
//unlock sequence SST $2AAA 0x55
uint8_t unlock2_bank; //unlock sequence #1 bank number for mapper reg
uint8_t unlock2_AH; //unlock sequence #2 A15:A8
uint8_t unlock2_AL; //unlock sequence #2 A7:A0
uint8_t unlock2_data; //unlock sequence #2 D7:D0
//command SST byte write $5555 0xA0, SST sector/chip erase $5555 0x80
uint8_t command_bank; //flash command bank (ie bank to write byte write, sector erase cmd)
uint8_t command_AH; //flash command A15:A8
uint8_t command_AL; //flash command A7:A0
uint8_t command1_data; //flash command D7:D0 command 1 data (ie SST sect erase 0x80)
uint8_t command2_data; //flash command D7:D0 command 2 data (ie SST sect erase 0x30)
//actual byte operation (ie Byte address bank and addr)
uint8_t oper_bank; //current bank value for actual operation to be done (ie write byte)
uint8_t oper_AH; //operation A15:A8 (ie actual byte write address)
//uint8_t oper_AL; //operation A7:A0
//uint8_t oper_data; //operation D7:D0 (ie actual byte data)
//TODO oper_funcptr op_func; //function used for overall operation
read_funcptr rd_func; //function used to read memory
write_funcptr wr_mem_func; //function used to write to memory
write_funcptr wr_map_func; //function used to write to mapper
}operation_info;
#endif

View File

@ -182,6 +182,11 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) {
rv[RV_DATA0_IDX+1] = cur_usb_load_buff->last_idx;
rlen = 3;
break; //end of USB
case DICT_OPER:
//just give operation.c the setup packet and let it figure things out for itself
usbMsgPtr = (usbMsgPtr_t)operation_usb_call( spacket, rv, &rlen );
break; //end of OPER
default:
//request (aka dictionary) is unknown

View File

@ -132,16 +132,16 @@ int set_map_n_mapvar( USBtransfer *transfer, int buff_num, int mapper, int map_v
( (mapper<<8) | (map_var) ), buff_num, USB_IN, NULL, 1);
}
/* Desc:Set buffer manager operation
* Pre: buffers are allocated and elements set ready to start operation
* Post:operation starts on device
* Rtn: SUCCESS if no errors
*/
int set_buff_operation( USBtransfer *transfer, int operation )
{
return dictionary_call( transfer, DICT_BUFFER, SET_BUFFER_OPERATION, operation,
NILL, USB_IN, NULL, 1);
}
///* Desc:Set buffer manager operation
// * Pre: buffers are allocated and elements set ready to start operation
// * Post:operation starts on device
// * Rtn: SUCCESS if no errors
// */
//int set_buff_operation( USBtransfer *transfer, int operation )
//{
// return dictionary_call( transfer, DICT_BUFFER, SET_BUFFER_OPERATION, operation,
// NILL, USB_IN, NULL, 1);
//}
/* Desc:Payload IN transfer
* Pre: buffers are allocated operation started
@ -193,15 +193,15 @@ int get_buff_elements( USBtransfer *transfer, int buff_num )
return SUCCESS;
}
/* Desc:Get buffer opertationt
* Pre:
* Post:
* Rtn: SUCCESS if no errors
*/
int get_buff_operation( USBtransfer *transfer )
{
printf("operation:");
dictionary_call_debug( transfer, DICT_BUFFER, GET_BUFF_OPERATION, NILL, NILL,
USB_IN, NULL, RV_DATA0_IDX+1);
return SUCCESS;
}
///* Desc:Get buffer opertationt
// * Pre:
// * Post:
// * Rtn: SUCCESS if no errors
// */
//int get_buff_operation( USBtransfer *transfer )
//{
// printf("operation:");
// dictionary_call_debug( transfer, DICT_BUFFER, GET_BUFF_OPERATION, NILL, NILL,
// USB_IN, NULL, RV_DATA0_IDX+1);
// return SUCCESS;
//}

View File

@ -25,10 +25,8 @@ int reset_buffers( USBtransfer *transfer );
int allocate_buffers( USBtransfer *transfer, int num_buffers, int buff_size );
int set_mem_n_part( USBtransfer *transfer, int buff_num, int mem_type, int part_num );
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 );
#endif

View File

@ -39,7 +39,7 @@ typedef struct cartridge{
memory *sec_rom; //secondary rom if used (CHR-ROM for NES)
memory *save_mem; //save data memory
memory *aux_mem; //additional memory
memory *logic_mem; //programmable logic
memory *logic_mem; //programmable logic
} cartridge;

View File

@ -148,6 +148,13 @@ int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_
// transfer->wLength = length;
break;
case DICT_OPER: debug("dict: OPER");
// transfer->wLength = length;
if (buffer != NULL) {
transfer->data = (unsigned char *)buffer;
}
break; //end of BUFF
default:
//request (aka dictionary) is unknown
sentinel("unknown DICT err:%d",ERR_UNKN_DICTIONARY);

View File

@ -65,15 +65,15 @@ int dump_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart )
USB_IN, NULL, RV_DATA0_IDX+1);
//debugging print out buffer elements
//get_buff_operation( transfer );
//get_operation( transfer );
//get_buff_elements( transfer, buff0 );
//get_buff_elements( transfer, buff1 );
debug("\n\nsetting operation STARTDUMP");
//inform buffer manager to start dumping operation now that buffers are initialized
check(! set_buff_operation( transfer, STARTDUMP ), "Unable to set buffer operation");
check(! set_operation( transfer, STARTDUMP ), "Unable to set buffer operation");
// get_buff_operation( transfer );
// get_operation( transfer );
// get_buff_elements( transfer, buff0 );
// get_buff_elements( transfer, buff1 );
//manager updates buffer status' so they'll start dumping
@ -86,7 +86,7 @@ int dump_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart )
// check(! append_to_file( rom, data, buff_size ), "Error with file append");
//
// debug("first payload done");
// get_buff_operation( transfer );
// get_operation( transfer );
// get_buff_elements( transfer, buff0 );
// get_buff_elements( transfer, buff1 );
//
@ -94,7 +94,7 @@ int dump_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart )
// check(! payload_in( transfer, data, buff_size ), "Error with payload IN");
// check(! append_to_file( rom, data, buff_size ), "Error with file append");
//
// get_buff_operation( transfer );
// get_operation( transfer );
// get_buff_elements( transfer, buff0 );
// get_buff_elements( transfer, buff1 );
clock_t tstart, tstop;
@ -130,7 +130,7 @@ int dump_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart )
check(! set_map_n_mapvar( transfer, buff1, NROM, NILL ), "Unable to set mapper and map_var");
debug("\n\nsetting operation STARTDUMP");
check(! set_buff_operation( transfer, STARTDUMP ), "Unable to set buffer operation");
check(! set_operation( transfer, STARTDUMP ), "Unable to set buffer operation");
for( i=0; i<(8*KByte/buff_size); i++) {
//payload transfer in and append to file

View File

@ -27,6 +27,7 @@
#include "cartridge.h"
#include "file.h"
#include "buffer.h"
#include "operation.h"
int dump_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart );

View File

@ -75,15 +75,19 @@ int flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart )
//TODO when start implementing other mappers
//debugging print out buffer elements
get_buff_operation( transfer );
get_operation( transfer );
get_buff_elements( transfer, buff0 );
get_buff_elements( transfer, buff1 );
//load operation elements into buff0 and then copy buff0 to oper_info
load_oper_info_elements( transfer, cart );
get_oper_info_elements( transfer );
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");
check(! set_operation( transfer, STARTFLASH ), "Unable to set buffer operation");
// get_buff_operation( transfer );
// get_operation( transfer );
// get_buff_elements( transfer, buff0 );
// get_buff_elements( transfer, buff1 );
// //manager updates buffer status' so they'll start dumping
@ -95,12 +99,12 @@ int flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart )
// 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_operation( transfer );
// get_buff_elements( transfer, buff0 );
// get_buff_elements( transfer, buff1 );
//
// debug("first payload done");
//// get_buff_operation( transfer );
//// get_operation( transfer );
//// get_buff_elements( transfer, buff0 );
//// get_buff_elements( transfer, buff1 );
////
@ -108,7 +112,7 @@ int flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart )
// 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_operation( transfer );
// get_buff_elements( transfer, buff0 );
// get_buff_elements( transfer, buff1 );
@ -151,7 +155,7 @@ int flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart )
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");
check(! set_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");

View File

@ -27,6 +27,7 @@
#include "cartridge.h"
#include "file.h"
#include "buffer.h"
#include "operation.h"
int flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart );

129
host/source/operation.c Normal file
View File

@ -0,0 +1,129 @@
#include "operation.h"
/* Desc:Set all oper_info elements based on cartridge
* Pre: buff0 must be initialized
* Post:oper_info elements loaded
* Rtn: SUCCESS if no errors
*/
int load_oper_info_elements( USBtransfer *transfer, cartridge *cart, int mem )
{
uint8_t rv[RETURN_BUFF_SIZE];
uint8_t buff_num = 0; //buffer used to load elements according to shared_dict_operation.h
uint8_t oper_info[OPER_DATA_NUM_BYTE_ELEMENTS];
int i;
//first make sure buff0 is big enough
dictionary_call_debug( transfer, DICT_BUFFER, GET_PRI_ELEMENTS, NILL, buff_num,
USB_IN, rv, RETURN_BUFF_SIZE);
check( rv[BUFF_LASTIDX] >= OPER_DATA_NUM_BYTE_ELEMENTS,
"buff0 not large enough to load oper_info. Only %d available, need %d",
rv[BUFF_LASTIDX], OPER_DATA_NUM_BYTE_ELEMENTS );
//fill array with oper_info elements then payload to buff0
//overall type of operation being performed
oper_info[OPERATION] = PREPARING,
//mask page_num lower byte to get directly addressable A15:A8 bits
oper_info[ADDRH_DMASK] = MSK_32KB,
//shift page_num to right this many bits to get cur bank value
oper_info[PG2BANK_SHRIGHT] = PG2B_32KB,
//most significant bit that must be valid for operation (ie A14 SST)
oper_info[VALID_ADDR_MSB] = 14,
//unlock sequence SST $5555 0xAA
//unlock sequence #1 bank number for mapper reg
oper_info[UNLOCK1_BANK] = 0,
//unlock sequence #1 A15:A8
oper_info[UNLOCK1_AH] = 0x55,
//unlock sequence #1 A7:A0
oper_info[UNLOCK1_AL] = 0x55,
//unlock sequence #1 D7:D0
oper_info[UNLOCK1_DATA] = 0xAA,
////unlock sequence SST $2AAA 0x55
//unlock sequence #1 bank number for mapper reg
oper_info[UNLOCK2_BANK] = 0,
//unlock sequence #2 A15:A8
oper_info[UNLOCK2_AH] = 0x2A,
//unlock sequence #2 A7:A0
oper_info[UNLOCK2_AL] = 0xAA,
//unlock sequence #2 D7:D0
oper_info[UNLOCK2_DATA] = 0x55,
//command SST byte write $5555 0xA0, SST sector/chip erase $5555 0x80
//flash command bank (ie bank to write byte write, sector erase cmd)
oper_info[COMMAND_BANK] = 0,
//flash command A15:A8
oper_info[COMMAND_AH] = 0x55,
//flash command A7:A0
oper_info[COMMAND_AL] = 0x55,
///flash command D7:D0 command 1 data (ie SST sect erase 0x80)
oper_info[COMMAND1_DATA]= 0xA0,
//flash command D7:D0 command 2 data (ie SST sect erase 0x30)
oper_info[COMMAND2_DATA]= 0,
//actual byte operation (ie Byte address bank and addr)
//current bank value for actual operation to be done (ie write byte)
oper_info[OPER_BANK] = 0,
//operation A15:A8 (ie actual byte write address)
oper_info[OPER_AH] = 0,
//load byte element data into buff0
dictionary_call( transfer, DICT_BUFFER, BUFF_PAYLOADN,
NILL, buff_num, USB_OUT,
oper_info, OPER_DATA_NUM_BYTE_ELEMENTS);
//now that elements are in buff0 instruct them to be copied over
dictionary_call_debug( transfer, DICT_OPER, COPY_BUFF0_TO_ELEMENTS,
NILL, NILL, USB_IN, NULL, RV_ERR_IDX+1);
error:
return ~SUCCESS;
}
/* Desc:Get all oper_info elements
* Pre: buff0 must be initialized
* Post:
* Rtn: SUCCESS if no errors
*/
int get_oper_info_elements( USBtransfer *transfer )
{
uint8_t oper_info[OPER_DATA_NUM_BYTE_ELEMENTS];
uint8_t buff_num = 0; //buffer used to load elements according to shared_dict_operation.h
int i;
//now that buff0 is filled with junk copy elements over to buff0
dictionary_call( transfer, DICT_OPER, COPY_ELEMENTS_TO_BUFF0,
NILL, NILL, USB_IN, NULL, RV_ERR_IDX+1);
//now read back buff0
dictionary_call( transfer, DICT_BUFFER, BUFF_PAYLOADN,
NILL, buff_num, USB_IN,
oper_info, OPER_DATA_NUM_BYTE_ELEMENTS);
printf("oper_info:\n");
for( i=0; i<OPER_DATA_NUM_BYTE_ELEMENTS; i++) {
printf("%d: %x \t", i, oper_info[i]) ;
}
printf("\n");
return SUCCESS;
}
/* Desc:Set operation
* Pre: buffers are allocated and oper_info elements set ready to start operation
* Post:operation starts on device
* Rtn: SUCCESS if no errors
*/
int set_operation( USBtransfer *transfer, int operation )
{
return dictionary_call( transfer, DICT_OPER, SET_OPERATION, operation,
NILL, USB_IN, NULL, 1);
}
/* Desc:Get opertation
* Pre:
* Post:
* Rtn: SUCCESS if no errors
*/
int get_operation( USBtransfer *transfer )
{
printf("operation:");
dictionary_call( transfer, DICT_OPER, GET_OPERATION, NILL, NILL,
USB_IN, NULL, RV_DATA0_IDX+1);
return SUCCESS;
}

31
host/source/operation.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef _operation_h
#define _operation_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"
#include "cartridge.h"
#include "pindef.h"
int load_oper_info_elements( USBtransfer *transfer, cartridge *cart );
int get_oper_info_elements( USBtransfer *transfer );
int set_operation( USBtransfer *transfer, int operation );
int get_operation( USBtransfer *transfer );
#endif

View File

@ -89,7 +89,8 @@
//set buffer manager operation value
//lower operand byte sets value
#define SET_BUFFER_OPERATION 0x01
//#define SET_BUFFER_OPERATION 0x01
//moved to shared_dict_operation.h
@ -135,9 +136,7 @@
//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
//designate what buffer to fill/read with miscdata byte
#define BUFF_PAYLOADN 0x41
@ -149,14 +148,22 @@
//return buffer elements
//misc/data: buffer number
#define GET_PRI_ELEMENTS 0x50
//rv0: success/error code
//rv1: last_idx
#define BUFF_LASTIDX 1
//rv2: status
#define BUFF_STATUS 2
//rv3: cur_byte
#define BUFF_CURBYTE 3
//rv4: reload
#define BUFF_RELOAD 4
//rv5: id
#define BUFF_ID 5
//rv76: page_num
#define GET_PRI_ELEMENTS 0x50
#define BUFF_PGNUM_MSB 7
#define BUFF_PGNUM_LSB 6
//return buffer elements
//misc/data: buffer number
@ -186,7 +193,8 @@
#define RAW_BANK_STATUS 0x60
//retrieve buffer manager current operation variable
#define GET_BUFF_OPERATION 0x61
//#define GET_BUFF_OPERATION 0x61
//moved to shared_dict_operation.h

View File

@ -0,0 +1,123 @@
#ifndef _shared_dict_operation_h
#define _shared_dict_operation_h
//define dictionary's reference number in the shared_dictionaries.h file
//then include this dictionary file in shared_dictionaries.h
//The dictionary number is literally used as usb transfer request field
//the opcodes and operands in this dictionary are fed directly into usb setup packet's wValue wIndex fields
//=============================================================================================
//=============================================================================================
// OPERATION DICTIONARY
//
// opcodes contained in this dictionary must be implemented in firmware/source/operation.c
//
//=============================================================================================
//=============================================================================================
//avr definition:
//typedef struct operation_info {
enum operation_elem_nums { //Each index is numbered by it's name
// uint8_t operation; //overall type of operation being performed
OPERATION = 0,
// uint8_t addrH_dmask; //mask page_num lower byte to get directly addressable A15:A8 bits
ADDRH_DMASK = 1,
// uint8_t pg2bank_shright; //shift page_num to right this many bits to get cur bank value
PG2BANK_SHRIGHT = 2,
// uint8_t valid_addr_msb; //most significant bit that must be valid for operation (ie A14 SST)
VALID_ADDR_MSB = 3,
//unlock sequence SST $5555 0xAA
// uint8_t unlock1_bank; //unlock sequence #1 bank number for mapper reg
UNLOCK1_BANK = 4,
// uint8_t unlock1_AH; //unlock sequence #1 A15:A8
UNLOCK1_AH = 5,
// uint8_t unlock1_AL; //unlock sequence #1 A7:A0
UNLOCK1_AL = 6,
// uint8_t unlock1_data; //unlock sequence #1 D7:D0
UNLOCK1_DATA = 7,
////unlock sequence SST $2AAA 0x55
// uint8_t unlock2_bank; //unlock sequence #1 bank number for mapper reg
UNLOCK2_BANK = 8,
// uint8_t unlock2_AH; //unlock sequence #2 A15:A8
UNLOCK2_AH = 9,
// uint8_t unlock2_AL; //unlock sequence #2 A7:A0
UNLOCK2_AL = 10,
// uint8_t unlock2_data; //unlock sequence #2 D7:D0
UNLOCK2_DATA = 11,
////command SST byte write $5555 0xA0, SST sector/chip erase $5555 0x80
// uint8_t command_bank; //flash command bank (ie bank to write byte write, sector erase cmd)
COMMAND_BANK = 12,
// uint8_t command_AH; //flash command A15:A8
COMMAND_AH = 13,
// uint8_t command_AL; //flash command A7:A0
COMMAND_AL = 14,
// uint8_t command1_data; //flash command D7:D0 command 1 data (ie SST sect erase 0x80)
COMMAND1_DATA = 15,
// uint8_t command2_data; //flash command D7:D0 command 2 data (ie SST sect erase 0x30)
COMMAND2_DATA = 16,
////actual byte operation (ie Byte address bank and addr)
// uint8_t oper_bank; //current bank value for actual operation to be done (ie write byte)
OPER_BANK = 17,
// uint8_t oper_AH; //operation A15:A8 (ie actual byte write address)
OPER_AH = 18,
// //uint8_t oper_AL; //operation A7:A0
// //uint8_t oper_data; //operation D7:D0 (ie actual byte data)
//number of byte elements in operation_data
//since first element is zero, this will equal num byte (non-pointer) elements
OPER_DATA_NUM_BYTE_ELEMENTS
//Function pointers get translated from function number to pointer within firmware
// oper_funcptr op_func; //function used for overall operation
// read_funcptr rd_func; //function used to read memory
// write_funcptr wr_mem_func; //function used to write to memory
// write_funcptr wr_map_func; //function used to write to mapper
};
//}operation_data;
//=============================================================================================
// 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:
//
//------------------------------------
#define OPER_OPCODE_NRV_MIN 0x00
#define OPER_OPCODE_NRV_MAX 0x3F
//------------------------------------
#define OPER_OPCODE_RV_MIN 0x40
#define OPER_OPCODE_RV_MAX 0x7F
//------------------------------------
//
//=============================================================================================
//=============================================================================================
//set buffer manager operation value
//lower operand byte sets value
#define SET_OPERATION 0x00
//set data currently stored in buff0 to operation_info elements
//This sets all byte elements, but not function pointers
#define COPY_BUFF0_TO_ELEMENTS 0x01
//copy oper info elements over to buff0
//this copies over all byte elements, but not function pointers
#define COPY_ELEMENTS_TO_BUFF0 0x02
#define SET_OPER_FUNC 0x03
#define SET_RD_FUNC 0x04
#define SET_WR_MEM_FUNC 0x05
#define SET_WR_MAP_FUNC 0x06
//retrieve buffer manager current operation variable
#define GET_OPERATION 0x40
#endif

View File

@ -129,4 +129,12 @@
//=============================================================================================
//=============================================================================================
//=============================================================================================
//=============================================================================================
#define DICT_OPER 7
#include "shared_dict_operation.h"
//dictionary used to initialize and control operation_info variables
//=============================================================================================
//=============================================================================================
#endif

View File

@ -66,7 +66,6 @@ enum operations {
//SRAM manf/prod ID
#define SRAM 0xAA
//MASK ROM read only
#define MASKROM 0xDD
@ -78,10 +77,11 @@ enum buff_mem_type {
SNESRAM
};
//buffer status values
//buffer/operation status values
#define EMPTY 0x00
#define RESET 0x01
#define PROBLEM 0x10
#define PREPARING 0x20
#define USB_UNLOADING 0x80
#define USB_LOADING 0x90
#define USB_FULL 0x98
@ -97,4 +97,42 @@ enum buff_mem_type {
#define STOPPED 0xFE
#define UNALLOC 0xFF
enum addr_high_direct_mask {
//actual value is part mapper dependent and part flash dependent
//mapper controlled address bits dictate where split is
//32KB banking A14-0 NES ctl, A15+ mapper ctl "bank" NROM, BNROM, ANROM
//addrH_dmask = 0b0111 1111 directly addressable addrH bits
MSK_32KB = 0x7F,
//16KB banking A13-0 NES ctl, A14+ mapper ctl "bank" UxROM, MMC1
//addrH_dmask = 0b0011 1111
MSK_16KB = 0x3F,
// 8KB banking A12-0 NES ctl, A13+ mapper ctl "bank" MMC3, FME7, CHR discrete banking
//addrH_dmask = 0b0001 1111
MSK_8KB = 0x1F,
// 4KB banking A11-0 NES ctl, A12+ mapper ctl "bank" ezNSF MMC1 CHR
//addrH_dmask = 0b0000 1111
MSK_4KB = 0x0F,
// 2KB banking A10-0 NES ctl, A11+ mapper ctl "bank" MMC3 CHR
//addrH_dmask = 0b0000 0111
MSK_2KB = 0x07,
// 1KB banking A9-0 NES ctl, A10+ mapper ctl "bank" FME7 CHR
//addrH_dmask = 0b0000 0011
MSK_1KB = 0x03
};
enum page2bankshiftright {
//A15->A8 = 7 shifts (equal to number of set bits in addrH_mask
PG2B_32KB = 7,
//A14->A8 = 6 shifts
PG2B_16KB = 6,
//A13->A8 = 5 shifts
PG2B_8KB = 5,
//A12->A8 = 4 shifts
PG2B_4KB = 4,
//A11->A8 = 3 shifts
PG2B_2KB = 3,
//A10->A8 = 2 shifts
PG2B_1KB = 2
};
#endif

View File

@ -14,6 +14,7 @@
#define ERR_BAD_SNES_OP_MINMAX 132
#define ERR_BAD_BUFF_OP_MINMAX 133
#define ERR_BUFN_DOES_NOT_EXIST 134
#define ERR_BAD_OPER_OP_MINMAX 135
#define ERR_UNKN_PP_OPCODE_ONLY 140
@ -47,6 +48,9 @@
#define ERR_OUT_CURLDBUF_STATUS 200
#define ERR_OUT_CURLDBUF_TO_SMALL 201
#define ERR_UNKN_OPER_OPCODE_NRV 210
#define ERR_UNKN_OPER_OPCODE_RV 211
//max error number 255
#endif