🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.modula2
Article #3249

Re: Reading Floppies.

#3249
From: Torbjørn Sund
Date: Tue, 06 Feb 1996 11:12
154 lines
4669 bytes
In <1996Feb1.125721.18589@ucl.ac.uk>, zcaccau@cs.ucl.ac.uk (Chris Austin) writes:
>
>In modula-2 is there any way that you can determine whether a floppy drive
>currently contains a disk and whether it is correctly formatted,  (i.e.
>whether the drive is readable), without getting the DOS abort, retry or
>ignore message.  I would like this to work with CD's, IOMEGA ZipDrives,
>etc... as well.

Here's an extract of my low-level BIOS and diskette access code.
All in Modula-2 (sort of), no assembler.
Note I have extracted only relevant portions, 
complain to me if I missed something out.
Written for Topspeed M2, but all the non-standard constructs 
have similar counterparts in the other DOS compilers.
(and I've seen most under DOS).

The idea of reading from the diskette to detect if it is present
is taken from a fast multitasking diskette copier supplied
in source with the full JPI M2 distribution. The code is mine
so there should be no copyright problems, but credit to 
JPI anyway.

Hope this helps.

Cut here:
- - - - - -
DEFINITION MODULE BIOSFun;

CONST
  MaxBytesInSector = 1024;

(* following are direct mappings from BIOS functions *)

PROCEDURE ResetDisk( DrvNo: SHORTCARD): SHORTCARD;
PROCEDURE ReadSectors( DrvNo: SHORTCARD;
                       VAR Buffer: ARRAY OF SHORTCARD; VAR NoSec: SHORTCARD;
                       HedNo, CylNo, SecNo: SHORTCARD): SHORTCARD;

END BIOSFun.

-- and here --

IMPLEMENTATION MODULE BIOSFun;

(* Interrupt 13H, chosen functions for diskett *)

IMPORT SYSTEM, Lib;
(*%T _XTD *) (* if compiled with extended (protected) memory model *)
  IMPORT TSXLIB;
(*%E *)

CONST Int13 = 013H;

(* function 0 *)
PROCEDURE ResetDisk( DrvNo: SHORTCARD): SHORTCARD;
  VAR
    r: SYSTEM.Registers;
  BEGIN
    r.AH := 0; r.DL := DrvNo;
    Lib.Intr( r, Int13);
    RETURN r.AH;
  END ResetDisk;

(* function 02 *)
PROCEDURE ReadSectors( DrvNo: SHORTCARD;
                       VAR Buffer: ARRAY OF SHORTCARD; VAR NoSec: SHORTCARD;
                       HedNo, CylNo, SecNo: SHORTCARD): SHORTCARD;
  VAR
    r: SYSTEM.Registers;
  BEGIN
    WITH r DO
      AH := 2;
      DL := DrvNo;
      AL := NoSec;
      CH := CylNo;
      CL := SecNo;
      DH := HedNo;
      ES := Seg(Buffer);
      BX := Ofs(Buffer);
      Lib.Intr( r, Int13);
      NoSec := AL;
      RETURN AH;
    END;
  END ReadSectors;


BEGIN
(*%T _XTD *)
  TSXLIB.InitInt13();
(*%E *)

END BIOSFun.

---- and here ----

DEFINITION MODULE Diskett;

(* Utility functions for diskette *)
(* Drive number should be 0 and 1 for A: and B: 
    if memory serves me right, or maybe it's 1 and 2 
*)

PROCEDURE DiskIsPresent( DrvNo: SHORTCARD): BOOLEAN;
PROCEDURE Wait4DiskChange( DrvNo: SHORTCARD);

END Diskett.

--- and here ---

IMPLEMENTATION MODULE Diskett;

IMPORT Lib, BIOSFun;

VAR
  DummyBuffer: ARRAY [0 .. BIOSFun.MaxBytesInSector-1] OF SHORTCARD;

PROCEDURE DiskIsPresent( DrvNo: SHORTCARD): BOOLEAN;
  VAR
    SecCnt,
    result : SHORTCARD;
  BEGIN
    IF BIOSFun.ResetDisk( DrvNo) # 0 THEN RETURN FALSE; END;
    SecCnt := 1;
    result := BIOSFun.ReadSectors( DrvNo, DummyBuffer, SecCnt, 0, 0, 1);
    (* yeah, I know, the result codes below should have been changed
        into symbolic constants instead of magic numbers *)
    RETURN (result = 0) OR (result = 2) OR (result = 3) OR (result = 4)
        OR (result = 6) OR (result = 8) OR (result = 9) OR (result = 10H);
  END DiskIsPresent;

PROCEDURE Wait4DiskChange( DrvNo: SHORTCARD);
  VAR
    SecCnt,
    res : SHORTCARD;
  BEGIN
    (* first wait for diskette to be removed *)
    REPEAT
      Lib.Delay(750);
      SecCnt := 1;
      res := BIOSFun.ReadSectors( DrvNo, DummyBuffer, SecCnt, 0, 0, 1);
    UNTIL (res=6);
    (* then wait until a new one is present *)
    WHILE NOT DiskIsPresent( DrvNo) DO Lib.Delay(100); END;
  END Wait4DiskChange;


END Diskett.

---------- cut here

Torbjørn Sund                     	Telenor R&D
Tel (+47) 77 61 27 87           	Pb 1156, Strandgt 9
Fax (+47) 77 61 27 02           	N-9001 Tromsø
torbjorn.sund@fou.telenor.no    	Norway
Technical Details
Message-ID: <4f7d26$bmh@nntp.nta.no>
Path: arc1-ca.pugleaf.net!nntp.nta.no!usenet
References: <1996Feb1.125721.18589@ucl.ac.uk>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!nntp.nta.no!usenet
From: torbjorn.sund@fou.telenor.no (Torbjørn Sund)
Newsgroups: comp.lang.modula2
Subject: Re: Reading Floppies.
Date: 6 Feb 1996 11:12:06 GMT
Organization: Telenor R&D, Tromsø, Norway
Distribution: world
Message-ID: <4f7d26$bmh@nntp.nta.no>
References: <1996Feb1.125721.18589@ucl.ac.uk>
Reply-To: torbjorn.sund@fou.telenor.no (Torbjørn Sund)
NNTP-Posting-Host: grim.tft.tele.no
X-Newsreader: IBM NewsReader/2 v1.9d - NLS