Sio.cpp, MemoryCardProtocol.cpp, MultitapProtocol.cpp and MemoryCardFile.cpp
become C89 units, and their headers C ones every unit can read. Sio0 and
Sio2 are plain structs with functions (sio0_set_tx_data, sio2_write and so
on) in place of methods; a state carries both whole, so their members keep
their order and types and a build check holds them to the layout states
have had on 64-bit hosts. The byte FIFOs move to SioFifo.c with their
state freeze, which tests/savestate now exercises directly instead of a
copy. The memory card images keep their slots in plain arrays, and read
what they need of the configuration through three functions in
Pcsx2Config.cpp; the card type the configuration carried at run time is
gone with them, since an open card file is what makes a card present. The
pads' three SIO entry points get C linkage (PAD/PADsio.h), and
sioConvertPadToPortAndSlot hands its port and slot back through pointers.
tests/sio drives SIO0, SIO2, the cards and the multitap through every
command a game sends, PS2 and PS1 cards, keyed and unkeyed MagicGate, DMA
blocks, auto-eject, the Python 1 slot latch and a state saved mid-command,
and compares every byte that comes back, the card files and the SIO state
blocks with the transcript the C++ made: they are the same. The tests that
built the C++ files now build the C ones.
FW.cpp becomes FW.c. With nothing on the bus it is the register file it
always was, byte for byte, and keeps no savestate block. With a device
(FWsetDevice) it runs the link, after Reliquary's: PHY registers and a
bus reset with self-ID that makes the console node 1, async transmit
through the user buffer (quadlet and block reads and writes), the two
PHT channels, and the device's own writes released one packet at a time
into the DBUF receive buffer, those to 0x1000:xxxx landing in IOP RAM as
the receive DMA would put them. Its buffers are fixed; the queue is a
byte ring allocated with the device. The device gets an IOP event of its
own (IopEvt_FW) and a tap on the SPU2's output.
The P1IO (FireWire/p1io.c) is Reliquary's KonamiPython1 device in C89:
the CF and ATA sector commands with the disk's timing on the status,
the battery-backed RAM, boot ROM and Dallas keys kept in their files,
the FSCI MAC stream, the UART's serial peripherals (EXTIO, the ICCA
reader, DDR's foot panels, B22 and Dog Station DX with a PS/2 keyboard),
the JAMMA panel and its coin counters, the offline network RPCs and the
ADPCM player. The sound is decoded as it plays rather than ahead into a
table, with the decoder kept at the loop's start, and is read again from
the disk when a state is loaded; it matches the decoded-ahead player
sample for sample. The network's DNS answers, dead with the network
forced offline, are left out.
The CF card's file is found and read in place by a small FAT reader
(FireWire/fatimg.c) instead of FatFs: FAT12, 16 or 32, a bare volume or
the first partition, the root's first file that is not empty, its
clusters kept as runs. Storage goes through the HDD image layer, so an
HDD or CF image can be raw, VHD or CHD.
A .py1 descriptor (FireWire/py1desc.c, Reliquary's keys) loads the game:
the board goes on the bus, the memory card it names goes in slot 1 by
its whole path (FullpathToMcd now takes an absolute name as it is) with
the MagicGate ID file it names (FileMcd_SetIdPath), and the DEV9 HDD is
not used. A serial board selects the second port's card slot by its
latch, and only slot 0 answers. The panel is on the RetroPad per I/O
mode, the keyboard on the libretro keyboard.
tests/p1io drives the link through its registers as the IOP's driver
does, and the board through it: the stub's registers, bus reset, reads,
writes, PHT, the release of queued writes, the disk with its timing,
the board's memories, the panel and coins, the Dog Station DX latch, the
B22 keyboard, the sound against a decoded-ahead reference through its
loop and a savestate, and a refused state. FAT12/16/32 images with
scattered clusters, and the descriptor. tests/mcdid covers the absolute
card path and the named ID file; the SPU2 suite stubs the tap.
A BIOS whose ROMVER says zone T, model Z is a COH-H, the BIOS of the
arcade boards built on the PS2 (Konami Python and the like), and the
core now sets BiosIsArcade for it. With it:
- MagicGate loads the key store's arcade key set rather than the
retail one, and, as an arcade mechacon does, decrypts a KELF of
application type 0x07 with a Kbit and Kc of its own, read from
mg_kelf07_kbit.bin and mg_kelf07_kc.bin (16 bytes each) beside the
BIOS. Without them such a KELF is refused with 0x81; any other
type, and any non-arcade mechacon, goes by the header's keys.
- The NVRAM is read as it is. A COH-H keeps no language or PStwo
region block, and finding those blank no longer makes the core
replace the board's NVRAM with console defaults.
- The IOP's TOOL registers read as the board's: config switches at
0x1f803100 with only bit 3 set (no CD-ROM drive, which the BIOS
checks), board id 0x7c at 0x1f803204. A console still reads the
switches all high.
A memory card can also answer MagicGate with an ID of its own: eight
bytes in <image>.id beside the card image (dongle.ps2, dongle.id).
The mechacon keeps that ID as the card's key, so a real dongle's dump
and ID unwrap the KELFs bound to that dongle; a card without one keeps
the emulated card's ID. MemoryCardFile reads the file with the image
and MemoryCardProtocol hands it over as each handshake starts.
None of this is savestate data: the arcade key set, the type 0x07 keys
and the card IDs come from files at load, like the key store itself.
Tests: tests/mg drives a type 0x07 KELF through an arcade mechacon with
and without its keys, through a retail one, and from the key files;
binds a KELF to a card with its own ID. tests/cdvdscmd loads an NVRAM
with blank language and region under a COH-H BIOS and a console's.
tests/iopcoh reads the TOOL registers both ways, tests/mcdid opens
cards with and without a .id file; each fails on the code before this.
tests/biosver pins down the ROMVER zones BiosIsArcade rests on (COH-H
against T10K), which the old code already told apart.