Do away with the gcn64 work buffer (saves more memory!)

This commit is contained in:
Raphael Assenat 2015-10-28 23:30:26 -04:00
parent 1a44a190cb
commit b7b07a37ee
7 changed files with 45 additions and 65 deletions

View File

@ -41,7 +41,7 @@ static void gamecubeInit(void)
gamecubeUpdate(); gamecubeUpdate();
} }
void gc_decodeAnswer() void gc_decodeAnswer(unsigned char data[8])
{ {
unsigned char x,y,cx,cy; unsigned char x,y,cx,cy;
@ -87,14 +87,14 @@ void gc_decodeAnswer()
*/ */
last_built_report.pad_type = PAD_TYPE_GAMECUBE; last_built_report.pad_type = PAD_TYPE_GAMECUBE;
last_built_report.gc.buttons = gcn64_protocol_getByte(0) | gcn64_protocol_getByte(8) << 8; last_built_report.gc.buttons = data[0] | data[1] << 8;
x = gcn64_protocol_getByte(16); x = data[2];
y = gcn64_protocol_getByte(24); y = data[3];
cx = gcn64_protocol_getByte(32); cx = data[4];
cy = gcn64_protocol_getByte(40); cy = data[5];
last_built_report.gc.lt = gcn64_protocol_getByte(48); last_built_report.gc.lt = data[6];
last_built_report.gc.rt = gcn64_protocol_getByte(56); last_built_report.gc.rt = data[7];
gcn64_protocol_getBytes(0, 8, last_built_report.gc.raw_data); memcpy(last_built_report.gc.raw_data, data, 8);
if (origins_set) { if (origins_set) {
last_built_report.gc.x = ((int)x-(int)orig_x); last_built_report.gc.x = ((int)x-(int)orig_x);
@ -117,8 +117,7 @@ void gc_decodeAnswer()
static char gamecubeUpdate() static char gamecubeUpdate()
{ {
//unsigned char tmp=0; unsigned char tmpdata[GC_GETSTATUS_REPLY_LENGTH];
unsigned char tmpdata[8];
unsigned char count; unsigned char count;
#if 0 #if 0
@ -147,12 +146,12 @@ static char gamecubeUpdate()
tmpdata[1] = GC_GETSTATUS2; tmpdata[1] = GC_GETSTATUS2;
tmpdata[2] = GC_GETSTATUS3(gc_rumbling); tmpdata[2] = GC_GETSTATUS3(gc_rumbling);
count = gcn64_transaction(tmpdata, 3); count = gcn64_transaction(tmpdata, 3, tmpdata, GC_GETSTATUS_REPLY_LENGTH);
if (count != GC_GETSTATUS_REPLY_LENGTH) { if (count != GC_GETSTATUS_REPLY_LENGTH) {
return 1; return 1;
} }
gc_decodeAnswer(); gc_decodeAnswer(tmpdata);
return 0; return 0;
} }

View File

@ -25,9 +25,6 @@
#undef FORCE_KEYBOARD #undef FORCE_KEYBOARD
#define GCN64_BUF_SIZE 40
static unsigned char gcn64_workbuf[GCN64_BUF_SIZE];
/******** IO port definitions and options **************/ /******** IO port definitions and options **************/
#ifndef STK525 #ifndef STK525
#define GCN64_DATA_PORT PORTD #define GCN64_DATA_PORT PORTD
@ -45,20 +42,6 @@ static unsigned char gcn64_workbuf[GCN64_BUF_SIZE];
#define DISABLE_INTS_DURING_COMM #define DISABLE_INTS_DURING_COMM
/* Read a byte from the buffer (where 1 byte is 1 bit).
* MSb first.
*/
unsigned char gcn64_protocol_getByte(int offset)
{
return gcn64_workbuf[offset/8];
}
void gcn64_protocol_getBytes(int offset, int n_bytes, unsigned char *dstbuf)
{
memcpy(dstbuf, gcn64_workbuf + offset/8, n_bytes);
}
void gcn64protocol_hwinit(void) void gcn64protocol_hwinit(void)
{ {
// data as input // data as input
@ -79,22 +62,22 @@ void gcn64protocol_hwinit(void)
* *
* The result is in gcn64_workbuf. * The result is in gcn64_workbuf.
*/ */
int gcn64_transaction(unsigned char *data_out, int data_out_len) unsigned char gcn64_transaction(const unsigned char *tx, int tx_len, unsigned char *rx, unsigned char rx_max)
{ {
int count; int count;
unsigned char sreg = SREG; unsigned char sreg = SREG;
// int i; //int i;
#ifdef DISABLE_INTS_DURING_COMM #ifdef DISABLE_INTS_DURING_COMM
cli(); cli();
#endif #endif
gcn64_sendBytes(data_out, data_out_len); gcn64_sendBytes(tx, tx_len);
count = gcn64_receiveBytes(gcn64_workbuf, 0); count = gcn64_receiveBytes(rx, rx_max);
SREG = sreg; SREG = sreg;
#if 0 #if 0
printf("Count: %d { ", count); printf("Count: %d { ", count);
for (i=0; i<count; i++) { for (i=0; i<count; i++) {
printf("%02x ", gcn64_workbuf[i]); printf("%02x ", rx[i]);
} }
printf("}\r\n"); printf("}\r\n");
#endif #endif
@ -123,8 +106,9 @@ int gcn64_detectController(void)
unsigned char tmp = GC_GETID; unsigned char tmp = GC_GETID;
unsigned char count; unsigned char count;
unsigned short id; unsigned short id;
unsigned char data[4];
count = gcn64_transaction(&tmp, 1); count = gcn64_transaction(&tmp, 1, data, sizeof(data));
if (count == 0) { if (count == 0) {
return CONTROLLER_IS_ABSENT; return CONTROLLER_IS_ABSENT;
} }
@ -132,7 +116,7 @@ int gcn64_detectController(void)
return CONTROLLER_IS_UNKNOWN; return CONTROLLER_IS_UNKNOWN;
} }
/* /*
* -- Standard gamecube controller answer: * -- Standard gamecube controller answer:
* 0000 1001 0000 0000 0010 0011 : 0x090023 or * 0000 1001 0000 0000 0010 0011 : 0x090023 or
* 0000 1001 0000 0000 0010 0000 : 0x090020 * 0000 1001 0000 0000 0010 0000 : 0x090020
@ -145,13 +129,13 @@ int gcn64_detectController(void)
* *
* 1110 1001 1010 0000 0001 0111 : 0xE9A017 * 1110 1001 1010 0000 0001 0111 : 0xE9A017
* (controller on) * (controller on)
* *
* 1010 1000 0000 * 1010 1000 0000
* *
* -- Intec wireless gamecube controller * -- Intec wireless gamecube controller
* 0000 1001 0000 0000 0010 0000 : 0x090020 * 0000 1001 0000 0000 0010 0000 : 0x090020
* *
* *
* -- Standard N64 controller * -- Standard N64 controller
* 0000 0101 0000 0000 0000 0000 : 0x050000 (no pack) * 0000 0101 0000 0000 0000 0000 : 0x050000 (no pack)
* 0000 0101 0000 0000 0000 0001 : 0x050001 With expansion pack * 0000 0101 0000 0000 0000 0001 : 0x050001 With expansion pack
@ -164,8 +148,8 @@ int gcn64_detectController(void)
* gamecube compatible controller is present. If on the other hand * gamecube compatible controller is present. If on the other hand
* we have a 5, then we are communicating with a N64 controller. * we have a 5, then we are communicating with a N64 controller.
* *
* This conclusion appears to be corroborated by my old printout of * This conclusion appears to be corroborated by my old printout of
* the document named "Yet another gamecube documentation (but one * the document named "Yet another gamecube documentation (but one
* that's worth printing). The document explains that and ID can * that's worth printing). The document explains that and ID can
* be read by sending what they call the 'SI command 0x00 to * be read by sending what they call the 'SI command 0x00 to
* which the controller replies with 3 bytes. (Clearly, that's * which the controller replies with 3 bytes. (Clearly, that's
@ -186,8 +170,7 @@ int gcn64_detectController(void)
* *
* */ * */
id = gcn64_protocol_getByte(0)<<8; id = (data[0]<<8) | data[1];
id |= gcn64_protocol_getByte(8);
#ifdef FORCE_KEYBOARD #ifdef FORCE_KEYBOARD
return CONTROLLER_IS_GC_KEYBOARD; return CONTROLLER_IS_GC_KEYBOARD;
@ -209,7 +192,7 @@ int gcn64_detectController(void)
// wavebird, controller off. // wavebird, controller off.
return CONTROLLER_IS_GC; return CONTROLLER_IS_GC;
default: default:
return CONTROLLER_IS_UNKNOWN; return CONTROLLER_IS_UNKNOWN;
} }

View File

@ -161,9 +161,6 @@
void gcn64protocol_hwinit(void); void gcn64protocol_hwinit(void);
int gcn64_detectController(void); int gcn64_detectController(void);
int gcn64_transaction(unsigned char *data_out, int data_out_len); unsigned char gcn64_transaction(const unsigned char *tx, int tx_len, unsigned char *rx, unsigned char rx_max);
unsigned char gcn64_protocol_getByte(int offset);
void gcn64_protocol_getBytes(int offset, int n_bytes, unsigned char *dstbuf);
#endif // _gcn64_protocol_h__ #endif // _gcn64_protocol_h__

View File

@ -1,7 +1,7 @@
#ifndef _gcn64txrx_h__ #ifndef _gcn64txrx_h__
#define _gcn64txrx_h__ #define _gcn64txrx_h__
void gcn64_sendBytes(unsigned char *data, unsigned char n_bytes); void gcn64_sendBytes(const unsigned char *data, unsigned char n_bytes);
/** /**
* \brief Receive up to \max_bytes bytes * \brief Receive up to \max_bytes bytes

View File

@ -78,8 +78,7 @@ static void hiddata_processCommandBuffer(void)
// TODO : Range checking // TODO : Range checking
// cmdbuf[] : RQ, CHN, LEN, data[] // cmdbuf[] : RQ, CHN, LEN, data[]
channel = cmdbuf[1]; channel = cmdbuf[1];
cmdbuf_len = gcn64_transaction(cmdbuf+3, cmdbuf[2]); cmdbuf_len = gcn64_transaction(cmdbuf+3, cmdbuf[2], cmdbuf + 3, CMDBUF_SIZE-3);
gcn64_protocol_getBytes(0, cmdbuf_len, cmdbuf + 3);
cmdbuf[2] = cmdbuf_len; cmdbuf[2] = cmdbuf_len;
cmdbuf_len += 3; // Answer: RQ, CHN, LEN, data[] cmdbuf_len += 3; // Answer: RQ, CHN, LEN, data[]
break; break;

2
main.c
View File

@ -222,10 +222,12 @@ Gamepad *detectPad(void)
return NULL; return NULL;
case CONTROLLER_IS_N64: case CONTROLLER_IS_N64:
printf("Detected N64 controller\n");
return n64GetGamepad(); return n64GetGamepad();
break; break;
case CONTROLLER_IS_GC: case CONTROLLER_IS_GC:
printf("Detected GC controller\n");
return gamecubeGetGamepad(); return gamecubeGetGamepad();
} }

28
n64.c
View File

@ -53,13 +53,14 @@ unsigned char tmpdata[40];
static char initRumble(void) static char initRumble(void)
{ {
int count; int count;
unsigned char data[4];
tmpdata[0] = N64_EXPANSION_WRITE; tmpdata[0] = N64_EXPANSION_WRITE;
tmpdata[1] = 0x80; tmpdata[1] = 0x80;
tmpdata[2] = 0x01; tmpdata[2] = 0x01;
memset(tmpdata+3, 0x80, 32); memset(tmpdata+3, 0x80, 32);
count = gcn64_transaction(tmpdata, 35); count = gcn64_transaction(tmpdata, 35, data, sizeof(data));
if (count == 1) if (count == 1)
return 0; return 0;
@ -69,12 +70,13 @@ static char initRumble(void)
static char controlRumble(char enable) static char controlRumble(char enable)
{ {
int count; int count;
unsigned char data[4];
tmpdata[0] = N64_EXPANSION_WRITE; tmpdata[0] = N64_EXPANSION_WRITE;
tmpdata[1] = 0xc0; tmpdata[1] = 0xc0;
tmpdata[2] = 0x1b; tmpdata[2] = 0x1b;
memset(tmpdata+3, enable ? 0x01 : 0x00, 32); memset(tmpdata+3, enable ? 0x01 : 0x00, 32);
count = gcn64_transaction(tmpdata, 35); count = gcn64_transaction(tmpdata, 35, data, sizeof(data));
if (count == 1) if (count == 1)
return 0; return 0;
@ -86,7 +88,8 @@ static char n64Update(void)
unsigned char count; unsigned char count;
unsigned char x,y; unsigned char x,y;
unsigned char btns1, btns2; unsigned char btns1, btns2;
unsigned char caps[3]; unsigned char caps[N64_CAPS_REPLY_LENGTH];
unsigned char status[N64_GET_STATUS_REPLY_LENGTH];
/* Pad answer to N64_GET_CAPABILITIES /* Pad answer to N64_GET_CAPABILITIES
* *
@ -98,7 +101,7 @@ static char n64Update(void)
* Bit 1 tells is if there was something connected that has been removed. * Bit 1 tells is if there was something connected that has been removed.
*/ */
tmpdata[0] = N64_GET_CAPABILITIES; tmpdata[0] = N64_GET_CAPABILITIES;
count = gcn64_transaction(tmpdata, 1); count = gcn64_transaction(tmpdata, 1, caps, sizeof(caps));
if (count != N64_CAPS_REPLY_LENGTH) { if (count != N64_CAPS_REPLY_LENGTH) {
// a failed read could mean the pack or controller was gone. Init // a failed read could mean the pack or controller was gone. Init
// will be necessary next time we detect a pack is present. // will be necessary next time we detect a pack is present.
@ -106,10 +109,6 @@ static char n64Update(void)
return -1; return -1;
} }
caps[0] = gcn64_protocol_getByte(0);
caps[1] = gcn64_protocol_getByte(8);
caps[2] = gcn64_protocol_getByte(16);
/* Detect when a pack becomes present and schedule initialisation when it happens. */ /* Detect when a pack becomes present and schedule initialisation when it happens. */
if ((caps[2] & 0x01) && (n64_rumble_state == RSTATE_UNAVAILABLE)) { if ((caps[2] & 0x01) && (n64_rumble_state == RSTATE_UNAVAILABLE)) {
n64_rumble_state = RSTATE_INIT; n64_rumble_state = RSTATE_INIT;
@ -173,7 +172,7 @@ static char n64Update(void)
} }
tmpdata[0] = N64_GET_STATUS; tmpdata[0] = N64_GET_STATUS;
count = gcn64_transaction(tmpdata, 1); count = gcn64_transaction(tmpdata, 1, status, sizeof(status));
if (count != N64_GET_STATUS_REPLY_LENGTH) { if (count != N64_GET_STATUS_REPLY_LENGTH) {
return -1; return -1;
} }
@ -200,10 +199,10 @@ static char n64Update(void)
24-31: analog Y axis 24-31: analog Y axis
*/ */
btns1 = gcn64_protocol_getByte(0); btns1 = status[0];
btns2 = gcn64_protocol_getByte(8); btns2 = status[1];
x = gcn64_protocol_getByte(16); // X axis x = status[2];
y = gcn64_protocol_getByte(24); // Y axis y = status[3];
#ifdef BUTTON_A_RUMBLE_TEST #ifdef BUTTON_A_RUMBLE_TEST
if (btns1 & 0x80) { if (btns1 & 0x80) {
@ -256,6 +255,7 @@ static char n64Probe(void)
int count; int count;
char i; char i;
unsigned char tmp; unsigned char tmp;
unsigned char data[4];
/* Pad answer to N64_GET_CAPABILITIES /* Pad answer to N64_GET_CAPABILITIES
* *
@ -274,7 +274,7 @@ static char n64Probe(void)
_delay_ms(30); _delay_ms(30);
tmp = N64_GET_CAPABILITIES; tmp = N64_GET_CAPABILITIES;
count = gcn64_transaction(&tmp, 1); count = gcn64_transaction(&tmp, 1, data, sizeof(data));
if (count == N64_CAPS_REPLY_LENGTH) { if (count == N64_CAPS_REPLY_LENGTH) {
return 1; return 1;