home *** CD-ROM | disk | FTP | other *** search
- { Super File Manager
-
- SFMVARS.INC
-
- by David Steiner
- 2035 J Apt. 6
- Lincoln, NE
-
- This include file is for declaring the majority of the program's
- global variables, constants and types. Also included are a
- couple of routines that need to come before all of the others,
- and don't fit in the second include file.
-
- }
-
-
- CONST
- version = 'v1.01';
- MaxFiles = 512;
- MinStack = 512; { Set aside to insure against heap/stack collision }
- KiloByte = 1024.0; { Formal definition, maybe you'd rather it was 1000 }
- WindowLen = 17;
- DelChar = #229; { DOS character to signal deleted file }
- NulChar = #000;
- PtrChar = #175; { Pointer character in directory windows }
-
- horzlin = #205; { These characters make up the window }
- vertlin = #179; { borders. }
- int1 = #209;
- int2 = #216;
- int3 = #207;
- corn1 = #213;
- corn2 = #184;
- corn3 = #212;
- corn4 = #190;
- tleft = #198;
- trght = #181;
- lbrk = #219 {#181};
- rbrk = #219 {#198};
-
- Rbit = $01; { These are masks for the bits in the file's }
- Hbit = $02; { attribute byte: read-only, hidden, sys, }
- Sbit = $04; { volume label, directory and archive. }
- Vbit = $08;
- Dbit = $10;
- Abit = $20;
-
- MakeNoise : boolean = true; { Typed constant so Int10 can access flag }
- cursornum : integer = $0607; { Default CGA cursor }
-
-
- TYPE
-
- {
- This 'variant record' allows accessing full and half registers
- without two separate variable declarations.
- }
- Reg_T = record case boolean of
- true : (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : integer);
- false : (AL,AH,BL,BH,CL,CH,DL,DH : byte);
- end;
-
-
- {
- The archaic DOS File Control Block.
- }
- FCB_T = record
- Drive : byte;
- Name : array[1..8] of char;
- Ext : array[1..3] of char;
- BlockNum,
- RecSize : integer;
- Size : array[0..1] of integer;
- Date : integer;
- Reserved2 : array[0..9] of byte;
- SeqNum : byte;
- RandomNum : array[0..3] of byte;
- end;
-
-
- {
- DOS Extended File Control Block.
- }
- ExtFCB_T = record
- ExtFlag : byte;
- Reserved : array[0..4] of byte;
- FileAttr,
- Drive : byte;
- Name : array[1..8] of char;
- Ext : array[1..3] of char;
- BlockNum,
- RecSize : integer;
- Size : array[0..1] of integer;
- Date : integer;
- Reserved2 : array[0..9] of byte;
- SeqNum : byte;
- RandomNum : array[0..3] of byte;
- end;
-
-
- {
- The entries in a directory follow the specifications of the
- following record. By using this record we can read from disk
- into a memory area reserved for an array of Entry_T.
- }
- Entry_T = record
- Name : array[1..8] of char;
- Ext : array[1..3] of char;
- Attr : byte;
- Reserved : array[0..9] of byte;
- Time,
- Date,
- Cluster : integer;
- Size : array[0..1] of integer;
- end;
-
-
- {
- This record outlines the table at an address returned by DOS function
- request $32. This is a non-documented function, but is supported
- from DOS v2.0 through v3.2 and seems very reliable.
- }
- DskTbl_T= record
- DRIVE1,
- DRIVE2 : byte;
- SECTORSIZE : integer;
- CLUSTERSIZE,
- NHEADS : byte;
- BOOTSIZE : integer;
- NFATS : byte;
- ROOTENTRIES,
- DATASECTOR,
- MAXCLUSTER : integer;
- FATSIZE : byte;
- ROOTSECTOR : integer;
- DEVDRIVER : array[0..1] of integer;
- FATATTR : byte;
- end;
-
- {
- String types for use in procedure declarations.
- }
- str4 = string[ 4];
- str6 = string[ 6];
- str10 = string[10];
- str11 = string[11];
- str80 = string[80];
-
- {
- Types for passing addresses between procedures.
- }
- Addr_T = ^integer;
- DskTblptr = ^DskTbl_T;
-
- EntryArr_T = array[1..MaxFiles] of Entry_T;
- MarkedArr_T = array[1..MaxFiles] of boolean;
-
-
- VAR
-
- SavedPath : str80;
-
- {
- Coordinates for specifying the current window
- }
- X1, X2, Y1, Y2 : integer;
-
- {
- Colors to be used by program, they are set in procedure Colors.
- }
- PATTR, NATTR, HATTR, HATTR2, BNATTR, BHATTR : integer;
- MATTR : array[1..2] of integer;
-
- Color,
- ShowAll,
- FATsaved,
- FuncKey : boolean;
- FATptr,
- HeapStart : Addr_T;
-
- DiskTable : array[1..2] of ^DskTbl_T;
- Path : array[1..2] of str80;
- HelpScreen,
- Loaded,
- Saved,
- NoSave : array[1..2] of boolean;
- Drive : array[1..2] of integer;
- TopEntry,
- CurLin,
- CurEntry,
- MaxEntry : array[1..2] of integer;
- DiskFree,
- DirSize,
- FATbytes : array[1..2] of real;
- Entry : array[1..2] of EntryArr_T;
- Marked : array[1..2] of MarkedArr_T;
-
- {
- Store the directory mask as entered and as converted by DOS.
- }
- Mask,
- ConvMask : array[1..2] of string[12];
-
-
-
- procedure Noise( freq, dur : integer );
- begin
- if MakeNoise then
- begin
- Sound( freq );
- Delay( dur );
- end;
- NoSound;
- end;
-
-
- {
- The following section takes over BIOS interrupt $10, function
- request $0E (Write Character as TeleType). This is done
- in order to prevent DOS from destroying our screen when it
- prints the message for changing disks on a one floppy
- system. The interrupt handler basically just forces the
- function request to conform to the current window settings.
- After Int10 is turned on calls to interrupt 10 will be directed
- to these routines rather than the BIOS.
- Don't forget to make sure the original interrupt handler is restored
- before the program exits. See procedures AbortProgram and
- AbortOnError in the sfmSCRN.inc file.
- }
-
- const
- DataSeg : integer = 0;
- Int10char : char = #0; { Temporary storage for character to print }
-
- OldInt10 : array[0..1] of integer = (0,0);
-
- procedure Int10;
- {
- The beep code below is not my own, I converted it from a sample
- program from 'The Complete Guide to IBM PC AT Assembly Language'
- by Harley Hahn. If you are looking for a good Assembly reference
- I've been pretty happy with this one (I don't have an AT either).
- The beep emulates the above Noise procedure by putting the
- frequency in CX and the duration (in milleseconds) in BX.
-
- OUTLINE OF INT10:
-
- Check if interrupt call was for 'Write Character as Teletype'
- if not
- (
- call the normal BIOS
- exit
- )
- otherwise
- (
- if the character to be printed is
- a Linefeed : make a short beep
- a Carriage Return : print a Space instead
- anything else : print the character using Turbo's Write
- exit
- )
- }
- begin
- { ; These lines are not entered by us, they
- PUSH BP ; are placed at the start of every subroutine
- MOV BP, SP ; by Turbo Pascal. You must therefore account
- PUSH SP ; for them before executing an IRET instruction.
- }
- Inline(
- $80/$FC/$0E { CMP AH, $0E }
- /$74/$0A { JE gotit }
- { ; }
- /$9C { PUSHF }
- /$2E/$FF/$1E/>OLDINT10 {CS: CALL FAR [>OldInt10] ; Call BIOS }
- { ; }
- /$89/$EC { MOV SP, BP ; Code to exit }
- /$5D { POP BP }
- /$CF { IRET }
- { ; }
- { ; Only enter here if BIOS function }
- { ; request was $0E, otherwise we }
- { ; let the BIOS procede normally }
- { ; with the above PUSHF and CALL. }
- { ; }
- /$50 {gotit: PUSH AX ; Save all registers }
- /$53 { PUSH BX ; so we can use Turbo }
- /$51 { PUSH CX ; code below. }
- /$52 { PUSH DX }
- /$57 { PUSH DI }
- /$56 { PUSH SI }
- /$06 { PUSH ES }
- /$1E { PUSH DS }
- { ; }
- /$2E/$A2/>INT10CHAR {CS: MOV [>Int10char], AL ; Get char }
- { ; }
- { ; Now we replace linefeed characters }
- { ; with a short beep if the }
- { ; MakeNoise flag is set. }
- { ; }
- /$3C/$0A { CMP AL, 10 }
- /$75/$36 { JNE nobeep }
- /$2E/$A0/>MAKENOISE {CS: MOV AL, [>MakeNoise] }
- /$3C/$00 { CMP AL, $00 }
- /$74/$2E { JE nobeep }
- { ; }
- /$B9/$E8/$03 { MOV CX, 1000 ; Frequency }
- /$BB/$64/$00 { MOV BX, 100 ; Duration (millsecs)}
- { ; }
- /$B0/$B6 { MOV AL, $B6 ; Prepare timer }
- /$E6/$43 { OUT $43, AL }
- { ; }
- /$BA/$12/$00 { MOV DX, $0012 ; Calculate freq. }
- /$B8/$DC/$34 { MOV AX, $34DC }
- /$F7/$F1 { DIV CX }
- { ; }
- /$E6/$42 { OUT $42, AL ; Send freq to timer }
- /$EB/$00 { JMP SHORT j1 }
- /$88/$E0 {j1: MOV AL, AH }
- /$E6/$42 { OUT $42, AL }
- { ; }
- /$E4/$61 { IN AL, $61 ; Save current timer }
- /$88/$C4 { MOV AH, AL ; setting }
- { ; }
- /$0C/$03 { OR AL, $03 ; Turn on speaker }
- /$E6/$61 { OUT $61, AL }
- { ; }
- /$B9/$D4/$01 {l1: MOV CX, 468 ; Delay }
- /$E2/$FE {l2: LOOP l2 }
- /$4B { DEC BX }
- /$75/$F8 { JNZ l1 }
- { ; }
- /$88/$E0 { MOV AL, AH ; Turn off speaker }
- /$E6/$61 { OUT $61, AL }
- {nobeep: }
- { ; }
- { ; The following two lines set the }
- { ; data segment to allow access to }
- { ; variables in the common area of }
- { ; the program. }
- { ; }
- /$2E/$A1/>DATASEG {CS: MOV AX, [>DataSeg] }
- /$8E/$D8 { MOV DS, AX }
- );
-
- case Int10char of { Not much here, but it does the job }
- #10 : { Already beeped };
- #13 : write( ' ' );
- else write( Int10char );
- end;
-
- InLine(
- $1F { POP DS ; Restore all registers }
- /$07 { POP ES }
- /$5E { POP SI }
- /$5F { POP DI }
- /$5A { POP DX }
- /$59 { POP CX }
- /$5B { POP BX }
- /$58 { POP AX }
- { ; }
- /$89/$EC { MOV SP, BP ; Code to exit }
- /$5D { POP BP }
- /$CF { IRET }
- );
- end;
-
- procedure Int10ON;
- {
- Direct interrupt 10 calls through our procedure, Int10.
- }
- var
- Regs : reg_T;
- begin
- DataSeg := Dseg;
- with Regs do
- begin
- AH := $35; { DOS function $35 - Get Interrupt Vector Address }
- AL := $10; { getting $10 - BIOS Video interrupt }
- MsDos( Regs );
- OldInt10[1] := ES;
- OldInt10[0] := BX;
- AH := $25; { DOS function $25 - Set Interrupt Vector Address }
- AL := $10; { setting $10 - BIOS Video interrupt }
- DS := Cseg;
- DX := ofs( Int10 );
- MsDos( Regs );
- end;
- end;
-
- procedure Int10OFF;
- {
- Restores the original address for interrupt 10.
- }
- var
- Regs : reg_T;
- begin
- with Regs do
- begin
- AH := $25; { DOS function $25 - Set Interrupt Vector Address }
- AL := $10; { setting $10 - BIOS Video interrupt }
- DS := OldInt10[1];
- DX := OldInt10[0];
- MsDos( Regs );
- end;
- end;
-
- function HexStr( num : integer ) : str4;
- {
- Convert integer to its four character hex representation
- (padded with zeros).
- }
- var
- tstr : string[4];
- i, j : integer;
- begin
- tstr[0] := #4;
- for i := 0 to 3 do
- begin
- j := ord('0') + ( (num SHR (4*i)) AND $0F );
- if j < 58 then
- tstr[4-i] := chr( j )
- else
- tstr[4-i] := chr( j + 7 );
- end;
- HexStr := tstr;
- end;