INL-retro-progdump/host/source/dictionary.c

188 lines
5.4 KiB
C

#include "dictionary.h"
/* Make dictionary calls simpler
* provide USBtransfer pointer with handle set to retro programmer
* provide dictionary as defined in shared_dictionaries.h (request)
* provide opcode from the dictionary (wValueLSB)
* provide 16bit addr used for usb transfer index (optional, can also send 8bits applied to wIndexLSB)
* provide miscdata optional to be used for wValueMSB
* provide data buffer pointer and length
*
* makes call to usb_transfer after determining:
* endpoint direction
* data length
*
* debug print of call and return values
*/
//default call dictionary without print option
int dictionary_call( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr,
uint8_t miscdata, uint8_t endpoint, uint8_t *buffer, uint16_t length)
{
return dictionary_call_print_option( FALSE, transfer, dictionary, opcode, addr, miscdata, endpoint, buffer, length);
}
//debug call dictionary without print option
int dictionary_call_debug( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr,
uint8_t miscdata, uint8_t endpoint, uint8_t *buffer, uint16_t length)
{
return dictionary_call_print_option( ~FALSE, transfer, dictionary, opcode, addr, miscdata,
endpoint, buffer, length);
}
int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_t dictionary, uint8_t opcode,
uint16_t addr, uint8_t miscdata, uint8_t endpoint, uint8_t *buffer, uint16_t length)
{
transfer->request = dictionary;
transfer->wValueMSB = miscdata;
transfer->wValueLSB = opcode;
transfer->wIndexMSB = (addr>>8);
transfer->wIndexLSB = addr;
//default IN for now reading back error codes from short commands
transfer->endpoint = endpoint;
transfer->wLength = length;
//default length of zero
// transfer->wLength = 0;
//return data buffer big enough for one data packet
uint8_t rbuf[8];
if ( buffer == NULL ) {
rbuf[0] = 0xee;
rbuf[1] = 0xee;
rbuf[2] = 0xee;
rbuf[3] = 0xee;
rbuf[4] = 0xee;
rbuf[5] = 0xee;
rbuf[6] = 0xee;
rbuf[7] = 0xee;
transfer->data = rbuf;
} else {
transfer->data = buffer;
}
if (print_debug) {
printf("\ndictionary call dict:%d opcode:%dd/%xh addr:%x data:%x\n",
dictionary, opcode, opcode, addr, miscdata);
}
switch (dictionary) {
case DICT_PINPORT: debug("dict: PINPORT");
//transfer->wLength = 1;
switch (opcode) {
case PP_OPCODE_ONLY_MIN ... PP_OPCODE_ONLY_MAX:
debug("PP_OPCODE_ONLY");
break;
case PP_OPCODE_8BOP_MIN ... PP_OPCODE_8BOP_MAX:
debug("PP_OPCODE_8BOP");
break;
case PP_OPCODE_16BOP_MIN ... PP_OPCODE_16BOP_MAX:
debug("PP_OPCODE_16BOP");
break;
case PP_OPCODE_24BOP_MIN ... PP_OPCODE_24BOP_MAX:
debug("PP_OPCODE_24BOP");
break;
case PP_OPCODE_8BRV_MIN ... PP_OPCODE_8BRV_MAX:
debug("PP_OPCODE_8BRV");
// transfer->wLength = 2;
break;
default: //pinport opcode min/max definition error
sentinel("bad PP opcode min/max err:%d",ERR_BAD_PP_OP_MINMAX);
}
break; //end of PINPORT
case DICT_IO: debug("dict: IO");
// transfer->wLength = 1;
switch (opcode) {
case IO_OPCODE_ONLY_MIN ... IO_OPCODE_ONLY_MAX:
debug("IO_OPCODE_ONLY");
break;
case IO_OPCODE_RTN_MIN ... IO_OPCODE_RTN_MAX:
debug("IO_OPCODE_RTN");
// transfer->wLength = 8;
break;
default: //io opcode min/max definition error
sentinel("bad IO opcode min/max err:%d",ERR_BAD_IO_OP_MINMAX);
}
break; //end of IO
case DICT_NES: debug("dict: NES");
// transfer->wLength = 1;
switch (opcode) {
case NES_OPCODE_24BOP_MIN ... NES_OPCODE_24BOP_MAX:
debug("NES_OPCODE_24BOP");
break;
case NES_OPCODE_16BOP_8BRV_MIN ... NES_OPCODE_16BOP_8BRV_MAX:
debug("NES_OPCODE_16BOP_8BRV");
// transfer->wLength = 2;
break;
default: //nes opcode min/max definition error
sentinel("bad NES opcode min/max err:%d",ERR_BAD_NES_OP_MINMAX);
}
break; //end of NES
case DICT_SNES: debug("dict: SNES");
// transfer->wLength = 1;
switch (opcode) {
case SNES_OPCODE_24BOP_MIN ... SNES_OPCODE_24BOP_MAX:
debug("SNES_OPCODE_24BOP");
break;
case SNES_OPCODE_24BOP_8BRV_MIN ... SNES_OPCODE_24BOP_8BRV_MAX:
debug("SNES_OPCODE_24BOP_8BRV");
// transfer->wLength = 2;
break;
default: //snes opcode min/max definition error
sentinel("bad SNES opcode min/max err:%d",ERR_BAD_SNES_OP_MINMAX);
}
break; //end of SNES
case DICT_BUFFER: debug("dict: BUFFER");
// transfer->wLength = length;
if (buffer != NULL) {
transfer->data = (unsigned char *)buffer;
}
break; //end of BUFF
case DICT_USB: debug("dict: USB");
// transfer->wLength = length;
break;
default:
//request (aka dictionary) is unknown
sentinel("unknown DICT err:%d",ERR_UNKN_DICTIONARY);
}
int xfr_cnt;
xfr_cnt = usb_transfer( transfer );
if (print_debug) {
//print transfer details if small xfr
if (xfr_cnt <= 8) {
printf(" xf: %d er: %d rv:",xfr_cnt, transfer->data[0]);
int i ;
for (i=1; i<xfr_cnt; i++){
printf(" %x,", transfer->data[i]);
}
printf("\n");
} else {
//just print xfr cnt
printf(" xf: %d\n",xfr_cnt);
}
}
if (xfr_cnt <= 8) {
check(transfer->data[0] == SUCCESS, "retro programmer had error: %d, dict:%d, opcode:%d/%x, addr:%x, data:%x",transfer->data[0], dictionary, opcode, opcode, addr, miscdata)
}
return SUCCESS;
error:
printf("dictionary call went to error\n");
return -1;
}