ZX Spectrum 48K emulator
Download at another page
Welcolme to ZX SPECTRUM 48k Emulator v4.0 readme file.
ZX SPECTRUM 48k Emulator v1.1 - v4.0 is (c) Martijn Groen 2001.
Many thanks & credits to Edwin Blink for tips, ideas and parts of B-DOS source code. Also many credits go to Robert van der Veeke for lending me his ZX Spectrum ROM disassembly book. And infinite credits go to Dr. Ian Logan & Dr. Frank O'Hara for disassembling the ZX SPECTRUM 48k ROM. Additional credits go to James McKay (x128), Gerton Luntor (Z80), Rui Ribeiro (WSpecEm) and others for designing the .SLT format and for placing lots of technical information on the internet.
* B-DOS v1.7p or higher
* Z80B 6 Mhz processor or higher recommended
* 256 KB RAM required
* Harddisk with at least 1 available record
* DALLAS & SAMBUS-clock supported
* Optional: Triple joystick interface splitter (from Edwin Blink!) for Kempston joystick emulation.
* Optional: Atapi CD-ROM drive, printer
This Emulator was basically written for game playing. Spectrum programs which were specifically written for special hardware, such as Disciple/+D won't work as they should do.
Supported file formats:
Normal programs: standard tape & Disciple/+D programs, TAP filessnaps: Snapshot 48k, SNA, SP, LERM3 files & Z80 (v1-v3.0x) level loaders: Disciple/+D using hookcodes, TAP & SLT files
This Emulator supports standard 48k SP files, which come from Spanish Spectrum emulator by Pedro Gimeno and not the ones that come from VGASpec emulator which is the illegal prerelease of the Spanish Spectrum emulator.
Supported file types on SAM disk/record:
Disciple (I guess +D too) Basic programs, Data/String arrays, Code files, Screen$ files & Snapshots 48k. Many Disciple & +D multi-loaders are also supported (hookcodes). Files saved by this emulator can be read by Disciple/+D again.
SAM CODE: file.SNA, file.SP, file.LRM, file.TAP & file.Z80/SLT If you want to use SLT (super level loader trap) files on SAM disk/record you have to rename them first to "xxxxxxxx.Z" TAP files: "xxxxxxxx.T" , SNA or SP files: "xxxxxxxx.S"
C/DVD-ROM: file.SNA, file.SP, file.TAP, file.SCR, file.Z80, file.SLT and file.POK
* Warning *
Always use RUN or F4 to return to the Emulator if you are in SAM Basic.
Although the Emulator will work with RECORD 0, it is recommended that you copy your Spectrum files to harddisk. If you have any problems running the ZX48 Emulator, try installing the latest Direct ZX drivers.
I have found out that the PLUS-D version of PAW (A16D) is fully compatible with my Emulator, except you can't switch drives Using the 'Y' option. Instead press F5 or F6 to go back one record or advance one record or ESCape to BASIC, select a recordand return to the Emulator again. With some games it's possible to Escape to BASIC, insert a few pokes and then return. However, a few games could crash by doing so. If a game does crash, try the following next time: type RUN,press Return but don't release it. Now hold down TAB key and then release Return key. This will select interrupt mode 1 instead of mode 2 at start up. You must use this procedure with:SABOTEUR 2 and BOMBJACK (found out myself). This will actually turn off the music played in BOOTY!!!
Keys inside Emulator:
You may use the - / + * = _ " ; : , . Delete, Edit and Cursor keys like in SAM BASIC.
* Control key = Extended mode
* Inverse key = Graphics mode (Keys A-U for UDG)
* Capslock key= Capitals mode
* Escape key = SAM BASIC (F4 returns to the Emulator)
* Control - gives VAL$
* Control Shift - gives FLASH
* Control + gives SCREEN$
* Control Shift + gives BRIGHT
* Control = gives ATTR
* Control Shift = gives RECORD
* Control " gives (C)
* Control ; gives OUT
* Control : gives BEEP
* Control , gives OVER
* Control . gives INVERSE
NMI: system reset
F0 key: Reset system
F1 key: Help screen
F2 key: Inverse palette
F3 key: Normal palette
F4 key: Close TAP file, select Disciple/+D/SP/SNA/LRM/Z80 files
F5 key: Go back one record (record 0 - 1 = max.record)
F6 key: Advance one record (max.record + 1 = record 0)
F7 key: Insert trainers (after a .POK has been loaded)
F8 key: Enter Emulator options screen
F9 key: C/DVD-ROM drive file selector
As the help screen is not present in memory, it will be loaded from the Emulator's startup record. If the 'ZX HELP' file is notpresent on that record, you won't see much of it... Notice that the ESC & F1-F9 functions only work when the system is in Interrupt MODE 1 and interrupts are enabled.
A record can be selected by RECORD followed by the number. Use Extended mode (CNTRL) followed by SYMBOL key 0.
A directory can be displayed by DIR (names only) or DIR 1/DIR 2 (extended dir). Use Extended mode followed by SYMBOL 9. A stringexpression may be used after DIR 1/DIR 2, such as DIR 2"MG*". Also, DIR * or DIR *"name*" may be used to display the extended directory of the current drive.
Loading files from SAM disk/record:
TAP files: To load a TAP file, it must be OPENed first (Extendedmode, SYMBOL 6). Example: OPEN "BATMAN*" and then LOAD "" Maximum TAP file lengths: 360439 bytes on 512k machines and 98295 bytes on 256k machines.
DIR 3 can be used to view the contents of a TAP file. It's now possible to LOAD any of the files in the TAP file. Make sure you supply the correct filename (upper and lower case letters!),otherwise the Emulator will just continue to keep searching for the next file, just like the original tape system! You may press'TAB' to exit this never-ending-loop.
Disciple/+D/SNA/SP/LRM/Z80 files: press F4 to close any open TAP file. Also, LOAD nr. sets the Emulator to this default mode.DIR 3 will display an extended directory of current drive now. Only files with one of the following directory types are shown:
1: Basic file, 2: Data array, 3: String array, 4: Code file, 5: Snapshot 48k & 7: Screen$ file. 19: SNA,SP,LRM,TAP & Z80/SLT
Some games try to read the Kempston or Fuller joystick port, however this will often cause unexpected movement. It is sometimes possible to remove this 'IN' by holding down 'SHIFT' key during loading of a game. You must hold the SHIFT key down until the game starts. This Kempston 'IN' is by default patched to read the third joystick port. This extremely handy for the Ultimate games which only have keyboard and Kempston support.
Kempston joystick emulation should work fine with most Ultimate games, Codemasters games (Dizzy, Dizzy 2), Boulderdash games andmany other games. Notice that this Kempston patch, smashes BC' &AF', so if a game crashes, this patch will be the reason.
Although Kempston emulation is possible using the first joystickit is recommended you use a 3-way joystick splitter and use the third joystick, because if the first one is used, it may give problems with Interface II joystick. Also, the third joystick is read by port not used in Spectrum games, so you can happily use Kempston and Sinclair I/II together.
Use the SYMBOL key in the same way to remove the following instructions: OUT (C),A , OUT (C),D , OUT (C),E , OUTD, OUTI,OUT (C),H, OUT (C),L & OUT (253),A Some 48k Speccy games also contain 128k paging code & 128k musicplayers which will cause unwanted interrupts, resulting in game crashes or garbadge on the screen.
After a SNAP/LRM/SNA/SP/Z80/SLT has been loaded, the Emulator options screen (same as F8) will be displayed.
Cursor up: move up
Cursor down: move down
ZX48 Emulator: return to Emulator; start game.
Kempston port: toggles between first & third joystick port
Patch Kempston: search all IN A,(31) instructions and replace them with RST 8, DEFB 250
Patch Fuller: search all IN A,(127) instructions and replace them with LD A,255
Remove OUT's: search all OUT (253),A OUT (C),A OUT (C),D OUT (C),E OUT (C),H OUT (C),L OUTI OUTD instructions and replace them with NOP,NOP
View screen: view current Spectrum screen. Press Return to return to the options menu screen.
SAM BASIC: This allows you to insert a few pokes or hack a game using a disassembler. Notice that variable 'a' has been predefined as addres 65536, so you can use POKE a+poke addres, value. RUN or F4 returns to the options screen.
Load .POK file: at this moment, only from C/DVD-ROM drive.
Insert pokes: only available if a .POK file has been loaded.
C/DVD-ROM drive file selector (F9): if no CD is
inserted, you may use the following keys: 'O' = open tray, 'C' = close tray.
After the tray is closed, wait a few seconds and if a valid C/ DVD is detected
the Root directory will be displayed.
F0: bottom page
F1: page down
F2: select .Z80/.SLT files
F3: select .SNA/.SP files
F4: page up
F5: select .TAP files
F6: select .SCR files
F7: top page
F8: select .POK files
F9: exit file selector
'P': enter previous directory
'R': enter root directory
Cursor up: move up
Cursor down: move down
Return: enter directory / load file.
After a .POK file has been loaded, the trainer selector will be displayed (same as F7). You may use the following keys:
F9: exit trainer selector
'A': select all trainers
Cursor up: move up
Cursor down: move down
Return: select trainer
For certain trainers you may asked to enter a value (0-255). Use Delete for bad input and Return to insert the trainer.
A file can be loaded by LOAD "filename" followed by nothing or DATA name() or DATA name$() or CODE or CODE address or SCREEN$. Disciple syntaxs like LOAD/MERGE d1/d2/d* "filename" are also accepted, although the drive variables are not acted upon. Filesare always loaded from or saved to the current record. It's evenpossible to use the microdrive command: LOAD *"m";1;"file" etc.
A CODE file can be loaded to the screen area by supplying the SCREEN$ keyword after the filename and the CODE file should be 6912 bytes or less. Also, SCREEN$ files can be loaded to any addres by LOAD "filename" CODE addres.
The MERGE command can be used to stop a BASIC file from auto- running after it has been loaded. The asterisk (*) can be used with the LOAD, MERGE, VERIFY & OPEN commands.
SAVE/LOAD/VERIFY commands examples:
SAVE "name" LINE line number
SAVE "name" DATA numeric array name()
SAVE "name" DATA string array name$()
SAVE "name" CODE start,length
SAVE "name" CODE start,length,autostart
SAVE "name" SCREEN$
Make sure there is already a SAM file in the first directory entry as Spectrum files are saved to (hard)disk which can't be in the first directory entry. The file will not be saved if the length of the file is zero or if there isn't a file in the firstdirectory entry or a MS-DOS disk/record was detected. Best thingto do is SAVE a dummy file as the first file in the directory entry from SAM BASIC: SAVE "dummy" CODE 0,1 for example.
Code files that have an autostart address can be stopped from auto-running by: LOAD "name" CODE start,length,82 Code files that don't have an autostart address can be made to autorun by: LOAD "name" CODE start,length,autostart Use LOAD "name" LINE x for BASIC programs, x = 0-9999
The DISCIPLE & PLUS-D LOAD pn / VERIFY pn / MERGE pn commands are also accepted (n = number shown in the left-hand column of adetailed directory). This works with directory types mentioned above (including SNA,SP,LRM,Z80), except for array & TAP files.
ZX Line printer emulation: the LPRINT, LLIST & COPY commands arefully supported. Make sure your printer is turned on and is on- line before you started the Emulator for the first time. You maypoke your own printer control codes in the Emulator code: Reset your SAM type CLEAR 32767 followed by LOAD "ZX CODE"CODE and POKE addres 32833 with: A,x,x,x etc. A is the number of control codes and the x's are the control codes. Upto 32 bytes can be poked and the first byte being the nr. of control code bytes. After the POKES save it with SAVE "ZX CODE" CODE 32768,16384.
The standard control codes (addres 32833 holds 11) are:
27, 108, 10 - sets left margin at 10
27, 51, 24 - sets 24/180-inch line spacing
27, 42, 4, 0, 1 - select CRT screen
Notice that a 8-pin graphics mode must be selected and the two bytes after the graphics control code must be 0 and 1.
Disciple/Plus-D Hookcodes supported:
HOFLE 35h = open file, IX points to start of complete UFIA
HSBYT 36h = save byte in A
HSVBK 37h = save BC bytes from addres DE
HCFSM 38h = close file sector map
HGFLE 3Bh = get file from disk, IX points to start of UFIA
HLBYT 3Ch = load byte in A
HLDBK 3Dh = load BC bytes to addres DE
HRSAD 3Fh = read track,sector DE at addres HL
Spectrum screen/error reports (* = new repport):
Successful completion, or an attempt to jump to a line number greater than any in the program. CONTINUE disregards this reportand resumes at the statement specified in the previous report.
1 NEXT without FOR
NEXT has been encountered without a corresponding FOR and a variable exists with the same name as the control variable.
2 Variable not found
A simple variable has been used without assignin
g it a value or loading the value from (hard)disk, or a control variable has been used with NEXT without first setting it up in a FOR statement, or a subscripted variable has been used before dimensioning the array with DIM or loading an array from disk.
3 Subscript wrong
A subscript is beyond the dimensions of the array.
4 Out of memory
There is not enough memory space left to complete the statement or command.
5 Out of screen
INPUT has generated more than 23 lines in the lower part of the screen, or a line number of 22 or more has been used with PRINT AT.
6 Number too big
The computer has tried to produce a number greater then about 10^38.
7 RETURN without GOSUB
The number of RETURN statements is one greater then the number of GOSUB statements.
8 Insert disk *
There is no disk inserted in the floppy disk drive.
9 STOP statement
STOP has been used to halt the program. CONTINUE will resume at the next statement.
A Invalid argument
A function has been given a wrong argument or value.
B Integer out of range
A value has been rounded to the nearest integer and is out of the range that can be accepted.
C Nonsense in BASIC
The text of the (string) argument does not form a valid expression.
D BREAK - CONT repeats
BREAK has been pressed. CONTINUE will repeat the statement at which the computer stopped.
E Out of DATA
READ has tried to read beyond the end of the final DATA statement in the program.
F Invalid file name
SAVE, LOAD, VERIFY, MERGE, ERASE or OPEN has been used with a name containing more than 10 characters or no name was specifiedor a stream other than channel K, S or P was opened.
G No room for line
There is not enough memory left to enter the new program line.
H STOP in INPUT
STOP has been entered in response to INPUT or began the data entered. CONTINUE repeats the INPUT statement.
I FOR without NEXT
A FOR NEXT loop has not been carried out because the limits or STEP value were wrong (for example, FOR x=5 TO 0 without STEP) and the corresponding NEXT has not been found.
J File was not found *
The file specified after a MERGE, LOAD, VERIFY, ERASE or OPEN was not found on the current B-DOS/MS-DOS record or CD-ROM.
K Invalid colour
The value specified for INK, PAPER, FLASH, BRIGHT, INVERSE or OVER or the corresponding control characters is out of range.
L BREAK into program
BREAK was pressed. The report specifies the last statement to beexecuted and CONTINUE resumes at the next statement.
M RAMTOP no good
The value specified for RAMTOP is either too big or too small.
N Statement lost
A jump has been attempted to a statement that no longer exists.
O Invalid stream
An attempt to open a stream greater than 15 was made.
P FN without DEF
An FN statement has been used without the corresponding DEF FN statement.
Q Parameter error
An FN statement contains the wrong number of values to be passed to the function, or one of the values is the wrong type.
R File loading error *
The file could not be handled by the command or a bad sector on (hard)disk was found.
Some ZX Speccy ROM bugs fixed:
In the 'Cursor left' subroutine, the line number is tested against an upper value of 24 which should be 25.
The last instruction of the 'Cursor right' subroutine is a RET, which should be JP PO-STORE (0ADC).
The first instruction of the 'Print comma' subroutine is CALL PO-FETCH (0B0C) which is redundant.
In the 'Test for scroll' subroutine there is a CALL to WAIT-KEY (15D4). However, the WAIT-KEY subroutine doesn't handle some control codes properly meaning garbage will appear on screen if you use the Capslock or Graphics code for example, if you want to scroll further.
At the end of the 'Close stream look-up table (1716)' there is no end-marker. So, an instruction like CLOSE #0 could cause the system to crash.
In the 'GO TO (1E67)' command routine the line number is tested against an upper value of 61439 which should be 10000 as only lines 0-9999 can be entered in the BASIC system.
At the end of the 'Scanning SCREEN$ subroutine' there is a JUMP to STK-STO-$ (2AB2) which leads to double storing of the string result. This instruction should be a RET.
The instruction line at L-DELETE$ (2B72) is LD HL,(DEST) which is redundant.
There should have been an extra instruction after the RST 28 (FP-CALC) instruction at (2E25). This extra instruction is DEFB 2 (delete). Without it, the stack becomes unbalanced. An expression like PRINT "2" + STR$ 0.5 is evaluated incorrectly as 0.5; the zero left on the stack displaces the "2" and is treated as a null string.
In the 'Division operation' routine there is a JR Z to DIV-START(31E2) which should be to DIV-34TH (31DB). No 34th bit will everbe obtained without first shifting the dividend. Hence importantresults like 1/100 and 1/1000 are not rounded up as they should be. Rounding up never occurs when it depends on the 34th bit.
The 'USR function (34B3)' routine doesn't cater for a successfulroutine to BASIC as HL' must contain 10072 (2758). This holds the next literal pointer and is not restored should it have beendisturbed by machine code.
The ZX Spectrum 48k ROM does not always handle the number -65536 correctly. This value is sometimes put in 'short' form and at oher times in 'floating point' and this leads to trouble.
The 'Addition operation (3014)' routine can't add two smaller negative integers like -65000 + -536 and it's printed as -1E-38 obtained by treating it as -0 in an illegitimate format. At 3032there should be a test for this number and, if it's present, produce the five byte floating-point form of this number: 91,80,0,0,0 (hex) which causes no problems.
The five bytes at 30E5 in the 'Multiplication operation' routinecan be removed if the number -65536 (0,255,0,0,0) is excluded from the system.
The 28 bytes from 3223 to 323E inclusive should be removed too, as the 'Integer truncation towards zero (3214)' subroutine can'thandle the number -65536 resulting in returning the value -1 after a INT (-65536).
Memory map of ZX48 Emulator:
Page 1: emulator code
Page 2: buffer/stack space
Page 3: 16k ROM (patched)
Page 4: 16k RAM
Page 5: 16k RAM
Page 6: 16k RAM
Remaining pages: used for loading/saving of programs.