diff --git a/firmware/source/buffer.c b/firmware/source/buffer.c index 778e1ae..ea74d78 100644 --- a/firmware/source/buffer.c +++ b/firmware/source/buffer.c @@ -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; istatus = 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 diff --git a/firmware/source/buffer.h b/firmware/source/buffer.h index f58dfd2..47920e9 100644 --- a/firmware/source/buffer.h +++ b/firmware/source/buffer.h @@ -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 ); diff --git a/firmware/source/flash.c b/firmware/source/flash.c index c7364b4..05c906f 100644 --- a/firmware/source/flash.c +++ b/firmware/source/flash.c @@ -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 ); diff --git a/firmware/source/operation.c b/firmware/source/operation.c new file mode 100644 index 0000000..27cdc70 --- /dev/null +++ b/firmware/source/operation.c @@ -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; +} diff --git a/firmware/source/operation.h b/firmware/source/operation.h new file mode 100644 index 0000000..93bbad2 --- /dev/null +++ b/firmware/source/operation.h @@ -0,0 +1,26 @@ +#ifndef _operation_h +#define _operation_h + +#include +#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 diff --git a/firmware/source/types.h b/firmware/source/types.h index 08b9d64..e50f33f 100644 --- a/firmware/source/types.h +++ b/firmware/source/types.h @@ -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 diff --git a/firmware/source/usb.c b/firmware/source/usb.c index 10a3d6c..43423f1 100644 --- a/firmware/source/usb.c +++ b/firmware/source/usb.c @@ -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 diff --git a/host/source/buffer.c b/host/source/buffer.c index e20c4b5..e977fae 100644 --- a/host/source/buffer.c +++ b/host/source/buffer.c @@ -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; +//} diff --git a/host/source/buffer.h b/host/source/buffer.h index a7b51c7..c58b5bc 100644 --- a/host/source/buffer.h +++ b/host/source/buffer.h @@ -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 diff --git a/host/source/cartridge.h b/host/source/cartridge.h index 0d40e45..20c7df1 100644 --- a/host/source/cartridge.h +++ b/host/source/cartridge.h @@ -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; diff --git a/host/source/dictionary.c b/host/source/dictionary.c index e7c3d43..fd62939 100644 --- a/host/source/dictionary.c +++ b/host/source/dictionary.c @@ -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); diff --git a/host/source/dump.c b/host/source/dump.c index d8a3426..1956b4c 100644 --- a/host/source/dump.c +++ b/host/source/dump.c @@ -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 diff --git a/host/source/dump.h b/host/source/dump.h index 17f2a93..069b839 100644 --- a/host/source/dump.h +++ b/host/source/dump.h @@ -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 ); diff --git a/host/source/flash.c b/host/source/flash.c index 2a23bf1..806c3c5 100644 --- a/host/source/flash.c +++ b/host/source/flash.c @@ -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"); diff --git a/host/source/flash.h b/host/source/flash.h index 2a141d0..8e1daf1 100644 --- a/host/source/flash.h +++ b/host/source/flash.h @@ -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 ); diff --git a/host/source/operation.c b/host/source/operation.c new file mode 100644 index 0000000..d488d5e --- /dev/null +++ b/host/source/operation.c @@ -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 +#include +#include +#include + +//include prior to other file includes +//that way DEBUG can be turned on/off for this file alone +//uncomment to DEBUG this file alone +#define DEBUG +//"make debug" to get DEBUG msgs on entire program +#include "dbg.h" + +#include "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 diff --git a/shared/shared_dict_buffer.h b/shared/shared_dict_buffer.h index 90510a8..f92d19a 100644 --- a/shared/shared_dict_buffer.h +++ b/shared/shared_dict_buffer.h @@ -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 diff --git a/shared/shared_dict_operation.h b/shared/shared_dict_operation.h new file mode 100644 index 0000000..55f8e23 --- /dev/null +++ b/shared/shared_dict_operation.h @@ -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 diff --git a/shared/shared_dictionaries.h b/shared/shared_dictionaries.h index 10b6533..509e09e 100644 --- a/shared/shared_dictionaries.h +++ b/shared/shared_dictionaries.h @@ -129,4 +129,12 @@ //============================================================================================= //============================================================================================= + +//============================================================================================= +//============================================================================================= +#define DICT_OPER 7 +#include "shared_dict_operation.h" +//dictionary used to initialize and control operation_info variables +//============================================================================================= +//============================================================================================= #endif diff --git a/shared/shared_enums.h b/shared/shared_enums.h index 970bb29..626f147 100644 --- a/shared/shared_enums.h +++ b/shared/shared_enums.h @@ -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 diff --git a/shared/shared_errors.h b/shared/shared_errors.h index 14f5a01..8213c00 100644 --- a/shared/shared_errors.h +++ b/shared/shared_errors.h @@ -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