home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 10: Diskmags / nf_archive_10.iso / MAGS / ST_USER / 1991 / USERSP91.MSA / TEXT_STOS.DOC < prev    next >
Encoding:
Text File  |  1991-07-16  |  14.1 KB  |  322 lines

  1.                                 BEYOND STOS
  2.      
  3.                           by: Mike Dixon-Kennedy
  4.  
  5.      A  great deal has already been said and written about STOS  since 
  6.      it was first released way back when,  but there is still a  great 
  7.      deal than needs to be looked at. The manual provided with STOS is 
  8.      good  enough,  but it does leave out a few of the more  important 
  9.      facts.
  10.  
  11.      For example, the PACK command can take a parameter list, but does 
  12.      the manual tell you about them?  No.
  13.  
  14.      How about using the TRAP command?   Can you understand it  simply 
  15.      from the brief description of this very powerful command?  I know 
  16.      I  couldn't,  so it's that command we're going to have a look  at 
  17.      this month.
  18.  
  19.      The manual tells us that the command syntax is:
  20.  
  21.                        TRAP n[,parameters]
  22.  
  23.      and that the optional parameters have to be placed onto the stack 
  24.      before you execute the TRAP function and that these can be  sized 
  25.      to  either  word  or long word by use of 'W' of  'L'  before  the 
  26.      expression to be passed.  And that's really all you get.
  27.  
  28.      There  are a large number of really useful routines that  can  be 
  29.      accessed by correct use of the TRAP function, but unless you know 
  30.      what you're doing you'll get nowhere extremely quickly.  I did!
  31.  
  32.      The most useful set of functions that can be accessed through the 
  33.      trap command are those concerned with the discs.   Some of course 
  34.      are well catered for in STOS anyway,  but there are several  that 
  35.      are not,  and can,  if used properly,  enhance the performance of 
  36.      STOS dramatically.
  37.  
  38.      A  word to the wise though.   Anybody playing around  indiscrimi-
  39.      nately  with  the  valuable data normally  held  on  discs  wants 
  40.      shooting.   ALWAYS  make sure you have a blank disc in the  drive 
  41.      when  you are experimenting.   That way you're not going to  wipe 
  42.      any valuable data.   Also,  save your programs before trying  out 
  43.      any of the TRAP calls if you are at all unsure about them,  as if 
  44.      they aren't 100% correct you could hang up your ST (not crash it, 
  45.      but cause an internal endless loop).   If that happens it's press 
  46.      the reset button time. You have been warned.
  47.  
  48.      So  just what are these tremendous functions for  playing  around 
  49.      with  the  discs?   The  following list tells you  which  ones  I 
  50.      consider  useful.   Any  good book on  machine  code  programming 
  51.      should contain a list of all of the functions you can access, and 
  52.      go into each in much greater detail.
  53.  
  54.                         GEMDOS - TRAP #1
  55.  
  56.      $36 - Get disc free space
  57.  
  58.                          BIOS - TRAP #13
  59.  
  60.       #4 - Read and write disc sector
  61.       #7 - Get BIOS parameter block
  62.       #9 - Enquire media change
  63.  
  64.                         XBIOS - TRAP #14
  65.  
  66.       #8 - Read disc sector
  67.       #9 - Write disc sector
  68.      #10 - Format disc track
  69.      #18 - Produce disc boot sector
  70.      #19 - Verify disc sector
  71.  
  72.  
  73.      All  the  other disc functions that can be accessed  through  the 
  74.      TRAP function are more than adequately covered from STOS anyway.
  75.  
  76.      Over the next couple of months I'm shall be looking at these, and 
  77.      some others,  but here's just a couple to keep you going for this 
  78.      month.
  79.  
  80.      GEMDOS - $36 - Get disc free space
  81.  
  82.      Now  I know STOS has a 'dfree' function that tells you  how  much 
  83.      space you've got left on your disc, but this call can provide you 
  84.      with much better information,  and it's a nice easy one to  start 
  85.      with.
  86.  
  87.      The assembly language for this TRAP call would look like:
  88.  
  89.      MOVE.W  #0,-(SP)         * Information from the active drive
  90.      MOVE.L  #BUFFER,-(SP)    * Address of a 16 byte buffer
  91.      MOVE    #$36,-(SP)       * The GEMDOS function number
  92.      TRAP    #1               * Call it
  93.      ADDQ.l  #8,SP            * Clean up the stack
  94.  
  95.      The equivalent STOS function would read:
  96.  
  97.                      TRAP 1,$36,.l BUFFER,0
  98.  
  99.      The first thing to notice about this is the use of the 'long' for 
  100.      the buffer which should be set to the start of a reserved  memory 
  101.      bank  BEFORE the trap call is made with something like  BUFFER  = 
  102.      START(10), or whatever bank you have decided to use.
  103.  
  104.      The  next thing is the order in which the parameters are  listed, 
  105.      these  are always in the reverse order to the  assembly  language 
  106.      version,  so  the function number comes first in STOS whereas  it 
  107.      comes just before the TRAP in assembly language.   The trick here 
  108.      is  to look at the assembly version and read upwards to find  the 
  109.      order required for the correct STOS version.
  110.  
  111.      The final thing is the last parameter passed in the STOS  version 
  112.      (first  in assembly).   This specifies the drive.   A value of  0 
  113.      does not in this instance signify drive 0, but instead the active 
  114.      drive.   Drive  0  (or A if you prefer) needs a parameter  of  1, 
  115.      drive 1 or B needs 2, and so on.  Remember that, it's important.
  116.  
  117.      Okay,  having  called this function,  what do you get in  return?  
  118.      More than the simple 'Ok' if you've tried it out in direct  mode, 
  119.      that's for sure.
  120.  
  121.      Four  four byte (long word) values are placed into the buffer  by 
  122.      this function.
  123.  
  124.      The first long word (buffer+0 to buffer+3) contains the number of 
  125.      free  allocation units on the disc.   These units are simply  the 
  126.      way  in which the disc operating system keeps track of what's  on 
  127.      your disc,  and where it is.   Each file, even if it's only a few 
  128.      bytes long, needs at least one of these units.
  129.  
  130.      The  second long word (buffer+4 to buffer+7) contains  the  total 
  131.      number  of allocation units on the disc,  no matter whether  they 
  132.      have been used or not.
  133.  
  134.      The third long word (buffer+8 to buffer+11) contains the size  of 
  135.      a  single sector on the disc.   You'll find,  unless  you've  got 
  136.      really weird discs, this will always be 512 bytes.
  137.  
  138.      The  fourth and last long word (buffer+12 to buffer+15)  contains 
  139.      the  number  of physical sectors that make  up  each  allocation.  
  140.      Again, unless you've got funny discs, this should be two.
  141.  
  142.      From  all  this information it is possible to work out  the  free 
  143.      space on your disc,  the total capacity of your disc if blank and 
  144.      the  total  number of bytes already used.   The  following  short 
  145.      program  does all this (crudely).   The file 'DFREE.ACB'  on  the 
  146.      cover  disc  gives a much more refined version to be  run  as  an 
  147.      accessory.
  148.  
  149.  10 reserve as work 10, 256 : rem >>> reserve memory bank
  150.  20 BUFFER = start(10)
  151.  30 trap 1,$36, .l BUFFER, 0 : rem >>> dfree on active drive
  152.  40 ALLOC_FREE=leek(BUFFER) : rem >>> free allocation units
  153.  50 ALLOC_ALL=leek(BUFFER+3) : rem >>> total allocation units
  154.  60 ALLOC_SECS=leek(BUFFER+7) : rem >>> sectors / allocation unit
  155.  70 SEC_SIZE=leek(buffer+11) : rem >>> sector size in bytes
  156.  80 rem >>> calculate the free bytes on the disc
  157.  90 BYTES_FREE=ALLOC_FREE*ALLOC_SECS*SEC_SIZE
  158. 100 rem >>> calculate capacity of disc
  159. 110 BYTES_ALL=ALLOC_ALL*ALLOC_SECS*SEC_SIZE
  160. 120 rem >>> calculate bytes used
  161. 130 BYTES_USED=BYTES_ALL-BYTES_FREE
  162. 140 rem >>> now print it out
  163. 150 print "Total capacity of disc  =";BYTES_ALL;" bytes"
  164. 160 print "Free capacity of disc   =";BYTES_FREE;" bytes"
  165. 170 print "Bytes used on this disc =";BYTES_USED;" bytes"
  166.  
  167.      And that, as they say, is that.  Simple isn't it?
  168.  
  169.      Now for something a little harder, a disc verifier.  Again you'll 
  170.      find a much cleaner version of all this on the cover disc in  the 
  171.      file  'VERIFY.ACB'.   That's right,  another one to be run as  an 
  172.      accessory.
  173.  
  174.      To  get  a disc verifier to work we need two  XBIOS  trap  calls, 
  175.      being  those to read a disc sector and to verify a  disc  sector.  
  176.      These are function numbers 8 and 19 respectively.
  177.  
  178.      To  verify the sectors on a disc we first have to know  how  that 
  179.      disc has been formatted,  and we can find this out by reading the 
  180.      boot sector on the disc in question.  To do this we need a buffer 
  181.      that is at least 512 bytes long (make it longer to be on the safe 
  182.      side), the address of which is passed to the routine.
  183.  
  184.      To  read the boot sector from the disc we need to read  track  0, 
  185.      sector  1 on side 0 of the disc into the buffer,  and  then  take 
  186.      certain  information out of the buffer.   To read the  sector  we 
  187.      use:
  188.  
  189. trap 14,8,.l BUFFER,.l 0,.w dr,.w sect,.w tr,.w side,.w count
  190.  
  191.      where dr is the drive being accessed, sect should be 1 for sector 
  192.      1,  tr should be 1 for track 1,  side should be 0 for side 0  and 
  193.      count  should be 1 to read just one sector.   The proper  command 
  194.      should read:
  195.  
  196. trap14,8,.l BUFFER,.l 0,.l dr,.w 1,.w 0,.w 0,.w 1
  197.  
  198.      Having got the boot sector into the buffer we can take out of  it 
  199.      the  information we need being the number of sides on  the  disc, 
  200.      number of sectors per track and the number of tracks on the disc.
  201.  
  202.      We'll take a closer look at the boot sector next  month,  suffice 
  203.      to  say  for now that this information is found  by  peeking  the 
  204.      following locations.
  205.  
  206.      sides = deek(buffer+26)
  207.      sectors_per_track = deek(buffer+24)
  208.      To  find  out the number of tracks on the disc we need  to  do  a 
  209.      small calculation in the form of:
  210.      (peek(buffer+19)+peek(buffer+20)*256)/sides/sectors_per_track
  211.  
  212.      Now we know just how the disc has been formatted we can check it.
  213.  
  214.      WARNING!   If you mistakenly set the sector number to 0 you  will 
  215.      cause an internal loop which will mean you'll have to reset  your 
  216.      ST.   This  only happens with track 1.   On other tracks it  will 
  217.      produce  an XBIOS error code which can be found out  by  printing 
  218.      the contents of DREG(0).
  219.  
  220.      If for any reason the sector is not loaded an error code will  be 
  221.      placed in dreg(0), so you should always look at this after making 
  222.      the  trap call.   A value of 0 indicates that all went  well.   A 
  223.      negative value indicates an error.   These error codes and  their 
  224.      meanings are:
  225.  
  226.           0    Ok, no error
  227.          -1    General error (ST unable to determine it!)
  228.          -2    Drive not ready
  229.          -3    Unknown command
  230.          -4    CRC error
  231.          -5    Bad request, invalid command
  232.          -6    Seek error, track not found
  233.          -7    Unknown media - invalid boot sector
  234.          -8    Sector not found
  235.          -9    No paper? (Not sure what this one means)
  236.         -10    Write error
  237.         -11    Read error
  238.         -12    General error
  239.         -13    Disc write protected
  240.         -14    Disc has been changed
  241.         -15    Unknown device
  242.         -16    Bad sector - during verify
  243.         -17    Insert disc - provided drive connected
  244.  
  245.      So having found out the format of the disc we can verify it using 
  246.      the  XBIOS function 19 which verifies a single sector at a  time.  
  247.      This  could be very slow,  but thankfully we can do a track at  a 
  248.      time.
  249.  
  250.      The assembly version of the required trap call is:
  251.  
  252.      MOVE.W    count,-(SP)    * number of sectors to verify
  253.      MOVE.W    side,-(SP)     * disc side
  254.      MOVE.W    track,-(SP)    * track number
  255.      MOVE.W    sector,-(SP)   * sector number
  256.      MOVE.W    drive,-(SP)    * the disc drive
  257.      CLR.L     -(SP)          * a dummy that must be 0
  258.      MOVE.L    buffer,-(SP)   * address of the buffer
  259.      MOVE.W    #19,-(SP)      * the function number
  260.      TRAP      #14            * do it
  261.      ADD.L     16,sp          * tidy up the stack
  262.  
  263.      buffer    ds.b 10240     * the buffer (10K)
  264.  
  265.      The STOS version would read:
  266.  
  267. trap 14,19,.l buffer,.l 0,.w dr,.w sect,.w tr,.w side,.w count
  268.  
  269.      where buffer is the start address of a previously reserved memory 
  270.      bank,  dr  is the required drive,  sect is the sector (to read  a 
  271.      whole track as we are doing this MUST be 1), tr the track number, 
  272.      side the disc side and count the number of sectors to verify.
  273.  
  274.      Now we know how to do it, let's put it into action.
  275.  
  276.  10 rem >>> set up the buffer we need
  277.  20 reserve as work 10,10240 : rem >>> this is 10K
  278.  30 Input "Drive to verify";DR
  279.  40 rem >>> test to see if that drive is connected
  280.  50 D=drvmap : if btst(DR,D)=0 then 10
  281.  60 rem >>> now read the boot sector
  282.  70 BUFFER=start(10)
  283.  80 trap 14,8,.l BUFFER,.l 0,.w DR,.w 1,.w 0,.w 0,.w 1
  284.  90 rem >> got it - get the info we need
  285. 100 SECTS=deek(BUFFER+24) : rem >>> sectors per track
  286. 110 SIDES=deek(BUFFER+26) : rem >>> number of sides on disc
  287. 120 ALL_SECTS=peek(BUFFER+19)+peek(BUFFER+20)*256
  288. 130 TRACKS=ALL_SECTS/SIDES/SECTS : rem >>> tracks on disc
  289. 140 rem >>> got it - now verify
  290. 150 TR=0 : repeat : rem >>> start at track 0
  291. 160 SI=0 : repeat : rem >>> start on side 0
  292. 170 rem >>> verify a track
  293. 180 trap 14,19,.l BUFFER,.l 0,.w DR,.w 1,.w TR,.w SI,.w SECTS
  294. 190 rem >>> check for error
  295. 200 ERR=dreg(0)
  296. 210 inc SI : rem >>> next side (if we can)
  297. 220 rem >>> exit loop if done all sides or error occurred
  298. 230 until SI>SIDES or ERR<>0
  299. 240 rem >>> next track
  300. 250 inc TR
  301. 260 rem >>> exit if done all tracks or error occurred
  302. 270 until TR=TRACKS or ERR<>0
  303. 280 if ERR<>0 then boom: print "Disc error - verify aborted"
  304.  
  305.      Note that in line 270 the loop is exited when we reach the number 
  306.      we calculated earlier.   This is because tracks are numbered from 
  307.      0,  and  any  attempt  to read beyond the end of  the  disc  will 
  308.      produce  an  error (and a nasty click from your drive -  but  not 
  309.      harmful,  I hope!).  An eighty track disc has the tracks numbered 
  310.      0 to 79.
  311.  
  312.      It really is a simple as that.
  313.  
  314.      Next month we'll take a close look at the disc format options  as 
  315.      here we can expand the capacity of your discs (or shrink them  if 
  316.      that's  what  you  want),  and produce some  really  clever  disc 
  317.      formats, even some that only you can read!
  318.  
  319.      Till  then,  get hold of a book on machine code  programming  and 
  320.      have a go at playing around with the trap function yourself.
  321.  
  322.