585 Commits
Author SHA1 Message Date
Antonio SJ Musumeci b398d5592f Add LICENSE file 2026-11-05 09:04:00 -06:00
LibretroAdmin 54fe4f3754 Savestates: format V4, 25.5 MB down to 6.6 MB
A state stored the whole 22 MB DRAM allocation -- sized for the
largest memory configuration and the high-resolution VRAM copies --
plus both ROMs, whatever the game used, and the DSP's 70 KB of decode
tables. V4 keeps everything else as it was and changes two chunks:

- MEM2 replaces MEM. It holds the memory configuration, then only the
  RAM that configuration uses (DRAM, VRAM and VRAM's three high-
  resolution copies), then NVRAM. The copies are kept whether or not
  high resolution is on, because it can be switched mid-game and the
  state size must not change under a frontend that sized its buffers
  once; the configuration itself is fixed for a session. The ROMs are
  left out: they are the BIOS and font loaded for the session and
  never change. For the stock 2 MB/1 MB configuration that is 6 MB of
  RAM instead of 22 MB, and 2 MB of ROM gone.
- DSP2 replaces DSPP. INSTTRAS, REGCONV and BRCONDTAB are decode tables
  opera_dsp_init() builds and nothing changes, so they are not stored;
  a load keeps the running core's.

V3 states still load: MEM and DSPP are still read, and the tables a
DSPP chunk carries are stepped over. A core without this change
refuses a V4 state as an unknown version.

Measured with a libretro driver, stock configuration, together with
the array I/O change before this:

             size        serialize   unserialize
  before     25550222    3.8 ms      4.2 ms
  V4          6605970    0.5 ms      0.6 ms

Checked: a V3 state saved by the previous core loads and plays the
next 240 frames with audio and video identical to the original run; a
V4 state does the same; save-load-save is byte-identical; a replay of
60 frames from a loaded state matches; a sweep flipping 9721 bytes
never lets a refused load change the running state; and the changed
files build big-endian (PowerPC).
2026-10-28 20:58:23 +01:00
LibretroAdmin 02f675e3c3 opera_state: write and read arrays in one go
Saving or loading a state spent most of its time in the state
writer's and reader's per-element calls rather than in copying memory.
Every u8/u16/u32 went through write_bytes/read_bytes, which bounds-
checked and memcpy'd one to four bytes, and every array -- the CLIO
register file alone is 65536 words -- was written and read one element
at a time that way.

- Arrays are written and read with one bounds check and one copy. The
  stored form is little-endian, so on a little-endian host that is the
  array's own bytes; a big-endian host converts element by element.
- Scalars reserve their bytes and store them directly instead of
  building them in a temporary and copying it in.

The bytes written are unchanged. A state saved by this core matches
one saved by the previous core except for the PRNG seed, which already
differs from run to run. Checked on little- and big-endian (PowerPC
under qemu) that the layout matches byte for byte and that overruns
are still refused. Run-ahead and rewind see the difference: serialize
went from 3.8 to 2.7 ms and unserialize from 4.2 to 3.0 ms.
2026-10-28 20:58:20 +01:00
LibretroAdmin 93ae3b9520 retro_unserialize: validate instead of backing up the running state
Every state load first serialized the running state into a fresh
allocation the size of a state -- 25.5 MB -- so a failed load could be
rolled back. That doubled the cost of every load, and run-ahead and
rewind load every frame.

A current-format state is now checked first and then loaded. Each
current-format loader already parses its chunk into locals and checks
it before touching emulator state; with opera_state_set_validating()
set they stop there, so a state that validates is one the real load
accepts in full and there is nothing to roll back. In that pass:

- the MEM chunk's 25 MB payload is stepped over (sizes and config are
  still checked), not copied;
- the xbus devices are not reset, and the CD-ROM device fields are
  checked against a scratch copy;
- the memory-map sync, pbus reset and other side effects after loading
  are skipped.

