Skip to content

Speccy - RetroBIOS

Type standalone
Classification Other
Source https://fms.komkon.org/Speccy/
Upstream closed-source
Version 5.9.11
Profiled 2026-08-12
Cores speccy, SPECCY, com.fms.speccy.deluxe, com.fms.speccy
Systems sinclair-zx-spectrum, timex-tc2048, timex-ts2068, sam-coupe
Author Marat Fayzullin (Garage Research)
Checked by existence
Technical notes

Sinclair emulator by Marat Fayzullin, covering ZX Spectrum 16kB, 48kB and 128kB, Spectrum +2, +2A and +3, Timex TC2048 and TS2068, the Slovak Didaktik Gama, the Russian Pentagon and Scorpion clones, and the Sam Coupe. The build read here is the free Android package com.fms.speccy, versionName 5.9.11 versionCode 5911, taken as the Play app bundle drop, xapk sha256 a93f2fd474234291d2c0dee57885204ffb12a22c94602fdfcdfbf084ed7cb354, base apk sha256 7163451489ac59b8c63ca49976571ad284cffa11b54d615c1693c909dd6bf768. Its META-INF/BNDLTOOL.RSA is the author's own key, CN=Marat Fayzullin O=Garage Research issued 2011, fingerprint d09469e9b550cbc9005d3bd089f3df5f0ba89cba71cdd3b33736a0382d6f9848, beside a Play distribution source stamp in the signing block. The paid package com.fms.speccy.deluxe, last published as 5.9.3 versionCode 5903 in December 2021, is carried by no mirror that answers: the author's site links only to Play for it, apkcombo bounces its download page back to the app page, apkpure redirects to its generic downloader, apkvision holds no copy and archive.org none either. The native libraries keep their symbol tables, so the readings below cite libmain.so offsets in the x86_64 slice; the arm64-v8a slice carries the same nineteen ROM names. The free Speccy 5.9 builds for Windows and Ubuntu were read beside it and open the same names with the same lengths and the same order. No source has ever been published: every download on the site, from 1.7 for MSDOS through 5.9, is a binary package, while ColEm and fMSX on the same site ship source archives. ref: com.fms.speccy.apk META-INF/BNDLTOOL.RSA, https://fms.komkon.org/Speccy/, Speccy59-Windows-bin.zip, Speccy59-Ubuntu-x86-bin.tgz

One directory holds everything. MainActivity hands the home directory to jniStart, which copies it into the buffer GetHomeDir returns and passes that same buffer to SetPrivateDir, and Application stores what GetHomeDir returns as the directory LoadBIOS changes into before it opens the first ROM and back out of when it is done. That directory is external storage joined with the application label up to its first space, so /sdcard/Speccy for the package read here, falling back to getExternalFilesDirs(null) when it is not a writable directory; the author's own instructions give the same placement. Every open goes through mopen, which calls OpenRealFile first: the name is tried as given, and again as /, keeping the larger of the two when both open. mopen then layers gzdopen over the descriptor, so any of these files also opens gzipped, and a content:// name is routed to the Android storage framework. The desktop builds have no home directory of their own and open every name where they stand, which -home changes for the system ROMs alone. ref: MainActivity.java:2561-2573, EMULib.java:750, 812, libmain.so jniStart 0x32dd0-0x33530 (0x332af-0x332c1, 0x33312), GetHomeDir 0x30a90, SetPrivateDir 0x571d0, Application 0x602f0-0x60324, OpenRealFile 0x57440-0x5766c, mopen 0x57680-0x57800, LoadBIOS 0x6436d-0x6439a, 0x6466b-0x6467b, Speccy59-Ubuntu-x86-bin speccy 0x3dae5-0x3db17, Speccy.html "-home ", EmuAndroid "System ROMs"

