oricdemo2026 is a HIRES-mode demoscene production for the Oric Atmos, built with the Oscar64 cross-compiler. v1.0.0 is the first public release: twelve sections, real AY-3-8912 music, real converted photographs, and two independent, fully-playable distributions built from the same source.
It is a direct nod to the machine's own 1985 "Welcome to Oric Atmos" tape demo -- same spirit (a splash, a logo, an animated scene, a handful of effect showcases, a credits roll), reworked as a longer, real multi-section production.

Bare metal, no ROM calls
Like the other recent Oric projects on this site -- LOCI File Manager v2 and Oric Screen Editor for LOCI -- oricdemo2026 runs on Oscar64's native, bare-metal compilation mode: no Oric ROM jump table, screen and hardware driven directly through memory-mapped registers. The demo goes one step further than either of those two projects, though, because it needs HIRES bitmap graphics rather than character-mode text -- which meant retargeting the runtime a second time.
HIRES mode uses the memory region ($9800-$BFDF) that the shared text-mode runtime normally reserves for code, data, and stack. A separate runtime, oric_crt_hires.c, shrinks those regions to make room for the bitmap instead. The two runtimes are mutually exclusive: a program is built against one or the other, never both. The practical consequence is a noticeably tighter budget in HIRES mode -- around 36 KB of usable code/data/BSS space versus roughly 42 KB in text mode -- which shaped several of the decisions below.
Twelve sections, one running order
Splash, logo, an animated bird scene, four effect showcases (HIRES shapes, a rotating wireframe star, a 3D wireframe height-field mesh, a sprite over a starfield), a scroller, a sine-wave photo distortion, a full-colour photo with a scrolling caption, a raster-IRQ colour-split effect, and a closing credits scroller. The whole sequence cycles forever once started, driven by a fixed section table and a generic runner: each section gets an init() that runs once and a tick() that runs every frame, advancing on a natural end, a keypress, or a maximum tick count, whichever comes first.
![]()
The starfield behind the satellite sprite was originally a loaded picture asset -- a reasonable choice at first, but wasteful for something that is, structurally, just scattered dots. It is now generated procedurally instead: forty star positions precomputed once (via a small Python script, not at runtime) and drawn with plain pixel set/clear calls, scrolling left independently of and slower than the satellite for a simple two-speed parallax. The change also freed up a file-index slot on the floppy distribution, which does not carry loaded picture assets it does not need.
A raster interrupt that earns its keep
The raster-IRQ showcase is the one section that steps outside the demo's otherwise strict "everything runs from the main loop" discipline. Three full-screen colour bars sweep continuously over three procedurally drawn stars, driven by a genuine hardware interrupt via a self-contained VIA Timer 1 handler -- the only place in the whole demo where interrupts are enabled at all. Everywhere else, they stay off for the entire run.

