home *** CD-ROM | disk | FTP | other *** search
- BEYOND STOS
-
- by: Mike Dixon-Kennedy
-
- A great deal has already been said and written about STOS since
- it was first released way back when, but there is still a great
- deal than needs to be looked at. The manual provided with STOS is
- good enough, but it does leave out a few of the more important
- facts.
-
- For example, the PACK command can take a parameter list, but does
- the manual tell you about them? No.
-
- How about using the TRAP command? Can you understand it simply
- from the brief description of this very powerful command? I know
- I couldn't, so it's that command we're going to have a look at
- this month.
-
- The manual tells us that the command syntax is:
-
- TRAP n[,parameters]
-
- and that the optional parameters have to be placed onto the stack
- before you execute the TRAP function and that these can be sized
- to either word or long word by use of 'W' of 'L' before the
- expression to be passed. And that's really all you get.
-
- There are a large number of really useful routines that can be
- accessed by correct use of the TRAP function, but unless you know
- what you're doing you'll get nowhere extremely quickly. I did!
-
- The most useful set of functions that can be accessed through the
- trap command are those concerned with the discs. Some of course
- are well catered for in STOS anyway, but there are several that
- are not, and can, if used properly, enhance the performance of
- STOS dramatically.
-
- A word to the wise though. Anybody playing around indiscrimi-
- nately with the valuable data normally held on discs wants
- shooting. ALWAYS make sure you have a blank disc in the drive
- when you are experimenting. That way you're not going to wipe
- any valuable data. Also, save your programs before trying out
- any of the TRAP calls if you are at all unsure about them, as if
- they aren't 100% correct you could hang up your ST (not crash it,
- but cause an internal endless loop). If that happens it's press
- the reset button time. You have been warned.
-
- So just what are these tremendous functions for playing around
- with the discs? The following list tells you which ones I
- consider useful. Any good book on machine code programming
- should contain a list of all of the functions you can access, and
- go into each in much greater detail.
-
- GEMDOS - TRAP #1
-
- $36 - Get disc free space
-
- BIOS - TRAP #13
-
- #4 - Read and write disc sector
- #7 - Get BIOS parameter block
- #9 - Enquire media change
-
- XBIOS - TRAP #14
-
- #8 - Read disc sector
- #9 - Write disc sector
- #10 - Format disc track
- #18 - Produce disc boot sector
- #19 - Verify disc sector
-
-
- All the other disc functions that can be accessed through the
- TRAP function are more than adequately covered from STOS anyway.
-
- Over the next couple of months I'm shall be looking at these, and
- some others, but here's just a couple to keep you going for this
- month.
-
- GEMDOS - $36 - Get disc free space
-
- Now I know STOS has a 'dfree' function that tells you how much
- space you've got left on your disc, but this call can provide you
- with much better information, and it's a nice easy one to start
- with.
-
- The assembly language for this TRAP call would look like:
-
- MOVE.W #0,-(SP) * Information from the active drive
- MOVE.L #BUFFER,-(SP) * Address of a 16 byte buffer
- MOVE #$36,-(SP) * The GEMDOS function number
- TRAP #1 * Call it
- ADDQ.l #8,SP * Clean up the stack
-
- The equivalent STOS function would read:
-
- TRAP 1,$36,.l BUFFER,0
-
- The first thing to notice about this is the use of the 'long' for
- the buffer which should be set to the start of a reserved memory
- bank BEFORE the trap call is made with something like BUFFER =
- START(10), or whatever bank you have decided to use.
-
- The next thing is the order in which the parameters are listed,
- these are always in the reverse order to the assembly language
- version, so the function number comes first in STOS whereas it
- comes just before the TRAP in assembly language. The trick here
- is to look at the assembly version and read upwards to find the
- order required for the correct STOS version.
-
- The final thing is the last parameter passed in the STOS version
- (first in assembly). This specifies the drive. A value of 0
- does not in this instance signify drive 0, but instead the active
- drive. Drive 0 (or A if you prefer) needs a parameter of 1,
- drive 1 or B needs 2, and so on. Remember that, it's important.
-
- Okay, having called this function, what do you get in return?
- More than the simple 'Ok' if you've tried it out in direct mode,
- that's for sure.
-
- Four four byte (long word) values are placed into the buffer by
- this function.
-
- The first long word (buffer+0 to buffer+3) contains the number of
- free allocation units on the disc. These units are simply the
- way in which the disc operating system keeps track of what's on
- your disc, and where it is. Each file, even if it's only a few
- bytes long, needs at least one of these units.
-
- The second long word (buffer+4 to buffer+7) contains the total
- number of allocation units on the disc, no matter whether they
- have been used or not.
-
- The third long word (buffer+8 to buffer+11) contains the size of
- a single sector on the disc. You'll find, unless you've got
- really weird discs, this will always be 512 bytes.
-
- The fourth and last long word (buffer+12 to buffer+15) contains
- the number of physical sectors that make up each allocation.
- Again, unless you've got funny discs, this should be two.
-
- From all this information it is possible to work out the free
- space on your disc, the total capacity of your disc if blank and
- the total number of bytes already used. The following short
- program does all this (crudely). The file 'DFREE.ACB' on the
- cover disc gives a much more refined version to be run as an
- accessory.
-
- 10 reserve as work 10, 256 : rem >>> reserve memory bank
- 20 BUFFER = start(10)
- 30 trap 1,$36, .l BUFFER, 0 : rem >>> dfree on active drive
- 40 ALLOC_FREE=leek(BUFFER) : rem >>> free allocation units
- 50 ALLOC_ALL=leek(BUFFER+3) : rem >>> total allocation units
- 60 ALLOC_SECS=leek(BUFFER+7) : rem >>> sectors / allocation unit
- 70 SEC_SIZE=leek(buffer+11) : rem >>> sector size in bytes
- 80 rem >>> calculate the free bytes on the disc
- 90 BYTES_FREE=ALLOC_FREE*ALLOC_SECS*SEC_SIZE
- 100 rem >>> calculate capacity of disc
- 110 BYTES_ALL=ALLOC_ALL*ALLOC_SECS*SEC_SIZE
- 120 rem >>> calculate bytes used
- 130 BYTES_USED=BYTES_ALL-BYTES_FREE
- 140 rem >>> now print it out
- 150 print "Total capacity of disc =";BYTES_ALL;" bytes"
- 160 print "Free capacity of disc =";BYTES_FREE;" bytes"
- 170 print "Bytes used on this disc =";BYTES_USED;" bytes"
-
- And that, as they say, is that. Simple isn't it?
-
- Now for something a little harder, a disc verifier. Again you'll
- find a much cleaner version of all this on the cover disc in the
- file 'VERIFY.ACB'. That's right, another one to be run as an
- accessory.
-
- To get a disc verifier to work we need two XBIOS trap calls,
- being those to read a disc sector and to verify a disc sector.
- These are function numbers 8 and 19 respectively.
-
- To verify the sectors on a disc we first have to know how that
- disc has been formatted, and we can find this out by reading the
- boot sector on the disc in question. To do this we need a buffer
- that is at least 512 bytes long (make it longer to be on the safe
- side), the address of which is passed to the routine.
-
- To read the boot sector from the disc we need to read track 0,
- sector 1 on side 0 of the disc into the buffer, and then take
- certain information out of the buffer. To read the sector we
- use:
-
- trap 14,8,.l BUFFER,.l 0,.w dr,.w sect,.w tr,.w side,.w count
-
- where dr is the drive being accessed, sect should be 1 for sector
- 1, tr should be 1 for track 1, side should be 0 for side 0 and
- count should be 1 to read just one sector. The proper command
- should read:
-
- trap14,8,.l BUFFER,.l 0,.l dr,.w 1,.w 0,.w 0,.w 1
-
- Having got the boot sector into the buffer we can take out of it
- the information we need being the number of sides on the disc,
- number of sectors per track and the number of tracks on the disc.
-
- We'll take a closer look at the boot sector next month, suffice
- to say for now that this information is found by peeking the
- following locations.
-
- sides = deek(buffer+26)
- sectors_per_track = deek(buffer+24)
- To find out the number of tracks on the disc we need to do a
- small calculation in the form of:
- (peek(buffer+19)+peek(buffer+20)*256)/sides/sectors_per_track
-
- Now we know just how the disc has been formatted we can check it.
-
- WARNING! If you mistakenly set the sector number to 0 you will
- cause an internal loop which will mean you'll have to reset your
- ST. This only happens with track 1. On other tracks it will
- produce an XBIOS error code which can be found out by printing
- the contents of DREG(0).
-
- If for any reason the sector is not loaded an error code will be
- placed in dreg(0), so you should always look at this after making
- the trap call. A value of 0 indicates that all went well. A
- negative value indicates an error. These error codes and their
- meanings are:
-
- 0 Ok, no error
- -1 General error (ST unable to determine it!)
- -2 Drive not ready
- -3 Unknown command
- -4 CRC error
- -5 Bad request, invalid command
- -6 Seek error, track not found
- -7 Unknown media - invalid boot sector
- -8 Sector not found
- -9 No paper? (Not sure what this one means)
- -10 Write error
- -11 Read error
- -12 General error
- -13 Disc write protected
- -14 Disc has been changed
- -15 Unknown device
- -16 Bad sector - during verify
- -17 Insert disc - provided drive connected
-
- So having found out the format of the disc we can verify it using
- the XBIOS function 19 which verifies a single sector at a time.
- This could be very slow, but thankfully we can do a track at a
- time.
-
- The assembly version of the required trap call is:
-
- MOVE.W count,-(SP) * number of sectors to verify
- MOVE.W side,-(SP) * disc side
- MOVE.W track,-(SP) * track number
- MOVE.W sector,-(SP) * sector number
- MOVE.W drive,-(SP) * the disc drive
- CLR.L -(SP) * a dummy that must be 0
- MOVE.L buffer,-(SP) * address of the buffer
- MOVE.W #19,-(SP) * the function number
- TRAP #14 * do it
- ADD.L 16,sp * tidy up the stack
-
- buffer ds.b 10240 * the buffer (10K)
-
- The STOS version would read:
-
- trap 14,19,.l buffer,.l 0,.w dr,.w sect,.w tr,.w side,.w count
-
- where buffer is the start address of a previously reserved memory
- bank, dr is the required drive, sect is the sector (to read a
- whole track as we are doing this MUST be 1), tr the track number,
- side the disc side and count the number of sectors to verify.
-
- Now we know how to do it, let's put it into action.
-
- 10 rem >>> set up the buffer we need
- 20 reserve as work 10,10240 : rem >>> this is 10K
- 30 Input "Drive to verify";DR
- 40 rem >>> test to see if that drive is connected
- 50 D=drvmap : if btst(DR,D)=0 then 10
- 60 rem >>> now read the boot sector
- 70 BUFFER=start(10)
- 80 trap 14,8,.l BUFFER,.l 0,.w DR,.w 1,.w 0,.w 0,.w 1
- 90 rem >> got it - get the info we need
- 100 SECTS=deek(BUFFER+24) : rem >>> sectors per track
- 110 SIDES=deek(BUFFER+26) : rem >>> number of sides on disc
- 120 ALL_SECTS=peek(BUFFER+19)+peek(BUFFER+20)*256
- 130 TRACKS=ALL_SECTS/SIDES/SECTS : rem >>> tracks on disc
- 140 rem >>> got it - now verify
- 150 TR=0 : repeat : rem >>> start at track 0
- 160 SI=0 : repeat : rem >>> start on side 0
- 170 rem >>> verify a track
- 180 trap 14,19,.l BUFFER,.l 0,.w DR,.w 1,.w TR,.w SI,.w SECTS
- 190 rem >>> check for error
- 200 ERR=dreg(0)
- 210 inc SI : rem >>> next side (if we can)
- 220 rem >>> exit loop if done all sides or error occurred
- 230 until SI>SIDES or ERR<>0
- 240 rem >>> next track
- 250 inc TR
- 260 rem >>> exit if done all tracks or error occurred
- 270 until TR=TRACKS or ERR<>0
- 280 if ERR<>0 then boom: print "Disc error - verify aborted"
-
- Note that in line 270 the loop is exited when we reach the number
- we calculated earlier. This is because tracks are numbered from
- 0, and any attempt to read beyond the end of the disc will
- produce an error (and a nasty click from your drive - but not
- harmful, I hope!). An eighty track disc has the tracks numbered
- 0 to 79.
-
- It really is a simple as that.
-
- Next month we'll take a close look at the disc format options as
- here we can expand the capacity of your discs (or shrink them if
- that's what you want), and produce some really clever disc
- formats, even some that only you can read!
-
- Till then, get hold of a book on machine code programming and
- have a go at playing around with the trap function yourself.
-
-