Sinclair ZX Spectrum Emulator V2.0x 25 July 1994 ----------------------------------- This program emulates a Sinclair ZX Spectrum 48-kbyte z80-based computer on any Amiga computer. The files in this archive may be distributed anywhere provided they are unmodified and are not sold for profit. Ownership remains with the author, Peter McGavin, 86 Totara Crescent, Lower Hutt, New Zealand. e-mail: peterm@maths.grace.cri.nz (note changed e-mail address). I assume you have enough knowledge to manipulate binary files and to transfer data over a serial line without help. If you don't know what I'm talking about, don't try this program. Spectrum-00 is an executable for 68000-based Amigas only. Spectrum-10 is for 68010-based Amigas, but also works on higher processors. Spectrum-20 is optimised for 68020/30/40...-based Amigas with fast memory. Spectrum-00-special is for 68000-based Amigas. It is faster and dangerous. The Spectrum-00-special version takes some shortcuts to get some extra speed. Some games will run 2 or 3 times faster in Spectrum-00-special than in Spectrum-00, but because of the shortcuts, not all programs will work. In the special version: o Self-modifying z80 code does not work at all. This affects some games. It also means that you will only be able to run one program and then quit. If you try to load a second Spectrum program, without quitting Spectrum-00-special and re-running it first, it very probably won't work. o Code is optimised for faster animated graphics and scrolling, at the expense of speed when the display is static, so you will get faster animated games and slower ray-tracing :-) o The ROM is unprotected. Note that the standard Spectrum ROM corrupts itself. In particular, location 0 usually gets overwritten very quickly, so that NEW does not work any more. Do not try to develop or write Spectrum programs with Spectrum-00-special, because you will probably lose your work. It is provided only because it is significantly faster for running some animated Spectrum games. All the programs require the file "spectrum.rom" (not supplied) in the current directory, or they will not load. The emulator uses the dreaded move-sr instruction after almost every z80 instruction emulated. It ran 30-40% slower when I tried replacing the move-sr instruction with a call to GetCC()! This is quite exceptional --- with most programs you wouldn't notice the difference. Therefore I have supplied a 68010 version which uses move-ccr instead of move-sr. The Spectrum-20 version uses 68020 addressing modes which are not available on lower processors. The program has been tested on a 3.5 Mbyte Amiga 500 and on a 2 Mbyte Amiga 3000 (but it uses only about 300 kbytes). I developed the code, entirely in assembler, in my spare time using z80 emulation code based (originally) on Ulf Nordquist's CP/M emulator (Fred Fish disk 165). I have fixed several bugs in the z80 emulation code, and made it more than twice as fast, but there are still some (very hard to find) bugs. Features: --------- The following Spectrum features are implemented: screen output in the same resolution and colours as a real Spectrum --- includes bright, reverse and flash attributes, and border colour (looks much better than the old TV!) keyboard implemented at the z80 "in" instruction level. Note that like a real Spectrum you have to hold the key down until it registers. Because the emulator is running slower, you might have to hold keys down longer. More often, you might have to hold your fingers off the keyboard for longer. Make sure the Spectrum window is active when you start to type. See Appendix 1 for key map. kempston joystick implemented at the Z80 "in" instruction level. This uses the rear Amiga gameport. Note that the joystick is active only when the Spectrum window is active. If another Amiga program is currently using the joystick, you will get a retry/no-joystick requester. sound implemented using 2 techniques. Calls to the "beeper" routine at $03b5 in the Spectrum rom are trapped and the sound is emulated at the exact same frequency and duration. Sound is also reproduced when a Spectrum program outputs to z80 port 254. In this case the pitch and duration may or may not sound correct, depending on the Spectrum program and the speed of the Amiga you are using. cassette tape loading, if you have a sound sampler capable of at least 20 kHz sampling rate attached to your parallel port. This is implemented by trapping calls to the "ld-bytes" routine at $056b in the Spectrum rom. Note that copy-protected games with custom loaders cannot always be loaded this way. It is possible to save to and load from amiga disk files. That Missing File: ------------------ As already mentioned, a vital file is missing. You must supply an image of the Spectrum's ROM in the file "spectrum.rom". The file must be exactly 16384 bytes long and must contain exactly the same byte sequence as memory locations 0..16383 in the Spectrum. There are several ways to get this across to your Amiga, including: Use the Sinclair Interface 1 serial port connected to the Amiga's serial port. The data can be transferred using a small BASIC program on the Spectrum, then captured on the Amiga with either another small program or a comms program. Use a Spectrum disk drive system that writes IBM-format sectors, then read the diskettes on your Amiga using MSH (Fred Fish disk 382) or CrossDOS (commercial) and a sector editor like DiskX (Fred Fish disk 158). An MGT PLUS D disk drive will work for this. Find a program that will read Spectrum cassette tapes through an Amiga sound sampler, writing the data to a disk file as it goes. Kristian Nielson (e-mail bombadil@freja.diku.dk) has written a program that will do this. Try looking for specload.lzh at your local PD site. Find another Spectrum emulator that comes with the ROM code. Rumour has it that there is an Atari-ST Spectrum emulator comes with the ROM code. I'll leave it up to you to figure out how to get the data across. You could always type it in :-) There are several third-party books that list the code, e.g, "The Complete Spectrum ROM Disassembly" by Dr Ian Logan and Dr Frank O'Hara, Melbourne House Software Ltd, ISBN 0 86161 116 0, or ISBN 0 86759 117 X, 1983; "The Spectrum Machine Code Reference Guide" by Richard Ross-Langley, Interface Publications, ISBN 0 907563 51 1, September 1983. I believe that Spectrums have been sold with several slightly different ROMs, including Scandinavian and Argentinian internationalised versions. Also various ROM patch hacks have been distributed around user-groups (requiring a personal ROM burner to apply). Any ROM should work, but I have not been able to test them all. A non-standard version should behave in the emulator exactly as if it was installed in a real Spectrum. In fact you can supply any 16384-byte file containing valid z80 code and called spectrum.rom. The emulator will transfer z80 control to location 0. Screen and keyboard hardware is programmed the same as a real Spectrum. (Once loaded, the first 16384 memory locations are readonly.) Please don't ask me to e-mail spectrum.rom to you, because I won't. Operation: ---------- You can start the emulator from either the Workbench or SHELL (or CLI). There are no command-line parameters. If you use the SHELL (or CLI), spectrum.rom must be in the current directory. From the workbench, spectrum.rom should be in the same directory as the program. If the emulator can't find spectrum.rom, then it will display a requester saying so, and it will not run. To use the ARP file requester, you must have arp.library installed in your LIBS: directory. The emulator runs in its own custom screen and window. The emulator does not disable multitasking, and it does not interfere with other tasks (except when loading from a sound sampler). You can drag the screen down or click it to the back with the mouse, in the usual way. (Grab the screen bar to the left of the window to pull it down.) The emulator lowers its own priority to -5, otherwise it would significantly slow down other tasks. Raising the priority back to 0 (e.g, with xoper or artm) does not significantly speed up the emulator on a standard system. Raising it higher will prevent most other tasks from running at all. To exit the emulator, do any of the following: o click the close box with the left mouse button; o select "Quit..." from the Project menu, or o press the ESC key. Menus: ------ Project menu Reset... Resets the z80, unless you cancel the requester that pops up. This is like the Spectrum NEW command, but it works even when you are running an "unbreakable" or "crashed" program. Load snapshot... F1 Loads a disk file that has been created with "Save snapshot", restoring the state of the system to what it was when the snapshot was made. Any currently loaded Spectrum program is lost. Uses the ARP file requester. You can use "Load snapshot..." even if the Spectrum has "crashed", or if you are running a Spectrum program which does not have a "quit" option. Save snapshot... F2 Saves the current state of the emulator to a disk file. The entire state of the system is saved, including all 48 kbytes of Spectrum ram and the state of the z80 processor. Uses the ARP file requester. The format of a snapshot file is listed in Appendix 2. Help... HELP Displays the "Spectrum.help" file, which is a diagram of a real Spectrum keyboard. You need about 70 kb of CHIP ram free for this. Quit... ESC Quits the emulator. (You get a chance to change your mind.) Settings menu LOAD/MERGE/VERIFY... Selects what happens when the emulator executes a Spectrum BASIC LOAD, MERGE or VERIFY command. Note that this has nothing at all to do with "Load snapshot", which always loads from disk. What it does do, is to change the behaviour of the standard Spectrum BASIC tape loading commands, which are normally used to load, merge and verify BASIC programs, array data and binary code, from cassette tape. In fact, this selects what happens when any program (including any machine code program) calls the cassette tape loading routine in the Spectrum rom. You have a choice of: Disk files Select a disk file using the ARP file requester. The data in the file is interpreted as if it is being read from cassette tape. The first byte in the file is the "header" byte, then the raw data, then the checksum byte. The Spectrum normally reads 2 blocks of data from cassette tape, a "header" file followed by the "data" file. These should be stored in 2 separate disk files. The emulator will request both files. I implemented it this way to allow support for "headerless" files which are used by many Spectrum machine code programs. Note that the Spectrum still thinks it is reading from cassette tape, so you might see messages like "Start tape now", even though it is reading from disk. If the file you select is not in the correct format, or if the checksum is wrong, the Spectrum will usually just request the same file again, without any messages, as if it read garbage noise from cassette tape. ProSound Read data from a ProSound sound sampler connected to the parallel port. Rombo Read data from a Rombo sound sampler connected to the parallel port (the sampler that comes with MegaMIX Master software). Please note that this option is untested. Other sampler Read data from any other kind of sound sampler connected to the parallel port. The sampler must be capable of at least 20 kHz sampling rate and it must be connected to the parallel port (not the game port). You should be able to feed standard Spectrum cassette tapes in. Some copy-protected programs have custom loaders that will not work in the emulator. It is possible to connect the Spectrum EAR output to the sound sampler to transfer data directly from your Spectrum. (Use a SAVE command at one end, and a LOAD at the other.) Important: Interrupts on the amiga are disabled while you are loading from a sound sampler. This will interfere with other tasks. For example, a file transfer running in the background will probably fail. Please make certain that no other tasks are writing to disk at the instant you start sampling! You have a choice of: Disk files Select a disk file using the ARP file requester. The data that would normally be written to cassette tape is written to the selected file instead. The first byte in the file is the "header" byte, then the raw data, then a checksum byte. The Spectrum normally writes 2 blocks of data to cassette tape, a "header" file followed by the "data" file. These should be stored in 2 separate disk files. The emulator will request both files. I implemented it this way to allow support for "headerless" files which are used by many Spectrum machine code programs. Note that the Spectrum still thinks it is writing to cassette tape, so you might see messages like "Start tape, then press any key". Audio Not implemented in V2.0. More on Reading Cassette Tapes: ------------------------------- To load a cassette tape through your sound sampler, first select your sampler type in the Settings menu, then enter LOAD "" (that is, J followed by ALT/P twice, then RETURN). Now start the cassette tape playing into your sound sampler. If it is working, the screen border should flash colours, very much like your Spectrum, and the mouse pointer will be frozen. The MERGE and VERIFY commands should also work, as should things like LOAD "" CODE, etc. The border of the screen flashes different colours, exactly like a real Spectrum. The colours mean: flashing yellow and blue: the load is working flashing red and white: synchronising or not working not flashing: not working or tape not playing If it doesn't work, try adjusting the volume and tone controls on the tape recorder. If you have trouble, try adjusting the controls while sampling with software that came with your sampler. Ideally, the input should be a square wave which fills the graphic display. I found it necessary to have the volume control much lower than when using a real Spectrum, but it probably varies, depending on the sampler type. You should be able to save directly from your Spectrum to the Amiga with a direct connection --- i.e, no cassette tape or recorder at all. Use a SAVE command on the Spectrum and a corresponding LOAD command in the emulator. Loading works by intercepting calls to the LD-BYTES routine at location $056b in the Spectrum ROM. If a Spectrum program has its own loading routine, then it won't work. Some copy-protected games and fast-loaders are like that, and they will not work. On the other hand, some Spectrum programs call LD-BYTES to load headerless tape files. Those programs should work fine. If you have been using the parallel port recently (for printing or ParNet for example), you might get a requester asking you to please free up the parallel port. Try shutting down the program that has allocated it. The following sound samplers should be suitable, but I have not had the opportunity to test any except the first: o ProSound o Rombo (the one that comes with MegaMIX Master) o Perfect Sound (except that recent Perfect Sound samplers are different from early versions and recent ones might not work) o Datel DSS o Future Sound Documentation on how various samplers work seems to be hard to obtain. They all seem to be slightly different, especially the way stereo/mono modes are switched and different channels are selected. For the technically minded, here are the cia register settings currently used by the loader: ProSound Rombo Other setup ciab-ddra 4 7 6 setup ciab-pra 4,0 or none * 6 4 inter-sample ciab-pra 4,0,4,0 none none ciaa-prb input bias $80 $80 $80 * If bit 0 of ciab-pra is 0 then output 4 followed by 0 else none. Note that the tape-loading routine disables interrupts for the whole time it takes to load a tape. That greatly exceeds Commodore's recommended limit of 250 microseconds. While interrupts are disabled, the mouse pointer freezes, the keyboard is locked out, all other tasks stop, and any data arriving at the serial port is lost. Please make sure your disks are not busy when you start to load a tape. Especially make certain that no other program is writing to your hard disk! If I knew another way to make it work, I'd do it that way. As far as I am aware, all sound sampling software on the Amiga disables interrupts for excessive periods. The Spectrum loader has to interpret the incoming data in real time, which is quite a lot more than just saving it to a buffer in memory. To break out of the load routine without actually loading anything, press the left mouse button. The Spectrum BREAK key (SHIFT/SPACE) won't work in this situation. If the keyboard doesn't work after you break out with the left mouse button, it's probably because you accidently deselected the window (by clicking outside it). Just click anywhere inside the Spectrum window and the keyboard will work again. The load routine is based on code kindly provided by Kristian Nielson. It has been tested on both standard and accelerated amigas. General Notes: -------------- o The emulator runs about 2 to 8 times slower than a real Spectrum, on a standard 68000-based A500. If you are the lucky owner of an Amiga 3000, the emulator runs faster than a real Spectrum, but make certain it's running out of FAST ram. If you run it out of CHIP ram, then it's more than twice as slow. I'm afraid the 68000 doesn't have a built-in z80 emulation mode, and a 3.5 MHz z80 is much harder to emulate than a 6502 as used in the Commodore 64 and BBC microcomputers. The Spectrum NEW command takes 9.7 seconds on an A500, compared with about 2.0 seconds on a real Spectrum, 1.8 seconds on an A3000 (in FAST static-column ram), and 1.6 seconds on a 33MHz Mega-Midget-Racer with 32-bit ram. One person reported to me that it runs about 3 times faster again on a 68040. o This version of Spectrum uses the blitter to refresh the screen in parallel with the emulator. That is, it uses multi-processing. Thus, the overhead of a z80 instruction writing to the Spectrum's display file is minimised. Before you A3000 owners complain that the 68030 is faster than the blitter for blitting, remember that while the blitter is refreshing the screen, the 68030 is busy emulating the z80. The program uses QBlit() for concurrency, not OwnBlitter() which would block the z80 emulator. o I've just about run out of ideas on how to significantly speed up the code from what it is now. One thought is to code some common ROM routines in pure 68000. Obvious candidates are the text output, scrolling, and maskable interrupt routines. Of course this would only speed up programs that call the ROM, which excludes most games. Also, It would probably be illegal. The major speed bottleneck used to be the z80 instruction decode. I've pretty well eliminated that by going to threaded code. The display routines are about as fast as I can get them. Taking over the machine and doing everything at the hardware level would probably give only a slight speed improvement, and the program would become much less friendly and less portable. o In version 2.0, the following Spectrum features are NOT implemented yet: saving to cassette tape; bank roms (e.g, Interface 1); printing to a printer o The following z80 features are NOT properly implemented: the z80 h processor flag; the z80 daa instruction (decimal adjust a) --- daa works properly only immediately after add, sub, adc or sbc; the timer interrupt occurs after every 1500 branch, jump, call and return z80 machine instructions, instead of every 20 ms. On accelerated amigas, interrupts will not occur any faster than every 20 ms. updating of the flash attribute occurs every 24000 branch, jump, call and return z80 instructions, instead of every 320 ms. On accelerated amigas, the flash speed will never be faster than every 320 ms. interrupts and screen updates can occur only immediately after branch, jump, call, return and halt z80 machine instructions. because the emulator is not real-time, the real interval between timer interrupts and flash attribute updates depends on the nature of the Spectrum program being run. there might still be rare problems executing certain long, self-modifying z80 instructions located at exactly 32763..32766 in z80 memory, because of the 68000 addressing modes used to load instruction operands; there is at least one other bug I haven't been able to track down yet. o The emulator allocates and uses two sound channels. If there are not enough free channels, you get the option of running the emulator with no sound. If you have enough memory you can test this by running 3 copies of Spectrum at once! o Because it's running slower, maybe now you can get past that "impossible" level in your favourite game. o Now you can print Spectrum graphics by transferring to your Amiga. o If you're cross-developing Spectrum software, now you can see which parts need speeding up. o I've tested it with several Sinclair Basic programs and all ran perfectly. o I've tried lots machine-code programs and most work ok. The following programs seem to work ok in the emulator: Zeus Assembler and Monitor Scrabble Jetset Willy Atic Atac Jetpac Tron The Train Game Backgammon PSSST Horace and the Spiders Sam Spade Draughts Sam Stoat 3D Deathchase Technician Ted Kosmic Kanga Monty Mole Talk Chess Horace Goes Skiing Hungry Horace Star Raid Cyclone Wheelie Full Throttle Mugsy Dynamite Dan Dynamite Dan II Heathrow IS Chess 48 Matchpoint Max Headroom no joystick Spy vs Spy Kong The Alchemist Daley Decathlon Automania Penetrator Gyron Alien8 Cyberun KnightLore Batman Tomahawk Fighter Pilot Athena Basil the Detective Pacland Orbix Meteor Manic Miner Madmix Kokotoni Wilf Ikari Warriers Gauntlet Dustin Ant Attack St Bernard resets the Spectrum at the end of the first level. SabreWulf runs, except sometimes the rhino runs backwards (very amusing). (If you know why either of these programs don't work, please tell me.) Note: The Amiga doesn't crash. If a Spectrum program crashes, you can either: Quit the emulator and continue working on the Amiga, or: Press F1 and load another snapshot. Note: Some of the above have not been tested since Spectrum v0.7 or v0.8. Another note: Some of the above programs won't load from tape, but they will run if you can create a snapshot file somehow (e.g, Mirage Microdriver and serial port). o One problem I have had with snapshotting games by transferring a snapshot file from the real Spectrum to the amiga, is as follows: If there is non-standard hardware in your real Spectrum (like a non-standard joystick or disk drive), and the program knows about the special hardware, then the program might have already done a hardware test (before you made the snapshot) that makes it believe the special hardware exists permanently. Then, when run under the emulator, the program tries to access the non-existent hardware and behaves erratically. What is wrong is that the program was started in one environment (the real Spectrum with add-ons) and is now running in another (the plain Spectrum emulator). For example, if your program behaves as if the joystick button is continuously pressed (when run in the emulator), maybe it is because you made the original snapshot from a Spectrum which has non-standard joystick hardware. See if you can disconnect the joystick interface and reload the original program from tape before you make a snapshot. o If the keyboard, joystick and/or menus do not respond at all, well, then... er... umm... --- try clicking in the window :-) o I am not supplying the source of the emulator yet. o Please report bugs to peterm@maths.grace.cri.nz. I'd much prefer bug reports like "the `or' instruction doesn't zero the carry flag" to "Dan Dare doesn't work". Appendix 1: The keyboard: The Spectrum has a weird way of mapping functions to keys that doesn't translate nicely to the Amiga. To get a "[" on a real Spectrum, for example, you press CAPS-SHIFT and SYMBOL-SHIFT together followed by SYMBOL-SHIFT and F. In the emulator, you do the same thing except CAPS-SHIFT is either of the SHIFT keys and SYMBOL-SHIFT is either of the ALT keys. Pressing "[" on the Amiga keyboard won't work. The following table lists the Amiga key(s) corresponding to each Spectrum key: Amiga key Spectrum key 0..9 0..9 keypad 0..9 0..9 A..Z A..Z SPACE SPACE RETURN or ENTER ENTER either SHIFT key CAPS-SHIFT either ALT key SYMBOL-SHIFT The following special Amiga keys correspond to Spectrum key combinations. Amiga key Spectrum key combination . SYMBOL-SHIFT/M , SYMBOL-SHIFT/N ; SYMBOL-SHIFT/O - SYMBOL-SHIFT/J = SYMBOL-SHIFT/L keypad ( SYMBOL-SHIFT/8 keypad ) SYMBOL-SHIFT/9 keypad / SYMBOL-SHIFT/V keypad * SYMBOL-SHIFT/B keypad - SYMBOL-SHIFT/J keypad + SYMBOL-SHIFT/K keypad ENTER ENTER keypad . SYMBOL-SHIFT/M left arrow SHIFT/5 down arrow SHIFT/6 up arrow SHIFT/7 right arrow SHIFT/8 ESC quits the emulator (unless you cancel the requester that comes up). HELP displays the Spectrum.help file, which is a diagram of the real Spectrum keyboard. (You need about 70 kb of CHIP ram free for this.) F1 brings up the load snapshot requester (provided arp.library is installed). F2 brings up the save snapshot requester (provided arp.library is installed). F3 changes the sampler type for cassette tape loading. All the other Amiga keys do nothing. Appendix 2: Snapshot file format: This format is based on the format used by the Mirage Microdriver "Dump" command. Snapshot files are always 49179 bytes long. Note that in the table, the byte offset starts from 0, not 1. Byte offset into file Value 0 i register 1 l' register 2 h' register 3 e' register 4 d' register 5 c' register 6 b' register 7 f' register 8 a' register 9 l register 10 h register 11 e register 12 d register 13 c register 14 b register 15 iy low register 16 iy high register 17 ix low register 18 ix high register 19 bit 2 is set if interrupts are enabled 20 r register 21 flags register 22 a register 23 sp low register 24 sp high register 25 interrupt mode (0, 1 or 2) 26 border colour in low 3 bits 27..49178 48 kbytes ram dump Appendix 3: Other Spectrum Emulators: When I started this project I did not know of any other Spectrum emulators. Now I have heard of at least 12, including this one, in various stages of development. 1: This one. 2: The public domain K.G.B. emulator advertised in "Amiga Format". I have seen only version 1.2 which does not multitask and does not work properly on my A3000. 3: An Italian emulator was released (possibly commercially) about 3 years ago. The version I saw was very bug free and worked on accelerated amigas, but it did not multitask and was slightly slower than mine. 4: An emulator is under development in Sweden. 5: Another emulator, intended to be commercial, was written in Holland, but it was never released as far as I know. From what I have heard about it, it is much faster than mine. 6: The Whitby Software Spectrum Simulator is a Spectrum ROM rewrite for the C64. It runs just fine under TheA64Package and is surprisingly fast. Because it is a ROM rewrite and not a z80 emulator, you cannot run z80 machine code programs (i.e, most games). 7: VGASPEC is a Spectrum emulator for the IBM-PC and clones (not for the amiga). A VGA graphics adaptor is required. I think it was developed in Spain or Portugal (I don't recognise the language that all the messages are written in). 8: JPP is another Spectrum emulator for the IBM-PC and clones, developed recently by Arnt Gulbrandsen. An 80386 and VGA are required. It is faster than VGASPEC. The name JPP is derived from the keys you press to get LOAD "". 9: There is another very good Spectrum emulator for the IBM-PC. From memory I think it is called Z80. 10: There is a Spectrum emulator for the Atari ST available from various ftp sites. 11: I heard from one person working on a Spectrum emulator for the BBC RISC computer (status unknown). 12: I have heard rumours of other emulators in various stages of development in Australia and Germany for platforms including the Amiga, the IBM-PC and Unix/X-Windows. There is a good collection of Spectrum emulators available by ftp from wuarchive.wustl.edu and its mirrors. Programs to convert between various snapshot formats are also available there. Appendix 4: Update Notes: v0.0 22 Oct 1990 First release. v0.1 15 Nov 1990 Sped up display code slightly. Also sped up main instruction decode slightly. Display flash attribute as reverse. v0.2 30 Dec 1990 Now use double buffered display and implemented flash attribute properly. Added error requesters. Used pc-relative jump tables in z80 emulator --- slightly faster, and much, much smaller. v0.3 20 Jan 1991 Changed display routines to update screen periodically instead of after every z80 instruction that pokes the Spectrum's display file. Used the blitter for this, running in parallel with the z80 emulator. (Only character rows that have changed since the last screen update are redrawn.) Reverted to single buffer display and used blitter to implement flash. (It's smaller and faster this way.) Fixed bug where couldn't use path string in arp file requester. v0.4 Changed the z80 emulator to use threaded code. Now all that is executed between each pair of z80 instructions is "move.w (a3)+,d6; jmp table(pc,d6.w)" instead of about ten 68000 instructions to decode the next z80 opcode byte. Overheads introduced are a new 128 kbyte table giving the routine offset for every byte in z80 ram, and the necessity to write a zero word into this table every time the emulator writes to z80 ram. The overall speed increase is about 20%. Expanded some subroutines to macros and expanded $dd and $fd prefix instructions to independent code for a slight speed increase. A side-effect is that the executable increased in size from 27k to over 40k. Introduced some bugs during the systematic changes that are proving hard to track down. v0.5 7 Apr 1991 Fixed bug in "sra a" instruction. Fixed bugs in rotate and shift (ix+d) and (iy+d) instructions. Fixed bugs where used "offset(a4,rr.w)" to address z80 memory space where offset is -2, -1, 1 or 2. (Can't use that mode because of the unlikely event of rr.w being near $8000.) Implemented mode 2 interrupts. Low byte of interrupt vector (normally provided by an external peripheral device) is assumed to be 0. Increased the interrupt interval from 2500 instructions to every 5000 instructions, because otherwise some programs with their own (mode 2) interrupt routines overflowed the stack. v0.6 23 Apr 1991 Fixed bugs in the following z80 instructions: ld ixh,b ld ixh,d rl (ix+dd) rr (ix+dd) sla (ix+dd) cpdr and iy equivalents of the above instructions. Implemented ini, outi, ind, outd, inir, otir, indr, otdr. (Out instructions do nothing). Now preserve (otherwise) unused flag bits in push af, pop af and ex af,af' (instead of setting them all to 0). Changed layout of vector table for threaded code (origin now in middle). Fixed bug in vector table wraparound code (when pc incremented from 32767 to 32768). Sped up ram writes by optimising macro for writing a byte to ram. Added processor type check. Now you get a requester when you try to run the wrong version for your processor type, instead of "Software Error, Task Held". Implemented sound by opening audio.device and trapping calls to the "beeper" subroutine at $03b5 in Spectrum ROM. v0.7 Optimised blits to update flash attributes by keeping track of which parts of the display are flashing and updating only those parts. That saves a lot of blits. No blits are needed at all when there are no flashing characters displayed. It used to redraw the entire display for every blink. v0.8 13 May 1991 Further optimised the display routines by adding a 6144-byte lookup table. v0.9 22 Jul 1991 Lower task priority to -5 at startup. This is friendlier to other tasks because Spectrum is highly CPU intensive. If Spectrum is running at a higher priority than another task, then that other task is completely blocked. Sped up the emulator by 5% by checking for interrupts only after branch, jump, call and return instructions, instead of after all instructions. Open gameport.device and emulate Kempston joystick (at Z80 "in" instruction level) using the rear Amiga gameport. v0.9b 1 Sep 1991 Implemented all the undocumented z80 sls instructions. Fixed bug in ld (nn),sp instruction. (It didn't work at all!) Implemented the z80 n flag --- all instructions now set/reset the n flag. Fixed bugs in inc/dec (hl), inc/dec (ix+dd) & inc/dec (iy+dd) (never set v). The daa instruction now works correctly after add and sub (not just adc & sbc). Incorporated Kristian Nielson's tape load routine. Allocate/free misc.resource. Added "File already exists! Overwrite?" requester (in save snapshot). Fixed keypad 0 key. Rationalised keyboard. Arrow keys are now equivalent to SHIFT+5/6/7/8 instead of 5/6/7/8 (without the SHIFT). ESC key quits. The halt instruction now calls WaitTOF(). (Was too fast.) The Spectrum Basic PAUSE function now works correctly. Added a separate timer task to prevent interrupts occurring too quickly. The "flash" rate and keyboard interrupt rates are now more constant. The HELP key now displays Spectrum.help IFF/ILBM file from current directory. Reorganised register usage in z80 emulator to try to speed it up (lots of work but not much success). v1.0 9 Nov 1991 Implemented menus. Added noise correction code to cassette tape loader. Added support for 2 kinds of sound samplers. Screen to front after error requester in IFF loader. Use an interrupt server instead of extra task for timer. Further optimised blitter routines. Put z80 parity byte in a register (slight speedup). Implemented ld-bytes and sa-bytes to/from disk. v1.1 Dec 1991 Created 68020 version (uses 68020/30/40-only addressing modes for extra speed) Moved z80 address space to FAST RAM with a copy of 16384..22527 in CHIP RAM (instead of having the whole Z80 address space in CHIP RAM). Added more undocumented z80 instructions. Sped up display routines by changing update algorithm. Animated graphics and scrolling are now faster by a factor of 2 or 3. v1.2 7 Jan 1992 Rewrote joystick handling routines to avoid continuous polling. v1.3 Feb 1992 Implemented a much faster algorithm for handling z80 prefix instructions that was suggested to me by Richard Carlsson. Preserve high bit of R register between LD R,A and LD A,R, and also in snapshot files. Tomahawk works now. GetCC() is now documented to preserve d0/d1/a0/a1. Fixed movesr macro. Mode 2 interrupts assume $ff is on the external bus, not $00. This change fixed quite a few games. Fixed glaring bug in "set 4,l" instruction. Sabre Wulf, Fighter Pilot, Basil the Detective, Athena and lots of other programs work now. Changed implementation of daa instruction to speed up add/adc/sub/sbc instrs. Use blitter to do comparisons as well as copies in display updater. Sped up CPU computation of blitter attribute masks in display updater. Display updater now translates black to bright black on the fly. This leaves a colour register free for the border colour (one day). Fixed bug in display updater that caused flashing to fail sometimes. v1.4 17 Mar 1992 Changed ld-bytes ROM patch entry point from $0556 to $056b to be compatible with more programs. v1.4a 22 Mar 1992 Sped up LDIR by calling CopyMem(). This nearly doubled the speed of some programs (e.g, ManicMiner and JetsetWilly). Increased the interrupt rate and screen refresh rate when executing lots of large LDIRs. v1.5 27 Dec 1992 (This version later abandoned) Major revamp of z80 emulator, as suggested by several correspondents (3 days' work). Implemented conventional decoding scheme for z80 instructions, and did away with threaded code tables and the overhead of updating them on every write. 68000 and 68010 versions now use 2-instruction decode (self-modifying) as follows: move.b (a3)+,1$+2-base(a5) ; get opcode and modify next instr 1$: jmp $ff00(a5) ; jump directly to next instruction 68020/30/40 version uses a slightly longer macro to avoid self-modifying code. Instruction routines are all exactly 256 bytes in size and the total size of all 256 routines is 64 kbytes. Added about 5 more such 64 kb blocks of code for prefixed instructions. Managed to interleave all the 64 kb code blocks so that they effectively reduced to a single 64 kb code block (even sharing the same base address register but each table having a different byte-offset). About 25 instruction routines didn't fit in their allocated space and required long jumps to routines elsewhere. Several features broke, including ROM write-protection, invisible ROM-hooks for load/save/beep, (in fact I did not re-implement ROM hooks, so loading, saving and sound did not work at all), daa mechanism, fast prefix mechanism, potential to treat common sequences of instructions as a single instruction with no overhead, etc. Speed was almost exactly the same as v1.4a (which still had the broken features intact), and there seemed to be no significant advantages. v1.6 25 Jan 1993 Gave up on conventional decoding and reverted to v1.4a sources. Implemented border colour (at last!) Made window borderless and changed colours. The old "filler" byte in the snapshot file format now holds the border colour. Added "Reset" menu item. Changed sa-bytes ROM patch entry point from $04c2 to $04c6 to be compatible with more programs. The ld-bytes and sa-bytes routines were not always setting the de, ix and flag registers on return, causing some tape-copying programs to fail. Corrected the problem. File-names longer than 10 characters passed to the SAVE command could crash the amiga. Corrected the problem. Added support for Rombo sound sampler (the one that comes with MegaMIX Master). I do not own a Rombo sound sampler and I have been unable to test this option. (I used information provided by a correspondent in Portugal, who also informed me that v1.4a did not work with his Rombo sampler.) Implemented sound at the z80 port 254, bit 4, level. Changed keyboard handling code to precalculate the most common z80 port address values whenever a key is pressed or released, instead of doing a full calculation every time an "in" instruction is executed.