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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
#ifndef _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

View File

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

2
main.c
View File

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

28
n64.c
View File

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