The Oric has no hardware raster/colour-split register the way the C64 does -- what this buys is a 50Hz update rate for the bars, distinct from the main loop's own roughly 16.7Hz pacing, at the cost of real complexity: the interrupt handler and the demo's Arkos Tracker music player share the same 20ms timer period, so the bar-drawing code has to do bounded, small-batch work per firing rather than a full redraw, or it starves the music of its own tick budget. That exact failure mode -- a big per-tick batch stealing cycles from the music player -- had already caused two real slowdown bugs earlier in the project, in a different section, before this one was built with the lesson already learned.
From PT3 to Arkos Tracker
The demo's music went through a full player replacement mid-project. The original choice was a PT3 (Vortex Tracker) player, and it worked, in the sense that it decoded and produced sound -- but getting it to produce correct sound took several rounds of real decode-bug fixes (bassline note-strike resets, volume/mixer decode errors, a background track playing as noise instead of melody), and even after all of them, the result still was not musically satisfying.
The replacement is an Arkos Tracker (.aky) player, ticking at 50Hz via the same raster-IRQ mechanism described above. Arkos Tracker modules bake absolute 16-bit pointers into their own linker and track tables at export time, which means -- unlike PT3 -- there is no relocation step: every module has to be exported to, and loaded at, one fixed address. That address is the demo's own overlay-RAM buffer, the same region used for loaded pictures, so the two building blocks the demo depends on most -- music and full-screen photos -- have to share a single memory window without either one silently overflowing into the other. The PT3 player itself was not deleted; it is kept archived on a separate branch as a record of the six rounds of diagnostic work it took to get that far.
A bug only real hardware could find
Every picture and both music tracks load from disk at runtime through a LOCI mass-storage device, via bare filenames like steppingout.aky. That approach passed every automated test the project had, including the headless Phosphoric emulator runs used throughout development. It failed silently on real LOCI hardware with more than one storage device mounted.
The cause: a bare filename's resolution against "the current directory" is not reliably the directory the currently-running program itself was launched from, once a second drive is in the picture. Phosphoric's own LOCI emulation apparently treats this case more forgivingly than the real firmware does, which meant the bug was invisible to every test the project could run against it -- it only ever surfaced once real hardware was involved. The fix mirrors one already applied to LOCI File Manager v2's shared LOCI driver: capture the boot-time working directory once, and prefix it onto every bare filename before opening it. It is a small function, but the failure mode it guards against would not have shown up in any amount of additional emulator testing.
Two distributions, one source
oricdemo2026 ships two ways from the same src/main.c and section files. The LOCI target is a small .tap (the code only) plus seven asset files that all have to sit together in one folder on the LOCI's storage -- music and every picture load from there at runtime. The floppy target is a single, fully self-contained bootable Microdisc disk image with everything baked in: no LOCI, no DOS, nothing else needed at all.
The floppy target exists largely because Oricutron, one of the two emulators used during development, has no LOCI emulation whatsoever -- running the LOCI target there would load the code and then silently fail every music and picture load, by the same graceful-degradation design that makes the real-hardware bug above possible in the first place. Phosphoric's own --loci-flash option does emulate a LOCI device, so it is the one way to see the LOCI target's full experience without the floppy image or real hardware. Between the two, the project's own make run-disk target -- the floppy image running under Oricutron -- gives the complete demo plus Oricutron's own debugger and breakpoints, which is why there is no plain, LOCI-less Oricutron target at all: it could only ever show a worse version of what the floppy target already does better.

New in v1.1.0: voice samples on the AY chip
Version v1.1.0 adds two digitized speech clips to the demo: "Welcome to Oric Atmos", spoken once the Oric logo section's picture has loaded, and "Thanks for watching", spoken once the credits section's sunset photograph is up. Both are crude AY-3-8912 playback, not synthesized speech on the Oric itself -- a text-to-speech source (via ElevenLabs) is converted offline into a raw 4-bit sample stream, one byte per sample, matching the AY chip's own volume-register resolution.
Playback works by muting a channel's tone and noise generators (via the AY's own mixer register) and then rapidly rewriting its volume register from the sample buffer, paced by a VIA timer reprogrammed to the sample rate. Each write briefly changes the channel's output level; done fast enough, and in sequence, the ear reconstructs a rough approximation of the original waveform. The technique is based on ChibiAkumas's Z80 tutorial series, specifically Lesson P35, "Playing Digital Sound with WAV on the AY!", adapted here for the Oric's own 6502 and VIA hardware rather than a Z80 system.

