================================================================================
madsim - the MAD-65 simulator, v1.0.3
Runs MAD-65 software on a Windows PC
Release date: 2026-09-03
visit: https://mad65.codepainters.com/software/madsim.html
================================================================================

ABOUT

madsim simulates a whole MAD-65 console: both 65C02 processors, the video
circuit, the two SN76489 PSGs and the YM2413 FM chip, and the two joystick
ports. It runs the real firmware ROMs and real cartridge images, so software
that runs here runs on the hardware.

The simulation is paced to the true MAD-65 frame rate of 60.317 Hz, independent
of your monitor's refresh rate. Set your monitor to 60 Hz for the smoothest
result.


PACKAGE CONTENTS

  madsim.exe          the simulator
  roms\cpu_os.bin     MAD-65 firmware, CPU  - V0.9, build 260903
  roms\gpu_os.bin     MAD-65 firmware, GPU  - V0.9, build 260903
  README.txt          this file


RUNNING IT

  Windows. No installation. Unpack the archive and run madsim.exe.

  Run it from the folder it was unpacked into: it looks for the roms\ folder
  next to itself and loads the firmware automatically.

  With no cartridge, the machine boots into the built-in diagnostic demo. The
  demo exercises the sound chips, vector graphics, scrolling text and the
  joystick ports, and prints the build date of both ROMs. If it runs, your
  setup is correct.

  To run a game, drop its cartridge image next to madsim.exe as cart.bin, or
  point at it explicitly:

      madsim.exe --cart mygame.bin


COMMAND LINE OPTIONS

  --cpu1 <FILE>          CPU1 system ROM (16 KiB, $C000-$FFFF).
                         Omitted: auto-discovers cpu_os.bin
  --gpu <FILE>           GPU ROM (16 KiB, $C000-$FFFF).
                         Omitted: auto-discovers gpu_os.bin
  --cart <FILE>          Cartridge image, a multiple of 8 KiB banks, mapped at
                         $8000-$9FFF and bank-switched via $BF60.
                         Omitted: auto-discovers cart.bin
  --scale <N>            Integer window scale (window = 400*N x 300*N)
                         [default: 2]
  --dump-dir <DIR>       Directory for the state dumps written by F2
                         [default: dumps]
  --meter                Start with the utilization meter shown
                         (hidden by default; toggle with F3)
  --pause                Start paused (resume with Space or P)
  --tate                 Start with the screen already turned 90 degrees
                         clockwise, opening the window at the rotated aspect
                         rather than turning it afterwards. F12 still toggles
                         it at runtime
  --audio <on|off>       Audio, on by default. Use --audio off to run silent
  --wait-states <N>      Wait states charged on each slow (EPROM / cartridge)
                         read. 3 is what the hardware does; 0 gives a
                         no-wait-state baseline to measure the cost against
                         [default: 3]
  -h, --help             Print help
  -V, --version          Print version


KEYBOARD

  Joystick 1:  Arrow keys      move
               Right Ctrl      FIRE
               Right Shift     2ND FIRE

  Joystick 2:  W A S D         move
               Left Shift      FIRE
               Left Ctrl       2ND FIRE

  Esc          quit
  Space / P    pause / resume both CPUs
  F2           dump full machine state to the dump directory (developer info)
  F3           toggle the on-screen utilization meter (developer info)
  F5           reset - hardware-style /RESET, restarts both CPUs
  F8           cycle the display filter:
               plain -> B/W CRT -> green phosphor -> amber -> blue phosphor
  F11          toggle borderless fullscreen
  F12          rotate the screen 90 degrees clockwise - the monitor stood on
               its side, for MAD-65's vertical (TATE) mode, which firmware
               V0.9 supports. Press again to restore. In the CRT modes the whole tube turns,
               scanlines and curvature included
  M            mute / unmute audio
  -  and  =    music/SFX mixer knob: '-' turns toward music, '=' toward sound
               effects, centre is an equal mix. Music is SN76489 #1 plus the
               YM2413, SFX is SN76489 #2 - the MAD-65's own static split


GAMEPADS

  A USB gamepad is picked up automatically. No configuration, no flags.

  The first pad connected drives joystick port 1, a second one port 2. Unplug
  a pad and its port falls back to the keyboard; both sources are OR-ed, so
  they can be used together. Hot-plugging works while the simulator runs.

    D-pad and left analogue stick        directions
    Vertically opposed face buttons      FIRE
      (A/Cross, Y/Triangle)
    Horizontally opposed face buttons    2ND FIRE
      (X/Square, B/Circle)

  Each fire line is wired to both buttons of its pair, so it does not matter
  which of the two your thumb lands on. The right stick is deliberately
  ignored.

  A PS1/PS2-to-USB adapter must be in ANALOGUE mode - press the pad's ANALOG
  button, LED on. In digital mode the pad reports its right stick as the four
  face buttons and its D-pad as the left stick; those are the same signals real
  button presses use, so nothing downstream can tell them apart and the right
  stick appears to fire.


