Skip to content
This repository was archived by the owner on Dec 14, 2025. It is now read-only.

Commit 666ff02

Browse files
committed
[WIRED] Handle shifted VMU frames
1 parent 3594e70 commit 666ff02

File tree

1 file changed

+64
-28
lines changed

1 file changed

+64
-28
lines changed

main/wired/maple.c

Lines changed: 64 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@
6868
#define TIMEOUT_ABORT 100
6969

7070
#define VMU_BLOCK_SIZE 512
71-
#define VMU_WRITE_ACCESSES 4
72-
#define VMU_READ_ACCESSES 1
7371

7472
#define wait_100ns() asm("movi a8, 5\n\tloop a8, waitend%=\n\tnop\n\twaitend%=:\n":::"a8");
7573
#define wait_500ns() asm("movi a8, 49\n\tloop a8, waitend%=\n\tnop\n\twaitend%=:\n":::"a8");
@@ -89,6 +87,11 @@ struct maple_pkt {
8987
};
9088
};
9189

90+
typedef union {
91+
uint8_t bytes[4];
92+
uint32_t val;
93+
} u32_val_t;
94+
9295
static const uint8_t gpio_pin[][2] = {
9396
{21, 22},
9497
#ifndef CONFIG_BLUERETRO_WIRED_TRACE
@@ -192,7 +195,8 @@ static inline void load_mouse_axes(uint8_t port, uint16_t *axes) {
192195
}
193196
#endif
194197

195-
static void maple_tx(uint32_t port, uint32_t maple0, uint32_t maple1, uint8_t *data, uint32_t len) {
198+
static uint8_t maple_tx(uint32_t port, uint32_t maple0, uint32_t maple1, uint8_t *data, uint32_t len) {
199+
uint8_t crc_ret = 0;
196200
uint8_t *crc = data + (len - 1);
197201
*crc = 0x00;
198202

@@ -248,6 +252,7 @@ static void maple_tx(uint32_t port, uint32_t maple0, uint32_t maple1, uint8_t *d
248252
GPIO.out_w1tc = maple1;
249253
wait_200ns();
250254
}
255+
crc_ret = *crc;
251256
*crc ^= *data;
252257
}
253258
GPIO.out_w1ts = maple0;
@@ -269,6 +274,7 @@ static void maple_tx(uint32_t port, uint32_t maple0, uint32_t maple1, uint8_t *d
269274
core0_stall_end();
270275
gpio_set_direction_iram(gpio_pin[port][0], GPIO_MODE_INPUT);
271276
gpio_set_direction_iram(gpio_pin[port][1], GPIO_MODE_INPUT);
277+
return crc_ret;
272278
}
273279

274280
static unsigned maple_rx(unsigned cause) {
@@ -277,13 +283,12 @@ static unsigned maple_rx(unsigned cause) {
277283
uint32_t bit_cnt = 0;
278284
uint32_t gpio;
279285
uint8_t *data = pkt.data;
280-
#ifdef CONFIG_BLUERETRO_WIRED_TRACE
281286
uint32_t byte;
282-
#endif
283287
uint32_t port;
284288
uint32_t bad_frame;
285-
uint8_t len, cmd, src, dst, crc = 0;
289+
uint8_t len, cmd, src, dst, crc = 0, wcrc = 0;
286290
uint32_t maple1;
291+
u32_val_t func;
287292
uint8_t phase;
288293
uint8_t block_no;
289294

@@ -331,7 +336,8 @@ static unsigned maple_rx(unsigned cause) {
331336
*data &= ~mask;
332337
}
333338
}
334-
crc ^= *data;
339+
crc = wcrc;
340+
wcrc ^= *data;
335341
++data;
336342
}
337343
maple_end:
@@ -358,6 +364,7 @@ static unsigned maple_rx(unsigned cause) {
358364
ets_printf("\n");
359365
#else
360366
len = ((bit_cnt - 1) / 32) - 1;
367+
byte = ((bit_cnt - 1) / 8);
361368
/* Fix up to 7 bits loss */
362369
if (bad_frame) {
363370
cmd = maple_fix_byte(bad_frame, pkt.data[2], pkt.data[3]);
@@ -369,7 +376,7 @@ static unsigned maple_rx(unsigned cause) {
369376
cmd = pkt.data[2];
370377
src = pkt.data[1];
371378
dst = pkt.data[0];
372-
bad_frame = 1;
379+
bad_frame = 8;
373380
}
374381
else {
375382
cmd = pkt.cmd;
@@ -558,8 +565,16 @@ static unsigned maple_rx(unsigned cause) {
558565
case ADDR_MEM:
559566
pkt.src = src;
560567
pkt.dst = dst;
568+
func.bytes[0] = maple_fix_byte(bad_frame, pkt.data[3], pkt.data[4]);
569+
func.bytes[1] = maple_fix_byte(bad_frame, pkt.data[4], pkt.data[5]);
570+
func.bytes[2] = maple_fix_byte(bad_frame, pkt.data[5], pkt.data[6]);
571+
func.bytes[3] = maple_fix_byte(bad_frame, pkt.data[6], pkt.data[7]);
572+
block_no = maple_fix_byte(bad_frame, pkt.data[7], pkt.data[8]);
573+
phase = maple_fix_byte(bad_frame, pkt.data[9], pkt.data[10]);
574+
// ets_printf("%ld S: %ld C: %02X F: %08X B: %02X P: %02X\n", bad_frame, byte, cmd, func.val, block_no, phase);
561575
switch(cmd) {
562576
case CMD_INFO_REQ:
577+
case CMD_EXT_INFO_REQ:
563578
pkt.len = 28;
564579
pkt.cmd = CMD_INFO_RSP;
565580
pkt.data32[0] = ID_VMU_CLK | ID_VMU_LCD | ID_VMU_MEM;
@@ -571,39 +586,60 @@ static unsigned maple_rx(unsigned cause) {
571586
pkt.data32[27] = PWR_VMU;
572587
maple_tx(port, maple0, maple1, pkt.data, pkt.len * 4 + 5);
573588
break;
574-
case CMD_EXT_INFO_REQ: /* unimplemented */
575589
case CMD_GET_CONDITION:
576590
case CMD_MEM_INFO_REQ:
577-
pkt.len = 0x07;
578591
pkt.cmd = CMD_DATA_TX;
579-
pkt.data32[0] = ID_VMU_MEM;
580-
memcpy((void *)&pkt.data32[1], vmu_media_info, sizeof(vmu_media_info));
581-
maple_tx(port, maple0, maple1, pkt.data, pkt.len * 4 + 5);
592+
pkt.data32[0] = func.val;
593+
switch (func.val) {
594+
case ID_VMU_MEM:
595+
pkt.len = 0x07;
596+
memcpy((void *)&pkt.data32[1], vmu_media_info, sizeof(vmu_media_info));
597+
maple_tx(port, maple0, maple1, pkt.data, pkt.len * 4 + 5);
598+
break;
599+
case ID_VMU_LCD:
600+
pkt.len = 0x02;
601+
pkt.data32[1] = 0x2F1F1002;
602+
maple_tx(port, maple0, maple1, pkt.data, pkt.len * 4 + 5);
603+
break;
604+
}
582605
break;
583606
case CMD_BLOCK_READ:
607+
if (func.val != ID_VMU_MEM) {
608+
ets_printf("RD ERR func: 0x%08X\n", pkt.data32[0]);
609+
}
584610
pkt.len = 0x82;
585611
pkt.cmd = CMD_DATA_TX;
586-
pkt.data32[0] = ID_VMU_MEM;
587-
phase = (uint8_t)((pkt.data32[1] >> 16) & 0x00FF);
612+
pkt.data32[0] = func.val;
613+
pkt.data32[1] = (phase << 16) | block_no;
588614
if (phase) {
589-
ets_printf("Block Read with unexpected phase: 0x%02X, expected 0\n", phase);
615+
ets_printf("RD ERR phase: %d, expected 0\n", phase);
590616
}
591-
block_no = (uint8_t)((pkt.data32[1]) & 0x00FF);
592617
mc_read(block_no * VMU_BLOCK_SIZE, (void *)&pkt.data32[2], VMU_BLOCK_SIZE);
593-
maple_tx(port, maple0, maple1, pkt.data, pkt.len * 4 + 5);
618+
crc = maple_tx(port, maple0, maple1, pkt.data, pkt.len * 4 + 5);
619+
// ets_printf("R: %02X %d %02X\n", block_no, phase, crc);
594620
break;
595621
case CMD_BLOCK_WRITE:
596-
if (pkt.len != (32 + 2) && pkt.data32[0] == ID_VMU_MEM) {
597-
ets_printf("Unexpected Block Write packet length: 0x%02X, expected 0x22\n", pkt.len);
598-
}
622+
// if (pkt.len != (32 + 2) && func.val == ID_VMU_MEM) {
623+
// ets_printf("WR ERR: %d words, expected 34\n", pkt.len);
624+
// }
625+
// if (func.val == ID_VMU_MEM) {
626+
// if (crc != pkt.data[pkt.len * 4 + 4]) {
627+
// ets_printf("CRC ERR: 0x%02X, 0x%02X\n", pkt.data[pkt.len * 4 + 4], crc);
628+
// }
629+
// }
599630
pkt.len = 0x00;
600631
pkt.cmd = CMD_ACK;
601-
if ((!bad_frame) && pkt.data32[0] == ID_VMU_MEM) {
602-
phase = (uint8_t)((pkt.data32[1] >> 16) & 0x00FF);
603-
block_no = (uint8_t)((pkt.data32[1]) & 0x00FF);
604-
/* Data is written to the MC module in wire byte order. */
605-
/* If creating a read/write function, this must be accounted for. */
606-
mc_write((block_no * VMU_BLOCK_SIZE) + (128 * phase), (void *)&pkt.data32[2], 128);
632+
if (func.val == ID_VMU_MEM) {
633+
// ets_printf("W: %02X %d %02X\n", block_no, phase, crc);
634+
if (bad_frame) {
635+
for (uint32_t i = 0; i < 128; i++) {
636+
uint8_t mc_data = maple_fix_byte(bad_frame, pkt.data[i + 11], pkt.data[i + 12]);
637+
mc_write((block_no * VMU_BLOCK_SIZE) + (128 * phase) + i, &mc_data, 1);
638+
}
639+
}
640+
else {
641+
mc_write((block_no * VMU_BLOCK_SIZE) + (128 * phase), (void *)&pkt.data32[2], 128);
642+
}
607643
}
608644
maple_tx(port, maple0, maple1, pkt.data, pkt.len * 4 + 5);
609645
break;
@@ -613,7 +649,7 @@ static unsigned maple_rx(unsigned cause) {
613649
maple_tx(port, maple0, maple1, pkt.data, pkt.len * 4 + 5);
614650
break;
615651
default:
616-
ets_printf("%02X: Unk cmd: 0x%02X\n", dst, cmd);
652+
ets_printf("%02X: Unk cmd: %02X %02X %ld\n", dst, cmd, crc, byte);
617653
break;
618654
}
619655
break;

0 commit comments

Comments
 (0)