The two clips use different sample rates. "Welcome to Oric Atmos" plays at 4000Hz; "Thanks for watching" plays at 7000Hz, a deliberate choice after the lower rate made it noticeably less recognizable than the other clip. A byte-histogram comparison ruled out a quantization or normalization problem -- both clips already used the AY's full 16-level range in a similar distribution. The likely explanation is content, not encoding: "Thanks for watching" carries more consonant and fricative sound than "Welcome to Oric Atmos", and those higher-frequency sounds need more time resolution to stay distinguishable at only 16 amplitude steps. The clip also had comfortably more spare budget within the shared byte-size ceiling both samples share, so the higher rate cost nothing.
Building this also surfaced a real Oscar64 compiler bug: a Timer 1 acknowledge read, written as an ordinary C volatile local variable, was silently optimized away outside interrupt-handler context, leaving the timer's own status flag never cleared and the whole sample playing back far too fast. The fix needed genuine inline assembly rather than the C-level idiom that works everywhere else in the project's interrupt handler. A second, unrelated issue -- two separate library files each keeping their own private path-scratch buffer -- had to be consolidated into one shared buffer to fit the demo's already tight ~36 KB code/data/BSS budget.
This release also fixes three visible bugs reported after longer play sessions: a brief flash to white-on-black during the transition between sections, a permanent black stripe at the left edge of the bird scene's sky and river bands, and the bird scene's own animation state not resetting between passes through the demo's twelve-section loop -- the second time the bird scene played, it started from wherever it had last stopped, with a visible pixel artifact left over from a mismatched sprite erase.
A short video of the demo running is on the YouTube channel.
v1.0.0 is available now
v1.0.0 is the first public release of oricdemo2026:
- oricdemo.tap + 7 asset files -- the LOCI distribution
- oricdemo_floppy.dsk -- the self-contained floppy distribution
- Full documentation (README, architecture writeup, per-library API reference)
The floppy image is the simplest way to just watch and listen: boot it under Microdisc emulation, or write it to a real floppy for real Microdisc hardware, and it plays the full demo end-to-end with no other hardware required. The LOCI distribution needs a real or emulated LOCI device -- see the README for full installation steps either way. The project is licensed under GPLv3.
Credits
- Code: Xander Mol
- Music: "Stepping Out" (2019) by Roald Strauss (Mr.Lou, Dewfall Productions); "Boules Et Bits" by Tom & Jerry, from Arkos Tracker's own bundled sample-song folder
- Bird sprite: adapted from mihai-dragan's oric_BAS project (MIT License)
- Oric Atmos logo: Oric International's own wordmark, via Wikimedia Commons
- Scarlet macaw photo: Kandukuru Nagarjun (Jurong Bird Park), CC BY 2.0
- Credits-screen sunset photo: Artem Beliaikin, via Wikimedia Commons, CC0
- Voice samples: text-to-speech via ElevenLabs (Pepper voice); playback technique based on ChibiAkumas's Z80 tutorial series, Lesson P35
- Compiler: Oscar64 by drmortalwombat
- A nod to "Welcome to Oric Atmos" (Oric International, 1985) and to idi8b
Licensed under the GNU General Public License v3.0.
Sources and More Information
oricdemo2026 repository -- source code, libraries, build instructions, and full documentation: github.com/xahmol/oricdemo2026
v1.0.0 release -- release notes and downloads: github.com/xahmol/oricdemo2026/releases/tag/v1.0.0
v1.1.0 release -- release notes and downloads: github.com/xahmol/oricdemo2026/releases/tag/v1.1.0
Architecture writeup -- memory maps, section sequencer design, and a per-section technique table: docs/architecture.md
Voice-sample design writeup -- memory budget, playback sequence, and the real bugs found building it: docs/voice.md
ChibiAkumas Z80 tutorials -- Lesson P35, source of the AY digidrums playback technique: chibiakumas.com/z80/platform4.php#LessonP35
Demo video -- oricdemo2026 running on real/emulated hardware: youtu.be/d7EyumIpWCo
Oscar64 compiler -- C99/C++ cross-compiler for 6502, by drmortalwombat: github.com/drmortalwombat/oscar64
LOCI ROM by Sodiumlightbaby -- the mass-storage device firmware used by the LOCI distribution: github.com/sodiumlb/loci-rom
Phosphoric -- headless Oric emulator by benedictemarty, used for the automated regression suite: github.com/benedictemarty/Phosphoric
Oricutron -- Oric emulator by pete-gordon, used for the floppy target's own debugger-backed testing: github.com/pete-gordon/oricutron
Arkos Tracker -- AY-3-8912 music tracker by Julien Nevo, source of the demo's own player and both music tracks: julien-nevo.com/arkostracker
LOCI File Manager v2 release post -- the shared Oscar64/Oric runtime's own origin story: /blogs/locifilemanager-v2-release
Oric Screen Editor for LOCI release post -- another recent project on the same runtime lineage: /blogs/oric-screen-editor-loci-release