An older format, or a state carrying an older CD-ROM chunk, is not
validated and takes the old backup path, as does anything that fails
validation, so a refused state still leaves the running state as it
was.

Measured with a libretro driver over 200 loads: retro_unserialize went
from 9.08 ms to 4.20 ms on average (best 7.80 ms to 3.58 ms). Checked:
save, load and save again is byte-identical; a state loaded and run 60
frames matches the original run byte for byte; and a sweep flipping
each of 9721 bytes (every 64th byte of the first 360 KB, every byte of
the last 4 KB) is accepted or refused exactly as before, with no
refused load ever changing the running state.
2026-10-28 20:21:15 +01:00
LibretroAdmin a8b62eba35 retro_cdimage: read images in place, without syscalls per sector
Every sector read was a seek and a read through the VFS, and a CHD
copied each compressed hunk twice on its way to the decoder: from the
file into a 64 KiB request buffer, in pieces of at most 64 KiB, then
into the decoder's own staging buffer.

- Images are opened with RETRO_VFS_FILE_ACCESS_HINT_FREQUENT_ACCESS,
  and HAVE_MMAP is now defined for unix, osx and Android, so the
  local VFS maps them. A BIN/ISO/CUE sector read becomes a copy out
  of the page cache into the drive's buffer, which is the one copy
  the emulated drive needs.
- CHD: the compressed hunk is lent to the decoder straight from the
  mapping (rchd_feed_borrow), so it is never copied. Unmapped (a
  frontend VFS, a platform without mapping, a file too big to map),
  each hunk is read in one call into a buffer sized to a hunk at open
  and lent from there, rather than copied in again. The open sequence
  is still fed by copy. The file position is tracked so a read that
  continues where the last one stopped does not seek.
- On a mapped CHD the OS is asked to bring the next 1 MiB of the file
  in ahead of the decoder (filestream_prefetch), coalesced so one
  request covers many hunks; cold pages would otherwise stall the
  emulation thread on a page fault.
- BIN/ISO/CUE: a read that starts where the previous one ended skips
  the seek.

Measured over 20 passes of every sector of a 2400-sector test disc:
BIN/CUE went from 75593 read/lseek syscalls to 9 and from 0.57 to
0.22 us per sector; a CHD from 13392 syscalls to 26 (default hunks)
and from 1493 to 28 (1 MiB hunks). Unmapped, lseeks on a CHD dropped
from 6009 to 26 and 1 MiB-hunk reads from 984 to 264.

tools/chd/run.sh now also checks every codec at the largest hunk
chdman writes (1 MiB), and passes under ASan/UBSan on both the mapped
and the unmapped path.
2026-10-28 20:21:11 +01:00
LibretroAdmin bf06fa747d libretro-common: sync rchd and rflac from RetroArch
Brings in RetroArch's "rchd: allocate nothing per hunk once an image
is open" and "rchd: say how long lent bytes have to live". CHD reads
no longer allocate once the image is open: the staging buffer is
reused, the CD FLAC decoder is kept and rewound, and the hunk cache,
CD sector scratch and FLAC rewind point are allocated at open. A
malloc counter over every sector of CD LZMA, CD FLAC and mixed images
went from 299 allocations during reads to 0.
2026-10-28 20:21:07 +01:00
LibretroAdmin 4a3556a195 Replace deps/zlib with libretro-common rinflate/rdeflate
zlib had two users left. The core inflated its built-in boot ROM with
it, and the test harness deflated RGB frames for the kitty terminal
preview. libretro-common's encoding_deflate already does both and the
core already built it for CHD, so deps/zlib-1.3.1.2 goes.

- opera_bios.c: inflate the boot ROM with rinflate (zlib wrapper,
  adler32 checked) straight into the caller's buffer. Checked: the
  ROM comes out at 131072 bytes with CRC32 dacb21ad, as opera_boot.h
  records, under ASan/UBSan.
