* contrib/hbnf/acctyear.prg
* contrib/hbnf/byteneg.prg
* contrib/hbnf/isshare.prg
* contrib/hbnf/sinkey.prg
* contrib/hbnf/kspeed.c
* contrib/hbnf/prtscr.c
* contrib/hbnf/descendn.c
* contrib/hbnf/peek.c
* contrib/hbnf/scancode.prg
* contrib/hbnf/vidmode.prg
* contrib/hbnf/nwsem.prg
* contrib/hbnf/acctadj.prg
* contrib/hbnf/week.prg
* contrib/hbnf/vidcur.prg
* contrib/hbnf/iamidle.c
* contrib/hbnf/miltime.prg
* contrib/hbnf/prtesc.prg
* contrib/hbnf/acctmnth.prg
* contrib/hbnf/proper.c
* contrib/hbnf/savearr.prg
* contrib/hbnf/madd.prg
* contrib/hbnf/rand1.prg
* contrib/hbnf/dispmsg.prg
* contrib/hbnf/fttext.c
* contrib/hbnf/mouse1.prg
* contrib/hbnf/settime.prg
* contrib/hbnf/page.prg
* contrib/hbnf/restsets.prg
* contrib/hbnf/byt2bit.prg
* contrib/hbnf/setkeys.c
* contrib/hbnf/month.prg
* contrib/hbnf/byt2hex.prg
* contrib/hbnf/findith.prg
* contrib/hbnf/at2.prg
* contrib/hbnf/acctweek.prg
* contrib/hbnf/dispc.c
* contrib/hbnf/gcd.prg
* contrib/hbnf/pegs.prg
* contrib/hbnf/min2dhm.prg
* contrib/hbnf/acctqtr.prg
* contrib/hbnf/numlock.c
* contrib/hbnf/dosver.prg
* contrib/hbnf/nooccur.prg
* contrib/hbnf/dayofyr.prg
* contrib/hbnf/metaph.prg
* contrib/hbnf/ontick.c
* contrib/hbnf/menu1.prg
* contrib/hbnf/byteand.prg
* contrib/hbnf/sqzn.prg
* contrib/hbnf/bytexor.prg
* contrib/hbnf/ftidle.c
* contrib/hbnf/workdays.prg
* contrib/hbnf/byteor.prg
* contrib/hbnf/asum.prg
* contrib/hbnf/shift.c
* contrib/hbnf/sleep.prg
* contrib/hbnf/wda.prg
* contrib/hbnf/woy.prg
* contrib/hbnf/aavg.prg
* contrib/hbnf/any2any.prg
* contrib/hbnf/origin.c
* contrib/hbnf/mouse.c
* contrib/hbnf/chdir.c
* contrib/hbnf/adessort.prg
* contrib/hbnf/setdate.prg
* contrib/hbnf/netpv.prg
* contrib/hbnf/amedian.prg
* contrib/hbnf/blink.prg
* contrib/hbnf/stod.c
* contrib/hbnf/vertmenu.prg
* contrib/hbnf/linked.prg
* contrib/hbnf/qtr.prg
* contrib/hbnf/aredit.prg
* contrib/hbnf/n2color.c
* contrib/hbnf/alt.c
* contrib/hbnf/xbox.prg
* contrib/hbnf/ftround.prg
* contrib/hbnf/hex2dec.prg
* contrib/hbnf/getver.c
* contrib/hbnf/nwuid.prg
* contrib/hbnf/dectobin.prg
* contrib/hbnf/aemaxlen.prg
* contrib/hbnf/bitset.prg
* contrib/hbnf/nwlstat.prg
* contrib/hbnf/invclr.prg
* contrib/hbnf/ctrl.c
* contrib/hbnf/popadder.prg
* contrib/hbnf/lastday.prg
* contrib/hbnf/tempfile.prg
* contrib/hbnf/diskfunc.prg
* contrib/hbnf/scregion.prg
* contrib/hbnf/d2e.prg
* contrib/hbnf/mouse2.prg
* contrib/hbnf/ftisprn.c
* contrib/hbnf/pickday.prg
* contrib/hbnf/firstday.prg
* contrib/hbnf/daytobow.prg
* contrib/hbnf/anomatch.prg
* contrib/hbnf/menutonf.prg
* contrib/hbnf/ftattr.c
* contrib/hbnf/pvid.prg
* contrib/hbnf/isbiton.prg
* contrib/hbnf/color2n.c
* contrib/hbnf/isbit.prg
* contrib/hbnf/datecnfg.prg
* contrib/hbnf/cntryset.prg
* contrib/hbnf/putkey.c
* contrib/hbnf/getenvrn.c
* contrib/hbnf/easter.prg
* contrib/hbnf/bytenot.prg
* contrib/hbnf/ntow.prg
* contrib/hbnf/aeminlen.prg
* contrib/hbnf/poke.c
* contrib/hbnf/floptst.prg
* contrib/hbnf/pchr.prg
* contrib/hbnf/savesets.prg
* contrib/hbnf/tbwhile.prg
* contrib/hbnf/mkdir.c
* contrib/hbnf/year.prg
* contrib/hbnf/caplock.c
* contrib/hbnf/rmdir.c
* contrib/hbnf/calendar.prg
* contrib/hbnf/e2d.prg
* contrib/hbnf/elapsed.prg
* contrib/hbnf/sysmem.prg
* contrib/hbnf/bitclr.prg
* contrib/hbnf/eltime.prg
* contrib/hbnf/aading.prg
* contrib/hbnf/dfile.prg
* contrib/hbnf/elapmil.prg
* contrib/hbnf/setlastk.c
* contrib/hbnf/pending.prg
* contrib/hbnf/clrsel.prg
- Stripped NFDOC/HBDOC from source code.
237 lines
7.3 KiB
Plaintext
237 lines
7.3 KiB
Plaintext
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* File......: floptst.prg
|
|
* Author....: Gary Smith
|
|
* CIS ID....: 70714,3015
|
|
*
|
|
* This work is based on an original work by Joseph LaCour that
|
|
* was placed in the public domain. This work is placed in the
|
|
* public domain.
|
|
*
|
|
* ACKNOWLEDGEMENTS:
|
|
*
|
|
* PAOLO RAMOZZI FOR HIS WORK IN DBDCHECK FOR SHOWING HOW TO
|
|
* USE INT 13H.
|
|
*
|
|
*
|
|
* Modification history:
|
|
* ---------------------
|
|
*
|
|
* Rev 1.4 05 May 1995 03:05:00 TED
|
|
* Gary Smith ported ASM source to Clipper.
|
|
*
|
|
* Rev 1.3 23 Sep 1991 14:56:42 GLENN
|
|
* Bug reports from Craig Austin, James Finnal, and Ted Means. Line 128
|
|
* had MOV FDRIVE,AL which should have been MOV FDRIVE,BL. This caused the
|
|
* function to erroneously use the last drive available instead of the one
|
|
* specified by the calling process.
|
|
*
|
|
* Rev 1.2 15 Aug 1991 23:07:48 GLENN
|
|
* Forest Belt proofread/edited/cleaned up doc
|
|
*
|
|
* Rev 1.1 11 May 1991 00:21:42 GLENN
|
|
* File header changed to conform to Toolkit standard.
|
|
*/
|
|
|
|
*/
|
|
|
|
#include "ftint86.ch"
|
|
|
|
#DEFINE ERR_WRONG_PARAMETERS -1
|
|
#DEFINE ERR_NO_ERROR 0
|
|
#DEFINE ERR_DRIVE_NOT_READY 1
|
|
#DEFINE ERR_UNFORMATTED 2
|
|
#DEFINE ERR_WRITE_PROTECTED 3
|
|
#DEFINE ERR_UNKNOWN 4
|
|
|
|
#IFDEF FT_TEST
|
|
#define CR_LF chr(13)+chr(10)
|
|
|
|
PROCEDURE MAIN( ;
|
|
cArg1 ;
|
|
)
|
|
LOCAL nErrCode
|
|
|
|
IF ValType( cArg1 ) == "C"
|
|
nErrCode := FT_FLOPTST( Asc( Upper(cArg1) ) - Asc( "A" ) )
|
|
OutStd( "Return Code is "+LTrim(Str(nErrCode)) +CR_LF )
|
|
ELSE
|
|
OutStd( "Usage: floptst cDrive"+CR_LF+" where cDrive is 'A' or 'B' etc..."+CR_LF )
|
|
ENDIF
|
|
|
|
RETURN
|
|
|
|
#ENDIF
|
|
|
|
FUNCTION FT_FLOPTST( ; // error code defined by ERR_*
|
|
nDriveNum_i ; // letter of floppy drive.
|
|
)
|
|
LOCAL cBuffer
|
|
LOCAL nErrorCode
|
|
LOCAL nRetCode
|
|
|
|
nRetCode := ERR_WRONG_PARAMETERS
|
|
IF ValType( nDriveNum_i ) == "N"
|
|
|
|
IF _GetDisketteNum( nDriveNum_i )
|
|
_ResetDisketteSystem()
|
|
_ReadBootSector( nDriveNum_i, @cBuffer, @nErrorCode )
|
|
|
|
IF nErrorCode == 0
|
|
_WriteBootSector( nDriveNum_i, cBuffer, @nErrorCode )
|
|
DO CASE
|
|
CASE nErrorCode == 0
|
|
nRetCode := ERR_NO_ERROR
|
|
CASE nErrorCode == 3
|
|
nRetCode := ERR_WRITE_PROTECTED
|
|
OTHERWISE
|
|
nRetCode := ERR_UNKNOWN
|
|
ENDCASE
|
|
ELSE
|
|
DO CASE
|
|
CASE nErrorCode == 128 // 80h
|
|
nRetCode := ERR_DRIVE_NOT_READY
|
|
CASE nErrorCode == 2
|
|
nRetCode := ERR_UNFORMATTED
|
|
OTHERWISE
|
|
nRetCode := ERR_UNKNOWN
|
|
END CASE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN nRetCode
|
|
|
|
#define BITS_6AND7 192 // value of byte when bits 6&7 are high
|
|
|
|
STATIC FUNCTION _GetDisketteNum( ; // returns false if no floppy drive installed or nDrive_i is invalid
|
|
nDrive_i ; // drive number to query status
|
|
)
|
|
LOCAL aRegs[INT86_MAX_REGS]
|
|
LOCAL lRetCode
|
|
LOCAL nByte
|
|
LOCAL nDriveCount
|
|
|
|
// ASSERT 0 <= nDrive_i
|
|
|
|
lRetCode := .F.
|
|
IF FT_INT86( 1*16+1, aRegs ) // INT for equipment determination
|
|
nByte := lowbyte( aRegs[AX] )
|
|
// bit 0 indicates floppy drive installed
|
|
IF Int( nByte / 2 ) * 2 != nByte // is it odd i.e. is bit 0 set??
|
|
// bits 6 & 7 indicate number of floppies installed upto 4.
|
|
nDriveCount := Asc( FT_BYTEAND( Chr(nByte), chr(BITS_6AND7) ) )
|
|
IF nDriveCount >= nDrive_i
|
|
lRetCode := .T.
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN lRetCode
|
|
|
|
STATIC PROCEDURE _ResetDisketteSystem()
|
|
LOCAL aRegs[INT86_MAX_REGS]
|
|
|
|
aRegs[AX] := 0
|
|
|
|
FT_INT86( 1*16+3, aRegs )
|
|
|
|
RETURN
|
|
|
|
#define BUFFER_SIZEOF_SECTOR 512+1
|
|
|
|
STATIC FUNCTION _ReadBootSector( ;
|
|
nDriveNum, ;
|
|
cBuffer_o, ;
|
|
nErrCode_o ;
|
|
)
|
|
// call BIOS INT 13 for sector read
|
|
LOCAL aRegs[INT86_MAX_REGS]
|
|
LOCAL cBuffer := Space( BUFFER_SIZEOF_SECTOR )
|
|
LOCAL lSuccess
|
|
LOCAL nErrorCode
|
|
LOCAL lCarryFlag
|
|
|
|
aRegs[DX] := nDriveNum // DH = 0 Head 0, DL = drive number
|
|
aRegs[CX] := 1 // CH = 0 track 0, CL=1 sector 1
|
|
aRegs[BX] := REG_ES // buffer in ES:BX
|
|
aRegs[ES] := cBuffer
|
|
aRegs[AX] := makehi(2)+1 // AH = 02 read , AL=1 read one sector
|
|
|
|
lSuccess := _CallInt13hRetry( aRegs, @lCarryFlag, @nErrorCode )
|
|
|
|
cBuffer_o := aRegs[ES]
|
|
nErrCode_o := nErrorCode
|
|
|
|
RETURN lSuccess
|
|
|
|
STATIC FUNCTION _WriteBootSector( ;
|
|
nDriveNum, ;
|
|
cBuffer_i, ;
|
|
nErrCode_o ;
|
|
)
|
|
// call BIOS INT 13 for sector write
|
|
LOCAL aRegs[INT86_MAX_REGS]
|
|
LOCAL lSuccess
|
|
LOCAL nErrorCode
|
|
LOCAL lCarryFlag
|
|
|
|
aRegs[DX] := nDriveNum // DH = 0 Head 0 , DL = drive number
|
|
aRegs[CX] := 1 // CH = 0 track 0, CL=1 sector 1
|
|
aRegs[BX] := REG_ES // buffer in ES:BX
|
|
aRegs[ES] := cBuffer_i
|
|
aRegs[AX] := makehi(3)+1 // AH = 03 write , AL=1 read one sector
|
|
|
|
lSuccess := _CallInt13hRetry( aRegs, @lCarryFlag, @nErrorCode )
|
|
|
|
nErrCode_o := nErrorCode
|
|
|
|
RETURN lSuccess
|
|
|
|
STATIC FUNCTION _CallInt13hRetry( ; // logical: did the interrupt succeed?
|
|
aRegs_io, ; // registers values for INT 13h
|
|
lCarrySet_o, ; // status of carry flag if return code is true.
|
|
nDriveStatus_o ; // status of drive ( error code )
|
|
)
|
|
LOCAL lCarrySet
|
|
LOCAL aRegisters
|
|
LOCAL lSuccess
|
|
LOCAL nInterrupt_c := 1*16+3 // INT 13h
|
|
LOCAL i
|
|
|
|
lCarrySet := .F.
|
|
aRegisters := AClone( aRegs_io )
|
|
lSuccess := FT_INT86( nInterrupt_c, aRegisters )
|
|
IF lSuccess
|
|
lCarrySet := carrySet( aRegisters[FLAGS] )
|
|
IF lCarrySet
|
|
_ResetDisketteSystem()
|
|
|
|
aRegisters := AClone( aRegs_io )
|
|
FT_INT86( nInterrupt_c, aRegisters )
|
|
lCarrySet := carrySet( aRegisters[FLAGS] )
|
|
IF lCarrySet
|
|
_ResetDisketteSystem()
|
|
|
|
aRegisters := AClone( aRegs_io )
|
|
FT_INT86( nInterrupt_c, aRegisters )
|
|
lCarrySet := carrySet( aRegisters[FLAGS] )
|
|
IF lCarrySet
|
|
_ResetDisketteSystem()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
FOR i := 1 TO INT86_MAX_REGS
|
|
// pass altered register back up
|
|
aRegs_io[i] := aRegisters[i]
|
|
NEXT // i
|
|
lCarrySet_o := lCarrySet
|
|
nDriveStatus_o := highByte( aRegisters[AX] )
|
|
|
|
RETURN lSuccess
|