xzx An X11-based ZX Spectrum emulator by Des Herriott and many others Version 1.0.0 Introduction ------------ Included are instructions on how to build the emulator, some docs on how the internals work, a few other notes which may or may not be useful, and a list of the people to whom credit is due. Requirements ------------ o An X11R4 or newer server. R3 might work, but I haven't tried it. o The MIT-SHM extension is *strongly* recommended. It'll work without it, but will be SLOW. o An C compiler which supports prototypes. gcc works fine, although not in strict ANSI mode (-ansi), since xzx uses some extensions. Installing ---------- An Imakefile is provided. If your system lacks imake, there is also a non-imake makefile, "makefile.std", which you can hack about. If you do have imake (and xmkmf), then use them. To install the emulator, do the following: 0) Check the Imakefile for some tweakable defines; descriptions of what each definition does appear in the Imakefile. 1) Create a Makefile with 'xmkmf' 2) Create dependencies with 'make depend' 3) Build the emulator with 'make'. NOTE: emul.c takes quite a while to compile. 4) You can test the emulator at this point by typing 'xzx'. This should start Sinclair BASIC and give you the familiar "(c) 1982 Sinclair Research Ltd" message. If it doesn't, something's wrong. 5) You can now install the emulator and its support files by typing 'make install'; the manual page can be installed by typing 'make install.man'. xzx is known to work on the following machines/operating systems: Sparc - Solaris 2.2 & 2.3, SunOS 4.x Intel - SVR4, Linux, SCO Mips - SVR4, DEC Ultrix, SGI Irix IBM RS6000 - AIX v3.2.x Hewlett Packard - HP/UX DEC Alpha - OSF/1 Motorola 68K - Bull B.O.S. (but very slowly even on a 68040) xzx will work with monochrome displays; contrasting colours are displayed with the darker colour in black and the lighter colour in white, which works reasonably well. Halftoning is used if the scaling factor is increased. If and when you succeed in getting xzx working on other platforms, please let me know. Any diffs or descriptions of changes you made to make it work are welcome. Testing Microdrive Emulation ---------------------------- A sample cartridge file MDRTEST.MDR is supplied which contains a short test program to exercise the microdrives. Here's how to make it go. First create a scratch cartridge file with a command such as: dd if=/dev/zero of=SCRATCH.MDR bs=137923 count=1 Alternatively, there is a shell script, mkcart, to do this; just type mkcart SCRATCH.MDR Start the emulator with the additional options -m1 MDRTEST.MDR -m2 SCRATCH.MDR Now type RUN and hit enter. You will be prompted for a source drive, type 1. You are then prompted for a scratch drive, type 2. The cartridge in drive 2 will be formatted and various operations carried out on it to prove the damn thing works. If all goes well you will get an Ok - Phew! message at the top of the screen. RS232 Emulation --------------- The Interface 1 'B' and 'T' RS232 streams are connected to stdin and stdout of the emulator. So to get your listings printed on a PostScript printer a pipeline such as: xzx | dos2unix | mp | lpr -Pps should work, dos2unix allows for IF 1 'T' streams turning end of line into CRLF. If you don't have dos2unix, you can use 'tr -d \015'. And if you're using a SYSV-ish machine, you're more likely to have lp than lpr. Check your manual pages. There are also two run-time options, 'crlf' & 'strcr', which alter the behaviour of RS232 I/O. Read the manual page for a full description of what they do. Inside xzx you can type in or LOAD a BASIC program then do something like OPEN #n,'T': LIST #n: CLOSE #n to send the program to stdout. Note that this works by trapping the Interface 1 ROM and will not work if you substitute a modified ROM image. 128K RS232 emulation does not work, since I don't have any documentation on the 128K ROMs. If anyone out there does, feel free to add the emulation. Floppy Disk Emulation --------------------- As of release 0.7, xzx has been able to emaulate a +3 Spectrum, with partial support for +3DOS, the floppy disk operating system. Full support will be added in time. At release 0.7, the disk operations CAT, COPY, MOVE, ERASE, LOAD & SAVE are usable. FORMAT is not yet available. The disk format used is identical to that used by Marco Vieth's Amstrad CPC emulator, so disk images should be interchangable. An extra program, ddtrans has been supplied, with which you can translate Amstrad CPC (and Spectrum +3) disks to formats usable by xzx and Marco Vieth's Amstrad CPC emulator. (It performs a very similar task to Marco's CPCTRANS program). It should be possible to read CPC/+3/PCW format disks with the Unix dd command and use ddtrans like so: $ dd if=/dev/fd0 of=image bs=727280 # or whatever Unix device your FD is on $ ddtrans # option 1: set 'dd' file to # option 3: copy 'dd' file -> Image This will create a file named which xzx will be able to read. Have a play with ddtrans; it's menu-driven and pretty straightforward to use, though documentation is lacking at the moment. In this manner, you can transfer all your old Speccy +3 disks for use with xzx, although you will need a +3 with a 3.5" disk drive to do this... ddtrans can also be used to create blank, formatted disks for use with xzx; select option 5 from ddtrans' main menu. You will be presented with a variety of formats readable by +3DOS; choose whichever suits you best. Installing Setuid ----------------- If you build xzx on Linux with PC Speaker support, xzx controls the PC Speaker using direct inb() and outb() calls. To do this xzx must either be run by root or setuid root. Uncomment the InstallXzxSetUID definition in the Imakefile to achieve this. xzx will throw away its root permissions as soon as it gets permission to write to the speaker port, so there shouldn't be any security problems. Notes on the Emulator Internals ------------------------------- If you're planning to add or modify xzx, feel free, but I recommend reading the rest of this section. There are a couple of points worth keeping in mind. o Since xzx uses a segmented memory model, you should use the calls read_byte(), write_byte(), read_word() and write_word() to access memory. It is also possible to get to the memory directly by using realMem[ROM0..3] and realMem[RAM0..7], which are 16K pages, but make sure you know what you're doing. o If you need to report errors/messages, there's a function to do this: xzx_mesg(). Call it like this: xzx_mesg(int sev, char *fmt, ...); where can be one of XZX_INFO, XZX_WARN, XZX_ERR, or XZX_FATAL, and is a printf-style format string. If is XZX_FATAL, xzx will shut itself down with an exit code of 1. o Several unused Z80 instruction have special meaning to xzx: ED 00 - Dumps the current processor state, and wait for a keypress to continue. If 'q' is pressed, xzx will exit. ED FB - If LEVEL_LOADER is defined, activates the level loader trap. Used in hacked-up multiload games. More documentation about this can be found in ftp.ijs.si:/pub/zx/xzx. ED FC - Activates the tape loader trap. ED FD - Activates the tape saver trap. ED FE - Activates RS232 input. A byte read from stdin is placed in the accumulator. ED FF - Activates RS232 output. The accumulator is written to stdout. Credits ------- Thanks are due to lots of people, including: Nic Percival , who provided innumerable useful ideas, and spotted quite a few bugs; The authors of xtrs, a TRS-80 emulator, for inspiration on dealing with BCD arithmetic, and letting me use their disassembler module; Gerton Lunter for his excellent hardware (and .Z80 format) description from Z80 2.01, his MS-DOS Spectrum emulator. Arnt Gulbrandsen (author of JPP, another MS-DOS Spectrum emulator) for some good ideas, and letting me use his FTP site; All those who alpha tested the program and sent fixes/updates etc. - too numerous to mention here - see the ChangeLog for major contributors. The following reference materials were used during the construction of the emulator: The Complete Spectrum ROM Disassembly - Melbourne House; Programming the Z80 - Rodney Zaks.