The first problem we're dealing with
appears as a result of a serious bug in the
ROM; this causes the machine to crash
if there is insufficient memory space,
and a LOAD *"m" or SAVE *"m"
command is entered. The relevant Microdrive motor switches on, but no SAVEing
or LOADing occurs, and you cannot
halt the proceedings. The only way out
is to remove the plug during rotation,
something which might easily damage
the cartridge. To get round the problem,
before making such a command enter
RANDOMIZE USR 23296 (or whatever the value of 'st' in line 10 has been
made). If an 'Out of memory' error
appears, it means that a SAVE or
LOAD to Microdrive is dangerous, so
don't try it. If no error message occurs, it
means there is sufficient room and all
such commands will be carried out. |
Another problem can occur when you have a lot of OPENed streams. For each OPENED stream, a certain amount of memory is consumed, ranging from 11 to 595 bytes. The only way to get the use of all the memory is to CLOSE# or CLEAR#, but these sometimes fail to clear the memory, particularly if an error such as BREAK occurs during such a command. The second machine code routine, at st+8 (ie. 23304 if in the printer buffer), is designed to supplement the CLEAR# routine by removing any remaining memory areas of additional streams. Before using it, though, always do a CLEAR# first for example, CLEAR#: RANDOMIZE USR 23304.
The final routine will prove extremely
While there's plenty to recommend
about Sinclair Research's elusive Microdrive device, as with most innovations
there's room for improvement. The first
part of this article is for all users and
explains the problems and tells how to
use the 'cures'; and the second part is for
those who know some machine code
and who appreciate fuller explanations. |
Before presenting the listings, here is a very useful feature that can greatly decrease the loading times of some programs. Say you have a Basic program that loads another file such as a SCREEN$ or some machine code. If you SAVE the Basic then SAVE the second file, there may well be a considerable delay when you re-load it between the Basic part, and the second file. This is because two files SAVEd directly after one another cannot usually LOAD directly after each other. To be sure of fast loading, after each SAVE,
do a VERIFY, then the next SAVE,
and so on. This method ensure minimum time taken for loading. |
Figure 1 is a listing of a Basic program that contains all the data for the machine code routines; it's loaded into the printer buffer area of memory, at locations 23296-23353. However, the machine code is position independent, which means it can be put anywhere that's convenient in memory. Alternative places are the user-defined graphics area and above RAMTOP, and the start location can be altered by changing line 10 of the Basic listing. Do not put the code into a REM statement, ZX81 fashion - for technical reasons this is a very bad place to store Microdrive routines.
5 REM Printer buffer 10 LET st=23296 20 RESTORE 100 30 FOR i=0 TO 57 40 READ a: POKE i+st,a 50 NEXT i 60 REM test-room=st 70 REM clear#+ =st+8 80 REM collapse=st+41 90 REM 99 REM Test-Room 100 DATA 207,49,1,147,2,195,5,31 199 REM CLEAR# more 200 DATA 17,240,92,42,79,92,229,167,237,82,225,196,229,25,42,79,92, 17,20,0,25,235,42,83,92,43,26,254,128,196,229,25,201 299 REM Collapse 300 DATA 42,79,92,17,73,163,25,208,33,240,92,17,182,92,195,229,25
|Figure 1. The Basic program containing the Microdrive 'cure-all'.|
10 ; Test-room for 20 ; Microdrive commands 5B00 30 ORG 23296 ;printer buffer 5B00 CF 40 TESTRM RST 8 5B01 31 50 DEFB #31 ;create extra system variables 5B02 019302 60 LD BC,659 ;required space 5B05 C3051F 70 JP #1F05 ;test-room 80 ; 90 ; True CLEAR# 5B08 11F05C 100 CLEAR LD DE,23792 5B0B 2A4F5C 110 LD HL,(CHANS) 5B0E E5 120 PUSH HL 5B0F A7 130 AND A 5B10 ED52 140 SBC HL,DE 5B12 E1 150 POP HL 5B13 C4E519 160 CALL NZ,#19E5 ;reclaim maps if CHANS<>23792 5B16 2A4F5C 170 LD HL,(CHANS) 5B19 111400 180 LD DE,20 5B1C 19 190 ADD HL,DE 5B1D EB 200 EX DE,HL 5B1E 2A535C 210 LD HL,(PROG) 5B21 2B 220 DEC HL 5B22 1A 230 LD A,(DE) 5B23 FE80 240 CP #80 5B25 C4E519 250 CALL NZ,#19E5 ;reclaim channel bytes 5B28 C9 260 RET 270 ; 280 ;set constants 5C4F 290 CHANS EQU 23631 5C53 300 PROG EQU 23635 310 ; 320 ; 330 ;COLLAPSE to remove extra system variables 5B29 2A4F5C 340 COLAPS LD HL,(CHANS) 5B2C 1149A3 350 LD DE,#A349 5B2F 19 360 ADD HL,DE 5B30 D0 370 RET NC ;return if no variables anyway 5B31 21F05C 380 LD HL,#5CF0 ;end of area 5B34 11B65C 390 LD DE,#5CB6 ;start of area 5B37 C3E519 400 JP #19E5 ;reclaim the area 5B3A 410 END
|Figure 2. The assembler listing of the three routines presented in Figure 1.|
|useful for converting certain cassette programs on to Microdrive, particularly those containing machine code in REM statements. Many commercial games contain such REM statements of this kind as the first line in a program, with subsequent commands such as RANDOMIZE USR 23760. However, with Interface 1 in use, the location of the first line in a program can, and does, change which normally makes the machine 'fall over' when it tries the USR statement. The third machine code routine starts at st+41 (23337 in the printer buffer) and removes the extra system variables; thus the first line will be in the same place as it would if there was no Interface 1 connected. Note that any error (except 'OK') and any Microdrive commands will move the line back to its previous position. Written originally for the game, Valhalla, the routine has proved useful on a number of other occasions too.||
Microdrive ROM doesn't quite get right.
When doing a SAVE *"m" or LOAD
*"m", a total of 659 free bytes are
required, made up of 595 bytes for the
CHANS buffer, 32 bytes for the Microdrive map, and 32 bytes for stack usage.
Sad to say, the Interface 1 ROM only
checks for 627 bytes - the ROM
authors having overlooked the stack
usage - thus causing the crash. The
routine itself is quite straightforward.
Firstly hook code #31 is used to make
sure the 58 bytes of extra system variables
are in existence, then the ROM routine
at #1F05 is executed to test for 659 free
Before we discuss the CLEAR# supplementary routine, it would be useful to examine the relevant section of the Spectrum memory map - see Figure 3.
To remove all the extra memory areas after a CLEAR#, any Microdrive maps (plus any additional channel information) have to be reclaimed from
the memory map, and everything above
shifted down, while all the system
pointers are altered. The ROM routine
at #19E5 is designed to do just that
with the location of the first bytes to be
reclaimed in DE, and the first location
to be left alone in HL. The routine
initially tests to see if CHANS is equal
to 23792, and if it does not then any
bytes in the Microdrive maps area are
reclaimed. Then the byte at
CHANS+20 is tested to see if it is the
end marker of #80. If it is not then any
extra channel information is reclaimed. |
The third routine, COLAPS, first checks to see if CHANS is less than 23735, and returns if it is. If it is not then it means that the extra system variables exist; these are reclaimed, again using the ROM routine at #19E5. The extra bytes are created by the Interface 1 whenever an error occurs, when an incorrect Basic line is entered, or when an Interface 1 command is entered.
THE SECOND LEVELThose not understanding Z-80 machine code are likely to find the rest of this article something of a closed book although, of course, you can still use the routines. Figure 2 is the assembler listing of all the routines, and it was produced on the excellent HiSoft GENS assembler, which uses the unusual method of signifying hexadecimal numbers by preceding them with '#'.
The first routine starts at TESTRM, and carries out a memory test that the
Figure 3. The area of the Spectrum memory map affected by the second of the three routines.