- encoding_deflate.c is now always built (it was CHD-only), and a
  static build adds it with encoding_crc32 and features_cpu whether
  or not CHD is on.
- test_harness.c: kitty preview compression through rdeflate. Output
  checked to decode with zlib, including incompressible input against
  the buffer bound.
- Makefile/Makefile.common: drop the zlib sources, SYSTEM_ZLIB,
  DEPS_DIR and -I$(DEPS_DIR).

tools/embed_boot_rom.py still uses Python's zlib module to make
opera_boot.h; that is a build-time tool, not a dependency of the core.
2026-10-28 20:21:04 +01:00
LibretroAdmin 00805de892 libretro-common: sync from RetroArch
Bring every libretro-common file the core builds up to RetroArch
61606d92b8b026106b51f75365bea592a6fb94b9. 34 files had drifted, including rchd (now accepts
version 5 hunks up to 1 MiB, the largest chdman writes) and
chd_stream, which now reads through vfs_prefetch.

New files the synced sources need: vfs/vfs_prefetch.c and
encodings/encoding_xxh64.c (with their headers), built with HAVE_CHD.

Dropped what nothing builds or includes any more:
streams/file_stream_transforms.c and its header (the core never calls
rfopen/rfread and friends) and the libchdr headers (the core always
reads CHDs with rchd).

tools/chd/run.sh: drop memmap/memmap.c, which the repo does not carry
(the script could not build), and add the new sources plus
retro_eventcount.c that vfs_prefetch needs with threads.
2026-10-28 20:20:53 +01:00
Antonio SJ Musumeci 370d9a25c0 Fix VDL zero persistence and retained-next field transfers 2026-10-23 14:23:15 -05:00
Antonio SJ Musumeci 2d03e48495 Fix audio DMA cursor when restarting input transfers
Crash 'n Burn (USA, Not for Resale) played character-selection speech ahead
of its video after loading the supplied state and pressing B.

The state retained input DMA channel 7's consumed-byte cursor at 8,112.
When the game programmed the next sample's current address as 0x002e753c,
Opera replaced the buffer base but left that cursor intact. Actual reads
therefore began at 0x002e94ec, skipping the first 8,112 compressed bytes of
the new speech sample.

The game's half-rate mono SDX2 stream consumes 22,050 compressed bytes per
second, so the skipped data advances speech by 367.891 ms. Its movie
player advances pictures from the graphics VBL counter independently of
the audio cursor, exposing the mismatch as lip-sync error.

Reset the selected input channel's cursor whenever its current DMA
address is written. Apply the register semantics to every input channel,
without a title-specific or savestate-specific workaround. Updating only
the next-buffer address still leaves the current transfer untouched.

Replaying the supplied state for 1,200 fields with the correction kept all
600 captured video frames unchanged and corrected the predicted audio
offset of 16,224 output frames at 44.1 kHz. The production replay matched
the diagnostic cursor-reset reference exactly in both pictures and PCM.
2026-10-22 21:45:34 -05:00
Antonio SJ Musumeci 3b346384fc MADAM: hold SPRON for the CEL engine's rendering time
AutoBahn Tokio (Japan) could appear frozen at the end of its unattended
attract race. Its animation advances by counting rendering iterations,
while a separate attract timer determines when the sequence ends.
Instantaneous CEL completion let the animation finish too early, then
repeatedly redraw its final scene until that timer expired. The expensive
redraws made the remaining hold especially slow in wall-clock time.

Keep STATBITS/SPRON busy for an estimated rendering interval after each
list is drawn, so software polling CEL completion cannot submit lists
without consuming emulated rendering time. Estimate work from the greater
of evaluated source texels and written destination pixels, at roughly
9 million work units per second, plus 64 CPU cycles per fetched CCB.
AutoBahn's surface-mapped lists evaluate substantially more source texels
than they write pixels; counting only writes still finishes its animation
too early.

