ZX Spectrum ROM mods

In this blog, I will show you how to interface an Atari-style joystick to the Altera DE1 FPGA board running a Spectrum implementation, how to change the ROM to enable you to input some game-cheat pokes, and a few games I eventually completed using this setup.

Although this article revolves around my particular ZX Spectrum implementation, the code and ideas are applicable to all similar setups.

I went through my formative years playing (and eventually disassembling and hacking) Spectrum games. Thanks to a friend whose brother in Germany was supplying an incessant stream of games for the machine, I had the privilege of checking out most of them and picking only the best ones to play. Perhaps such a flood of games made me bored with gaming and more curious about software design, programming, and computer design, all of which eventually became my life-long profession and a hobby. I am sure ours is a whole generation impacted in a similar way.

Mike Singleton's Lords of Midnight
Mike Singleton’s Lords of Midnight

Those early games were creative: they required planning, strategy, and exploration instead of relying on a joystick action and a fast button tapping alone. Many of those games had puzzles to be solved, labyrinths explored and large unseen maps navigated and discovered. It is no surprise that even now, 30 years later, there is still a large number of Spectrum enthusiasts and fans playing those games and even writing new ones.

Today, these retro games could be found in many places on the web. Their bits and bytes have been processed into various file formats suitable to load directly into one of many software simulators or dedicated retro hardware boards. The files can still be used to recreate the original sounds which could then be loaded into real Spectrums or FPGA boards.

Since I wanted to load games into my Spectrum FPGA design in this old, retro way, I have written an Android app with a built-in large database of games (more than 10,000). Games can be rated, searched for, downloaded, and played as originally intended – through a high-pitch buzzing sound. Connect an Android device to your Speccy or FPGA board, press LOAD “” and sit back to enjoy the show.

You can pick up the free PlayZX Android app here.

Clearly not suited to everyone’s patience limits (there are many faster ways to load games, for example, use a DivIDE interface), loading a game this way keeps evoking those childhood memories, re-enacting that excitement of seeing and hearing a game being loaded, watching the screen border dancing in colors. Various parts of a game, having different tones, release that magic and wonder of what exactly is being loaded: screen image (easy to spot), sprites and maps (have a regular beat to it), or code (sudden jumble of pattern-less sound noise).

My 17-year old feeling challenged!
My 17-year old son is feeling challenged!

ZX Spectrum ROM

ZX Spectrum ROM was written by Dr. Steve Vickers when he was 29 years of age. Compact in design (fits in 16K), it implements a substantial version of ANSI BASIC including floating-point arithmetic, trigonometric functions, and all necessary system routines.

Dr. Vickers wrote the entire code in assembly language, on paper, with a pencil.[i] The code was assembled on a Zilog ZDS-1 system using Zilog’s assembler. [ii]

It has been disassembled and commented on, line by line, in the book “Complete Spectrum ROM Dissasembly[iii] One can learn a lot by studying that code and reading the comments.

As an example, its internal powerful calculator routines were Forth-like, stack-based which subsequently became the cornerstone of Steve’s next venture – a somewhat odd “Jupiter-ACE” personal computer. Instead of BASIC, it used Forth, a language better suited to how Steve perceived computing (he was a mathematician and a computer scientist). Eventually, it did not fare well in the increasingly crowded market where BASIC started to be the expected norm.

For those interested, this wiki page has a nice history on the Spectrum BASIC: http://faqwiki.zxnet.co.uk/wiki/Sinclair_BASIC_history

The ROM, modified

Game cheats are usually limited to giving a player an unlimited number of lives or making his character invincible. That is done by modifying one or more bytes in the program memory after a game has been loaded. Most software simulators provide an option to stop the simulation and modify memory, thus applying the cheats. On an FPGA solution, the situation is a bit trickier since the board cannot be easily stopped. A solution I used in this hack was to modify the ROM in such a way that it lets the user break and enter a cheat using normal keyboard input methods, all while the FPGA/Spectrum is running. As such, it is independent of the platform it is running on: this solution could as well be used on real Spectrum hardware with such modified ROM and an added NMI button.

An NMI (non-maskable, means it can not be disabled in software) interrupt pin, when asserted, causes the Z80 to issue a call to the address 0x66 which is in the ROM. At that address, the code is patched to jump to our custom handler which is placed high in the ROM address space at some spare locations normally not used by any code. These bytes all contain 0xFF.

