Dungeon levels

Dungeon levels are stored on an 8×8 grid. They loop at the edges. Each tile is stored in four bits as follows:

0000 empty
0001 magical barrier
0010 illusionary wall
0011 wall
0100 door
0101 locked door
0110 180 rotate pad
0111 banner
1000 stairs down
1001 poison field
1010 stairs up
1011 lightning field
1100 pit trap
1101 flame field
1110 falling rocks
1111 sleep field

Non-player characters

Non-player characters are not restricted to the player character gender, classes, or races. The engine can support up to 256 NPCs.

NPCs have the following dialog attributes:

  • Name
  • Gender (he, she, it, they)
  • Visual Description
  • Self Description of Occupation
  • Self Description of Health
  • Key Word #1
  • Special Knowledge #1
  • Key Word #2
  • Special Knowledge #2
  • Y/N Question
  • Response to Answer Y
  • Response to Answer N
  • Monetary Threshold
  • Response to Money
  • Action Response

It is also possible to set a flag on the following questions:

  • Question Y
  • Question N

ZX Spectrum +2B technical specification

Some background on the target platform. The original ZX Spectrum was launced in 1982. In some regards it can be considered the British equivalent of the Apple ][ as it used a variety of hardware tricks to keep costs down. In 1985 Sinclair launched the Spectrum 128 in Spain. In 1986, before they had even bought the company, Amstrad had tooled up to produce a clone of the 128, the Spectrum +2. In 1987 Amstrad launched the Spectrum/PCW hybrid, the Spectrum +3 with a disk drive. After the existing stock of gray-cased +2s were sold, Amstrad briefly sold the black-cased +2A with depopulated +3 motherboards. It soon replaced these motherboards with a cut down design that removed the disk functionality entirely. This was the +2B, although it still said +2A on the case. It was manufactured between 1988 and 1990 and continued to be sold until at least 1992, making it the most common variant of the Spectrum 128.

  • CPU: Zilog Z80A @ 3.5469MHz.
  • RAM: 128K in eight banks of 16K (pageable in the top 16K of the address space).
  • Video: ULA provides 256 x 192 pixels, 15 colours, two colours per 8×8 pixel cell. The ZXodus][Engine rapidly updates the attributes to provide a view window of 144×144 pixels with 8×1 sized cells.
  • Audio: AY-3-8912 three channel, eight octave programmable sound generator and 1-bit CPU-driven audio.

Memory use

The ZXodus][Engine is designed around the hardware limitations of the ZX Spectrum +2B. The RAM is divided into eight banks of 16K. Half of those banks (the last four) have shared access with the video ASIC and suffer additional timing delays. Also, most of the banks are available only in the top 16K of the Z80’s 64K address space. Because the display routine is timing intensive, compression is only used for infrequently accessed data.

The address space contains the following banks:

C000-FFFF: any
8000-BFFF: bank 2
4000-7FFF: bank 5
0000-3FFF: ROM

The RAM is used as follows:

bank 0: 2D tiles
bank 1: 3D tiles
bank 2: executable (game logic)
bank 3: dungeon maps + compressed music
bank 4: world map
bank 5: frame buffer + font + temporary work space
bank 6: compressed town maps + encounter maps
bank 7: compressed text + dialog trees

Reading the keyboard

I’ve finally started writing the console. The first task is to read the keyboard. This is done by polling eight different I/O addresses and seeing which bits are cleared to determine which of 40 keys has been pressed. One of those keys is the shift key, which modifies the number keys to do things like backspace and the cursors. Depending on the bit set I’ll end up with a number for each row of 16, 8, 4, 2, or 1, which I then have to convert into a value in the key look-up table. Ideally I want the routine to place the key read in the accumulator without storing anything in memory. This will take some more thought.