The observed attract sequence now continues its ending animation through
the credits and fade and returns to the title screen. Native and HiRes
rendering share native-resolution timing accounting, and state loading
preserves whether a list still needs drawing or is only waiting for its
busy deadline. Legacy states retain their pending-list convention.

This also changes pacing in Casper and other games that depend on CEL
completion instead of an independent frame limiter. Casper comparisons
showed a reduced render/present cadence while video refresh remained
constant; that is a broader timing impact, not a separately established
Casper bug fix.

The busy interval is an approximation. Emulator scene progression and
pacing observations do not establish hardware-calibrated CEL timings.
2026-10-22 21:45:34 -05:00
Antonio SJ Musumeci 39bf0700c1 Fix streaming completion timing on CD-ROM reads and CLIO input DMA
Wing Commander III - Heart of the Tiger (USA, Disc 1) could stall during
its credits or opening movies because streaming completion became visible
at the wrong boundaries.

Publish successful MEI READ_DATA status only after the final requested
byte has left the data FIFO. Reporting success as soon as one sector is
buffered prematurely ends Portfolio's read-ahead command, even while data
from the request remains unread.

Raise CLIO input-DMA completion and reload the next buffer when the final
sample is consumed, rather than waiting for another DSP read. Wing
Commander III can otherwise observe the end address and detach an audio
attachment whose completion has not fired. Once the instrument stops,
there is no further read to generate completion and playback waits
forever.

During investigation, stock-2x playback advanced through the previously
stuck credits and opening movie sequence to the interactive hangar. This
addresses the observed streaming stalls, not an exhaustive compatibility
claim for every gameplay or disc-transition path.

Also default CD-ROM speed to the stock 2x rate in both option definitions
and the missing-option fallback. This affects all titles using the
default; explicit unbounded and other saved speed selections remain
available and unchanged.
2026-10-22 21:45:34 -05:00
Antonio SJ Musumeci 684926fe20 Embed Opera Boot as the default BIOS
Store the ROM as a compressed static blob and load it directly into
ROM memory. Keep Opera Boot first and default in BIOS settings while
preserving external BIOS selection and load errors.
2026-10-12 19:17:46 -05:00
Antonio SJ Musumeci 5a09dc47c1 Emulate ROM-overlay boot, reset semantics, and XBUS DIPIR
- Boot ARM at address zero through a ROM overlay cleared by CPU DRAM
  writes; preserve overlay state with backward-compatible save loading.
- Distinguish power-on, software, and DIPIR resets; preserve hardware
  state and interrupted ARM context, including the SWP return address.
- Latch XBUS media access in CLIO, enforce DIPIR protection, resume
  pending DMA when access returns, and derive enabled interrupt summaries.
- Separate CD-ROM media load/eject from device reset, model local reset
  transitions, and defer ODE media access until the launch response drains.
- Let the boot ROM initialize the display; remove synthetic boot-memory
  and startup VDL seeding.
2026-10-11 18:25:29 -05:00
LibretroAdmin ee0273a8f6 cuefile: include compat/msvc.h for snprintf
MSVC before 2015 has no snprintf; compat/msvc.h maps it to the
c99_snprintf_retro__ implementation in compat_snprintf.c.
2026-10-09 18:04:50 +02:00
LibretroAdmin 38cec61acf cuefile: bound path copies to their buffers
The CUE FILE entry is joined onto the directory of the content path with
snprintf, and every copy into the fixed STRING_MAX buffers goes through
strlcpy/strlcat, so an over-long path or FILE line truncates instead of
overrunning the stack.
2026-10-09 12:40:47 +02:00
LibretroAdmin fa313b75bc Drop memmap.c from the build
Nothing in the core calls into memmap.c: file_stream maps files through
vfs_implementation, which takes mmap() from the system headers. The
synced copy carries memshm_create, which needs shm_open/shm_unlink from
librt on glibc older than 2.34, so linking it with --no-undefined fails
on the xenial build lanes.
2026-10-09 12:40:44 +02:00
libretroadmin 85e45d084f Lock-free DSP thread on libretro-common; trim libretro-common
The threaded DSP takes no mutex or condition variable. The emulation
thread publishes a monotonic tick count with a release store and wakes
the DSP thread through a retro_eventcount once per 32 ticks and at
frame end; the DSP thread runs every posted tick and writes samples
into a retro_spsc ring that upload hands to the frontend in place.
Mode switches keep samples in order, and the thread runs out every
posted tick before it exits. THREADED_DSP defines HAVE_THREADS and
builds the eventcount and SPSC sources.

