'===========================================================================
' Subject: Floppy Disk Image Reader           Date: 06-16-02 (  :  )       
'  Author: Harold Koenig                      Code: QB, PDS                
'  Origin: harkon@shaw.ca                   Packet: DISK.ABC
'===========================================================================
'===========================================================================
' Subject: FLOPPY DIS IMAGE READER            Date: 05-29-02 (10:00:00)   
'  Author: Harold Koenig                      Code: QB            
'  Origin: harkon@shaw.ca                   Packet: DISK.ABC
'===========================================================================

'*******************************************************
'*                                                     *
'*          Floppy Image Reader (FIREAD)               *
'*                                                     *
'* This program was created by Harold Koenig (2002)    *
'*                                                     *
'* You are welcome to use any part of this code for    *
'*  your own purposes, but if you do, please give      *
'*  credit where it's due.                             *
'*                                                     *
'* FIREAD will read a floppy disk and write the image  *
'*  to the filename you specify. The image file is     *
'*  standard as for as image files go, and is          *
'*  compatible with RAWRITE. This is actually a sort   *
'*  of RAREAD clone, without the command line          *
'*  interface                                          *
'*                                                     *
'* The companion to this file is the FIWRITE program   *
'*  which is used to restore the image file created    *
'*  by FIREAD.                                         *
'*                                                     *
'* Somewhere along the way I intend to add the command *
'*  line interface, add some command line help and     *
'*  maybe add a GUI, maybe with VBDOS, do't know yet.  *
'*  I also intend to be able to make SFX image files,  *
'*  this would just eb a function of creating the SFX  *
'*  program, most of the FIWRITE code, and putting     *
'*  it in fron of the image file.                      *
'*                                                     *
'* This program should work to create an image of      *
'*  almost any floppy disk, but it has been tested     *
'*  only with 1.44MB disks and drives.                 *
'*                                                     *
'*                                                     *
'*******************************************************



DEFINT A-Z

'define regtype for interrupt call
  TYPE RegTypeX
     ax AS INTEGER
     bx AS INTEGER
     cx AS INTEGER
     dx AS INTEGER
     BP AS INTEGER
     SI AS INTEGER
     DI AS INTEGER
     flags AS INTEGER
     DS AS INTEGER
     es AS INTEGER
  END TYPE


'declare interrupt sub (in library)
DECLARE SUB interruptx (intnum AS INTEGER, InReg AS RegTypeX, OutReg AS RegTypeX)

'declare subs and functions here
DECLARE SUB dinfo (drive, maxhead, maxsector, maxtrac)
DECLARE SUB dread (drive, Head, track, sector, maxsector, buffer$, flags)
DECLARE SUB dreset (drive)

ON ERROR GOTO ErrorHandler

CLS

INPUT "Enter drive A or B "; drive$
drive$ = LTRIM$(RTRIM$(UCASE$(drive$)))
IF drive$ <> "A" AND drive$ <> "B" THEN
   PRINT "not a valid drive"
   PRINT "enter only the drive letter A or B"
   END
END IF


drive = ASC(drive$) - ASC("A")

dinfo drive, maxhead, maxsector, maxtrac


PRINT "Drive data for "; drive$; ":"
PRINT "maxhead="; maxhead
PRINT "maxsector="; maxsector
PRINT "maxtrack="; maxtrac


'setup memory for buffer
buffersize = maxsector * 512
buffer$ = STRING$(buffersize, 21)


INPUT "Filename to save image to: "; filename$

'this begins the floppydrive read process

OPEN filename$ FOR OUTPUT AS #1

sector = 1
Head = 0

FOR track = 0 TO maxtrac

LOCATE 8, 1
PRINT "Reading Track# "; USING "##"; track;
PRINT "   Head# "; Head;
PRINT "  ";
PRINT USING "###"; ((track / maxtrac) * 100);
PRINT "% Read";


dread drive, Head, track, sector, maxsector, buffer$, flags
'if an error is detected in the read it is recommended to try 3 times
IF flags <> 0 THEN
   dreset drive
   dread drive, Head, track, sector, maxsector, buffer$, flags
      IF flags <> 0 THEN
         dreset drive
         dread drive, Head, track, sector, maxsector, buffer$, flags
            IF flags <> 0 THEN
               dreset drive
               errdesc$ = "Error reading drive " + drive$ + ":"
               GOTO ErrorHandler
               END
            END IF
      END IF
END IF


IF Head = 0 THEN
   Head = 1
   track = track - 1
   ELSE Head = 0
END IF


PRINT #1, buffer$;
NEXT track
CLOSE #1
PRINT ""
PRINT "Use FIWrite to restore diskette image."
PRINT ""
END

ErrorHandler:
  errnum = ERR
  IF errornum = 53 THEN RESUME
  PRINT ""
  PRINT "Error Number "; errnum; ":"; errdesc$
  CLOSE #1
END

SUB dinfo (drive, maxhead, maxsector, maxtrac)

DIM inregs AS RegTypeX, outregs AS RegTypeX

inregs.ax = &H800
inregs.dx = drive

CALL interruptx(&H13, inregs, outregs)


'extract only the DH value_DL contains number of drives
maxhead = (outregs.dx AND &HF00) / &H100

'bits 0-5 are for max sector info
maxsector = outregs.cx AND &H3F

'bits 0-7 CH are the low order info for # of tracks
maxtraclow = (outregs.cx AND &HFF00) / &H100
'bits 6&7 CL are the high order info for # of tracks
'bits need to be shifted left 2 bits for final add to work
maxtrachigh = (outregs.cx AND &HC0) * &H4
maxtrac = maxtrachigh + maxtraclow



END SUB

SUB dread (drive, Head, track, sector, maxsector, buffer$, flags)

DIM inregs AS RegTypeX, outregs AS RegTypeX

bufferseg = VARSEG(buffer$)
bufferadd = SADD(buffer$)

'track information is in both CH bits 0-7 low order
' and CL bits 6-7 high order. This is only an issue
' should the drive have a tack count higher than &HFF
' This is doubtful, however, for the sake of precision
' we'll parse the number and distyribute the components

'this line gets only the low order 8 bits
' we shift these left 8 bits in the inregs.cx= line
tracklow = track AND &HFF
'this line gets the 2 high order bits, and shifts them
' right 2 bits, adding the sector value (1) to this
' leaves bits 0-5 untouched and moves thee 2 bits
' into position 6&7
trackhigh = (track AND &H300) / &H4


inregs.ax = &H200 + maxsector
inregs.bx = bufferadd
'inregs.cx = (track * &H100) + sector
inregs.cx = (tracklow * &H100) + (trackhigh + sector)
inregs.dx = (Head * &H100) + drive
inregs.es = bufferseg
CALL interruptx(&H13, inregs, outregs)

flags = outregs.flags

flags = flags AND &H1


END SUB

SUB dreset (drive)

DIM inregs AS RegTypeX, outregs AS RegTypeX

inregs.ax = &H0
inregs.dx = drive

CALL interruptx(&H13, inregs, outregs)

END SUB

