Changes and additions to the Interface 1 ROM The file imc.i1rom contains a modified version of the Interface 1 ROM (the newer of the two versions) and also an extra 8K of new commands. All the files ending with "T" are assembler source files made with Hisoft GENS and in xzx format (in order to use these on xzx you should define LOAD_SAVE_2). Warning: the source is incomplete, and even the source that does exist is not guaranteed to give a working ROM! In particular, at least one of the entry addresses differs between the address table in "ROMHEX+ T" and the address named in the separate source file (the latter appears to be correct). Note also that in order to compile this source you need a version of GENS in which the ENT instruction works properly. Tweaks and bug fixes in the Interface 1 (I1ALTER T) * In several places, the Interface 1 ROM needs to make some space within the BASIC memory map - for instance when making a microdrive channel or loading a program. It does this by calling either 1655H or 0030H in the Spectrum ROM. In the case of loading a program, it also calls 1F05H to test whether there is enough room before performing the load. Unfortunately this does not work properly. If there is not enough room then the Spectrum ROM will raise an error with the microdrive channel still open, the microdrive running and the interrupts disabled. This will crash the machine [%]. Most of the bug fixes are concerned with changing the requests for memory so that they report any errors using the Interface 1's error routine, which closes channels, switches the microdrive off and enables the interrupts before reporting the error. [%] The Spectrum ROM reports an out-of-memory error by storing the error number in 23610 and clearing the stack. It avoids using RST 8 in order to prevent a syntax marker from appearing in case the error occurred while a line was being entered. Since the interrupts are disabled, the machine crashes at the HALT instruction at the start of the error routine. Inserting an EI instruction here would prevent the crash but still leave the microdrive running and the channel open. Changing the test-room routine so that it uses RST 8 to report the error would prevent the crash because the Interface 1 would be able to intercept it and clean up before reporting the error. A file called "imc.rom" containing these changes (and others) is available. The modified Interface 1 ROM will work without these changes, however. * The call that reclaims a microdrive map has been changed so that it ignores the case when a map is not present (this might happen when an error occurred because there was not enough memory); the machine would otherwise crash. * The length of data which is initially copied from 14B1 into a microdrive channel has been changed from 25 to 28 (for reasons which may become clear in due course...). * MERGEing a program which was saved with a LINE number is allowed. * The machine does not reset if you press the Break key while loading a "RUN" program. * MERGE "x" LINE and MERGE "x" CODE are disallowed at syntax time. * A "t" channel prints character 127 verbatim instead of as "?" (no doubt I did this before I had a real printer...). * If you OPEN a microdrive file which has an incorrect type, the original Interface 1 ROM would have left the microdrive channel unused in memory. The modified version does not. If you MOVE something from or to a "t" or "b" channel, the original Interface 1 ROM would have left a temporary channel unused in memory after the command finished. The modified version does not. * A call to the Spectrum ROM's NMI routine has been inserted at 0066H (the NMI address). * IOBORD has been set to 4 and the screen and border colours for CLS# have been changed to white-on-black. * This source file also contains the jump (at 01EC) which hooks in the new commands. Parallel Printer Interface (PARALLEL T) The interface in which I placed my EPROM is also a parallel printer interface. This can be switched on and off. When it is switched on, any output to the RS232 interface is automatically redirected to the parallel interface. The interface uses IN 127 to detect some inputs from the printer (most importantly, the BUSY signal in bit 0) and OUT 127 to output a character to the printer (this one OUT does all the necessary work; it is not necessary to activate STROBE separately, for example). IN 127 is guaranteed not to equal 255 if the interface is switched on. In order to disable this modification (for the benefit of the xzx RS232 hack), poke 060B2F into 0D07 and the following two locations. Note that in the newer Interface-1 version, the input address is 0B98 and the output address is 0D07. If xzx does not recognise this ROM version, these values should be written in place of the older values 0C5A and 0B9A respectively. CIRCLE (source missing) Typing ".CIRCLE" followed by the usual three parameters draws a fast circle (which is also more circle-like than those which the spectrum's CIRCLE command usually draws). Using ",CIRCLE" draws a filled circle. These commands are plug-compatible with the ordinary CIRCLE command, but they can draw circles which go partially off-screen. SYNTAX (source missing) Typing ?0 turns normal syntax checking off, so you can enter a program which is written in total gibberish (Sinclair BASIC still works though). Typing ?1 puts the situation back to normal. Don't ask why I added that... LOAD (source missing) Typing an exclamation mark (!) followed by a name (not in quotes) will load that file (it must be a BASIC program) from microdrive 1. AUTO (ROMAUTO T) Typing ".a" gives auto line numbering starting from 10 and in steps of 10. ".a x" gives auto numbers starting at x and in steps of x, while ".a x,y" gives auto numbers starting at x and in steps of y. To stop auto numbering, delete the number and press enter. CAT (ROMCAT T) Typing a star (*) before a CAT command gives a catalogue which shows the type of each file. Hidden files are shown with a first character of "(c)" (copyright). The command *CAT "c" is also allowed; this reads tape headers and displays the details. The "c" must be written verbatim - *CAT a$ is not allowed, for example. Printer channel (ROMCHAN T) Typing ".u" opens #4 to channel "b" and #3 to channel "u" (which is "t" plus a bit extra). Data sent to channel "u" is expanded by having all graphic characters plus the characters "pounds", "copyright" and "vertical bar" sent as graphics using "ESC K". Also, poking anything into 23681 causes that character to be printed at the start of each line until it is cancelled by poking zero there (this is useful for persistent expanded text, for example, which requires character 14 to be printed at the start of each line). Copier (ROMCOPY T) [with apologies to the writer of that utility in the ZX expansion pack, where I nicked most of the code from...] Copy files by typing *MOVE source TO dest, where source is either "c";;"filename" or "m";n;"filename", and dest is either "c" or "m";n. Device "c" indicates a cassette file. The filename of a cassette file may be blank, in which case every file which is played in will be copied until a break-in (or a tape loading error) occurs. Source and destination may not both be "c". If both are microdrive files and they refer to the same microdrive, then the copier will pause for cartridges to be exchanged between loading and saving. RAMTOP should be below 26000 when the copier is used. Files will be loaded into memory starting at about that address. Cassette files larger than about 39K cannot be copied. Screen copy (ROMDUMP T) Type "COPY n", where n is a 2-bit number in which bit 0 gives a shaded copy when set and bit 1 gives a large copy when set. This program uses "ESC K" to output graphic data, and the printer needs room for 576 columns of dots in order to print a large copy, which is three times as high and wide as a small copy. Hex (ROMHEX+ T - this file also contains the address table for all the commands) The ampersand (&) prefix may be used in any expression for hex numbers having 1-4 digits. The command "PRINT ~" works just like PRINT but prints any numbers in hex instead of in decimal (all the numbers should be between 0 and 65535). INKEY5 (ROMINKEY T) The command ".i1" turns INKEY5 on and ".i0" turns it off. When INKEY5 is turned on and #5 is open, any incoming data on #5 acts as if it had just been typed in. If no data is available at #5, the keyboard works normally. This can be used with the xzx RS232 hack to type in spectrum programs from the tty rather than the spectrum keyboard (use -crlf true in this case). Tokens can be spelled out in capital letters; they will be assembled when Enter is pressed (warning - the tokeniser is not terribly intelligent. Almost any word will be tokenised if it appears in capitals, even if it is within another word). KEY (ROMKEY T) ".k1" turns KEY on, and "CLOSE #5" turns it off. When KEY is active, any key on the keyboard may be redefined by adding a REM line to the start of the current program saying REM k=definition where k is the key being defined. Control keys may be redefined or used in the definition by saying |K, where K is the character which is 64 above the key code - for example, |M is the "enter" key, which must be placed at the end of a line if the line is to be entered automatically. The vertical bar character must be written |SGN (with SGN written as a token) unless it is the last thing on the left- or right-hand side of a definition. A sample set of key definitions is supplied in the program REMs (which is in xzx format). One of these is a definition of INKEY$ which waits for you to press a key and then tells you what it is in vertical-bar notation. This can be an extended key (when you press both shifts a flashing E will appear). (For some reason, this sometimes doesn't appear to work on xzx 0.5 unless you edit line 90 and press enter before doing it). SAVE (ROMSAVE T) This is just a utility for lazy typists, really. The commands are: *Lname = LOAD *"m";1;"name" *Sname = SAVE *"m";1;"name": VERIFY *"m";1;"name" *Vname = VERIFY *"m";1;"name" *Mname = MERGE *"m";1;"name" *Ename = ERASE "m";1;"name" *Rname = ERASE "m";1;"name": SAVE *"m";1;"name": VERIFY *"m";1;"name" Any space coming after the command letter counts as part of the name. The command letters may be typed in upper or lower case. The *r command doesn't bother erasing if the file doesn't already exist, so it is faster than typing the commands individually. The *v and *l commands do not require you to specify the type information (for instance, CODE or DATA a$()). If you do not specify the type, then they will load or verify any kind of file. SECTOR (ROMSECTORT) This is a utility for examining and attempting to fix broken microdrive cartridges (which should be placed in microdrive 1). Start off by typing "/M". This will create a map of the cartridge which will remain in memory until you have finished examining it (if you don't, then the first SECTOR command you type will execute /M instead of its usual function. It is supposed to do that "as well" rather than "instead", but there appears to be a bug). The SECTOR commands work on microdrive channels, just like the one illustrated on page 47 of the microdrive manual. You can open such a stream with the OPEN # command, but it is easier just to let SECTOR open it by using one of the commands (SECTOR does not do anything special to open it - it just reserves the memory). Each command may be followed by a hash (#) and a number; if it isn't, then #4 is assumed (if the command has a parameter, the hash and number come first, followed by a semicolon (;) and then the parameter). Data may be poked into a channel, using the address of the channel and the numbers in the manual (for instance, set a variable IX to the channel's start address, then POKE IX+68,2 [set RECNUM to 2] or POKE IX+71,0 [clear the first character of RECNAM] etc.). Use the /DATA command to check that it has gone in correctly. Note: in the manual it is not stated that bit 1 of RECFLG is used to signal "end of file". This must be set to 1 at the end of the file and 0 in the middle, or the file will not function correctly. The SECTOR commands are: /DATA (with DATA as a keyword) print out the given microdrive channel's contents. This consists of the channel address, the contents of the important fields of the channel, the microdrive map with the amount of free memory, and the contents of the data buffer. You may break in at the "scroll?" message, as usual. /N Create a "null" sector in the given microdrive channel. /L n Load sector n of the cartridge into the given microdrive channel. /L "file";n Load record n of "file" into the given microdrive channel. /S Save the given microdrive channel in the next free sector on the cartridge. /S n Save the given microdrive channel in sector n of the cartridge, overwriting whatever was there. /V n Verify the given microdrive channel against sector n of the cartridge. /P a Put the data from the given microdrive channel into memory at address a. /G a Get the data from memory at address a into the given microdrive channel. /M Make a new map (do this if you change cartridges). /CLOSE# (with CLOSE# as a keyword) Finish editing. Notes: Any of the command letters may be typed in upper or lower case. If you save a null sector from /N on the cartridge, it will appear as a free sector. If you poke RECFLG to 1 before saving it, it will appear as a full sector (in this case you should poke RECNAM to zeros or else that name will appear on the catalogue). Do this to mark any bad sectors that appear. The checksum of a sector will be calculated automatically before the sector is saved. If a loaded sector has an incorrect checksum, a message will be printed but the sector is still loaded in the state in which it was found. After a sector is saved, the /DATA command will tell you which sector of the cartridge it was saved in. The first nine bytes of record number zero of any file which is not a PRINT file will contain data relating to the file (same as HD_00 to HD_11 in the system variables section of the manual). This is important for calculating the address parameter of the /P and /G commands. Make sure that the record flag and the record number are correct before you use these commands and calculate the address carefully. Sector numbers decrease as the cartridge goes round, and files are usually saved on every other sector, not every sector. This means that the next record of a file is most likely to be on the sector with the number 2 less than the present sector. Historians might like to note that the format of sectors is described in detail in Microdrive File, p.148, Your Computer June 1984. To finish editing, type /CLOSE# and also close all the microdrive channels. Tape copy (ROMTCOPY T) Type ".c" to enter the tape copier. Play a tape, and when the border turns green, start recording and press a key. In theory, this should copy any normal file or headerless file, but it won't work too well with xzx and I'm not sure that it works anyway...