LoadBIOS drives the whole set from one word of hardware flags, calling TryLoadROM once per name in a fixed order with the length to read and the bit that asks for it. TryLoadROM does nothing when the bit is clear, and clears the bit when mopen fails, which is the only check the emulator makes: the count mread returns is compared against the requested length solely to pick the word it logs, OK or FAILED, and a short read leaves the bit set. Nothing else about a file is examined and no hash is compared. A machine ROM that loads clears every other machine bit and a peripheral ROM that loads clears every other peripheral bit, so one machine and one disk interface stand at a time. StartZXS gives up when no machine bit survives, logging FAILED TO LOAD SYSTEM ROM! and returning zero without starting the emulation, which makes the ROM of the selected model the one file the emulator cannot run without. ref: libmain.so LoadBIOS 0x64350-0x646cd, TryLoadROM 0x659b0-0x65aa4 (mopen 0x659d4, mread 0x65a3c, bit cleared 0x65a1c, masks 0x65a7d-0x65a94), StartZXS 0x64040-0x6434c (LoadBIOS 0x6416d, mask 0x64172, message 0x64315), Speccy59-Ubuntu-x86-bin speccy 0x3dac0-0x3ddaa, 0x3d970-0x3da04, 0x3f43c-0x3f469, 0x3f640

Two names are reached only through another. ZXS128TR.ROM is tried in place of ZXS128.ROM when the 128kB model and the TR-DOS interface are both asked for, and ZXS128.ROM is loaded after it when it fails. The Multiface bit picks its image from the machine already loaded, MFPLUS3.ROM behind a +2A or +3, MF128.ROM behind a 128kB or +2 and MF1.ROM behind a 16kB or 48kB, and the 8192 bytes at offset 8192 of what it read are copied into the page below the machine ROM. ref: libmain.so LoadBIOS 0x64564-0x6458b, 0x645d9-0x645f5, 0x645c2-0x64651, Speccy59-Ubuntu-x86-bin speccy 0x3dc79-0x3dca1, 0x3ddf0-0x3de10, 0x3dcd9-0x3dd64, Speccy.html "Now trying to load ZXS128TR.ROM BIOS file"

Thirteen of the nineteen ROMs ship inside the Android package. MainActivity reads assets/memfs.mp3 whole and jniStart mounts it through SetMemoryFS as an in-memory filesystem, which mopen consults only after OpenRealFile has failed, so a copy in the home directory is served ahead of the packaged one. The directory is a run of 32 byte entries, a length then a name, closed by an entry with an empty name whose first word is the key: rotated left by three times the entry count, XORed sixteen bits at a time into each length and rotated right by three after each, it yields the thirteen lengths, which run consecutively from the end of the directory and account for the file exactly. Eleven of the thirteen are the same bytes the Windows and Ubuntu distributions ship, and TC2048.ROM and TS2068.ROM appear in no distribution at all. ref: MainActivity.java:2561-2573, libmain.so jniStart 0x32f72-0x32f98, InitMemoryFS 0x57180, SetMemoryFS 0x57200-0x57422 (key 0x572a0-0x572c1, lengths 0x572e0-0x57305), mopen 0x57749-0x577e4

Companion files come from the loaded program's path. LoadFile derives .sta, .pok, .cht and .pal from it and reads each when it is there, and the startup palette is a name of its own, /Speccy.pal on Android and Speccy.pal beside the binary on the desktop, which -palette redirects. ref: libmain.so LoadFile 0x65482, 0x65569, 0x65590, 0x655b7, Application 0x60436-0x60484, StartZXS 0x641c5-0x641d4, LoadPAL 0x648d0, Speccy59-Ubuntu-x86-bin speccy 0x3f4ac-0x3f4bd, 0x3e450-0x3e494, Speccy.html "-palette "

27 files | 11 required, 16 optional | 20 in repo, 7 missing Categories: 19 BIOS, 8 game data

ZXS48.ROM required in repo bundled
ZX Spectrum 48kB BASIC ROM

  • System: sinclair-zx-spectrum
  • Size: 16.0 KB
  • SHA1: 5ea7c2b82467...
  • MD5: 4c42a2f07521...
  • CRC32: ddee531f
  • Source: libmain.so LoadBIOS 0x645a8-0x645bb, Speccy59-Ubuntu-x86-bin speccy 0x3dcbe-0x3dcd1
  • Read as 16384 bytes for the 48kB model, which is the model the emulator starts in when nothing else is asked for. Present in the packaged filesystem and in the Windows and Ubuntu distributions.

ZXS16.ROM required missing
ZX Spectrum 16kB BASIC ROM

  • System: sinclair-zx-spectrum
  • Size: max 16.0 KB
  • Source: libmain.so LoadBIOS 0x64590-0x645a3, Speccy59-Ubuntu-x86-bin speccy 0x3dca8-0x3dcbb
  • Read for the 16kB model under a name of its own, with no fallback to ZXS48.ROM, so the model refuses to start without it however many other ROMs are present. Neither the package nor the desktop distributions carry a copy.

