ノヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘサ コ コ コ W A R A J E V O Z X S P E C T R U M S I M U L A T O R コ コ コ コ Release 1.2 コ コ コ ネヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘシ CONTENTS ======== 1. 1.1. 1.2. 1.3. 1.4. PREFACE What is this and how we developed it Contents of the package How to help authors (!) Acknowledgements 2. 2.1. 2.2. 2.3. 2.4. 2.5. 2.6. BASIC INTRODUCTIONS Command line options The function keys The keyboard and KEYPAD The emulation of tape recorder The syntax of ZX BASIC Simulator error messages 3. 3.1. 3.2. 3.3. 3.4. BUILT IN MONITOR The front panel Arguments of commands Monitor commands Monitor error messages 4. 4.1. 4.2. 4.3. 4.4. PROGRAM 'ZXTOOLS' Tape files menu Z80 snapshots menu DOS menu The communication program 5. 5.1. 5.2. 5.3. 5.4. 5.5. 5.6. 5.7. 5.8. 5.9. PROGRAM 'ZXSHELL' Main menu Entering and editing the main database Entering and editing additional databases Indexing Sorting and reindexing Deleting records Marking of records Making a reports Executing the simulator from ZXSHELL environment 5.10. The 'Startup' menu 5.11. ZXSHELL and snapshot files 6. 6.1. 6.2. 6.3. PROGRAM 'ZXCOMP' Compiling Supporting of saving and loading blocks Automatization of save & load supporting 7. 7.1. 7.2. 7.3. 7.4. 7.5. 7.6. 7.7. 7.8. 7.9. 7.10. 7.11. 7.12. TECHNICAL INFORMATIONS Z80 processor simulation The ROMs and RAMs Simulations of I/O ports Video memory simulation Beeper and AY chip simulation Keyboard and KEYPAD simulation Formats of files Interrupt congestion 'Wrapping' problem Communication protocoles Informations for Windows users Edge recognizer 8. 8.1. 8.2. PROTECTED PROGRAMS Examples of transfering protected programs Program 'Turbo copy' 1. PREFACE ======= 1.1. WHAT IS THIS AND HOW WE DEVELOPED IT ==================================== Maybe this program is not too interesting itself, as a fact that the program comes from Bosnia and Hertzegovina, from more than three years surrounded city Sarajevo. Our names are Zeljko Juric and Samir Ribic. Even in middle-school days, about ten years before, we began to interest about computers just thanking to ZX Spectrum. From this reason, we are a bit sentimentally tied with this computer. Between the other, this computer remembers us to the times when in our regions the life was normal and nice. However, when we bought AT 286 computers, at the end of 1990, we did not forget our Spectrums. We had great interest when, in June 1991, we got one Spectrum simulator, which, without underestimating of anybody's work, had very bad characteristics (it was slow, quite incompatible with the original machine, with unpractical emulation of the tape recorder etc.). Its origin is unknown to us (we suppose that the program is from any Slavish state), and when starting it displays the copyright message '(C) 1991. Roman & easy inc.'. When the war started in our country, we wanted to reject some dark minds from our heads as possible. So, in April 1993, we started the development of our Spectrum simulator, symbolically called 'Warajevo Spectrum simulator' which should have much better characteristics. We mention, that we were known as quite good programers, especially in assembly language. The program was developed in horrible conditions. The grenades fell on every place, there was no electrical power during the months, sometimes even the hospitals had not the power during two month! When we had electrical power, it was only 2-3 hours during the night. However, we did not quit and caught every moment when the electrical power was present to develop the program. It was often in an Army's camp, with the improvised generator, with voltage that varies from 150 V to 300 V! The greatest part of ZXTOOLS was developed even without hard disc, because this voltage destroyed it. We progressed very well, and in November 1993, reading some newspapers that came from the enemy's territory we've got the information about the simulator 'Z80', written by Gerton Lunter. In even worse winter conditions we continued the development (in the rooms where we slept the water was frozen), hoping to get this simulator to compare our program and his program. In April 1994, the foundation Sorosh opened the electronic mail in Sarajevo. We sent a general request and in June 1994, we got Lunter's simulator. Between the other, from documentation we got the information about many Spectrum simulators around Europe, but we think that our program is better than all the others, except the Lunter's program. We think that it is a great success, according to conditions where the program was development and the quality of Gerton's program. The same opinion has Gerton itself, and we contacted him. The Lunter's simulator 'Z80' is much better than the 'Warajevo' simulator, but, our simulator has some important advantages comparing with his one. We will be self-critical and start with disadvantages. Two major disadvantages of our program are: - It is slower than Lunter's program, not drastically, about 15-30%, but the situation varies from program to program. For example, the game 'Manic miner' is remarkably slower, but, from other side, there are programs that work faster on our program than on Lunter's one, especially on some slower machines. As time of the slower machines passes, this disadvantage loses its meaning. - Some programs on our simulator have sometimes very ugly flickering, which Lunter's program successes to avoid, even to realize a high color resolution and BORDER effects in some cases. These disadvantages were caused by some conceptual errors in our simulator (if you do not understand this, it is not very important): - We update the screen after every access to video memory, and not periodically as Lunter works. From that reason, the programs using the fact that real Spectrum generates the picture periodically too, can flicker. Also, this method slows the access to the video memory and especially to attributes. This is remarkable with programs that intensively access to the video memory. 'Manic Miner' is the most drastic example. 'Warajevo' is seven times faster than 'Roman & Easy inc.' simulator, but Lunter's 'Z80' is three times faster than 'Warajevo' (it is really so fast), when playing this game. From the other side, this video updating method made the sound generated by our program perfectly clean. - We wrote the sequences that emulate Z80 instructions to be as fast as possible, but we did not come to the idea to use positional dependent code, so the sequence that decodes the instruction looks very ugly. The other advantages of (fully registered) Lunter's simulator are: - It supports much more peripheral devices, not supported by our simulator (microdrive, many disc interfaces, Multiface 128, AMX mouse). The emulation of the RS232 interface is more flexible (we emulate the RS232 interface only to LPT1 port, usually printer), and joystick simulation is more flexible. The keyboard has more special keys. Program supports the HP LaserJet printer. - The program supports EMS memory, AdLib compatible sound cards, VOC and OUT files. Lunter's program works even on XT, while 'Warajevo' needs at least AT. - The setting of some parameters can be done in any moment, while in our program many parameters can be set only when starting the program. The speed adjustment is realized on better way. The HELP screen for keyboard is more beautiful. - We both emulate all undocumented instructions of Z80 processor, but Lunter's program more precisely updates undocumented flags. The instruction timing is more precise. - The Lunter's simulator can directly load the programs from the tape recorder, while we use only RS232 transfer (but very elegantly realized). The work with snapshot files is more advanced (snapshot file formats are compatible, and it is very important). - Lunter's simulator supports so-called SamRam. Something similar we have too, in many cases even better. - The registered version includes even source files. From the other side, the advantages of the 'Warajevo' simulator are: - The tape emulation, using TAP files, is realized on much better way. Our simulator success to load from TAP files many programs that load themselves using nonstandard methods (ex. the running screen, quick loading, etc.). The especial advantage is with games that loads the levels from the tape using nonstandard routines. The Lunter's simulator has some great problems with such programs, while our simulator success to solve this problem without problems. - The organization of TAP files is much more flexible. The tapes can be in the compressed format, and occupy about 40-70% less space on the disc. The moving - - - - - - - - - through the tape is much more simple for users. The simulator automatically determines when was necessary the emulation of R register and full LDIR emulation, and the user not needs to worry about it. Also, the user does not need to worry about programs that request version 'Issue 2' or 'Issue 3', because it is solved automatically too. It allows the full emulation of memory management mechanism on Spectrum 128, with no need for EMS memory. Our simulator in the 128 version, in BASIC, when EMS memory is not present, works remarkably faster than Lunter's emulator! The 128 version emulates also the extended keyboard (KEYPAD). There is a possibility of the emulation of 'ZX Spectrum +2'. The 'Warajevo' simulator has cleaner emulation of the beeper. Also, the emulation of the AY sound chip on PC beeper is realized better (pseudo 3-channel sound) and more flexible. The simulator allows automatic loading and starting of the program placed on any place in the TAP file. The emulation of EGA card is faster than in Lunter's emulator. We have no problems with Trident VGA card. We support also EGA cards on the monochrome monitor. The patterns for shades for monochomatic cards are better chosen, and the emulation of BORDER and FLASH is faster. The emulation of BORDER and attributes can be switched off, and it is sometimes useful. Very quality machine-code monitor is included, which is, differently from those included in SamRam, fully transparent. The monitor has also some other things, dedicated for those who not knows the machine code programming, for example the screen dumping to the printer in different sizes, and some of them are very useful for making the maps of games. The program transfer using RS232 is far more developed comparing with Lunter's simulator. Using the additional program ZXTOOLS, it is possible to do many manipulations with TAP files (reorganization, compression, etc.), fully bidirectional communication with Spectrum, conversion of ASCII files to different other formats (BASIC, GENS, etc.), and reverse, the conversion of SCREEN$ files to TIFF, the conversion of TAP formats from 'Warajevo' to the 'Z80' format and much more. The additional program ZXSHELL manages the database of Spectrum programs (the name, the producer, the type, etc.). To every program you can join the data about the tape where the program is, the position on this tape, the disc drive where the tape is placed, the program parameters, etc. This allows very easy starting of Spectrum's programs, using some simple commands. Using the additional program ZXCOMP, the Z80 snapshot files, under some conditions, can be converted to EXE programs which can be executed totally independently from the simulator, and they are not too much longer than snapshot files itself (sometimes, rarely, can be even shorter)! This simulator is free software, and all users will have all options! As you see, both programs 'Warajevo' and 'Z80' have its advantages and disadvantages. To better use all advantages of both programs, we reorganized the format of our snapshot files to establish the compatibility with Lunter's format. The snapshot files in this format you can find on FTP servers like: ftp.nvg.unit.no directory /pub/sinclair/snaps ftp.ijs.si directory /pub/zx If you have only E-MAIL, not FTP access, on Internet there are servers (like BITFTP) which send you files from FTP servers as UU-encoded E-MAIL messages. In period from April 1995 to December 1995, we received E-MAIL messages from 11 countries, with greetings, questions, new ideas and bug remarks. We appologise if yet any message stayed unanswered because E-MAIL did not work during summer (rocket damaged the building and also Sarajevo again was with minimum of electric power). We hope that the war will be really finished, and that we will again have normal, Europian life. On this place we must say a few words about bugs. Version 1.0. (which is described in a manual of Lunter's simulator, version 3.03.) had some serious bugs, which are cleaned in version 1.01. Version 1.1. has a great improvements, so although we tested this program intensively, we can not guarantee that there are no bugs at all. We must say that version 128 of this simulator is not tested very much (because we have not many programs for Spectrum 128). Also, program ZXCOMP is not intensively tested too (there are still some unlocated bugs, unfortunately). Some bugs which are noticed into release 1.1 are removed in releases 1.11 and 1.2. The users remarked that program not work on some VGA boards (it is vissible only half of picture), and keyboard not responds well on some computers. It is hard to repair these errors, because program works correctly on machines that we have access, and we can not discover what is a problem. VGA mode that we use is fairly unstandard, because standard modes are too slow. 1.2. CONTENTS OF THE PACKAGE ======================= In the package, there are these files: SPEC48.EXE SPEC128.EXE ZX48.ROM ZXI1.ROM ZX128_0.ROM ZX128_1.ROM 48K version of the simulator 128K version of the simulator ROM file for 48K version of the simulator ROM file for simulation of Interface 1 ROM file for 128K version of the simulator (Derby ROM) ROM file for 128K version of the simulator (Standard ROM) ZXP2_0.ROM ZXP2_1.ROM ZXTOOLS.EXE ZXTOOLS.HLP COMM128.BZX TURBO.TAP ROM file for the simulation of Spectrum +2 (Derby ROM) ROM file for the simulation of Spectrum +2 (Standard ROM) Program for maintaining TAP and Z80 files Help file for ZXTOOLS Communication program for ZX Spectrum 128 TAP file with the program 'Turbo copy' for transfer of some protected programs ZXSHELL.EXE Database about converted software and program shell ZXCOMP.EXE Compiler for converting snapshot files to EXE programs MEASURE.COM Measuring of speed for correct using of option /W WARAJEVO.ICO Windows icon WRJVSPSM.DOC Documentation on (not so perfect) English language WRJVSPSM.BIH Documentation on Bosnian language NEWS.DOC What is new in version 1.2, English text NEWS.BIH What is new in version 1.2, Bosnian text TESTED.LST The list of tested programs, remarked problems and hints how to solve some of these The programs in this package use, or create, the following files: *.TAP *.Z80 SPECSIM.CFG MONITOR.OUT SOFTWARE.DBF SOFTWARE.DBT SOFTWARE.NTX ADDITION.DBF ZXSHREP.TXT *.nnn *.BAK 1.3. The files for emulation of the tape Snapshot files The configuration file for SPEC48 and SPEC128 The file created by monitor The database about programs The file with descriptions joined to file SOFTWARE.DBF The index file joined to file SOFTWARE.DBF The file with additional data ZXSHELL report file The files created by ZXTOOLS as a result of the extraction BACKUP files created by ZXTOOLS HOW TO HELP AUTHORS (!) ======================= This program is free, public domain, and you can give it to anybody if you not change, or remove anything from the package. However, because we have no sources of money, and almost collect the money to survive, every donation is welcomed. If you like this program, and if you want to help the authors, pay the desired value to one of the following banks: Bank: ABANKA LJUBLJANA (Slovenia) CREDITANSTALT BANKVEREIN WIEN (Austria) DEUTCHE BANK AG FRANKFURT/M (Germany) DEUTCHE BANK AG FRANKFURT/M (Germany) Currency: DEM ATS DEM USD Account number: 7010-070-280-8753 0101-66536/00 9362617 9362617 SWISS BANK CO ZUERICH (Swiss) SWISS BANK CO ZUERICH (Swiss) ABN-AMRO-BANK AMSTERDAM (Nederland) ABN-AMRO-BANK AMSTERDAM (Nederland) DEN DANSKE BANK COPENHAGEN (Denmark) DEN NORSKE BANK OSLO (Norway) SKANDINAVISKA ENSKILDA B.STOCKHOLM (Sweden) CHF USD NLG USD DKK NOK SEK 163973-0 147547-0 54.04.28.213 54.04.93.929 512392 7001-02-25335 5201-85 507 48 The assignement paying is possible in any bank and in any country, to one of these account numbers of 'Central banka DD Sarajevo' (former 'Kreditna banka DD Sarajevo'). When paying, it is necessary to include the following: - The receiver's name and surname; The address of the receiver; The number of the receiver's personal card; Telephone number of the receiver. The necessary data about us is: Zeljko Juric Brcanska 10, 71000 Sarajevo, BiH LK 5013/91 telephone 387 71 526-726 Samir Ribic Trg ZAVNOBiH-a 14, 71000 Sarajevo, BiH LK 11899/88 telephone 387 71 543-174 If you want to contact with us, these addresses are not very useful, because the letters to Sarajevo using regular mail or relief organizations very often are lost or come with delay of few months. Also, the telephone call is not recommended because it is probably expensive for you, and our English is not too perfect for the direct conversation. It is best to use E-MAIL. Our Internet E-MAIL addresses are: [email protected] [email protected] Thank you in advance. To eventual donators, according to the situation, we cannot promise anything, except that we will include in all new versions the list of donators with values of donations. 1.4. ACKNOWLEDGEMENTS ================ Of course, many people helped us to realize this project. We want to thank to: - Gerton Lunter from Holland - - for sending us his program for comparation, sending our program to the world, and information in his documentation about Warajevo simulator; George Hills from United Kingdom for donation of 30 pounds and remarking of some errors Rui Fernando Ribeiro from Portugalia for fixing bug with keyboard hanging on some boards. Daniel Herak from Croatia for information about hosts with Spectrum software and sending our program to the world; Belan Josip and Cvetkovic Dalibor from Sarajevo for helping us in solution of some hardware problems; Almir Osmanovic from Sarajevo for giving us many Spectrum programs for testing; Dragan Ivanovic and Aleksandar Zelenovic from Sarajevo for some useful suggestions about simulator. The organizations we want to thank are: - UNHCR and many relief organizations because we did not die of hunger; - Bosnian Army because it defends our city; - SOROSH foundation for installing and financing E-MAIL; - Electrodistribution in Sarajevo for minimal amount of electrical power. 2. BASIC INTRODUCTIONS =================== You can start simulator using SPEC48 (48 version) or SPEC128 (128 version). Version 128 is a bit slower, so it is not recommended to use 128 version of simulator for running of 48K programs, except if you have any special reason for it (for example, if 48K program supports AY 3-channel sound). 2.1. COMMAND LINE OPTIONS ==================== For correct using of the simulator, it is necessary to well know the command line options, because many options may be set only when you start the simulator. Square brackets have meaning that parameter may be omitted. /V<code> -------Normally, the simulator automatically detects present graphic card. If it is necessary to change this solution, you can use option /V with meaning: /VC /VH /VE /VM /VV /VX - Force CGA card. Force Hercules card. Force EGA card. Force EGA mono card. Force VGA card. Activate nonstandard resolution on Hercules card to establish a full screen picture. There are some reasons for using of these options: - You have nonstandard card compatible with one of listed, but the simulator not recognizes it or recognizes wrongly. - On Hercules card the option /VX displays the nicer picture. However, this mode is about 30% slower than ordinary Hercules mode and sometimes requests synchronization adjusting on many monitors. - On VGA cards there is a sense to use /VE, which gives a smaller picture on the screen (due to changed number of scan lines) if resolution looks too ugly for you (but this will not work on all VGA cards), or /VM if you want shaded graphic (without attributes). On VGA card is possible to use /VC switch too, but tihs is not very useful. On CGA, Hercules and EGA Mono cards, the attributes are simulated by shading (BRIGHT is not implemented). CGA is not in color because it has only four colors. This should look very ugly, and this card today is used only on some LAPTOP-s with black-and-white LCD. VGA and EGA display all Spectrum colors including BRIGHT. Some color combinations emulated by shadings are badly readable. This widely repairs option /VX. /M<mode> -------Simulation of attributes is often too slow, and sometimes it results in unreadable combinations. This option can disable the simulation of attributes: /M0 - Attributes are emulated by shading (default). /M1 - Attributes are not emulated, background is black and pixels are white. /M2 - Attributes are not emulated, background is white, pixels are black. This option can be activated from the simulator itself, by pressing F5. On EGA and VGA cards option /M is ignored. This option should widely accelerate programs that intensively operate with attributes, especially if /VX option is active. However, some pictures is 'square-like' when you turn off attributes. Also, some programs use setting same ink and paper color for hiding strange data of screen, so in such programs switching attributes off is not recommended. /K -FLASH is normally implemented, but on CGA it is not implemented. Also, FLASH is out of function if the emulation of attributes is switched off. Consequently, the cursor becomes an ordinary letter, hard to distinguish from other letters. Option /K changes ROM, and the cursor is displayed inverse. As a negative effect, programs that check a containing of ROM will not work (very rarely). /U<mode> -------On simulator BORDER is implemented (on CGA, Hercules and EGA Mono cards as thick frame around the screen, and on EGA and VGA fully). The programs that change BORDER in synchronization with picture generation to realize many BORDER effects under the simulator will produce ugly flickering (ex. Aquaplane, GU! etc.) The simulator also emulates sound; it is not always welcomed (ex. during a night). This is reason for existence of option /U: /U0 /U1 /U2 /U3 - Border and sound are not emulated. Only BORDER is emulated. Only sound is emulated. BORDER and sound are emulated (default). The same things could be done from the simulator itself, by pressing F4 (sound off/on) and F6 (BORDER off/on). Options /M1 and /M2 switch off BORDER emulation too. /S<mask> -------128 version of the simulator emulates three-channel sound, generated by AY chip using the PC beeper by interlacing of channels. This often sounds very good (but sometimes is terrible). However, sometimes it is good to emulate only one channel (playing the main melody) or two of three channels. For this purpose exists the option /S: /S0 /S1 /S2 /S3 /S4 /S5 /S6 /S7 - All 3 channels Channels B and Channels A and Only channel C Channels A and Only channel B Only channel A The AY chip is are emulated (default). C are emulated. C are emulated. is emulated. B are emulated. is emulated. is emulated. not emulated. Generally, the simulation of the AY chip on the PC beeper is better than in Lunter's 'Z80' emulator. Only by experiments you could decide which parameter after /S is best for use, because it varies from program to program. On the 48 version of the simulator, this option is ignored. /N -This simple option disables painting of the titling picture when starting the simulator. /X -At Spectrum 128, some programs use the alternate bank for video memory. The simulator emulates the alternate bank too, but every time when the bank is being changed simulator repaints the whole picture. If bank switching is done very often (for example in smooth animation), this will be very slow. With option /X simulator simulates the alternate bank simply by changing graphic pages on PC graphic cards (except CGA without graphics pages), which is much faster. However, after /X FLASH is disabled, because the simulation of FLASH attributes is based on the same algorithm (graphic page changing, so there is no FLASH on CGA card). Another (lower) artefact is that after option /X programs which use RAM bank 7 will be slightly slower. On the 48 version , and on the computers with CGA card, the option /X is ignored. On VGA card FLASH will work even with option /X (VGA has enough graphic pages). Generally, option /X is not recommended if the program not use intensively alternate bank for video memory. /E[X] ----Normally, ZX Interface 1 is not emulated. If you specify option /E, ZX Interface 1 is also emulated. In that case, the file 'ZXI1.ROM' must be present. The ROM switching is done only in lower 8K, while real ZX Interface 1 switches all 16K. If you want to simulate this, use option /EX, but now the switching is slower. Unfortunately, option /E is not very useful because it is implemented only simulation of RS232 output to LPT1 port (typically some printer), while microdrive and networking are not implemented. It is planned for next release of the simulator. /D[<drive>:][<path>] -------------------It sets active disc and directory for TAP files (which simulate tapes) and for snapshot files. If the directory not contains any tape (i.e. a TAP file), and if /T option is not present the simulator creates empty tape file called 'E.TAP'. /R[<drive>:][<path>][<filename>] -------------------------------It loads the snapshot file. The assumed extension is '.Z80'. The snapshot files are compatible with the emulator called 'Z80', written by Gerton Lunter up to version 3.03, including. So, you can load the snapshot files created with this simulator. If the name is omitted, the assumed name is SNAP.Z80. If the names of drive and directory are omitted, the assumed names are these given by the option /D, and the active drive and directory is the option /D is omitted. /T<filename> -----------This option sets up the active tape. The tape will be ready for work when you start the simulator. It is not necessary to write the extension, but if it is written it must be '.TAP'. Omit the names of drive and directory, for this purpose use the option /D. If the tape with a defined name not exists, empty tape with this name will be created. The active tape may be changed from the simulator itself by pressing F2. More about tapes and emulation of the tape recorder will be written in the chapter 2.4. In the name of the tape you may use wildcards '*' and '?', but it is not very useful except with option /O. /F<filepos> ----------This option seeks to the desired block in active tape. It is used almost exclusively with option /A. Of course, the seeking may be done from the simulator itself (F2). About this will be more discussed later. This option is ignored if given option /R. /A[-] ----After you chose desired drive, directory, tape and position of the block at tape, by using the option /A you could establish automated starting of the program on the tape. This option makes small changes in ROM, so after simulator starts LOAD"" is performed automatically. Also, writing of the message 'Program....' is canceled, and the initial attribute is changed from 56 to 7 (white on black), with an intention that loading of the program causes the least possible additional effects on the screen. After loading the program (more precisely, after loading the first header), all ROM changes are canceled, so there is no problem with ROM checking. On the 128 version, the option /A loads and automatically starts the program in '128' mode. The option /A is very powerful, but also complex for using. So, we developed the external program ZXSHELL that completely automates using of makes work with the simulator very simple. the chapter 5. The option /A is ignored if possibility for ZXSHELL to manipulate with the options /D, /T, /F and /A and About this program will be told in option /R is given too, so this makes snapshot files too. Option /A- cancels previously used /A option. This is implemented if you want (from any reason) to cancel autostart of program from ZXSHELL environment. ZXSHELL automatically inserts /A option, and you can use /A- to cancel it. /Y<attr> -------Using this option, it is possible to change the initial attribute that set the option /A. The default value is 7. If you use options /Y and /H (it will be described later) correctly, and use BORDER, PAPER and INK instructions with corresponding values in the BASIC loader (i.e., this started with /A), program loading and its start should be done invisible, without any additional effects on the screen (if you are too pedant and this disturbs you). Most of the users will not use these options. /H -No matter about effort that program loading using option /A generates as less as possible minimal effects on the screen, one thing could not be done without more 'radical jobs': BORDER flickering while loading every block on the tape. In fact, one instruction at the beginning of LD_BYTES routine changes the BORDER color to white every time before block loading. The option /H does this 'radical job', it removes this instruction from the ROM. Eventual non-desired effects are the same as with option /K. /L<mode> -------The option /L selects algorithm for tape emulation: /L0 /L1 /L2 /L3 /L4 /L5 - Algorithm Algorithm Algorithm Algorithm Algorithm Algorithm is is is is is is AUTO, SLOW, FAST, AUTO, SLOW, FAST, no stopping between blocks (default). no stopping between blocks. no stopping between blocks. with stopping between blocks. with stopping between blocks. with stopping between blocks. The selection of the algorithm may be done from the simulator itself (by key F2). More about algorithmes for simulation of tape recorder see in chapter 2.4. /O -Use this option with /T. It establishes 'filter' for active tapes. For example, after the options /TARC* /O, the simulator will recognize only the tapes with the names starting with ARC. Yet another example is that /TSHOOT sets up the tape SHOOT.TAP for the active tape, but the other tapes may be used too. If you type /TSHOOT /O , the simulator will recognize only the tape SHOOT.TAP. Sometimes it may be useful. /2 -On the 128 version of the simulator it activates the emulation of 'ZX Spectrum +2'. On the 48 version, this option is ignored. The main difference is in using of ROM files ZXP2_0.ROM and ZXP2_1.ROM instead ZX128_0.ROM and ZX128_1.ROM. Some ill-based programs request ROM-s of +2. This option enables working of such programs. /B -This option accelerates BASIC programs for about 10% (in '128 Basic' on the 128 version even 50%). This almost has no negative effects. For details, see the technical part of the manual (chapter 7.). /P -The simulator emulates the ZX printer at I/O level using LPT1 port on Epson or IBM compatible printers using the resolution of 72 dots per inch. This resolution results in a picture of the same size as on the real ZX printer. The option /P activates the enlarged picture where every dot on the ZX printer is emulated by the matrix of 2x2 dots on Epson or the IBM printer. So, the picture that is created using COPY command is now almost wide as full A4 size paper, not only a half of it. /J<code>[<calibration>] ----------------------The simulator supports emulation of many joystick interfaces on different methods. By default, the gray cursor keys and cursor keys on the numerical keyboard behavior like pressing the keys CAPS SHIFT + 5, 6, 7 and 8. Using option /J this could be changed: /JC - The emulation of the cursor joystick with cursor keys: the cursor keys on the numerical keyboard generate 5, 6, 7 and 8, and gray cursor keys CAPS SHIFT and 5, 6, 7 and 8. The key '+' on the numerical keyboard, like the key '~' (more precisely, the key with scan code 41) generates '0' (fire). /JS - The emulation of Sinclair joystick 1 with cursor keys: the cursor keys on numerical keyboard and gray cursor keys generate 1, 2, 3 and 4, and key '+' on the numerical keyboard and key '~' generate 5 (fire). /JB - The emulation of Sinclair joystick 2 with cursor keys: the same as /JS, but replace 1, 2, 3, 4 and 5 respectively with 6, 7, 8, 9 and 0. /JK - The emulation of the Kempstone joystick with cursor keys: the cursor keys on the numerical keypad and gray cursor keys emulate the moving of joystick using port 31, and keys '+' on the numerical keyboard and '~' emulate the shoot button. All these options are out of function if KEYPAD emulation on the 128 version is active (KEYPAD is activated or deactivated pressing the 'NumLock' key). More about this in the chapters 2.3. and 7.6. The following options are specific because they not affect to behavior of cursor keys: /JA - Kempston joystick is emulated with PC analogue joystick. This option is a bit slow because it calls BIOS. Simulator automatically performs joystick calibration, but if you are not happy with it, you can use the manual calibration with /JAlllrrruuuddd where lll, rrr, uuu and ddd represent 3-digit decimal values for left, right, up and down joystick moving (for example /JA090210100200). You can read this values using the following QBASIC or GWBASIC program: 10 LOCATE 1,1 20 PRINT "X=";STICK(0);" Y=";STICK(1) 30 GOTO 10 Most of the analog joysticks have the variable resistors to adjust it. /JM - Kempston joystick is emulated with the mouse (driver MOUSE.SYS must be present). This unusual simulation in some programs works very well. This option is hard to describe, so you try it. Mouse moving is buffered, and for example, if you make greater moving to the left, simulator will longer return values for joystick left moving. Some of these options may exist together, for example, you can give /JC and /JM simultaneously. /I[<num>] --------This simulator updates the screen after every access to the video memory. One of the consequences is that programs which manipulates with a great amount of screen data could on slower machines (often with Hercules, CGA and EGA Mono cards, and especially in /VX mode) congest the simulator because the program cannot finish the interrupt-routine before incoming of the new interrupt. The option /I reduces the frequency of incoming of the Spectrum interrupt from 50 Hz to 50/(<num>+1) Hz. If /I without parameters is used, the assumed value is /I2, which results in frequency of about 16.6 Hz. If any program not works under the simulator, try this option. Negative effects of this option are: - Time (system variable FRAMES) is not updated in regular intervals. - Keyboard reading, if based on interrupt (as in BASIC) becomes slower, including the auto repeat. - Programs synchronized with interrupt became slower. It is often case with melodies, especially in 3-channel melodies on the 128 version of simulator based on interrupt. The allowed values of parameter <num> are from 0 to 9. If you need this option for any program, try first with lowest number. Using of this option sometimes can also reduce some non desired effects (for example flickering, appearance of 'ghosts' on the screen, etc.). /W<num> ------The time of slow machines passes. This simulator is not as fast as it could be, but on most of the today machines it is too fast. The option /W slows down the simulator on one relatively primitive method: by executing empty loop in the timer interrupt 10000 times per second. Parameter <num> defines duration of the empty loop in the units of about 11 processor cycles. The simulator with this option is really slowed down, not quite smoothly (because the instruction timing remains the same), but in discrete timing intervals. Unfortunately, this option will cause small sound distorsion. Try to understand us: we developed program at 12 MHz AT and we have not any need for slowing simulator down. So, option /W is implemented in a last moment, when some peoples say that on their machines simulator works too fast. That is a reason why is option /W relatively primitive. However, in many cases this method will be satisfactory. If you omit /W option, /W0 is assumed (e.g. without slowing down). You must be warned that in case if too big parameter <num> is given, the duration the empty loop can pass the limit of 0.1 ms, resulting in overpassing of the timer interrupts, which is not a desired thing. If the overpassing of the timer-interrupt occurs, the easiest way to remark it is in lower speed of flashing of FLASH. Approximated value of parameter <num> where this effect occurs is about 95 on 12 MHz machine and 295 on 33 MHz machine. Using auxilary program MEASURE.COM you can read approximative value of this critical value on your machine. The slowing down is greatest just for values of parameter <num> which is a bit lower than the critical value. /?128 ----- This option will work only with 48 version of the simulator. Using this option you can test when 48K program supports some Spectrum 128K possibilities (for example, 3-channel sound). If you give /?128 option, any attempt to writing any Spectrum 128K port will cause stopping simulator with error message. So, you can (if you want) try to load this program in 128 version of the simulator. /! -This simulator instals handler for processor interrupt 0DH, because this grows compatibility with Spectrum software. However, this may cause interaction with some resident programs on 386 machines which use 'virtual 8086' mode, usually EMS drivers like EMM386, QEMM or Windows 386. So, simulator displays a warning message if processor works in 'virtual 8086' mode (this not mean that a problems must occur). Option /! prevents displaying of this warning message, you can use this with some program (tipically as a initial option iz ZXSHELL) if you are sure that this program works fine in 'virtual 8086' mode. See 'WRAPPING PROBLEM' in a technical part of manual. /C -This option is used mostly for linking with program ZXSHELL; However, it can be used independently. Giving the option /C all command parameters are loaded from the file SPECSIM.CFG. This file must have only one row, up to 127 characters long, and must be terminated with a sign for end of line (ENTER). With the option /C it is possible using of other command options, but any option written after /C will be ignored. 2.2. THE FUNCTION KEYS ================= The explanation of function keys used in the simulator follows: F1 - Displays HELP screen, that gives meaning of all function keys and the layout of the Spectrum keyboard. F2 - Calls the subroutine for selecting active tape and the active block, selecting algorithm for tape emulation etc. About this and about emulation of the tape recorder read in chapter 2.4. F3 - Calls embedded machine-code monitor, which contains some options interesting even to those who has no interest in machine code programming (for example, hard-copy of the screen to the printer.) The monitor is in detail explained in the chapter 3. F4 - Activates and deactivates emulation of the sound (beeper and AY). F5 - Cyclic mode switching for attribute emulation (like option /M) in order /M0, /M1, /M2. For details see option /M. F6 - Activates and deactivates BORDER emulation. After deactivating, the BORDER color remains like it was in a moment of deactivating. F7 - Saves the snapshot file in a format compatible with Lunter's Z80 simulator (like version 2.0.). The loading of the snapshot file can be done (option /R) from the file of any name; saving using F7 is always in the file 'SNAP.Z80'. Changing of the name, so, can be done only by exiting to DOS. If from any reason saving of the snapshot file was unsuccessful, it is reported with warning sound. F8 - Generate NMI. This has a sense only if you changed ROM. F9 - Generate RESET signal. F10 - Leaves the simulator. 2.3. THE KEYBOARD AND KEYPAD ======================= The keyboard is mostly mapped as standard Spectrum's keyboard (key F1 displays the keyboard layout on the original keyboard). For CAPS SHIFT you can use keys 'Shift' or 'Ctrl', and for SYMBOL SHIFT you can use key 'Alt'. Some keys on the PC keyboard have the special meaning: CapsLock: Tab: Esc: Backspace: CAPS CAPS CAPS CAPS SHIFT SHIFT SHIFT SHIFT + + + + 2 SYMBOL SHIFT SPACE 0 (CAPS LOCK) (EXTENDED MODE) (BREAK) (DELETE) The cursor keys on the numerical keyboard, like gray cursor keys normally generate CAPS SHIFT + 5, 6, 7 and 8, but this can be changed using previously described option /J. The key '+' on the numerical keyboard and key '~', depending on the option /J behavior like fire on the joystick. It is all we can say about the keyboard in the 48 version of the simulator. However, the 128 version of the simulator emulates also the KEYPAD. It is the addition to the keyboard delivered with first versions of Spectrum 128K, and later it was bought optionally. The KEYPAD simulation activates or deactivates pressing the key 'NumLock', and the corresponding LED diode determines is the simulation active. When simulating the KEYPAD, the keys on the numerical keyboard and some gray keys receive special meaning. Because most of the users had no opportunity to see a real KEYPAD, we will describe it more detailed. The KEYPAD consisted of 18 keys (one key more, than on most of PC numeric keyboards). Its keys have the same labels as on the PC, except that 'NumLock' not exists, but left and right brackets are present. The keyboard layout is almost identical, with small differences. The keys '*' and '/' are above the keys '7' and '8'. The keys '(' and ')' are above '9' and '+'. Instead a big '+' key, on the KEYPAD there are the keys '-' (up) and '+' (down), one key above another. The layout of the other keys is the same. But, on the KEYPAD keys exist also the labels signing different enhanced editor functions. The ROM routine that reads from the KEYPAD, differently interprets pressing of these keys, depending on this is the computer in '128 Basic' or 'Calculator' mode. In 'Calculator' mode the KEYPAD works as numerical keyboard. It is implemented in the simulator too, while the keys are mapped like writes on the PC keyboard (only the brackets are missing), and there is nothing to say more. However, in '128 Basic' mode, the KEYPAD keys have the additional functions. Unfortunately, they are mapped on the way that must be kept in the mind, because these labels are not written on the PC's numerical keyboard. Even these written, they are on the other places. The keys are mapped on this way: 7 9 * 8 4 5 6 + 1 2 3 . / 0 - Cursor left for one character Cursor right for one character Cursor up for one character Cursor down for one character Cursor left for one word Cursor right for one word Cursor up for 10 rows Cursor down for 10 rows Cursor to the start of BASIC line Cursor to the end of BASIC line Cursor to the top of the program Cursor to the end of program Delete characters left from cursor Open command menu SHIFT for destructive functions (LEFT) (RIGHT) (UP) (DOWN) (WORD LEFT) (WORD RIGHT) (PAGE UP) (PAGE DOWN) (HOME) (END) (TOP) (BOTTOM) (DELETE LEFT) (CMND) (DEL SHIFT) Some destructive functions are activated if you simultanous press '0' on the numerical keyboard, and one of the following keys on the numerical keyboard too: 1 2 4 5 - Delete Delete Delete Delete from from word word cursor to start of line cursor to end of line left from the cursor right from the cursor (DELETE (DELETE (DELETE (DELETE FROM START) TO END) WORD LEFT) WORD RIGHT) Two functions, on the keypad located on brackets, deleting of the character at cursor position (DELETE RIGHT) and switching of the editor's window to the bottom part of the screen (TOGGLE) are given, according to PC conventions, to the keys 'Delete' (gray) and 'Scroll lock'. This key mapping is a bit unusual, for a first view. Of course that the keys could be mapped to be like some labels on the PC's numerical keyboard, but because the KEYPAD is emulated on I/O level, and the routine in ROM differently interprets the keys depending on '128 Basic' or 'Calculator' mode, more precisely, depending on bit 0 of the system variable FLAGS3 (23398), any other keyboard mapping (without ROM changing) will ruin the correct behavior of the KEYPAD keys in the 'Calculator' mode. To simplify using of some extended editor's functions, when KEYPAD emulation is active, the following gray keys have the meanings: Page Up: Page Down: Home: End: Cursor Cursor Cursor Cursor up for 10 rows (PAGE UP) down for 10 rows (PAGE DOWN) to the start of the BASIC line (HOME) to the end of the BASIC line (END) The backside effect (which not disturbs) is that pressing of these keys in the 'Calculator' mode generates the signs '6', '+', '1' and '2' respectively. The key 'Insert' works too like SHIFT for destructive operations (in the calculator it generates a sign '0'). Meaning of keys 'Delete' (gray) and 'Scroll lock' in '128 BASIC' mode is described already. In our calculator they generate missing brackets. To reduce confusion, while the KEYPAD is active, the gray cursor keys always generate the moving of the cursor (CAPS SHIFT + 5, 6, 7 and 8), no matter about option /J. Mention that, because scanning of the KEYPAD in ROM executes quite ugly routine, program execution, especially on slower machines, is slower when KEYPAD emulation is active. 2.4. THE EMULATION OF TAPE RECORDER ============================== The direct loading from the tape is not possible (about transferring programs from the tape will be written below). Instead it, the simulator uses files with the extension .TAP for tape emulation (in further we will call it tapes). The tapes are organized on flexible way that allows saving of the block to any place (more about tape organization see below) and can be compressed. The tape format is not compatible with Lunter's Z80 emulator (while snapshot files are compatible), but the conversion from one format to another is possible. The loading and saving are realized by classic LOAD and SAVE commands, as on real Spectrum (the automatic loading is possible, see the option /A). If LOAD, from any reason, fails, the consequences are the same as on original Spectrum, which in conventional cases results with 'R Tape loading error', but this with headerless files need not be a case. If SAVE failed from any reason (for example the disc was writing protected) the computer sounds with a warning sound. Pressing F2 activates the subroutine that selects the active tape and seeks to any block in the tape (in further: Tape Manager). On the top part of the screen it is written the name of the active tape that can be changed by pressing TAB or F2 (in the directory defined with /D, and eventually, in according with 'filter' sets by option /O), and the current algorithm for tape emulation (displayed inverse). In the middle of the screen there is written data about the current block on the tape. If the block represents any header, the name of the block is displayed. Also, there are: the type (it can be 'Basic', 'Bytes', 'Number array' or 'Character array'), the size of the block of data following the header (more precisely, block which should follow the header according the header information), and the data dependant on header type. For 'Basic' type the line of the automatic start is written and the pure BASIC program size, without variables. For the type 'Bytes' it is written the address where the block will be loaded. For the types 'Number array' and 'Character array', the array name is displayed. If the block represents the data, instead the name, the flag byte is written, and the type is 'Headerless' or 'Compressed' if the block is compressed (the compression executes program ZXTOOLS). For a case of compressed blocks, the compressed size is also written, the same as compressing effiency (according to ARJ convention). The header blocks are never compressed. On the bottom of the screen there is a brief list of meanings of some keys. The active block (i.e. the next block to be loaded, or the block before the block who will be saved) is changed with the up and down arrows. Using the 'PageUp' and 'PageDown' keys, the moving is to the previous and to the next block of the BASIC header (typically the loader of any multi part program), it very simplifies the work. Mention that these commands can confuse the simulator if the file with extension '.TAP' was given to it with a format incompatible with a regular '.TAP' file. The 'Home' and 'End' keys seek to the beginning and the end of the tape, respectively. You can leave the Tape Manager pressing the key ENTER. The key 'Backspace' makes a selection will the simulator make a pause after every loaded block ('STOP' mode) or not ('CONT' mode). In 'STOP' mode, after every loaded block the simulator automatically calls Tape Manager, enabling to change the tape and position before loading the next block. It is necessary for example if any program after its start expects loading of any block (for example some data) which is on the other place. This mode can be very efficiently used with option /O. However, in most of situations, 'CONT' mode is the best. The simulator knows three algorithms for the tape emulation, called AUTO, SLOW and FAST which could be changed pressing on SPACE (the default value is AUTO). In normal situations the simulator traps execution of the instructions on addresses 1388 and 1232, in the LD_BYTES and SA_BYTES routines, then executes the subroutine that loads (or saves) from '.TAP' files from the disc rather than from the real tape. This well functions for the programs that use standard load routines, with no matter are they with or without their header. However, many programs use nonstandard load routines (for example the running screens, faster loading, changed BORDER effects, loading with the counter etc.). For example, see 'Spy vs. Spy', 'Fairlight', 'Trap door', 'The halls of the things' and many pirated programs. Probably the best loader was published in one computer magazine 'Svet kompjutera': The loader that contains one primitive game which you can play while loading the main game! The simulator usually successes (analyzing Z80 machine code) to recognize nonstandard loading routine and loads such programs! This sounds incredible, but it is true. We tested many programs with nonstandard routines and very rare we had problems. There were problems with routines that modify themselves while loading, routines that use more than one LD_EDGE subroutine and with totally nonstandard routines. This complex algorithm for recognizing of nonstandard load routines we called EDGE RECOGNIZER and we explained it more detailed in technical part of the manual. The loading of the program with a nonstandard routine is much slower than in normal situations (it needs about 1 min on 12 MHz AT for the 48K program) and very looks like loading on the original Spectrum including sound (use F4 if this disturbs you). The loading sound effect is not emulated exactly because this will slow down loading too much. From the same reason, BORDER effects are omitted. It is supported most of the other effects, so you can see on your PC loading for a long time ago forgotten 'Running screen'. However, the simulator not recognizes nonstandard saving routines, which are more rare, and in these cases you must use the monitor. All this happens if algorithm AUTO is active. If you selected the algorithm SLOW, the simulator not traps at the address 1388 in LD_BYTES, and simulation of the tape recorder is always like with nonstandard routines, i.e. slow. This algorithm you can use if you want from any reason the slow loading, for example to success to read some instructions that program keeps on the screen while next block is loading. There is yet another reason when to use the SLOW algorithm. The routine that loads when trapped at address 1388 returns most of the registers like the original load routine, but not all (for example A, B and C registers). During the SLOW algorithm, the loading will be just as dictated in loading routine, including correct updating of all registers. In rare cases some programs are sensible to values of all registers after loading (for example some COPY programs), and then we recommend using of the SLOW algorithm. When the FAST algorithm is selected, EDGE RECOGNIZER is switched off, i.e. the recognizing of nonstandard load routines. In very rare cases the simulator can the sequence of instructions that is not part of load routine recognize as a part of loading routine (he had no yet such case, but it is possible if you want to torture program). In these cases it is necessary to use the FAST algorithm. This algorithm you need to use also if you do not want recognition of nonstandard load routines, it is very often a case with protection cracking. Finnaly, some programs which cause interaction with 'Virtual 8086' drivers will not cause interaction if FAST algotithm is selected. Summary, the tape emulation is realized very flexiblely. The Lunter's simulator has often great problems with some games that loads its levels from the tape using nonstandard routines. We have no such problems. Our simulator successfully loads even many speedlock files (if the routine is not completely nonstandard), for example levels in game ROBOCOP. There is only a question how to transfer Spectrum programs to your PC, because the simulator not supports direct loading from the tape. Generally, there are two ways: 1) Using program ZXTOOLS you can very elegantly transfer the programs from Spectrum (128 version, but it is no so hard to make communication program for Spectrum 48 and Interface 1, see technical part of the manual) to PC using the RS232 connector included in Spectrum 128. The transfer goes without problems, for normal speed programs, no matter about their sizes! About this transfer will be discussed later. The speedily saved blocks must be previously slowed using the 'Turbo copy' program, included in the simulator for be transferred using the communication program but there is no need for interventions in a transferred program itself, thanks to EDGE RECOGNIZER. It will successfully recognize most of the speed load routines. 2) Because 'Warajevo Spectrum simulator' and 'Z80' by Gerton Lunter have compatible snapshot formats, it is possible to use programs directly loaded from the tape using 'Z80' emulator. Snapshot files can be used directly, or converted to Lunter's TAP format using his program Z802TAP. The formats of TAP files in our simulator and Lunter's simulator are not compatible, but ZXTOOLS enables conversion of one format to another. The selection of the algorithm of tape emulation can be realized using the command /L, about this we already told. The selected algorithm very slightly acts to speed of the simulator, however, generally, the simulator is a bit faster in SLOW mode, in spite that this for a first view seems strange. In most of cases, however, it is recommended to keep the simulator in 'AUTO' mode. We remark that it is not recommended to call Tape Manager while loading with nonstandard routines, and especially to change the algorithm while loading. This may cause wrong loading. However, you can call the monitor even while loading. 2.5. THE SYNTAX OF ZX BASIC ====================== For those who forgot it we give here a short view of the syntax of the Spectrum BASIC, in very usual form (simplified Backus-Nauer form): x, y, z ... x$, y$ ... m, n, p ... represent represent represent integer v1, v2 ... represent ・ ... represent represent represent represent numerical expressions alphanumerical expressions numerical expressions which are rounded to the nearest v, ・ c d b numerical variable names a single letters ('a'..'z' or 'A'..'Z') any character a single digit (0..9) any BASIC command [A] {A|B|C} [A...] means 'A can be omitted' means 'A or B or C' means 'A can be omitted or repeated many times' Statements: BEEP x,y BORDER m BRIGHT m CAT CIRCLE [{BRIGHT m|FLASH m|INK m|INVERSE m|PAPER m|OVER m};...]x,y,z CLEAR [m] CLOSE #m CLS CONTINUE COPY DATA {x|x$}[,{y|y$}...] DEF FN {・[畆$][,躰$]...]])=x|・([畆$][,躰$]...]])=x$} DIM 濕$](m[,n ...]) DRAW [{BRIGHT m|FLASH m|INK m|INVERSE m|PAPER m|OVER m};...]x,y[,z] ERASE x$ FLASH m FOR ・x TO y STEP z FORMAT x$ GO SUB m GO TO m IF x THEN b INPUT {x|x$|#m|AT m,n|BRIGHT m|FLASH m|INK m|INVERSE m|LINE ・[([m[,n...]][,[p] TO [q]])][([[r][ TO [s]]])...]|PAPER m|TAB m|OVER m}[{;|,|'}{y|y$|#p|AT p,q| BRIGHT p|FLASH p|INK p|INVERSE p|LINE ・[([i[,j...]][,[k] TO [l]])][([[t] [ TO [u]]])...]|PAPER p|TAB p|OVER p}...} INVERSE m LET {{v|・m[,n...])}=x|・[([m[,n...]][,[p] TO [q]])][([[r][ TO [s]]])...]=x$} LIST {#m[,n]|[n]} LLIST {#m[,n]|[n]} LOAD x$[{CODE [m[,n]]|DATA 濕$]()|SCREEN$}] LPRINT {|x|x$|#m|AT m,n|BRIGHT m|FLASH m|INK m|INVERSE m|PAPER m|TAB m|OVER m} [{;|,|'}{|y|y$|#p|AT p,q|BRIGHT p|FLASH p|INK p|INVERSE p|PAPER p|TAB p| OVER p}...] MERGE x$ MOVE x$,y$ NEW NEXT ・ OPEN #m,x$ OUT m,n OVER m PAPER m PAUSE m PLOT [{BRIGHT m|FLASH m|INK m|INVERSE m|PAPER m|OVER m};...]x,y POKE m,n PRINT {|x|x$|#m|AT m,n|BRIGHT m|FLASH m|INK m|INVERSE m|PAPER m|TAB m|OVER m} [{;|,|'}{|y|y$|#p|AT p,q|BRIGHT p|FLASH p|INK p|INVERSE p|PAPER p|TAB p| OVER p}...] RANDOMIZE [n] READ {v1|・m[,n...])|・[([m[,n...]][,[p] TO [q]])][([[r][ TO [s]]])...]}[,{v2| ・p[,q...])|・[([i[,j...]][,[k] TO [l]])][([[t][ TO [u]]])...]}...] REM [c...] RESTORE [m] RETURN SAVE x$[{CODE m,n|DATA 濕$]()|LINE m|SCREEN$}] STOP VERIFY x$[{CODE [m[,n]]|DATA 濕$]()|SCREEN$}] ZX Interface 1 statement extensions: CAT [#m,]n CLEAR # CLS # ERASE x$;m;y$ FORMAT x$; m[;y$] LOAD *x$[;m[;y$]][{CODE [m[,n]]|DATA 濕$]()|SCREEN$}] MERGE *x$[;m[;y$]] MOVE {#m|x$[;n[;y$]]} TO {#p|z$[;q[;r$]]} OPEN #m{,|;}x$[;n[;y$]] SAVE *x$[;m[;y$]][{CODE n,p|DATA 濕$]()|LINE q|SCREEN$}] VERIFY *x$[;m[;y$]][{CODE [m[,n]]|DATA 濕$]()|SCREEN$}] '128 Basic' extensions: CAT ! ERASE !x$ FORMAT x$;m LOAD !x$[{CODE [m[,n]]|DATA 濕$]()|SCREEN$}] MERGE !x$ PLAY x$[,y$[,z$,[r$[,s$[,t$,[u$,[w$]]]]]]]] SAVE !x$ [{CODE m,n|DATA 濕$]()|LINE m|SCREEN$}] SPECTRUM VERIFY !x$[{CODE [m[,n]]|DATA 濕$]()|SCREEN$}] (but this is a bug) The '128 Basic' no longer accepts incomplete syntax form accepted by '48 Basic' CAT, ERASE x$ and FORMAT x$. The numerical expressions have the following form: <number> x+y x-y x*y x/y x^y +x -x (x) {x=y|x$=y$} {x>y|x$>y$} {x<y|x$<y$} {x<=y|x$<=y$} {x>=y|x$>=y$} {x<>y|x$<>y$} v ・m[,n...]) ABS x ACS x x AND y ASN x ATTR (m,n) BIN {0|1}[{0|1}...] CODE x$ COS x EXP x FN ・[畆$][,躰$]...]]) IN m INT x LEN x$ LN x NOT x x OR y PEEK m PI POINT (m,n) RND SGN x SIN x SQR x TAN x USR {x|x$} VAL x$ The alphanumerical expressions have the following form: "[c...]" x$+y$ (x$) x$([[m][ TO [n]]]) ・[([m[,n...]][,[p] TO [q]])] x$ AND x CHR$ m INKEY$[#m] SCREEN$ (m,n) STR$ x VAL$ x$ The numbers have the form d[d...][.[d...]][{E|e}[{+|-}]d[d...]], and a numerical variable names have the form 濕{痞 d|_}...]. 2.6. SIMULATOR ERROR MESSAGES ======================== Sometimes the simulator interrupts work (or even not starts it) with reporting of some errors. This chapter describes these events. "Program finish at address #nnnn" Normal finish of the program (pressing F10). The hexadecimal address of the instruction where interrupted the instruction is written. If this occurred in Shadow ROM (the ROM of ZX Interface 1) the text '(Shadow ROM)' is displayed too. On the 128 version, if the stopping occurred in ROM, it is displayed '(Standard ROM)' or '(Derby ROM)' depending on currently active ROM. If the stopping occurred on the address greater than 49152, after the address is written also the active bank of RAM like '(RAM page n)'. "Error loading CFG file" The instruction /C was given, but the simulator cannot load a file 'SPECSIM.CFG' from any reason (the most probably even it not exists). "Invalid command line parameter" The nonexisting command option was given (directly, or in the file 'SPECSIM.CFG'), or any wrong parameter of the existing option. Also, this message occurs if missing the final ENTER sign (CR, 13) in 'SPECSIM.CFG' file. "Invalid tape name or tape error" From any reason the name after the option /T is not correct. Most probably the name was omitted completely, or the extension was different from '.TAP'. Also, it may be that tape creation was not successfull. "Invalid drive or directory" The option /D, from any reason, has not done its task. Most probably the directory was nonexisting. "File ZX48.ROM not found" The 48 version of the simulator was started, and the file 'ZX48.ROM' was not found in the current directory. "The file ZX128_0.ROM or ZX128_1.ROM not found" The 128 version of the simulator, without option /2 was started, and one of files 'ZX128_0.ROM' or 'ZX128_1.ROM' was not found in the current directory. "The file ZXP2_0.ROM or ZXP2_1.ROM not found" The 128 version of the simulator, with option /2, was started, and one of files 'ZXP2_0.ROM' or 'ZXP2_1.ROM' was not found in the current directory. "File ZXI1.ROM not found" The simulator was started with option /E, and the file 'ZXI1.ROM' was not found in the current directory. "Error in snapshot file" From any reason, the loading of the snapshot file using command /R failed. Most probably, something is wrong with your snapshot file name (or the snapshot file with this name not exists), or the file was not created with 'Warajevo' nor Lunter's 'Z80' emulator up to version 3.03. "Incorrect hardware version" Most probably, this error occurs when loading the 48K snapshot file in the 128K version of the emulator, or opposite. Also, this error occurs in a case if the snapshot file is with active ZX interface 1, but the file 'ZXI1.ROM' is not present, or when trying to load Lunter's snapshot files with a active SamRam or Multiface 128. "Can not work on 8086/8088" This simulator requires at least '80286' processor for work. "Invalid graphic card" There is no graphic card that responds like CGA, Hercules, EGA, EGA Mono or VGA. "DOS critical error was fatal" In most of cases, the simulator traps DOS critical error interrupt and does required actions. However, in some situations, the simulator cannot recover from critical error (mostly on the beginning or the end of the program). In this case this error occurs. "Program use 128 ports at address #nnnn" This error message occurs when option /?128 is active, and program tries to write some data to any Spectrum 128 port. Address will be displayed in a same way as with raport "Program finish at address #nnnn". "Unexpected wrapping at address #nnnn" The processor '80286' and its younger brothers 'cannot' to put 16-bit number to the address with offset #FFFF, and in this case execute INT 0DH. The simulator traps this interrupt and does some actions for problem solution. We think we solved all cases. However this rapport is kept for a case of the unexpected interrupt 0DH. If this rapport occurs, this means existence of a bug in the simulator. The address when the problem happened is displayed in a same way as with rapport "Program finish at address #nnnn". In a case of this rapport, please inform us under which circumstances and with which program occurred this rapport. 3. BUILT IN MONITOR ================ 3.1. THE FRONT PANEL =============== Monitor is one of the most interesting features of the Warajevo Spectrum simulator. The monitor is started by pressing F3, and it is fully transparent for Z80 programs (e.g. it is written in PC machine code and do not use any butes in Spectrum RAM as workspace). After you pressed this key, you saw the front panel. The front panel contains these: - Values of all registers (AF, BC, DE, HL, SP, PC, IX, IY, IR, AF', BC', DE', HL', F and F'); - Memory pointer (MP); - Instruction at a program counter (PC); - The effective address of argument and its value (ARG and (ARG) fields); - The interrupt mode, and flip-flops IFF1 and IFF2; - Memory banks (128 version only) and state of LOCK bit; - A break point address (and eventually page); - Memory bytes around PC, SP, HL, IX, IY, DE, BC and memory pointer. Values of the registers are displayed as sixteen-bit values. They should be decimal or hexadecimal. One register is active, and it is marked with a sign ':'. Registers F and F' are displayed in binary form too, with the explaining of all the bits. Marked register could be changed using the TAB key. The memory pointer (MP) is a default value for many instructions. It is sixteen-bit value too. The program-counter (PC) shows the current instruction. At the top of the screen the program counter, hexadecimal values at this address and the mnemonic of the current instruction are displayed. The mnemonic is standard with addition of some synthetic instructions, listed in the technical part of the manual. If the current instruction reads or changes value in memory, argument field 'ARG' is not blank. It contains the effective address of argument. For example, if the current instruction is 'LD A,(IX+3)', field 'ARG' will have the value of IX register incremented by three. Field '(ARG)' is a value at the address shown by field 'ARG'. Complex implicit read/write instructions like RRD and LDIR do not affect this field. If the current instruction have no memory arguments, these fields will be blank. The interrupt mode is displayed below the sign 'IM'. Two Z80 interrupt flip-flops IFF1 and IFF2 are displayed below the signs 'I' and 'J'. The character under the letter 'R' shows currently active ROM with following meaning: 'S' for standard ROM, 'I' for ZX Interface 1 shadow ROM, and 'D' for 128 Derby ROM. Fields 'M', 'V' and 'L' are meaningful only in 128 version, and shows active RAM page, active video page and status of 48K lock bit. 48 version displays asterisks ('*') instead. Your program could have one break point, where the program immediately jumps to monitor. 'BP' displays its address and eventualy memory page (S, I or D D for ROM, 0-7 for RAM above 49152 in 128 version), and warning message if it is in ROM. If there is no breakpoint, this field will be empty. Finally, you can see the memory bytes register is shown in the middle of the line. bytes on addresses from <rr>-6 to <rr>-1. On bytes on addresses from <rr> to <rr>+5. Used DE, BC and memory pointer (MP). around register values. The On the left side of the line are the right side of the line are registers are: PC, SP, HL, IX, IY, The bottom two lines are used for entering commands and error messages. 3.2. ARGUMENTS OF COMMANDS ===================== Arguments may be numerical or string. Numerical arguments may be entered in a decimal or hexadecimal system. If the number is hexadecimal, it must be preceded by hash (for example #3EC0). Special argument '?' is used in some instructions as a wildcard sign, but if you use this argument in some other instructions, you must know that it is internaly coded as 65535. String arguments are, in fact, packed numeric argument. For example, F'ABC' is the same as F'A' 'B' 'C' or F65 66 67 Two special argument symbols, '.' and '$' have meaning 'Value of memory pointer' and 'Value of current marked register'. Arguments are separated with a space. When you are in monitor, the keys are mapped in PC style, not in Spectrum style. 3.3. MONITOR COMMANDS ================ We will use symbol <word> for sixteen-bit values, and <byte> for eightbit values. Square brackets have meaning 'Optional argument'. A[<word>] --------- ABORT (48 version) ------------------ Leaves the monitor and tries to interrupt program returning to BASIC. If the parameter <word> is omitted, the monitor recovers some system variables (ERRSP, DF_SZ, FLAGX, FLAGS, P_RAMT, PIP, RASP), registers (IY, SP), interrupt modes (IM 0) and flip-flops (EI) then jumps to the main loop (MAIN_EXEC, address 4770) of the Spectrum Basic interpreter. This will interrupt many programs. Sometimes this will not be enough. In that case, use <word> argument. The monitor will restore RASP, PIP and P_RAMT variables and act as: CLEAR <word-1>: NEW Examples: A A25000 A<byte> [<word>] ---------------- Tries to return to BASIC. Restore some variables and act as CLEAR 24999: NEW ABORT (128 version) ------------------- ABORT command in 128 version of simulator is quite complex. The first parameter must have value 48 or 128 with meaning 'Abort to 48 Basic' or 'Abort to 128 Basic'. If you not familiar with Spectrum 128 system variables, you can not understand a lot of things. If the first parameter equals 48, A acts like A command in 48 version of simulator. The only difference is that if the parameter <word> is omitted (soft abort), monitor restores printer channel "P" too, because 48 Basic and 128 Basic have different "P" channels. If the first parameter equals 128, monitor first recovers some vital things, like paging subroutines at address 23296 (SWAP, YOUNGER, ONERR, PIN, POUT and POUT2), and system variables BANKM, RAMRST, P_RAMT, PIP and RASP. Then, if parameter <word> is present, monitor acts like CLEAR <word>-1: NEW in '128 Basic'. But, if parameter <word> is omitted, monitor tries to restore BASIC system. It recovers system variables, registers, interrupt mode and flip-flops like command A48, but it recovers system variables COL, TVPARS, WIDTH, BAUD, some undocumented editor variables in page 7 of RAM (60435 and 65316/7), and printer channel "P" too. Then monitor jumps at address 561 in Derby ROM. This will prepare screen editor for working, and opens a main menu. If you now select '128 Basic', in many cases you can continue work with Basic program who was present in memory. By using command Y (for unlocking a 48K lock bit) and then A128 command, in many cases you can transfer BASIC program from '48 Basic' to '128 Basic'. This is impossible on real Spectrum 128! Note: The A128 command does not restore system variables SFSPACE and SFNEXT, so if their contents are not corrupted, in many cases after A128 command you can normally work with RAM disc. However, this will not work if this variables are corrupted, usually after switching from '48 Basic' to '128 Basic'. In this cases, you must manually restore these variables if you want to use RAM disc after A128 command. Examples: A48 A128 A48 30000 A128 30000 B[<word>] --------- Tries to return in 48 Basic Tries to return in 128 Basic Acts nearly like CLEAR 29999: NEW in 48 Basic Acts nearly like CLEAR 29999: NEW in 128 Basic SET/CLEAR BREAKPOINT -------------------- Sets the break point at address <word>, in current active page. The first byte of the instruction at address <word> will be replaced with 199, a code of instruction RST 0, when you leave monitor. This instruction have special meaning when breakpoint is set (it acts like breakpoint if PC is equal <word>, else it acts like normal RST 0). Then when you leave the monitor and continue executing of the program, incoming of this instruction will return you to the monitor. The original value of this address will be restored. If the break point is in ROM area, you will have the warning message 'Warning: ROM'. This should make the failure in the simulator if the break point is in a data area instead on the beginning of the instruction. Then, first reenter the monitor and then press F9 for reset. Any entrance to monitor will clear the break point, the original value of the changed instruction will be restored, except if you changed it in the mean time, for example with basic POKE instruction. B without parameters clear the breakpoint too. Examples: B#C3A8 B Puts breakpoint at address #C3A8 Remove breakpoint C<word1> <word2> <word3> ------------------------ INTELIGENT COPY --------------- Copies a <word3> bytes from address <word1> to address <word2>. Copying is inteligently, the blocks may be overlaped. Example: C40000 50000 100 Copy 100 bytes from address 40000 to address 50000 D[<word1> [<word2> [<byte1> [<byte2>]]]] ---------------------------------------- DISASSEMBLE ----------- Displays disassembled listing of the program in a form: address bytes mnemonic Parameters are: <word1> <word2> Start address, if omitted, it will be the value of the program counter. End address, if omitted, the instruction will be listed until you pressed the SPACE key. <byte1> Number of rows on the screen, if ommited, or if you give '?' the default value is 24. <byte2> Disassembly option (see text below). Disassembling of RST instruction is smart: the monitor knows that after every RST 8 instruction in every ROM (and after RST 32 instruction in Interface 1 shadow rom) follows one inline byte parameter, and it will be disassembled like 'DB n'; after RST 40 instruction in Derby ROM and after RST 16 instruction in Interface 1 shadow ROM follows one inline word parameter, and it will be disasembled like 'DW n'. Howewer, disassembling of RST 40 instruction in standard ROM (calculator) is only quasi-smart. This restart may have many different inline parameters. Monitor will disasemble inline parameters who follows RST 40 instructions as 'DB n' until monitor detect 'end-calc' inline code (#38) or 'jump' inline code (#33). In many cases this is correct, but sometimes this is not. If you specify parameter <byte2>, it have following meaning: 0 - Turns smart disassembling off, e.g do not display inline parameters as DB and DW; 1 - Disassembly everything as DB n, sometimes useful with O command; 2 - Disassembly everything as DW n; 3 - Disassembly everything as DB n, until byte #38 (end-calc) or byte after byte #33 (jump), then continue with smart disassembling; this is sometimes useful when disassembling FP calculator routines. Examples: D D. D30000 D$ #FC38 D1366 . 14 D43200 43500 ? 2 D0 $ 15 0 D'Aa' D65000 ? E[<word>] --------- Disassemble from current value of program counter Disassemble from current value of memory pointer Disassemble from address 30000 Disassemble from value of current marked register to address #FC38 Disassemble from address 1366 to current value of memory pointer, in pages of 14 screen lines Disassemble everything like DW n from address 43200 to address 43500 Disassemble without displaying inline parameters from address 0 to value of current marked register, in pages og 15 screen lines Disassemble from address 65 to address 97 (this is silly usage of parameters, but it is possible) Disassemble from address 65000 to 65535 (this is unusual using on '?') EXIT/EXECUTE ------------ Returns from monitor to our program with updating changed registers. You can put some values in registers including PC and then execute E command. This will force jump at new PC. If you specify optional parameter <word>, PC register will be set to <word> and then monitor will do ordinary E command. Examples: E E. E$ E30000 Continue executing simulator from current value of program counter (e.g. exit monitor if you not change registers during work in monitor) Continue executing simulator from current value of memory pointer Continue executing simulator from value of current marked register Continue executing from address 30000 F[<byte1> [<byte2> ...]] ------------------------ FIND BYTES/STRING ----------------- Searches sequence of bytes in memory, starting from the memory pointer. You could use the value of bytes or wildcard '?' with meaning 'any byte'. F command without parameters, searchs for a next occurrence of already found sequence of bytes. Examples: F1 2 3 F'Sinclair' F30 25 ? #FD F2 4 'money' F? 63 H - Finds sequence 1,2,3 in memory Finds string 'Sinclair' in memory Finds sequence who have first and second byte 30 and 25, third byte is not significant, and who have fourth byte #FD Finds sequence 2,4,'m','o','n','e','y' in memory Finds sequence who have second byte 63 HEX/DEC TOGGLE -------------- Toggles between decimal and hexadecimal values on display. Parameters are always by default in decimal system, and byte values of the memory are always shown as hexadecimal, because they are shorter. Example: H I[<word>] --------- Toggles hex/dec display on screen INSTRUCTION SINGLE STEP ----------------------- Executes current instruction. If you give the parameter <word>, the executing will be continued with updating the front panes, until the program counter receives the value <word>, or breakpoint, or until you press the SPACE key. You can single step through non-standard load routine, and edge recognizer will still work without problems! Sometimes, when you single step through load (or save) routine, and through some restarts if you have /B command line option, monitor make some unusual steps, but it is not a great problem. Also, monitor will execute instruction after EI together with EI in one step. Examples: I I40000 Performs a instruction single step Performs a continous single stepping until program counter reachs 40000 J[<word>] --------- JUMP TO ------- Puts breakpoint at address <word> and perform E command (e.g. leave monitor, and return to monitor when PC reaches value <word>). If parameter <word> is omitted, breakpoint will be put after current instruction, or after inline parameters if current instruction is RST (for more informations about inline parameters see description of D command). This is useful when you not wish single stepping through subroutine, or if you want to execute a complete loop without single stepping. You can normally use J with sequence RST 40; DW <address> in 128 Derby ROM, because monitor knows that RST 40 in Derby ROM have one word inline parameter. However, you must be carefully when use J command to execute calculator restart (RST 40 in standard ROM), because breakpoint will not always be put on correct place. It is better to specify parameter <word> manually in this case. Examples: J J. J#C328 K<word1> <word2> <byte> ----------------------- Puts breakpoint after current instruction, then leave monitor Puts breakpoint at value of memory pointer, then leave monitor Puts breakpoint at address #C328, then leave monitor KILL MEMORY BLOCK ----------------- Fills a memory block from address <word1> to <word2> (including <word2>) with a value <byte>. Example: K16384 22527 0 L[<word>] --------- Fills address from 16384 to 22527 with 0 (e.g. clear video memory) LOAD BLOCK ---------- Loads a next block from the tape at the address <word>. If address <word> is omitted, the assumed value will be a memory pointer. A flag byte is ignored. Examples: L L16384 Loads block at current value of memory pointer Loads block at address 16384 (e.g. in video memory) M[<word> [<byte1> [<byte2> ...]]] --------------------------------- SET MEMORY POINTER ------------------ Sets a memory pointer to a value <word>. If the value is omitted, the assumed value is marked register. This instruction may have more than one parameter. In that case it acts as a combination of M and P commands, sets a memory pointer and then executes command P with a rest of parameters (see command P). Examples: M M24500 M40000 5 3 200 M24220 3 ? ? 'Sinclair' M$ 'ZX' O - Sets memory pointer to value of currently marked register Sets memory pointer to value 24500 Sets memory pointer to value 40000, then puts bytes 5, 3 and 200 at address 40000, 40001 and 40002; memory pointer now have value 40003 Sets memory pointer to value 24220, puts value 3 there, skips two bytes, and finnaly, puts string 'Sinclair' at address 24223; memory pointer now have value 24231 Sets memory pointer to value of currently marked register, then put string 'ZX' there TOGGLES OUTPUT FILE ON/OFF -------------------------- This is one of the most powerful command in the monitor. When you give command O first time, this command will create file 'MONITOR.OUT' if this file is not exist, or it will open this file for appending. After this, any following actions in the monitor will send results of actions into this file, until you close this file by giving command O again. When output file is open, you will see double prompt '>>' instead of single prompt '>'. Any opening of the output file will cause sending contents of the front panel (in slightly modified format, and without memory bytes arround register values) to the output file. Commands which you give will be send to output file (with prompt '>' to indicate that is a command) including eventually error messages. After this, influence to the output file depends of the command: - Commands D and T will send listing to the output file. - Commands B, C, K, L, S, V and Z do not affect output file. - Commands H, R, U, X and Y force sending of front panel after end of command. - Commands A, E, J and Q leave monitor, and when you returns to monitor (for example, by pressing F3), front panel will be send to the output file. - Commands F, M, P and W will send new value of memory pointer to the output file. - Commands ?, +, -, *, /, &, | and ^ will send results of commands to the output file in same format as at screen. - Command ! will send new status of interrupt flip-flops and mode to the output file. - Command I without parameter will send disassembled current instruction to the output file, but if you give I command with parameter, any instructions that monitor executes will be sent in disassembled format to the output file. So, you will get trace of program execution in similary form as a listing produced with D command. - Command O temporary closes output file, and it is opened again when you type O again. So, two subsequently O commands will force sending of front panel too. Example: O Open or close monitor output file 'MONITOR.OUT' P<byte1> [<byte2> [<byte3> ... ]] --------------------------------- POKE BYTES ---------- Places a sequence of bytes in memory, from the memory pointer. The memory pointer is incremented by one after every byte. If any of values is a '?', the original value at this address will not be changed. Examples: P10 100 ? 25 P'Stop the war in Bosnia!' P? Q - Puts bytes 10 and 100 at current value of memory pointer, skips one byte, and finnaly, puts value 25; memory pointer will be incremented by four Puts string 'Stop the war in Bosnia!' at current value of memory pointer, and increments memory pointer by 22 Increments memory pointer by one QUIT MONITOR ------------ Returns to the program, with restoring registers as they were when you entered the monitor. You must make difference between Q and E commands. Q acts like combination of U and E commands. Example: Q Quit monitor R[<word>] --------- REGISTER CHANGE --------------- Changes a value of a marked register to <word>. If this parameter is omitted, register receives a value of the memory pointer. The marked register can be changed using TAB key. Examples: R Sets currently marked register to current value of memory pointer Sets currently marked register to 5000 R5000 S<word1> <word2> [<byte1> [<byte2> ...]] ---------------------------------------- SAVE BLOCK (OR BYTES) --------------------- Saves a part of memory from address <word1> with a size <word2>. If there are no extra parameters, memory will be saved as headerless block, with flag byte 255. Otherwise, memory will be saved as 'Bytes' file (with header). Extra parameters represents byte values of file name. Examples: S16384 6912 S16384 6912 'Scr' Save 6912 bytes from address 16384 (e.g. screen) as a headerless file Save screen as a 'Bytes' file with filename 'Scr' T[<word1> [<word2> [<byte>]]] ----------------------------- TEXT LIST --------- Displays contest of memory in hexadecimal and ASCII form. Characters with codes which is greater than 128 will be reduced to range 0-127, and will be displayed in inverse video. Control codes will be displayed as '.'. Parameters are: <word1> <word2> <byte> Start address, if omitted, it will be the value of the memory pointer. End address, if omitted, the memory will be listed until you pressed the SPACE key. Number of rows on the screen, if omitted, the default value is 24. Examples: T40000 50000 10 Displays HEX and ASCII memory dump from address 40000 to 50000, in pages of 10 screen lines T1000 2000 T#C000 T$ T Displays HEX and ASCII memory dump from 1000 to 2000 Displays HEX and ASCII memory dump from #C000 Displays HEX and ASCII memory dump from currently marked register (usualy PC) Displays HEX and ASCII memory dump from value of memory pointer U - address address value of current UNDO REGISTER CHANGES --------------------Returns a value of all registers to be as when you entered the monitor. Example: U Undo all changes of registers V - VIEW SCREEN ----------- Displays original contents of video memory (standard or alternative on 128 version of simulator, depending of V field on front panel) on the screen until you pressed a key. Example: V View screen W<word1> [<word2> [<word3> ...]] -------------------------------- POKE WORDS ---------- Places a sequence of the words in memory from a memory pointer. After every word, the memory pointer will be incremented by two. Examples: W40000 #C500 $ 44200 W50 ? 400 W'ZX' X[<byte>] Poke words 40000, #C500, value of currently marked register, and 44200 at current value of memory pointer; memory pointer will be incremented by 8 Poke words 50 (e.g. bytes 50 and 0), 65535 ('?' is not a wildcard in W command) and 400 at current value of memory pointer Poke following sequence of bytes: 'Z',0,'X',0 at value of memory pointer SET XOR BYTE --------- ------------ Many programs are encrypted using XOR function. To see it, without executing a decryption routine, you could use command X followed with <byte>. After this, commands T, F, D will execute XOR function between every displayed and checked byte and value <byte>. This also works with front panel display. Next, the commands P, K, and W will execute XOR function between <byte> and every byte stored in memory. For example, for listing of texts in adventures written in 'The quill' use X255 command. Command X without a parameter is the same as X0 (i.e. undo effect of command X). Examples: X30 X Set xor byte to 30 Undo effect of X Y - SWAP ROMS (48 version) ---------------------- Toggles active ROM between standard ROM and Interface 1 shadow ROM (if Interface 1 is present). This command is expanded on 128 version of simulator. Example: Y Switch on/off ZX Interface 1 shadow ROM Y[<byte1> [<byte2> [<byte3> [<byte4>]]]] ---------------------------------------- MEMORY PAGES (128 version) -------------------------- Changes active memory banks on 128 version of simulator. Parameters are: <byte1> <byte2> <byte3> <byte4> Active ROM (0 = Derby, 1 = Standard, 2 = Interface 1 shadow) Active RAM bank at addresses from 49152 to 65535 (0-7) Active video page (0 = Standard, 1 = Alternative) Value of 48K lock bit (1 = MMU is locked) Command Y without parameters restores memory banks to be as when you entered the monitor (e.g. undo changes of memory pages). Parameters <byte1>, <byte2> and <byte3> may be '?' with meaning 'No changes'. Examples: Y Y2 Y0 7 Undo changes of memory pages Set Interface 1 ROM as active ROM Set Derby ROM as active ROM and select RAM page 7 Y? 4 Y1 ? 1 Y? ? 0 Y1 0 0 1 Y? ? ? 0 Z[<byte> [<word>]] ------------------ Set RAM page 4 as active RAM Set Standard ROM as active ROM and use alternative video page Switch off alternative video page Set Standard ROM as active ROM, select RAM page 0, use standard video page, and then lock memory management unit (e.g. acts nearly like a SPECTRUM command in '128 Basic') Only reset 48K lock bit; this is impossible on real ZX Spectrum 128, but in this simulator it is possible, but only by using Y command in monitor DUMP SCREEN ----------- Dumps screen on Epson or IBM compatibile printer. The first parameter has the following meaning: 0 - Make a big and a very nice shadow screen dump, with 36 dots per inch. Every screen pixel (set or reset) will be converted into 2x2 matrix onto printer, depending of atribute byte on screen. So, real printer resolution in this mode is 72 dots per inch, and dump size is 18 x 13.6 cm. This is default value of <byte> parameter. 1 - Make a big bit-map screen dump, with 36 dots per inch. Every screen pixel which is set will be converted into 2x2 solid matrix onto printer, so real printer resolution in this mode is 72 dots per inch, and dump size is some as in previous option, 18 x 13.6 cm. 2 - Make a medium size bit-map screen dump, with 72 dots per inch. Every screen pixel which is set give one pixel on printer. Dump size in this mode is 9 x 6.8 cm. 3 - Make a small size bit-map screen dump, useful for making game maps, with 144 dots per inch, and with two passes per every line. Dump size in this mode is 4.5 x 3.4 cm. 4 - Make a extremly small size bit-map screen dump, with 240 dots per inch, and with three passes per every line. Dump size is 2.7 x 2 cm. 5 - Like 0, but with border arround screen. 6 - Like 1, but with border arround screen. 7 - Like 2, but with border arround screen. 8 - Like 3, but with border arround screen. 9 - Like 4, but with border arround screen. Dump is smart in meaning that every set pixel which have ink color same as paper color will be treated as a reset pixel. This is implemented because many programs use this method for hideing some strange data on screen, and this need not be seen at screen dump. The parameter <word> sets a left margin for screen dump in screen pixels (depending of dump mode). So, if <word> is 256, dump is moved right for one full dump width in this dump mode. This is useful when you make game maps. If you have A4 printer, maximum legal value of this parameter who does not produce dump out of paper is 32, 320, 896 and 1664 for modes 0 (or 1), 2, 3 and 4 respectively. If you are skilled, in some cases you can make whole map of game on only one page of paper! Examples: Z Z2 Z7 Z4 Z4 256 Z4 512 !<byte1> [<byte2>] ------------------ Make a nice shadow dump of screen Make a medium size bit-map dump of screen Make a medium size bit-map dump of screen, with border around picture Make a extremly small bit-map screen dump Make a extremly small bit-map screen dump from a colon where previous command finish Make a extremly small bit-map screen dump from a colon where previous command finish SET INTERUPT MODE AND IFFS -------------------------- Sets interrupt flip-flops IFF1 and IFF2 to <byte1> and switch interrupt mode to IM <byte2>, if <byte2> is present. Parameter <byte1> may be '?', with meaning 'No change'. Examples: !0 !1 !0 2 !? 1 ?[<byte>|<word>] ---------------- Disable interrupts Enable interrupts Disable interrupts and sets interrupt mode 2 Sets interrupt mode 1 PRINT NUMBER ------------ If an argument is byte value, it will be displayed in hexadecimal and decimal form. If it is between 32 and 127, will be also displayed its ASCII value. For arguments above 127 it will be displayed also as a negative number. If an argument is word value (greater than 255), it will be displayed in hexadecimal and decimal form, then will be eventually displayed as a negative number (if greater than 32767), and finally with high and low bytes. In a case of missing argument, the default value is value of the marked register. This is useful for examining high and low byte of 16-bit registers. Examples: ?10 ?40 ?#FF ?30000 ?45000 ?'a' ?? ? Displays "#000A 10" Displays "#0028 40 '('" Displays "#00FF 255 -1" Displays "#7530 30000 117,48" Displays "#AFC8 45000 -20536 175,200" Displays "#0061 97 'a'" Displays "#FFFF 65535 -1 255,255" (meaning of '?') Displays value of currently marked register in many forms, depending of its value Displays current value of memory pointers in many forms, depending of its value ?. +<byte1>|<word1> <byte2>|<word2> -------------------------------- ADDITION -------- Adds arguments and displays a result as in '?' command. Example: +7 8 Adds 7 and 8 and displays result (i.e. "#000F 15") -<byte1>|<word1> <byte2>|<word2> -------------------------------- SUBSTRACTION ------------ Subtracts arguments and displays a result as in '?' command. Example: -. $ Substracts value of currently marked register from value of memory pointer, and displays result *<byte1>|<word1> <byte2>|<word2> -------------------------------- MULTIPLICATION -------------- Multiples arguments and displays a result as in '?' command. Example: *7 3273 Multiply 7 and 3273 and displays result /<byte1>|<word1> <byte2>|<word2> -------------------------------- DIVISION -------- Divides arguments and displays a integer part of result as in '?' command. Example: /1200 14 Divides 1200 by 14 and displays a integer part %<byte1>|<word1> <byte2>|<word2> -------------------------------- REMAINDER --------- Divides arguments and displays a remainder of division as in '?' command. Example: %1200 14 Divides 1200 by 14 and displays remainder &<byte1>|<word1> <byte2>|<word2> -------------------------------- BINARY AND ---------- Performs a binary AND between the arguments and displays a result as in '?' command. Example: &3200 1500 Performs a binary AND between 3200 and 1500 and displays result (which is 1152) |<byte1>|<word1> <byte2>|<word2> -------------------------------- BINARY OR --------- Performs a binary OR between the arguments and displays a result as in '?' command. Example: |4200 1700 Performs a binary OR between 4200 and 1700 and displays result (which is 5868) ^<byte1>|<word1> <byte2>|<word2> -------------------------------- BINARY XOR ---------- Performs a binary XOR between the arguments and displays a result as in '?' command. Example: ^$ #FFAA Performs a binary XOR between value of currently marked register and #FFAA, then displays result 3.4. MONITOR ERROR MESSAGES ====================== "Invalid command" The monitor understand given command. "Syntax error" The given command is correct, but there is an error in a syntax, usualy in some parameters. "Too few parameters" The given command expects more parameters than you gave. However, any excess parameters are ignored. "Parameter too big" Some parameter has too big value for given command. "Overflow" The result of multiplication excess 16 bit, or given command performs division by zero. "RAMPTOP too low" Minimal legal value for RAMPTOP in A (ABORT) command is 23900. "String not found" Command F not founded given sequence (or next occurence of previously given sequence). "Warning: ROM" The breakpoint could be put into ROM, but sometimes it is dangerous. "MMU is locked" Command Y (or A) tried to switch memory banks during 48K lock bit is switch on (128 version only). "No ZX Interface 1" Command Y tries to set Interface 1 shadow ROM, but simulator was not started with /E option (e.g. Interface 1 not present) "Abort may be 48 or 128" The first parameter of the A command on 128 version of simulator must be 48 or 128 to specify abort in '48 Basic' or '128 Basic'. "File output error" From any reason, monitor log file (MONITOR.OUT) is not open correctly with command O, or there was some error during writing to monitor log file. "Type Q to quit" This is only a short help message, if you entered the monitor because you press F3 key in mistake. 4. PROGRAM 'ZXTOOLS' ================= ZXTOOLS is special program for manipulations with tape and snapshot files. It is written in Turbo Pascal. This version has redesigned user interface like in Borland compilers. Hard disk is recommended, if you use floppy do not remove diskette from drive. This program uses three files: ZXTOOLS.EXE ZXTOOLS.HLP COMM128.BZX Main file Help file Communication program to be sent to Spectrum 128 Because this program has enough big help file, we will only briefly list all its options. Access help using F1. 4.1. TAPE-FILES MENU =============== This menu is dedicated for manipulations with TAP files. 4.1.1. TAPES SUBMENU ============= This submenu contains options: Select View Selecting the active tape file View the contest of the current tape file Print Copy to New Print the contest to screen, file or printer Copy selected blocks to other tape file 4.1.2. BLOCKS SUBMENU ============== This submenu contains following options: Reorder Extract Delete Add Exclude Change position Changing order of blocks Extracting blocks to standalone files Deleting blocks Adding standalone file to tape file Making block unaccesable Moving block to new position 4.1.3. IMPLODE SUBMENU =============== ZXTOOLS has built in compresor, similar to PKZIP (but unfortunantely slower). Tape files can be still normally loaded even compressed. The options of this submenu are: Compress Decompress Efficiency Compress all blocks, selected blocks or removes unaccesable blocks Decompresses the tape file Statistics about compression 4.1.4. COMMUNICATIONS SUBMENU ====================== For connection with Spectrum 128 and exchanging of software, use this menu, with options: Send to Spectrum Receive from Spectrum Send selected blocks to Spectrum 128 Append block received from Spectrum 128 to tape-file Send communicat. program Send communication program to Spectrum 128 Configure RS232 Set baud rate and port 4.1.5. CONVERT SUBMENU =============== We supported conversion of different Spectrum formats and tape files of many other emulators. The options are: ASCII<->Basic ASCII<->Hisoft Convert ASCII file to Spectrum BASIC file and in opposite direction Convert ASCII file to Spectrum GENS, Pascal or C file and in opposite direction ASCII<->Tassword Convert ASCII file to Spectrum Tassword 2 or 3 file and in opposite direction ASCII<->The last word Convert ASCII file to Spectrum The last word file and in opposite direction ASCII<->Machine lighning Convert ASCII file to Spectrum Machine lightning file and in opposite direction ASCII<->Forth Convert ASCII file to Spectrum Abersoft Forth file and in opposite direction ASCII<->Logo Convert ASCII file to Spectrum Logo file and in opposite direction SCREEN$->TIFF Converts Spectrum screen to standard TIFF format with or without colors Other simulators Converts tape files to or from formats of Spectrum emulators Z80 (Holland), ZX (Roman and easy inc), SPECEM (Irish) and SP (Polish). 4.2. Z80 SNAPSHOTS MENU ================== This is menu dedicated for manipulations with snapshot files. 4.2.1. SNAPS SUBMENU ============= This submenu contains the following options: Select Info Selecting the active snapshot file View and explain snapshot header 4.2.2. EDIT SUBMENU ============ This submenu contains these options: Processor registers Hardware devices Memory Change values of processor registers Change values of some I/O ports etc. Change memory locations 4.2.3. CONVERT SUBMENU =============== This submenu contains these options: Spanish Spectrum <-> Warajevo Convert snapshots between Spanish emulator called Spectrum and Warajevo VGASPEC<->Warajevo Convert snapshots between Spanish emulator called VGASPEC and Warajevo Irish SPECEM<->Warajevo Convert snapshots between Irish emulator called SPECEM and Warajevo JPP<->Warajevo Convert snapshots between Norway emulator called JPP and Warajevo Z80(48K) <-> Z80 (128K) Convert any Warajevo compatible snapshot to ZXCOMP compatible snapshot. Z80 snapshot -> TAP Convert snapshot to tape file 4.3. DOS MENU ======== This menu contains standard MS DOS functions: About Directory Change directory OS Shell Exit 4.4. Informations about ZXTOOLS and release List the current directory Change the current directory Temporary leave ZXTOOLS Exit from ZXTOOLS THE COMMUNICATION PROGRAM ========================= This program is dedicated for use on original 'Spectrum 128' and will be transfered to this computer using ZXTOOLS. It is a modification of 'Mastercopy 128' written by Vatroslav Sobot. We decided to use this program for communications, because Spectrum 128 has enough memory and RS232 interface, and this program is very user-friendly. Connect the cable like this (if you find ugly Sinclair's connector): Spectrum 128 1 2 3 4 5 6 PC COM port 24 pins トトトトトトトトトトトトトトトトトトトトトトトト トトトトトトトトトトトトトトトトトトツトトトトトトトトトトト タトトトトトトトトトトト トトトトトトトトトトトトトトトトトトトトトトトトトトトトトト トトトトトトトトトトトトトトトトトトトトトトトトトトトトトト トトトトトトトトトトトトトトトトトトトトトトトトトトトトトト トトトトトトトトトトトトトトトトトトトトトトトトトトトトトト 5 6 20 3 2 7 When you load communication program to your Spectrum you have three options: 1. TAPE TO TAPE 2. TAPE TO PC 3. PC TO TAPE These options define input and output device. After you select devices, you have these options: L - Loads header and corresponding data block from input device until BREAK key was pressed, or if loading fails. S - Saves all blocks from memory to output device. H - Loads headerless blocks from input device until BREAK key was pressed or if loading fails. C - Clears all blocks from memory. R - Removes last block from memory F - Loads headers and displays them on the screen, but not store in RAM. Q - Resets computer. V - Views all blocks in the memory. While viewing you have these options: A - cancel autostart from BASIC programs. N - change name of header blocks. R - remove this headerless (or header and corresponding block) from memory. S - Saves blocks from this to the output device. n - Make pause (n=1-9 sec.) when saving this block. Using this program you can transfer all programs with normal speed. For speedlock programs, see technical part of the manual. 5. PROGRAM 'ZXSHELL' ================= ZXSHELL is a program for easier use of the 'Warajevo' spectrum simulator. Purpose of this program is to make easier starting of transferred software, and keeping the database about it. ZXSHELL is written in Clipper 5.01, so it uses standard DBF and NTX files. ZXSHELL needs a PC with a hard disc. We do not recommend using this program on floppy, because it is database software. Also, its speed depends on the amount of free memory (so remove resident programs if it looks too slow for you). This program uses these files: ZXSHELL.EXE SOFTWARE.DBF SOFTWARE.DBT SOFTWARE.NTX ADDITION.DBF SPECSIM.CFG Main program Main database Text assigned with main database Index file Part of the database stored in RAM Configuration file for simulator If any of these files is missing, ZXSHELL will create it. ZXSHELL must be in the same directory with simulator and ZXTOOLS, for correct executing. It executes SPEC48, SPEC128 or ZXTOOLS by stuffing their names in the keyboard buffer. So, you must start it from programs that allows direct command typing (COMMAND.COM, 4DOS, Norton commander), but not from programs (as Windows, DOS Shell, etc.) without direct prompt. 5.1. MAIN MENU ========= The main menu of this program contains eight options. They are: - Execute: Edit: Index: Sort/Reindex: Delete: Report: Mark: Startup: For For For For For For For For starting other parts of the simulator; entering and editing of data base; creating method of indexing the database; reindexing of the main database and sorting of additionals; deleting records from the database; creating the report; marking records to be before other records in data base; setting and removing initial options. Key F1 is a HELP key. HELP is a topic sensitive, and you can get detail help about current option in every time. So, instructions for this program is not very descriptive. 5.2. ENTERING AND EDITING THE MAIN DATABASE ====================================== First, you must fill the database with your data, of course. To do it, select option 'Main data base' in 'Edit' menu. As you see, you could see 16 records displayed on the screen. Main base is organized as a table that scrolls in all four directions. You can also see the highlighting. It shows the active record and field. If you want to enter the new record, you must be at most bottom position. The fastest way to be there is by pressing Ctrl + PgDn and then press cursor down. Then will appear a new row, and you could fill it with values. It is not necessary to say that if you are not on the last row, you edit highlighted fields. While moving through the data base, you could use the following keys (these keys can be displayed using F1 key): Arrows: Move the highlighting Ctrl+Left: Scroll left Ctrl+Right: Scroll right Home: Move to start of the window End: Ctrl+Home: Ctrl+End: PgUp: PgDn: Ctrl+PgUp: Ctrl+PgDn: F1: F2: Esc: Enter: Move to end of the window Move to start of the record Move to end of the record Move up by one page Move down by one page Move to start of the database Move to end of the database HELP key Seek to desired record (see section 5.2.12.) Return to main menu Editing of the highlighted field You have 12 accessible fields, which can be edited. 5.2.1. FIELD 'SHORT NAME' ================== This field has important meaning when you starti ZXSHELL. If ZXSHELL is started with the parameter (this short name) loading will be done automatically. For example: ZXSHELL ATICATAC will search the record, with the short name 'ATICATAC', look its position and then execute SPEC48.EXE, with a such configuration file, that program 'ATICATAC' will be loaded and started automatically. 5.2.2. FIELD 'FULL NAME' ================= Of course, a short name is not enough descriptive. The full name of the program is stored in the database too. 5.2.3. FIELD 'SOFTWARE DISTRIBUTOR OR PRODUCTOR' ========================================= There is a place in the database to keep a name of the corporation that wrote the program. You can enter the new corporation, or the already entered corporation. If you want to enter the new name of program producer press ENTER, then type in the name. If you already entered this name, press the first letter of the name many times until this name appears. It is also possible to press ENTER, then first few letters of the name, and then ENTER again. On the screen you will see the menu with all producers whose names start with these letters. 5.2.4. FIELD 'CATEGORY OF PROGRAM' =========================== Enter the category of the program (eg. Arcade Adventure) in same way as a corporation. 5.2.5. FIELD 'YEAR' ============ Simply type in the value of the year when program was produced. 5.2.6. FIELDS 'TAPE NAME' AND 'POSITION' ================================= Here, enter the name of the tape file where the program is located and its position in the tape. You could not have two different tape files with same name, even if they are on different disks (this will be explained later). 5.2.7. FIELD 'COMPUTER TYPE' ===================== Editing of this field makes the pop-up for choosing type of computer for which the game is dedicated. 5.2.8. FIELD 'MESSAGE LANGUAGE' ======================== To distinguish programs with messages in English, French, Dutch, German or Bosnian, enter the language in same way as category or producer. 5.2.9. FIELD 'DESCRIPTION' =================== This field will display values 'Empty' or 'Not empty'. When you enter it, you will have a simple text editor. Finish editing with Ctrl + W to save changes or Esc to discard (if you make changes, you must type Y after Esc). You can use following keys for editing: Arrows: Ctrl+Left: Ctrl+Right: PgUp: PgDn: Ctrl+PgUp: Ctrl+End: Home: End: Ctrl+Home: Cursor moving Move left by one word Move right by one word Move up by one page Move down by one page Move to start of the field Move to end of the field Move to start of the line Move to end of the line Move to start of the window Ctrl+End: Enter: Tab: Del: Ctrl+Y: Ctrl+T: Insert: Ctrl+V: Ctrl+B: Ctrl+W: Esc: F1: Move to end of the window Move to next line Tabulator key Delete a char Delete a line Delete a word Toggle insert mode Same as Insert Rephormat word-wrap Write changes Discard changes HELP key 5.2.10. FIELD 'TROUBLES' ================ Unfortunately, our simulator is not perfect, so it is good to keep info about problems with this program. Editing of this field opens a list of possible problems. Just type Y if a problem of this kind appears. For example, if your program flickers too much, you can press Y when the highlight is on flickering. If all is right, in this field will be displayed OK, else will be displayed 'Troubles?'. For meaning of troubles, see file TESTED.LST. 5.2.11. FIELD 'STARTUP OPTIONS' ======================= Here enter the command parameter string to be attached with 'SPEC48.EXE' when executing this program. This string can be globally changed also from the 'Startup' menu. 5.2.12. SEEK KEY ======== The key F2 is used to seek to the desired record. When you pressed this key, enter values of fields to be searched. All fields active in the index will be ready to enter. 5.3. EDITING OF ADDITIONAL DATABASES =============================== To avoid duplicated names due to typing errors, we used previously explained method for entering producers, categories, languages and tapes. Why we complicated? Imagine this situation: First you entered 'Ultimate' for the producer, and later 'Ultmate' for the other game of the same producer. The second was typing error, but the computer does not know about it. So, we do not keep in the main database the whole word 'Ultimate' but only its internal code, for example U002. File 'ADDITION.DBF' keeps meaning of these internal codes, which are stored in memory, too. So, we could press U few times and be sure that we have two different games of the same producer! If you want to modify the producer name, you must use 'Manufacturers' option in 'Edit' menu, place highlighting to the second column and type the new text. There is nothing new to say about options 'Languages' and 'Program categories' in 'Edit' menu. Option 'Tape' in 'Edit' menu is a bit different. When you want to change the tape name, you must enter drive and directory where the tape is located, and optionally, diskette name. Using diskette name ZXSHELL can warn you if you entered a wrong diskette into a disk drive. 5.4. INDEXING ======== A very interesting feature of this database program is capability of creating desired indexes. As you see, 'Index' menu contains a dashed line. All fields above the dashed line will be included in the index. Field below this line will not be part of the index. If you move the highlight to the field, and press ENTER, the field will change its relative position to the line. If the field was below the line, it will go to the top of the menu. If you choose the field above the line, it will go down. It is easy, doesn't it. 5.5. SORTING AND REINDEXING ====================== When you defined order of the fields included in the index, select option 'Main data base' in the 'Sort/Reindex' menu. The file 'SOFTWARE.NTX' will be created and it will seem to you that the database is sorted! You will remark that some fields which keeps code, not name (fields Manufacturer, Category and Language) are not completely sorted. In fact, they are sorted according to code. The code begins with the same letter as the field, so the name 'Ultimate' will surely be before 'Vortex' and after 'Topo soft', but may be after 'University software'. Last three options in 'Sort/Reindex' menu sorts the additional databases changing the codes to become sorted. 5.6. DELETING RECORDS ================ Deleting of records in databases is easy. Move through all four databases like in 'Edit' menu. Press SPACE to toggle the sign on record, is it to be deleted or not. Finally, press ENTER. Then will appear the pop-up known from ZXTOOLS: 'Reselect/Proceed/Abandon'. If you choose 'Proceed', deleting will start. In case of 'Reselect' continues selecting of records. Finally, choice of 'Abandon' will forget deleting of all the fields. 5.7. MARKING OF RECORDS ================== Every record can be marked. Index of the main database, in fact, contains yet another field. This field is one char long, and included in the index at its beginning. So, if this field is not empty, corresponding record will be sent to the end of the database. 5.7.1. MARKING SPECIFIC RECORDS ======================== You can mark the records in a main database on same way as in deleting of the records. 5.7.2. MARKING MATCHED RECORDS ======================= Use this option to mark records that satisfy any defined condition. You could enter the field name, including wildcards as '*' and '?'. These wildcards have the same meaning as in DOS. 5.7.3. SWAP PRIORITY ============= This option marks unmarked records and unmarks marked. It should make the work much faster, if correctly done. 5.7.4. UNMARK ALL ========== All marked records will become unmarked. 5.8. MAKING A REPORTS ================ ZXSHELL could make the reports. You could print them to printer, screen and file named ZXSHREP.TXT. The user could choose the fields to be displayed, and it is possible to choose printing of all or only marked (unmarked) records. 5.8.1. DEFINITION OF THE REPORT ======================== Reports are organized in the way that one record is printed in one line. Because there are limited number of characters in line, fields may be cut, but optimally. Select the fields to be printed using 'Y'. You could also enter page size in lines, and number of characters in one line, which may be between 80 and a number which depends of selected printer. At the bottom of the window for defining a report select 'M' for printing marked fields, 'U' for unmarked, or 'A' for all fields. If you include printing of troubles into report, troubles will be coded with meaning described in file TESTED.LST. 5.8.2. PRINTING THE REPORT =================== After you defined the report, you could print it on the screen, the printer or send it to the file. Next three options of 'Report' menus are used for printing to one of these three devices. 5.8.3. SELECTING A PRINTER =================== Using this option you can select a printer. This option will define necessary control codes for printing, and a maximal line length. If you select ASCII printers, control codes will not be inserted. Maximal line lengths are: ASCII A4: ASCII A3: Epson A4 Pica: Epson A4 Compressed: Epson A4 Elite Compressed: HP LaserJet Courier: HP LaserJet Compress: Epson A3 Pica: Epson A3 Compressed: Epson A3 Elite Compressed: 5.9. 80 characters 132 characters 80 characters 132 characters 160 characters 80 characters 132 characters 132 characters 200 characters 255 characters EXECUTING THE SIMULATOR FROM ZXSHELL ENVIRONMENT ================================================ When you entered the database, you could use it. The menu 'Execute' is used for a link with other three components of Warajevo simulator, SPEC48, SPEC128, and ZXTOOLS. They must be in the same directory as ZXSHELL. 5.9.1. START SIMULATOR AND PROGRAM =========================== You could move through the database like in 'Edit' or 'Delete' menu. When you selected the program, press ENTER. Depending on type of computer in the database will be started SPEC48 or SPEC128 with option /C. Commands: /T<tapename> /D<directory> /A /F<file_position> and additional configuration parameters from the database will be written in the configuration file 'SPECSIM.CFG'. The program will stuff some codes in the keyboard buffer and then exit to DOS. This will cause running of desired program. 5.9.2. OTHER OPTIONS OF 'EXECUTE' MENU =============================== Last four options simply start SPEC48, SPEC128, ZXTOOLS or exits to DOS respectively, without command line parameters. 5.10. THE 'STARTUP' MENU ================== If you want to replace startup options of all programs in the database, you can use this menu. For example, if you want to add the /JA switch to all programs because you bought the analog joystick. The first option of the Startup menu simply appends the entered string to all startup strings in the database. The second option of the Startup menu removes the entered string from startup strings in the database, if the entered string is before the space character. For example the option /I will not be removed from startup string /A /I9 but will be removed from /A /I /VC 5.11. ZXSHELL AND SNAPSHOT FILES ========================== ZXSHELL can work with snapshot files too. If the tape name is omitted, ZXSHELL will simply start simulator with startup parameters. You can simply add /R command that loads your program in startup string. Unfortunately, on this way ZXSHELL will not warn you if you used the wrong diskette, which happens with TAP files. If you will to solve this, make one dummy tape file (it may be empty) on the diskette which contains snapshot files, and assign this tape name with desired snapshot file. Then you can describe this tape as other tapes, so you can use all things as with working with TAP files. As a artefact, this tape will be the active tape during working in the simulator. 6. PROGRAM 'ZXCOMP' ================ Using program ZXCOMP you can compile snapshot files into a standalone EXE programs which can be started indipedently of simulator and ROM files. This compiling has a following limitations: - Snapshot files which are saved during Interface 1 emulation was active can't be compiled. Simulation of Spectrum +2 is not supported in compiled programs. - You can not call Tape Manager or monitor from compiled program (because these are not included into compiled program), so keys F2 and F3 have no functions. Also, keys F7, F8 and F9 will not work, too. - Key F1 acts as a 'pause' key, not as keyboard HELP. Compiled program will not paint title screen (Clive Sinclair). - Compiled program does not support RS232 and ZX printer emulations, and a tape system emulations. However, loading and saving blocks is possible on two ways, using two special instructions with codes #ED #FF and #ED #FE, or two special instructions with codes #ED #FD and #ED #FC (see sections 6.2. and 6.3.). - Any jumps to address 0 in source program will cause exiting to DOS instead a simulator reseting. F10 key do the same thing. When you exit compiled program a small copyright message will be printed instead of break address. - Command switches /2, /A, /B, /C, /D, /E, /F, /H, /K, /L, /N, /O, /P, /R, /T and /Y have no sense in a compiled program. - Only 'Warajevo' and Lunter's version 2.0. snapshot files can be compiled (not Lunter's snapshot files version 3.0.). This is not a problem, because you can load Lunter's snapshot file version 3.0. into 'Warajevo' simulator, and save snapshot again in 'Warajevo' format. 6.1. COMPILING ========= You can start compiler from DOS command line. ZXCOMP without parameters will display short message about compiling syntax. The syntax is: ZXCOMP <z80_file> [<exe_file> [<initial_switches>]] where parameters have meaning: <z80_file> Source snapshot file <exe_file> Target executable file <initial_switches> Command options which will be embedded in compiled program If you omit extension for file <z80_file>, will be assumed 'Z80'. If you omit extension for file <exe_file>, 'EXE' is assumed. If you omit <exe_file>, will be assumed same name as in file <z80_file>. As command options you can use options /!, /I, /J, /M, /S, /U, /V, and /W with same meaning as in simulator. There is one new option /Z which has a following meaning: /Z0 - Keys F4, F5 and F6 will this option). /Z1 - Key F4 will not work in /Z2 - Key F5 will not work in /Z3 - Keys F4 and F5 will not /Z4 - Key F6 will not work in /Z5 - Keys F4 and F6 will not /Z6 - Keys F5 and F6 will not /Z7 - Keys F4, F5 and F6 will work in the compiled program (default if you omit the compiled program, but F5 and F6 will work. the compiled program, but F4 and F6 will work. work in the compiled program, but F6 will work. the compiled program, but F4 and F5 will work. work in the compiled program, but F5 will work. work in the compiled program, but F4 will work. not work in the compiled program. For example, ZXCOMP ATICATAC.Z80 ATICATAC.EXE /JM /JC /! /Z7 /W30 compiles snapshot file ATICATAC.Z80 into executable program ATICATAC.EXE. In the compiled program Kempston joystick will be emulated using mouse, and cursor joystick will be emulated using cursor keys. Warning message will not be displayed if processor is in 'Virtual 8086' mode. Only F1 and F10 function keys will work. Executing will be slowed down by 30 'wait' states. Command option /V acts as in simulator, except suboption /VX which activate extended Hercules mode only if real Hercules card is detected. For example, if you use ZXCOMP MMINER MMINER /VX then will be created executable program MMINER.EXE which on Hercules card works in extended Hercules mode, but it not force Hercules card, e.g. for example this program will normally work on VGA card. When compiling, you can see some data on screen. Field 'Length:' contains length of source file. Field 'Compiling:' shows how many bytes is compiled till now. After compiling, field 'Code:' contains length of the compiled program. It tipically will be about 5-20 Kb longer than a source file for 48K snapshot files and about 10-40 Kb for 128K snapshot files. Not so often, compiled code can be shorter than a source file! We must say that compiled program is totally independent of any file in simulator package, and may be distributed without simulator. Compiled program may be started with command options /I, /J, /S, /V and /W. This option will have stronger effect than options which are embedded in the compiled program. For example, ATICATAC /JA /W0 will start earlier compiled program ATICATAC, Kempston joystick will be emulated using PC analogue joystick, and program will run on full speed (without 'wait' states). Similary, MMINER /VH will start MMINER.EXE in a normal Hercules mode. 6.2. SUPPORTING OF SAVING AND LOADING BLOCKS ======================================= Compiled program does not support emulation of tape system. However, we want to enable possibility of status saving and loading from games which have this options (for example, all adventure games), and possibility of compiling games which load levels from tape. So, we implemented two new instructions, for saving and loading blocks directly from disc. You must put this instructions in program (using our internal monitor) at appropriate places before you save snapshot file. This instructions have a following form: DB #ED,#FE,'<filename>',0 DB #ED,#FF,'<filename>',0 Saves a block from address in register IX with length in register DE on disk with filename <filename>. Loads a block from disk with filename <filename> at address in register IX, with length in register DE. All registers will be unchanged. Flag C will be set if loading was correct. In both cases error will cause warning sound. Here we will give two examples. If the game saves or loads status in only one block, using standard routines at address 1218 and 1366 (or some near addresses), you must replace CALL 1218 and CALL 1366 with CALL SAVE and CALL LOAD, and put these routines at some free space in memory: SAVE DB #ED,#FE DB 'STATUS.DAT',0 RET LOAD DB DB #ED,#FF 'STATUS.DAT',0 RET We can not say any special if game don't use ROM routines for loading and saving. If game saves status in more than one block, or with header, situation is a bit complex, but if you understand this example, this will not be a great problem for you. If the game loads levels from tape, you must extract levels using ZXTOOLS in separate files named for example LEVEL1.OVL, LEVEL2.OVL, etc. For example, suppose that we have a game which loads levels using a subroutine at address 40000, that register A before calling contains level number, and that levels starts at address 49152 with length 16384. Then you must replace CALL 50000 with CALL LLEVEL, and put following subroutine somewhere: LLEVEL LD LD ADD LD DB LNAME DB RET IX,49152 DE,16384 A,'0' (LNAME+5),A #ED,#FF 'LEVEL0.OVL',0 Similary, you can solve many harder cases too, of course, if you have elementary knowledge about machine code programing and load routines. Except these two instructions, we also support two instructions with codes #ED #FC and #ED #FD which save and load block described by IX and DE registers too, but they not have block filename as inline parameter. Instead, filename will be automatically created depending of IX and DE values (more precisely, filename will represent hexadecimal values of IX and DE registers). Extension will always be '.DAT'. This may be practical if you have not enough space to insert appropriate subroutines for saving and loading. For example, you may replace instruction CALL 1218 with DB #ED,#FC and one NOP insctuction (to fills one-byte free space). 6.3. AUTOMATIZATION OF SAVE & LOAD SUPPORTING ======================================== Support which is described in the section 6.2. has a great power, but it is so hard for unexperienced users. So, we implemented option /TAPE in ZXCOMP program which in many cases can automatically solve problem of game status saving and loading. If game saves and loads status in only one block using ROM subroutines, compiling with /TAPE option tries to automatically accomplish inserting which is described in previous section. Block will have same name as the name of EXE program, with extension '.DAT'. For example, ZXCOMP KTYME KTYME /TAPE compiles snapshot file KTYME.Z80 (game 'Knight time') into a executable program with name KTYME.EXE which can save and load status into a block with name KTYME.DAT. If you are not happy with this convention of names, you may use expanded form of /TAPE option in format /TAPE:<filename>. For example, ZXCOMP KTYME KTYME /TAPE:POSITION.STS /JM does some thing as a previous example but the block will have name POSITION.STS (and with Kempston joystick emulation using mouse). If you omit extension in name <filename>, '.DAT' will be assumed. In the case when game saves (loads) status in more than one block, you can try option /TAPE!. This option acts as replacing calls to save and load routines with #ED #FC and #ED #FD instructions. So, blocks which will be saved will have unusual names, but very often this will work correctly. For example, the game 'Hobbit' saves status into four blocks. If you compile this program with: ZXCOMP HOBBIT HOBBIT /TAPE! compiled program will save (load) status into (from) four files with filenames B5DC001C.DAT, C00B0614.DAT, C97300BF.DAT and B97A05D9.DAT. Of course, this names are not beautiful, nor descriptive, but this is price of automatization. Option /TAPE supports automatization in many cases, but surely it can not be all-powerful. The best is to try it. If compiled program using this option correctly saves (loads) status, it is good. Else, if compiled program don't work correctly, you must do manual modifications. Of course, if you know to do it. For loading levels from tape, automatization is usually not possible, because levels loading is in different programs implemented on quite different ways. 7. TECHNICAL INFORMATIONS ====================== 7.1. Z80 PROCESSOR SIMULATION ======================== We simulated the Z80 processor very well. All standard instructions and registers are simulated. There are even some instructions which are not listed in official Z80 manuals, which behavior as on original machine. Our internal monitor will disasemble these instructions: The instruction NOPD is like instruction NOP, but it is two bytes long, and changes R register differently. The instruction 'IN F,(C)' reads a value from a port at the address shown with register pair BC, throws away the result, but updates flags. There is yet another new I/O instruction: 'OUT (C),0'. Many instructions have more than one code, for example: IM 0, IM 1, IM 2, NEG, RETI, RETN. For example, NEG have eight different codes. Instructions with codes #FC, #FD, #FE and #FF after #ED prefix have no effect in the simulator (NOPD), but they have special meaning in ZXCOMP program (see section 6.2.). There is instruction SLL that shifts one to the zero bit of argument. All bits are shifted to the left. The most significant bit is shifted to C flag. If you have the prefix #DD before an instruction which works with register H or register L, this instruction will work with a higher or lower byte of IX. Similarly, if the prefix byte is #FD, it will work with a higher or lower byte of IY. These instructions have the mnemonic like LD XH,5. If you have the prefix #DD (or #FD) before an instruction which not affect registers H or L, this prefix will be ignored. Monitor will display this as NOP IX and NOP IY. There are also new instructions with a double prefix. We called them like RRP (IX+nn),r etc. These instructions rotate or shift the indexed argument and then put a result in register, which is second argument. For example: RRP (IX+5),B will do: RR (IX+5) LD B,(IX+5) Similary, we have RLP, RRCP, RLCP, SLAP, SLLP, SRAP and SRLP. We have also the instructions like this: SETP n,(IX+nn),r For example: SETP 5,(IY+6),H will do: SET 5,(IY+6) LD H,(IY+6) We have RESP too, but instructions BITP do not exist, so instructions BIT with indexed arguments in fact have eight different codes. While we emulated some instructions, we had to implement some specific behavior for internal use into simulator if this instructions are on specific address. Specific instructions and addresses are listed in this table (this is mainly transparent for the user): Address 8 602 1974 4692 1232 1388 1792 5867 xxxx Instruction With option Purpose LD HL,(nn) #ED #01 #ED #01 #ED #01 EX AF,AF' CALL nnnn RET INC HL RST 0 Switch to Interface 1 ROM Simulate pressing of ENTER key (128) Restore changed ROM after header Put LOAD "" in the editor buffer (48) Fast save block Fast load block Return to standard ROM Switch to Interface 1 ROM Jump to monitor if it is a break point /E (Startup) /A (Startup) /A (Startup) /A (Startup) FAST,AUTO (Tape) FAST,AUTO (Tape) /E (Startup) /E (Startup) Bxxxx (Monitor) With option /B, RST 24 and RST 32 instructions, and RST in Derby ROM (128 version only) are executed in one step. This for about 10% (in 128 BASIC sometimes even 50%) but R register correctly changed by this instructions. However, R register is unimportant in BASIC programs. 40 instructions accelerates BASIC will not be really totally R register is incremented after every instruction by number of bytes before first argument. When simulator detects LD R,A instruction, after this the simulator will emulate R register correctly. The emulation is interrupted if passed 10 seconds from the last use of R register (that is reason why some programs become slightly faster after some seconds, very often you can see this in intro melodies in some games). After this, R register acts as random number generator. Also, emulation of R register is activated in following cases: - When you enter or leave the monitor; - When you change tape simulation mode; - When simulator detects part of LD_EDGE routine, or when 'kills' LD_EDGE routine (see part 7.12. of the manual). Of course, emulation is interrupted after 10 seconds too, except when you are in monitor. Instruction LDIR works completely, even in case of self-modification. The simulator checks for a possibility of self-modification, and works as fast as possible. The flags are updated correctly except: - bits 3 and 5 of flag register (except in POP AF and EX AF,AF' instructions); - flags displayed in Z80 manuals as 'unknown' (like S flag after BIT). This may cause problems with some ill-based programs. Unlike the original machine IM 2 will not make problems with the Kempston joystick. Register I may show anywhere, without problems. Nonmascable (NMI) interrupt is implemented only for users who want to replace ZX48.ROM with his own, so key F8 is mostly unuseful. 7.2. THE ROMS AND RAMS ================= The ROMs are not changed. The user could change PCTOOLS) but if you make changes on addresses shown on paragraph, some things (like Interface 1 paging, etc.) to ROM is ignored, but these things change the contest - them (for example by table of the previous will not work. Any POKE of ROMs: Option /K (an inverse cursor) changes value at address 6355 from 0 to 12. Option /H (hide border during LOAD) puts two NOP-s at address 1372. The break point may be in ROM. The option /A on 48 version of simulator does following: It puts auto-run escape code #ED #01 at addresses 1974 and 4692. The initial attribute is changed from 56 to 7 or to value set by option /Y (at address 4710). The escape code at address 4692 stuffs LOAD "" and ENTER in the editor's buffer. Address 4769 is changed to 11 for skiping call of SET_MIN routine (see ROM disassembly). The beginning of PRINT_OUT routine (address 16) is changed to RET (to forbid 'Program: ...' message on screen). The simulator begins working at address 4591 (label RAM_DONE), not at 0. Finnaly, after loading of the first header, the escape code #ED #01 at address 1974 restores all changes in ROM. - The option /A on 128 version of simulator does following: It puts auto-run escape code #ED #01 at addresses 1974 in standard ROM and 602 in Derby ROM. The initial attribute is changed from 56 to 7 or to value set by option /Y (at address 520 in Derby ROM), and initial BORDER is set accordingly (at address 535 in Derby ROM). The escape code at address 602 simulates pressing of ENTER key by putting 13 in LAST_KEY variable and by setting bit 5 in FLAGS variable. The beginning of PRINT_OUT routine (address 16 in both ROMs) is changed to RET (to forbid 'Program: ...' message on screen). Similar thing is done in PLOT subroutine (RET at address 8937 in standard ROM), to suppress menu drawing. If some of addresses 14307, 14345, 14437 or 14470 in Derby ROM contains instructions LD (HL),A and INC HL, instruction LD (HL),A will be changed to NOP. This modification suppress some minor modification of screen (testing for this instructions is done because ordinary Spectrum 128 and +2 have different ROMs, and those instructions are not on same addresses). The simulator begins working at address 0 in Derby ROM (as usual). Finnaly, after loading of the first header, the escape code #ED #01 at address 1974 restores all changes in ROMs. This is quite complicate, but this works fine. RAM is so simple in 48 version of simulator, and we cannot say any special thing about it. But in 128 version of simulator, RAMs paging is important. We fully simulate paging of RAM addresses above 49152 (including special tretman of pages 2 and 5 which are copies of memory blocks 32768-49151 and 16384-32767 respectively) without EMS memory (Lunter's 'Z80' simulator has only partial emulation without EMS)! Unfortunately, this slightly slows down 128 version of simulator. Also, we not support EMS memory. So, RAM paging in simulator is very slow. But, ROM paging is extremly fast (this is not case in Lunter's 'Z80' simulator)! Our simulator (version 128) in '128 Basic' without EMS memory works many times faster than Lunter's simulator (see menu drawing for example, or try to use screen editor)! We use two paralel memory buffers, with identical RAM images, but first buffer contains standard ROM, and second buffer contains Derby ROM. So, ROM paging is implemented by swapping of some segment registers which is extremly fast. Unfortunately, this method slows down RAM paging. However, we detect presence of 80386 processor, and if it is present, we use some 80386 instructions (MOVSD instead of MOVSW) for speed up RAM paging twice. Slow RAM paging may sometimes (but rarely) cause problems on slow machines (if the problematic game has option 'Turn the music off', very often this option will solve problem, for example, in 'Knight time 128'on 10MHz AT). Also, Interface 1 ROM paging is slow too, but this is not a great problem. We have two methods for simulating two video pages on 128 version of simulator. See description of switch /X. 7.3. SIMULATION OF I/O PORTS ======================= 7.3.1. 'ULA' PORTS =========== Every port with address bit A0=0 acts on ULA (usualy 254). We implemented this ports on the following way: Output: bits D0-D2: change BORDER bit D3: tape output bit, not implemented bit D4: toggle speaker for making BEEP Input: bits D0-D4: read keyboard halfrows, relate with bits A8-A15 bits D5,D7: always 1, as on real Spectrum bit D6: tape input bit, toggles continously between 1 and 0 for some programs that requires Issue 2 or Issue 3 Every IN A,(254) instruction is checked for a part of loading routine. This will be explained later. 7.3.2. 'ZX PRINTER' PORTS ================== Every port with address bit A2=0 acts on the printer (usualy 251). We implemented following features: Output: bit D1: bit D2: bit D7: motor speed motor on/off styli on/off Input: bit bits bit bit encoder bit always 1 printer present out of paper D0: D1-D5: D6: D7: Brief description of implementation of the ZX printer emulation: When D2=1 (motor off), writting to this port is ignored. When D2=1, the state of bit D7 sent to this port is buffered. When the buffer fills itself, or when the motor is again off, the buffer is sent to the printer. One pixel on ZX is emulated with a one pixel (or with a square of four pixels if option /P is present) on the Epson printer. If D1=0 (motor fast), the buffer takes four rows of pixels. When D1=1, buffer takes only one row of pixels. For input, the bit D0 is connected to READY of the printer, bit D6 to ACK and bit D7 to 'Out of paper' signal. The latching of the bits D0 and D7 is not emulated, but this is not important. All routines for the ZX printer which use standard protocol (reading the encoder bit) will be correctly emulated, including ROM routines. There is a small problem with ROM routines that will wait forever if the printer is switched on, but off-line. Then switch off the printer, or change it to ONLINE. 7.3.3. 'JOYSTICK' PORTS ================ Every port with A5=0 acts to the joystick while reading (usually 31), depending on /J options. This port is read only: Input: bit bit bit bit bit bits D0: D1: D2: D3: D4: D5-D7: joystick moving to right joystick moving to left joystick moving to down joystick moving to right status of joystick fire button always 0, as on real joystick interface The option /JK will read this port from cursor keys and the gray '+' or '~' key. The option /JA will read this port from the analogue joystick. The option /JM will read this port from the mouse. The MOUSE.SYS driver must be installed. If no /J option is present, this port will return 255 always, with meaning 'No joystick interface'. 7.3.4. 'ZX INTERFACE 1' PORTS ====================== Interface 1 ROM paging is implemented, but now we simulate Interface 1 ports (i.e. ports with A3=0 or A4=0, tipically 247, 239 and 231) only for simulating RS232 output through LPT1 port (usually printer). So, reading or writing this ports have only limited effects: PORT 231: --------Output: Ignored (no microdrive) Input: Ignored, e.g. always return 255 (do not cause crash) PORT 239: --------Output: Bit D0 activate/deactivate RS232 output, other bits are ignored Input: Bit D3 is 1 if printer is ready (DTR), else 0. Bit D0 is always zero, and other bits are always one (with meaning 'No microdrive' etc.). PORT 247: --------Output: Acts as on real ZX Interface 1, bit D0 is RS232 output. We simulated RS232 output by buffering eight bits after start bit and sending to LPT1 when whole byte is completed. Other bits are ignored, as at real machine. Input: Always return 30, e.g. no RS232 input (D0) and net input (D7). Bits D1-D4 on real ZX Interface 1 is always one, and bits D5 and D6 have random values, which is always 0 in our simulator. 7.3.5. 'ZX SPECTRUM 128' PORTS ======================= Every port with A1=0 acts to the Spectrum 128 peripherals (AY sound chip, memory management, RS232, KEYPAD and MIDI ports). True meaning of this ports depend of other address bits. Every port with A1=0 and A15=0 (usualy 32765) acts to memory management unit. This port is write only: Output: bits bit bit bit D0-D2: D3: D4: D5: select RAM bank at addresses above 49152 select active video page (0 = normal, 1 = alternative) select active ROM (0 = Derby, 1 = Standard) 48K lock bit (1 = MMU is locked) Due to hardware bug, reading this port is same as writing 255 at this port, so IN 32765 will cause crash, as a real Spectrum 128. Every port with A1=0 and A15=1 acts to AY sound chip (and RS232, KEYPAD and MIDI who works through register R14 of sound chip). When A14=1 (usualy port 65533) writing to this port selects active sound chip register, and reading from this port returns value of active sound chip register. When A14=0 (usualy 49149) writing to this port stores value in active sound chip register, and reading from this port will always return 255. Some of the sound chip registers have length smaller than 8 bits (extra bits is always zero). This is brief table of sound chip registers: Register Length Description R0 R1 R2 R3 R4 R5 R6 R7 8 4 8 4 8 4 6 7 R8 R9 R10 R11 R12 R13 5 5 5 8 8 4 R14 8 Fine control of channel A frequency Coarse control of channel A frequency Fine control of channel B frequency Coarse control of channel B frequency Fine control of channel B frequency Coarse control of channel B frequency Noise pseudofrequency (not implemented) Mixer control: D0 - if D0=0, channel A produce tone D1 - if D1=0, channel B produce tone D2 - if D2=0, channel C produce tone D3 - if D3=0, channel A produce noise (not implemented) D4 - if D4=0, channel B produce noise (not implemented) D5 - if D5=0, channel C produce noise (not implemented) D6 - if D6=0, register R14 is input port, else output port Channel A volume, if D4=1 use envelope generator Channel B volume, if D4=1 use envelope generator Channel C volume, if D4=1 use envelope generator Fine control of envelope period Coarse control of envelope period Envelope control register D0 - HOLD bit D1 - ALTERNATE bit D2 - ATTACK bit D3 - CONTINUE bit Controls RS232, KEYPAD and MIDI (see text below) When you try to select register above R14, this attempt is ignored. When register R14 acts as output port (bit D6=1 in register R7), bits in register R14 have following meanings: Output: bit bit bit bit bits D0: D1,D4: D2: D3: D5-D7: KEYPAD clock (see KEYPAD simulation) have no meaning CTS and MIDI output signal (not implemented) RS232 output bit (implemented as in ZX Interface 1) masks for reading bits D5-D7 (see text below) Input: bits bit bit bit D0-D4: D5: D6: D7: last values sent to these bits KEYPAD response bit DTR bit (i.e. printer is ready) RS232 input bit (not implemented, always one) The bits D5-D7 when reading return valid values only if they are not masked, i.e. if corespodent mask bits is one, else they will return zeroes. When register R14 acts as input port (bit D6=0 in register R7, Spectrum 128 softwares never make this setting), bits in register R14 have following meaning: Output: Ignored! Input: bits bit bit bit D0-D4: D5: D6: D7: always one KEYPAD response bit DTR bit (i.e. printer is ready) RS232 input bit (not implemented, always one) In this case, bits D5-D7 could not be masked. 7.3.6. 'BUS IDLE' PORT =============== Every port which does not affect any peripheral device, for example port who has all bits from A0 to A7 identical to 1 (for example 255) is a 'bus idle' port. This port keeps the current value that ULA reads from the screen memory and sends it to the video device. We emulated this effect, so programs who use this port will work, but unfortunately this emulation have no any influence to the video synchronization. 7.4. VIDEO MEMORY SIMULATION ======================= BORDER on Hercules, CGA and EGA Mono is realized as a thick frame around the displayed picture. On VGA and EGA, it is realized using palette changing, and with overscan hardware border. Attributes on CGA, Hercules and EGA Mono are emulated with shading. VGA and EGA use a special mode. It is text mode with one (or two at EGA) pixel height of chars redefined to look like high resolution graphic. This simulator updates video memory every time when changing its value, but this may cause flickering in some programs. FLASH exists on all cards, except CGA. This is because we realized FLASH by changing the graphic pages. CGA has only one. We implemented BRIGHT only on EGA and VGA. 128 alternative video page is simulated on two different ways, see /X switch. 7.5. BEEPER AND AY CHIP SIMULATION ============================= The Spectrum beeper sound looks ordinary very well and clear. However, there are problems with quality of the sound in a program 'Wham the music box' and in programs who have 'Wham-type' sound routines, but many other polyphony tones sounds very well, for example in 'Four soccer simulator', 'Vectron' and 'Top gun'. 128 version of simulator simulates AY sound through PC beeper by using interlace of sound channels. Every channel have 20 ms, then simulator gives a chance to next active channel. So, if it is only one active channel, sound is totally clear, else you can hear interlacing. Very often, this sounds quite good, usually better than in Lunter's 'Z80' simulator, and if sound is bad, you may use /S option. Simulator treate as active channel every channel who has volume greater than 7 (including envelope effects), and who has corespodent bit in register R7 with value 0. Beeper will still work during AY is simulated, because AY is simulated using PC timer chip, and beeper is simulated using the toggle bit of PC speaker, so AY and beeper sound are ANDed. Envelope generator is simulated too, using timer interrupt. However, there are still one little harmless bug in envelope generator which is not yet located. 7.6. KEYBOARD AND KEYPAD SIMULATION ============================== Keyboard simulation is simple: simulator installs new driver for keyboard interrupt, which keeps keyboard state in similar way as real Spectrum. Later, when program reads keyboard ports, simulator reads this state, so keyboard reading is smooth and extremly fast. However, 'matrix' effect is not simulated, so CAPS SHIFT + SYMBOL SHIFT + Z will not generate BREAK. We think that this is really not very important. KEYPAD (at Spectrum 128) is a quite complex device, but it is not obvious at a first look (this is a reason why it was so expensive). KEYPAD controler is a (hardware) finite automat with timeout, which change state on every transient of a KEYPAD clock pulse. It is implemented on simulator as a software finite automat. KEYPAD controler communicate with Spectrum 128 by using very unusual serial protocol. When we first time connect KEYPAD on Spectrum, KEYPAD controler goes through following sequence of states (this is initial test sequence, states is grouped in groups of four states for more readability): 1011 0111 0111 0111 0111 After this, KEYPAD controler enters a working loop. It scans rows of KEYPAD. If we number rows from 1 to 5 (1 is a top row), controler scans rows in following order: 5, 4, 1, 2, 3. If controler detects that keys positions (non-press or press) in current row is not changed since last scanning, controler goes through following sequence of states: 0011 Otherwise (if some key in current row changes its position), controler goes through following sequence of states: 0111 0A11 0B11 0C11 0D11 Letters A, B, C, D have meaning 'state of first, second etc. key in current row' (1 = pressed, 0 = released). After first row, KEYPAD controler scans next row, and so on. If clock pulse is set for a long time, KEYPAD controler will go out of working loop, e.g. it will reset, and next time, respond with initial test sequence. As you see, KEYPAD protocol is very complex, and ROM routine who reads KEYPAD is long (and slow, that is reason why KEYPAD simulation slows down BASIC programs). The system variables ROW01, ROW23 and ROW45 (addresses 23432, 23433 and 23434) keeps bit images of KEYPAD keys, and ROM routine decode this bits differently, depending of active mode ('128 Basic' or 'Calculator'), more precisely, depending of bit 0 in system variable FLAGS3 (address 23398). INKEY$ function in BASIC will read KEYPAD and for KEYPAD keys it will return codes as with ordinary number keys (except if you give command POKE 23398,0 within BASIC program). Variable ROW01 contains some flags for KEYPAD reading too: D7=0 & D6=0 => ROM routine waits for reset of KEYPAD controler and responding with initial sequence (during this, bit b0=1 means waiting for reset, and then ROW23 acts as waiting counter); D7=1 & D6=0 => ROM routine detects that something is wrong with KEYPAD and stops any following scanning; D7=1 & D6=1 => KEYPAD controler is into working loop. So, if you execute POKE 23432,128 from BASIC, ROM routine will not scan KEYPAD, and this will speed up BASIC program (even when KEYPAD simulation is active). On a real Spectrum 128, when KEYPAD is not connect, bit D5 in register R14 will be 1. However, in simulator, this bit is 0 when KEYPAD simulation is not active. This is done because with this bit as zero ROM routine who scan KEYPAD will fail (and exit with NOTDONE status) earlier, and this trick slightly speeds up interrupt routine when KEYPAD simulation is not active). 7.7. FORMATS OF FILES ================ 7.7.1. TAPE FILES ============ Tape files (TAP) has the format as follows: At the beginning of the file there is four bytes with the pointer to the first block. Then follows four bytes with pointer to the last block. The next four bytes contains #FFFFFFFF. So, empty tape have a format: #04 #00 #00 #00 #00 #00 #00 #00 #FF #FF #FF #FF Sequence #00 #00 #00 #00 #FF #FF #FF #FF is, in fact, a EOF (end-of-file) marker. Every block contains following: - 4 bytes, a pointer to the previous block, which is 0 for first block; 4 bytes, a pointer to the next block or to the EOF marker for last block; 2 bytes, block size; 1 byte, a flag byte; the data bytes. If the block size is 65535, it is a compressed block. It looks like: - 4 bytes, a pointer to the previous block; 4 bytes, pointer to next block; 2 bytes, 65535; 1 byte, a flag byte; 2 bytes, decompressed size; 2 bytes, compressed size; 2 bytes, signature length (internal); the data bytes. Signatures are important for the imploding algorithm used in the 'Warajevo' simulator. This algorithm, when decompressing, copies bytes from the source file, or returns for a few bytes, and copies some bytes from a destination file. Details of the imploding algorithm are too complex for this manual. 7.7.2. SNAPSHOT FILES ============== This format is compatible with the format of the simulator 'Z80' written by Gerton Lunter. While loading simulator keeps compatibility with versions up to 3.02. (including), but our simulator saves snapshot files as version 2.0. This format is as follows: Byte Length Description 0 1 2 4 6 1 1 2 2 2 8 10 11 12 2 1 1 1 13 15 17 19 21 22 23 25 27 28 29 30 32 34 2 2 2 2 1 1 2 2 1 1 1 2 2 1 35 36 37 1 1 1 38 39 1 16 A register F register BC register pair (LSB, i.e. C, first) HL register pair Always 0 (simulator create snapshoot files like version 2.0 of Lunter's 'Z80' simulator) Stack pointer (SP) Interrupt register (I) Refresh register (Bit 7 is not significant!) Bit D0: bit 7 of the R-register Bits D1-D3: BORDER colour Bit D4: always 0 Bit D5: always 1 (e.g. blocks are always compressed) Bits D6-D7: not used DE register pair BC' register pair DE' register pair HL' register pair A' register F' register IY register (Again LSB first) IX register Interrupt flip-flop IFF1 (0 = DI, otherwise EI) IFF2 (not particularly important...) Interrupt mode (0, 1 or 2) Length of additional header block (contains 23) Program counter (PC) Hardware mode: 0 = Spectrum 48K, 1 = Spectrum 48K with Interface 1, 3 = Spectrum 128K, 4 = Spectrum 128K with Interface 1. In version 128, contains last OUT to 32765 Contains 255 if Interface 1 ROM paged in Some flags Bit D0: 1 if R register emulation on Bit D1: Always 1 (e.g. always full LDIR emulation) Last OUT to 65533 (AY register number, 128 version) Contents of the AY chip registers (128 version) Hereafter a number of memory blocks follow, each containing the compressed data of a 16K block. The structure of a memory block is: Byte Length Description 0 2 3 2 1 ? Length of data (without this 3-byte header) Page number of block Compressed data The pages are numbered, depending on the hardware mode, in the following way: Page: 0 1 2 3 4 5 6 7 8 9 10 In 48 version: In 128 version: Standard 48 ROM Interface 1 shadow ROM RAM, 32768-49151 RAM, 49152-65535 RAM, 16384-32767 - Standard 128 ROM Interface 1 shadow ROM Derby 128 ROM RAM, page 0 (49152-65535) RAM, page 1 (49152-65535) RAM, page 2 (49152-65535 or 32768-49151) RAM, page 3 (49152-65535) RAM, page 4 (49152-65535) RAM, page 5 (49152-65535 or 16384-32767) RAM, page 6 (49152-65535) RAM, page 7 (49152-65535) In 48 version, pages 4, 5 and 8 are saved. In 128 version, all pages from 3 to 10 are saved. Pages will be saved in numerical order. The compression method is very simple: it replaces repetitions of at least five equal bytes by a 4-byte code #ED #ED #xx #yy, which stands for 'byte #yy repeated #xx times'. Only sequences of length at least 5 are coded. The only exception is sequences consisting of #ED's; if they are encountered, even two #ED's are encoded into #ED #ED #02 #ED. Finally, every byte directly following a single #ED is not taken into a block, for example #ED #00 #00 #00 #00 #00 #00 is not encoded into #ED #ED #ED #06 #00 but into #ED #00 #ED #ED #05 #00. Important: because we want to be compatibile with Lunter's snapshot format, we do not put in snapshot file some things that are important for 'edge recognizer', ZX Printer simulation, and RS232 simulation. So if you create snapshot file (by pressing F7 key) during loading program with unusual loading routine, or during writing on ZX Printer, when you load snapshot file back into simulator, program will not be continued correctly in all cases. 7.7.3. DATABASE FILES ============== We use the classic database DBF format. Here will be explained the meaning of the fields. These fields maybe have strange names, because names are acronyms or words in Bosnian language. File: SOFTWARE.DBF -----------------Field Name Description DODATNI GODISTE KOMPJUTER MATERJEZIK OPIS POZICIJA PRIORITET PROBLEMI PROIZVODJ PUNOIME SIMULOPC SKRACENO TRAKA VRSTA For future expansion Year of production Computer type Messages language Description (descriptor) Block position in the tape Marking sign Problems (coded) Producer Full name of the program Startup options Short name Tape name Category of the program Type Width Dcp AN AN AN AN MO NU AN NU AN AN AN AN AN AN 10 4 4 4 10 3 1 5 4 30 50 10 10 4 0 0 Record length: 149 File: ADDITION.DBF -----------------Field Name Description REDPODAT See below Type Width Dcp AN 60 The first letter of REDPODAT is P, V, J or T, for producer, category, language or tape. If it is P, V or J then follows four letters for a code and then 55 letters for the corresponding name. 7.8. INTERRUPT CONGESTION ==================== Some programs crash if started on a slower machine. This is due to very long interrupt routine who deals with a lot of video data in them, or switchs RAM banks intensively. The long interrupt routines can block the main program because it has very few time for execution. The worst case is when long interrupt routine does not disable interrupts, and in this case unexpected nesting of interrupts may cause crash. When you use command /I, the number of interrupts per one second will be smaller (instead 50), see description of option /I. Many programs that crashes without this option at slow machines, works with it. Rarely, as in 'Repton', even this is not enough, and helps only starting on a faster machine. 7.9. 'WRAPPING' PROBLEM ================== Processors I80286 and better ones generate INT 0DH when reading word from the address 65535. We wrote the handler for this interrupt routine. However, QEMM, EMM386, Windows etc. have also the same handler, which has a bigger priority than our handler if processor is 80386 (or better), because these programs turns processor in so-called 'Virtual 8086 mode' and so simulator has no full control of situation. The effect is conflict with these programs, and a possibility of crashing some Spectrum programs, which else should not crash. So, be very careful if you use the simulator with these programs. Simulator will display warning message if processor is in 'virtual' mode. See description of option /!. 7.10. COMMUNICATION PROTOCOLES ======================== This is communication procedure for sending to Spectrum in pseudo Pascal which is used in ZXTOOLS (if you want to write own communication program on Spectrum, e.g. on Spectrum 48K). Surely, corespodent program on Spectrum is complementary: procedure SendToSpectrum(Addr,Size:word; Flag:byte); begin Modem_DTR(0); Bytes:=Size+3; Send(Lo(Bytes)); Send(255-Lo(Bytes)); Send(Hi(Bytes)); Send(255-Hi(Bytes)); Send(Flag); Send(255-Flag); Parity:=Flag; for j:=0 to Size-1 do begin Byte:=GetFromMemory(Address); inc(Address); Parity:=Parity xor Byte; Send(Byte) end; Send(Parity) end; {Send the size with complement} {Send the flagbyte with complement} {Do like classic save routine} This is communication procedure for receiveing from Spectrum in pseudo Pascal which is used in ZXTOOLS (different protocol is used from some practical reasons): procedure ReceiveFromSpectrum(Address:word; var Size:word; var Flag:byte); begin Modem_DTR(1); repeat Receive(Byte1); {Read signature bytes} Receive(Byte2); Receive(Byte3); Receive(Byte4); Receive(Byte5); Receive(Byte6); if (Byte1+Byte2=255) and (Byte3+Byte4=255) and (Byte5+Byte6=255) then SignsOK:=true else begin SignsOK:=false; AbortTransfer end until SignsOK; Counter:=Byte1+256*Byte3; Size:=Counter-3; Flag:=Byte5; Address:=0; repeat CheckSum:=0; repeat Receive(Byte); PutIntoMemory(Address,Byte); CheckSum:=CheckSum+Byte; Inc(Address); Dec(Counter) until Lo(Counter)=0; Receive(Byte); {Checksum is sent every 256 bytes} if Byte=CheckSum then DisplayOK else begin Modem_DTR(0); AbortTransfer end until Counter=0; Modem_DTR(0) end; The communication program is 6000 bytes long Z80 binary file. It should be also different size (if you wrote own communication program), but in that case transfering instructions for users will not be fully correct. 7.11. INFORMATIONS FOR WINDOWS USERS ============================== This because our Windows can if you want simulator was not specially designed to be used with Windows, machines are too weak to use this operating system. However, start DOS applications using PIF files. Here are the informations to create PIF files for your Windows system: The applications SPEC48.EXE and SPEC128.EXE work in text or graphic mode. On 286 (recommended also for 386 or 486) prepare options for them that they can not be in multitasking mode, directly modify keyboard, must be in full screen mode and you must prevent program switch. The required memory is about 550K or more. These programs are very dirty written, to be fastest as possible. There is no much sense to start them from Windows, except, of course, if you have WIN command in AUTOEXEC.BAT. After we published version 1.1, we've found some stronger machines and checked behavior of the simulator under Windows. We did not expected it, but on some 386 and 486 machines these programs however can work under Windows 3.11, in window and paralelly with other applications (of course not apsolutely clear, there are some messages written after finishing the job and sometimes some keys locks up). However, there is a limit that (on VGA card) the simulator must be started with option /vc to initialize CGA graphic mode. The picture is not in color, it is not painted smoothly, sound is not clean, the system is relatively slow - but it works! The Hercules, EGA and VGA mode Windows does not emulate, while EGAMONO mode is too slow that there is sence to use it only for cutting of any already prepared picture, because painting of one picture on 40 MHz 486 machine will require few minutes. From same reason, if you have 386 with Hercules, do not think about executing of Spectrum programs in window. We have informations from users that Warajevo works better under OS/2 than other Spectrum emulators, but some users remarked problems with Windows 95. Due to machines we have access to, we were not able to check it. ZXTOOLS, ZXSHELL and ZXCOMP can be in window and in multitasking mode. Ensure for them about 500K of memory or more. ZXSHELL uses also EMS memory if exists. ZXTOOLS can directly modify one COM port, if you used 'Communication' options. For these programs, the main sence of starting them under Windows is to do something else (read: to play Solitaire) while trasfering programs, compressing tapes, sorting the database or compiling snaphot file. If you want to start any program from ZXSHELL, the trick we used (stuffing the keys to buffer) will not work under Windows. For this purpose you must make BATCH file like this: DEL SPECSIM.CFG >NUL ZXSHELL %1 IF EXIST SPECSIM.CFG SPEC48 /C but unfortynately this method can not automatically select SPEC48 or SPEC128 (or eventually ZXTOOLS). However, very often this is just that you wish. If you want to include icon for Windows, it is in a file WARAJEVO.ICO. 7.12. EDGE RECOGNIZER =============== If you are not familiar with LOAD routines, skip this and next chapter. The most of load routines have the LD_EDGE routines. In the AUTO or SLOW tape mode, when executing IN A,(254) instruction, simulator checks its arounds and contents of the stack, and if all looks like this: . . . LD_EDGE_2 CALL RET LD_EDGE_1 . . . . IN RRA RET XOR AND . . . LD_EDGE_1 NC A,(254) NC C 32 ; This instruction may be omited or changed! this will be recognized as a part of LD_EDGE routine. Then the program will: - Load next block from tape file to memory buffer. - Set the trap on the first instruction (at LD_EDGE_1) to return the values of registers as in ordinary LD_EDGE routine, reading bit by bit the values from memory buffer. This includes simulating of leader tone (with 260 pulses) and sync pulse. Returned register values are choosen very inteligently (B register is unchanged after zero pulse, and it is set on 255 after one pulse), so these will satisfied loaders at any speed! If you are familiar with LD_BYTES, you can understand this. - After the program was completly read from the memory buffer, the first instruction of LD_EDGE_1 will be restored. The simulator does same thing if passed one second after last access to tape. Of course, this was only a very brief description of complex recognizer algorythm. We tested about 100 loaders. We had problems with some self modified loaders, loaders who have more than one LD_EDGE routine, and surely, with absolutely nonstandard loaders. It is recommended, if load routine is visible, to change its first bytes, usualy like: INC D EX AF,AF' DEC D DI to JP 1366 for faster loading, but this will not work always. 8. PROTECTED PROGRAMS ================== There is a great problem if the communication program can not load the game that you want to transfer, because it has speedlock. The easiest solution is to buy Multiface 128. However, if you have not it, you must to crack the protection. This is not so hard as on original ZX Spectrum, because we have internal monitor and some tools which are not avaliable on original machine. Sometimes, usage of 'Turbo copy' program is sufficient. For cracking you must use both simulator and original machine. Here are three useful examples. 8.1. EXAMPLES OF TRANSFERING PROTECTED PROGRAMS ========================================== 8.1.1. EASY CASE: 'CRAZY CARS 2' ========================= Simply use 'Turbo copy' on original ZX Spectrum ('Turbo copy' will be descripted in the next chapter). Try different speed, from higher to lower until you load the block correctly. This will be at 3000 Bd. Then save it at 1500 Bd. Now use the communication program. Our edge recognizer will accept this kind of speedlock without any problems! 8.1.2. MEDIUM CASE: 'MICROPROSE SOCCER' ================================ Program 'Microprose soccer' has a block which is too big for normal transfer using 'Turbo copy' program. You may try option M in 'Turbo copy', and it can solve problem, but on this way it is difficult to determine proper loading speed. We will explain how to transfer this program without 'Turbo copy' as a example what to do if 'Turbo copy' cannot be used. SPECTRUM: Transfer the BASIC and loader to PC. PC: Switch tape mode to FAST. The loader is encrypted. Simply start it until BORDER begins flashing. Now the loader is decrypted. Enter the monitor. Save decrypted loader. Transfer it to Spectrum. SPECTRUM: On address 65292 there is a program LD LD LD SCF CALL JP LOADER INC EX IX,16384 DE,43264 A,255 65308 24861 D AF,AF' ; LOADER Then follows classic loader except that it every byte rotates as a mirror. Now write the program: LOOP ORG LD LD LD SCF CALL LD IN RRA JR LD LD LD SCF JP 65000 IX,16384 DE,43264 A,255 65308 A,#7F A,(254) ; This loads the program, waits for ENTER and saves ; program using normal speed. C,LOOP IX,16384 DE,43264 A,255 1218 After saving, load communication program and send the just saved block to PC. PC: Finnaly, make the following loader and put it before just saved block: Our edge recognizer will accept transfered block, but previous loading causes bytes mirroring, and original loader will not load such a block correctly. So, make the following loader and put it before just saved block: ORG 65292 LD LD LD SCF CALL JP IX,16384 DE,43264 A,255 1366 24861 This loader is necessary. Our 'edge recognizer' will accept transfered block, but previous loading causes bytes mirroring, and saving was without mirroring. So, original loader will not load such a block correctly. If you, however, transfered block using 'Turbo copy', original loader should not be changed. 8.1.3. (VERY) HARD CASE: 'ROBOCOP' =========================== ROBOCOP has too many complex features, totaly strange load routine, very complex encryption method, etc. Cracking on original ZX Spectrum is quite hard, nearly impossible, because the speedlock loader is encrypted many hundred times with refresh register etc. but using our simulator it is not so great problem: SPECTRUM: Transfer the ugly BASIC loader to PC. PC: Switch tape to FAST mode. Start the BASIC and wait for about half minute. When border starts flashing, the loader is decrypted and ready! Simple, isn't it? Descrypting was the greatest problem on original machine. But there are still many problems. Now enter the monitor. The loader is at 64454. Save the loader (other part of memory are clean). Send modified loader to Spectrum. SPECTRUM: At the end of the loader, there is a sequence: LOOP NEXT LD LD LD LD INC DJNZ DEC JR LD LD CALL ... SP,65535 HL,16384 BC,27 (HL),0 HL LOOP C NZ,LOOP IX,NEXT DE,232 65089 ; Well, the next, very short block is loaded just ; after this, so after CALL will be continued ; this short block! ; Loads block So, we must save this short block (more precisely, next part of the loader, using standard speed. At address 40000 you can write: LOOP LD LD LD CALL LD IN RRA JR LD LD LD JP SP,65535 IX,65257 DE,232 65089 A,127 A,(254) C,LOOP IX,64454 DE,1200 A,255 1218 ; Loads block ; Waits for ENTER ; Save whole loader This saved the loader of the main block. Now, analyse the new loader. Look how vicious are in OCEAN: The call of loading of the main block is at address 65257 and looks like this: XOR LD LD LD LD LD CALL A (33535),A IX,16384 DE,6143 HL,64948 (64946),HL 64759 ; ; ; ; ; ; ; On the first view it looks like loading of the screen, but load routine is self modificated. It will load many parts of memory. After loading the picture, this routine will load the part of memory from about 24000 to 47000. The arround of loader will be third time changed. So, we must not put the saving instruction after CALL. What to do? Look at the load routine itself. It is totaly unstandard and finishs at address 65219 with: POP XOR OUT LD CP RET DE A (254),A A,H 1 C You must replace this with: POP DE JP 23296 In printer buffer (fortunately, it is empty) we could put the routine which saves all the memory, but we preffered return to BASIC to continue the analyse. So at 23296 put this: LD LD HL,23999 (23730),HL JP 4545 This will change RAMTOP and execute NEW command after loading. ROBOCOP do not use printer buffer or checks the picture, so this will not make any problems. Now, we are in BASIC. Look the memory, there is a gap between addresses 47000 and 64000. We could save with normal SAVE command the space between 24000 and 47000 and between 64000 and 65535. Send these blocks to PC. PC: Enter the monitor. After loading program continues from 65277. There is now: LD OR CALL LD IM LD EXX LD OUT LD LD LD LD LD DI LD LD LD LD LDIR JP A,(65204) A NZ,64459 IY,23610 1 HL,10077 ; These instructions prepares registers and jumps ; to start of the program A,0 (254),A A,0 R,A A,#3F I,A SP,24575 HL,0 DE,0 BC,1 (HL),0 65089 At address 65089 there is: LOOP LD LD LD XOR LD INC DEC LD OR JR JP HL,32767 BC,14000 A,(HL) 227 (HL),A HL BC A,B C NZ,LOOP 24576 ; ; ; ; ; It is very simple XOR encryption loop. The loader was extremly complexly encrypted, but this is trivial hiding of main program. But you can simply do: POKE 65105,201: PRINT USR 65089 The program will be decrypted! ; Address 65105 We could save the memory again, but now decrypted. Program is started using PRINT USR 24576. Let's analyse the program, we must transfer the levels. At address 33113 there is: LEVLD LD LD CALL SELFM LD CP JR LD LD CALL . . . DE,1 IX,SELFM+1 33270 A,0 0 NZ,LEVLD IX,43608 DE,0 33270 ; Level speed-load routine ; Look! Loads in argument of instruction! ; This is also selfmodificable instruction ; Level speed-load routine So, at 33270 is LOAD routine for loading levels. Edge recognizer accepts it routine, but we could put on this address LD A,#88 OR A SCF JP 1366 ; Standard LD_BYTES routine for faster work. The easiest way of level transfer is using 'Turbo copy' at about 2800 Bd. Save them to normal speed and transfer to PC. 8.2. 'TURBO COPY' PROGRAM ===================== 'Turbo copy' program is on tape TURBO.TAP and it must be transfered to original ZX Spectrum using communication program and ZXTOOLS. This program is very similar to communication program, but you have transfer only from tape to tape. Avaliable commands are: n - If you press a number key (0..9) you can select loading (and saving) speed: 0 = 1400 Bd; 1 = 1500 Bd; 2 = 1850 Bd; 3 = 1900 Bd; 4 = 2750 Bd; 5 = 3050 Bd; 6 = 3250 Bd; 7 = 3300 Bd; 8 = 3650 Bd; 9 = 7500 Bd; L - Loads header and corresponding data block from input device until BREAK key was pressed, or if loading fails. S - Saves all blocks from memory to output device. H - Loads headerless blocks from input device until BREAK key was pressed or if loading fails. C - Clears all blocks from memory. F - Loads headers and displays them on the screen, but not store in RAM. Q - Resets computer. V - Views all blocks in the memory. While viewing you have these options: A - cancel autostart from BASIC programs. N - change name of header blocks. K - remove this headerless (or header and corresponding block) from memory. S - Saves blocks from this to the output device. < - Make pause when saving this block. M - Option to transfering a very long blocks, up to 48745 bytes. After this option, returning to the main menu is impossible. You have two suboptions: L - Load a long block. BORDER will be white if loading is OK, and black if loading fails. S - Save loaded block, always at 1500 Bd (this is good for our purpose). Loading speed must be set before using command M. Warning: if you try to load a headerless block which is longer than free memory space (41400 bytes when program is empty) or 48745 bytes with M command, program will crash because it have no protection, and loading such a block will destroy loading routine which is located at top of memory.
© Copyright 2026 Paperzz