idmac: status good

This commit is contained in:
Hay1tsme
2024-12-22 03:35:55 -05:00
parent 66006cf869
commit 4437716bd0
9 changed files with 323 additions and 343 deletions
+25 -261
View File
@@ -60,21 +60,6 @@ emulates an IC card in its proximity. A variety of different IC cards can be
emulated; the exact choice of card that is emulated depends on the presence or
absence of the configured card ID files.
## `[amvideo]`
Controls the `amvideo.dll` stub built into Taitools. This is a DLL that is
normally present on the SEGA operating system image which is responsible for
changing screen resolution and orientation.
### `enable`
Default: `1`
Enable stub `amvideo.dll`. Disable to use a real `amvideo.dll` build. Note that
you must have the correct registry settings installed and you must use the
version of `amvideo.dll` that matches your GPU vendor (since these DLLs make
use of vendor-specific APIs).
## `[clock]`
Controls hooks for Windows time-of-day APIs.
@@ -143,122 +128,6 @@ Default: Empty string (i.e. use value from `default` setting)
Overrides the target of the `aime.naominet.jp` host lookup.
## `[ds]`
Controls emulation of the "DS (Dallas Semiconductor) EEPROM" chip on the AMEX
PCIe board. This is a small (32 byte) EEPROM that contains serial number and
region code information. It is not normally written to outside of inital
factory provisioning of a Sega Nu.
### `enable`
Default: `1`
Enable DS EEPROM emulation. Disable to use the DS EEPROM chip on a real AMEX.
### `region`
Default: `1`
AMEX Board region code. This appears to be a bit mask?
- `1`: Japan
- `2`: USA? (Dead code, not used)
- `4`: Export
- `8`: China
### `serialNo`
Default `AAVE-01A99999999`
"MAIN ID" serial number. First three characters are hardware series:
- `AAV`: Nu-series
- `AAW`: NuSX-series
- `ACA`: ALLS-series
## `[eeprom]`
Controls emulation of the bulk EEPROM on the AMEX PCIe board. This chip stores
status and configuration information.
### `enable`
Default: `1`
Enable bulk EEPROM emulation. Disable to use the bulk EEPROM chip on a real
AMEX.
### `path`
Default: `DEVICE\eeprom.bin`
Path to the storage file for EEPROM emulation. This file is automatically
created and initialized with a suitable number of zero bytes if it does not
already exist.
## `[gpio]`
Configure emulation of the AMEX PCIe GPIO (General Purpose Input Output)
controller.
### `enable`
Default: `1`
Enable GPIO emulation. Disable to use the GPIO controller on a real AMEX.
### `sw1`
Default `0x70` (`VK_F1`)
Keyboard binding for Nu chassis SW1 button (alternative Test)
### `sw2`
Default `0x71` (`VK_F2`)
Keyboard binding for Nu chassis SW2 button (alternative Service)
### `dipsw1` .. `dipsw8`
Defaults: `1`, `0`, `0`, `0`, `0`, `0`, `0`, `0`
Nu chassis DIP switch settings:
- Switch 1: Game-specific, but usually controls the "distribution server"
setting. Exactly one arcade machine on a cabinet router must be set to the
Server setting.
- `0`: Client
- `1`: Server
- Switch 2,3: Game-specific.
- Used by Mario&Sonic to configure cabinet ID, possibly other games.
- Switch 4: Screen orientation. Only used by the Nu system startup program.
- `0`: YOKO/Horizontal
- `1`: TATE/Vertical
- Switch 5,6,7: Screen resolution. Only used by the Nu system startup program.
- `000`: No change
- `100`: 640x480
- `010`: 1024x600
- `110`: 1024x768
- `001`: 1280x720
- `101`: 1280x1024
- `110`: 1360x768
- `111`: 1920x1080
- Switch 8: Game-specific. Not used in any shipping game.
## `[hwmon]`
Configure stub implementation of the platform hardware monitor driver. The
real implementation of this driver monitors CPU temperatures by reading from
Intel Model Specific Registers, which is an action that is only permitted from
kernel mode.
### `enable`
Default `1`
Enable hwmon emulation. Disable to use the real hwmon driver.
## `[jvs]`
@@ -270,96 +139,6 @@ Default `1`
Enable JVS port emulation. Disable to use the JVS port on a real AMEX.
## `[keychip]`
Configure keychip emulation.
### `enable`
Enable keychip emulation. Disable to use a real keychip.
### `id`
Default: `A69E-01A88888888`
Keychip serial number. Keychip serials observed in the wild follow this
pattern: `A6xE-01Ayyyyyyyy`.
### `gameId`
Default: (Varies depending on game)
Override the game's four-character model code. Changing this from the game's
expected value will probably just cause a system error.
### `platformId`
Default: (Varies depending on game)
Override the game's four-character platform code (e.g. `AAV2` for Nu 2). This
is actually supposed to be a separate three-character `platformId` and
integer `modelType` setting, but they are combined here for convenience. Valid
values include:
- `AAV0`: Nu 1 (Project DIVA)
- `AAV1`: Nu 1.1 (Chunithm)
- `AAV2`: Nu 2 (Initial D Zero)
- `AAW0`: NuSX 1
- `AAW1`: NuSX 1.1
- `ACA0`: ALLS UX
- `ACA1`: ALLS HX
- `ACA2`: ALLS UX (without dedicated GPU)
- `ACA4`: ALLS MX
### `region`
Default: `1`
Override the keychip's region code. Most games seem to pay attention to the
DS EEPROM region code and not the keychip region code, and this seems to be
a bit mask that controls which Nu PCB region codes this keychip is authorized
for. So it probably only affects the system software and not the game software.
Bit values are:
- 1: JPN: Japan
- 2: USA (unused)
- 3: EXP: Export (for Asian markets)
- 4: CHS: China (Simplified Chinese?)
### `billingType`
Default: `1`
Set the billing "type" for the keychip. The type determins what kind of revenue share,
if any, the game maker has with SEGA. Some games may be picky and require types other
then 1 (ex. Crossbeats requires billing type 2), so this option is provided if this
is an issue. Billing types are:
- 0: No billing?
- 1: Billing type A
- 2: Billing type B1
- 3: Billing type B2
### `systemFlag`
Default: `0x64`
An 8-bit bitfield of unclear meaning. The least significant bit indicates a
developer dongle, I think? Changing this doesn't seem to have any effect on
anything other than Project DIVA.
Other values observed in the wild:
- `0x04`: SDCH, SDCA
- `0x20`: SDCA
### `subnet`
Default `192.168.100.0`
The LAN IP range that the game will expect. The prefix length is hardcoded into
the game program: for some games this is `/24`, for others it is `/20`.
## `[netenv]`
Configure network environment virtualization. This module helps bypass various
@@ -396,46 +175,6 @@ Default: `01:02:03:04:05:06`
The MAC address of the virtualized Ethernet adapter. The exact value shouldn't
ever matter.
## `[pcbid]`
Configure Windows host name virtualization. The ALLS-series platform no longer
has an AMEX board, so the MAIN ID serial number is stored in the Windows
hostname.
### `enable`
Default: `1`
Enable Windows host name virtualization. This is only needed for ALLS-platform
games (since the ALLS lacks an AMEX and therefore has no DS EEPROM, so it needs
another way to store the PCB serial), but it does no harm on games that run on
earlier hardware.
### `serialNo`
Default: `ACAE01A99999999`
Set the Windows host name. This should be an ALLS MAIN ID, without the
hyphen (which is not a valid character in a Windows host name).
## `[sram]`
Configure emulation of the AMEX PCIe battery-backed SRAM. This stores
bookkeeping state and settings. This file is automatically created and
initialized with a suitable number of zero bytes if it does not already exist.
### `enable`
Default `1`
Enable SRAM emulation. Disable to use the SRAM on a real AMEX.
### `path`
Default `DEVICE\sram.bin`
Path to the storage file for SRAM emulation.
## `[vfs]`
Configure Windows path redirection hooks.
@@ -468,3 +207,28 @@ Default: Empty string
Configure the location of the "Option" data mount point. This mount point is
optional (hence the name, probably) and contains directories which contain
minor over-the-air content updates.
## `[idmac]`
### `dipsw_override`
Default: 0
Weather the value of `dipsw` will override the dipswitch value set by the DLL.
Only useful for debugging. Leave disabled.
### `dipsw`
Default: 0
Controls the value of the 4-switch dipswitch on the DMAC's daughter board. Each
bit is one of the switches, with LSB being switch 1. Ignored if `dipsw_override`
is 0.
### `hook_dll`
Default: 0
If 1, hook the iDmacDrvxx.dll functions, otherwise create a fake device. Set to
1 if you're using the stub included with this hook as a substitute for the real
DLL. Both hooking methods lead to the same place, so it doesn't matter too much
what you use.
+4
View File
@@ -23,5 +23,9 @@ void idmac_config_load(struct idmac_config *cfg, const wchar_t *filename)
assert(cfg != NULL);
assert(filename != NULL);
cfg->dipsw = GetPrivateProfileIntW(L"idmac", L"dipsw_override", 0, filename) << 4;
cfg->dipsw |= GetPrivateProfileIntW(L"idmac", L"dipsw", 0, filename);
cfg->hook_dll = GetPrivateProfileIntW(L"idmac", L"hook_dll", 0, filename);
jvs_config_load(&cfg->jvs, filename);
}
+205 -70
View File
@@ -1,58 +1,66 @@
#include <windows.h>
#include <assert.h>
#include <stdlib.h>
#include <winioctl.h>
#include "idmac/idmac.h"
#include "idmac/jvs.h"
#include "hook/table.h"
#include "hook/table.h"
#include "hook/iohook.h"
#include "util/dprintf.h"
#include "util/str.h"
enum IDAMC_IOCTL {
DMA_READ = 0xC3502000,
DMA_WRITE = 0xC3502004,
REGISTER_READ = 0xC3502008,
REGISTER_WRITE = 0xC350200C,
REGISTER_BUFFER_READ = 0xC3502012,
REGISTER_BUFFER_WRITE = 0xC3502016,
MEMORY_READ = 0xC3502018,
MEMORY_WRITE = 0xC350201C,
MEMORY_READ_EXT = 0xC3502080,
MEMORY_WRITE_EXT = 0xC3502084,
MEMORY_BUFFER_READ = 0xC3502020,
MEMORY_BUFFER_WRITE = 0xC3502024,
};
#define IDMAC_IOCTL_DMA_READ CTL_CODE(0xC350, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IDMAC_IOCTL_DMA_WRITE CTL_CODE(0xC350, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IDMAC_IOCTL_REGISTER_READ CTL_CODE(0xC350, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IDMAC_IOCTL_REGISTER_WRITE CTL_CODE(0xC350, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IDMAC_IOCTL_REGISTER_BUFFER_READ CTL_CODE(0xC350, 0x804, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define IDMAC_IOCTL_REGISTER_BUFFER_WRITE CTL_CODE(0xC350, 0x805, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define IDMAC_IOCTL_MEMORY_READ CTL_CODE(0xC350, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IDMAC_IOCTL_MEMORY_WRITE CTL_CODE(0xC350, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IDMAC_IOCTL_MEMORY_BUFFER_READ CTL_CODE(0xC350, 0x808, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IDMAC_IOCTL_MEMORY_BUFFER_WRITE CTL_CODE(0xC350, 0x809, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IDMAC_IOCTL_MEMORY_READ_EXT CTL_CODE(0xC350, 0x820, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IDMAC_IOCTL_MEMORY_WRITE_EXT CTL_CODE(0xC350, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS)
DWORD hook_iDmacDrvOpen(int dev_num, DWORD *dev_handle, DWORD *other_ptr);
DWORD hook_iDmacDrvClose(HANDLE a1, DWORD *lp);
int hook_iDmacDrvDmaRead(HANDLE a1, LPVOID lp, UINT_PTR ucb, unsigned int *a4);
int hook_iDmacDrvDmaWrite(HANDLE a1, void *lp, UINT_PTR ucb, unsigned int *a4);
int hook_iDmacDrvRegisterRead(HANDLE a1, DWORD register_id, DWORD* lp, unsigned int *a4);
int hook_iDmacDrvRegisterWrite(HANDLE a1, DWORD register_id, int a3, DWORD *lp);
int hook_iDmacDrvRegisterBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5);
int hook_iDmacDrvRegisterBufferWrite(HANDLE a1, DWORD BytesReturned, void *lp, UINT_PTR ucb, DWORD *a5);
int hook_iDmacDrvMemoryRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, DWORD *a4);
int hook_iDmacDrvMemoryWrite(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp);
int hook_iDmacDrvMemoryBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5);
int hook_iDmacDrvMemoryBufferWrite(HANDLE a1, unsigned int a2, void *lp, UINT_PTR ucb, DWORD *a5);
int hook_iDmacDrvMemoryReadExt(HANDLE a1, DWORD BytesReturned, unsigned int a3, LPVOID lp, int nOutBufferSize, DWORD *a6);
int hook_iDmacDrvMemoryWriteExt(HANDLE a1, int a2, unsigned int a3, void *Source, rsize_t DestinationSize, unsigned int *lp);
static uint8_t dipsw = 0;
static HANDLE idmac_fd;
DWORD (*next_iDmacDrvOpen)(int dev_num, DWORD *dev_handle, DWORD *other_ptr);
DWORD (*next_iDmacDrvClose)(HANDLE a1, DWORD *lp);
int (*next_iDmacDrvDmaRead)(HANDLE a1, LPVOID lp, UINT_PTR ucb, unsigned int *a4);
int (*next_iDmacDrvDmaWrite)(HANDLE a1, void *lp, UINT_PTR ucb, unsigned int *a4);
int (*next_iDmacDrvRegisterRead)(HANDLE a1, DWORD BytesReturned, LPVOID lp, unsigned int *a4);
int (*next_iDmacDrvRegisterWrite)(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp);
int (*next_iDmacDrvRegisterBufferRead)(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5);
int (*next_iDmacDrvRegisterBufferWrite)(HANDLE a1, DWORD BytesReturned, void *lp, UINT_PTR ucb, DWORD *a5);
int (*next_iDmacDrvMemoryRead)(HANDLE a1, DWORD BytesReturned, LPVOID lp, DWORD *a4);
int (*next_iDmacDrvMemoryWrite)(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp);
int (*next_iDmacDrvMemoryBufferRead)(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5);
int (*next_iDmacDrvMemoryBufferWrite)(HANDLE a1, unsigned int a2, void *lp, UINT_PTR ucb, DWORD *a5);
int (*next_iDmacDrvMemoryReadExt)(HANDLE a1, DWORD BytesReturned, unsigned int a3, LPVOID lp, int nOutBufferSize, DWORD *a6);
int (*next_iDmacDrvMemoryWriteExt)(HANDLE a1, int a2, unsigned int a3, void *Source, rsize_t DestinationSize, unsigned int *lp);
static HRESULT idmac_handle_irp(struct irp *irp);
static HRESULT idmac_handle_open(struct irp *irp);
static HRESULT idmac_handle_close(struct irp *irp);
static HRESULT idmac_handle_ioctl(struct irp *irp);
static DWORD hook_iDmacDrvOpen(int dev_num, DWORD *dev_handle, DWORD *err);
static DWORD hook_iDmacDrvClose(HANDLE a1, DWORD *lp);
static int hook_iDmacDrvDmaRead(HANDLE a1, void *lp, int ucb, unsigned int *err);
static int hook_iDmacDrvDmaWrite(HANDLE a1, void *lp, int ucb, unsigned int *err);
static int hook_iDmacDrvRegisterRead(HANDLE a1, DWORD register_id, DWORD* lp, unsigned int *err);
static int hook_iDmacDrvRegisterWrite(HANDLE a1, DWORD register_id, int a3, DWORD *lp);
static int hook_iDmacDrvRegisterBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5);
static int hook_iDmacDrvRegisterBufferWrite(HANDLE a1, DWORD BytesReturned, void *lp, UINT_PTR ucb, DWORD *a5);
static int hook_iDmacDrvMemoryRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, DWORD *a4);
static int hook_iDmacDrvMemoryWrite(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp);
static int hook_iDmacDrvMemoryBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5);
static int hook_iDmacDrvMemoryBufferWrite(HANDLE a1, unsigned int a2, void *lp, UINT_PTR ucb, DWORD *a5);
static int hook_iDmacDrvMemoryReadExt(HANDLE a1, DWORD BytesReturned, unsigned int a3, LPVOID lp, int nOutBufferSize, DWORD *a6);
static int hook_iDmacDrvMemoryWriteExt(HANDLE a1, int a2, unsigned int a3, void *Source, rsize_t DestinationSize, unsigned int *lp);
static DWORD (*next_iDmacDrvOpen)(int dev_num, DWORD *dev_handle, DWORD *err);
static DWORD (*next_iDmacDrvClose)(HANDLE a1, DWORD *lp);
static int (*next_iDmacDrvDmaRead)(HANDLE a1, void *lp, int ucb, unsigned int *err);
static int (*next_iDmacDrvDmaWrite)(HANDLE a1, void *lp, int ucb, unsigned int *err);
static int (*next_iDmacDrvRegisterRead)(HANDLE a1, DWORD BytesReturned, LPVOID lp, unsigned int *err);
static int (*next_iDmacDrvRegisterWrite)(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp);
static int (*next_iDmacDrvRegisterBufferRead)(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5);
static int (*next_iDmacDrvRegisterBufferWrite)(HANDLE a1, DWORD BytesReturned, void *lp, UINT_PTR ucb, DWORD *a5);
static int (*next_iDmacDrvMemoryRead)(HANDLE a1, DWORD BytesReturned, LPVOID lp, DWORD *a4);
static int (*next_iDmacDrvMemoryWrite)(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp);
static int (*next_iDmacDrvMemoryBufferRead)(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5);
static int (*next_iDmacDrvMemoryBufferWrite)(HANDLE a1, unsigned int a2, void *lp, UINT_PTR ucb, DWORD *a5);
static int (*next_iDmacDrvMemoryReadExt)(HANDLE a1, DWORD BytesReturned, unsigned int a3, LPVOID lp, int nOutBufferSize, DWORD *a6);
static int (*next_iDmacDrvMemoryWriteExt)(HANDLE a1, int a2, unsigned int a3, void *Source, rsize_t DestinationSize, unsigned int *lp);
static const struct hook_symbol idmac_hooks[] = {
{
@@ -144,7 +152,7 @@ void idmac_hook_table_apply(HMODULE target)
);
}
HRESULT idmac_hook_init(const struct idmac_config *cfg, jvs_provider_t jvs)
HRESULT idmac_hook_init(const struct idmac_config *cfg, struct idmac_hardware *hardware)
{
HRESULT hr;
@@ -152,7 +160,13 @@ HRESULT idmac_hook_init(const struct idmac_config *cfg, jvs_provider_t jvs)
dprintf("iDmac: Init\n");
hr = jvs_hook_init(&cfg->jvs, jvs);
dipsw = hardware->dipsw & 0x0F;
if (cfg->dipsw >> 4) {
dipsw = cfg->dipsw & 0x0F;
}
hr = jvs_hook_init(&cfg->jvs, hardware->jvs);
if (FAILED(hr)) {
return hr;
@@ -160,97 +174,218 @@ HRESULT idmac_hook_init(const struct idmac_config *cfg, jvs_provider_t jvs)
idmac_hook_table_apply(NULL);
hr = iohook_open_nul_fd(&idmac_fd);
if (FAILED(hr)) {
return hr;
}
hr = iohook_push_handler(idmac_handle_irp);
if (FAILED(hr)) {
return hr;
}
return S_OK;
}
DWORD hook_iDmacDrvOpen(int dev_num, DWORD *dev_handle, DWORD *other_ptr)
static HRESULT idmac_handle_irp(struct irp *irp)
{
assert(irp != NULL);
if (irp->op != IRP_OP_OPEN && irp->fd != idmac_fd) {
return iohook_invoke_next(irp);
}
switch (irp->op) {
case IRP_OP_OPEN: return idmac_handle_open(irp);
case IRP_OP_CLOSE: return idmac_handle_close(irp);
case IRP_OP_IOCTL: return idmac_handle_ioctl(irp);
default: return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
}
}
static HRESULT idmac_handle_open(struct irp *irp)
{
if (!wstr_ieq(irp->open_filename, L"\\\\.\\iDmacDrv0")) {
return iohook_invoke_next(irp);
}
dprintf("iDmac: Opened handle\n");
irp->fd = idmac_fd;
return S_OK;
}
static HRESULT idmac_handle_close(struct irp *irp)
{
dprintf("iDmac: Closed handle\n");
return S_OK;
}
static HRESULT idmac_handle_ioctl(struct irp *irp)
{
switch (irp->ioctl) {
/*case IDMAC_IOCTL_DMA_READ:
return hook_iDmacDrvDmaRead(irp);
case IDMAC_IOCTL_DMA_WRITE:
return hook_iDmacDrvDmaWrite(irp);
case IDMAC_IOCTL_REGISTER_READ:
return hook_iDmacDrvRegisterRead(irp);
case IDMAC_IOCTL_REGISTER_WRITE:
return hook_iDmacDrvRegisterWrite(irp);
case IDMAC_IOCTL_REGISTER_BUFFER_READ:
return hook_iDmacDrvRegisterBufferRead(irp);
case IDMAC_IOCTL_REGISTER_BUFFER_WRITE:
return hook_iDmacDrvRegisterBufferWrite(irp);
case IDMAC_IOCTL_MEMORY_READ:
return hook_iDmacDrvMemoryRead(irp);
case IDMAC_IOCTL_MEMORY_WRITE:
return hook_iDmacDrvMemoryWrite(irp);
case IDMAC_IOCTL_MEMORY_BUFFER_READ:
return hook_iDmacDrvMemoryBufferRead(irp);
case IDMAC_IOCTL_MEMORY_BUFFER_WRITE:
return hook_iDmacDrvMemoryBufferWrite(irp);
case IDMAC_IOCTL_MEMORY_READ_EXT:
return hook_iDmacDrvMemoryReadExt(irp);
case IDMAC_IOCTL_MEMORY_WRITE_EXT:
return hook_iDmacDrvMemoryWriteExt(irp);*/
default:
dprintf("iDmac: Unknown ioctl %#08x, write %i read %i\n",
irp->ioctl,
(int) irp->write.nbytes,
(int) irp->read.nbytes);
return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
}
}
static DWORD hook_iDmacDrvOpen(int dev_num, DWORD *dev_handle, DWORD *err)
{
dprintf("hook_iDmacDrvOpen: Open device #%X\n", dev_num);
return 0;
}
DWORD hook_iDmacDrvClose(HANDLE dev_handle, DWORD *lp)
static DWORD hook_iDmacDrvClose(HANDLE dev_handle, DWORD *lp)
{
dprintf("hook_iDmacDrvClose: Close handle %p\n", dev_handle);
return 0;
}
int hook_iDmacDrvDmaRead(HANDLE a1, LPVOID lp, UINT_PTR ucb, unsigned int *a4)
static int hook_iDmacDrvDmaRead(HANDLE a1, void *lp, int ucb, unsigned int *err)
{
//dprintf("hook_iDmacDrvDmaRead: This code should not run!\n");
dprintf("hook_iDmacDrvDmaRead: Read %d bytes\n", ucb);
return 0;
}
int hook_iDmacDrvDmaWrite(HANDLE a1, void *lp, UINT_PTR ucb, unsigned int *a4)
static int hook_iDmacDrvDmaWrite(HANDLE a1, void *lp, int ucb, unsigned int *err)
{
//dprintf("hook_iDmacDrvDmaWrite: This code should not run!\n");
dprintf("hook_iDmacDrvDmaWrite: Write %d bytes\n", ucb);
return 0;
}
int hook_iDmacDrvRegisterRead(HANDLE a1, DWORD register_id, DWORD* lp, unsigned int *a4)
static int hook_iDmacDrvRegisterRead(HANDLE a1, DWORD register_id, DWORD* register_val, unsigned int *err)
{
//dprintf("hook_iDmacDrvRegisterRead: This code should not run!\n");
if (register_id == 0x4140) { // get coin slot 1
*lp = 0;
}
if (register_id == 0x4144) { // get coin slot 2
*lp = 0;
}
if (register_id == 0x4120 && (GetAsyncKeyState(VK_DELETE) & 0x8000)) { // get keys
*lp = 0x40;
*register_val = 0;
*err = 0;
switch (register_id) {
case 0x0400: break;
case 0x4000: *register_val = -2; break; // Status
case 0x4004: *register_val = -2; break; // Status
case 0x4120: // JVS Buttons
if (GetAsyncKeyState(VK_DELETE) & 0x8000) {
*register_val = 0x40; // Test
}
break;
case 0x4124: break; // Analog 1
case 0x4128: break; // Analog 2
case 0x412C: break; // Analog 3
case 0x4140: break; // Coin slot 1
case 0x4144: break; // Coin slot 2
case 0x41A0: break;
case 0x41A4: break;
case 0x41A8: break;
case 0x41AC: break;
case 0x41C0: break;
case 0x41C4: break;
default:
dprintf("iDmac: Requested register %04lX\n", register_id);
break;
}
return 0;
}
int hook_iDmacDrvRegisterWrite(HANDLE a1, DWORD register_id, int a3, DWORD *lp)
static int hook_iDmacDrvRegisterWrite(HANDLE a1, DWORD register_id, int a3, DWORD *lp)
{
//dprintf("hook_iDmacDrvRegisterWrite: This code should not run!\n");
//dprintf("hook_iDmacDrvRegisterWrite: Write %d to register %04lX\n", a3, register_id);
return 0;
}
int hook_iDmacDrvRegisterBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5)
static int hook_iDmacDrvRegisterBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5)
{
//dprintf("hook_iDmacDrvRegisterBufferRead: This code should not run!\n");
return 0;
}
int hook_iDmacDrvRegisterBufferWrite(HANDLE a1, DWORD BytesReturned, void *lp, UINT_PTR ucb, DWORD *a5)
static int hook_iDmacDrvRegisterBufferWrite(HANDLE a1, DWORD BytesReturned, void *lp, UINT_PTR ucb, DWORD *a5)
{
//dprintf("hook_iDmacDrvRegisterBufferWrite: This code should not run!\n");
return 0;
}
int hook_iDmacDrvMemoryRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, DWORD *a4)
static int hook_iDmacDrvMemoryRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, DWORD *a4)
{
//dprintf("hook_iDmacDrvMemoryRead: This code should not run!\n");
return 0;
}
int hook_iDmacDrvMemoryWrite(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp)
static int hook_iDmacDrvMemoryWrite(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp)
{
//dprintf("hook_iDmacDrvMemoryWrite: This code should not run!\n");
return 0;
}
int hook_iDmacDrvMemoryBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5)
static int hook_iDmacDrvMemoryBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5)
{
//dprintf("hook_iDmacDrvMemoryBufferRead: This code should not run!\n");
return 0;
}
int hook_iDmacDrvMemoryBufferWrite(HANDLE a1, unsigned int a2, void *lp, UINT_PTR ucb, DWORD *a5)
static int hook_iDmacDrvMemoryBufferWrite(HANDLE a1, unsigned int a2, void *lp, UINT_PTR ucb, DWORD *a5)
{
//dprintf("hook_iDmacDrvMemoryBufferWrite: This code should not run!\n");
return 0;
}
int hook_iDmacDrvMemoryReadExt(HANDLE a1, DWORD BytesReturned, unsigned int a3, LPVOID lp, int nOutBufferSize, DWORD *a6)
static int hook_iDmacDrvMemoryReadExt(HANDLE a1, DWORD BytesReturned, unsigned int a3, LPVOID lp, int nOutBufferSize, DWORD *a6)
{
//dprintf("hook_iDmacDrvMemoryReadExt: This code should not run!\n");
return 0;
}
int hook_iDmacDrvMemoryWriteExt(HANDLE a1, int a2, unsigned int a3, void *Source, rsize_t DestinationSize, unsigned int *lp)
static int hook_iDmacDrvMemoryWriteExt(HANDLE a1, int a2, unsigned int a3, void *Source, rsize_t DestinationSize, unsigned int *lp)
{
//dprintf("hook_iDmacDrvMemoryWriteExt: This code should not run!\n");
return 0;
+16 -1
View File
@@ -1,15 +1,30 @@
#pragma once
#include <windows.h>
#include <stdint.h>
#include "idmac/jvs.h"
#pragma pack(push,1)
struct idmac_config {
uint8_t dipsw;
bool hook_dll;
struct jvs_config jvs;
};
struct idmac_hardware {
uint8_t dipsw;
jvs_provider_t dongle;
jvs_provider_t jvs;
jvs_provider_t fastio_main;
jvs_provider_t fastio_sub;
};
#pragma pack(pop)
HRESULT idmac_hook_init(
const struct idmac_config *cfg,
jvs_provider_t jvs);
struct idmac_hardware *hardware);
void idmac_hook_table_apply(HMODULE target);
+14 -5
View File
@@ -16,6 +16,7 @@
#include "gfxhook/d3d11.h"
#include "gfxhook/dxgi.h"
#include "sivahook/fastio.h"
#include "sivahook/reader.h"
#include "sivahook/config.h"
#include "sivahook/siva-dll.h"
@@ -45,10 +46,10 @@ static DWORD CALLBACK siva_pre_startup(void)
/* Hook Win32 APIs */
serial_hook_init();
//gfx_hook_init(&siva_hook_cfg.gfx);
//gfx_d3d9_hook_init(&siva_hook_cfg.gfx, siva_hook_mod);
//gfx_d3d11_hook_init(&siva_hook_cfg.gfx, siva_hook_mod);
//gfx_dxgi_hook_init(&siva_hook_cfg.gfx, siva_hook_mod);
gfx_hook_init(&siva_hook_cfg.gfx);
gfx_d3d9_hook_init(&siva_hook_cfg.gfx, siva_hook_mod);
gfx_d3d11_hook_init(&siva_hook_cfg.gfx, siva_hook_mod);
gfx_dxgi_hook_init(&siva_hook_cfg.gfx, siva_hook_mod);
/* Initialize emulation hooks */
@@ -73,7 +74,15 @@ static DWORD CALLBACK siva_pre_startup(void)
goto fail;
}
hr = idmac_hook_init(&siva_hook_cfg.idmac, siva_reader_init);
struct idmac_hardware idhw = {
.dipsw = 0b0000,
.dongle = NULL,
.jvs = siva_reader_init,
.fastio_main = siva_fastio_init,
.fastio_sub = NULL,
};
hr = idmac_hook_init(&siva_hook_cfg.idmac, &idhw);
if (FAILED(hr)) {
goto fail;
+45
View File
@@ -0,0 +1,45 @@
#include <windows.h>
#include <assert.h>
#include "jvs/jvs-bus.h"
#include "idmac/jvs.h"
#include "board/io3.h"
#include "sivahook/fastio.h"
#include "sivahook/siva-dll.h"
#include "util/dprintf.h"
static void fastio_jvs_read_switches(void *ctx, struct io3_switch_state *out);
static void fastio_jvs_read_coin_counter(
void *ctx,
uint8_t slot_no,
uint16_t *out);
static const struct io3_ops siva_jvs_fastio_ops = {
.read_switches = fastio_jvs_read_switches,
.read_coin_counter = fastio_jvs_read_coin_counter,
};
static struct io3 siva_jvs_fastio;
HRESULT siva_fastio_init(struct jvs_node **out)
{
HRESULT hr;
assert(out != NULL);
dprintf("Siva Nesica Fastio: Init\n");
io3_init(&siva_jvs_fastio, NULL, &siva_jvs_fastio_ops, NULL);
*out = io3_to_jvs_node(&siva_jvs_fastio);
return S_OK;
}
static void fastio_jvs_read_switches(void *ctx, struct io3_switch_state *out) {}
static void fastio_jvs_read_coin_counter(
void *ctx,
uint8_t slot_no,
uint16_t *out)
{}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include <windows.h>
#include "jvs/jvs-bus.h"
HRESULT siva_fastio_init(struct jvs_node **out);
+2
View File
@@ -30,5 +30,7 @@ shared_library(
'touch.h',
'reader.c',
'reader.h',
'fastio.c',
'fastio.h',
],
)
+6 -6
View File
@@ -10,15 +10,15 @@
#include "util/dprintf.h"
static void carol_jvs_read_switches(void *ctx, struct io3_switch_state *out);
static void carol_jvs_read_coin_counter(
static void reader_jvs_read_switches(void *ctx, struct io3_switch_state *out);
static void reader_jvs_read_coin_counter(
void *ctx,
uint8_t slot_no,
uint16_t *out);
static const struct io3_ops siva_jvs_reader_ops = {
.read_switches = carol_jvs_read_switches,
.read_coin_counter = carol_jvs_read_coin_counter,
.read_switches = reader_jvs_read_switches,
.read_coin_counter = reader_jvs_read_coin_counter,
};
static struct io3 siva_jvs_reader;
@@ -37,8 +37,8 @@ HRESULT siva_reader_init(struct jvs_node **out)
return S_OK;
}
static void carol_jvs_read_switches(void *ctx, struct io3_switch_state *out) {}
static void carol_jvs_read_coin_counter(
static void reader_jvs_read_switches(void *ctx, struct io3_switch_state *out) {}
static void reader_jvs_read_coin_counter(
void *ctx,
uint8_t slot_no,
uint16_t *out)