                   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 <ENTER>

[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 <ENTER>

[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 <ENTER>

[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