-
-
Notifications
You must be signed in to change notification settings - Fork 1
Roadmap
What Xpeccy+ is working on, roughly in the order it is likely to happen. Priorities, not promises: anything here can move, and the further down an item sits, the less has been decided about it.
The focus is the experience of using the emulator - for development and for playing - on ZX Spectrum compatible machines.
Most of the order below serves one goal: telling people outside this project that it exists. What stands in the way is not features - it is documentation, and a way into the emulator that does not begin with a right click. Everything that makes a stranger's first hour go well is ranked above everything only the author would notice.
A release ships when one thing is finished, not when a set of things is. Versions are
YEAR.NUMBER, so cutting one costs nothing and finished work never waits for company.
Speed control and rewind. Slow motion and overclocking are one slider now, and fast forward runs at eighteen to thirty times real time on most machines. What is left is frame by frame, and a ring buffer of save states to step back through - on hotkeys, with a small control bar rather than the whole debugger window. Half of it is paid for: run-ahead takes a complete snapshot every frame. It also stands aside while a tape, a disk or an RZX recording is running, which is exactly what rewind has to survive, so that is the part still to build.
A regression check. CI builds all three platforms nightly, so a broken build is caught the
same day; a build that starts and shows the wrong picture is not - TSConf was broken for about
half a year before anyone noticed. Boot each bundled machine, run a fixed number of frames,
hash the frame buffer, compare against a stored image. The runner exists: --bench runs a
machine with no window for N frames and hashes every frame, sample and byte of memory, which
is how the speed-up of September 2026 was shown to change nothing. What is missing is the
stored references and a CI job that compares against them.
The part of the emulator this fork cares most about.
Run for N frames. Stepping stops at an instruction; nothing says "run fifty frames and stop". It is the natural granularity for anything that draws, and it is one of the first things a breakpoint condition should be able to count.
Ports as input. Deciding from the debugger what a read of the keyboard or a joystick port returns, and holding it until it is changed - so an input routine can be tested with nobody at the keyboard.
Panels that float. The screen and the sound chips already detach into windows of their own, which is what a panel beside the emulator is for while the machine runs. The rest are dock widgets with a remembered layout and floating switched off in the source, because the styling broke on a floating panel. That is the work, and the heat map is the one that wants it most - with a second layer showing only the current frame over the accumulated one.
Panels that match the machine. The sound panel is built from the machine in front of it, one tab per chip that is really there. The rest of the list is not: a disk panel shows up on a machine with no drive.
A frame-budget view. Right now the border is the profiler: you color it and count stripes. The idea taking shape in the ZX coding chat is to record what the border did, or what was written to a debug port, and show it per frame as a strip beside the screen with some history - so a frame that runs over budget is visible without recording video and stepping through it. Nothing is settled, including whether the markers come from the Spectrum side or from breakpoints on labels.
Logging to a file. The emulator writes an event log, and a breakpoint can put a line in it on every hit, with the registers and the pages. Watch changes are not in it yet, and the breakpoint list does not show which points log. Asked for by TmK.
Small things people keep hitting. A breakpoint gutter in the listing instead of coloring the whole row; splitters you can actually grab; the pixel readout as its own indicator with the character cell and the T-state rather than a line of text; a key to switch the video page between 5 and 7; the memory dump losing its selection.
A menu in the emulator window. Everything is on the right mouse button today, which nobody finds. This is the one thing standing between the emulator and people outside the local scene, who will not be told where to click.
The fullscreen menu. That right-button menu does not appear in fullscreen on Windows. The cause is known - exclusive flip presentation - the fix is not.
Settings where you expect them. The machine's devices are on one page now, and what is in the drives is on the right-click menu rather than in Options. The rest has grown by addition and it shows, worst on the hotkey page: one flat list, most of the width empty. Group it by where the key works, and keep regrouping the rest as needs turn up.
Shortcuts that fit the platform. macOS now has Cmd+, and Cmd+Q; what is still missing is a base set chosen for that keyboard instead of borrowed from Windows.
A hint bar. The important keys along the bottom of the window, the way Norton Commander and the ZX Next menu do it. Asked for by Sergei Smirnov, and it answers the discoverability problem better than a manual does.
Telling you there is a new version. Releases are already published by CI and the version being run is already known, so checking is a web request and a comparison. Say so quietly, show what changed, link the download. Replacing the program while it runs is a different job on each of the three platforms - and on macOS it means signing again - so that half waits until it is clear people are not updating on their own. It matters more once there are people here who do not follow the repository.
Opening archives. A .zip, .rar or .7z with images inside, opened directly - the one
image if there is one, a short list if there are several.
Screenshots that catch what was meant. Synchronized to the start of a frame, the active screen page on a 128K machine, gigascreen.
Shaders worth having. The look being aimed at is a Mega Bezel PVM preset - a sharp broadcast monitor inside a frame, with the picture reflected in the frame around it - and it has to stay fast. The pipeline today cannot host anything like it: one pass, one texture, four uniforms. That look needs multi-pass with its own render targets, feedback from the previous frame (phosphor persistence, and the blur the reflection is built from), a blur pyramid, an external texture for the frame artwork, and parameters exposed in the interface.
That is most of what RetroArch's slang preset format provides, and the earlier verdict on it stands: carrying the format, and SPIRV-Cross with it, is too much. The way through is a chain of fixed shape built into the emulator - linearize, horizontal beam, vertical beam and mask, a three-step blur pyramid, frame and reflection, output - with the knobs declared in the shader file and drawn as a panel. Six to eight passes tuned for one job, rather than thirty that have to suit every console ever made, which is also what keeps it quick. The aim is still one good CRT shader with knobs, not ten shaders each hard-coding a setting. Compile errors should reach a log too. Volutar is writing the shader itself.
Sound as a subsystem. Latency now looks after itself, which was the loudest symptom. What is left is structural: sound wants its own thread and a synchronization model that does not depend on how the audio buffer happens to be filled. Moving it does not make the work smaller, but it takes it off the one thread that must not fall behind - and there is a lot of it, more than half of what the emulator spends at normal speed. Every chip in the machine is mixed 1.4 million times a second, because the whole output is oversampled 32 times for the sake of the beeper alone. The chips cannot simply be handed to another thread while the emulation writes their registers; what makes it possible is a queue of register writes stamped with emulated time, which the sound thread plays back at its own pace.
There is a cheaper step first, and it is not throwaway work: give each chip its own rate. Only the beeper needs 32 times oversampling. The AY, the SAA and General Sound do not, and running them at their own rate through a proper resampler cuts the cost of sound several times over with no threading at all. It is also the shape the threaded version wants.
The beeper. Decimation is dealt with. The filter that turns the 32 times oversampled signal back into 44.1 kHz was a plain average over a block that does not overlap, which folds everything above 22 kHz straight back into what you hear, and a square wave has plenty up there; a 512 tap sinc on a sliding window does it now, and every machine starts with it on. What is left is the speaker itself: a real Spectrum rolls off above about 3 kHz and has no bottom end to speak of, which is two biquads.
Input lag. Measured on the picture: level with Spectaculator, and only MAME is faster. Sound lag has never been measured, and ideally the two match.
Two things are left. The frame reaches the window through two turns of the event loop rather than one - the emulation's signal, and a second event posted from inside it - and the second one has never been explained. And the picture goes out through a QOpenGLWidget, which Qt draws into a framebuffer of its own and then composites; a native surface would skip that copy, but the window's whole painting model rests on that widget, so this is a measurement to take before it is a change to make.
Run-ahead is in and off by default: it doubles the emulation work and puts the picture slightly ahead of the sound. Fixing that offset is what would let it be the default.
Pads read off events rather than a timer. They are polled every 2 ms now, which is as good as a timer gets; reading them as SDL reports them would drop the last millisecond and the polling with it. A thread of their own is the step after that, and only worth taking once a heavier shader starts holding the interface thread up.
All of it wants the same thing: driving the emulator with nobody in front of it.
More of the emulator on the command line. A fair amount is there - a config directory, a binary at an address, labels, a fetch breakpoint, the starting PC and SP. Missing is everything that lets a script decide what happened: run N frames and exit, write out the screen, memory or registers, and say through an exit code whether a breakpoint was hit.
A trace between breakpoints. Start, and from the first time a breakpoint is hit until the next one, write what the processor did to a file. Cheap once the above exists, and it turns "why is this frame different" into a diff.
Remote control. There is a small network interface already. Speaking to DeZog is one candidate for what it would talk to, not a commitment.
Getting started and a debugger guide, in English, travelling with the release rather than living somewhere else. Written after the debugger layout settles - screenshots taken before a rework have to be taken again.
The bigger half of it belongs in the program: tooltips, a "?" that explains the thing you point at, help next to the features that need it. Clicking a register in the debugger navigates to that address, and almost nobody knows.
RZX. Recording is not supported at all. Playback is, packed snapshots included.
Tape loading. Fast loading runs any loader flat out and skips the edge loops it knows, and the tape stops after a loader it knows. Two things are left. Loading is still drawn dot by dot for every T of the load, which is most of the time it takes now. And the tape input is taken as a clean signal: on a real 48K it passes a capacitor, and a WAV pre-equalised for that - DeciLoad ships one - only loads if the emulator models it, which no emulator does.
Recording video. Sound can already be saved to a WAV file while the machine runs; the picture cannot, and people capture the window instead. Asked about now and then.
Most of it is already there. Screenshots know about formats, intervals and what to leave out; sound knows how to write itself to a file as it plays; and the two are already in step, because the frame and the sample are counted off the same emulated clock in the same loop. What is missing is a container.
It should be ffmpeg, run as a separate process with raw frames and raw sound going in on a pipe. That is a couple of hundred lines against writing a container by hand, it produces files that open everywhere, and running it as a process rather than linking libavcodec is what keeps Xpeccy+ under its own license. Where it is not installed, offer to fetch it, and say plainly what is being fetched and on what terms.
Timing on the rarer machines. The 48K, 128K, +2 and +2A/+3 are done and tested against real hardware. Scorpion, the ATMs and the rest have almost no precise timing tests to check against, so they may still be off.
divMMC and esxDOS. The one piece of add-on hardware here worth the trouble: still sold, still written for, and how people move files onto a real Spectrum today. Most of the cost is already paid - the SD card is emulated, and so is serving a host folder as one - so what is left is the paging, which is small. It is also half of what a ZX Next would need, if that day ever comes. The rest of the classic peripherals - Interface 1, +D, Multiface, Opus - are a long list, and Fuse has all of them; matching it there is not what would bring anyone here.
Drive sound. A floppy that sounds like one. Pure atmosphere - MAME shows it can be done, and that it can be done better than MAME does it.
Not refusals - just an honest account of what each one costs.
ZX Next. The most frequent request by a distance, and closer to a second machine than a feature: 28 MHz and its speed modes, the copper, extra video modes, sprites, DMA, its own banking and esxDOS. Six to eight thousand lines of new code, against a target that keeps moving - core firmware, NextZXOS, and a software library that grows every month.
Speed is not the objection it was written up as. At 28 MHz the dot loop costs the same, because the pixel clock does not change; only the processor side grows. Fast forward runs a 128K machine at about eighteen times real time, and TSConf - the nearest thing here to a machine with layers and a fast processor - at about six. Tight on a weak laptop, fine on a desktop. What rules it out is the size of the job, not the frame rate. MAME is the best option for it today.
ZXM-Moonsound and other later sound hardware. An OPL4 is an OPL3 with a 24 voice sampler bolted on, the samples live in a two megabyte ROM nobody can ship, and the card itself was built in tiny numbers. It waits for someone who uses one to ask.
Issues and pull requests are welcome, including "this machine is wrong" - single-handed projects miss things, and machine settings are where they get missed most.