Disk Input/Output

Yes, every PC has the BIOS to control the disks. Furthermore, DOS has INT 13h. Still, many times you want a high level interface to the disk subsystem. I must have had a sound reason to make DiskIO. But I forgot. Still, here is the source for the definition module:

DEFINITION MODULE DiskIO;

FROM    SYSTEM      IMPORT      ADDRESS;

TYPE    DriveData = RECORD
            DriveType, MaxTrack,
            MaxSector, MaxHead,
            AckUnits                : CARDINAL;
            ParameterTable          : ADDRESS;
        END;


PROCEDURE   DiskReset  (drive : CARDINAL; VAR result : CARDINAL) : BOOLEAN;

    (*  Reset the disk subsystem    *)

PROCEDURE   GetStatus   (drive  : CARDINAL; VAR res : CARDINAL) : BOOLEAN;

    (*  Get the state in which the disk subsystem is since the last operation   *)

PROCEDURE   ReadSectors (drive, head, sector, track, count : CARDINAL;  buffer : ADDRESS;
                                                                    VAR result : CARDINAL) : BOOLEAN;
    (* Read sectors from this disk position into the buffer     *)

PROCEDURE   WriteSectors (drive, head, sector, track, count : CARDINAL; buffer : ADDRESS;
                                                                    VAR result : CARDINAL) : BOOLEAN;
    (*  Write sectors from buffer to this disk position         *)

PROCEDURE   VerifySectors (drive, head, sector, track, count : CARDINAL; buffer : ADDRESS
                                                                    VAR result : CARDINAL) : BOOLEAN;

    (* Verify data written to disk matches original data in buffer  *)

PROCEDURE   GetParams (drive : CARDINAL; VAR  Outcome : DriveData; VAR result  : CARDINAL) : BOOLEAN;

    (*  Read drive parameters for this diskdrive                *)

PROCEDURE   FormatTrack (drive, head, sector, track, count : CARDINAL;  buffer  : ADDRESS
                                                                    VAR result : CARDINAL) : BOOLEAN;
    (* Format a track               *)

END DiskIO.
   
And the implementation module, As you will see, the module heavily relies on the inline assembler of FST Modula-2. As far as I can recollect, the DiskIO module was meant to be used in a floppy disk rescue program.
IMPLEMENTATION MODULE DiskIO;

(*  This is FREE software, as described in the GNU General Public Licences. 
    Therefore it comes WITH THE FULL SOURCES. Please feel free to improve this 
    code when necessary. You OWN this code. I am not Bill Gates.

    I would appreciate that people let in this message when extending this 
    library, as a small tribute to me (for laying the foundation). 

    In case people need extra information, contact me via:

        snail mail: Jan Verhoeven, NL-5012 GH 272
   electronic mail: jan@verhoeven272.fol.nl

    I remain full copyrights to these sources. If you want to send me a small 
    "thanks", please send me a postcard of your hometown to the above shown
    snailmail address. Yes it is in code; the internal code of our national 
    mail deliverer.

    Use this software at your own risk. Please find yourself a GNU GPL if you 
    are in any doubt. I use these functions for all my own software, but there 
    is NO GUARANTEE OF ANY KIND covering it.            *)


FROM    SYSTEM      IMPORT  ASSEMBLER, ADDRESS;


PROCEDURE   DiskReset  (drv : CARDINAL; VAR res : CARDINAL) : BOOLEAN;    (*  Reset the disk subsystem    *)

VAR     tmp     : CARDINAL;
        Flag    : BOOLEAN;

BEGIN
    Flag  := TRUE;
    ASM
        MOV  DL, drv
        MOV  AH, 0
        INT  13H
        JNC  done
        MOV  Flag, 0
        MOV  AL, AH
        MOV  AH, 0
        MOV  tmp, AX
    done:
    END;
    IF  Flag = TRUE  THEN  res := 0  ELSE  res := tmp  END;
    RETURN Flag
END DiskReset;


PROCEDURE   GetStatus   (drv  : CARDINAL; VAR res  : CARDINAL) : BOOLEAN;

VAR     tmp     : CARDINAL;             (*  Get state of disk subsystem since last operation   *)
        Flag    : BOOLEAN;

BEGIN
    Flag := TRUE;
    ASM
        MOV  DL, drv
        MOV  AH, 1
        INT  13H
        JNC  done
        MOV  Flag, 0
        MOV  AL, AH
        MOV  AH, 0
        MOV  tmp, AX
    done:
    END;
    IF  Flag = TRUE  THEN  res := 0  ELSE  res := tmp  END;
    RETURN Flag
END GetStatus;


PROCEDURE   ReadSectors (drv, hd, sctr, trk, cnt : CARDINAL;  buff : ADDRESS; VAR res : CARDINAL) : BOOLEAN;

