Microdrive Utilities Jon Ellis with a Microdrive toolkit for the Spectrum. Although the Microdrive has been in widespread use with the Spectrum for well over a year now, very little software utilising the Microdrive has been published. The one kind of routine which has received exposure is the extended Cat, which gives information on the length and type of the files on a cartridge. The programs in this article deal with the Microdrive in a more sophisticated way. The first two programs make up a secure saving system. Files which are saved from the first program can only be loaded using the second. Protected files cannot be seen on a normal Cat, extended Cat programs reveal no valid information, and the files cannot even be erased normally. The third program is of more widespread application - it eliminates the tortuous syntax of the normal Microdrive commands, enabling you to load a file with an expression as simple as *LOAD "filename" All of the new functions are implemented in the form of new Basic commands so there are no Pokes required in ope- ration. All of the commands are made up of a command word preceded by a star, and followed by various parameters. None of the new commands are keywords, and so they must be typed out letter by letter. Before you can enter a line containing one of the new commands, you will have to make one USR call to insert the new command interpreter. The address to call is different for each program and is given in the paragraph describing the program. This USR call will have to be placed at the start of any program which uses the new Basic, and will need to be re-executed after any NEW. All of the major listings are given in the form of a hex-dump which is designed for use with the hex loader given in listing 1. [This program is on the .mdr which goes with this article, under the obvious name of "hex loader".] The task of programming was complicated by the fact that there are at least two different shadow ROM programs in existence. I have therefore given two listings for each of the major programs. To find out which version of the shadow ROM you have in your Interface 1, type in the bytes from listing 2 using the hex loader. [This is on the .mdr as "Version".] When you have finished, type RANDOMIZE USR 40000 and the program will tell you which ROM you have. If you have a version 1 ROM you should use listings 3a, 4a and 5a, version 2 owners should use listings 3b, 4b and 5b. If you have an unknown ROM then you will be unable to use the programs. The first program, given in listing 3, enables you to save and erase files in the special protected format. The new commands are *Dump to save a file, and *Wipe to erase one. The USR call to invoke the two commands is RANDOMIZE USR 64280 Before beginning to type in the bytes from listing 3a or 3b you must CLEAR 64279 to move Ramtop out of the way. This also applies when you want to load the completed code for use in a program. When you have finished entering the bytes, the code should be saved: SAVE *"m";1;"Safe=Save"CODE 64280,1080 [Both a and b versions of this code are on the .mdr, as "Safe=SaveA" and "Safe=SaveB". I've only been able to test the b version, but the a code does at least checksum OK.] The required syntax for the *Dump command is very similar to that of the SAVE command referred to the tape system. For example, the expression *DUMP "file 1" would save the current Basic program onto drive 1 in the protected format. You may save to drives other than 1 by the inclusion of a valid drive number and a semicolon before the filename - the line *DUMP 3;"file 1" would have saved the program to drive 3. Note that all filenames for use with the protected save system may be a maximum of /nine/ characters in length. The forms *DUMP "filename" LINE, *DUMP "filename"SCREEN$ and *DUMP "filename"CODE are supported, but *Dump "filename" DATA is not. When saving code you can include an optional third parameter as an autorun address for the code block - e.g. *DUMP "game"CODE 30000,5000,31000 will save 5000 bytes of code starting at 30000. Immediately on loading, the code will be executed from 31000. The other command provided by this listing, *Wipe, required no para- meters apart from the filename and an optional drive number - the only allowed syntax forms being *WIPE "filename and *WIPE 5;"filename" Listings 4a and 4b contain the bytes for the other half of this utility - the program which allows you to reload protected files. Before beginning to type the bytes in you must CLEAR 64444 and likewise on any subsequent loading. When you have finished, you should save the object code: SAVE *"m";1;"Safe=Load"CODE 64445,920 [On the .mdr as "Safe=LoadA" and "Safe=LoadB", and again I've only been able to actually test the B version.] This program provides only one new command, *Take, and the required address that must be called to insert it is 64445. The only permissible syntax is *TAKE "filename" or *TAKE 4;"filename" If the Break key is pressed whilst the program is load- ing a file then the machine will be reset. I suggest that you experiment with the safe loading system on a blank cartridge until you are sure that it is working properly. Note that when a Basic program is *Taken from cartridge, all its variables are loaded as well. The final major program is the syntax simplifier. The bytes are given in listing 5. Before typing in or loading the object code you must CLEAR 64879 When you have finished entering, the code should be saved: SAVE *"Short Syn"CODE 64880,480 [Same note as above: two versions, only b version tested.] This program provides six new commands which are inserted with the line RANDOMIZE USR 64880 The six commands are *Save, *Load, *Verify, *Merge, *Erase and *Format. These commands perform exactly the same func- tions - with one exception - as their normal counterparts. However, the clumsy "M";1; syntax has been abandoned. All six commands have the drive number as an optional parameter as in *Dump etc. All the commands except *Save take exactly the same syntax form as *Take and *Wipe. Note that, contrary to the normal requirement, you do not need to state in a Load-type command the kind of file you want to load - the program automatically determines the nature of the incoming file, and treats it accordingly. All the usual options for saving screens, arrays and code are available with the *Save command. The *Erase command has an extra function - a wildcard facility in the filename. As an example- if you had three files on a cartridge called Block 1, Block 2 and Block 3, you could erase all three in a single *Erase line: *ERASE "Block ?" The '?' character in the filename indicates that that par- ticular character position need not be checked for a match when searching the cartridge for records of the file to be erased. Note that the line *ERASE "??????????" will erase all files on the cartridge. Listing 6 is a sub-routine which enables you to have your new commands give their own unique error messages. Each error message should be added to the table with 80hex added to the last character. The messages are printed with a black square instead of an error letter or number to indicate that they are non- standard errors. The routine is activated from your program by loading the location Error with the number of the message in the table minus one, and then calling NewRR. The new ROM /must/ be paged in when this routine is called, otherwise a crash will occur - line 90. Listing 7 is a command interpreter for building a library of new Basic statements. It scans the table CMTAB for a command, giving a syntax error if it is not found, and jumping to the appropriate address if it is. [Both these subroutines were given as assembler listings only, not as pre-assembled machine code. They also provide sample data only, and as such are not usefully assemblable in the state they are in - they're useful only as a start for your own programs. Therefore, I'm giving them here in their assembly format, and they are not on the .mdr.] ___________________________________________________________ Listing 6. 00010 ;*********************** 00020 ;** NEW ERROR SYSTEM ** 00030 ;** by Jon Ellis 1985 ** 00040 ;*********************** 00050 ORG address 00060 NEWRR LD SP,(23613) 00070 LD HL,HANDL 00080 EX (SP),HL 00090 RST 0 00100 HANDL LD HL,(23755) 00110 LD (23645),HL 00120 RES 5,(IY+1) 00130 LD HL,0 00140 LD (IY+55),H 00150 LD (23563),HL 00160 INC HL 00170 LD (23574),HL 00180 CALL 5805 00190 CALL 3438 00200 SET 5,(IY+2) 00210 LD A,143 00220 RST 16 00230 LD A,32 00240 RST 16 00250 LD A,(ERROR) 00260 LD DE,ERTAB 00270 JP 4934 00280 ;________________________ 00290 ;************************ 00300 ;** ERROR MESSAGES ** 00310 ;************************ 00320 ERROR DEFB 0 00330 ERTAB DEFB 128 00340 DEFM /Example / 00350 DEFM /messag/ 00360 DEFB "e+128 P0 ___________________________________________________________ Listing 7. 00010 ;*********************** 00020 ;** COMMAND SEARCHER ** 00030 ;** by Jon Ellis 1985 ** 00040 ;*********************** 00050 ORG address 00060 VECTR RST 8 00070 DEFB 49 00080 LD HL,NWCOM 00090 LD (23735),HL 00100 RET 00110 NWCOM RST 16 00120 DEFW 24 00130 CP "* 00140 JR NZ,NFIND 00150 LOOK LD B,number 00160 LD HL,CHTAB 00170 LOOP1 PUSH BC 00180 LD DE,(23645) 00190 NXLET PUSH HL 00200 RST 16 00210 DEFW 32 00220 POP HL 00230 XOR (HL) 00240 JR Z,LETOK 00250 XOR 32 00260 JR NZ,WRONG 00270 LETOK INC HL 00280 LD A,(HL) 00290 CP "= 00300 JR NZ,NXLET 00310 INC HL 00320 LD E,(HL) 00330 INC HL 00340 LD D,(HL) 00350 RST 16 00360 DEFW 32 00370 EX DE,HL 00380 POP BC 00390 JP (HL) 00400 WRONG LD (23645),DE 00410 LD B,255 00420 LD A,"^" 00430 CPIR 00440 POP BC 00450 DJNZ LOOP1 00460 NFIND JP 496 00470 ;_____________________ 00480 ;********************* 00490 ;** COMMAND TABLE ** 00500 ;********************* 00510 CMTAB DEFM /EXAMPLE=/ 00520 DEFW EGRUN 00530 DEFB "^" P0