278 lines
9.4 KiB
C++
278 lines
9.4 KiB
C++
#include "ezusb.h"
|
|
|
|
#include "rawinput/rawinput.h"
|
|
#include "util/logging.h"
|
|
|
|
#include "iidx.h"
|
|
#include "io.h"
|
|
|
|
bool games::iidx::EZUSBHandle::open(LPCWSTR lpFileName) {
|
|
return wcscmp(lpFileName, L"\\\\.\\Ezusb-0") == 0;
|
|
}
|
|
|
|
int games::iidx::EZUSBHandle::read(LPVOID lpBuffer, DWORD nNumberOfBytesToRead) {
|
|
log_warning("iidx", "EZUSB invalid read operation!");
|
|
return -1;
|
|
}
|
|
|
|
int games::iidx::EZUSBHandle::write(LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite) {
|
|
log_warning("iidx", "EZUSB invalid write operation!");
|
|
return -1;
|
|
}
|
|
|
|
int games::iidx::EZUSBHandle::device_io(DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize,
|
|
LPVOID lpOutBuffer, DWORD nOutBufferSize) {
|
|
|
|
// initialize check
|
|
if (!init) {
|
|
// TODO: initialize input
|
|
init = true;
|
|
init_success = true;
|
|
}
|
|
|
|
if (init_success) {
|
|
switch (dwIoControlCode) {
|
|
|
|
// device descriptor
|
|
case 0x222004:
|
|
|
|
// check output buffer size
|
|
if (nOutBufferSize >= 18) {
|
|
|
|
// set descriptor data
|
|
*((char *) lpOutBuffer + 8) = 0x47;
|
|
*((char *) lpOutBuffer + 9) = 0x05;
|
|
*((char *) lpOutBuffer + 10) = 0x35;
|
|
*((char *) lpOutBuffer + 11) = 0x22;
|
|
|
|
// return output buffer size
|
|
return 18;
|
|
|
|
} else // buffer too small
|
|
return -1;
|
|
|
|
// vendor
|
|
case 0x222014:
|
|
|
|
// check input buffer size
|
|
if (nInBufferSize >= 10)
|
|
return 0;
|
|
else
|
|
return -1;
|
|
|
|
// data read
|
|
case 0x22204E:
|
|
|
|
// check input buffer size
|
|
if (nInBufferSize < 4)
|
|
return -1;
|
|
|
|
// read 0x01
|
|
if (*(DWORD *) lpInBuffer == 0x01) {
|
|
*((DWORD *) lpOutBuffer) = get_pad();
|
|
*((char *) lpOutBuffer + 4) = FPGA_CMD_STATE;
|
|
*((char *) lpOutBuffer + 7) = get_tt(1, false);
|
|
*((char *) lpOutBuffer + 8) = get_tt(0, false);
|
|
*((char *) lpOutBuffer + 9) = FPGA_COUNTER++;
|
|
*((char *) lpOutBuffer + 11) = 1; // 1 success; 0 failed
|
|
*((char *) lpOutBuffer + 13) = get_slider(1) << 4 | get_slider(0);
|
|
*((char *) lpOutBuffer + 14) = get_slider(3) << 4 | get_slider(2);
|
|
*((char *) lpOutBuffer + 15) = get_slider(4);
|
|
return (int) nOutBufferSize;
|
|
}
|
|
|
|
// read 0x03
|
|
if (*(DWORD *) lpInBuffer == 0x03) {
|
|
|
|
// check output buffer size
|
|
if (nOutBufferSize < 64)
|
|
return -1;
|
|
|
|
// null node read
|
|
if (FPGA_CUR_NODE == 0) {
|
|
*(int *) lpOutBuffer = 0;
|
|
return (int) nOutBufferSize;
|
|
}
|
|
|
|
// check node size
|
|
if (FPGA_CUR_NODE != 64)
|
|
return -1;
|
|
|
|
// check command
|
|
if (SRAM_CMD != 2)
|
|
return -1;
|
|
|
|
// check if page exists
|
|
if (SRAM_PAGE >= 12)
|
|
return -1;
|
|
|
|
// write page
|
|
*((char *) lpOutBuffer + 1) = (char) SRAM_PAGE;
|
|
|
|
// copy page
|
|
memcpy((uint8_t*) lpOutBuffer + 2, SRAM_DATA + 62 * SRAM_PAGE, 62);
|
|
SRAM_PAGE++;
|
|
|
|
// write node
|
|
*((char *) lpOutBuffer) = (char) FPGA_CUR_NODE;
|
|
|
|
return (int) nOutBufferSize;
|
|
}
|
|
|
|
// unknown
|
|
return -1;
|
|
|
|
// data write
|
|
case 0x222051:
|
|
|
|
// check in buffer size
|
|
if (nInBufferSize < 4)
|
|
return -1;
|
|
|
|
// write 0x00
|
|
if (*(DWORD *) lpInBuffer == 0x00) {
|
|
|
|
// check out buffer size
|
|
if (nOutBufferSize < 10)
|
|
return -1;
|
|
|
|
// get data
|
|
uint16_t lamp = *((uint16_t *) lpOutBuffer + 0);
|
|
uint8_t led = *((uint8_t *) lpOutBuffer + 6);
|
|
uint8_t top_lamp = *((uint8_t *) lpOutBuffer + 8);
|
|
uint8_t top_neon = *((uint8_t *) lpOutBuffer + 9);
|
|
|
|
// process data
|
|
write_lamp(lamp);
|
|
write_led(led);
|
|
write_top_lamp(top_lamp);
|
|
write_top_neon(top_neon);
|
|
|
|
// flush device output
|
|
RI_MGR->devices_flush_output();
|
|
|
|
char write_node = *((char *) lpOutBuffer + 2);
|
|
if (write_node != 0) {
|
|
switch (write_node) {
|
|
case 4:
|
|
switch (*((char *) lpOutBuffer + 3)) {
|
|
case 1: // init
|
|
FPGA_CMD_STATE = 65;
|
|
break;
|
|
case 2: // check
|
|
FPGA_CMD_STATE = 66;
|
|
break;
|
|
case 3: // write
|
|
{
|
|
//int write_data = *((short *) lpOutBuffer + 4);
|
|
break;
|
|
}
|
|
case 4: // write done
|
|
FPGA_CMD_STATE = 67;
|
|
break;
|
|
default: // unknown
|
|
return -1;
|
|
}
|
|
break;
|
|
case 5:
|
|
break;
|
|
case 9:
|
|
break;
|
|
case 64: // SRAM command
|
|
SRAM_CMD = *((char *) lpOutBuffer + 3);
|
|
switch (SRAM_CMD) {
|
|
case 2: // read
|
|
SRAM_PAGE = 0;
|
|
break;
|
|
case 3: // write
|
|
SRAM_PAGE = 0;
|
|
break;
|
|
case 4: // done
|
|
break;
|
|
default: // unknown
|
|
return -1;
|
|
}
|
|
break;
|
|
default: // unknown node
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// save node
|
|
FPGA_CUR_NODE = write_node;
|
|
|
|
// return out buffer size
|
|
return (int) nOutBufferSize;
|
|
}
|
|
|
|
// write 0x02
|
|
if (*(DWORD *) lpInBuffer == 0x02) {
|
|
|
|
// check out buffer size
|
|
if (nOutBufferSize < 64)
|
|
return -1;
|
|
|
|
int cmd = *(char *) lpOutBuffer;
|
|
switch (cmd) {
|
|
case 0: // null write
|
|
break;
|
|
case 4: // unknown
|
|
break;
|
|
case 5: // 16seg
|
|
{
|
|
// write to status
|
|
IIDX_LED_TICKER_LOCK.lock();
|
|
if (!IIDXIO_LED_TICKER_READONLY)
|
|
memcpy(IIDXIO_LED_TICKER, (char *) lpOutBuffer + 2, 9);
|
|
IIDX_LED_TICKER_LOCK.unlock();
|
|
|
|
break;
|
|
}
|
|
case 64: // SRAM write
|
|
{
|
|
// get page
|
|
static char page = *((char *) lpOutBuffer + 1);
|
|
page = (char) SRAM_PAGE++;
|
|
|
|
// check page
|
|
if (page >= 12)
|
|
return -1;
|
|
|
|
// copy data
|
|
memcpy(SRAM_DATA + 62 * page, (uint8_t*) lpOutBuffer + 2, 62);
|
|
|
|
break;
|
|
}
|
|
default: // unknown node
|
|
return -1;
|
|
}
|
|
|
|
// return out buffer size
|
|
return (int) nOutBufferSize;
|
|
}
|
|
|
|
// unknown write
|
|
return -1;
|
|
|
|
// firmware upload
|
|
case 0x22206D:
|
|
|
|
// check buffer size
|
|
if (nInBufferSize >= 2)
|
|
return (int) nOutBufferSize;
|
|
else
|
|
return -1;
|
|
|
|
// unknown control code
|
|
default:
|
|
log_warning("iidx", "EZUSB unknown: {}", dwIoControlCode);
|
|
return -1;
|
|
}
|
|
} else
|
|
return -1;
|
|
}
|
|
|
|
bool games::iidx::EZUSBHandle::close() {
|
|
return true;
|
|
}
|