This is the handler code:

The handler code reads the keyboard port and polls for exactly 8 number keys to be typed in: the first 5 digits represent the address and the next 3 digits represent a value to be set to that address. The address can reasonably be anything from 16384 to 65535 (decimal), although the code will let you input any number (a nice feature allows you to type 00000, or any address in the ROM if you had accidentally pressed the NMI button without really wanting to modify a value). A value itself can range from 000 to 256 (decimal).

After 8 digits have been read, they are processed into machine code address and value pairs after which the value is being set, or “POKE’d”, to the given address, and the control is returned to the interrupted game.

The routine is using the first line of the screen as temporary buffer storage, so as you type the numbers, you may see a line of “garbage” (as you can see below in the screenshot of Sabre Wulf while it is being poked with a cheat code).

The A-Z80 project has the updated files (both on the OpenCores and GitHub): you will find changes in the ZX Spectrum host folder both as a source and a compiled ROM binary which you can use in your own project.

Let’s Go Gaming

There are several places on the web that list a large number of POKEs, cheats, and maps. My favorite is The Tipshop (http://www.the-tipshop.co.uk).

3D Deathchase

3D Deathchase, high score
3D Deathchase, high score

POKE: 26463, 0 for infinite lives

After increasingly difficult levels, the game wraps around. I have stopped playing it after exceeding a score of 100,000.

Sabre Wulf

SabreWolf, found all 4 pieces
Sabre Wolf, found all 4 pieces

Here is the final screen which they show you once you complete the game:

SabreWolf, end screen
SabreWolf, end screen

POKE: 43575, 0 for infinite lives

A question might be raised: what’s the point of cheating in a game in order to complete it? Does not that defy the purpose of playing it or take from the enjoyment of accomplishment?

Most of us do not have much free time to dedicate to master games we once loved to play. This way, we can finally have them completed. For me, it also satisfies the curiosity I had about what happens at the end of a game and how it feels to have it finished. Yes, I could have always simply looked it up on YouTube, but actually working through games myself provided satisfaction and a certain sense of closure.

Atari Joystick

In my previous blog, I described a modification of a Bluetooth game joystick that connects to the Altera DE1 FPGA board. In the meantime, I’ve found an old-style Atari joystick in a Goodwill store which I just could not pass on. It has only a single button but a very convenient 9-pin RS232 connector. (Although there are 2 physical buttons, only one can be selected at a time using a switch on the base.)

The joystick’s connector can easily be bridged by a standard 9-pin internal cable used in PC motherboards:

SERIAL 9 PIN INTERNAL
SERIAL 9 PIN INTERNAL

Connect the other end, 2X5 header connector, directly onto the FPGA GPIO pins.

The joystick exports 5 signals: 4 directional and one from a fire button, and has a common ground pin. Pull-up resistors are not needed since Altera FPGA GPIO pins already have built-in pull-ups which should be enabled with this configuration line:

set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MyPin

This picture shows the Joystick attached to the Altera DE1 board using that cable:

Atari joystick connected to DE1
Atari joystick connected to DE1

The 2×4 header plugs in nicely to one end of a GPIO connector.

DB-9 to 2x4 header cable
DB-9 to 2×4 header cable

In the Altera Quartus project, you would define GPIO pins like this:

Lastly, define those ports in the Verilog code:

Your particular connector (and joystick pin assignment) may be slightly different, always use common sense and check before connecting.


Notes:

[i] https://groups.google.com/forum/comp.sys.sinclair

[ii] You can read more on the ZDS-1 development system here:

http://archive.computerhistory.org/resources/Zilog/102646173.pdf

[iii]  CompleteSpectrumROMDisassemblyThe.pdf

Bookmark the permalink.

2 Comments

  1. Great article(s). Greetings and many thanks.

  2. ciao Goran !
    Ho anche io una Altera DE1, sono riuscito a ampliare la tastiera sul progetto di Mike Stirling con i tasti extra come da tuo sorgente “zx_kbd.sv” ma non riesco ad implementare il joystick kemston del quale ho realizzato una board su GPIO1
    http://www.mike-stirling.com/retro-fpga/zx-spectrum-on-an-fpga/
    mi puoi aiutare?
    Grazie

    Domenico

Leave a Reply (your email address will not be published):