FlashD0 - user guide

Definitions. Page - a substantial memory area of 16kB defined by number (e.g. 0..7). Bank - page and its configuration, defined by value (0..255) OUTed to a portu. Sector - the smallest memory (EPROM type) size that can be repreogramming at once.

FlashD0 is programmable read only memory (PEROM) for ZX Spectrum, used in place original PROM chip. In the basic version it is 128kB, seen as 8 pages of 16kB each. Memory is accessible in addresses 0..16383 (#0000..#3FFF), so replaces ZX Spectrum ROM. The original ROM chip is removed. ROM pages have numbers 0..7 and are called ROM0..ROM7. (Don't mess page names ROM0 and ROM1 of FlashD0 upgrade with names ROM0 and ROM1 of the ZX Spectrum 128K computer.)

Extra ROM pages enable to use ZX Spectrum with ROM containing various patches (e.g. errors, printer driver, character set), inststalling operating systems (ZXVGS, NeOS), placing applications in ROM (e.g. from Interface 2 cartridge) and using extra memory for files that can be loaded (e.g. PEROM-disk under ZXVGS - see description of ROM4 or simulaton of Interface 1 with Microdrive tape).

ROM banks can be switched with 208 (#D0) port. Port address was intended to be kind of hardware compatibile with Z88 computer. In Timex computers this works without problems. In ZX Spectrum 48K and 128K machines, an ULA port lock must be installed for addresses with A2=0. (This is included in ZX4MB - 4MB RAM upgrade.) Details on bankswitching are in description of the recomended purpose of the pages.

Phisically the memory is AT29C010A chip. The factory guarantees the chip can be reprogrammed at least 10000 times (e.g. once every day during 28 years). In place of this chip, usual EPROM can be used, having from 16kB to 128kB capacity. However, the oridinary EPROM the upgrade looses main part of functionality. Pages are still accessible (number of them depends on EPROM capacity), but reprogrmming is not possible. Also original ZX Spectrum PROM can be inserted into FlashD0 socket.

There also can exist a FlashD0 with 256kB PEROM (AT29C020A chip). It will provide 8 extra pages numbered 8..15 (ROM8..ROM15). In comparison to 128kB verion, requires more complicated logic and different programming code (has sectors of 256 bytes).

There is also available a small board with AT29C040 chip (512kB) surface mounted. In this case, for binary values %1xxx0cba written to 208 (#D0) port, page ROM0..ROM7 is selected (%cba=0..7, %x doesn't matter). For values %1edx1cba, pages ROM00..ROM31 are selected (%edcba=0..31). The chip has sectors of 512 bytes and also requires different code for programming.

In place of 29C010, 29C020, 29C040 (PEROM) chips, also 29F010, 29F020, 29F040 (Flash EEPROM) chips can be used. In this situation direct file writing into the PEROM-disk is not possible. These chip have sectors of 8kB, 16kB, 32kB or 64kB and only such amount can be erased (change zeros to ones). A kind of solution can be copying the PEROM-disk contents to RAM (including disk parameters), then Flash EEPROM reprogramming just after all changes in files. This requires enough amount of RAM, e.g. ZX4MB upgrade.

Caution! In the ZX4MB upgrade is installed but is not initialized by start ROM nor extrernal interface, then executing e.g. OUT 208,128 from BASIC can cause machine crash. In this situation the computer should be resetted (not switched off!), the type OUT 209,21, reset again, type OUT 210,18, again reset and type OUT 211,16. This writs correct values to bank registers and then executing OUT 208,128 will correctly switch from defaults into the values written to ports.

ROM0 - basic ZX Spectrum ROM

ROM0 is the pages, with which the computer wakes up after power-on. It is dedicated for cooperation with external interfaces, that use ZX Spectrum ROM contents (e.g. Interface 1, Timex Interface M-397 for Timex FDD, Plus D), or they exchange part of ROM into own memory (e.g. Macface 2 replaces first 2kB). Due to this, the ROM0 should not contain many patches to original ZX Spectrum ROM. It is possible to use other contents for ROM0, but be warned on problems with connecting external interfaces with own memory.

From BASIC, ROM0 can be activated by executing OUT 208,128.

Now for the ROM0 three patches are suggested. They are optional and in case of need (i.e. when problems with an interface is detected) they can be removed by flashing original ZX Spectrum ROM. (Timex computers require ROM with a patch specific to them, which does not disturb in ZX Spectrum, but is needed for correct operation.)

First patch is code that programms FlashD0 pages. To programm any page, load new contents into 32768 to 49149 addresses (#8000..#BFFF) then execute PRINT USR 1460X. In place of "X" put the page number. For page 5 this is PRINT USR 14605. Additionally, to protect against accidentally call, you need to POKE values 255 into 16384 and 16385 addresses (#4000 i #4001). To be sure the patch is installed, check addresess 14600..14614 (#3908..#3916) for zeros and the adresem 14615 address (#3917) for 121 (#79).

The second patch can safely switch to other ROM page. Execute from BASIC PRINT USR 1480X, replacing "X" with page number. In recommended configuration correct are:

Caution! After bank switching, it is enough to execute OUT 208,128 to go back to ROM0. Checking if the patch is installed is similar to above, just add 200 to addresses.

Third patch works just after power-on. It is placed at 14560 (#38E0). It initializes ZX4MB upgrade (4MB RAM) by writing to ports 208, 209, 210 i 211 (#D0..#D3) values 128, 21, 18 i 16 (#80, #15, #12, #10) respectively. This is start configuration for RAM banks organized like ZX Spectrum 128K.

ROM1 - ZXROM and TR-DOS traps for ZXVGS

ROM1 together with ROM3 are dedicated to be used as for ZXVGS FD0 purposes. They contain modified ZX Spectrum ROM, in which RST 8 calls are redirected into ZXVGS. ROM1 differs from ROM3 - in character set generator 15360..16383 (#3C00..#3FFF) it has redirection for TR-DOS calls (Beta interface) into ZXVGS. ROM1 and ROM3 are used by ZXVGS FD0, but also con be used by ZXVGS 4MB. In case you don't need ZXVGS FD0 and after removing patches specific to FD0 version of ZXVGS - ROM1 and ROM3 can be used (to support TR-DOS traps) by other ZXVGS versions, like TMX, MB2, UPB.

ROM1 can be excluded from ZXVGS FD0 by changes in ZXVGS code. ZXVGS will use only ROM3. In this situation the TR-DOS traps will not work, but ROM1 can be used for other purposes, depending on needs, e.g. like PEROM-disk (see description of ROM4), or other ZXROM version.

ROM2 - ZXVGS FD0 code

ROM2 contains main code of ZXVGS FD0. In case you don't need ZXVGS FD0, this page can be used for other ROM contents. To run ZXVGS FD0 (and while ROM0 is currently selected), execute PRINT USR 14802.


ROM3 is used together with ROM1 in ZXVGS FD0, as modified ZX Spectrum ROM. See description of ROM1.

ROM4 - EXROM and ZXVGS disk drivers

First 8kB ROM4 is dedicated to be used as EXROM of Timex 2068. If the 2068 mode is not used, this area is free for other purposes.

The first 8kB ROM4 can be used as PEROM-disk for ZXVGS. However, first 256 bytes (#0000..#00FF) are reserved for interrupts service code. So, addresses of following PEROM-disk sectors are placed in table dedicated to this. Area reserved for ZXVGS in the second 8kB ROM4 is marked in PEROM-disk as bad sectors. Unused area (usually 3kB) of the second 8kB can be occupied by PEROM-disk files. PEROM-disk has currently CP/M structure, so the memory is not exploited too optimal.

To make the PEROM-disk visible to ZXVGS and other systems, at address 14976 (#3A80) must be placed text "PEROM" followed by XDPB table (disk structure information) of PEROM-disk. At 15008 address (#3AA0) are bytes that define the banks belonging to PEROM-disku. Then, at 15040 address (#3AC0) is a tabele, whose 64 following bytes are high byte of the PEROM-disk sector addresses (256 each), and value #00 means inaccessible sector. PEROM-disk can be continued in other pages (ROM5, ROM6, ROM7, optionally ROM0..ROM3, and also ROM8..ROM15). The PEROM-disk can include also pages used as alternative ROM, what allows to reprogram such memory under ZXVGS just by writing such file. PEROM-disk in CP/M format ususally allows up to 31 files.

Second 8kB of ROM4 is uded by ZXVGS FD0 to store disk interface drivers (FDD and IDE). Spare space can be used to increase PEROM-disk size. For ZXVGS FD0 0.35 it is 3.25kB in addresses 12288..12543 (#3000..#37FF) and 15104..16383 (#3B00..#3FFF).

Below example describes PEROM-disk placed in pages ROM0..ROM7 of 128kB capacity. Decription of XDPB (27 bytes at #3A85): track has 32 sectors (#20 #00), allocation unit is 1kB (#03 #07), one directory entry defines 16kB of file (#00), last allocation unit number is 127 (#7F #00), last directory entry is 31 (#1F #00), the directory takes one allocation unit (#80 #00), there are no control sum of directory (#00 #00), there are no reserved tracks (#00 #00). Bytes behind standard DPB: phisical sector has 128 bytes (#00 #00), there are 4 sides (#03), 8 cylindrs (#08), 32 sectors per track (#20), first sector number is 0 (#00), phisical sector has 128 bajtów (#80 #00), 2 bytes are not used (#00 #00), disk type is PEROM (#1F), format is not recognized automaticly (#FF). Banks table contains OUT values used to page-in the pages of PEROM-disk. Sectors table says that first sector is at #3B00, then some next 20 are "damaged".

;XDPB table for PEROM-disku in 29C010 chip (128kB)
3A80  50 45 52 4F 4D 20 00 03  07 00 7F 00 1F 00 80 00
3A90  00 00 00 00 00 00 03 08  20 00 80 00 00 00 1F FF

;banks - values that select following PEROM-disk pages
3AA0  84 85 86 87 80 81 82 83  00 00 00 00 00 00 00 00
3AB0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00

;sectors (each 256 bytes) used inside ROM4
3AC0  3B 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F
3AD0  10 11 12 13 14 15 16 17  18 19 1A 1B 1C 1D 1E 1F
3AE0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
3AF0  30 31 32 33 34 35 36 37  00 00 00 00 3C 3D 3E 3F

If the files placed in ROM4 are fixed there and will never be deleted, a trick can be used to increase the useful space. If the last allocation unit (1kB) there are spare 256, 512 albo 768 bytes, the coresponding sectors can be marked as "damaged", while the released memory an extra allocation unit in other place can be created. However, deleting such prepared file will cause problems to write other file in this place, due to "bad sectors".

In ZXVGS FD0 0.35 pages ROM0, ROM1, ROM2, ROM3 are seen as files in "15/" directory (USER 15): "FLASHD00.ROM", "FLASHD01.ROM", "FLASHD02.ROM", "FLASHD03.ROM", each of 16kB length. Parts of ROM4 used by ZXVGS are seen as a file of 5kB length called "FLASHD04.ROM". ROM6 and ROM7 are seen as one 32kB file "ZX128.ROM" in main directory (USER 0). Only this file can be deleted, giving 32kB spare space for other files.

In 512kB PEROM the phisical sector has 512 bytes. In accordance to that, only the even bytes of sectors table are meaningful.

ROM5 - Home ROM for Timex 2068 mode

ROM5 is dedicated to be paged as Home ROM in Timex 2068 mode. Together with first 8kB from ROM4 can be used to run software dedicated to Timex 2068 machines. This mode can be invoked from ROM0 by executing PRINT USR 14805. Caution! Extra multiplexed must be installed inside the machine to make the 2068 mode working!

ROM5 can also contain other ZXROM version (e.g. SE BASIC or other modification like GOSH WONDERFUL). ROM5 can be paged in just by executing OUT 208,133 in BASIC. In this case first 8kB ROM4 are free for other purposes than EXROM.

ROM5 can also be used as continuation of PEROM-disk for ZXVGS, started in ROM4.

FlashD0 dedicated for Timex 2068 machines can have the ROM0 and ROM5 swapped. This means the ROM0 contains Home ROM 2068, while the ROM5 - ZXROM. This depends on the most often connected interface, for example such change is required by Aerco FD-68 floppy interface for Timex Sinclair 2068. With that swap the 2068 mode can work without the extra multiplexer, paging in ROM0 for Home and ROM4 for EXROM.

ROM6 - ROM0 for BASIC 128 mode

ROM6 together with ROM7 can be used to run BASIC 128, which by default welcomes in ZX Spectrum 128K. This mode is selectied after executing OUT 208,166, but making this from BASIC 48K can cause a machine crash. The recommended way is using PRINT USR 14806 from ROM0 instead.

In case you don't need BASIC 128 mode, both ROM6 and ROM7 can be used for other purposes. However PRINT USR 14806 may not start the alternative ROM placed in ROM6, because enables the switching between ROM6 and ROM7 by bit 4 in 32765 port (#7FFD). Writing to this port a value with bit 4 set, forces the ROM7 to replace ROM6. It is safer then to use OUT 208,134 instead.

ROM6 and ROM7 also can be used to continue the PEROM-disk area, started in ROM4 (see ROM4 description).

ROM7 - ROM1 for BASIC 128 mode

This page, together with ROM6 is dedicated to support BASIC 128 mode - see description of ROM6. Executing OUT 208,135 or PRINT USR 14807 from ROM0 will cause the ROM1 of ZX Spectrum 128K to be used. This ROM has extra diagnostic code, which can be activated by executing PRINT USR 0 and holding some keys.

In case you don't need ROM compatibility with ZX Spectrum 128K, this page and also ROM6 can be used for other purposes.

ROM8, ROM9, ROM10, ROM11, ROM12, ROM13, ROM14, ROM15

Pages of FlashD0 available in 256kB version. Dedicated mostly for PEROM-disk.


32 pages of 512kB FlashD0, available after mounting small board FlashD0 v201 with chip AT29C040, surface mounted. To access to pages above 7 (ROM7) set bit 3 in port 208 (#D0). When this bit is set, extra switching features are disabled (TR-DOS traps and ZX Spectrum 128K compatibility), but all 32 pages can be accessed.

Pages ROM08..ROM31 cannot be programmed nor paged directly by the support patches PRINT USR 1460X and PRINT USR 1480X. These patches work only for pages ROM0..ROM7.

PEROM-disk in CP/M format (under ZXVGS) will have around 456kB capacity, 2kB allocation units and 127 directory entries. To keep the 1kB allocation unit, it must be divided int 2 disks of 256kB and 200kB. In future ZXVGS versions the FAT12 is going to be used, having allocation units of 512 bytes. However, such disks will not be accessible from CP/M (CPM22QED).

© 2006-04-23 Jarek Adamski