VAR     Flag    : BOOLEAN;      (*  Read sectors from this disk position into the buffer    *)
        tmp     : CARDINAL;

BEGIN
    Flag    := TRUE;
    ASM
        LES  BX, buff
        MOV  DH, hd
        MOV  DL, drv
        MOV  CH, trk
        MOV  CL, sctr
        MOV  AL, cnt
        MOV  AH, 2
        INT  13H
        JC   L0
        CBW
        MOV  tmp, AX
        JMP  done

    L0: MOV  Flag, 0
        MOV  AL, AH
        MOV  AH, 0
        MOV  tmp, AX
    done:
    END;
    res := tmp;
    RETURN Flag
END ReadSectors;


PROCEDURE   WriteSectors (drv, hd, sctr, trk, cnt : CARDINAL; buff : ADDRESS; VAR res : CARDINAL) : BOOLEAN;

VAR     Flag    : BOOLEAN;          (*  Write sectors from buffer to this disk position     *)
        tmp     : CARDINAL;

BEGIN
    Flag    := TRUE;
    ASM
        LES  BX, buff
        MOV  DH, hd
        MOV  DL, drv
        MOV  CH, trk
        MOV  CL, sctr
        MOV  AL, cnt
        MOV  AH, 3
        INT  13H
        JC   L0
        CBW
        MOV  tmp, AX
        JMP  done

    L0: MOV  Flag, 0
        MOV  AL, AH
        MOV  AH, 0
        MOV  tmp, AX
    done:
    END;
    res := tmp;
    RETURN Flag
END WriteSectors;


PROCEDURE   VerifySectors (drv, hd, sctr, trk, cnt : CARDINAL; buff : ADDRESS;  VAR res : CARDINAL) : BOOLEAN;

VAR     Flag    : BOOLEAN;          (*  Verify data written to disk matches original data in buffer     *)
        tmp     : CARDINAL;

BEGIN
    Flag    := TRUE;
    ASM
        LES  BX, buff
        MOV  DH, hd
        MOV  DL, drv
        MOV  CH, trk
        MOV  CL, sctr
        MOV  AL, cnt
        MOV  AH, 4
        INT  13H
        JC   L0
        CBW
        MOV  tmp, AX
        JMP  done

    L0: MOV  Flag, 0
        MOV  AL, AH
        MOV  AH, 0
        MOV  tmp, AX
    done:
    END;
    res := tmp;
    RETURN Flag
END VerifySectors;


PROCEDURE   GetParams (drv : CARDINAL; VAR  Outcome : DriveData; VAR res  : CARDINAL) : BOOLEAN;

VAR     Flag    : BOOLEAN;          (*  Read drive parameters for this diskdrive    *)
        tmp     : CARDINAL;

BEGIN
    Flag    := TRUE;
    ASM
        MOV  DL, drv
        MOV  AH, 8
        INT  13H
        JNC  GOon

        MOV  Flag, 0
        MOV  AL, AH
        MOV  AH, 0
        MOV  tmp, AX
        JMP  exit

    GOon:
        PUSH ES
        PUSH DI
        LES  DI, Outcome
        MOV  AH, 0
        MOV  AL, BL
        STOSW               (*  Drive type          *)
        MOV  AL, CL
        SHL  AX, 1
        SHL  AX, 1
        MOV  AL, CH
        STOSW               (*  Maximum Track       *)
        MOV  AH, 0
        MOV  AL, CL
        AND  AL, 3FH
        STOSW               (*  Maximum Sector      *)
        MOV  AL, DH
        STOSW               (*  Maximum Head        *)
        MOV  AL, DL
        STOSW               (*  Drives acknowledging consecutively      *)
        POP  AX
        STOSW
        POP  AX
        STOSW               (*  Store pointer to drive parameter table  *)

    exit:
        NOP
    END;
    IF Flag = TRUE THEN  res := 0  ELSE  res := tmp  END;
    RETURN Flag
END GetParams;


PROCEDURE   FormatTrack (drv, hd, sctr, trk, cnt : CARDINAL;  buff  : ADDRESS;  VAR res : CARDINAL) : BOOLEAN;

VAR     Flag    : BOOLEAN;          (*  Format a track      *)
        tmp     : CARDINAL;

BEGIN
    Flag    := TRUE;
    ASM
        LES  BX, buff
        MOV  DH, hd
        MOV  DL, drv
        MOV  CH, trk
        MOV  CL, sctr
        MOV  AL, cnt
        MOV  AH, 5
        INT  13H
        JNC  done

        MOV  Flag, 0
        MOV  AL, AH
        MOV  AH, 0
        MOV  tmp, AX
    done:
    END;
    IF  Flag = TRUE  THEN  res := 0  ELSE  res := tmp  END;
    RETURN Flag
END FormatTrack;

END DiskIO.
   

Page created September 13, 2012 and