Skip to content

Latest commit

 

History

4,350 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Casso

CI License: MIT

Casso is a retro platform emulator, 6502/65C02 assembler, and disk manager, written in C++ with hardware-accelerated DirectX rendering and a multithreaded core.

It's your retro Swiss Army knife.

Today it emulates the Apple II family:

  • Apple ][
  • Apple ][+
  • Apple //e
  • Apple //e Enhanced
  • Apple //c

On the horizon:

  • Apple IIgs
  • Atari 400/800
  • Commodore VIC-20, 64

The casso-rocks demo disk asks which monitor you have and draws the cassowary for it: a color screen groups the same double hi-res framebuffer into 16-color cells, a monochrome one shows all 560 dots, and an image authored for either reads as noise on the other. Here it is in all three built-in themes:

The Skeuomorphic theme on an Apple //e: the casso-rocks demo on a modeled desk with Monitor II switched to color, the cassowary in 16-color double hi-res
Skeuomorphic on the //e
The Skeuomorphic theme on an Apple //c: a Monitor //c over two Disk IIc drives, the cassowary dithered to one bit in green phosphor
Skeuomorphic on the //c
The Retro Terminal theme: the same demo in green phosphor with heavy scanlines and bloom, under green-tinted chrome
Retro Terminal on green
The Dark Modern theme: the same demo on an amber monitor under flat dark chrome, the cassowary dithered to one bit across all 560 dots
Dark Modern on amber

Switching machines swaps the whole modeled stack. Themes hot-swap from Settings → Theme with no restart and no machine reset, and full screen is the picture alone. See Themed chrome.

CassoCli accelerates the retro development loop, with no need for third-party tools:

  • Assembler — from-scratch, AS65-compatible, and assembles Merlin; ca65 next
  • Disk management — create, initialize, catalog, read and write files, logical or physical sectors, and ProDOS blocks, across .woz, .dsk, .do, .po, .nib and .nb2
  • Headless execution — assemble and run 6502 code with no GUI
  • Launches the emulator — with a machine and disks already selected

Contents

What's New

The last few releases, in brief. CHANGELOG.md has the granular history, and ARCHITECTURE.md covers the emulator's internals.

[2026-10-03 · 1.30] WOZ 2.1 flux support—great Scott!

Casso now supports WOZ 2.1 flux tracks. A flux track holds the timing of every magnetic transition instead of a stream of bits, which is how Applesauce preserves copy protection that depends on that timing. Flux tracks play back at their recorded timing, and at the same speed as bit tracks. Support is validated with Bandits, Minotaur, Fly Wars, Cyclod, Lemmings and Jellyfish. Saving a disk with flux tracks leaves the tracks that weren't written to unchanged.

WOZ disks with flux tracks can also be created in the create dialog or with CassoCli disk create --flux. The disk create command can mix bit and flux tracks on one disk.

Casso now mounts a WOZ disk with unreadable tracks read-only, so the rest of the disk can be read, and offers to salvage it. Previously the disk failed to mount.

[2026-09-29 · 1.29] Controllers Just Work™

Setting up controllers is now much simpler. Controllers are assigned to Player 1 and Player 2 automatically, in the order you connect them or the order you first use them. Player 2's controller works the same way as Player 1's unless you pick otherwise: as a joystick, one or two paddles, or an Atari joystick on the other jack of the Sirius Joyport. In Joyport mode, every stick, D-pad and fire button on the controller is mapped for you, so two Xbox controllers can play a two-player Joyport game with no setup at all.

Profiles are now saved per input mode, so each controller keeps its own joystick, paddle and Joyport setups, and switching between them no longer means remapping. One controller's sticks or D-pad can work as separate paddles if you like, and controllers, joysticks and flight sticks with a throttle or slider now work like a real paddle's knob. The Controllers page also shows more responsive views of sticks, paddles and buttons, and we may have snuck in an amusing surprise or two there too.

The Controllers page in Settings with one Xbox One S controller in Two paddles mode: its left stick X on PDL0 and right stick X on PDL1, each with a Paddle speed slider at 768/s and a live bar beside it at 206 and 76, with the A and B buttons on PB0 and PB1
Two paddles on one controller
The Controllers page in Settings for two players, both on Automatic: the Xbox Series X|S controller for Player 1 in Joystick mode and the Xbox One S controller for Player 2, whose mode follows Player 1 as Automatic (joystick), with the Series X|S left stick on PDL0 and PDL1 and its live stick readout off center
Two players, assigned automatically
The Controllers page in Settings with the Sirius Joyport: Player 1 on Automatic with the Xbox Series X|S controller on the left jack, and Player 2 on Automatic with the Xbox One S controller, which resolves to the right jack. The left stick, right stick and D-pad all drive left/right and up/down, a scrolling list of buttons and triggers fires, and a top-down drawing of an Atari joystick lights its right marker
Two players on the Joyport
The toolbar's controller picker on the Apple //e desk scene with Lode Runner running: a submenu for each player, and Player 1's submenu open under three headings, Controller with Automatic, the Xbox Series X|S controller, the Xbox One S controller checked and keys as a joystick, Mode with Joystick checked above the two Joyport jacks, Paddle and Two paddles, and Profile with Default checked and New... at the bottom
Controller, mode and profile on the toolbar

[2026-09-19 · 1.26] A real installer

Casso installs from an MSIX package, which adds it to Start and puts casso and cassocli on PATH.

[2026-09-06 · 1.23] It finds its voice

The Mockingboard's SSI 263A is synthesized from the chip's registers rather than played back from recordings, and this release is where that synthesis stopped approximating and started matching. Measured against a recording of real silicon, mean error across six bands falls from 9.9 dB to 4.9 dB. What changed:

  • Speech ran 75% too slow. Every line now plays at the tempo the chip actually produces, so speech in any title that uses the board is faster and higher than it was.
  • The voice had no fundamental, which left it thin and tilted bright across the whole vowel range. It now falls away from the fundamental the way the real chip does.
  • Voiced fricatives came out as sonorants, so Z sounded like L. The two are properly distinct now.
  • Fricatives were harsh and the voice too bright throughout. Both are matched to the real chip's balance.
  • Speech interrupts reached the wrong support chip, where an interrupt-driven speech driver would never find them.
  • Powering the chip down clicked, so every spoken line ended on a pop.

A speech demo disk ships with it. Boot Apple2/Demos/mockingboard-speech-demo-dhgr.dsk for three film lines and Daisy Bell, spoken and sung under a HAL 9000 panel whose eye pulses on each syllable and holds through a sung note. Each character gets its own articulation. There is a hi-res version of the same demo beside it, and mockingboard-speech-test.dsk is the smaller smoke test.

The speech demo on the Apple //e desk scene: a HAL 9000 panel in double hi-res, its eye lit orange to a white center, with the caption DAISY DAISY and the legend MOCKINGBOARD SPEECH CHIP

Singing is the part that cannot be faked. An emulator that plays recorded phonemes can say the words, but only one that synthesizes from the registers can put them on a melody, because pitch is the 12-bit inflection value and not a property of a recording.

Source to a running machine, without leaving the command line. The assembler can now emit an assembled binary directly into a disk image, make that image bootable, and insert it into the emulator. Casso detects and responds to external modifications of a mounted image automatically, so a build reaches the running guest with no eject and re-insert. Where both sides have changed the same disk it has a good deal of machinery to make sure nothing is lost. For details, see One source, one image and Building into a disk Casso already has open.

Screenshots now save to a PNG as well as going to the clipboard, in Pictures\Casso Screenshots. You choose whether a shot is of the whole desk scene, the screen with its CRT effects applied, or the raw picture at its native resolution.

The command bar offers quick access to the things you change most: full screen, theme, and monitor color. In full screen the menu bar, command bar and drive widgets all hide and slide back into view when you reach for them. The menu bar is new to that reveal, having previously stayed out of reach behind the toolbar, and the whole behavior now works in every theme rather than only on the desk scene.

The flat themes get a richer drive widget. Its activity LED shows where the head is sitting on the disk rather than only that the drive is busy, and the disk name is itself the control: click it to eject and pick another, which used to mean a trip to the Disk menu.

Startup dropped from about twenty seconds to under one, and the executable is about 80% smaller, by prebuilding the object meshes, optimizing tessellation and precompiling the shaders.

Earlier releases

Each links to its full write-up in docs/WhatsNew.md.

Date Release Highlights
2026-09-25 1.28 Sirius Joyport
2026-09-24 1.27 Separate controller profiles for each player
2026-09-16 1.25 Game controllers and joysticks
2026-09-10 1.24 The //e's own character ROM, Applesoft round-trip fixes, and a faster //c startup
2026-08-31 1.22 Nibble images (.nib, .nb2), and disk decoding up to 100x faster
2026-08-29 1.21 A real-time 3D desk scene: period monitors and drives modeled in CAD, lit and shadowed
2026-08-27 1.20 CassoCli disk: make disks and move files on and off them, and AS65's exact command line
2026-08-27 1.19 The Mockingboard speaks, driven by the SSI 263A's own ROM read off the die photographs
2026-08-25 1.18.1 Monochrome monitors show all 560 dots of double hi-res
2026-08-21 1.18 Merlin source assembles unmodified, verified against the Merlin Pro disk
2026-08-20 1.17 Salvage a damaged .woz into a structurally correct copy
2026-08-10 1.16 Create blank, bootable disks in the app, and a write-protect toggle
2026-07-28 1.15 MousePaint works again on the //c
2026-07-26 1.14 An emulated ImageWriter II with a live 3D preview and real print-head sound
2026-07-25 1.13 Emulation and rendering performance
2026-07-22 1.12 The first skeuomorphic CRT monitor
2026-07-19 1.11 The stable undocumented 6502 opcodes, validated against Harte
2026-07-18 1.10 The //c's 80/40 and keyboard switches
2026-07-16 1.9 Write-protect indicator
2026-07-15 1.8 The Apple //c and //e Enhanced, on a new 65C02 core
2026-07-12 1.7 Mockingboard sound card
2026-07-08 1.6.2 Reliable disk writes
2026-07-07 1.6 Disk picker search, and the Dxui UI library
2026-06-03 1.5.1523 Play action games from the keyboard, with hardware-faithful auto-repeat
2026-05-30 1.5.1395 Themed first-run downloads
2026-05-30 1.5.1289 Copy-protected Broderbund games boot from unmodified images
2026-05-26 1.4.1171 Themed chrome, CRT effects, and skeuomorphic drives
2026-05-15 1.3.670 Disk II mechanical audio
2026-05-09 1.3.509 Apple //e fidelity: aux RAM, the Language Card, and a cycle-accurate Disk II
2026-05-03 1.0.244 The first GUI emulator, for the Apple ][, ][+ and //e
2026-04-28 0.9.32 An AS65-compatible assembler, and a Harte-validated 6502
2024-11-24 My6502 Where it started: a 6502 emulator

Features

Machines

Apple ][, ][+, //e, //e Enhanced, and //c, from data-driven machine configs in Machines/<Name>/<Name>.json. The //e brings 80-column text, auxiliary RAM, and an audit-correct Language Card state machine; the //e Enhanced and the //c run a 65C02. The //c models its slotless phantom-slot firmware map, the built-in IWM drive plus a connectable external one, dual 6551 serial ports, and the //c mouse driven by the machine's own mouse firmware. Its two latching case switches are modeled on a control strip: 80/40 drives $C060, and the keyboard switch flips the typed stream to Dvorak.

On first launch Casso fetches the ROMs and Disk II audio samples it needs, with your consent, and its boot disk picker offers the DOS 3.3 System Master and ProDOS Users Disk, downloaded from the Asimov archive when picked, so a fresh Casso.exe boots to a usable BASIC prompt with nothing installed by hand. Machines/ and Devices/ are fully runtime-managed — delete either and the next launch rebuilds it.

CPU

All 56 standard 6502 mnemonics plus the 65C02 set, and the stable undocumented NMOS opcodes (SAX, LAX, DCP, ISC, SLO, RLA, SRE, RRA and the NOP family). Cycle-accurate IRQ/NMI infrastructure. Validated against Klaus Dormann's functional test suite (full pass) and Tom Harte's SingleStepTests, which check both what every instruction computes and what it costs in cycles. The vectors are authored elsewhere, which makes them an independent oracle rather than a restatement of our own assumptions. Per-opcode mnemonics, addressing modes, lengths and cycle counts for both cores are in docs/cycle-reference.md, generated from the instruction tables so it describes this build rather than a 6502 in general.

Display

40- and 80-column text, Hi-Res and Double Hi-Res, rendered through D3D11. Color, green, amber, and white monitors each decode for the monitor you picked rather than tinting a color decode — on a monochrome monitor both graphics modes show the full 560 half-dot stream.

Optional CRT effects — scanlines, phosphor bloom, color bleed, persistence trails, contrast and gamma — each independently toggleable with its own sliders. Per-monitor presets seed defaults, themes can override, and your tweaks persist on top of either. The Settings popup gets out of the way as you scrub a control: the panel fades and only the focused control stays opaque, so you can judge every parameter change against live output.

Display tab CRT controls: monitor preset, brightness, contrast, gamma, scanlines, bloom, color bleed, persistence

The CRT monitor that frames the display is one of the CAD models pictured in the 1.21 write-up, lit and shadowed with the rest of the desk scene. It can be turned off with 3D CRT monitor on Settings → Theme, which leaves the drives standing on the desk under a flat picture. Alt+Enter goes full screen: every chrome band hides and the glass fills the screen edge to edge, with the drives available as an overlay strip from the View menu.

Casso full screen: Lode Runner filling the whole display, with only the rounded corners of the glass left of the desk scene

Screenshots land as a PNG in Pictures\Casso Screenshots and on the clipboard at the same time, from the toolbar camera, Edit → Copy screenshot or Ctrl+Alt+C. Three modes pick what a shot is of: the whole scene, the screen alone with its CRT effects, or the raw 560x384 image at native resolution. Each file carries what it was a picture of — machine, monitor, CRT settings and scene pose — in its own metadata, so a render bug dragged into an issue arrives with the settings that produced it.

Themed chrome

Casso's entire UI renders onto the same D3D11 framebuffer that draws the emulator video, through a native Direct2D / DirectWrite pipeline — no third-party UI engine. Three built-in themes (Skeuomorphic, Dark Modern, Retro Terminal) hot-swap from Settings → Theme with no restart and no machine reset. Each ships under Resources/Themes/<Name>/ with a theme.json describing colors, CRT defaults, drive visuals, and other UI tokens; see docs/themes/AUTHORING.md for the authoring surface. The two flat themes keep the chrome to a menu, a toolbar and a slim drive bar, so the picture gets the window; all three are at the top of this page.

Retro Terminal turns the CRT effects up: scanlines at three quarters strength, a wide bloom and color bleed, all still yours to adjust on the Display tab. Here is what that does, on one letter of the demo's title:

A letter of the Retro Terminal title with the CRT effects switched off: flat green strokes with hard edges
effects off
The same letter with the effects on: scanlines cutting through every stroke, and the bloom lighting the scanline gaps next to each lit pixel
effects on

The same pixels, one capture apart, doubled with nearest-neighbor so every screen pixel is a whole block. Nothing else changes: same picture, same phosphor, same brightness. Watch the scanline gaps immediately beside a lit pixel -- that is the bloom, and it is why the strokes look like they are glowing rather than merely striped.

The drives are Disk II models on the desk, the same CAD objects as the monitor, with the DRIVE 1 and IN USE marks, the disk ][ logotype and the cassowary badge molded into the faceplate. An empty drive rests with its door open, as the real one does; mounting a disk swings the door shut on its cantilever, and ejecting swings it open again. The IN USE lamp is a real red light in the shading pass, lit whenever the motor runs. The mounted image's name sits under each drive, and a write-protected disk wears a padlock beside its name, with hover text explaining why it is protected. Click a drive's door to pick an image, or drag one onto the drive.

Two Disk II drives on the desk: Drive 1 loaded with Karateka.woz, its red IN USE lamp lit and a padlock beside the name, Drive 2 empty with its door open

A consolidated Settings sheet holds machine selection and its slots, emulation speed, disk write mode, floppy sound and mechanism, write protect, the theme picker, the CRT controls and printer options, in one non-modal window with full keyboard navigation. Preferences persist to %LOCALAPPDATA%\Casso\UserPrefs.json — global UI state under global, per-machine deltas under machines.

Settings, Machine tab: machine and CPU speed dropdowns, the //e memory map, and the device tree with the slot 1 printer, slot 4 Mockingboard and slot 6 Disk ][ controller

Press F10 to drive the painted chrome from the keyboard: a Tab focus ring walks the menu titles and the drive widgets, and never leaks keystrokes through to the emulated keyboard.

Disks

A Disk II controller that models quarter-track head positioning and the Logic State Sequencer faithfully enough to boot original, copy-protected Broderbund WOZ images straight off the wire — protection schemes and all.

Karateka Choplifter Lode Runner
Karateka on the Apple //e desk scene, the hero squaring off with the first guard Choplifter's title screen on the desk scene, the drive lamp still lit from loading Lode Runner's demo running on the desk scene

.woz (including WOZ 2.1 flux tracks), .dsk, .do, .po, .nib and .nb2 images all mount — drag one onto a drive, pick it from the dialog, or name it on the command line. Casso can create blank disks in-app — DOS 3.3, ProDOS, or unformatted raw media, across WOZ (with bit or flux tracks), DSK, PO and NIB, optionally bootable from the stock masters — and a created disk is usable immediately, with no INIT step.

Create new disk dialog with folder browsing, format and image-type dropdowns, Make-bootable checkbox, and name field

Mounted disks carry a write-protect toggle: WOZ images hold the flag inside the file so it travels with the image, sector formats use the host file's read-only attribute, and a protected disk fails a guest SAVE with WRITE PROTECTED just like the notch tab on real media. Dirty disks flush when the drive motor spins down, so changes survive a crash or a force-quit.

Inserting a .woz checks its integrity. If the checksums are wrong or some tracks can't be read from the file, Casso mounts it read-only to prevent further loss and offers to salvage what it can into a structurally correct copy.

Salvage dialog listing total, verified, recoverable and lost sectors for a damaged disk

Sound

Speaker audio through WASAPI on a dedicated event-driven render thread that keeps the device fed regardless of emulation cadence.

Disk II mechanical audio mixes in alongside it: stereo motor hum, head-step clicks, track-0 and max-track bumps, insert and eject. Per-drive equal-power panning places Drive 1 left and Drive 2 right in two-drive profiles. Contiguous step bursts during DOS RWTS recalibration fuse into a continuous seek buzz instead of N overlapping clicks. Recordings come from the OpenEmulator project, downloaded on first run with consent.

A Mockingboard in slot 4 of the ][+ and //e profiles, built from two clean-room chip cores written off the datasheets: a reusable 6522 VIA and the AY-3-8910 PSG (three tone voices, noise, envelope), with VIA Timer 1 driving the periodic IRQs music players use for tempo. The default is the Mockingboard C — the sound card plus Sweet Micro's speech option — and the A stays selectable. Ultima IV, Skyfox, and Music Construction Set get their real soundtracks back.

Printer

A full Apple ImageWriter II on a parallel card in slot 1, default on the ][, ][+, //e and //e Enhanced. PR#1 lists a BASIC program or CATALOGs a disk in an original 95-glyph dot-matrix font, and The Print Shop prints banners, signs and greeting cards in four-color glory, its command set locked from real byte captures.

Casso at The Print Shop's sign print menu on an Apple //e, beside the live 3D ImageWriter II preview with the printed sign on fanfold paper

Output appears in a live 3D preview — the project's own CAD model — with fanfold paper, tractor-feed holes and perforations feeding out of the platen as you watch. One print-head clock drives the whole illusion: the carriage sweeps bidirectionally at true draft speed laying ink column by column, and the mechanical sound is gated to what the head is actually doing. Any printout delivers three ways without re-printing — Save as PNG, Copy to the clipboard, or Print to a real Windows printer — and the paper stays loaded until you tear it off, so a pending printout survives across sessions.

Input

Analog game I/O via the PREAD timer, and a Map arrows to joystick mode that puts the arrow keys on paddle 0/1 with X / Z on buttons 0/1, so Karateka, Choplifter and Lode Runner play from the host keyboard with no physical stick. The //e keyboard generates hardware-faithful auto-repeat — initial delay, then steady cadence — rather than leaning on host-OS key repeat, so timing-sensitive arrow input behaves the way it did on real hardware. An Input Debug panel (Ctrl+Shift+I) logs host → guest key events, the $C000/$C010 strobe, Open/Closed-Apple state, and synthesized paddle reads.

Physical game controllers (Xbox controllers, gamepads, joysticks and flight sticks) can drive the Apple's paddles and buttons too. Controllers are assigned to Player 1 and Player 2 automatically, and each works as a joystick, one or two paddles, or an Atari joystick on either jack of a Sirius Joyport on the ][, ][+ or //e, with profiles for each configured on the Controllers page in Settings.

Assembler and CLI

CassoCli is a from-scratch reimplementation of Frank A. Vorstenbosch's AS65, intended as a drop-in replacement: macros, conditional assembly, the full expression evaluator, equ/= constants, include, the three-segment model, AS65-style listings, and AS65's command line exactly — values attached to flags, flag concatenation, -x for the 65C02, and exit codes 0 through 3 carrying the meanings the AS65 manual gives them.

It also assembles Merlin (Glen Bredon's Merlin Pro), in the absolute subset that needs no linker, verified byte-for-byte against six objects from the Merlin Pro 2.23 distribution disk. A dialect is a directive table and a line model behind one profile seam, sharing the two-pass engine, expression evaluator and opcode tables — so the next dialect is a profile, not a second assembler.

Beyond assembling, a run subcommand loads and executes a binary or source, and a disk subcommand closes the build loop: create, init, list, get, put, delete, boot, sectorread, sectorwrite, blockread and blockwrite, on DOS 3.3 and ProDOS volumes across .dsk, .do, .po, .woz, .nib and .nb2 alike.

Full reference: docs/Assembler.md.

Testing

4000+ unit tests covering CPU encoding and addressing, assembler features, the audio pipeline, the 6522 VIA and AY-3-8910, //e MMU and Language Card, video timing, the Disk II nibble engine, WOZ and nibblized formats, DOS 3.3 and ProDOS file read/write, the printer pipeline, and reset semantics.

HeadlessHost drives the emulator with no Win32 window for deterministic integration tests — cold boot, disk boot, framebuffer hashing, reset. A separate scenario suite boots a real 6502 over images the command line just wrote and checks what the guest makes of them, because that is the only oracle for "the disk is right" that our own reader cannot satisfy by agreeing with itself.

Harte vectors run at 200 per opcode on every build, checking each instruction's final state and its cycle count, undocumented opcodes included; the full 10,000 per opcode are an opt-in download and are what you run when touching the CPU core. See docs/testing.md.

Install

From the latest release:

  • Casso-<version>.msixbundle — open it to install. Adds Casso to Start and puts casso and cassocli on PATH.
  • Casso-<version>-x64.zip or Casso-<version>-ARM64.zip — unpack and run Casso.exe.

Requirements

  • Windows 10/11
  • PowerShell 7 (pwsh) for build/test scripts
  • Visual Studio 2026 (v18.x)
    • Workload: Desktop development with C++
    • Components: MSVC build tools, Windows SDK, C++ unit test framework
    • Optional: MSVC ARM64 build tools (for ARM64 builds)
  • Optional: VS Code (repo includes .vscode/ tasks)

Quick Start

Build

# Build Debug for current architecture (Ctrl+Shift+B in VS Code)
.\scripts\Build.ps1

# Build Release
.\scripts\Build.ps1 -Configuration Release

# Build all platforms
.\scripts\Build.ps1 -Target BuildAllRelease

# Rebuild with code analysis (warnings as errors)
.\scripts\Build.ps1 -Configuration Release -RunCodeAnalysis

Test

# Build and run tests
.\scripts\RunTests.ps1

# Or use VS Code: Run Tests (current arch)

Run the emulator

Run Casso with no arguments for an Apple //e, or the machine you picked last time, with the disk it had last time. ROMs are fetched on first launch, with your consent; the boot disk picker then offers the DOS 3.3 System Master and ProDOS Users Disk, which Casso downloads from the Asimov archive when one is picked.

The release zip carries Apple2\Demos beside the executable, holding casso-rocks, the two Mockingboard speech demos and the tone demo, so the picker offers them and the paths below work from a downloaded build as well as a source tree.

# Launch the emulator (defaults to the Apple //e)
Casso

# Pick a machine
Casso --machine Apple2e

# Boot a disk in drive 1
Casso --machine Apple2e --disk1 "Apple2\Demos\casso-rocks.dsk"

# Both drives
Casso --machine Apple2c --disk1 "side-a.woz" --disk2 "side-b.woz"

# Every option, in a dialog. Anything Casso cannot read gets the same dialog
# and no emulator.
Casso --help

Machine names come from Resources/Machines/<Name>/: Apple2, Apple2Plus, Apple2e, Apple2eEnhanced, Apple2c. ROM images live under Machines/<Name>/ and shared device boot ROMs under Devices/<Family>/.

Assemble and run

The dialect is required — as65 is a subcommand, not an assumption. Every value attaches to its flag, which is AS65's grammar; -o is the one switch where the space before its value is optional. Full reference: docs/Assembler.md.

# Assemble a source file
CassoCli as65 input.a65 -ooutput.bin

# With a listing file and a symbol table
CassoCli as65 input.a65 -ooutput.bin -llisting.txt -t

# Motorola S-record (.s19) or Intel HEX (.hex)
CassoCli as65 input.a65 -s   -ooutput.s19
CassoCli as65 input.a65 -s2  -ooutput.hex

# The default output is the assembled bytes and nothing else. --flat pads to a
# full 64KB image at the origin; --dos-bin writes a BLOAD-ready DOS 3.3 binary.
CassoCli as65 input.a65 --flat     -ooutput.bin
CassoCli as65 input.a65 --dos-bin  -ooutput.bin

# Pre-define a symbol, or generate a listing with cycle counts
CassoCli as65 input.a65 -dDEBUG=1 -ooutput.bin
CassoCli as65 input.a65 -c -llisting.txt

# 65C02 source (STZ, BRA, RMB/SMB/BBR/BBS, ...). The default is a strict 6502;
# 65C02-only opcodes are rejected without -x.
CassoCli as65 input.a65c -x -ooutput.bin

# Merlin. Merlin derives its own object file, so -o only overrides the source,
# and there is no CPU flag: Merlin selects its CPU in the source with XC.
CassoCli merlin SOURCE.S
CassoCli merlin SOURCE.S -o OBJECT

# Assemble and run in one step. `run` specifies its assembler for the same reason
# assembling does: a source with neither flag is refused, not guessed at.
CassoCli run input.a65 --as65
CassoCli run PROG.S --merlin

# A binary names no assembler, because none reads it
CassoCli run output.bin --load $8000

Project Structure

Casso.sln
├── CassoCore/     Static library — CPU emulator, assembler, parser, opcode table
├── CassoEmuCore/  Static library — Apple II devices, video modes, audio generator + drive-audio mixer
├── Dxui/          Static library — reusable Direct2D/DirectWrite UI framework (host window, panels, layouts, widgets, menu bar, popup host, dialogs)
├── Casso/         Win32 application — Apple II platform emulator (D3D11, WASAPI, Disk II audio)
├── CassoCli/      Console application — assembler CLI (`as65`, `merlin`) with `run` and `disk` subcommands
├── UnitTest/      Test DLL — Microsoft Native CppUnitTest (4000+ tests)
└── ScenarioTests/ Test DLL — system tests needing the DOS 3.3 System Master and a booted guest (`RunTests.ps1 -Scenario`)

Why "Casso"?

While emu is the more obvious name and mascot for an emulator, I wanted Casso to stand out; to be just a little weird; to think different. I picked its larger, flightless, considerably more dangerous cousin: the cassowary, Casso to his friends.

I thus present to you our regal namesake, revel in his splendor!

Southern Cassowary

Cassowary photo by Mr. Smiley / BunyipCo, licensed under CC BY-NC-SA 3.0.

Acknowledgments and Attributions

Casso's correctness is validated against two exceptional open-source test suites:

  • Klaus Dormann's 6502 Functional Test Suite: @Klaus2m5's exhaustive functional test exercises every documented 6502 behavior: all instructions, addressing modes, flag interactions, BCD arithmetic, and edge cases. Casso passes the full suite.
  • Tom Harte's SingleStepTests: @TomHarte's per-opcode test vectors run every legal 6502 opcode from a recorded initial state and compare the registers, flags, touched memory and cycle count against what the instruction really did. Every conditional cycle is covered, since each vector records what its own operands actually cost: page crossings, taken branches, and the 65C02's decimal ADC/SBC penalty. Casso passes all 151 legal-opcode test sets and every byte of the Rockwell 65C02 opcode map. What this still does not cover is which cycle a bus access lands on; the fixtures keep the length of the upstream per-cycle trace, not its contents.

Thank you to both authors for making these invaluable resources freely available. They are the gold standard for 6502 emulator validation.

Casso also builds on several third-party components and assets:

  • CRT display shaders: the optional CRT effect is a set of HLSL ports from the libretro glsl-shaders collection: crt-pi by Davide Berra (MIT), the ntsc-adaptive chroma stage by Themaister and hunterk (MIT), and the bloom passes by hunterk (public domain). Per-file attribution and license terms are in CassoEmuCore/Shaders/CRT/LICENSES.md.
  • stb_vorbis: Sean Barrett's public-domain Ogg Vorbis decoder (nothings.org/stb_vorbis), used to decode the Disk II and printer audio samples.
  • ImageWriter II printer sounds: recorded from a real ImageWriter II by Scott Lawrence, licensed under CC BY 4.0.
  • Disk II mechanical sounds: recordings from the OpenEmulator project.

Contributing

See CONTRIBUTING.md for commit conventions, build instructions, code style guidelines, and other contributor guidelines.

License

MIT

Releases

Packages

Used by

Contributors

Languages