ZXS128.ROM required in repo bundled
ZX Spectrum 128kB ROM pair

  • System: sinclair-zx-spectrum
  • Size: 32.0 KB
  • SHA1: 16375d42ea10...
  • MD5: 85fede415f42...
  • CRC32: 2cbe8995
  • Source: libmain.so LoadBIOS 0x64575-0x6458b, Speccy59-Ubuntu-x86-bin speccy 0x3dc85-0x3dca1
  • Read as 32768 bytes, two pages. Loaded after ZXS128TR.ROM has been tried when the TR-DOS interface is on as well.

ZXS128TR.ROM optional in repo bundled
ZX Spectrum 128kB ROM pair carrying TR-DOS

  • System: sinclair-zx-spectrum
  • Size: 32.0 KB
  • SHA1: 9b8bc3190086...
  • MD5: 44082607f78a...
  • CRC32: ce98811c
  • Source: libmain.so LoadBIOS 0x645d9-0x645f5, Speccy59-Ubuntu-x86-bin speccy 0x3ddf0-0x3de10
  • Tried in place of ZXS128.ROM when the 128kB model and the TR-DOS interface are both asked for, and ZXS128.ROM is loaded in its place when it fails.

ZXSPLUS2.ROM required in repo bundled
ZX Spectrum +2 ROM pair

  • System: sinclair-zx-spectrum
  • Size: 32.0 KB
  • SHA1: 8cafb292af58...
  • MD5: 238f77692156...
  • CRC32: e7a517dc
  • Source: libmain.so LoadBIOS 0x64544-0x6455f, Speccy59-Ubuntu-x86-bin speccy 0x3dc56-0x3dc72
  • Read as 32768 bytes for the +2. The +2A bit is cleared ahead of the call whenever the +3 bit is set, so the pair that asks for ZXSPLUS3.ROM cannot leave a second machine standing.

ZXSPLUS3.ROM required in repo bundled
ZX Spectrum +2A and +3 ROM set

  • System: sinclair-zx-spectrum
  • Size: 64.0 KB
  • SHA1: 500c0945760a...
  • MD5: 7e00ed3562ab...
  • CRC32: be0d9ec4
  • Source: libmain.so LoadBIOS 0x6452c-0x6453f, Speccy59-Ubuntu-x86-bin speccy 0x3dc3e-0x3dc51
  • Read as 65536 bytes, four pages covering both the +2A and the +3, which the loader asks for under one bit pair.

TC2048.ROM required in repo bundled
Timex Computer 2048 ROM

  • System: timex-tc2048
  • Size: 16.0 KB
  • SHA1: febb2d495b6e...
  • MD5: 9dd7ecf784a6...
  • CRC32: f1b5fa67
  • Source: libmain.so LoadBIOS 0x644e4-0x644f7, Speccy59-Ubuntu-x86-bin speccy 0x3dbf6-0x3dc09
  • Read as 16384 bytes for the TC2048. Carried in the packaged filesystem only: the Windows and Ubuntu distributions ship no copy.

TS2068.ROM required in repo bundled
Timex Sinclair 2068 ROM set

  • System: timex-ts2068
  • Size: 24.0 KB
  • SHA1: 34cd8113bf75...
  • MD5: 9194283503a1...
  • CRC32: 48004230
  • Source: libmain.so LoadBIOS 0x644cc-0x644df, Speccy59-Ubuntu-x86-bin speccy 0x3dbdd-0x3dbf1
  • The loader asks for 49152 bytes while the author's own image is 24576, so the read stops short of what was asked and the machine starts anyway. Carried in the packaged filesystem only.

DIDAKTIK.ROM required in repo bundled
Didaktik Gama ROM

  • System: sinclair-zx-spectrum
  • Size: 16.0 KB
  • SHA1: 8466a9da0169...
  • MD5: 28287c397def...
  • CRC32: 45c29401
  • Source: libmain.so LoadBIOS 0x644fc-0x6450f, Speccy59-Ubuntu-x86-bin speccy 0x3dc0e-0x3dc21
  • Read as 16384 bytes for the Slovak Didaktik Gama clone.

