Your Spectrum
Issue 13, April 1985 - Microdrivin'
Home Contents KwikPik
big title
Investing in a Microdrive is a relatively easy process - using it is another matter entirely! AJ Unwin offers tricks and tips on how to get around a number of seemingly insurmountable hassles experienced by Microdrive users.
Hands up all those of you who are disillusioned with their Microdrives. The promises of faster access times and reliable storage are often not enough to encourage investment, and the expected support from the major software houses has proved non-existent.
However, Spectrum owners are well used to having to make do with what's available - and, to tell the truth, the Microdrive isn't a bad piece of kit at all ... you just have to know what you're doing!

FIRST THINGS FIRST

Our first task here is to gain some insight into the complications of shifting commercial and home-grown software from slow-loading cassette, across to the faster access Microdrives. Commercial programs available for the job are not too well reckoned and, in fact, claims of a 60 per cent success rate may be a little high - especially when you consider that most of the commercial attempts use a low RAMtop address in the programs, and any CLEAR statement with a number below 23610 makes it
nearly impossible to use any Microdrive function at all!
Later on in this article, we'll be looking at a few of the shortcomings of the Microdrive itself and investigating areas that could be improved. Finally, it must be said that our thoughts here are directed towards the 48K Spectrum rather than the 16K model; most of the programs that would benefit from the Microdrive's higher access speeds are those of the longer variety. But, having said that, the 16K machine can still use most of the techniques described here.

DOUBLE TROUBLE?

There are two types of program that are particularly hard to convert for Microdrive: those that use machine code with a RAMtop too low for a Basic loader program (or even Microdrive functions); and the type of program that uses cassette- based SAVE and LOAD routines.
In general, if the code uses all the space available above RAMtop, and RAMtop is lower than 24610, then forget it! This code cannot be moved
easily without resorting to machine code access of the Microdrive.
However, since most of the programs of the first type can be transferred with the help of a few tricks, that makes a good place to start. Most of the software on the market contains a Basic loader and a main section of machine code ... therefore, to be able to save the program to Microdrive, we need to know both the start and length of the code. We also need to find out the address from which to run it; look out for the 'USR xxxxx' in the Basic loader program!
The start and length of a particular program is not so easy to find, so we resort to a versatile cassette header reader like that given in this article. With these three vital pieces of information, it's a simple process to load from cassette and then save all the necessary codes to Microdrive using a line of code such as:

LOAD "" CODE: SAVE *"m";1;"name" CODE start, length

Where 'start' and 'length' are taken from the header reader program.
A word of warning though. Some programs use the areas required by the Microdrive system itself. For instance, addresses 23734 to 23813 are used for the system when no buffers are present but, as soon as a Microdrive access is made, another 595 byte block is needed. If the command 'PRINT 23734;"to";PEEK STKEND + PEEK (STKEND+1) * 256' gives the range which will coincide with the code, then the system could be overwritten.
However, in general, if the Microdrive block is going to be overwritten, the answer (if memory space will allow) is to load the code into a different area of memory and save it from there - remembering, of course, that the loader will need to be altered accordingly to:

LOAD "" CODE start2: SAVE *"m";1;"name" CODE start2,length

Now, all you have to do is create a loader program with the minimum information necessary to re-load the code parts.
cartoon

Owners of 16K games can make use of the fact that the top 32K in the 48K machine is effectively redundant - so you can ignore the 'CLEAR 23610' statement in the loader and keep RAMtop above 32K. For this case, use a loader of the form:

10 LOAD *"m";PI/PI;"name" CODE
20 RANDOMIZE USR VAL "xxxxx"


Where 'xxxxx' is the address the program starts execution from. Study this program for a minute or two and you'll see some weird looking statements in the loader. These will be explained more fully later on, but in short they're here to save memory since in most cases spare memory will be a scarce commodity indeed.

TWO UP

