Yet another ZX Spectrum emulator
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Spiffy: Yet another ZX Spectrum emulator

Spiffy is currently in a fairly early stage of development.
The Z80 core works (and passes the Fuse coretests).  The debugger works but it's not the friendliest of interfaces.
Peripherals available include ULAplus and the ZX Printer.  There's also an AY chip, which (along with the beeper) is run through a low-pass filter / downsample to prevent aliasing, which can sometimes create bassy and semi-muffled audio (known to fans and detractors alike as the 'drainpipe-O-matic').
Also, timings and contention are somewhat inaccurate.  In particular, the 'split bus' is not properly emulated, chiefly because I don't understand it.  (I need to read csmith's book!)

Installation (Dependencies):
	You will need runtime and development packages for the following libraries:
		* SDL, SDL_image, SDL_ttf
		* GTK+2
		* libspectrum
	On debian systems, just run:
		sudo apt-get install libsdl1.2debian libsdl1.2-dev libsdl-image1.2 libsdl-image1.2-dev libsdl-ttf2.0-0 libsdl-ttf2.0-dev libgtk2.0-0 libgtk2.0-dev libspectrum8 libspectrum-dev
	Now compile & install spiffy, with:
		sudo make install
	Spiffy will be installed to /usr/local.  If this is not on your $PATH you may want to change that, or change the installation prefix which is defined at the top of the Makefile.

Command line options:
		Start with the debugger activated.
		Set a breakpoint at xxxx (hex).
		Start with the emulation paused.
		Enable the ZX Printer.  If <file> is specified, saves the (NetPBM format) output to <file>, otherwise "zxp.pbm".
		Apply the ZX Printer Port Decoding fix: make the printer only recognise ports (A6&&!A2) instead of all of !A2.  Useful for compatibility with ZXI devices, including ULAplus.
		Enable the AY chip.
		Enable ULAplus emulation.  If using with --zxprinter, you will also need to use --zxpfix.
		Enable 8x1 attribute mode (Timex hi-colour).  This is rampantly inaccurate, and doesn't even load a different ROM so anything in ZX Basic will just leave you with a black screen.  This feature was added in order to try out an 8x1 HAM256 slideshow by Chev.
		Enable the keyboard assistant.  This appears below the UI controls, and dynamically highlights the key functions corresponding to the current shift state, cursor mode, etc.
		Enable single-Tstate stepping in the debugger.
		Disable single-Tstate stepping, instead step by instruction (this is the default)
		Run the core tests; produces a load of output on stdout.
		Select 128k Spectrum.  Currently the timings are probably extra-inaccurate and there's limited debugger support; probably plenty of other things are wrong too.

UI controls:
There are three rows of controls: Tape, Audio and Misc.  Each button should have an icon on it; if they're just square boxes of colour, it means Spiffy couldn't find its data files.  You can also get a tooltip by hovering the cursor over a button.
	Speed readout.  Should hover around 100%.
	Load (light brown).  Opens a file chooser dialog which you can use to load a tape or a snapshot.
	Tape traps (toggle).  White=on, dark gray=off.  Enables trapping of LD-EDGE-1 in the ROM tape loader, for fast tape loading.  Also enables trapping of SA-LEADER and SA-BIT-1 in the ROM tape saver, for fast tape saving (though not quite as fast as loading).
	Play (green).  When tape is playing, turns pink.
	Skip (dark blue).  Skips to next tape block.
	Stop at end of block (toggle).  Lilac=on, dark red=off.  When enabled, the tape will be stopped at the end of each block.  Handy for multiload tapes.
	Rewind (magenta).  Rewinds the tape to the beginning.
	Record tape (toggle).  Red, brighter when active.  Records tape SAVE to a CSW file.
	Tape counter.  Displays the number of seconds remaining in the current block.  (If tape traps are enabled, this will be slightly inaccurate, but close enough.)
	Record audio (toggle).  Red, brighter when active.  Records the filtered beeper audio to a WAV file.  (Note: you can't use this to save tapes.  Use the CSW record on the Tape row, above).
	BW: controls the filter bandwidth.  Left-click changes by increments of 1; right-click doubles or halves.  Try 38, 52 or 76 for most beeper engines; AY will usually want 128.
	SR: controls sinc_rate, the oversampling ratio.  Higher values improve audio but use more CPU.  6 should be plenty.
	Pause (toggle).  Gold=unpaused, orange=paused.  Pauses the emulation.  Technically, not everything is paused, so timing-critical code may glitch when resuming.
	Reset (orange).  Resets the Spectrum.
	Debug (sickly green).  Activates the debugger.  (Only works if Spiffy was run from a terminal)  See `debugger' for manual.
	Save Snapshot (grey).  Opens a file chooser dialog to save a .z80 snapshot.
	Printer Feed (purple).  While held, feeds paper through the ZX Printer.  (Greyed out if ZX Printer disabled)
	Keystick mode (green & grey).  Selects the joystick mode to use for the cursor keys (and numpad 0 to fire); C=Cursors, S=Sinclair, K=Kempston, X=disable keystick.
	Black & White (grey/white).  Toggles the "Black & White" filter.
	TV Scanlines (blue).  Toggles the "TV Scanlines" filter.  (These aren't proper scanlines, only pretend ones, because the display is only 1x size).
	Horizontal Blur (pink).  Toggles the "Horizontal Blur" filter.
	Vertical Blur (pink).  Toggles the "Vertical Blur" filter.
	Misaligned Green (olive green).  Toggles the "Misaligned Green" filter.
	Slow Fade (grey-blue).  Toggles the "Slow Fade" filter.  (Warning: this filter eats up a lot of CPU!)
	PAL chroma (purple/grey).  Toggles the "PAL Chroma Distortion" filter.

Notable features of Spiffy's design:
The Z80 emulation (and main loop) operates at a 1-Tstate resolution, making accurate timing theoretically easy to implement.
The main bus (A0-A15, D0-D7, /MREQ, /IORQ, /RD, /WR, /M1, /RFSH, /WAIT) is fully populated with the correct control signals; for instance all memory reads from the Z80 are actually performed by asserting the bus, then reading D0-D7 on the next Tstate.  In other words, the communication between the Z80 and other 'virtual chips' is confined entirely to the virtual bus.  This should make the implementation of peripherals a simple matter.

Pitfalls to beware of:
In debugging information, Spiffy refers to M-cycles, but be warned!  These do not match up to official documentation.  The opcode fetch cycle (usually M1) is notated M0; subsequent M-cycles are similarly reduced by one.  Prefixes are considered to be an extra M0.  Single-cycle operations consist of two Spiffy M-cycles, M0 (opcode fetch, 4T) and M1 (internal operation, 0-2T).  Also, some cleverness is practiced with the 'dT' counter (that is, Tstate within this M-cycle) - it is often set to a negative value and the M counter incremented early, when an M-cycle has finished processing before its allotted Tstates are up.  Generally debugging information should always be interpreted with reference to the source code, rather than to one's expectations of the normal behaviour of a Z80 or to common conventions used to document said behaviour.

Spiffy is copyright (c)Edward Cree, 2010-13, and licensed under the GNU GPL v3+.  (You should have received a copy of the GPL with this software, in the file 'COPYING')
The ZX Spectrum ROM images (48.rom, 128.rom) are copyright Amstrad Plc.  Amstrad have kindly given their permission for the redistribution of their copyrighted material but retain that copyright (see
Any software (or software images) you run using this emulator remain the property of their respective owners.