INL-retro-progdump/firmware/source/old/operation.c

165 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 == 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 == 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;
}