PENTAGON.ROM required in repo bundled
Pentagon 128kB ROM set

  • System: sinclair-zx-spectrum
  • Size: 48.0 KB
  • SHA1: 582254842091...
  • MD5: 36e48cd89847...
  • CRC32: e7bbb552
  • Source: libmain.so LoadBIOS 0x64488-0x644c7, Speccy59-Ubuntu-x86-bin speccy 0x3dbb8-0x3dbd7, 0x3de18-0x3de37
  • Read as 49152 bytes, three pages. The third is copied into the disk interface window once it has loaded, so the Pentagon carries its own TR-DOS and does not need TRDOS.ROM.

SCORPION.ROM required in repo bundled
Scorpion 256kB ROM set

  • System: sinclair-zx-spectrum
  • Size: 64.0 KB
  • SHA1: 66cecdadf992...
  • MD5: b26cba495108...
  • CRC32: fef73c28
  • Source: libmain.so LoadBIOS 0x64444-0x64483, 0x643d5-0x643e3, Speccy59-Ubuntu-x86-bin speccy 0x3db94-0x3dbb2, 0x3de40-0x3de5f
  • Read as 65536 bytes, four pages, the last copied into the disk interface window. The Scorpion bit also drops every peripheral bit before the first ROM is opened, so its own service ROM stands in place of the separate interfaces.

COUPE.ROM required in repo bundled
Sam Coupe ROM

  • System: sam-coupe
  • Size: 32.0 KB
  • SHA1: 58186fd34a8b...
  • MD5: 9f40c46cce40...
  • CRC32: 39ff160a
  • Source: libmain.so LoadBIOS 0x64514-0x64527, TryLoadROM 0x65a7d-0x65a94, Speccy59-Ubuntu-x86-bin speccy 0x3dc26-0x3dc39, Speccy.html "Now disabling all trapdoor-based devices in Sam Coupe mode"
  • Read as 32768 bytes for the Sam Coupe, which is a machine of its own in the same flag word, so selecting it clears every Spectrum bit and the trapdoor devices are switched off with it.

TRDOS.ROM optional in repo bundled
Beta Disk TR-DOS interface ROM

  • System: sinclair-zx-spectrum
  • Size: 16.0 KB
  • SHA1: 282eb7bc819a...
  • MD5: 53e2f417c699...
  • CRC32: d8882a8c
  • Source: libmain.so LoadBIOS 0x643e6-0x643f7, Speccy59-Ubuntu-x86-bin speccy 0x3db20-0x3db47
  • Opened first of all, before any machine ROM, and read as 16384 bytes. A failed open drops the interface and leaves the emulation running without it. Its presence is also what makes the 128kB model reach for ZXS128TR.ROM.

IF1.ROM optional in repo bundled
Sinclair Interface I ROM

  • System: sinclair-zx-spectrum
  • Size: 8.0 KB
  • SHA1: 5cfb6bca4177...
  • MD5: 31b704ae9253...
  • CRC32: bb66dd1e
  • Source: libmain.so LoadBIOS 0x643fc-0x6440f, Speccy59-Ubuntu-x86-bin speccy 0x3db4c-0x3db5f, Speccy.html "Fixed some .Z80 snapshots not loading when IF1.ROM is missing"
  • Read as 8192 bytes when the Interface I is on, and dropped silently when it is missing. Snapshots that page it in need it to restore.

DISCIPLE.ROM optional in repo
DISCiPLE disk interface ROM

  • System: sinclair-zx-spectrum
  • Size: max 16.0 KB
  • Source: libmain.so LoadBIOS 0x64414-0x64427, Speccy59-Ubuntu-x86-bin speccy 0x3db64-0x3db77
  • Read when the DISCiPLE interface is on, up to 16384 bytes, and dropped silently when it is missing. Neither the package nor the desktop distributions carry a copy.

PLUSD.ROM optional in repo
MGT +D disk interface ROM

  • System: sinclair-zx-spectrum
  • Size: max 8.0 KB
  • Source: libmain.so LoadBIOS 0x6442c-0x6443f, Speccy59-Ubuntu-x86-bin speccy 0x3db7c-0x3db8f
  • Read when the +D interface is on, up to 8192 bytes, and dropped silently when it is missing. Neither the package nor the desktop distributions carry a copy.

MF1.ROM optional in repo
Multiface One ROM

  • System: sinclair-zx-spectrum
  • Size: max 16.0 KB
  • Source: libmain.so LoadBIOS 0x64605-0x64651, Speccy59-Ubuntu-x86-bin speccy 0x3dea8-0x3deb7, 0x3dcf9-0x3dd0b
  • Read up to 16384 bytes when the Multiface is on behind a 16kB or 48kB machine, and the 8192 bytes at offset 8192 of what it read are copied into the page below the machine ROM. Dropped silently when it is missing.