THE UTILIZATION METER

  F3 shows how much of each frame CPU1 and the GPU actually used, plus the
  percentage of time each spent stalled on wait states. It is the quickest way
  to see whether a game is running out of frame budget on real hardware.


SCOPE

  - The frame model is sequential per frame: CPU1 runs a full frame, then the
    GPU, then the VSYNC swap. This is correct because the two processors only
    ever talk through the ping-pong shared RAM, which swaps at the frame
    boundary.
  - Video is a per-frame snapshot taken at VSYNC. madsim does not model
    mid-scanline raster timing; for register tricks inside a frame, use the
    gate-level Verilator simulator in the MAD-65 sources.
  - Audio register writes are captured per CPU cycle and replayed at sample
    resolution, so note timing within a frame does not smear. The SN76489
    model is faithful but not gate-level; the YM2413 is the emu2413 reference
    emulator.


CHANGELOG

  v1.0.3 - 2026-09-03
    - Fixed PLA, PLX and PLY not setting the N and Z flags from the pulled
      byte, as a real 65C02 does. Code that branches on the result of a
      stack pull (a common shape in RLE/control-byte decoders) could take
      the wrong branch about half the time.
    - Fixed an IRQ pushing a stale B flag instead of a clear one, so
      firmware that tells BRK from IRQ by that bit now reads it correctly.
    - The CPU core moved to a vendored, patched copy (upstream has no fix
      available), with a new flag-semantics test suite covering the pulls,
      transfers, loads, arithmetic and shifts.

  v1.0.2 - 2026-08-22
    - --tate starts the simulator with the screen already rotated, so the
      window opens at the rotated aspect instead of being turned afterwards.
      F12 still toggles it while running.
    - The utilization meter now follows the display rather than the picture:
      it comes out upright in the top-left corner in both orientations,
      instead of sideways when the screen is rotated.

  v1.0.1 - 2026-08-19
    - USB gamepad support: first pad connected drives port 1, a second one
      port 2, with hot-plugging and no configuration.
    - F11 toggles borderless fullscreen.
    - F12 rotates the screen 90 degrees clockwise, for MAD-65's vertical
      (TATE) mode. In the CRT modes the tube itself turns, so the
      scanlines and curvature turn with it.
    - Keyboard and gamepad are tracked separately and OR-ed per port, so
      releasing a direction on one device no longer cancels a direction still
      held on the other.

  v1.0.0 - 2026-07-15
    - The v6 architecture: shadow code-RAM on both CPUs, with the $BF70
      SHADOW_REG and the GPU's VIDEO_REG bit 3.
    - Wait-state accounting. Only reads stall, and after boot only the
      cartridge path stays slow; the meter reports a stall percentage
      alongside each CPU's figure.

  v0.11.0 - 2026-07-13
    - Music/SFX mixer knob on '-' and '='.
    - Configurable CRT background colour.

  v0.10.1 - 2026-07-07
    - YM2413 level balanced against the two PSGs, so the OPLL no longer
      swamps them.

  v0.10.0 - 2026-07-03
    - Optional CRT filter: curvature, scanlines, glow, vignette and a phosphor
      tint. F8 cycles plain, B/W, green, amber, blue.

  v0.9.7 - 2026-06-27
    - cart.bin is auto-discovered in the default ROM search paths.
    - The utilization meter is hidden by default; --no-meter became --meter.

  v0.9.5 - 2026-06-22
    - Second fire button, the Amiga-style second fire on DE-9 pin 9: Right
      Shift for port 1, Left Ctrl for port 2.

  v0.9.4 - 2026-06-19
    - F5 hardware-style /RESET. RAM and VRAM survive, as on real silicon; the
      audio chips are silenced so a stuck tone cannot outlive the reset.

  v0.9.3 - 2026-06-18
    - Input lag substantially reduced.

  v0.9.2 - 2026-06-16
    - LED diagnostic latches surfaced on the title bar, used by the firmware
      for POST progress.

  v0.9.0 - 2026-06-13
    - Initial release: both CPUs, the v5.2 memory map, monochrome 400x300
      double-buffered video with the hardware background copy, full audio,
      the per-CPU utilization meter and 60.317 Hz frame pacing.

================================================================================