The second type of program is the one using the cassette LOAD/SAVE routines from within the program. With most program loaders, these LOAD/SAVEs are done from within this Basic program, with calls to the main code; therefore, there's no reason why it should be difficult to change all these to Microdrive versions. The code, however, may be sitting in a very low position and may need the area above for file data - try and keep the RAMtop as low as possible. This imposes large memory restrictions on our Basic program. If you're going to write a program that still incorporates all the original SAVE/LOADs, you'll have to pull some memory saving tricks out of the bag!
Take a look at the program line 'LET A=10'. Here, you can see five bytes and there are six bytes used to store the floating point representation of the number. (Check out page 122 of the Spectrum manual if you don't believe me!) As these all consume excessive amounts of memory, we'll take advantage of two ways of saving space when using numeric values.
First, make all numeric constants into variables if they're used a lot during a particular program. For example, if
'LET A=1' is converted to 'LET A=PI/PI', you'll save three bytes the first time round; then if 'a' is used to replace all the appearances of the digit '1', you'll save five bytes each time. The 'overhead', however, is that you've now got a variable 'a' using up precious space in the VARS area of memory.
The next area of conservation is when dealing with numbers that appear less frequently - for instance, if you convert RANDOMIZE USR xxxxx to RANDOMIZE USR VAL "xxxxx", you'll save three bytes each time you use it. Have a look at the table included in this article, providing a number of ways to save memory space.
Another very useful tip that I've not seen many people make use of - but which is good for extra clarity and space saving - is the idea of using labels instead of numerical references in GO TO and GO SUB statements. This not only aids reading a program but is also useful when writing/debugging since all labels are set up, say, in the first line and can then be used in association with the LIST command; it's certainly much easier to remember a label than some obscure line number!
Anyway, using just some of these methods, you'll find that, by changing only the Basic bits of software you want to convert to Microdrive operation, you'll save enough room to allow it safe passage on to cartridge.

THAT DARNED CAT!

One of the greatest problems with Microdrives is their lack of filetype descriptors in the catalogues produced when using 'CAT D'. However, by clever use of the 10-byte filename allowed, the problem can be alleviated to quite a reasonable degree. The method suggested here is to adopt a name and extension to indicate a filetype (BASIC, CODE, DATA or PRINT, for example). So, to store a program written in Basic, you'd use a filename such as 'MATHS.BAS'; a code file would be stored as 'MATHS.COD'.
Other extension types that can be used are: '.TXT' for any textual files; '.PRT' for any PRINT files generated using an OPEN # statement; '.DAT' for data files; and '.TMP' for temporary files that'll only be stored for a short while. The only drawback to this is that the name part of the descriptor is now restricted to a mere six letters, but this is a small price to pay in relation to the information provided on-screen.

OPEN ACCESS

If you're the proud possessor of more than one Microdrive, you may well have come across the following problem. If you load a Basic program that autoruns and subsequently loads another lump of code from a different drive to the one it was saved on, you'll find yourself in all sorts of trouble. The reason this causes a problem is because the loader program makes explicit reference to a particular Microdrive and then tries to access it, whether or not it's the Microdrive required.
However, there's a simple solution to this problem - and it involves the following routine:

LET d=PEEK 23766
LOAD *"m";d;"name" CODE ... (any type of file)


Watch out though! The PEEK statement must not be embedded in the load statement; if you do, you'll get the 'Invalid drive number' error message flashed up on-screen. The reason this happens is probably due to the fact that the old ROM line scanner is not in use and hence, the line scanner in the Interface 1 ROM is not able to cope properly. The actual value being PEEKed here is the new system variable D_STR1; this is normally a two-byte variable, but when
CONSERVATION TABLE
NumberEquivalent FormBytes Saved
0NOT PI4
1PI/PI3
10VAL "10"3
n<255CODE "ASCII CHR"2
The conservation of bytes is important if you've got to lower RAMtop before Microdrive conversion can take place. Here are a few 'tricks of the trade' to get you going.
Spotty Dog
1070 DEF FN a(a)=PEEK a+PEEK (a+1)*256
1080 LET d=0: LET ix=23296
1090 LET rdhead=23400
1100
1110 FOR a=0 TO 14: READ b: LET d=d+b: POKE 23400+a,b: NEXT a
1120 IF d<>1396 THEN PRINT "Error in data line"''"Recheck before RUN";: GO TO 10000: REM Main Program
1130 RANDOMIZE USR rdhead
1140 CLS: PRINT '"Name   : ";
1150
1160 FOR a=1 TO 10: PRINT CHR$ PEEK (a+ix);: NEXT a
1170
1180 IF PEEK ix<>3 THEN PRINT AT 10,3; FLASH 1;"Not CODE type Wind tape on": GO TO 1220
1190
1200 PRINT ''"Start  : ";FN a(ix+13)
1210 PRINT '"Length : ";FN a(ix+11)
1220 PRINT AT 21,0;"BREAK to Quit !!"
1230 GO TO 1130: REM M/c Routine
1240 DATA 221,33,0,91,175,55,17,17,0,205,86,5,48,242,201
This is a versatile header reader program, that you'll need to find out the start and end address of the code of a particular program.
2090 LET in=2410: REM Label. : REM Prompt for printer opt.
2100 POKE 23658,8: REM Capslock
2110 LET m$="Printer on Y/N >>"
2120 GO SUB in
2130 IF d$<>"N" AND d$<>"Y" THEN GO TO 2110
2140 LET p$=d$: REM Prompt for drive no.
2150 LET m$="Drive no>>"
2160 GO SUB in
2170 IF d$<"1" OR d$>"8" THEN BEEP .2,-20: GO TO 2150
2180 LET d=VAL d$
2190 CLOSE #10: REM Close stream: REM Create the cat file.
2200 OPEN #10;"m";d;"?"
2210 CAT #10;d: REM Cat to drv.
2220 PRINT #10;CHR$ 0;CHR$ 0;
2230 CLOSE #10: REM Close stream: REM Get catalogue into A$
2240 OPEN #10;"m";d;"?"
2250 LET a$=" "
2260 LET a$=a$+INKEY$ #10
2270 LET j=LEN a$
2280 IF a$(j)=CHR$ 0 AND a$(j-1)=CHR$ 0 THEN GO TO 2300
2290 GO TO 2260: REM Repeat.
2300 CLOSE #10: REM Finished cat: REM Remove temp file
2310 ERASE "m";d;"?": REM Print out file
2320 LET s=2: REM Default Scr.
2330 IF p$="Y" THEN LET s=3
2340 FOR a=1 TO j-2
2350 IF a$(a)<>CHR$ 13 THEN PRINT #s;a$(a);: GO TO 2380
2360 IF a$(a+1)=CHR$ 13 THEN PRINT #s: PRINT #s,: GO TO 2380
2370 PRINT #s,
2380 NEXT a
2390 PRINT #s;"Drive:";d
2400 STOP: REM Subroutine
2410 INPUT (m$); LINE d$
2420 IF d$="" THEN GO TO 2410
2430 RETURN
This is an improved CAT program, allowing you to print up to 40 filenames up on-screen at the same time.

small title used with Microdrives it usually contains a single byte reference to the particular Microdrive in use (since the last Microdrive used will do the same, you can use this bit of programming in your loader).
Although the loading time of the Microdrive is, in general, very fast - in fact, of the order of seven seconds maximum if the access is made in the first pass - it can be speeded up still
further by utilising the technique of saving more than one copy of the program on the cartridge. You can do this by POKEing the system variable COPIES (address 23791) with the number of copies required; this number is normally set to value '1'; and will be reset to this after you have made however many copies you require. The command to carry out the saving is shown below:

POKE 23791,10: SAVE *"m";1; ...

The above command would be used to save ten copies of the program specified later on in the expression. This procedure will be useful when the tape is fairly empty and it's taking a fair time to access the data.
To give you a bit of further help using the CAT command, you'll find a listing that provides an improved double- screen version of CAT. What you'll get is a catalogue of the Microdrive's contents listed in two columns, thus giving up to 40 names on-screen before the 'Scroll?' message pops up. This will mean you'll be able to see clearly what's on each Microdrive ... but the program's been geared to read only ASCII characters and not tokens; the tokens can still be read, although they might slightly upset the display format.
Well, that's it for now. Using the techniques outlined here, you should be able. to make much more of the Microdrives. And if you've got any more hints and tips for those attempting Microdrivin', let's be hearing from you ... we have the technology, but there's still a fair way to go before the Microdrives come up to the usefulness of disk drives on other home computers. Go for it!
cartoon
Home Contents KwikPik