166 lines
4.7 KiB
C
166 lines
4.7 KiB
C
#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 dict, uint8_t func_num )
|
|
{
|
|
|
|
if ( dict == NES ) {
|
|
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;
|
|
}
|
|
} else {
|
|
//dictionary not supported
|
|
return (void*)~SUCCESS;
|
|
}
|
|
}
|
|
|
|
write_funcptr decode_wrfunc_num(uint8_t dict, uint8_t func_num )
|
|
{
|
|
if ( dict == NES ) {
|
|
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;
|
|
}
|
|
}
|
|
} else {
|
|
//dictionary not supported
|
|
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;
|
|
//operMSB contains dictionary, operLSB contains function number
|
|
//decode that into proper function pointer
|
|
case SET_OPER_FUNC:
|
|
//oper_info->oper_func = decode_opfunc_num( operLSB );
|
|
break;
|
|
case SET_RD_FUNC:
|
|
oper_info->rd_func = decode_rdfunc_num( operMSB, operLSB );
|
|
break;
|
|
case SET_WR_MEM_FUNC:
|
|
oper_info->wr_mem_func = decode_wrfunc_num( operMSB, operLSB );
|
|
break;
|
|
case SET_WR_MAP_FUNC:
|
|
oper_info->wr_map_func = decode_wrfunc_num( operMSB, 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;
|
|
}
|