Entry 16

The oracle takes input: SIO0 and the BIOS interrupt queues

Documented in The input module.

Filescrates/rugrats-hle/src/sio.rshw.rslib.rsdocs/engine/input.md

The game reads its pads through libpad's direct driver, so the oracle's BIOS pad buffers never reached it. Two pieces fix that:

  • sio.rs models the controller port with a digital pad in port 1: data, status, mode, control, baud; the pad answers FF 41 5A lo hi and pulls /ACK after each byte but the last. The driver clears I_STAT bit 7, waits for /ACK to rise, acknowledges, takes the answer, and only then polls I_STAT bit 7 for the pulse. With the harness's clock still within a slice, the pulse lands at that I_STAT read (or the slice's end). A pulse that landed at once was cleared before the poll, and the driver gave up after the first byte.
  • The BIOS's interrupt queues (SysEnqIntRP/SysDeqIntRP) are kept and run before libetc's dispatcher, each entry's func1 then func2. libpad's vertical-blank handler is queued there (priority 2) and tests I_STAT bit 0 itself, so it must run before libetc acknowledges it.

The buffer at 0x800cdbb0 now reads 00 41 ff ff, and ef ff with Triangle held. With a pad present the game behaves differently: after the logos it shows the memory card check and then, on X, the title menu (Start Game, Load Game, Audio; Start Game leads to Main Game, Activities, Training). Without a pad it had gone from the logos straight to the opening cinematic, which is the order the port follows today. That order has to change once the front end is ported.

Was unknown
  1. where the opening cinematic plays with a pad in (after Main Game?)
    closed by #18
  2. the memory card's BIOS calls, which the oracle answers as no card
    closed by #17