libretro-common is synced with RetroArch master and holds only the
sources the core builds and the headers they and the core include;
rstrtod.c is built since file_stream needs it.
2026-10-08 07:42:18 +02:00
Antonio SJ Musumeci 787c1dce03 Fix expanded memory configuration and SPORT handling
Address both VRAM banks and correct SPORT mask semantics, including
high-resolution plane preservation. Validate configured and saved
memory layouts, and propagate allocation failures through core
initialization and reset.

Keep the 22 MB backing allocation and state formats unchanged. Add
memory regressions and document panafz1 boot compatibility without
patching the BIOS.
2026-10-08 00:01:24 -05:00
LibretroAdmin ea60917d7f chd: decode zstd hunks
The CHD build selects rchd's zstd codec alongside DEFLATE, LZMA and
FLAC and compiles encoding_rzstd.c, so images compressed with cdzs or
zstd read like any other. rchd, chd_stream, encoding_rzstd,
encoding_deflate and compat/intrinsics.h are resynced from RetroArch.

tools/chd/run.sh compresses a synthetic two-track image with each CD
codec chdman offers and checks every sector against the CUE it came
from, raw and cooked, under ASan and UBSan.
2026-10-03 06:18:03 +02:00
LibretroAdmin a501a278d0 Makefile: put libctru on the include path for the ctr target
The CHD path adds features_cpu.c to SOURCES_C whenever
STATIC_LINKING is set, and on _3DS that translation unit reaches
for <3ds/svc.h>, <3ds/os.h> and <3ds/services/cfgu.h> for
svcGetSystemTick, osGetTime and CFGU_GetSystemModel. Nothing else
in the core touches a libctru header, so the ctr block never
carried an include directory for one and the compile stops at the
first #include.

