home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 13 / CD_ASCQ_13_0494.iso / news / swag / hardware.swg < prev    next >
Text File  |  1994-03-11  |  73KB  |  1 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00027         HARDWARE DETECTION                                                1      05-28-9313:48ALL                      SWAG SUPPORT TEAM        Write to TWO Monitors    IMPORT              9      └╫å# {π> Hi I am looking For some help on use 2 monitors at the same time... 1π> is mono and the other is vga.  I would like to just post a certainπ> screen on the mono and leave the vga like normal..ππVGA Text mode memory begins at $b800, VGA Graphics memory at $A000, andπMDA/Herc memory begins at $b000.  If you plan on running Text and Text,πtry something like this:π}πTypeπ  WhichMonitor = (MDA, VGA);ππProcedure ChangeCel (Row, Column, Foreground, Background, Character : Byte;π                     Which : WhichMonitor);πVarπ  Point : Word;πbeginπ  If Which = MDA thenπ    Point := $b000π  elseπ    Point := $b800;π  MemW[Point : (Row - 1) * 160 + Col * 2] :=π               (Foreground + Background * 16) * 256 + Character;π  end;π{πOf course, there are more optimized ways to do this, but this shouldπportray the basic concept.  Herc Graphics and VGA Graphics would beπdone in much the same manner, but I don't have an Herc With my VGA toπcheck it.π}                                                                      2      05-28-9313:48ALL                      SWAG SUPPORT TEAM        ALOCSIZE.PAS             IMPORT              21     └╫┬y *--*  03-31-93  -  21:47:03  *--*π/. Date: 03-30-93 (23:45)              Number: 24023 of 24035π  To: PEDRO PACHECO                 Refer#: 23957πFrom: ERIC LU                         Read: NOπSubj: allocation Units              Status: PUBLIC MESSAGEπConf: R-TP (552)                 Read Type: GENERAL (A) (+)ππPP>> Is there any way to find (in Pascal) what's de size of each allocation uniπPP>> in a Hard drive?ππPedro,π     See if the following is what you wanted...ππ-------------------------------- Cut  ----------------------------------ππProgram Int21_36;πUses Crt,Dos;πProcedure DiskfreeSpace( DriveCode: Byte);πVarπ   Regs: Registers;π   SectorsPerCluster,π   AvailableClusters,π   BytesPerSector,π   ClustersPerDrive,π(63 min left), (H)elp, More?    AllocationSize,π   Capacity,π   Free:  LongInt;πbeginπ   Regs.AH := $36;π   Regs.DL := DriveCode;π   MSDos(Regs);ππ   {************* Obtaining Infos ******************}π   SectorsPerCLuster:= Regs.AX;π   AvailableClusters:= Regs.BX;π   BytesPerSEctor   := Regs.CX;π   ClustersPerDrive := Regs.DX;ππ   {************* Calculations ********************)π   AllocationSize   := BytesPerSector * SectorsPerCluster;π   Capacity := SectorsPerCluster * BytesPerSector * ClustersPerDrive;π   Free     := SectorsPerCLuster * AvailableClusters * BytesPerSector;ππ   {************* Display *************************}π   Writeln(' Sectors Per Cluster   = ',SectorsPerCluster:15,'');π   Writeln(' Available Clusters    = ',AvailableClusters:15,'');π   Writeln(' Bytes Per Sector      = ',BytesPerSector:15,'');π(63 min left), (H)elp, More?    Writeln(' Clusters Per Drive    = ',ClustersPerDrive:15,'');π   Writeln(' Allocation Size       = ',AllocationSize:15,' Bytes');π   Writeln(' Drive Capacity        = ',Capacity:15,' Bytes');π   Writeln(' Free Space            = ',Free:15,' Bytes');πend;ππbeginπ   ClrScr;π   DiskFreeSpace(0);   {Get Current Drive Info}π   readln;πend.πππ----------------------------- Cut ----------------------------------ππ The above should be ready to run as I have tested on my computer..π It's got more infos..  I was learning it as I was typing it in so Iπ made it more than what you need.π hope this is what you wanted to know...ππ                                                        Ericππ---π(63 min left), (H)elp, More?  ■ OLX 2.1 TD ■ It's only a hobby ... only a hobby ... only aπ * Casino Bulletin Board * Hammonton/Atlantic City NJ U.S.A. 1-609-561-3377π * PostLink(tm) v1.05  CASINO (#18) : RelayNet(tm)ππ(63 min left), (H)elp, end of Message Command?                3      05-28-9313:48ALL                      SWAG SUPPORT TEAM        Determine Cluster Size   IMPORT              5      └╫8∩ {π> Is there any way to find the size of each allocation Unit in a Hard drive?π}ππUses Dos;ππFunction clustsize (drive : Byte) : Word;πVarπ  regs : Registers;πbeginπ  regs.cx := 0;         {set For error-checking just to be sure}π  regs.ax := $3600;     {get free space}π  regs.dx := drive;     {0=current, 1=a:, 2=b:, etc.}π  msDos (regs);π  clustsize := regs.ax * regs.cx;      {cluster size!}πend;ππbeginπ  Writeln(ClustSize(0));πend.                                                                           4      05-28-9313:48ALL                      SWAG SUPPORT TEAM        CPU-ID.PAS               IMPORT              12     └╫m╔ {π> How do i get info about witch CPU it is in the current computer??π}ππ{$F+}ππConstπ  CPU_Type : Array[1..4] of String[5] = ('8086', '80286', '80386', '80486');π  Cpu8086  = 1;π  Cpu80286 = 2;π  Cpu80386 = 3;π  Cpu80486 = 4;πVarπ  Result : Byte;πππFunction GetCPU_Type: Byte; Assembler;ππAsmπ  MOV   DX,Cpu8086π  PUSH  SPπ  POP   AXπ  CMP   SP,AXπ  JNE   @OUTπ  MOV   DX, Cpu80286π  PUSHFπ  POP   AXπ  or   AX,4000hπ  PUSH  AXπ  POPFπ  PUSHFπ  POP   AXπ  TEST  AX,4000hπ  JE   @OUTπ  MOV DX, Cpu80386π  {"DB 66h" indicates '386 extended instruction}π  DB 66h; MOV   BX, SP      {MOV EBX, ESP}π  DB 66h, 83h, 0E4h, 0FCh   {AND ESP, FFFC}π  DB 66h; PUSHF             {PUSHFD}π  DB 66h; POP AX            {POP EAX}π  DB 66h; MOV   CX, AX      {MOV ECX, EAX}π  DB 66h, 35h, 00hπ  DB 00h, 04h, 00           {XOR EAX, 00040000}π  DB 66h; PUSH   AX     {PUSH EAX}π  DB 66h; POPF              {POPFD}π  DB 66h; PUSHF             {PUSHFD}π  DB 66h; POP   AX     {POP EAX}π  DB 66h, 25h, 00hπ  DB 00h, 04h, 00h          {AND EAX, 00040000}π  DB 66h, 81h, 0E1h, 00hπ  DB 00h, 04h, 00h          {AND ECX, 00040000}π  DB 66h; CMP   AX, CX      {CMP EAX, ECX}π  JE @Not486π  MOV DX, Cpu80486π@Not486:π  DB 66h; PUSH   CX         {PUSH EXC}π  DB 66h; POPF              {POPFD}π  DB 66h; MOV   SP, BX      {MOV ESP, EBX}π@Out:π  MOV AX, DXπend;ππbeginπ  Result := GetCPU_Type;π  Writeln(Result);πend.π                     5      05-28-9313:48ALL                      SWAG SUPPORT TEAM        Determine CPU Speed      IMPORT              13     └╫Z {π·    Subject: How to determine mhz using TP6.0...ππIt seems to work pretty well, but on a 486/33DX it gave inacurate results...π}ππProgram CpuSpeed;πUsesπ  Crt;πVarπ  Speed, DelayCalibrate : Word;πConstπ  Offset = 9; { For TP 4.0, it should be 16 }πππProcedure WaitForFloppy;πVarπ  tickTil     : LongInt;π  TimerTicks  : LongInt Absolute $40 : $6C;π  motorStatus : Byte Absolute $40 : $3F;πbeginπ  if MotorStatus and $F > 0 thenπ  beginπ    WriteLn('Loading...');π    TickTil := TimerTicks + 91;π    {There are $17FE80 ticks in a day}π    if TickTil > $17FE80 thenπ      Dec(TickTil, $17FE80);π    Repeat Until (MotorStatus and $F = 0) or (TimerTicks >= TickTil);π  end;πend;ππbeginπ  WaitForFloppy;π  DelayCalibrate := MemW[Seg(CheckSnow): Ofs(CheckSnow)+Offset];π  WriteLn('Delay calibration value is ', DelayCalibrate);π  Speed := ((LongInt(1000) * DelayCalibrate) + 110970) div 438;π  Write('Calculated speed: ', Speed div 100,'.');π  WriteLn((speed div 10) MOD 10, speed MOD 10);π  Write('CPU speed is probably ');π  Case Speed OFπ    0..499     : WriteLn('4.77MHz or below');π    500..699   : WriteLn('6MHz');π    700..899   : WriteLn('8MHz');π    900..1099  : WriteLn('10MHz');π    1100..1399 : WriteLn('12MHz');π    1400..1799 : WriteLn('16MHz');π    1800..2199 : WriteLn('20MHz');π    2200..2699 : WriteLn('25MHz');π    2700..3599 : WriteLn('30MHz');π    ELSEπ      WriteLn('30MHz or MORE!');π  end;πend.π                                                                                                                       6      05-28-9313:48ALL                      SWAG SUPPORT TEAM        FLOPSIZE.PAS             IMPORT              10     └╫1 {π>Does anybody know how to determine the size of a disk drive.  I meanπ>whether it is a 360 K drive or 720 K, 1.4 M or 1.2 M drive.  I'mπ>working on a Program which has the ability to Format diskettes andπ>I want it to be able to come up With the size of a disk drive as aπ>default.  I have looked at the equipment flag in the BIOS and theπ>only thing I can get out of that is the Type of a disk drive not theπ>size.π}πFunction VarCMOS(i : Byte) : Byte ;πbeginπ     port[$70]:=i;π     VarCMOS:=port[$71]πend;ππVar  b    : Byte ;ππbeginπ     b:=VarCMOS($10);π     if b and $f0<>0 thenπ     beginπ          Write('Drive A: = ');π          Case (b and $f0) shr 4 ofπ               1 : Write('5" 360 Ko');π               2 : Write('5" 1,2 Mo');π               3 : Write('3" 720 Ko');π               4 : Write('3" 1,44 Mo')π          end;π     end;π     if b and $f<>0 thenπ     beginπ          Write(', B: = ');π          Case b and $f ofπ               1 : Writeln('5" 360 Ko');π               2 : Writeln('5" 1,2 Mo');π               3 : Writeln('3" 720 Ko');π               4 : Writeln('3" 1,44 Mo')π          end;π     end else WriteLn ;πend.π        7      05-28-9313:48ALL                      SWAG SUPPORT TEAM        LPT-ADDR.PAS             IMPORT              5      └╫└' {πOr better yet, the BIOS stores the addresses of the parallel Interfacesπon the system at memory location $0040:$0008.  There are four Wordsπhere, allowing up to 4 parallel devices.π-Brian Papeπ}πVarπ  i : Byte;π  par : Array[1..4] of Word;πbeginπ  For i := 1 to 4 doπ  beginπ    par[i] := Word(ptr($0040, $0008 + (i - 1) * 2)^);π    If Par[i] = 0 thenπ      Writeln('Not Found')π    elseπ      Writeln(Par[i]);π  end;πend.πππ                                                                                     8      05-28-9313:48ALL                      SWAG SUPPORT TEAM        SCSICODE.PAS             IMPORT              30     └╫Hv {π > I am trying to issue an SCSI START/StoP Unit via Adaptec's ASPI SCSIπ > manager and an 1542B host adaptor.  This is For an application I amπ > writing in BP.  Adaptec is of no help.  if anyone here has anyπ > commentsπ > or suggestions please respond in this Forum.π}ππUnit Aspi;ππ{ I/O Error reporting:ππ  AspiSenseKey is the primary source of error inFormation.ππ    0:    I/O Complete.π          Warnings (Filemark, Short block, etc) may be posted in Sense.ππ    1-E:  Error occured.π          Examine SRBStat, HostStat, TargStat, Sense For details.ππ    F:    Severe error detected, no SCSI info available.ππ  -------------------------------------------------------------------- }ππInterfaceππConstπ  SrbIn = $08;π  SRBOut = $10;π  SRBNone = $18;π  AspiPtr:  Pointer = Nil;πππTypeπ  AspiSrb = Recordπ    SrbCmd:      Byte;π    SrbStat:     Byte;π    SrbHost:     Byte;π    SrbReqFlags: Byte;π    SrbHdrFill:  LongInt;π    Case Integer ofπ     2: (Srb2TargetID: Byte;π         Srb2LUN:      Byte;π         Srb2DataLen:  LongInt;π         Srb2SenseLen: Byte;π         Srb2DataPtr:  Pointer;π         Srb2LinkPtr:  Pointer;π         Srb2CDBLen:   Byte;π         Srb2HAStat:   Byte;π         Srb2TargStat: Byte;π         Srb2PostAddr: Pointer;π         Srb2Filler:   Array [1..34] of Byte;π         { Sense data follows CDB }π         Srb2CDB:      Array [0..50] of Byte);π     1: (Srb1TargetID: Byte;π         Srb1LUN:      Byte;π         Srb1DevType:  Byte);π     0: (Srb0Cnt:      Byte;π         Srb0TargetID: Byte;π         Srb0MgrID:    Array [1..16] of Char;π         Srb0HostID:   Array [1..16] of Char;π         Srb0HostParm: Array [1..16] of Char);π    end;ππVarπ  AspiSRBStat:      Byte;π  AspiHostStat:     Byte;π  AspiTargStat:     Byte;π  AspiSenseKey:     Byte;π  AspiSense:        Array [0..17] of Byte;π  AspiSenseCode:    Word;ππFunction AspiOpen: Integer;ππProcedure AspiCall (Var SRB: AspiSrb);π{ Call ASPI Handler With SRB }πInline ($FF/$1E/>AspiPtr/π        $58/$58);ππProcedure AspiWait (Var SRB: AspiSrb);ππFunction AspiClose: Integer;ππImplementationππUses Dos;ππProcedure AspiWait (Var SRB: AspiSRB);π{ Call ASPI Handler With SRB and wait For Completion }πbeginπ  if AspiPtr = Nilπ    then beginπ      AspiSenseKey := $0F;π      Exit;π      end;π  With Srb do beginπ    SrbStat := 0;π    AspiCall (Srb);π    While SrbStat = 0 do ;π    AspiSrbStat   := SrbStat;π    AspiHostStat  := Srb2HAStat;π    AspiTargStat  := Srb2TargStat;π    AspiSenseKey  := 0;π    FillChar (AspiSense, Sizeof (AspiSense), #0);π    Move (Srb2CDB [Srb2CDBLen], AspiSense, Sizeof (AspiSense));π    AspiSenseKey := AspiSense[2] and $0F;π    AspiSenseCode := (AspiSense [12] SHL 8) or AspiSense [13];π    end;π  end;ππFunction AspiOpen: Integer;πConstπ  AspiName: Array [1..9] of Char = 'SCSIMGR$'#0;πVarπ  R:       Registers;π  AspiHan: Word;πbeginπ  With R do beginπ    { Assume failure }π    AspiOpen := -1;π    AspiPtr := Nil;ππ    { Open ASPI device driver }π    AX := $3D00;π    DS := Seg (AspiName[1]);π    DX := ofs (AspiName[1]);π    MSDos (R);π    if odd (Flags)π      then Exit;π    AspiHan := AX;ππ    { Do IOCtl Read to get Pointer to ASPI handler }π    AX := $4402;π    BX := AspiHan;π    CX := 4;π    DS := Seg (AspiPtr);π    DX := ofs (AspiPtr);π    MSDos (R);π    if Odd (flags)π      then Exit;ππ    { Close device driver }π    AX := $3E00;π    BX := AspiHan;π    MsDos (R);π    if Odd (Flags)π      then Exit;π    end;ππ  { Indicate success  and Exit }π  AspiOpen := 0;π  end { AspiOpen };ππFunction AspiClose: Integer;πbeginπ  AspiClose := 0;πend { AspiClose };ππend.π                                                                                                                           9      05-28-9313:48ALL                      SWAG SUPPORT TEAM        SECTORIO.PAS             IMPORT              65     └╫ x {... so there I was, sitting in a bar when a known C Programmer  }π{comes up to me and sniggers "still doing it in Pascal eh?"      }π{"Yup" I replied, and tossed the bartender another hundred.      }π{"Yeah well, when you're ready For a Real language, only C has   }π{all the aces."                                                  }π{I'm a Pascal Programmer.  I don't have to take that.  "Such as?"}π{I hoped he'd bite and he did.                                   }π{"Such as disk sector reading and writing For starters."         }π{"Well I hope you're not bluffin', 'cause here's a trick that    }π{I'll bet you ain't covered."                                    }π{I pulled it out With a swish and laid it on the table.  "Even   }π{provides support For >32M volumes, which the C run-time library }π{manual Forgets to tell you it won't do."                        }π{"Huh?  Where?"                                                  }π{"Right here" I said.  "Just where it says...                    }ππProgram AbsReadTest;ππ{This Program demonstrates a C-style absread and absWrite For TP.}π{As is, it reads the boot sector off drive A:, and optionally    }π{Writes it out to the very last sector on drive A: (assumes 1.2Meg}π{This Program IS dangerous, and is released to the public domain.}π{I take no responsibility For use or misuse, deliberate or       }π{accidental, of this Program or any Program which Uses the       }π{techniques described herein.                                    }ππ{Author: Mitch Davis 3:634/384.6 +61-3-890-2062 v1.0 28-Jun-92.  }ππVar bp:Pointer; {Will point to the buffer For the sector data}ππFunction absread (drive:Char; nsects:Word; lsect:Word; buffer:Pointer):Boolean;ππ{Works just like the C runtime one- including being restricted to 32M volumes!}ππ{drive is a Character, nsects is the number of sectors, and lsect is the first}π{sector.  buffer points to the buffer you'd like filled from disk.  Function  }π{returns True if there was an error, or False if all went well.               }ππVar kludgebuff:Array [0..$1f] of Byte; {Read Ralf Brown's interrupt listing}π    kludgePtr:Pointer;                 {Int 25h - ES:[BP+1E] may change    }ππbeginπ  kludgePtr := @kludgebuff;π  absread := True;π  if drive < 'A' then Exit;π  if drive > 'Z' then Exit;π  Asmπ    push  esπ    push  bpπ    push  diπ    les   di, kludgePtrπ    mov   al, drive      { Gets the passed parameter. }π    and   al, 1fh        { Cvt from ASCII to drive num }π    dec   al             { Adjust because A: is drive 0 }π    mov   cx, nsects     { number of sectors to read }π    mov   dx, lsect      { starting at sector.. }π    push  dsπ    lds   bx, buffer      { Get the address of the buffer }π    mov   bp, diπ    push  siπ    int   25h            { Do the drive read. }π    pop   si             { Remove the flags int 25h leaves on stack}π    pop   siπ    pop   dsπ    pop   diπ    pop   bpπ    pop   esπ    jc    @1π    mov   ah, 0          { No errors, so set Function to False }π    @1:π    mov   @result, ahπ  end;πend;ππFunction absWriteπ            (drive:Char; nsects:Word; lsect:Word; buffer:Pointer):Boolean;ππ{Works just like the C one - including being restricted to 32M volumes!}ππ{drive is a Character, nsects is the number of sectors, and lsect is the first}π{sector.  buffer points to the buffer you'd like filled from disk.  Function  }π{returns True if there was an error, or False if all went well.               }ππVar kludgebuff:Array [0..$1f] of Byte;π    kludgePtr:Pointer;ππbeginπ  kludgePtr := @kludgebuff;π  absWrite := True;π  if drive < 'A' then Exit;π  if drive > 'Z' then Exit;π  Asmπ    push  esπ    push  bpπ    push  diπ    les   di, kludgePtrπ    mov   al, drive      { Gets the passed parameter. }π    and   al, 1fh        { Cvt from ASCII to drive num }π    dec   al             { Adjust because A: is drive 0 }π    mov   cx, nsects     { number of sectors to Write }π    mov   dx, lsect      { starting at sector.. }π    push  dsπ    lds   bx, buffer      { Get the address of the buffer }π    mov   bp, diπ    push  siπ    int   26h            { Do the drive Write. }π    pop   si             { Remove the flags int 26h leaves on stack}π    pop   siπ    pop   dsπ    pop   diπ    pop   bpπ    pop   esπ    jc    @1π    mov   ah, 0π    @1:π    mov   @result, ahπ  end;πend;ππFunction absLread (drive:Char; nsects:Word; lsect:LongInt;πbuffer:Pointer):Boolean;ππ{This Function reads sectors on disks which have the >32M style made popular}π{by Compaq Dos 3.31, MS-Dos 4+ and DR-Dos 5+.                               }ππVar packet:Array [0..9] of Byte; {disk request packet - see Ralf Brown's ints}ππbeginπ  absLread := True;π  if drive < 'A' then Exit;π  if drive > 'Z' then Exit;π  Asmπ    mov   ax, Word ptr lsect     {Get the LSB of the start sector}π    mov   Word ptr packet[0], ax {Store it in the packet         }π    mov   ax, Word ptr lsect + 2 {Get the MSB of the start sector}π    mov   Word ptr packet[2], ax {Store this one too.            }π    mov   ax, nsects             {How many sectors to read       }π    mov   Word ptr packet[4], axπ    {Insert the Pointer to the data buffer into the packet}π    push  bp ; push dsπ    lds   dx, buffer      { Get the address of the buffer }π    mov   Word ptr packet[6], dxπ    mov   dx, dsπ    mov   Word ptr packet[8], dxπ    mov   al, drive      { Gets the passed parameter. }π    and   al, 1fh        { Cvt from ASCII to drive num }π    dec   al             { Adjust because A: is drive 0 }π    int   25h            { Do the drive read. }π    pop   si             { Remove the flags int 25h leaves on stack}π    pop   dsπ    pop   bpπ    jc    @1π    mov   ah, 0π    @1:π    mov   @result, ahπ  end;πend;ππFunction absLWrite (drive:Char; nsects:Word; lsect:LongInt;πbuffer:Pointer):Boolean;ππ{This Function Writes sectors on disks which have the >32M style made popular}π{by Compaq Dos 3.31, MS-Dos 4+ and DR-Dos 5+.                                }ππVar packet:Array [0..9] of Byte;ππbeginπ  absLWrite := True;π  if drive < 'A' then Exit;π  if drive > 'Z' then Exit;π  Asmπ    mov   ax, Word ptr lsectπ    mov   Word ptr packet[0], axπ    mov   ax, Word ptr lsect + 2π    mov   Word ptr packet[2], axπ    mov   ax, nsectsπ    mov   Word ptr packet[4], axπ    push  bp ; push dsπ    lds   dx, bufferπ    mov   Word ptr packet[6], dxπ    mov   dx, dsπ    mov   Word ptr packet[8], dxπ    mov   al, drive      { Gets the passed parameter. }π    and   al, 1fh        { Cvt from ASCII to drive num }π    dec   al             { Adjust because A: is drive 0 }π    int   26h            { Do the drive Write. }π    pop   si             { Remove the flags int 26h leaves on stack}π    pop   dsπ    pop   bpπ    jc    @1π    mov   ah, 0π    @1:π    mov   @result, ahπ  end;πend;ππFunction LongNeeded (drive:Char):Boolean;ππ{This Function returns True or False depending on whether the long versions}π{of absread/absWrite needed to be invoked; that is, it's a drive Formatted }π{in the Dos 4+ >32M style.                                                 }π{I strongly suggest you see Ralf Brown's interrupt listing For int21h subfs}π{440d and 53 - they'll tell you all you know to understand the guts of this}π{Function.                                                                 }ππLabel Escape;ππVar drivestats:Array [0..31] of Byte;ππbeginπ  LongNeeded := False;π  if drive < 'A' then Exit;π  if drive > 'Z' then Exit;π  Asmπ    push dsπ    mov  dx, ssπ    mov  ds, dxπ    lea  dx, drivestatsπ    mov  bl, drive      { Gets the passed parameter. }π    and  bl, 1fh        { Cvt from ASCII to drive num }π    mov  ax, 440Dhπ    mov  cx, 0860hπ    int  21hπ    jc   Escapeπ    mov  ax, Word ptr drivestats[0Fh]π    or   ax, axπ    jnz Escapeπ    mov  @Result, 1π  Escape:π    pop  dsπ  end;πend;ππbeginπ  getmem (bp,2048);π  Writeln (LongNeeded ('A'));π  Writeln (LongNeeded ('C'));π  Writeln (absread  ('A',1,0,bp));π(*  Writeln (absWrite ('A',1,2399,bp)); *) {remove the comments at your own}π                                           {risk!!!}π  freemem (bp,2048);πend.ππ{So I bought him a drink.  The poor guy looked like he needed one....}π                                 10     05-28-9313:48ALL                      SWAG SUPPORT TEAM        Activate TURBO Speed     IMPORT              9      └╫}v { Does anyone out there know how to set the Software Turbo Speed on Motherπ boards without hitting the Turbo Switch or the <Ctrl> <Alt> <-> key toπ slow the system and or Speed it up again? Thanks...π}ππProgram speed;πUses Dos,Crt;ππProcedure do_speed(mode : String);πVarπ reg : Registers;π oldmem : Byte;ππbeginπ oldmem := mem[$40:$17];π if UpCase(mode[1]) = 'N' thenπ beginπ  reg.al := 74;π  Writeln('Speed set to NorMAL MODE');π end elseπ beginπ  reg.al := 78;π  Writeln('Speed set to TURBO MODE');π end;π mem[$40:$17] := 140;π reg.ah := $4F;π intr($15,reg);π mem[$40:$17] := oldmem;πend;ππbeginπ if paramcount < 1 thenπ beginπ  Writeln(' Speed.exe (c) by Werner Schlagnitweit 2:310/3.0');π  Writeln(' This Program should work on all machines which ');π  Writeln(' use the CTRL-ALT-+ key to toggle the speed     ');π  Writeln;π  Writeln(' Usage : Speed N  For normal NON TURBO mode');π  Writeln('         Speed T  For normal TURBO mode    ');π  halt;π end else do_speed(paramstr(1));πend.π                                11     08-27-9322:08ALL                      SWAG SUPPORT TEAM        Set the TURBO speed      IMPORT              6      └╫   {π Does anyone out there know how to set the Software Turbo Speed on Motherπ boards without hitting the Turbo Switch or the <Ctrl> <Alt> <-> key toπ slow the system and or Speed it up again? Thanks...π}ππUsesπ  Dos;ππProcedure SetSpeed(Turbo : Boolean);πVarπ  Regs   : Registers;π  OldMem : Byte;ππbeginπ  {OldMem := Mem[$40 : $17];}π  If Turbo thenπ    Regs.AL := 78π  elseπ    Regs.AL := 74;ππ  {Mem[$40 : $17] := 140;}π  Regs.AH := $4F;π  Intr($15, Regs);π  {Mem[$40 : $17] := OldMem;}πend;ππbeginπ  SetSpeed(False);πend.π                                                                                                                   12     10-28-9311:29ALL                      BRUCE LACKLORE           CPU Info                 SWAG9311            87     └╫   Unit CPUInfo;ππ{        Version 1.1.0.Pππ        Requires Borland Turbo Pascal version 6.0 or later to compile.π        Author:  Bruce J. Lackore.  Created Saturday, October 9, 1993.π}ππ{$IFDEF Test}π        {$A+,B-,D+,F-,G-,I+,L+,O-,R+,S+,V-,X+}π{$ELSE}π        {$A+,B-,D-,F-,G-,I-,L-,O-,R-,S-,V-,X+}π{$ENDIF}ππ{        This unit contains a handy gadget for determining the CPU speed.  It is NOTπ        coded for the Pentium family (if anyone wants to take a shot at it, pleaseπ        let me know the results)!π}ππInterfaceππConstπ        Cpu8086                                                                          = 1;π        Cpu80286                                                                         = 2;π        Cpu80386                                                                         = 3;π        Cpu80486                                                                         = 4;ππFunction WhatCPU:  Word;ππ{        This function examines the CPU and returns a number corresponding to theπ        CPU type;  1 for 8086, 3 for 80386, etc.  This procedure came right out ofπ        Neil Rubenking's Turbo Pascal 6.0 Techniques and Utilities (thanx Neil!).π}ππProcedure CPUSpd(Var MHz, KHz:  Word);ππ{        This procedure is a ROUGH estimation of how fast the CPU is running inπ        MegaHertz.  It was adapted from a C program found in the Intel forum ofπ        CIS written by Glenn Dill.  I had to do some finagling of the original codeπ        because C allows for a 32-bit UNSIGNED integer, whereas Pascal allows for aπ        32-bit SIGNED integer (the LongInt), therefore, I was forced to reduce allπ        calculations by 10 in order to get it to fit properly.π}ππ{ ************************************************************************** }ππImplementationππFunction WhatCPU;  Assembler;ππ        Asm  { Function WhatCPU }π                        MOV            DX,Cpu8086π                        PUSH           SPπ                        POP            AXπ                        CMP            SP,AXπ                        JNE                 @OUTπ                        MOV                 DX,Cpu80286π                        PUSHFπ                        POP            AXπ                        OR             AX,4000hπ                        PUSH           AXπ                        POPFπ                        PUSHFπ                        POP            AXπ                        TEST           AX,4000hπ                        JE             @OUTπ                        MOV                 DX,Cpu80386                        {        "DB 66h" makes '386 extended instruction }π                        DB 66h; MOV BX,SP              {        MOV EBX,ESP }π                        DB 66h, 83h, 0E4h, 0FCh {        AND ESP,FFFC        }π                        DB 66h; PUSHF           {        PUSHFD }π                        DB 66h; POP AX          {        POP EAX        }π                        DB 66h; MOV CX, AX      {        MOV ECX,EAX }π                        DB 66h, 35h, 00hπ                        DB 00h, 04h, 00         {        XOR EAX,00040000        }π                        DB 66h; PUSH AX         {        PUSH EAX }π                        DB 66h; POPF            {        POPFD }π                        DB 66h; PUSHF           {        PUSHFD }π                        DB 66h; POP AX          {        POP EAX }π                        DB 66h, 25h,00hπ                        DB 00h, 04h,00h                {        AND EAX,00040000 }π                        DB 66h, 81h,0E1h,00hπ                        DB 00h, 04h,00h                {        AND ECX,00040000 }π                        DB 66h; CMP AX,CX              {        CMP EAX,ECX }π                        JE @Not486π                        MOV DX, Cpu80486π                @Not486:π                        DB 66h; PUSH CX         {        PUSH ECX }π                        DB 66h; POPF            {        POPFD }π                        DB 66h; MOV SP, BX      {        MOV ESP,EBX }π                @Out:π                        MOV AX, DXπ        End;        { Function WhatCPU }ππProcedure CPUSpd;ππ        Constπ                Processor_cycles:                                Array[0..4] of Byte = (165, 165, 25, 103, 42);π                                                                                                                {        Cycle times of 8086, 80186, 80286, 80386, 80486}ππ                {        Notice that here I have defined the 8086 as a Processor type of 0 viceπ                        the returned value of 1 from WhatCPU.  Since the original code did notπ                        distinguish between the 8086 and the 80186, I can get away with this.π                }ππ        Varπ                Ticks,π                Cycles,π                CPS:                                                                                LongInt;π                Which_CPU:                                                        Word;ππ        Function i86_to_i286:  Word;  Assembler;ππ                Asm  { Function i86_to_i286 }π                        CLIπ                        MOV                CX,1234π                        XOR                DX,DXπ                        XOR                AX,AXπ                        MOV                AL,$B8π                        OUT                $43,ALπ                        IN                AL,$61π                        OR                AL,1π                        OUT                $61,ALπ                        XOR                AL,ALπ                        OUT                $42,ALπ                        OUT                $42,ALπ                        XOR                AX,AXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IDIV        CXπ                        IN                AL,$42π                        MOV                AH,ALπ                        IN                AL,$42π                        XCHG        AL,AHπ                        NEG                AXπ                        STIπ                End;  { Function i86_to_i286 }ππ        Function i386_to_i486:  Word;        Assembler;ππ                Asm  { Function i386_to_i486 }π                        CLIπ                        MOV                AL,$B8π                        OUT                $43,ALπ                        IN                AL,$61π                        OR                AL,1π                        OUT                $61,ALπ                        XOR                AL,ALπ                        OUT                $42,ALπ                        OUT                $42,ALπ                        DB 66H,$B8,00h,00h,00h,80h;π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        DB 66H,0FH,$BC,$C8;                                {        BSF        ECX,EAX }π                        IN                AL,42Hπ                        MOV   AH,ALπ                        IN                AL,42Hπ                        XCHG        AL,AHπ                        NEG                AXπ                        STIπ                End;  { Function i386_to_486 }ππ        Begin  { Procedure CPUSpd }π                Which_CPU := WhatCPU;π                If Which_cpu < 3 Thenπ                        Ticks := i86_to_i286π                Elseπ                        Ticks := i386_to_i486;π                Cycles := 20 * Processor_cycles[Which_CPU];π                CPS := (Cycles * 119318) Div Ticks;π                MHz := CPS Div 100000;π                KHz := (CPS Mod 100000 + 500) Div 1000π        End;  { Procedure CPUSpd }ππEnd.  { Unit CPUInfo }ππ{ ---------------------   TEST PROGRAM --------------------------}ππProgram CPUSpeed;ππ{        Version 1.0.0.T.ππ        Requires Borland Turbo Pascal version 6.0 or later to compile.ππ        Author:  Bruce J. Lackore.  Created Saturday, October 9, 1993.π}ππ{$IFDEF Test}π        {$A+,B-,D+,E+,F-,G-,I+,L+,N-,R+,S+,V-,X+}π{$ELSE}π        {$A+,B-,D-,E+,F-,G-,I-,L-,N-,R-,S-,V-,X+}π{$ENDIF}ππ{$M 1024, 0, 0}ππUses CPUInfo;ππVarπ        MHz,π        KHz:                                                                                        Word;ππBegin  { Program: Cpuspeed }π        CpuSpd(MHz, KHz);π        Writeln('The CPU speed is ', MHz, '.', KHz, ' MHz.')πEnd.  { Program:  Cpuspeed }π                                    13     11-02-9310:33ALL                      ERIC SCHILKE             PORTS Info               SWAG9311            15     └╫   {πERIC SCHILKEππ>  I need help in obtaining all pertinent information aboutπ>  AuxInPtr and AuxOutPtr, as pertaining to TP 3.0 reservedπ>  Words. These Pointers are referencing BIOS entry points.ππThis is from memory, since I don't have the references here, andπit has been a While....  AuxInPtr and AuxOutPtr are Pointersπcontaining the addresses of the respective AuxIn Function andπAuxOut Procedure, which are used (and not available as a standardπFunction/Procedure) by the standard TP3 I/O drivers.ππEach of the I/O possibilities has a corresponding Procedure/Function,πaddress Pointer, and BIOS entry point as follows:ππ     Device        proc/funct        address      BIOS entryππ  CON:,TRM:,KBD:   ConIn:Char;       ConInPtr       CONINπ  CON:,TRM:,KBD:   ConOut(Ch:Char);  ConOutPtr      CONOUTπ  LST:             LstOut(Ch:Char);  LstOutPtr      LISTπ  AUX:             AuxIn:Char;       AuxInPtr       READERπ  AUX:             AuxOut(ch:Char);  AuxOutPtr      PUNCHπ  USR:             UsrIn:Char;       UsrInPtr       CONIN  ?π  USR:             UsrOut(ch,Char);  UsrOutPtr      CONOUT ?ππI'm not sure about the last two entry points.  Also, if memoryπserves correctly, there is another Function, ConSt:Boolean, whichπis used by the KeyPressed Function, having a corresponding addressπPointer, ConStPtr, With BIOS entry Const.  if you Write your own I/Oπdrivers, you should assign the address of the corresponding driverπFunction or Procedure to the proper Pointer Variable.  Your questionπis a bit vague; what specific problems have you encountered?  Iπthink that my recollection is accurate; however, my old referencesπare in an attic in Pennsylvania, While I am here in Huntsville,πAlabama.  Perhaps someone else could confirm and/or amplify onπthese observations.π}π         14     09-26-9308:48ALL                      GAYLE DAVIS              Determine CPU Type       SWAG9311            20     └╫   Unit CPU;ππINTERFACEππTypeπ  CpuType = ( cpu8088,π              cpu8086,π              cpu80286,π              cpu80386,π              cpu80486,π              cpuPentium,π              cpuFutureπ             );π  CpuStrType = String[7];ππFunction GetCpuType : CpuType;π  { Returns the currently executing CPU type }ππFunction GetCpuTypeStr : CpuStrType;π  { Returns the currently executing CPU type as a string }ππIMPLEMENTATIONππConstπ  CpuTypeIdentified : Boolean = False;πVarπ  ConfirmedCpuType : CpuType;ππ{$L CPU.OBJ}ππ{$F+}πFunction WhichCPU : CpuType;π  { Determines and returns the currently executing CPU type }πEXTERNAL;π{$F-}ππProcedure IdentifyCpuType;π  { Handles initialization of CPU type }πBeginπ  If Not CpuTypeIdentified Thenπ  Beginπ    ConfirmedCpuType  := WhichCPU;π    CpuTypeIdentified := True;π  End;πEnd;   { Procedure IdentifyCpuType }ππFunction GetCpuType : CpuType;π  { Returns the currently executing CPU type }πBeginπ  IdentifyCpuType;π  GetCpuType := ConfirmedCpuType;πEnd;   { Function GetCpuType }ππFunction GetCpuTypeStr : CpuStrType;π  { Returns the currently executing CPU type as a string }πBeginπ  IdentifyCpuType;π  Case ConfirmedCpuType Ofπ    cpu8088    : GetCpuTypeStr := '8088';π    cpu8086    : GetCpuTypeStr := '8086';π    cpu80286   : GetCpuTypeStr := '80286';π    cpu80386   : GetCpuTypeStr := '80386';π    cpu80486   : GetCpuTypeStr := '80486';π    cpuPentium : GetCpuTypeStr := 'Pentium';π    cpuFuture  : GetCpuTypeStr := 'Future';π  End;   { Case }πEnd;   { Function GetCpuTypeStr }ππEnd.π{ eof CPU.PAS }πππNOTE  :    Cut the following code to a seperate file, and thenπ           USE XX34 to DECODE the block which contains CPU.OBJπ           needed with this unit.ππ*XX3401-000399-290893--68--85-63424---------CPU.OBJ--1-OF--1πU+s+14BkRKZYMLBh9Y3HHE466++++-lIRL7WPm--QrBZPK7gNL6U63NZQbBdPqsUAmsmπaMUI+21dBaTF4UlXQ5JdN43nPGt-Iop0W+A+ECZAZU6++4W6+k-+cNGK-U+2Eox2FIKMπ-k-6wk+0+E2WY+w+++26JoV7EoV1I3I+++1xW+E+E86-YO1r++2++-uAm6vMu-k+D+7xπ-SUk+CgFu2Y+D+Bw0iVV+1k2T+DcV++TmtmQKs5XzkxHbNlPUSA+w1D+UTg+w5E0g+8RπkkOAm6v+zPc-+9xM+90EiEA+wufwY70EGd0EWw65ktkD+S1Fq5A3i+A+ul0s+5-EbNlMπUCFki+6+R+3+bQC9y6jQNdlab4NMNUo+++E+NZ-abKOQNZVaeE++-+-o+t0EFqORWyC9πlwBab4NMNcjMNXI++0++NZ-abKOQNZVaIqORNWI++0++Nc5X+++U+4MvkrESY7-ai+2+π+++Dch5coSXFuB5coSXFuB5coSUZ1k11i+E+kumQ-E12GJE-zMc0++-oπ***** END OF XX-BLOCK *****πππ                                                                                  15     11-02-9305:41ALL                      KAI ROHRBACHER           AT Extended BIOS ??      SWAG9311            16     └╫   {πKAI ROHRBACHERππ  As  promised,  here  is  some  TP-code  to  check whether your machineπ  supports  the  extended timing services of the AT's-BIOS: if all worksπ  fine,  the  Program should give two beeps, the 2nd exactly 5secs afterπ  the 1st one -and then terminate.ππ  (To  all  others  reading  this:  this  timing  scheme  normally worksπ  _asynchrone_ to whatever you are doing in the "foreground" Program andπ  thus  is  great  For  timing  events.  What's  more:  the  clock has aπ  resolution of some microseconds!)π}ππConstπ  WaitTime = 5000;πVarπ  IsAT,π  TimeFlag  : Byte;π  CycleTime : LongInt;ππFunction AT : Boolean;π{ in: - }π{out: True/False, if the machine is (at least) an AT}πbeginπ  AT := MEM[$F000 : $FFFE] = $FC;πend;ππProcedure SetWaitingTime(milliseconds : Word);π{ in: milliseconds = time to wait in ms}π{out: CycleTime := that same value in microseconds}π{     TimeFlag  := $80}π{rem: won't work With PC's}πbeginπ  TimeFlag  := $80;π  CycleTime := LongInt(milliseconds) * LongInt(1000);π  if (milliseconds <> 0) and AT thenπ    IsAT := 0      {yes, use timing mechanism}π  elseπ    IsAT := $80;   {no, don't use that extended service}πend;ππProcedure Wait;πbeginπ  Asmπ    MOV AL, IsATπ    or  AL, ALπ    JNE @L11π    MOV TimeFlag,ALπ    MOV DX, Word PTR CycleTimeπ    MOV CX, Word PTR CycleTime+2π    MOV BX, OFFSET TimeFlagπ    MOV AX, DSπ    MOV ES, AXπ    MOV AX, 8300hπ    INT 15hπ   @L11:ππ   @L10:π    MOV AL, TimeFlag {look at bit 7: 1/0 = time over/not over}π    and AL, $80π    JE  @L10π  end;πend;ππbeginπ  if not AT thenπ  beginπ    WriteLN('Sorry, this Program requires the extended BIOS-' +π            'services, available on AT''s only!');π    Halt(1);π  end;π  WriteLN('The time between the two beeps should be exactly ', WaitTime,π          ' milliseconds!');π  Write(#7);π  SetWaitingTime(5000);π  Wait;π  Write(#7);πend.π                                                 16     11-02-9304:59ALL                      KAI ROHRBACHER           Which BIOS               SWAG9311            9      └╫   {πKAI ROHRBACHERππ> What bios are you using?πIt's  an AMI-BIOS, dated 03-06-1992; but I ran the same code on an oldπTandon-AT (with BIOS from 1987) w/o problems, too!ππ> Do you have any other timing code?πNot  at  hand;  one  could reProgram the trigger rate of timer 0 to beπfaster  than  1/18.2  sec,  but in my experience, this results in evenπmore incompatibilities when interfacing the Unit to others.π}ππFunction BIOScompatible : Boolean;πVarπ  Flag : Byte;π  p    : Pointer;πbeginπ  Flag := 0;π  p    := @Flag;π  if AT thenπ  Asmπ    STIπ    xor CX, CXπ    MOV DX, 1π    LES BX, pπ    MOV AX, 8300h  {trigger 1 microsecond}π    INT 15hπ   @L11:π  end;π  Delay(1); {wait 1 ms:}π  BIOScompatible := Flag = $80; {has flag been set?}πend;ππ{π  ...results  in  False  For you, I can't do much! However, I'll add theπ  above  routine to disable the timing mechanism in that Case to preventπ  the endless loop, at least.π}π                                                                                                     17     11-02-9316:11ALL                      LAURENT M. CHARTINIER    Quick Reset and BOOT     SWAG9311            3      └╫   {Laurent M. CHARTINIER}π{computer do a RESET using a small Pascal routine?}ππProcedure Reboot;πBeginπ Asmπ  JMP FFFF:0000π End;πEnd;ππ                                                                                                                          18     01-27-9411:55ALL                      RANDALL WOODMAN          CMOS Data                SWAG9402            64     └╫   {π» Does anyone know how to get the hard drive type(s) from CMOS ?π» I can't seem to find this information documented anywhere.ππThis is probably a lot more than you are asking for but. . .πNOTE: one function (Long2Str) is not defined in this because it comes fromπa commercial unit.  Basically all it does is convert a number to a stringπand return the string.π     This code comes from a unit I wrote to get all kinds of nifftyπinformation about your system.  I think I included everything you will needπto get it up and running.  If you get any strange problems or ones youπcan't seem to resolve, let me know and I'll see if I can pass you the rightπinformation.π}ππUsesπ  KMath,π  Dos;ππtypeπ  String80 = String[80];  { some general purpose string types }π  String40 = String[40];π  String30 = String[30];π  String20 = String[20];π  String12 = String[12];π  String10 = String[10];π  String5  = String[5];ππ  CMOSRec = Recordπ    Found     : Boolean;  { was a CMOS found to exist }π    CmosDate  : String30; { the date found in CMOS }π    CmosTime  : String30; { the time found in CMOS }π    VideoType : String10; { Type of video found in CMOS }π    Coproc    : Boolean;  { does CMOS report a math coprocessor }π    FloppyA   : String12; { type of floppy drive for A }π    FloppyB   : String12; { Type of floppy drive for B }π    Hard0     : Byte;     { Type of hard drive for drive 0 }π    Hard1     : Byte;     { Type of hard drive for Drive 1 }π    ConvenRam : Word;     { amount of conventional ram indicated }π    ExtendRam : Word;     { amount of extended Ram indicated }π    checkSum  : Boolean;  { Did checksum pass }π  end; { CMOS Rec }ππconstπ  { values of constants for CMOS }π  DayName: array[0..7] of string[9] = ('Sunday', 'Monday', 'Tuesday',π                                       'Wednesday', 'Thursday', 'Friday',π                                       'Saturday', 'Sunday');π  MonthName: array[0..12] of string[9] = ('???', 'January', 'February', 'March',π                                          'April', 'May', 'June', 'July',π                                          'August', 'September', 'October',π                                          'November', 'December');π  ScreenName: array[0..3] of string[10] = ('EGA/VGA', 'CGA 40col',π                                           'CGA 80col', 'Monochrome');π  FloppyName: array[0..5] of string[11] = ('none', '5.25" 360K',π                                           '5.25" 1.2M', '3.5"  720K',π                                           '3.5"  1.44M', '3.5"  2.88M');π  CMOSport : Byte = $70; { port to access the CMOS }ππ{===========================================================================}πππVARπ  Regs : Registers; { General purpose variable to access registers }π  CMOS : CMOSRec;   { variable to hold CMOS data }ππfunction nocarry : boolean;π{ returns the status of the carry flag }πbeginπ  nocarry:=regs.flags and fcarry = $0000πend; {nocarry}ππ{---------------------------------------------------------------------------}ππFunction ByteToWord(ByteA, ByteB : byte) : word;πbeginπ   ByteToWord := Word(ByteB) shl 8 + ByteAπend; {cbw}ππ{---------------------------------------------------------------------------}ππFunction BitIsSet(CheckWord : Word; AndValue : Word) : Boolean;π{ returns true if the bit(s) indicated in AndValue are set in CheckByte }πBEGINπ  BitIsSet := CheckWord AND AndValue = AndValue;πend;ππ{---------------------------------------------------------------------------}ππFunction ReadCMOS(addr: byte): byte;π{ read a value from the CMOS }πBeginπ  if CMOSport = $70 thenπ  beginπ    inline($FA);π    Port[CMOSport] := addr;π    readCMOS := Port[CMOSport + 1];π    inline($FB)π  endπend; {readCMOS}ππ{---------------------------------------------------------------------------}ππfunction addzero(b: byte): string5;πvarπ  c2: string[2];πbeginπ  Str(b:0, c2);π  if b < 10 thenπ    c2:='0' + c2;π  addzero:=c2πend; {addzero}ππ{---------------------------------------------------------------------------}ππFunction ChangeBCD(b: byte): byte;π{ change a BCD into a byte structure }πBeginπ  ChangeBCD:=(b and $0F) + ((b shr 4) * 10)πend; {ChangeBCD}ππ{---------------------------------------------------------------------------}ππFunction GetCMOSDate : String30;π{ gets the date found in the CMOS and returns it in string format }πVARπ  Date,π  Century,π  Year,π  Month : Byte;π  WorkStr : String30;πBEGINπ  WorkStr := '';π  date    := ChangeBCD(readCMOS(7));π  century := ChangeBCD(readCMOS($32));π  year    := ChangeBCD(readCMOS(9));π  month   := ChangeBCD(readCMOS(8));π  WorkStr := DayName[readCMOS(6)]+', ';π  {case country.DateFormat ofπ    0, 3..255 :}π      WorkStr := WorkStr + Monthname[month]+' '+IntToStr(date)+', '+IntToStr(century)+addzero(year);π {   1 :π      WorkStr := WorkStr + Long2Str(date)+', '+Monthname[month]+' '+Long2Str(century)+addzero(Year);π    2 :π      WorkStr := WorkStr + Long2Str(century)+addzero(Year)+', '+Monthname[month]+' '+Long2Str(date);π  end; {case}π  GetCMosDate := workStr;πend; { GetCMOSDate }ππ{---------------------------------------------------------------------------}ππFunction GetCmosTime : String30;π{ returns the time as found in the CMOS }πVARπ  CH : Char;π  Hour,π  Min,π  Sec  : Byte;π  WorkStr : String30;π  IsPM    : Boolean;πBEGINπ  workStr := '';π  hour := ChangeBCD(readCMOS(4));π  min := ChangeBCD(readCMOS(2));π  sec := ChangeBCD(readCMOS(0));π  IsPm := false;π  case hour ofπ        0: hour := 12;π        1..11: hour := hour;π        12: IsPM := true;π        13..23: beginπ                  IsPM := true;π                  hour := hour - 12π                end;π  end; {case}π  WorkStr := WorkStr + AddZero(hour)+':'+addzero(min)+':'+addzero(sec);π  if IsPM thenπ    workStr := WorkStr + ' PM'π  Elseπ    WorkStr := WorkStr + ' AM';π  GetCMOSTime := WorkStr;πend; { GetCmosTime }ππ{---------------------------------------------------------------------------}ππFunction GetCmosCheckSum : Boolean;π{ performs checksum on CMOS and returns true if ok }πVARπ  CheckSum1,π  CheckSum2 : word;π  Count     : Byte;πBEGINπ  checksum1 := 0;π  for count := $10 to $2D doπ    Inc(checksum1, readCMOS(count));π  checksum2 := (word(256) * readCMOS($2E)) + readCMOS($2F);π  if checksum1 = checksum2 thenπ    GetCmosCheckSum := trueπ  elseπ    GetCmosCheckSum := false;πend; { GetCmosCheckSum }ππ{---------------------------------------------------------------------------}ππProcedure GetCMos;π{ gets the cmos record if it exist }πVARπ  Floppy : Byte;πBEGINπ  FillChar(CMOS, SizeOf(CMos), 0);π  regs.AH:=$C0;π  Intr($15, regs);π  if nocarry or (Mem[$F000:$FFFE] <= $FC) thenπ  With CMOS DOπ  beginπ    Found := true;π    CMOSDate := GetCMOSDate;π    CMOSTime := GetCmosTime;π    VideoType := ScreenName[(readCMOS($14) shr 4) and 3];π    CoProc := BitIsSet(readCMOS($14), 2);π    Floppy := readCMOS($10);π    if (Floppy shr 4) < 5 thenπ      FloppyA := FloppyName[floppy shr 4]π    elseπ      FloppyA := 'Unknown '+ Byte2Hex(floppy shr 4);π    if (floppy and $0F) < 5 thenπ      FloppyB := FloppyName[floppy and $0F]π    elseπ      FloppyB := 'Unknown '+ Byte2Hex(floppy and $0F);ππ    Hard0 := readCMOS($12);π    Hard0 := Hard0 shr 4;π    Hard1 := ReadCmos($12);π    Hard1 := Hard1 and $0F;π    if Hard0 = $F thenπ      Hard0 := readCMOS($19)π    Else Hard0 := $FF; { error }π    if Hard1 = $F thenπ      Hard1 := readCMOS($1A)π    Else Hard1 := $FF;π    ConvenRam := word(256) * readCMOS($16) + readCMOS($15); { value in K }π    ExtendRam := word(256) * readCMOS($18) + readCMOS($17); { value in K }π    CheckSum := GetCmosCheckSum;π  endπ  elseπ    CMOS.Found := false;πend;ππbeginπ  GetCmos;π  Writeln(CMOS.Found);π  Writeln(CMOS.CmosDate);π  Writeln(CMOS.CmosTime);π  Writeln(CMOS.VideoType);π  Writeln(CMOS.Coproc);π  Writeln(CMOS.FloppyA);π  Writeln(CMOS.FloppyB);π  Writeln(CMOS.Hard0);π  Writeln(CMOS.Hard1);π  Writeln(CMOS.ConvenRam);π  Writeln(CMOS.ExtendRam);π  Writeln(CMOS.checkSum);πend.π                                                                                                               19     01-27-9411:56ALL                      ANDREW KEY               Color Monitor            SWAG9402            7      └╫   {π> I have always addressed $B800 as the screen segment for direct videoπ> writes in text.... Err, umm, does anyone have the code to detect whetherπ> it is $B000 or $B800 (for Herc.'s and the like)...π}ππFunction ColorAdaptor: Boolean; Assembler; {returns TRUE for color monitor}πasmπ  int 11                   {BIOS call - get equipment list}π  and ax, $0030            {mask off all but bits 4 & 5}π  xor ax, $0030            {flip bits 4 & 5 - return val is in ax}πend;ππ{πThis function uses a BIOS interrupt to get the equipment list(at $0000:$0410)πas determined at time of power-up.  The only problem I can see here is thatπa TRUE(non-zero value in al) will also be returned if no video card wasπdetected at power-up.π}                                           20     01-27-9411:56ALL                      DUSTIN NULF              CPU Speed                SWAG9402            14     └╫   {π>>> How can i determine the machine's CPU clock speed from a TPπ>>> program? An 100% accurate result is not required.ππ>> Use a counter and continually increase it. Check the clock and see howππ> There's a big problem : Newer CPUs are faster in executingπ> this commands and caching really speed's up the timer.π}ππCONSTπ  Cpu8086  = 1;π  Cpu80286 = 2;π  Cpu80386 = 3;π  Cpu80486 = 4;ππVARπ  CPU : BYTE;πππFUNCTION CPUSpeed : BYTE; Assembler;πAsmπ MOV   DX,Cpu8086π PUSH  SPπ POP   AXπ CMP   SP,AXπ JNE   @OUTπ MOV   DX, Cpu80286π PUSHFππ POP   AXπ OR   AX,4000hπ PUSH  AXπ POPFπ PUSHFπ POP   AXπ TEST  AX,4000hπ JE   @OUTπ MOV DX, Cpu80386π {"DB 66h" indicates '386 extended instruction}π DB 66h; MOV   BX, SP      {MOV EBX, ESP}π DB 66h, 83h, 0E4h, 0FCh   {AND ESP, FFFC}π DB 66h; PUSHF             {PUSHFD}π DB 66h; POP AX            {POP EAX}π DB 66h; MOV   CX, AX      {MOV ECX, EAX}π DB 66h, 35h, 00hπ DB 00h, 04h, 00           {XOR EAX, 00040000}π DB 66h; PUSH   AX     {PUSH EAX}ππ DB 66h; POPF              {POPFD}π DB 66h; PUSHF             {PUSHFD}π DB 66h; POP   AX     {POP EAX}π DB 66h, 25h, 00hπ DB 00h, 04h, 00h          {AND EAX, 00040000}π DB 66h, 81h, 0E1h, 00hπ DB 00h, 04h, 00h          {AND ECX, 00040000}π DB 66h; CMP   AX, CX      {CMP EAX, ECX}π JE @Not486π MOV DX, Cpu80486π@Not486:π DB 66h; PUSH   CX         {PUSH EXC}π DB 66h; POPF              {POPFD}π DB 66h; MOV   SP, BX      {MOV ESP, EBX}π@Out:π MOV AX, DXπend;πππbegin { main }πππ  Writeln(CPUSpeed);  { 1, 2, 3, or 4 is returned; see above consts }πππend.ππ                                                                                                                      21     01-27-9411:57ALL                      WILLIAM PLANKE           device Driver Lists      SWAG9402            46     └╫   {πI've posted a working util that lists the Device Drivers that are resident inπmemory.  It uses the header record to point to the next driver in the chainπand "walks" the memory chain until an offset end flag is reached.  Hope youπenjoy it and that it isn't too sloppy.  At the end, I have a question thatπneeds to be answered if you're interested....π}ππprogram DevList;ππ{ this program walks the device driver memory chain. Each deviceπ  driver points to the next until the ENDFLAG is reached.  I useπ  the popular undocumented DOS function $52 to jump to the DOSπ  "List of Lists" then $22 bytes beyond that, the first device inπ  the chain (NUL) can be found.ππ  Thanks to Ralf Brown and his valuable MS DOS Interrupts List,π  to Timo Salmi, and to the person(?) who wrote the coolπ  hex-to-string conversion functions that I use all the time.π}ππ{$M 8192,0,0}ππusesπ  DOS;ππtypeπ  pstrg = string[9];                { pointer conversion format }ππ  Array8C = array [1..8] of char; { for device and file names }ππ  DevRec = recordπ    NextDev_ofs  : word; {pointer to next device header, offset value}π    NextDev_seg  : word; {pointer to next device header, segment value}π    Attributes   : word; {Attributes: block or char, IOCTL, etc.}π    Strategy     : word; {pointer to device strategy routine, offset}π    Interrupt    : word; {pointer to device interrupt routine, offset}π    NameDev      : Array8C; {Name if char, or units if block}π  end;π  DevPtr = ^DevRec;ππ  DevFileRec = recordπ    FileName : Array8C;π  end;π  DevFilePtr = ^DevFileRec;ππconstπ  LOL_HEADDEV_NUL  = $22; { offset from "List of Lists"π                            to NUL device header }π  FNAME            = $8;π  ENDFLAG          = $FFFF;π  STDDEVS : array [1..12] of Array8C =π    ('NUL     ', 'CON     ', 'AUX     ', 'PRN     ',π     'CLOCK$  ', 'COM1    ', 'COM2    ', 'COM3    ',π     'COM4    ', 'LPT1    ', 'LPT2    ', 'LPT3    ');ππvarπ  r       : registers;π  i,        { index }π  Adjust  : byte;π  Header  : DevPtr;π  DevFile : DevFilePtr;π  Valid,π  Done    : boolean;πππfunction BinW(Decimal : word) : string;πconstπ  BINDIGIT : array [0..1] of char = '01';πvarπ  i     : byte;π  Binar : string;πbeginπ  fillchar (binar, sizeof(Binar), ' ');π  Binar [0] := chr(16);π  for i := 0 to 15 doπ    Binar[16-i] := BINDIGIT[(Decimal shr i) and 1];π  BinW := Binar;πend;πππfunction HexN (b : byte) : char;        { convert nibble to char }πbeginπ  b := b and 15;                   { forces to only 4 bits }π  if b > 9 thenπ     inc(b,7);                    { adjust for hex digits };π  HexN := chr(b+48);              { convert to character }πend;πππfunction HexB(b : byte) : string;πbeginπ  HexB := HexN (b shr 4) + HexN (b);  { assemble the nibbles }πend;πππfunction HexW(w : word) : string;πbeginπ{$R-}π  hexw := HexB(w shr 8) + HexB(w);  { assemble the bytes }π{$R+}πend;πππfunction HexL(l : longint) : string;πbeginπ  HexL := HexW(l shr 16) + HexW(l); { assemble the words }πend;πππfunction XP(p : pointer) : pstrg;         { display pointer P }πbeginπ  XP := HexW(seg(p^)) + ':' + HexW(ofs(p^));πend;ππbeginπ  assign(output, '');π  rewrite(output);     { allow command line redirection }π  writeln('Device':0, 'Address':12, 'Strat':10, 'Intrpt':8,π          'Attrib':10, 'File Name':23);π  for i := 1 to 69 doπ    write('-');π  writeln;ππ  with r doπ  beginπ    es := 0;π    bx := 0;π    ah := $52;π    { this is an undocumented DOS function call:π      Get pointer to DOS "List of Lists" }π    msdos (r);π    { es and bx now have values }π    if (es = 0) and (bx = 0) thenπ      halt(0);ππ    Header := ptr(es, bx + LOL_HEADDEV_NUL); { we get NUL dev from this }π  end; {with}ππ  Done := FALSE; { dummy variable to keep the repeat loop going,π                    otherwise would have to duplicate the outputπ                    routines one more time for the final device. }π  repeatπ    with Header^ doπ    beginπ      Adjust := 0;π      { adjust keeps display columns aligned, bit 15 set is a Characterπ        device, if clear it is a Block device and 1st byte is # of blockπ        devs supported}ππ      if boolean ((Attributes shr 15) and 1) = TRUE thenπ        write (NameDev)π      elseπ      beginπ        write ('BLKdev=', byte (NameDev[1]));π        Adjust := byte (NameDev[1]) div 10;π      end;ππ      write(XP(Header) : 12 - Adjust);π      write(HexW(Strategy) : 7);π      write(HexW(Interrupt) : 7);π      write(HexW(Attributes) : 7, '=');π      write(BinW(Attributes));ππ      { this next section I can't find documented anywhere, but I observed itπ        and decided to include it anyway, with MSDOS v5.0, others are unknown.π        The file name's extension isn't saved and doesn't matter, either. }ππ      if ofs(Header^) < FNAME thenπ      { "borrow" from the segment and give it to the offset }π        DevFile := ptr(seg(Header^) - $1, ofs(Header^) + $10 - FNAME)π      elseπ        DevFile := ptr(seg(Header^), ofs(Header^) - FNAME);ππ      Valid := TRUE;π      for i := 1 to 12 doπ        if DevFile^.FileName = STDDEVS[i] thenπ          Valid := FALSE;ππ      if Valid thenπ        for i := 1 to 8 doπ          if not (DevFile^.Filename[i] in [' '..'z']) thenπ            Valid := FALSE;ππ      if {still} Valid thenπ        write ('  ', DevFile^.FileName);ππ      writeln;π      if NextDev_ofs = ENDFLAG thenπ        exit; { end of the device chain }ππ      Header := ptr(NextDev_seg, NextDev_ofs);ππ    end; {with}π  until Done;πend.π{πThe question: I have seen utils that do this actually give the size ofπthe driver in memory.  MSD and PMap both do this.  Does anybody knowπhow I can determine the size of the driver in memory?π}                                                                                                          22     01-27-9411:58ALL                      HELGE HELGESEN           HD Type                  SWAG9402            4      └╫   {π> Does anyone know how to get the hard drive type(s) from CMOS ?π}ππFunction GetFixedDrive(DriveNum : Byte) : Byte; Assembler;πAsmπ  mov  al, DriveNumπ  and  al, 1π  add  al, $19π  out  $70, alπ  in   al, $71πend;ππ{πYou specify what drive you want (0/1) and you'll get theπdisk type as specified in CMOS.π}ππbeginπ  Writeln(GetFixedDrive(3));πend.                                  23     01-27-9412:12ALL                      THORSTEN BARTH           Port Info                SWAG9402            18     └╫   {π> Can anybody give me any info on how to read signals from pins on sayπ> COM2: or from LPT1: or even from The joystick port? I think it hasπ> been done with the PORT command or something, but what are the valuesπ> to use to read them with? Thanks.ππYou can read in signals from different pins on LPT ports with the PORTπcommand ( =OUT/IN command in assembler). Just determine the base adress ofπthe LPT port usingπ}ππ  LPTadress := MemW[$40 : 6 + LPTNr * 2];ππ{πwhere LPTNr is the number of the LPT port from 1 to 3.ππShould return 03BCh, 0378h or 0278h.πThat has to be done once at the beginning of the program.πNow you can start to read/write values on this port.πThe LPT port has:ππ- 8 data outputs (pin 2 to 9), which can be written usingπ}ππ  Port[LPTAdress] := B;ππ{πwhere B is a byte consisting of the 8 bits. Voltage will be 5V for 1, and 0Vπfor 0. (but not very high power available (TTL/CMOS)ππ- 4 handshake outs which can be written byπ}ππ  Port[LPTAdress + 2] := B;ππ{πwhere B is a byte with the lowest 4 bits set to the values of the pins andπthe higher 4 bits always set to zero.ππ        PIN  1: Strobe --> bit 0π        PIN 14: AutoFD --> bit 1π        PIN 16: Init   --> bit 2π        PIN 17: SelIN  --> bit 3ππ        Attention! bit 2/pin 16 is 0V when set to zero, all othersπ        are INVERTED! (0 --> 5V and vice versa)ππ- 5 handshake inputs which can be read byπ}ππ     B := Port[LPTAdress + 1];ππ{π     After the command, B contains the signals that are connected to theπ     input pins of the LPT port:π        Bit 0-2: no functionπ        Bit 3 --> PIN 15/Errorπ        Bit 4 --> PIN 13/Selectπ        Bit 5 --> PIN 12/PaperEmptyπ        Bit 6 --> PIN 10/Acknowledgeπ        Bit 7 --> PIN 11/Busy     ===> Attention! This input is INVERSE!ππ For information: The pins 18 to 25 are Signal Ground pins.π To use the inputs, connect TTL level 0V for 0, and 5V for 1 to them.π (Or just use a resistor 10kOhm against +5V (take it from the keyboardπ connector or so, don't know what pin that is :-( and a switch against GND:π then you can read in the status of the swith: CLOSED: 0, OPEN: 1...)π}                                                          24     01-27-9412:18ALL                      MARK LEWIS               Port Addresses           SWAG9402            18     └╫   {π> does anybody knows the address for serial/parallel ports?ππyou can find them by reading the 7 (seven) WORDs starting at address 0040:0000π<smile>...π}ππCONSTπ  BIOSBASE : word = $0040;π  PORTADDR : word = $0000;ππVARπ  COM1, COM2,π  COM3, COM4,π  LPT1, LPT2, LPT3 : word;ππBEGINπ  COM1 := memw[BIOSBASE:PORTADDR+0];π  COM2 := memw[BIOSBASE:PORTADDR+2];π  COM3 := memw[BIOSBASE:PORTADDR+4];π  COM4 := memw[BIOSBASE:PORTADDR+6];π  LPT1 := memw[BIOSBASE:PORTADDR+8];π  LPT2 := memw[BIOSBASE:PORTADDR+10];π  LPT3 := memw[BIOSBASE:PORTADDR+12];πEND.ππ{πRICHARD BROWNEππ>I guess I can declare an absolute variable at $40:$0000 and use offset to fiπ>the addresses.  Just a guess - haven't tried it yet. Thanks for your help.ππDo this, it works.  When you WRITELN the variables to theπscreen, they will be in decimal.  If you convert them to hex,πyou'll see that they are the old, familiar addresses.  If anyπvariable is zero, there is no port present in your computer.ππAnother thing you'll notice, if you have com4, for instance, butπno com3.  The normal com4 address will show up in the com3πmemory location, and the com4 adderess will be 0.  Whichπexplains why funny things happen when you are using ports 1, 2πand 4 with no 3, or 1 and 3 with no 2, etc., and why we are toldπto always have consecutive com ports, with no "missing" numbers.π}πprogram testadr;πvarπ   com1adr : Word Absolute $0040:$0000; { Get COM1 Port address }π   com2adr : Word Absolute $0040:$0002; { Get COM2 Port address }π   com3adr : Word Absolute $0040:$0004; { Get COM3 Port address }π   com4adr : Word Absolute $0040:$0006; { Get COM4 Port address }π   lpt1adr : Word Absolute $0040:$0008; { Get LPT1 Port address }π   lpt2adr : Word Absolute $0040:$000A; { Get LPT2 Port address }π   lpt3adr : Word Absolute $0040:$000C; { Get LPT3 Port address }ππbeginπ   writeln('com1 address: ',com1adr);π   writeln('com2 address: ',com2adr);π   writeln('com3 address: ',com3adr);π   writeln('com4 address: ',com4adr);π   writeln('lpt1 address: ',lpt1adr);π   writeln('lpt2 address: ',lpt2adr);π   writeln('lpt3 address: ',lpt3adr);π   readln;πend.π                                                             25     01-27-9413:31ALL                      GREG VIGNEAULT           CPU/FPU processor type   SWAG9402            20     └╫   (*-------------------------------------------------------------------*)π UNIT CPUID; {CPUID.PAS} { determine CPU and FPU processor types }π Interface               { Copyright 1992 Gregory S. Vigneault }ππ Const        CpuType :Array[0..10] of String[7] = ('8088','8086','NEC V20',π        'NEC V30','80186','80188','80286','386DX','386SX','486DX','486SX');ππ        FpuType :Array[0..4] of String[5] = ('None','8087','80287','80387',π        '80487');ππ FUNCTION GetCPU( VAR FPUtype :BYTE ) :BYTE;π { GetCPU codes:π    0 = 8088      |   6 = 80286π    1 = 8086      |   7 = 386DX   or older/undetected 386SXπ    2 = NEC V20   |   8 = 386SX   * not always detected in all modesπ    3 = NEC V30   |   9 = 486DX   or (486SX with 487SX)π    4 = 80186     |   10= 486SXπ    5 = 80188     |π  FPUtype codes: 0 = noneπ                 1 = 8087π                 2 = 80287π                 3 = 80387   * 387DX or 387SXπ                 4 = 80487   * 487SX or 486DXπ                 17= undetermined copro reported by BIOS }π Implementation  { Mar.9.92 }π {$L GETCPU.OBJ}π FUNCTION GetCPU( VAR FPUtype :BYTE ) :BYTE; EXTERNAL;π END.    { Unit CPUID }π(*-------------------------------------------------------------------*)π(*-------------------------------------------------------------------*)π PROGRAM ProcessorID; {PID.PAS   determine CPU & FPU (NDP) types }π USES    CPUID;π VAR     FPUtype, CPUtype     :BYTE;π BEGINπ        WriteLn( #10,' PID v0.2, 1992 G.S.Vigneault',#10);π        Write(' CPU type: ');π        CASE GetCPU( FPUtype ) OFπ            0   : WriteLn('8088');π            1   : WriteLn('8086');π            2   : WriteLn('NEC V20');π            3   : WriteLn('NEC V30');π            4   : WriteLn('80188');π            5   : WriteLn('80186');π            6   : WriteLn('80286');π            7   : WriteLn('386DX');π            8   : WriteLn('386SX');π            9   : WriteLn('486DX');π            10  : WriteLn('486SX')π            END; {case GetCPU}π        Write(' FPU type: ');π        CASE FPUtype OFπ            0   : WriteLn('none');π            1   : WriteLn('8087');π            2   : WriteLn('80287');π            3   : WriteLn('80387');π            4   : WriteLn('80487');π            17  : WriteLn('in equipment byte');π            END; {case FPUtype}π END.    {ProcessorID}π(*-------------------------------------------------------------------*)π                                                              26     02-03-9409:19ALL                      DAVID GWILLIM            Complete BIOS Table      SWAG9402            36     └╫   {π  This is a complete map of PC, XT, AT, PS/2 and EGA-installed dataπ  areas between 0400h and 0500h in the low memory segment put into theπ  form of a Turbo Pascal 4/5/5.5 compatible unit.ππ  I found myself needing one or two of these absolute addresses from timeπ  to time and got tired of looking them up. Using a record structureπ  declared as absolute variable relieves you of specifying theπ  individual addresses for each variable, providing that all the Resrvedπ  areas are included too.ππ  I hope this saves all those Turbo Pascal programmers out there some timeπ  and lets them get on with the creative side of the business. Enjoy!ππ  David Gwillimπ  159 Woodbury Roadπ  Hicksville, NY 11801-3030π  (516) 942-8697ππ  6 August 1989ππ  CREDITS:ππ  The absolute addresses for this unit came from "The Programmer's PCπ  Sourcebook" by Thom Hogan, published by Microsoft Press.π  ISBN 1-55615-118-7. List price $24.95 USA.ππ  This book is very helpful (apart from a few inevitable) typos). Iπ  consider it an essential purchase for any programmer who has to dealπ  with a PC at the hardware level.ππ}ππunit Bios;ππinterfaceππvarπ   BiosSeg : recordπ      ComBase : array[1..4] of word;π      LptBase : array[1..4] of word;π      InstalledHardware : array[1..2] of byte;π      POST_Status : byte;      { Convertible only }π      MemorySize : word;π      _RESERVED1 : word;π      KeyboardControl : array[1..2] of byte;π      AlternateKeypadEntry : byte;π      KeyboardBufferHeadPtr : word; { points to first char in type-ahead buffer }π      KeyboardBufferTailPtr : word; { points to last char in type-ahead buffer }π      KeyboardBuffer : array[1..16] of word;π      FloppyRecalStatus : byte;π      FloppyMotorStatus : byte;π      FloppyMotorOffCounter : byte;π      FloppyPrevOpStatus : byte;π      FloppyControllerStatus : array[1..7] of byte;π      DisplayMode : byte;π      NumberOfColumns : word;π      RegenBufferLength : word;π      RegenBufferAddress : word;π      CursorPosition : array[1..8] of word;π      CursorType : word;π      CurrentDisplayPage : byte;π      VideoControllerBaseAddress : word;π      Current3x8Register : byte;π      Current3x9Register : byte;π      PointerToResetCode : pointer;  { PS/2 only - except model 30 }π      _RESERVED2 : byte;π      TimerCounter : longint;π      TimerOverflowFlag : byte;  { non-zero means timer passed 24 hours }π      BreakKeyState : byte;π      ResetFlag : word;  { $1234=bypass mem test; $4321=preserve mem (PS/2) }π                         { $5678=system supended (Convertible) }π                         { $9ABC=manufacturing test (Convertible) }π                         { $ABCD=system POST loop (Convertible only) }π      FixedDiskPrevOpStatus : byte;π      NumberOfFixedDrives : byte;π      FixedDiskDriveControl : byte;   {XT only}π      FixedDiskControllerPort : byte; {XT only}π      LptTimeOut : array[1..4] of byte;  { [4] valid for PC, XT and AT only }π      ComTimeOut : array[1..4] of byte;π      KeyboardBufferStartOffsetPtr :word;π      KeyboardBufferEndOffsetPtr :word;π      VideoRows : byte;π      CharacterHeight : word;  { bytes per character }π      VideoControlStates : array[1..2] of byte;ππ      _RESERVED3 : word;π      MediaControl : byte;π      FixedDiskControllerStatus : byte; { AT, XT after 1/10/85, PS/2 only }π      FixedDiskControllerErrorStatus : byte; { AT, XT after 1/10/85, PS/2 only }π      FixedDiskInterruptControl : byte; { AT, XT after 1/10/85, PS/2 only }π      _RESERVED4 : byte;π      DriveMediaState : array[0..1] of byte;π      _RESERVED5 : word;π      DriveCurrentCylinder : array[0..1] of byte;π      KeyboardModeState : byte;π      KeyboardLEDflags : byte;π      UserWaitCompleteFlagAddress : pointer;π      UserWaitCount : longint;   { micro-seconds }π      WaitActiveFlag : byte;π      _RESERVED6 : array[1..7] of byte;π      VideoParameterTable : pointer;          { EGA and PS/2 only }π      DynamicSaveArea : pointer;              { EGA and PS/2 only }π      AlphaModeAuxCharGenerator : pointer;    { EGA and PS/2 only }π      GraphicsModeAuxCharGenerator : pointer; { EGA and PS/2 only }π      SecondarySaveArea : pointer;            { PS/2 only (not Model 30) }π      _RESERVED7 : array[1..4] of byte;π      _RESERVED8 : array[1..64] of byte;π      PrintScreenStatus : byte;π   end absolute $0040:$0000;ππimplementationππend.ππππ                                                                                                                             27     02-03-9416:18ALL                      STEVE ROGERS             Disabling PrtScr         SWAG9402            5      └╫   π{  Anyone have any idea why this won't disable PrtScr? }ππusesπ  crt,dos;ππvarπ  i : word;π  old_status : byte;π  prt_status : byte absolute $0040:$0100; { PrtScr status byte }ππbeginπ  old_status:= prt_status;π  prt_status:= 1;π  for i:= 1 to 20 do writeln(' This is line ',i);π  writeln;π  writeln('Press PrtScr to test, any other key to exit');π  readkey;π  prt_status:= old_status;πend.π