Contributor: JON JASIUNAS { From: JON JASIUNAS Subj: Share Multi-tasking } {************************** * SHARE.PAS v1.0 * * * * General purpose file * * sharing routines * ************************** 1992-93 HyperDrive Software Released into the public domain.} {$S-,R-,D-} {$IFOPT O+} {$F+} {$ENDIF} unit Share; {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\} interface {/////////////////////////////////////////////////////////////////////////////} const MaxLockRetries : Byte = 10; NormalMode = 02ドル; { ---- 0010 } ReadOnly = 00ドル; { ---- 0000 } WriteOnly = 01ドル; { ---- 0001 } ReadWrite = 02ドル; { ---- 0010 } DenyAll = 10ドル; { 0001 ---- } DenyWrite = 20ドル; { 0010 ---- } DenyRead = 30ドル; { 0011 ---- } DenyNone = 40ドル; { 0100 ---- } NoInherit = 70ドル; { 1000 ---- } type Taskers = (NoTasker, DesqView, DoubleDOS, Windows, OS2, NetWare); var MultiTasking: Boolean; MultiTasker : Taskers; VideoSeg : Word; VideoOfs : Word; procedure SetFileMode(Mode: Word); {- Set filemode for typed/untyped files } procedure ResetFileMode; {- Reset filemode to ReadWrite (02h) } procedure LockFile(var F); {- Lock file F } procedure UnLockFile(var F); {- Unlock file F } procedure LockBytes(var F; Start, Bytes: LongInt); {- Lock Bytes bytes of file F, starting with Start } procedure UnLockBytes(var F; Start, Bytes: LongInt); {- Unlock Bytes bytes of file F, starting with Start } procedure LockRecords(var F; Start, Records: LongInt); {- Lock Records records of file F, starting with Start } procedure UnLockRecords(var F; Start, Records: LongInt); {- Unlock Records records of file F, starting with Start } function TimeOut: Boolean; {- Check for LockRetry timeout } procedure TimeOutReset; {- Reset internal LockRetry counter } function InDos: Boolean; {- Is DOS busy? } procedure GiveTimeSlice; {- Give up remaining CPU time slice } procedure BeginCrit; {- Enter critical region } procedure EndCrit; {- End critical region } {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\} implementation {/////////////////////////////////////////////////////////////////////////////} uses Dos; var InDosFlag: ^Word; LockRetry: Byte; {=============================================================================} procedure FLock(Handle: Word; Pos, Len: LongInt); Inline( $B8/00ドル/5ドルC/ { mov AX,5ドルC00 ;DOS FLOCK, Lock subfunction} 8ドルB/5ドルE/04ドル/ { mov BX,[BP + 04] ;Place file handle in Bx register} $C4/56ドル/06ドル/ { les DX,[BP + 06] ;Load position in ES:DX} 8ドルC/$C1/ { mov CX,ES ;Move ES pointer to CX register} $C4/7ドルE/08ドル/ { les DI,[BP + 08] ;Load length in ES:DI} 8ドルC/$C6/ { mov SI,ES ;Move ES pointer to SI register} $CD/21ドル); { int 21ドル ;Call DOS} {-----------------------------------------------------------------------------} procedure FUnlock(Handle: Word; Pos, Len: LongInt); Inline( $B8/01ドル/5ドルC/ { mov AX,5ドルC01 ;DOS FLOCK, Unlock subfunction} 8ドルB/5ドルE/04ドル/ { mov BX,[BP + 04] ;Place file handle in Bx register} $C4/56ドル/06ドル/ { les DX,[BP + 06] ;Load position in ES:DX} 8ドルC/$C1/ { mov CX,ES ;Move ES pointer to CX register} $C4/7ドルE/08ドル/ { les DI,[BP + 08] ;Load length in ES:DI} 8ドルC/$C6/ { mov SI,ES ;Move ES pointer to SI register} $CD/21ドル); { int 21ドル ;Call DOS} {=============================================================================} procedure SetFileMode(Mode: Word); begin FileMode := Mode; end; { SetFileMode } {-----------------------------------------------------------------------------} procedure ResetFileMode; begin FileMode := NormalMode; end; { ResetFileMode } {-----------------------------------------------------------------------------} procedure LockFile(var F); begin If not MultiTasking then Exit; While InDos do GiveTimeSlice; FLock(FileRec(F).Handle, 0, FileSize(File(F))); end; { LockFile } {-----------------------------------------------------------------------------} procedure UnLockFile(var F); begin If not MultiTasking then Exit; While InDos do GiveTimeSlice; FLock(FileRec(F).Handle, 0, FileSize(File(F))); end; { UnLockFile } {-----------------------------------------------------------------------------} procedure LockBytes(var F; Start, Bytes: LongInt); begin If not MultiTasking then Exit; While InDos do GiveTimeSlice; FLock(FileRec(F).Handle, Start, Bytes); end; { LockBytes } {-----------------------------------------------------------------------------} procedure UnLockBytes(var F; Start, Bytes: LongInt); begin If not MultiTasking then Exit; While InDos do GiveTimeSlice; FLock(FileRec(F).Handle, Start, Bytes); end; { UnLockBytes } {-----------------------------------------------------------------------------} procedure LockRecords(var F; Start, Records: LongInt); begin If not MultiTasking then Exit; While InDos do GiveTimeSlice; FLock(FileRec(F).Handle, Start * FileRec(F).RecSize, Records * FileRec(F).Rec end; { LockBytes } {-----------------------------------------------------------------------------} procedure UnLockRecords(var F; Start, Records: LongInt); begin If not MultiTasking then Exit; While InDos do GiveTimeSlice; FLock(FileRec(F).Handle, Start * FileRec(F).RecSize, Records * FileRec(F).Rec end; { UnLockBytes } {-----------------------------------------------------------------------------} function TimeOut: Boolean; begin GiveTimeSlice; TimeOut := True; If MultiTasking and (LockRetry < MaxLockRetries) then begin TimeOut := False; Inc(LockRetry); end; { If } end; { TimeOut } {-----------------------------------------------------------------------------} procedure TimeOutReset; begin LockRetry := 0; end; { TimeOutReset } {-----------------------------------------------------------------------------} function InDos: Boolean; begin { InDos } InDos := InDosFlag^> 0; end; { InDos } {-----------------------------------------------------------------------------} procedure GiveTimeSlice; ASSEMBLER; asm { GiveTimeSlice } cmp MultiTasker, DesqView je @DVwait cmp MultiTasker, DoubleDOS je @DoubleDOSwait cmp MultiTasker, Windows je @WinOS2wait cmp MultiTasker, OS2 je @WinOS2wait cmp MultiTasker, NetWare je @Netwarewait @Doswait: int 28ドル jmp @WaitDone @DVwait: mov AX,1000ドル int 15ドル jmp @WaitDone @DoubleDOSwait: mov AX,$EE01 int 21ドル jmp @WaitDone @WinOS2wait: mov AX,1680ドル int 2ドルF jmp @WaitDone @Netwarewait: mov BX,000ドルA int 7ドルA jmp @WaitDone @WaitDone: end; { TimeSlice } {----------------------------------------------------------------------------} procedure BeginCrit; ASSEMBLER; asm { BeginCrit } cmp MultiTasker, DesqView je @DVCrit cmp MultiTasker, DoubleDOS je @DoubleDOSCrit cmp MultiTasker, Windows je @WinCrit jmp @EndCrit @DVCrit: mov AX,101ドルB int 15ドル jmp @EndCrit @DoubleDOSCrit: mov AX,$EA00 int 21ドル jmp @EndCrit @WinCrit: mov AX,1681ドル int 2ドルF jmp @EndCrit @EndCrit: end; { BeginCrit } {----------------------------------------------------------------------------} procedure EndCrit; ASSEMBLER; asm { EndCrit } cmp MultiTasker, DesqView je @DVCrit cmp MultiTasker, DoubleDOS je @DoubleDOSCrit cmp MultiTasker, Windows je @WinCrit jmp @EndCrit @DVCrit: mov AX,101ドルC int 15ドル jmp @EndCrit @DoubleDOSCrit: mov AX,$EB00 int 21ドル jmp @EndCrit @WinCrit: mov AX,1682ドル int 2ドルF jmp @EndCrit @EndCrit: end; { EndCrit } {============================================================================} begin { Share } {- Init } LockRetry:= 0; asm @CheckDV: mov AX, 2ドルB01 mov CX, 4445ドル mov DX, 5351ドル int 21ドル cmp AL, $FF je @CheckDoubleDOS mov MultiTasker, DesqView jmp @CheckDone @CheckDoubleDOS: mov AX, $E400 int 21ドル cmp AL, 00ドル je @CheckWindows mov MultiTasker, DoubleDOS jmp @CheckDone @CheckWindows: mov AX, 1600ドル int 2ドルF cmp AL, 00ドル je @CheckOS2 cmp AL, 80ドル je @CheckOS2 mov MultiTasker, Windows jmp @CheckDone @CheckOS2: mov AX, 3001ドル int 21ドル cmp AL, 0ドルA je @InOS2 cmp AL, 14ドル jne @CheckNetware @InOS2: mov MultiTasker, OS2 jmp @CheckDone @CheckNetware: mov AX,7ドルA00 int 2ドルF cmp AL,$FF jne @NoTasker mov MultiTasker, NetWare jmp @CheckDone @NoTasker: mov MultiTasker, NoTasker @CheckDone: {-Set MultiTasking } cmp MultiTasker, NoTasker mov VideoSeg, $B800 mov VideoOfs, 0000ドル je @NoMultiTasker mov MultiTasking, 01ドル {-Get video address } mov AH, $FE les DI, [$B8000000] int 10ドル mov VideoSeg, ES mov VideoOfs, DI jmp @Done @NoMultiTasker: mov MultiTasking, 00ドル @Done: {-Get InDos flag } mov AH, 34ドル int 21ドル mov WORD PTR InDosFlag, BX mov WORD PTR InDosFlag + 2, ES end; { asm } end. { Share }