Point INCFLAGS_PLATFORM at $(CTRULIB)/include, defaulting CTRULIB
to $(DEVKITPRO)/libctru so the target builds both under
libretro-super, which exports CTRULIB, and in a bare devkitARM
container, which only exports DEVKITPRO.
2026-08-21 11:56:39 +02:00
LibretroAdmin 3889176d85 Merge pull request #285 from trapexit/vfs
Update libretro-common and adopt RCHD
2026-08-21 11:18:13 +02:00
Antonio SJ Musumeci f36833d57b Update libretro-common and adopt RCHD
- Refresh the vendored libretro-common tree to the pinned upstream snapshot.
- Replace CHD stream integration with VFS-backed RCHD decoding and per-track logical maps.
- Build the RCHD and RFLAC codec closure and remove obsolete libchdr and LZMA dependency trees.
- Negotiate frontend VFS v3 for file, path, and directory access with legacy fallback.
- Preserve mixed-track gaps, raw-sector offsets, and native CD-DA sample order.
2026-08-20 19:51:11 -05:00
Antonio SJ Musumeci 636a8dd634 Rename test harness executable 2026-08-04 22:55:20 -05:00
libretroadmin 0e9562eb2e For now we need to bake zlib in even for statically linked targets 2026-07-27 03:32:38 +02:00
Antonio SJ Musumeci 74dd2a8c63 Add deterministic PRNG seed controls 2026-07-23 20:38:46 -05:00
Antonio SJ Musumeci 5a4eb964e6 Clamp literal cel width after SKIPX
- Compute the source width before applying projection state.
- Treat SKIPX values that exhaust the span as empty draws.
- Preserve height-based CCB position advancement for skipped spans.
2026-07-18 02:29:44 -05:00
Antonio SJ Musumeci 278d179e11 Handle common unsupported retro environment commands 2026-07-18 02:29:44 -05:00
Antonio SJ Musumeci 1edda8a2a6 Print out additional details from harness 2026-07-13 16:42:36 -05:00
Antonio SJ Musumeci 7dd464b6a1 Fix improper SKIP_X subtractions 2026-07-13 12:13:27 -05:00
Antonio SJ Musumeci a52315ea83 Add Kitty and Sixel terminal rendering
Add image-protocol terminal renderers to the test harness with Kitty
and Sixel capability probes, renderer metrics, frame caching, and
resize/exit cleanup.
2026-07-13 12:13:27 -05:00
Antonio SJ Musumeci c95a315186 pbus: fix reload with retail lightgun
Games like Mad Dog McCree
2026-07-09 23:07:20 -05:00
Antonio SJ Musumeci 80d871b4bd pbus: fix orbatak silly pad to 24-bit and split trackball/buttons 2026-07-09 23:07:20 -05:00
Antonio SJ Musumeci 340f9e9014 Add terminal mode and artifact capture options
- Add live terminal framebuffer mode with keyboard input, rendering/color controls, adaptive redraw, and graceful quit/signal handling.
- Switch screenshot artifacts to PNG via stb_image_write, including periodic and filtered screenshot capture metrics.
- Add WAV audio capture controls, input-file support, BIOS listing, Makefile linkage, and opera-test-harness skill documentation.
2026-06-28 22:16:02 -05:00
Antonio SJ Musumeci eb3a9162e9 Add test harness for headless testing
- Add tools/test_harness.c with comprehensive test infrastructure
- Add Makefile harness target and build rules
- Update .gitignore to exclude test-harness binary
2026-06-19 19:09:21 -05:00
Antonio SJ Musumeci 78f834b175 ARM: update shifter carry for immediate rotates
Fixes Lost Eden
2026-06-15 20:25:44 -05:00
Antonio SJ Musumeci 8f77c80b39 MADAM: handle literal LRFORM rows
LRFORM describes the interleaved row-pair memory layout used by Opera
bitmaps. Adjacent vertical pixels are stored together, so literal
LRFORM CELs have VCNT values that count row pairs and source reads
that alternate between the two halfword lanes.

Although this layout is most commonly used for 16-bpp bitmap
extraction, games can apply lower-depth literal CELs to LR-format
bitmap-derived data. AITD2 uses a 1-bpp LRFORM priority mask to select
where foreground scenery is copied back over actors. Treating LRFORM
as 16-bpp-only leaves that mask at half height and decodes the wrong
row lane for the lower half.
2026-06-14 14:31:58 -05:00
Antonio SJ Musumeci 64f35570aa MADAM: ignore bottom 2 bits in CCB processing
The bottom two bits of the address bus aren't even wired up to
MADAM. Most titles use properly aligned addresses but not all. This
patch ensures the pointers read from the CCB and the CCB address
itself are masked to align them to word boundry.

Fixes Ballz and possibly other titles that had unaligned addresses.
2026-06-13 23:52:15 -05:00
Antonio SJ Musumeci 5ce402e62f MADAM: fix MARIA texel rendering 2026-06-13 18:58:54 -05:00
Antonio SJ Musumeci a51a91ac20 Remove compatibility hack plumbing 2026-06-13 13:29:34 -05:00
Antonio SJ Musumeci 1ae57d5b3a MADAM: fix REGCTL stride decoding
Fixes DinoPark Tycoon
2026-06-13 13:29:34 -05:00
Antonio SJ Musumeci bf2fd152b8 MADAM: Fix CEL PIXC PDC_MFONLY blending rendering
- Determine decoder transparency before blue-LSB substitution.
- Use decoded PDC multiplier bits for PDC_MFONLY PIXC processing.