MF128.ROM optional in repo
Multiface 128 ROM

  • System: sinclair-zx-spectrum
  • Size: max 16.0 KB
  • Source: libmain.so LoadBIOS 0x645f7-0x64651, Speccy59-Ubuntu-x86-bin speccy 0x3dcea-0x3dd0b
  • Read up to 16384 bytes when the Multiface is on behind a 128kB or +2 machine, and the 8192 bytes at offset 8192 of what it read are copied into the page below the machine ROM. Dropped silently when it is missing.

MFPLUS3.ROM optional missing
Multiface +3 ROM

  • System: sinclair-zx-spectrum
  • Size: max 16.0 KB
  • Source: libmain.so LoadBIOS 0x645cb-0x64651, Speccy59-Ubuntu-x86-bin speccy 0x3dee0-0x3dee7, 0x3dcf9-0x3dd0b
  • Read up to 16384 bytes when the Multiface is on behind a +2A or +3 machine, and the 8192 bytes at offset 8192 of what it read are copied into the page below the machine ROM. Dropped silently when it is missing. Neither the package nor the desktop distributions carry a copy.

Speccy.pal optional missing game_data
startup colour palette

  • Source: libmain.so Application 0x60436-0x60484, StartZXS 0x641c5-0x641d4, LoadPAL 0x648d0-0x64c5a, Speccy59-Ubuntu-x86-bin speccy 0x3f4ac-0x3f4bd, 0x3e450-0x3e560
  • Built as /Speccy.pal on Android and taken as the bare name beside the binary on the desktop, loaded once the machine has started and left alone when it is absent. The parser reads the file line by line, skipping blanks and comments, so a palette is text rather than a dump, and -palette points the desktop builds at another name or at one of four built-in palettes.

ROOT.chts optional in repo game_data
cheat database read by the Cheatopedia browser

  • Size: 1.6 MB
  • SHA1: 0b53d51635a2...
  • MD5: b41d9ebf8148...
  • CRC32: b58e81f1
  • Source: CheatHelper.java:17-67, Cheatopedia.java:397-427, EmuAndroid "Cheats support"
  • The package ships no cheat set. Cheatopedia looks for the file in the package assets, then in the home directory and its subdirectories, and takes it from Speccy-Cheats.zip in the Downloads directory when that is newer, unpacking it into /Cheats. The author publishes that archive at fms.komkon.org/EmuAndroid/Speccy-Cheats.zip and states it is what re-enables the cheat features Google Play made him disable in March 2019; the copy read here holds this one file.

Controls.png optional in repo game_data
virtual joystick skin

  • Size: 22.1 KB
  • SHA1: 14c4ab8ccc8e...
  • MD5: d10635cb6f10...
  • CRC32: dc9da322
  • Source: MainActivity.java:1100, LayoutEditor.java:415
  • Read as /Controls.png by the overlay button loader and by the layout editor. The author publishes the template to draw over at fms.komkon.org/EmuAndroid/Controls.png.

Backdrop.png optional in repo game_data
backdrop drawn around the emulated screen

  • Source: MainActivity.java:1287-1292
  • Read as /Backdrop.png. A built-in drawable stands in when the file is absent.

<game>.back.png optional missing game_data
backdrop for one title

  • Source: MainActivity.java:1287-1292
  • Named from the loaded program's path and preferred over the shared backdrop for that game.

<game>.pok optional missing game_data
POKE list for one title

  • Source: libmain.so LoadFile 0x65569-0x6558b, LoadPOK 0x692c0
  • Named from the loaded program's path and read by LoadPOK when present.

<game>.cht optional missing game_data
cheat codes for one title

  • Source: libmain.so LoadFile 0x65590-0x655b2, LoadCHT 0x696a0
  • Named from the loaded program's path and read by LoadCHT when present. Distinct from the .chts sets of the Cheatopedia browser.

<game>.pal optional missing game_data
colour palette for one title

  • Source: libmain.so LoadFile 0x655b7-0x655d1, LoadPAL 0x648d0
  • Named from the loaded program's path and read by LoadPAL when present, taking effect over the startup palette for that program.

Generated on 2026-08-23T16:12:06Z