Fixes text rendering in early credits scene in Alone in the Dark.
2026-06-13 13:29:34 -05:00
Antonio SJ Musumeci 1ec8b0cdc7 Remove Timing Hack 6 compatibility option
- Remove the FIX_BIT_TIMING_6 flag and LR CEL framebuffer-read branch.
- Drop the opera_hack_timing_6 core option from v1 and v2 definitions.
- Stop parsing hack_timing_6 into the emulator hack flags.
2026-06-13 13:29:34 -05:00
Antonio SJ Musumeci 165857cb6e MADAM: properly emulate YOXY CEL feature
- Correct CEL XYPOS, LINEDXY, and DXY register mapping.
- Retain and advance CEL origin for YOXY=0 chains.
- Remove the graphics_step_y compatibility hack option.

Fixes Samurai Shodown.
2026-06-13 13:29:34 -05:00
Antonio SJ Musumeci 665a922fc7 MADAM: include arbitrary CEL span endpoint
Arbitrary CEL rendering treated computed horizontal span endpoints as exclusive. When adjacent skybox CELs met on integer x boundaries, neither CEL covered the shared column, leaving the SPORT clear color in the frame buffer and producing vertical seams in NFS.

Include the right endpoint before clipping arbitrary CEL spans so shared boundaries are overwritten by CEL pixels instead of preserving stale clear-color columns.
2026-06-12 23:38:45 -05:00
Antonio SJ Musumeci 67feb48bfd arm: set ARM60 N-cycle timing to two S-cycles
- Change NCYCLE from 4 to 2 for uncached ARM60 timing.
- Document the timing rationale and source references.
2026-06-10 14:10:48 -05:00
Antonio SJ Musumeci 4f5e5b453a DSPP: return CPU-supplied DSP FIFO values
CPU writes to EI FIFO-head addresses 0x70..0x7c set CPUSupply and latch the
supplied word in EIRAM. When the DSP later reads the normal input FIFO window
at 0xf0..0xfc, consume that latched word instead of returning PRNG data.

The random source is the separate DSPP noise register. Using it for a valid
CPU-supplied FIFO read injects spurious samples, causing startup pops in
Flashback sound effects such as footsteps.

Source:
- WO 94/16383, PDF pp.17-18: 0EAh is the pseudorandom noise generator, 0F0h
  through 0FCh are input FIFOs, and 070h through 07Eh read the corresponding
  input FIFOs without removing the input word.
- WO 94/16383, PDF pp.25-26: EI FIFO reads refill EIRAM from the corresponding
  FIFO, and the EI FIFO control unit also receives direct host CPU input.
- Portfolio OS src/audio/audiofolio/dspp_addresses.h: DSPP_FIFOHEAD_ZERO_ADDRESS
  is 0x0070 and DSPI_NOISE is 0x00EA, separating FIFO-head data from the noise
  register.
- Portfolio OS src/audio/audiofolio/dspp_touch_anvil.c: dsphResetFIFO() clears
  DSPP_FIFOHEAD_ZERO_ADDRESS + DMAChan in EI memory to reduce pops.
2026-06-09 19:49:13 -05:00
Antonio SJ Musumeci 5e36d4a9fb Narrow the new C&B hack
Caused problems booting BIOS and certain titles.
2026-06-09 00:05:46 -05:00
Antonio SJ Musumeci 72fa9a33c1 Replace Crash & Burn hack with more generic workaround 2026-06-08 11:35:33 -05:00
Antonio SJ Musumeci 899ef5ea8b Replace misc literals with #defines for clarity in MADAM 2026-06-06 15:51:48 -05:00