home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 15 / CD_ASCQ_15_070894.iso / maj / swag / comm.swg < prev    next >
Text File  |  1994-05-27  |  189KB  |  2 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00045         COMMUNICATIONS/INT14 ROUTINES                                     1      05-28-9313:35ALL                      SEAN PALMER              Routines for AVATAR      IMPORT              35     ╣J╜╝ {πSEAN PALMERππ> Would you mind sharing that source w/us? I would like toπ> add AVATAR support to my doors, yet don't have those FSC docs.ππHere are some FSC Docs I got off a FIDO echo...ππThe basic commands are:   (AVT/0 FSC-0025)ππ   <^L>    -       clear the current Window and set current attributeπ                   to default. In the basic session this means:π                   Clear the screen and set its attribute to 3.ππ   <^Y>    -       Read two Bytes from the modem. Send the first oneπ                   to the screen as many times as the binary valueπ                   of the second one. This is the exception whereπ                   the two Bytes may have their high bit set. Doπ                   not reset it here!ππ   <^V> <^A> <attr> - Set the color attribute to <attr>. The defaultπ                   attribute remains unchanged. However, all Textπ                   will be displayed in <attr> Until the next ^V^A,π                   ^V^B, or ^L.ππ   <^V> <^B>   -   Turn the high bit of current attribute on. Inπ                   other Words, turn blink on.ππ   <^V> <^C>   -   Move the cursor one line up. Do nothing, if youπ                   already are at the top line of the currentπ                   Window.ππ   <^V> <^D>   -   Move the cursor one line down. Do nothing if youπ                   already are at the bottom line of the currentπ                   Window.ππ   <^V> <^E>   -   Move the cursor one column to the left. Do nothingπ                   if you already are at the leftmost column of theπ                   current Window.ππ   <^V> <^F>   -   Move the cursor one column to the right. Do nothingπ                   if you already are at the rightmost column of theπ                   current Window.ππ   <^V> <^G>   -   Clear the rest of the line in the current Windowπ                   using the current attribute (not to be confusedπ                   With the default attribute).ππ   <^V> <^H> <row> <col>   - Move the cursor to the <row> <col>π                   position Within the current Window.ππNew Commands (brief definitions) (AVT/0+ FSC-0037)ππ   <^V><^I>     -  Turn insert mode ON. It stays on Until any other AVT/0π                   command except <^Y> and <^V><^Y> is encountered afterπ                   which it is turned off;ππ   <^V><^J><numlines><upper><left><lower><right> - scroll area up;ππ   <^V><^K><numlines><upper><left><lower><right> - scroll area down;ππ   <^V><^L><attr><lines><columns>  - clear area, set attribute;ππ   <^V><^M><attr><Char><lines><columns>  - initialize area, set attribute;ππ   <^V><^N>     -  delete Character, scroll rest of line left;ππ   <^V><^Y><numChars><Char>[...]<count>  -  Repeat pattern.ππand here is some source I use For AVATAR codes.π}ππUnit Avatar;  {these Functions return avatar codes as Strings}πInterfaceππ{AVT/0+ FSC-0025}ππConstπ clearScr : String = ^L;π blink    : String = ^V^B;π up       : String = ^V^C;π dn       : String = ^V^D;π lf       : String = ^V^E;π rt       : String = ^V^F;π cleol    : String = ^V^G;ππFunction rep(c : Char; b : Byte) : String;πFunction attr(a : Byte) : String;πFunction goxy(x, y : Byte) : String;ππ{AVT/0+ FSC-0037}ππConstππinsMode : String = ^V^I;πdelChar : String = ^V^N;ππFunction scrollUp(n, l, t, r, b : Byte) : String;πFunction scrollDn(n, l, t, r, b : Byte) : String;πFunction clear(a, w, h : Byte) : String;πFunction fill(c : Char; a, w, h : Byte) : String;πFunction pattern(s : String; n : Byte) : String;ππImplementationππFunction rep(c : Char; b : Byte) : String;πbeginπ  rep := ^Y + c + Char(b);πend;ππFunction attr(a : Byte) : String;πbeginπ  attr := ^V^A + Char(a and $7F);πend;ππFunction goxy(x, y : Byte) : String;πbeginπ  goxy := ^V^H + Char(y) + Char(x);πend;ππFunction scrollUp(n, l, t, r, b : Byte) : String;πbeginπ  scrollUp := ^V^J + Char(n) + Char(t) + Char(l) + Char(b) + Char(r);πend;ππFunction scrollDn(n, l, t, r, b : Byte) : String;πbeginπ  scrollDn := ^V^K + Char(n) + Char(t) + Char(l) + Char(b) + Char(r);πend;ππFunction clear(a, w, h : Byte) : String;πbeginπ  clear := ^V^L + Char(a) + Char(h) + Char(w);πend;ππFunction fill(c : Char; a, w, h : Byte) : String;πbeginπ  fill := ^V^M + c + Char(a) + Char(h) + Char(w);πend;ππFunction pattern(s : String; n : Byte) : String;πbeginπ  pattern := ^V^Y + s[0] + s + Char(n);πend;ππend.ππ                             2      05-28-9313:35ALL                      SWAG SUPPORT TEAM        Carrier Detect           IMPORT              6      ╣J:∙ {π>Does anyone know how to detect when the modem connects?? Thanks.ππThrough the BIOS:π}ππFunction CarrierDetected(Port : Word) : Boolean;πConstπ  DCD = $80;πVarπ  Dummy : Byte;πbeginπ  Asmπ    dec portπ    mov ah,03hπ    mov dx,portπ    int 14hπ    mov dummy,alπ  end;π  CarrierDetected := (Dummy and DCD) = DCD       { carrier detected }πend;ππ{ Or directly: }ππFunction CarrierDetected(Port : Byte) : Boolean;πbeginπ  Case Port ofπ    1: CarrierDetected := ($3FE and $80) = $80;   { com 1 cd }π    2: CarrierDetected := ($2FE and $80) = $80    { com 2 cd }π  endπend;π                                                                     3      05-28-9313:35ALL                      SWAG SUPPORT TEAM        Chat                     IMPORT              43     ╣J╕ {π> Otherwise, how could I tell the difference between the local users inputπ> and the remote users input??? If I knew that I guess I could Write myπ> own chat Procedure.ππWell, I definately agree With you there.. Here's some ugly codeπI put into my doors, it's a chat Procedure, not With all the features I'd like,πbut it works, anyway..  (BTW, I'm working on a split screen version now, butπthat'll take some time as I'm very busy these days..)  This is a dump from partπof my SYSKEY.INC include File..π}ππ{$F+}ππ(* This include File is where you will take actions you define when trappedπ   keys such as ALT-keys, Function-keys, etc., are pressed.ππ   You will need to setup your Procedures here which in turn may call otherπ   Procedures within your code or you may do all you need to do right here.ππ   For example, if you wanted to trap For ALT-C being pressed on the localπ   keyboard and then call the Procedure CHAT:ππ   Your main block of code might look like this:ππ   begin  {main}π      ASSIGN(Output,'') ;π      REWrite(Output) ;π      SysopKey[1] := #0 + #46 ;   {define ALT-C as one of twenty keys }π                                  {to trap                            }π      SysopProc[1] := ALT_C ;     {define Procedure as defined here   }π      SysopKey ;                  {setup For Far call to this File    }π   end ;ππ   Now, whenever ALT-C is pressed, the following Procedure will be called:ππ   Procedure ALT_C ;π   beginπ      CHAT ;                      {call Procedure CHAT which is located }π   end ;                          {within your Program's code           }ππ   *)ππ(*π   The following Procedures are called when up/down arrows are pressedπ   provided they are defined using SysopKey[] and SysopProc[] withinπ   the main Program codeπ*)ππProcedure end_Chat;ππbeginπ  Chatended := True;π  { Do some other stuff here if you'd like }πend;ππProcedure Chat;ππConstπ  FKeyCode          = #0;π  Space             = ' ';π  Hyphen            = '-';π  BackSpace         = ^H;π  CarriageReturn    = ^M;π  MaxWordLineLength = 80;ππVarπ  WordLine  : String[MaxWordLineLength];π  Index1    : Byte;π  Index2    : Byte;π  InputChar : Char;π  F         : Text;ππLabel Get_Char;ππbegin {WordWrap}π  If LocalKey Thenπ    SetColor(0,14,0)π  Elseπ    SetColor(0,3,0);π  UserKeysOn := False;π  WordLine  := '';π  Index1    := 0;π  Index2    := 0;π  InputChar := Space;π  ClearScreen;π  Display(0,3,0,'');π  Display(0,12,0,'Sysop Entering Chat Mode: ');π  InputChar := GetChar;π  If LocalKey Thenπ    SetColor(0,14,0)π  Elseπ    SetColor(0,3,0);π  InactiveVal := 0;ππ  While  (NOT Chatended)π  do beginπ    If LocalKey Thenπ      SetColor(0,14,0)π    Elseπ      SetColor(0,3,0);π    Case InputChar OFπ      BackSpace: {Write destructive backspace & remove Char from WordLine}π        beginπ          If LocalKey Thenπ            SetColor(0,14,0)π          Elseπ            SetColor(0,3,0);π          sDisplay(0,7,0,BackSpace+Space+BackSpace);π          DELETE(WordLine,(LENGTH(WordLine) - 1),1)π        endπ      else {InputChar contains a valid Char, so deal With it}π      beginπ        If ( InPutChar = Chr(13) ) Thenπ        beginπ          If LocalKey Thenπ            Display(0,14,0,InputChar)π          Elseπ            Display(0,3,0,InputChar);π        endπ        Elseπ        beginπ          If LocalKey Thenπ            sDisplay(0,14,0,InputChar)π          Elseπ            sDisplay(0,3,0,InputChar);π        end;π        If InputChar <> Chr(13) Thenπ          WordLine := (WordLine + InputChar)π        Elseπ          WordLine := '';π        if (LENGTH(WordLine) >= (MaxWordLineLength - 1)) then {we have to do a Word-wrap}π        beginπ          Index1 := (MaxWordLineLength - 1);π          While ((WordLine[Index1] <> Space) and (WordLine[Index1] <> Hyphen) and (Index1 <> 0)) DOπ            Index1 := (Index1 - 1);π          if (Index1 = 0) {whoah, no space was found to split line!} thenπ            Index1 := (MaxWordLineLength - 1); {forces split}π          DELETE(WordLine, 1, Index1);π          For Index2 := 1 to LENGTH(WordLine) DOπ            sDisplay(0, 7, 0, BackSpace + Space + BackSpace);π          Display(0,3,0,'');π          If InPutChar = Chr(13) thenπ          beginπ            If LocalKey Thenπ              Display(0,14,0,WordLine)π            Elseπ              Display(0,3,0,WordLine);π          endπ          Elseπ          beginπ            If LocalKey Thenπ              sDisplay(0,14,0,WordLine)π            Elseπ              sDisplay(0,3,0,WordLine);π          end;π        endπ      endπ    end; {CASE InputChar}π    {Get next key from user.}π    Get_Char:π    beginπ     InputChar := GetChar;π     If ( WordLine = '' ) and ( InputChar = Chr(13) ) Thenπ      beginπ       Display(0,3,0,'');π       Goto Get_Char;π      end;π    end;π  end; {WHILE ( not (Chatended) )}π  Display(0, 12, 0, 'Sysop Left Chat Mode.');π  If (NOT Registered) Thenπ  DisplayLoc(0, 7, 0, '■ If you find this Program of value, please register.');π  Delay(2500);π  Display(0, 15, 0, 'Press ( '+#17+'──┘ ) to Continue . . .');π  ClearScreen;π  Chatended := False;π  InactiveVal := 30;π  UserKeysOn := True;πend;π{πThere.. let me know if you need any clarification..  (BTW, you need globalπVariables Chatended and Registered as Booleans in the main program..π}                                                                                     4      05-28-9313:35ALL                      SWAG SUPPORT TEAM        Communications Port      IMPORT              13     ╣J«X {  >1. Let me look at the RING line from the modemπ  >2. Let me determine the condition of CARRIER DETECT.ππ The Modem Status Register (MSR) Byte contains this info.ππ Carrier Detect:  MSR bit 7 will be set it there is a carrierπ detected.  Bit 3 indicates if there has been a change in theπ carrier detect status since the last time the MSR was read.ππ Ring:  is indicated by MSR bit 6.  Bit 2 indicates if thereπ was a change in bit 6 since the last time the MST was read.ππ Bits 2 and 3 are cleared each time the MSR is read.ππ Obtaining the MSR Byte may be done by directly reading theπ port value, or by calling the BIOS modem services interrupt $14.ππ I've Typed in the following without testing.ππ Using the BIOS...ππ        ...π}πFunction GetMSR( COMport :Byte ) :Byte;π{ call With COMport 1 or 2 }πVarπ  Reg : Registers;πbeginπ  Reg.DX := COMport - 1;π  Reg.AH := 3;π  Intr( $14, Reg );π  GetMSR := Reg.ALπend;π(*π...πMSRByte := GetMSR(1);   { MSR For COM1 (clears bits 0..3) }π...ππ Using direct access: For COM1, the MSR is at port $3FE; For COM2π it's at $2FE...ππ        ...π        MSRByte := Port[$3FE];  { MSR For COM1 (clears bits 0..3) }π        ...ππ To test the status...ππ        ...π*)πIF ( MSRByte and $80 ) <> 0 thenπ  CarrierDetect := TrueπELSEπ  CarrierDetect := False;πIF ( MSRByte and $40 ) <> 0 thenπ  Ring := True;πELSEπ  Ring := False;π{ππ Similar logic can be used With bits 2 and 3, which will informπ you of whether or not a change occurred in bit 6 or 7 since theπ last read of the MSR.π}             5      05-28-9313:35ALL                      SEAN PALMER              Another Carrier Detect   IMPORT              4      ╣J₧ß {πAuthor: Sean Palmerππ> Does anyone know how to detect when the modem connects?? Thanks.ππCheck For a carrier: (periodically, like 2-4 times per second)π}ππConstπ  pBase = $3F8;  {change For which port you're using}π  pMSR  = pBase + 6; {modem status register}ππFunction carrier : Boolean;πbeginπ  carrier := (port[pMSR] and $80) <> 0;πend;ππ                                         6      05-28-9313:35ALL                      SWAG SUPPORT TEAM        Remote ANSI Detect       IMPORT              13     ╣J£% { determine if ANSI.SYS loaded on micro }πFunction AnsiSysLoaded : Boolean;πVarπ  _AX : Word;π  Regs: Registers;πbeginπ   Regs.AX := $1a00;π   Intr($2f,Regs);π   _Ax := Regs.AX;π   ANSISysLoaded := Lo(_AX) = $FFπend;ππ{ ------------------------------------------------------------------------π                              DETECTANSIπ Detect whether the remote user has ANSI support For initial Graphic mode.π ------------------------------------------------------------------------ }πFunction DetectAnsi : Boolean;πVarπ  AnsiDetected : Boolean;π  AnsiChar     : Char;πbeginπ  AnsiDetected := False;π  If (OrgCarr) then                 { not sysop_local then }π  beginπ    Fossil.ModemPut(#27+'[6n');    { Esc[6n (Cursor Position Request) }π    Fossil.FlushBuff;π    Crt.Delay(2000);               { waits For response (2 second) }π    If (Fossil.SerialChar) then    { if modem buffer is not empty }π    beginπ      AnsiChar := Fossil.Receive;π      If (AnsiChar in [#27,'0'..'9','[','H']) thenπ        AnsiDetected := True;π    end;π    Crt.Delay(1000);      { Pause 1 second }π    Fossil.PurgeLine;     { Purge input buffer }π    Fossil.PurgeOutput;   { Make sure nothing is in output buffer }π  endπ  elseπ    { if local, check For ANSI.SYS loaded }π    AnsiDetected := AnsiSysLoaded;π    { here you might wanna say:π      if not AnsiSysLoaded then UseAnsiSimulator := True; }ππ  If AnsiDetected thenπ    PrintLn('ANSI Graphics detected.')π  elseπ    PrintLn('ANSI Graphics disabled.');π  DetectAnsi := AnsiDetected;πend;π           7      05-28-9313:35ALL                      SWAG SUPPORT TEAM        Dialing                  IMPORT              29     ╣J¬9 {π GL> I am writing a simple dialer and would like to know how doπ GL> I recieve the mode String like "BUSY" and "NO CARRIER" , Iπ GL> tried opening the Comport For reading but i just hung theπ GL> Computer. Could you please tell me how ?π GL> Regards , Garethππ  Gareth,π  I didn't see any replies to your message, but I've been lookingπ  For the same inFormation myself.  I saw the following code, basedπ  on a message from Norbert Igl, last year.  When I dial my ownπ  phone number, it gives me a busy signal For a second or two, andπ  then hangs up.  I don't know what makes the busy signal stop.  andπ  I don't know how to receive the modem String "BUSY" or "NO CARRIER"π  or "NO DIALtoNE".ππ  I noticed in my modem manual that modem command X4 willπ  generate the following responses:ππ  Number Response       Word Responseπ  (V0 command)           (V1 command)ππ     6                      NO DIALtoNEπ     7                      BUSYπ     8                      NO ANSWERπ                            (The modem responds With 8 if you sendπ                            the @ command [Wait For Quiet Answer],π                            and it didn't subsequently detect 5π                            seconds of silence.)ππ     I wish I could figure out a way to "capture" the response, either theπ     number (say, 7) or the Word ('BUSY').  if I could detect a busyπ     signal, I could then create a loop that would make theπ     Program continually redial if it detected busy signals.ππ     if you figure it out, could you post your solution?ππ     Here's how Norbert's code With a few modifications:ππ Date: 29 Jun 92  23:15:00π From: Norbert Iglπ to:   Jud Mccranieπ Subj: Dialing the phoneππ   here's a COM3-able version...(:-)}ππ   Program Dialing;π   Uses Crt;π   (* no error checking... *)ππ   Var ch : Char;π       num : String;ππ   Function Dial( Nb:String; ComPort:Byte ):Char;π            Const  DialCmd = 'ATDT';π                   OnHook  = 'ATH';π                   CR      =  #13;π                   Status  =  5;π            Var    UserKey : Char;π            PortAdr : Word;ππ            Procedure Com_Write( S: String );π                      Var i:Byte;ππ                      Function OutputOk:Boolean;π                          beginπ                          OutPutOk := ( Port[PortAdr+Status] and $20) > 0;π                          end;ππ                      Procedure ComWriteCh( Var CH:Char);π                          beginπ                          Repeat Until OutPutOk;π                          Port[PortAdr] := Byte(CH);π                          end;ππ                      beginπ                      For i := 1 to length(s) do ComWriteCh(S[i]);π                      end;ππ            Procedure Com_Writeln( S : String );π                      beginπ                      Com_Write( S + CR )π                      end;ππ   { DIAL.Main }π   beginπ   if (ComPort < 1) or ( ComPort > 4) then Exit;π   PortAdr := MemW[$40:(ComPort-1)*2 ];π   if PortAdr = 0 then Exit;π   Repeatπ       Com_Writeln( OnHook );π       Delay( 500 );π       Com_Write  ( DialCmd );π       Com_Writeln( Nb );π       UserKey := ReadKey;π       Until UserKey <> ' ';         { Hit [SPACE] to redial ! }π   Com_Writeln( OnHook );        { switch the line to the handset ...}π   Dial := UserKey;              { see what key the user pressed... }π   end;ππ  beginπ    ClrScr;π    Write ('Enter your own phone number:  ');π    Readln(Num);π    Writeln('Dialing now... Should get a busy signal.');π    ch := dial(Num,2);π  end.π                                               8      05-28-9313:35ALL                      SWAG SUPPORT TEAM        EMSI                     IMPORT              52     ╣Já# {πTERRY GRANTππHere is a Unit I posted some time ago For use With EMSI Sessions. Hope itπhelps some of you out. You will require a fossil or Async Interface forπthis to compile!π}ππProgram Emsi;ππUsesπ  Dos , Crt, Fossil;ππTypeπ  HexString = String[4];ππConstπ  FingerPrint          = '{EMSI}';π  System_Address       = '1:210/20.0';      { Your address }π  PassWord             = 'PASSWord';        { Session passWord }π  Link_Codes           = '{8N1}';           { Modem setup }π  Compatibility_Codes  = '{JAN}';           { Janis }π  Mailer_Product_Code  = '{00}';π  Mailer_Name          = 'MagicMail';π  Mailer_Version       = '1.00';π  Mailer_Serial_Number = '{Alpha}';π  EMSI_INQ : String = '**EMSI_INQC816';π  EMSI_REQ : String = '**EMSI_REQA77E';π  EMSI_ACK : String = '**EMSI_ACKA490';π  EMSI_NAK : String = '**EMSI_NAKEEC3';π  EMSI_CLI : String = '**EMSI_CLIFA8C';π  EMSI_ICI : String = '**EMSI_ICI2D73';π  EMSI_HBT : String = '**EMSI_HBTEAEE';π  EMSI_IRQ : String = '**EMSI_IRQ8E08';ππVarπ  EMSI_DAT : String;            { NOTE : EMSI_DAT has no maximum length }π  Length_EMSI_DAT : HexString;  { Expressed in Hexidecimal }π  Packet : String;π  Rec_EMSI_DAT : String;        { EMSI_DAT sent by the answering system }π  Len_Rec_EMSI_DAT : Word;ππ  Len,π  CRC : HexString;ππ  R : Registers;π  C : Char;π  Loop,ComPort,TimeOut,Tries : Byte;π  Temp : String;ππFunction Up_Case(St : String) : String;πbeginπ  For Loop := 1 to Length(St) doπ    St[Loop] := Upcase(St[Loop]);ππ  Up_Case := St;πend;ππFunction Hex(i : Word) : HexString;πConstπ  hc : Array[0..15] of Char = '0123456789ABCDEF';πVarπ  l, h : Byte;πbeginπ  l := Lo(i);π  h := Hi(i);π  Hex[0] := #4;          { Length of String = 4 }π  Hex[1] := hc[h shr 4];π  Hex[2] := hc[h and $F];π  Hex[3] := hc[l shr 4];π  Hex[4] := hc[l and $F];πend {Hex} ;ππFunction Power(Base,E : Byte) : LongInt;πbeginπ  Power := Round(Exp(E * Ln(Base) ));πend;ππFunction Hex2Dec(HexStr : String) : LongInt;ππVarπ  I,HexBit : Byte;π  Temp : LongInt;π  Code : Integer;ππbeginπ  Temp := 0;π  For I := Length(HexStr) downto 1 doπ  beginπ    If HexStr[I] in ['A','a','B','b','C','c','D','d','E','e','F','f'] thenπ      Val('$' + HexStr[I],HexBit,Code)π    elseπ      Val(HexStr[I],HexBit,Code);π    Temp := Temp + HexBit * Power(16,Length(HexStr) - I);π  end;π  Hex2Dec := Temp;πend;ππFunction Bin2Dec(BinStr : String) : LongInt;ππ{ Maximum is 16 bits, though a requirement For more would be   }π{ easy to accomodate.  Leading zeroes are not required. There  }π{ is no error handling - any non-'1's are taken as being zero. }ππVarπ  I : Byte;π  Temp : LongInt;π  BinArray : Array[0..15] of Char;ππbeginπ  For I := 0 to 15 doπ    BinArray[I] := '0';π  For I := 0 to Pred(Length(BinStr)) doπ    BinArray[I] := BinStr[Length(BinStr) - I];π  Temp := 0;π  For I := 0 to 15 doπ  If BinArray[I] = '1' thenπ    inc(Temp,Round(Exp(I * Ln(2))));π  Bin2Dec := Temp;πend;ππFunction CRC16(s:String):Word;  { By Kevin Cooney }πVarπ  crc : LongInt;π  t,r : Byte;πbeginπ  crc:=0;π  For t:=1 to length(s) doπ  beginπ    crc:=(crc xor (ord(s[t]) shl 8));π    For r:=1 to 8 doπ    if (crc and $8000)>0 thenπ      crc:=((crc shl 1) xor $1021)π    elseπ      crc:=(crc shl 1);π  end;π  CRC16:=(crc and $FFFF);πend;ππ{**** FOSSIL Routines ****}π{**** Removed from Code ***}ππProcedure Hangup;πbeginπ  Write2Port('+++'+#13);πend;ππ{**** EMSI Handshake Routines ****}ππProcedure Create_EMSI_DAT;πbeginπ  FillChar(EMSI_DAT,255,' ');ππ  EMSI_DAT := FingerPrint + '{' + System_Address + '}{'+ PassWord + '}' +π              Link_Codes + Compatibility_Codes + Mailer_Product_Code +π              '{' + Mailer_Name + '}{' + Mailer_Version + '}' +π              Mailer_Serial_Number;ππ  Length_EMSI_DAT := Hex(Length(EMSI_DAT));πend;ππFunction Carrier_Detected : Boolean;πbeginπ  TimeOut := 20;   { Wait approximately 20 seconds }π  Repeatπ    Delay(1000);π    Dec(TimeOut);π  Until (TimeOut = 0) or (Lo(StatusReq) and $80 = $80);ππ  If Timeout = 0 thenπ    Carrier_Detected := Falseπ  elseπ    Carrier_Detected := True;πend;ππFunction Get_EMSI_REQ : Boolean;πbeginπ  Temp := '';π  Purge_Input;ππ  Repeatπ    C := ReadKeyfromPort;π    If (C <> #10) and (C <> #13) thenπ      Temp := Temp + C;π  Until Length(Temp) = Length(EMSI_REQ);ππ  If Up_Case(Temp) = EMSI_REQ thenπ    get_EMSI_REQ := Trueπ  elseπ    get_EMSI_REQ := False;πend;ππProcedure Send_EMSI_DAT;πbeginπ  CRC := Hex(CRC16('EMSI_DAT' + Length_EMSI_DAT + EMSI_DAT));π  Write2Port('**EMSI_DAT' + Length_EMSI_DAT + EMSI_DAT + CRC);πend;ππFunction Get_EMSI_ACK : Boolean;πbeginπ  Temp := '';ππ  Repeatπ    C := ReadKeyfromPort;π    If (C <> #10) and (C <> #13) thenπ      Temp := Temp + C;π  Until Length(Temp) = Length(EMSI_ACK);ππ  If Up_Case(Temp) = EMSI_ACK thenπ    get_EMSI_ACK := Trueπ  elseπ    get_EMSI_ACK := False;πend;ππProcedure Get_EMSI_DAT;πbeginπ  Temp := '';π  For Loop := 1 to 10 do                  { Read in '**EMSI_DAT' }π    Temp := Temp + ReadKeyfromPort;ππ  Delete(Temp,1,2);                       { Remove the '**'      }ππ  Len := '';π  For Loop := 1 to 4 do                   { Read in the length   }π    Len := Len + ReadKeyFromPort;ππ  Temp := Temp + Len;ππ  Len_Rec_EMSI_DAT := Hex2Dec(Len);ππ  Packet := '';π  For Loop := 1 to Len_Rec_EMSI_DAT do    { Read in the packet   }π    Packet := Packet + ReadKeyfromPort;ππ  Temp := Temp + Packet;ππ  CRC := '';π  For Loop := 1 to 4 do                   { Read in the CRC      }π    CRC := CRC + ReadKeyFromPort;ππ  Rec_EMSI_DAT := Packet;ππ  Writeln('Rec_EMSI_DAT = ',Rec_EMSI_DAT);ππ  If Hex(CRC16(Temp)) <> CRC thenπ    Writeln('The recieved EMSI_DAT is corrupt!!!!');πend;ππbeginπ  { Assumes connection has been made at this point }ππ  Tries := 0;π  Repeatπ    Write2Port(EMSI_INQ);π    Delay(1000);π    Inc(Tries);π  Until (Get_EMSI_REQ = True) or (Tries = 5);ππ  If Tries = 5 thenπ  beginπ    Writeln('Host system failed to acknowledge the inquiry sequence.');π    Hangup;π    Halt;π  end;ππ  { Used For debugging }π  Writeln('Boss has acknowledged receipt of EMSI_INQ');ππ  Send_EMSI_DAT;ππ  Tries := 0;π  Repeatπ    Inc(Tries);π  Until (Get_EMSI_ACK = True) or (Tries = 5);ππ  If Tries = 5 thenπ  beginπ    Writeln('Host system failed to acknowledge the EMSI_DAT packet.');π    Hangup;π    halt;π  end;ππ  Writeln('Boss has acknowledged receipt of EMSI_DAT');ππ  Get_EMSI_DAT;π  Write2Port(EMSI_ACK);ππ  { Normally the File transfers would start at this point }π  Hangup;πend.ππ{π This DOES not include all the possibilities in an EMSI Session.π}                                  9      05-28-9313:35ALL                      SWAG SUPPORT TEAM        ASYNC Routines           IMPORT              221    ╣J└π {π>doors. But, i have one little problem: I don't know how to hang-up the modemπ>- I am using a ready-made TPU that does all the port tasks, but it just can'π>hang up!ππHere is some code I pulled out of this conference a While ago:π}ππUnit EtAsync;ππ{****************************************************************************}π{* EtAsync V.1.04, 9/4 1992 Et-Soft                                         *}π{*                                                                          *}π{* Turbo Pascal Unit With support For up to 8 serial ports.                 *}π{****************************************************************************}ππ{$A-}                              {- Word alignment -}π{$B-}                              {- Complete Boolean evaluation -}π{$D-}                              {- Debug inFormation -}π{$E-}                              {- Coprocessor emulation -}π{$F+}                              {- Force Far calls -}π{$I-}                              {- I/O checking -}π{$L-}                              {- Local debug symbols -}π{$N-}                              {- Coprocessor code generation -}π{$O-}                              {- Overlayes allowed -}π{$R-}                              {- Range checking -}π{$S-}                              {- Stack checking -}π{$V-}                              {- Var-String checking -}π{$M 16384,0,655360}                {- Stack size, min heap, max heap -}π{****************************************************************************}π                                   Interfaceπ{****************************************************************************}πUsesπ  Dos;π{****************************************************************************}π  {- Standard baudrates: -}π  {- 50, 75, 110, 134 (134.5), 150, 300, 600, 1200, 1800, 2000, 2400, 3600, -}π  {- 4800, 7200, 9600, 19200, 38400, 57600, 115200 -}ππFunction OpenCOM            {- Open a COMport For communication -}π  (Nr         : Byte;       {- Internal portnumber: 0-7 -}π   Address    : Word;       {- Port address in hex: 000-3F8 -}π   IrqNum     : Byte;       {- Port Irq number: 0-7  (255 For no Irq) -}π   Baudrate   : LongInt;    {- Baudrate: (see table) -}π   ParityBit  : Char;       {- Parity  : 'O','E' or 'N' -}π   Databits   : Byte;       {- Databits: 5-8 -}π   Stopbits   : Byte;       {- Stopbits: 1-2 -}π   BufferSize : Word;       {- Size of input buffer: 0-65535 -}π   Handshake  : Boolean)    {- True to use hardware handshake -}π     : Boolean;             {- Returns True if ok -}ππProcedure CloseCOM          {- Close a open COMport -}π  (Nr : Byte);              {- Internal portnumber: 0-7 -}ππProcedure ResetCOM          {- Reset a open COMport incl. buffer -}π  (Nr : Byte);              {- Internal portnumber: 0-7 -}ππProcedure COMSettings       {- Change settings For a open COMport -}π  (Nr        : Byte;        {- Internal portnumber: 0-7 -}π   Baudrate  : LongInt;     {- Baudrate: (see table) -}π   Paritybit : Char;        {- Parity  : 'O','E' or 'N' -}π   Databits  : Byte;        {- Databits: 5-8 -}π   Stopbits  : Byte;        {- Stopbits: 1-2 -}π   Handshake : Boolean);    {- True to use hardware handshake -}ππFunction COMAddress         {- Return the address For a COMport (BIOS) -}π  (COMport : Byte)          {- COMport: 1-8 -}π    : Word;                 {- Address found For COMport (0 if none) -}ππFunction WriteCOM           {- Writes a Character to a port -}π  (Nr : Byte;               {- Internal portnumber: 0-7 -}π   Ch : Char)               {- Character to be written to port -}π    : Boolean;              {- True if Character send -}ππFunction WriteCOMString     {- Writes a String to a port -}π  (Nr : Byte;               {- Internal portnumber: 0-7 -}π   St : String)             {- String to be written to port -}π    : Boolean;              {- True if String send -}ππFunction CheckCOM           {- Check if any Character is arrived -}π  (Nr : Byte;               {- Internal portnumber: 0-7 -}π   Var Ch : Char)           {- Character arrived -}π    : Boolean;              {- Returns True and Character if any -}ππFunction COMError           {- Returns status of the last operation -}π    : Integer;              {- 0 = Ok -}π                            {- 1 = not enough memory -}π                            {- 2 = Port not open -}π                            {- 3 = Port already used once -}π                            {- 4 = Selected Irq already used once -}π                            {- 5 = Invalid port -}π                            {- 6 = Timeout -}π                            {- 7 = Port failed loopback test -}π                            {- 8 = Port failed IRQ test -}ππFunction TestCOM            {- PerForms a loopback and IRQ test on a port -}π  (Nr : Byte)               {- Internal port number: 0-7 -}π    : Boolean;              {- True if port test ok -}π                            {- note: This is perFormed during OpenCOM -}π                            {- if enabled (TestCOM is by default enabled -}π                            {- during OpenCOM, but can be disabled With -}π                            {- the DisableTestCOM routine) -}ππProcedure EnableTestCOM;    {- Enable TestCOM during Openport (Default On) }ππProcedure DisableTestCOM;   {- Disable TestCOM during Openport -}ππFunction COMUsed            {- Check whether or not a port is open -}π  (Nr : Byte)               {- Internal port number: 0-7 -}π    : Boolean;              {- True if port is open and in use -}π                            {- note: This routine can not test -}π                            {- whether or not a COMport is used byπ                            {- another application -}ππFunction IrqUsed            {- Check whether or not an Irq is used -}π  (IrqNum : Byte)           {- Irq number: 0-7 -}π    : Boolean;              {- True if Irq is used -}π                            {- note: This routine can not test -}π                            {- whether or not an IRQ is used by -}π                            {- another application -}ππFunction IrqInUse           {- Test IRQ in use on the PIC -}π  (IrqNum : Byte)           {- Irq number: 0-7 -}π    : Boolean;              {- True if Irq is used -}ππProcedure SetIrqPriority    {- Set the Irq priority level on the PIC -}π  (IrqNum : Byte);          {- Irq number: 0-7 -}π                            {- The IrqNum specified will get the highest -}π                            {- priority, the following Irq number willπ                            {- then have the next highest priority -}π                            {- and so on -}ππProcedure ClearBuffer       {- Clear the input buffer For a open port -}π  (Nr : Byte);              {- Internal port number: 0-7 -}πππ{****************************************************************************}π                                 Implementationπ{****************************************************************************}πTypeπ  Buffer = Array[1..65535] of Byte;  {- Dummy Type For Interrupt buffer -}π  PortRec = Record                   {- Portdata Type -}π    InUse   : Boolean;               {- True if port is used -}π    Addr    : Word;                  {- Selected address -}π    Irq     : Byte;                  {- Selected Irq number -}π    OldIrq  : Byte;                  {- Status of Irq beFore InitCOM -}π    HShake  : Boolean;               {- Hardware handshake on/off -}π    Buf     : ^Buffer;               {- Pointer to allocated buffer -}π    BufSize : Word;                  {- Size of allocated buffer -}π    OldVec  : Pointer;               {- Saved old interrupt vector -}π    Baud    : LongInt;               {- Selected baudrate -}π    Parity  : Char;                  {- Selected parity -}π    Databit : Byte;                  {- Selected number of databits -}π    Stopbit : Byte;                  {- Selected number of stopbits -}π    InPtr   : Word;                  {- Pointer to buffer input index -}π    OutPtr  : Word;                  {- Pointer to buffer output index -}π    Reg0    : Byte;                  {- Saved UART register 0 -}π    Reg1    : Array[1..2] of Byte;   {- Saved UART register 1's -}π    Reg2    : Byte;                  {- Saved UART register 2 -}π    Reg3    : Byte;                  {- Saved UART register 3 -}π    Reg4    : Byte;                  {- Saved UART register 4 -}π    Reg6    : Byte;                  {- Saved UART register 6 -}π  end;ππVarπ  COMResult   : Integer;                    {- Last Error (Call COMError) -}π  ExitChainP  : Pointer;                    {- Saved Exitproc Pointer -}π  OldPort21   : Byte;                       {- Saved PIC status -}π  Ports       : Array[0..7] of PortRec;     {- The 8 ports supported -}ππConstπ  PIC = $20;                                {- PIC control address -}π  EOI = $20;                                {- PIC control Byte -}π  TestCOMEnabled : Boolean = True;          {- Test port during OpenCOM -}ππ{****************************************************************************}πProcedure DisableInterrupts;                {- Disable interrupt -}πbeginπ  Inline($FA);                            {- CLI (Clear Interruptflag) -}πend;π{****************************************************************************}πProcedure EnableInterrupts;                 {- Enable interrupts -}πbeginπ  Inline($FB);                            {- STI (Set interrupt flag) -}πend;π{****************************************************************************}πProcedure Port0Int; Interrupt;              {- Interrupt rutine port 0 -}πbeginπ  With Ports[0] Doπ  beginπ    Buf^[InPtr] := Port[Addr];             {- Read data from port -}π    Inc(InPtr);                            {- Count one step Forward.. }π    if InPtr > BufSize thenπ      InPtr := 1;    {  .. in buffer -}π  end;π  Port[PIC] := EOI;                          {- Send EOI to PIC -}πend;π{****************************************************************************}πProcedure Port1Int; Interrupt;                 {- Interrupt rutine port 1 -}πbeginπ  With Ports[1] Doπ  beginπ    Buf^[InPtr] := Port[Addr];             {- Read data from port -}π    Inc(InPtr);                            {- Count one step Forward.. }π    if InPtr > BufSize thenπ      InPtr := 1;    {  .. in buffer -}π  end;π  Port[PIC] := EOI;                          {- Send EOI to PIC -}πend;π{****************************************************************************}πProcedure Port2Int; Interrupt;                 {- Interrupt rutine port 2 -}πbeginπ  With Ports[2] Doπ  beginπ    Buf^[InPtr] := Port[Addr];             {- Read data from port -}π    Inc(InPtr);                            {- Count one step Forward.. }π    if InPtr > BufSize thenπ      InPtr := 1;    {  .. in buffer -}π  end;π  Port[PIC] := EOI;                          {- Send EOI to PIC -}πend;π{****************************************************************************}πProcedure Port3Int; Interrupt;                 {- Interrupt rutine port 3 -}πbeginπ  With Ports[3] Doπ  beginπ    Buf^[InPtr] := Port[Addr];            {- Read data from port -}π    Inc(InPtr);                           {- Count one step Forward.. }π    if InPtr > BufSize thenπ      InPtr := 1;   {  .. in buffer -}π  end;π  Port[PIC] := EOI;                         {- Send EOI to PIC -}πend;π{****************************************************************************}πProcedure Port4Int; Interrupt;                {- Interrupt rutine port 4 -}πbeginπ  With Ports[4] Doπ  beginπ    Buf^[InPtr] := Port[Addr];            {- Read data from port -}π    Inc(InPtr);                           {- Count one step Forward.. }π    if InPtr > BufSize thenπ      InPtr := 1;   {  .. in buffer -}π  end;π  Port[PIC] := EOI;                         {- Send EOI to PIC -}πend;π{****************************************************************************}πProcedure Port5Int; Interrupt;                {- Interrupt rutine port 5 -}πbeginπ  With Ports[5] Doπ  beginπ    Buf^[InPtr] := Port[Addr];            {- Read data from port -}π    Inc(InPtr);                           {- Count one step Forward.. }π    if InPtr > BufSize thenπ      InPtr := 1;   {  .. in buffer -}π  end;π  Port[PIC] := EOI;                         {- Send EOI to PIC -}πend;π{****************************************************************************}πProcedure Port6Int; Interrupt;                {- Interrupt rutine port 6 -}πbeginπ  With Ports[6] Doπ  beginπ    Buf^[InPtr] := Port[Addr];            {- Read data from port -}π    Inc(InPtr);                           {- Count one step Forward.. }π    if InPtr > BufSize thenπ      InPtr := 1;   {  .. in buffer -}π  end;π  Port[PIC] := EOI;                         {- Send EOI to PIC -}πend;π{****************************************************************************}πProcedure Port7Int; Interrupt;                {- Interrupt rutine port 7 -}πbeginπ  With Ports[7] Doπ  beginπ    Buf^[InPtr] := Port[Addr];            {- Read data from port-}π    Inc(InPtr);                           {- Count one step Forward..}π    if InPtr > BufSize thenπ      InPtr := 1;   {  .. in buffer-}π  end;π  Port[PIC] := EOI;                         {- Send EOI to PIC-}πend;π{****************************************************************************}πProcedure InitPort(Nr : Byte; SaveStatus : Boolean);     {- Port initialize -}ππVarπ  divider  : Word;                               {- Baudrate divider number -}π  CtrlBits : Byte;                                     {- UART control Byte -}ππbeginπ  With Ports[Nr] Doπ  beginπ    divider := 115200 div Baud;                {- Calc baudrate divider -}ππ    CtrlBits := DataBit - 5;                    {- Insert databits -}ππ    if Parity <> 'N' thenπ    beginπ      CtrlBits := CtrlBits or $08;            {- Insert parity enable -}π      if Parity = 'E' then                    {- Enable even parity -}π        CtrlBits := CtrlBits or $10;π    end;ππ    if Stopbit = 2 thenπ      CtrlBits := CtrlBits or $04;              {- Insert stopbits -}ππ    if SaveStatus thenπ      Reg3 := Port[Addr + $03];    {- Save register 3 -}π    Port[Addr + $03] := $80;                        {- Baudrate change -}ππ    if SaveStatus thenπ      Reg0 := Port[Addr + $00];    {- Save Lo Baud -}π    Port[Addr + $00] := Lo(divider);                {- Set Lo Baud -}ππ    if SaveStatus thenπ      Reg1[2] := Port[Addr + $01]; {- Save Hi Baud -}π    Port[Addr + $01] := Hi(divider);                {- Set Hi Baud -}ππ    Port[Addr + $03] := CtrlBits;                   {- Set control reg. -}π    if SaveStatus thenπ      Reg6 := Port[Addr + $06];    {- Save register 6 -}π  end;πend;π{****************************************************************************}πFunction IrqUsed(IrqNum : Byte) : Boolean;ππVarπ  Count : Byte;π  Found : Boolean;ππbeginπ  Found := False;                                 {- Irq not found -}π  Count := 0;                                     {- Start With port 0 -}ππ  While (Count <= 7) and not Found Do             {- Count the 8 ports -}π    With Ports[Count] Doπ    beginπ      if InUse thenπ        Found := IrqNum = Irq;                  {- Check Irq match -}π      Inc(Count);                               {- Next port -}π    end;ππ  IrqUsed := Found;                               {- Return Irq found -}πend;π{****************************************************************************}πProcedure EnableTestCOM;πbeginπ  TestCOMEnabled := True;πend;π{****************************************************************************}πProcedure DisableTestCOM;πbeginπ  TestCOMEnabled := False;πend;π{****************************************************************************}πFunction TestCOM(Nr : Byte) : Boolean;ππVarπ  OldReg0   : Byte;π  OldReg1   : Byte;π  OldReg4   : Byte;π  OldReg5   : Byte;π  OldReg6   : Byte;π  OldInPtr  : Word;π  OldOutPtr : Word;π  TimeOut   : Integer;ππ  beginππ  TestCOM := False;ππ  With Ports[Nr] Doπ  beginπ    if InUse thenπ    beginπ      OldInPtr  := InPtr;π      OldOutPtr := OutPtr;π      OldReg1 := Port[Addr + $01];π      OldReg4 := Port[Addr + $04];π      OldReg5 := Port[Addr + $05];π      OldReg6 := Port[Addr + $06];ππ      Port[Addr + $05] := $00;π      Port[Addr + $04] := Port[Addr + $04] or $10;ππ      OldReg0 := Port[Addr + $00];π      OutPtr  := InPtr;ππ      TimeOut := MaxInt;π      Port[Addr + $00] := OldReg0;ππ      While (Port[Addr + $05] and $01 = $00) and (TimeOut <> 0) Doπ        Dec(TimeOut);ππ      if TimeOut <> 0 thenπ      beginπ        if Port[Addr + $00] = OldReg0 thenπ        beginπ          if IRQ In [0..7] thenπ          beginπ            TimeOut := MaxInt;π            OutPtr := InPtr;ππ            Port[Addr + $01] := $08;π            Port[Addr + $04] := $08;π            Port[Addr + $06] := Port[Addr + $06] or $01;ππ            While (InPtr = OutPtr) and (TimeOut <> 0) Doπ              Dec(TimeOut);ππ            Port[Addr + $01] := OldReg1;ππ            if (InPtr <> OutPtr) thenπ              TestCOM := Trueπ            elseπ              COMResult := 8;π          endπ          elseπ            TestCOM := True;π        endπ        elseπ          COMResult := 7;            {- Loopback test failed -}π      endπ      elseπ        COMResult := 6;                {- Timeout -}ππ      Port[Addr + $04] := OldReg4;π      Port[Addr + $05] := OldReg5;π      Port[Addr + $06] := OldReg6;ππ      For TimeOut := 1 to MaxInt Do;π      if Port[Addr + $00] = 0 then;ππ      InPtr  := OldInPtr;π      OutPtr := OldOutPtr;π    endπ    elseπ      COMResult := 2;                    {- Port not open -}π  end;πend;π{****************************************************************************}πProcedure CloseCOM(Nr : Byte);ππbeginπ  With Ports[Nr] Doπ  beginπ    if InUse thenπ    beginπ      InUse := False;ππ      if Irq <> 255 then                         {- if Interrupt used -}π      beginπ        FreeMem(Buf,BufSize);                  {- Deallocate buffer -}π        DisableInterrupts;π        Port[$21] := Port[$21] or ($01 Shl Irq) and OldIrq;π{-restore-}π        Port[Addr + $04] := Reg4;              {- Disable UART OUT2 -}π        Port[Addr + $01] := Reg1[1];           {- Disable UART Int. -}π        SetIntVec($08+Irq,OldVec);            {- Restore Int.Vector -}π        EnableInterrupts;π      end;ππ      Port[Addr + $03] := $80;                    {- UART Baud set -}π      Port[Addr + $00] := Reg0;                   {- Reset Lo Baud -}π      Port[Addr + $01] := Reg1[2];                {- Reset Hi Baud -}π      Port[Addr + $03] := Reg3;                {- Restore UART ctrl. -}π      Port[Addr + $06] := Reg6;                  {- Restore UART reg6 -}π    endπ    elseπ      COMResult := 2;                               {- Port not in use -}π  end;πend;π{****************************************************************************}πFunction OpenCOMπ (Nr : Byte; Address  : Word; IrqNum : Byte; Baudrate : LongInt;π  ParityBit : Char; Databits, Stopbits : Byte; BufferSize : Word;π  HandShake : Boolean) : Boolean;ππVarπ  IntVec : Pointer;π  OldErr : Integer;ππbeginπ  OpenCOM := False;ππ  if (IrqNum = 255) orπ  ((IrqNum In [0..7]) and (MaxAvail >= LongInt(BufferSize))π                      and not IrqUsed(IrqNum)) thenπ    With Ports[Nr] Doπ    beginπ      if not InUse and (Address <= $3F8) thenπ      beginπ        InUse   := True;                    {- Port now in use -}ππ        Addr    := Address;                 {- Save parameters -}π        Irq     := IrqNum;π        HShake  := HandShake;π        BufSize := BufferSize;π        Baud    := Baudrate;π        Parity  := Paritybit;π        Databit := Databits;π        Stopbit := Stopbits;ππ        InPtr   := 1;                       {- Reset InputPointer -}π        OutPtr  := 1;                       {- Reset OutputPointer -}ππ        if (Irq In [0..7]) and (BufSize > 0) thenπ        beginπ          GetMem(Buf,BufSize);            {- Allocate buffer -}π          GetIntVec($08+Irq,OldVec);      {- Save Interrupt vector -}ππ          Case Nr of                    {- Find the interrupt proc. -}π            0 : IntVec := @Port0Int;π            1 : IntVec := @Port1Int;π            2 : IntVec := @Port2Int;π            3 : IntVec := @Port3Int;π            4 : IntVec := @Port4Int;π            5 : IntVec := @Port5Int;π            6 : IntVec := @Port6Int;π            7 : IntVec := @Port7Int;π          end;ππ          Reg1[1] := Port[Addr + $01];    {- Save register 1 -}π          Reg4    := Port[Addr + $04];    {- Save register 4 -}π          OldIrq  := Port[$21] or not ($01 Shl Irq);{- Save PIC Irq -}ππ          DisableInterrupts;              {- Disable interrupts -}π          SetIntVec($08+Irq,IntVec);    {- Set the interrupt vector -}π          Port[Addr + $04] := $08;        {- Enable OUT2 on port -}π          Port[Addr + $01] := $01;      {- Set port data avail.int. -}π          Port[$21] := Port[$21] and not ($01 Shl Irq);{- Enable Irq-}π          EnableInterrupts;         {- Enable interrupts again -}π        end;π        InitPort(Nr,True);                  {- Initialize port -}ππ        if TestCOMEnabled thenπ        beginπ          if not TestCOM(Nr) thenπ          beginπ            OldErr := COMResult;π            CloseCOM(Nr);π            COMResult := OldErr;π          endπ          elseπ            OpenCOM := True;π        endπ        elseπ          OpenCOM := True;ππ        if Port[Addr + $00] = 0 then;  {- Remove any pending Character-}π        if Port[Addr + $05] = 0 then;  {- Reset line status register-}ππ        Port[Addr + $04] := Port[Addr + $04] or $01;     {- Enable DTR-}π      endπ      else if InUse thenπ        COMResult := 3                        {- Port already in use-}π      else if (Address > $3F8) thenπ        COMResult := 5;                       {- Invalid port address-}π    endπ  else if (MaxAvail >= BufferSize) then         {- not enough memory-}π    COMResult := 1π  else if IrqUsed(IrqNum) then                  {- Irq already used -}π    COMResult := 4;πend;π{****************************************************************************}πProcedure ResetCOM(Nr : Byte);ππbeginπ  With Ports[Nr] Doπ  beginπ    if InUse then                        {- Is port defined ?-}π    beginπ      InPtr  := 1;                     {- Reset buffer Pointers-}π      OutPtr := 1;π      InitPort(Nr,False);              {- Reinitialize the port-}ππ      if Port[Addr + $00] = 0 then;    {- Remove any pending Character-}π      if Port[Addr + $05] = 0 then;    {- Reset line status register-}π    endπ    elseπ      COMResult := 2;                    {- Port not open-}π  end;πend;π{****************************************************************************}πProcedure COMSettings(Nr : Byte; Baudrate : LongInt; ParityBit : Char;π  Databits, Stopbits : Byte; HandShake : Boolean);πbeginπ  With Ports[Nr] Doπ  beginπ    if InUse then                                     {- Is port in use-}π    beginπ      Baud    := Baudrate;                          {- Save parameters-}π      Parity  := Paritybit;π      Databit := Databits;π      Stopbit := Stopbits;π      HShake  := HandShake;ππ      InitPort(Nr,False);                           {- ReInit port-}π    endπ    elseπ      COMResult := 2;                                 {- Port not in use-}π  end;πend;π{****************************************************************************}πFunction COMAddress(COMport : Byte) : Word;ππbeginπ  if Comport In [1..8] thenπ    COMAddress := MemW[$40:(Pred(Comport) Shl 1)]       {- BIOS data table-}π  elseπ    COMResult := 5;                                     {- Invalid port-}πend;π{****************************************************************************}πFunction WriteCOM(Nr : Byte; Ch : Char) : Boolean;ππVarπ  Count : Integer;ππbeginπ  WriteCom := True;ππ  With Ports[Nr] Doπ    if InUse thenπ    beginπ      While Port[Addr + $05] and $20 = $00 Do;   {- Wait Until Char send-}π      if not HShake thenπ        Port[Addr] := ord(Ch)                    {- Send Char to port-}π      elseπ      beginπ        Port[Addr + $04] := $0B;               {- OUT2, DTR, RTS-}π        Count := MaxInt;ππ        While (Port[Addr + $06] and $10 = 0) and (Count <> 0) Doπ          Dec(Count);                          {- Wait For CTS-}ππ        if Count <> 0 then                     {- if not timeout-}π          Port[Addr] := ord(Ch)                {- Send Char to port-}π        elseπ        beginπ          COMResult := 6;                    {- Timeout error-}π          WriteCom  := False;π        end;π      end;π    endπ    elseπ    beginπ      COMResult := 2;                            {- Port not in use-}π      WriteCom  := False;π    end;πend;π{****************************************************************************}πFunction WriteCOMString(Nr : Byte; St : String) : Boolean;ππVarπ  Ok : Boolean;π  Count : Byte;ππbeginπ  if Length(St) > 0 then                           {- Any Chars to send ?-}π  beginπ    Ok    := True;π    Count := 1;π    While (Count <= Length(St)) and Ok Do        {- Count Chars-}π    beginπ      Ok := WriteCOM(Nr,St[Count]);            {- Send Char-}π      Inc(Count);                              {- Next Character-}π    end;π    WriteCOMString := Ok;                        {- Return status-}π  end;πend;π{****************************************************************************}πFunction CheckCOM(Nr : Byte; Var Ch : Char) : Boolean;ππbeginπ  With Ports[Nr] Doπ  beginπ    if InPtr <> OutPtr then                      {- Any Char in buffer ?-}π    beginπ      Ch := Chr(Buf^[OutPtr]);                 {- Get Char from buffer-}π      Inc(OutPtr);                             {- Count outPointer up-}π      if OutPtr > BufSize thenπ        OutPtr := 1;π      CheckCOM := True;π    endπ    elseπ      CheckCOM := False;                         {- No Char in buffer-}π  end;πend;π{****************************************************************************}πFunction COMError : Integer;ππbeginπ  COMError := COMResult;                           {- Return last error-}π  COMResult := 0;πend;π{****************************************************************************}πFunction COMUsed(Nr : Byte) : Boolean;ππbeginπ  COMUsed := Ports[Nr].InUse;                      {- Return used status-}πend;π{****************************************************************************}πFunction IrqInUse(IrqNum : Byte) : Boolean;ππVarπ  IrqOn : Byte;π  Mask  : Byte;ππbeginπ  IrqInUse := False;ππ  if IrqNum In [0..7] thenπ  beginπ    IrqOn := Port[$21];         {-1111 0100-}π    Mask  := ($01 Shl IrqNum);π    IrqInUse := IrqOn or not Mask = not Mask;π  end;πend;π{****************************************************************************}πProcedure SetIrqPriority(IrqNum : Byte);ππbeginπ  if IrqNum In [0..7] thenπ  beginπ    if IrqNum > 0 thenπ      Dec(IrqNum)π    else IrqNum := 7;ππ    DisableInterrupts;π    Port[PIC] := $C0 + IrqNum;π    EnableInterrupts;π  end;πend;π{****************************************************************************}πProcedure ClearBuffer(Nr : Byte);ππbeginπ  With Ports[Nr] Doπ    if InUse and (BufSize > 0) thenπ      OutPtr := InPtr;πend;π{****************************************************************************}πProcedure DeInit;ππVarπ  Count : Byte;ππbeginπ  For Count := 0 to 7 Doπ    CloseCOM(Count);          {- Close open ports-}ππ  DisableInterrupts;π  Port[$21] := OldPort21;                          {- Restore PIC status-}π  Port[$20] := $C7;                                {- IRQ0 1. priority-}π  EnableInterrupts;ππ  ExitProc := ExitChainP;                          {- Restore ExitProc-}πend;ππ{****************************************************************************}πProcedure Init;ππVarπ  Count : Byte;ππbeginπ  COMResult  := 0;π  ExitChainP := ExitProc;                          {- Save ExitProc-}π  ExitProc   := @DeInit;                           {- Set ExitProc-}ππ  For Count := 0 to 7 Doπ    Ports[Count].InUse := False;                   {- No ports open-}ππ  OldPort21 := Port[$21];                          {- Save PIC status-}πend;ππ{****************************************************************************}ππbeginπ  Init;πend.π                10     05-28-9313:35ALL                      SWAG SUPPORT TEAM        Hangup Routine           IMPORT              6      ╣J} {π> I started writing communicating-Programs, and evenπ> trying to develope simple doors. But, i have oneπ> little problem: I don't know how to hang-up the modem!π> - I am using a ready-made TPU that does all the portπ> tasks, but it just can't hang up!π> All i know, is beFore the ~~~+++~~~ATH0 String, i need to 'Drop DTR'...π> How do i do that?!?ππif you are using a FOSSIL driver For communications, you could do this:π}ππProcedure Lower_DTR;πVar regs:Registers;πbeginπ  regs.dx:=0;  {com1=0;com2=1;com3=2;com4=3}π  regs.al:=$00;π  regs.ah:=$06;π  intr($14,regs);π  Exit;πend;ππ                                                          11     05-28-9313:35ALL                      SWAG SUPPORT TEAM        Another AVATAR Routine   IMPORT              41     ╣JtP {πGREGORY P. SMITHππHere's a Unit I just pieced together from some old code I wrote a coupleπyears ago.  It'll generate AVT/0+ and ANSI codes:π}ππUnit TermCode;  {$S-,D-,L-,R-,F-,O-}π{  Generate ANSI and AVT/0+ codes For color and cursor ctrl }π{  Public Domain -- by Gregory P. Smith  }  { untested }ππInterfaceππTypeπ  Str12 = String[12];  { Maximum size For most ANSI Strings }π  Str3  = String[3];π  grTermType = (TTY, ANSI, AVT0); { TTY, ANSI or Avatar/0+ }ππVarπ  grTerm : grTermType;π  grColor : Byte;  { Last color set }ππ{ Non Specific Functions }πFunction grRepChar(c:Char;n:Byte): String;   { Repeat Chars }πFunction grSetPos(x,y:Byte): Str12;   { Set Cursor Position }πFunction grCLS: Str12;          { Clear Screen + reset Attr }πFunction grDelEOL: Str12;                   { Delete to EOL }ππFunction grSetAttr(a:Byte): Str12;      { Change writing color }πFunction grSetColor(fg,bg:Byte): Str12; { Change color fg & bg }ππ{ AVT/0+ Specific Functions }πFunction AVTRepPat(pat:String;n:Byte): String; { Repeat Pattern (AVT/0+) }πFunction AVTScrollUp(n,x1,y1,x2,y2:Byte): Str12;πFunction AVTScrollDown(n,x1,y1,x2,y2:Byte): Str12;πFunction AVTClearArea(a,l,c:Byte): Str12;πFunction AVTInitArea(ch:Char;a,l,c:Byte): Str12;ππImplementationππConstπ  hdr = #27'['; { ansi header }ππ{ Misc support Functions }ππFunction bts(x:Byte): str3; { Byte to String }πVarπ  z: str3;πbeginπ  Str(x,z);π  bts := z;πend;ππFunction Repl(n:Byte; c:Char): String;πVarπ  z : String;πbeginπ  fillChar(z[1],n,c);π  z[0] := chr(n);π  repl := z;πend;ππ{ Cursor Control Functions }ππFunction grRepChar(c:Char;n:Byte): String;πbeginπ  if grTerm = AVT0 thenπ    grRepChar := ^Y+c+chr(n)π  elseπ    grRepChar := repl(n,c);πend; { repcahr }ππFunction grSetPos(x,y:Byte): Str12;πbeginπ  Case grTerm ofπ    ANSI : if (x = 1) and (y > 1) thenπ             grSetPos := hdr+bts(y)+'H'   { x defualts to 1 }π           elseπ             grSetPos := hdr+bts(y)+';'+bts(x)+'H';π    AVT0 : grSetPos := ^V+^H+chr(y)+chr(x);π    TTY  : grSetPos := '';π  end; { Case }πend;πππFunction grCLS: Str12;πbeginπ  Case grTerm ofπ    ANSI : grCLS := hdr+'2J';π    TTY,π    AVT0 : grCLS := ^L;π  end;π  if grTerm = AVT0 then GrColor := 3; { reset the color }πend; { cls }ππFunction grDelEOL: Str12; { clear rest of line }πbeginπ  Case grTerm ofπ    ANSI : grDelEOL := hdr+'K';π    AVT0 : grDelEOL := ^V^G;π    TTY  : grDelEOL := '';π  end;πend;ππ{ Color Functions }ππFunction grSetAttr(a:Byte): Str12;πConstπ  ANS_Colors : Array[0..7] of Char = ('0','4','2','6','1','5','3','7');πVarπ  tmp : Str12;πbeginπ  tmp := '';π  Case grTerm ofπ    ANSI :π    beginπ      tmp := hdr;π      if (a and $08)=8 then tmp := tmp+'1' else tmp := tmp+'0'; { bright }π      if (a and $80)=$80 then tmp := tmp+';5';  { blink }π      tmp := tmp+';3'+ANS_Colors[a and $07]; { foreground }π      tmp := tmp+';4'+ANS_Colors[(a shr 4) and $07]; { background }π      grSetAttr := tmp+'m'; { complete ANSI code }π    end;π    AVT0 :π    beginπ      tmp := ^V+^A+chr(a and $7f);π      if a > 127  then tmp := tmp+^V+^B; { Blink }π      grSetAttr := tmp;π    end;π    TTY  : grSetAttr := '';π  end; { Case }π  GrColor := a; { Current Attribute }πend; { setattr }ππFunction grSetColor(fg,bg:Byte): Str12;πbeginπ  grSetColor := grSetAttr((bg shl 4) or (fg and $0f));πend; { SetColor }ππ{ AVATAR Specific Functions: }ππFunction AVTRepPat(pat:String;n:Byte): String; { Repeat Pattern (AVT/0+) }πbeginπ  AVTRepPat := ^V+^Y+pat[0]+pat+chr(n); { Repeat pat n times }πend;ππFunction AVTScrollUp(n,x1,y1,x2,y2:Byte): Str12;πbeginπ  AVTScrollUp := ^V+^J+chr(n)+chr(y1)+chr(x1)+chr(y2)+chr(x2);πend; { AVTScrollUp }ππFunction AVTScrollDown(n,x1,y1,x2,y2:Byte): Str12;πbeginπ  AVTScrollDown := ^V+^K+chr(n)+chr(y1)+chr(x1)+chr(y2)+chr(x2);πend; { AVTScrollDown }ππFunction AVTClearArea(a,l,c:Byte): Str12;πVarπ  b:Byte;π  s:Str12;πbegin       { Clear lines,columns from cursor pos With Attr }π  b := a and $7f;π  s := ^V+^L+chr(b)+chr(l)+chr(c);π  if a > 127 thenπ    Insert(^V+^B,s,1); { blink on }π  AVTClearArea := s;π  GrColor := a;πend; { AVTClearArea }ππFunction AVTInitArea(ch:Char;a,l,c:Byte): Str12;πVarπ  b:Byte;π  s:Str12;πbeginπ  b := a and $7f;π  s := ^V+^M+chr(b)+ch+chr(l)+chr(c);π  if a > 127 thenπ    Insert(^V+^B,s,1);π  AvtInitArea := s;π  GrColor := a;πend; { AVTInitArea }ππ{ Initalization code }πbeginπ  GrTerm  := AVT0;  { Default to Avatar }π  GrColor := 3;     { Cyan is the AVT/0+ defualt }πend.ππ{πset GrTerm to whatever terminal codes you want to create; then you can use theπcommon routines to generate ANSI or Avatar codes.  Here's a Print Procedureπthat you were mentioning:π}ππProcedure Print(Var msg:String);πVarπ  idx : Byteπbeginπ  if length(msg) > 0 thenπ    For idx := 1 to length(msg) do beginπ      Parse_AVT1(msg[idx]);π      SendOutComPortThingy(msg[idx]);π    end; { For }πend;π{πYou could modify this so that it pays attention to the TextAttr Variable of theπCrt Unit if you wish so that it compares TextAttr to GrColor and adds aπSetAttr(TextAttr) command in before it sends msg.π}                                                                             12     05-28-9313:35ALL                      SWAG SUPPORT TEAM        Ring Detect              IMPORT              13     ╣J
  2. α (*******************************************************************)π Program RingDetector;  { TSR to detect telephone ring via modem    }π {$M $400,0,0}π Uses   Dos;            { import GetIntVec, SetIntVec               }π Const  COMport     = $3FE;             { COM1 = $3FE, COM2 = $2FE  }π        RingMsg     : Array [0..7] of Byte =π                    ( $52,$40,$49,$40,$4E,$40,$47,$40 );   { "RinG" }π Var    OldClock    : Procedure;        { For previous int vector   }π        GSpot       : Byte Absolute $B800:$072C;    { display area  }π        OldScreen   : Array [0..7] of Byte; { to save display are   }π {$F+}π Procedure RingDetect; Interrupt;π    beginπ        if ODD(Port[COMport] SHR 6)π        then beginπ            Move( GSpot, OldScreen, 8 );        { save screen area  }π            While ODD(PorT[COMport] SHR 6)π                do Move( RingMsg, GSpot, 8 );   { display "RinG"    }π            Move( OldScreen, GSpot, 8 );        { restore screen    }π        end; {if}π        InLine($9C);                            { to fake an inT    }π        OldClock;                               { chain ticker      }π    end {RingDetect};π {$F-}ππ beginπ        GetIntVec($1C,@OldClock);               { save current isr  }π        SetIntVec($1C,ADDR(RingDetect));        { install this isr  }π        Keep(0);                                { tsr               }π end {RingDetector}.π(*******************************************************************)π                                                             13     05-28-9313:35ALL                      SWAG SUPPORT TEAM        Is Modem Ringing ??      IMPORT              10     ╣Jú7 Function ModemRinging(Port : Word) : Boolean;  { through the BIOS }πVarπ  Dummy : Byte;πbeginπ  Asmπ    dec portπ    mov ah,03hπ    mov dx,portπ    int 14hπ    mov dummy,alπ  end;π  ModemRinging := (Dummy and RI) = RI       { ring indicated }πend;ππorππFunction ModemRinging(Port : Byte) : Boolean;  { direct port access }πConstπ  RI = $40;πbeginπ  Case Port ofπ    1 : ModemRinging := ($3FE and RI) = RI;   { com 1 }π    2 : ModemRinging := ($2FE and RI) = RI    { com 2 }π  endπend;ππFunction PhoneRinging(ComPort: Integer): Boolean;πbeginπ    Case ComPort Ofπ        1: PhoneRinging := (Port[$3FE] And 64) = 64;π        2: PhoneRinging := (Port[$2FE] And 64) = 64;π        3: PhoneRinging := (Port[$3EE] And 64) = 64;π        4: PhoneRinging := (Port[$2EE] And 64) = 64;π        Elseπ            PhoneRinging := False;π    end;πend;ππFunction returns True if phone is ringing. Hope it helps.ππ{π> Function returns True if phone is ringing. Hope it helps.ππJust nitpicking but...ππ PhoneRinging:=(Port[$3FE] and 64)<>0ππis more efficient, as isππ PhoneRinging:=Boolean(Port[$3FE] and 64)π}                                                             14     05-28-9313:35ALL                      SWAG SUPPORT TEAM        Serial Port Stuff        IMPORT              35     ╣J╘y {π│    Does anyone have a few minutes to help a novice?   I'm new to Pascalπ│  and have just added a new dimension to my Programming interestsπ│  through the purchase of Borland's Pascal With Objects 7.0 and as Iπ│  struggle through the 3000 odd pages of documentation I find I'mπ│  missing some of the basics.   For example, I'm trying to Write aπ│  little phone dialer as an exercise in using OOP and am having troubleπ│  talking to the modem With the following:π│  Assign(Port,COM1);   ReWrite(Port);    Write(Port,ATDT);π│    This works fine only if I run my dialer Program after having usingπ│  another comms Program With my modem. if I try to run it cold I  getπ│  Error 160: Device Write fault.  There is obviously some initializationπ│  I need to do to "WAKEUP" the modem.πππ...Here's some routines to initialize/manipulates the RS-232 port.π}πππProcedure InitCommPort(IniStr      : Byte;π                       CommPort    : Word;π                   Var LineStatusπ                       ModemStatus  : Byte);π(****************************************************************************π  Parameters:ππ        InitStr   -   Initialization paramterππ                      Bits 7654321     Meaningπ                           000           110 baudπ                           001           150 baudπ                           010           300 baudπ                           011           600 baudπ                           100          1200 baudπ                           101          2400 baudπ                           110          4800 baudπ                           111          9600 baudπ                              00        no parityπ                              01        odd parityπ                              10        no parityπ                              11        even parityπ                                0       1 stop bitπ                                1       2 stop bitπ                                 10     7-bit data lengthπ                                 11     8-bit data lengthππ                      ie: For 1200/N/8/1 use InitStr = 10000011bππ        CommPort  -   Communication port (0=com1, 1=com2, 2=com3 etc)ππ        LineStatus    Bits 76543210        Meaningπ                           1            time-out errorπ                            1           transfer shift register emptyπ                             1          transfer holding register emptyπ                              1         break interrupt detectedπ                               1        framing errorπ                                1       parity errorπ                                 1      overrun errorπ                                  1     data readyππ        ModemStatus   Bits 76543210         Meaningπ                           1            receive line signal detectπ                            1           ring indicatorπ                             1          data set ready (DSR)π                              1         clear to send (CTS)π                               1        delta receive line signal detectπ                                1       trailing edge ring detectorπ                                 1      delta data set ready (DDSR)π                                  1     delta clear to send  (DCTS)ππ*****************************************************************************)ππVarπ  regs : Registers;         (* Uses Dos Unit *)πbeginπ  regs.AH := $00;π  regs.AL := InitStr;π  regs.DX := CommPort;π  Intr($14, regs);          (* initialize comm port *)π  LineStatus := regs.AH;π  ModemStatus := regs.AL;πend;  (* InitCommPort *)πππProcedure TransmitChar(Ch: Byte;            (* Character to send *)π                       CommPort: Word;      (* comm port to use  *)π                   Var Code: Byte)          (* return code       *)π(****************************************************************************ππ  notE:   BeFore calling this routine, the port must be first initializedπ          by InitCommPort.ππ****************************************************************************)πVarπ  regs : Registers;πbeginπ  regs.AH := $01;π  regs.AL := Ch;π  regs.DX := CommPort;          (* 0=com1, etc    *)π  Intr($14, regs);              (* send Character *)π  Code := regs.AH               (* return code    *)πend;  (* TransmitChar *)π                                          15     05-28-9313:35ALL                      SWAG SUPPORT TEAM        DOOR Info & File Maker   IMPORT              20     ╣J╡ {πREYNIR STEFANSSONππSome time ago I looked at the Waffle BBS v1.63. I wrote this progletπto create a DOORINFO File For certain aftermarket utilities. Here you are:π}ππProgram DIMaker; {Writes DOORINFO.DEF/DORINFOn.DEF For Waffle BBS. }ππVarπ  tf          : Text;π  Graphic     : Integer;π  Port        : Char;π  SysName,π  SysOpFirst,π  SysOpLast,π  Baud,π  Terminal,π  First,π  Last,π  CallLoc,π  TimeLeft,π  SecLev,π  FossilOn,π  SysDir,π  FileName    : String;ππ{ Command line For Waffle: }ππ{ dimaker ~%b ~%t ~%O ~%a ~%F ~%A@~%n ~%L -1 [-|n] }ππProcedure WriteDorInfo;πbeginπ  Assign(tf, SysDir+FileName+'.DEF');π  ReWrite(tf);π  WriteLn(tf, SysName);                { BBS name }π  WriteLn(tf, SysOpFirst);             { SysOp's first name }π  WriteLn(tf, SysOpLast);              { SysOp's last name }π  WriteLn(tf, 'COM', Port);            { COMport in use }π  WriteLn(tf, Baud, ' BAUD,8,N,1');    { Speed and Char format }π  WriteLn(tf, '0');                    { ? }π  WriteLn(tf, First);                  { User's first name }π  WriteLn(tf, Last);                   { User's last name }π  WriteLn(tf, CallLoc);                { User's location }π  WriteLn(tf, Graphic);                { 1 if ANSI, 0 if not. }π  WriteLn(tf, SecLev);                 { Security level }π  WriteLn(tf, TimeLeft);               { Time Until kick-out }π  WriteLn(tf, FossilOn);               { -1 if using FOSSIL, 0 if not }π  Close(tf);πend;ππ{ Don't let my reusing of Variables disturb you. }πProcedure GatherInfo;πbeginπ  FileName[1] := '-';π  SysName := ParamStr(0);π  Graphic := Length(SysName);π  Repeatπ    Dec(Graphic)π  Until SysName[Graphic]='\';π  SysDir := Copy(SysName, 1, Graphic);π  Assign(tf, Copy(SysName, 1, Length(SysName)-4)+'.CFG');π  Reset(tf);π  ReadLn(tf, SysName);π  ReadLn(tf, SysOpFirst);π  ReadLn(tf, SysOpLast);π  Close(tf);π  Baud     := ParamStr(1);π  Terminal := ParamStr(2);π  TimeLeft := ParamStr(3);π  SecLev   := ParamStr(4);π  First    := ParamStr(5);π  Last     := ParamStr(6);π  CallLoc  := ParamStr(7);π  FossilOn := ParamStr(8);π  FileName := ParamStr(9);π  Port := FileName[1];π  if Port = '-' thenπ    FileName := 'DOORINFO'π  elseπ    FileName := 'DORINFO'+Port;π  if Terminal='vt100' thenπ    Graphic := 1π  elseπ    Graphic := 0;π  Port := '2';π  if Baud='LOCAL' thenπ  beginπ    Baud := '0';π    Port := '0';π  end;πend;ππbegin;π  GatherInfo;π  WriteDorInfo;πend.π                                 16     07-16-9306:00ALL                      KAI HENNINGSEN           Detect 16550A UART       IMPORT              24     ╣J  {πFrom: Kai_Henningsen@ms.maus.de (Kai Henningsen)πNewsgroups: comp.dcom.modemsπSubject: Help upgrade to 16550AπDate: Tue, 04 Aug 92 16:13:00 GMTπOrganization: MausNetππAny noncommercial use allowed. For commercial, ask me - or use somethingπelse. The ideas in this program are really very simple ... I seem toπremember most came from an article in DDJ.π}ππprogram ShowUARTs;ππusesπ  m7UtilLo;ππtypeπ  tUART           = (uNoUART, uBadUART, u8250, u16450, u16550, u16550a);ππconstπ  MCR             = 4;π  MSR             = 6;π  Scratch         = 7;π  FCR             = 2;π  IIR             = 2;π  LOOPBIT         = $10;ππfunction UARTat(UART: Word): tUART;πvarπ  HoldMCR,π  HoldMSR,π  Holder          : Byte;πbegin {|UARTat}π  HoldMCR := Port[UART + MCR];π  Port[UART + MCR] := HoldMCR or LOOPBIT;π  HoldMSR := Port[UART + MSR];π  Port[UART + MCR] := $0A or LOOPBIT;π  Holder := Port[UART + MSR] and $F0;π  Port[UART + MSR] := HoldMSR;π  Port[UART + MCR] := HoldMCR and not LOOPBIT;π  if Holder <> $90 then beginπ    UARTat := uNoUART;π    Exitπ  end {|if Holder<>$90};π  Port[UART + Scratch] := $AA;π  if Port[UART + Scratch] <> $AA thenπ    UARTat := u8250π  else beginπ    Port[UART + FCR] := $01;π    Holder := Port[UART + IIR] and $C0;π    case Holder ofπ      $C0: UARTat := u16550a;π      $80: UARTat := u16550;π      $00: UARTat := u16450;π      else UARTat := uBadUART;π    end {|case Holder};π    Port[UART + FCR] := $00;π  end {|if Port[UART+Scratch]<>$AA else};πend {|UARTat};ππprocedure DisplayUARTat(UART: Word; name: string; num: Integer);πbegin {|DisplayUARTat}π  Write(Hex(UART, 4), ' ', name, num);π  if UART = 0 thenπ    Writeln(' not defined')π  elseπ    case UARTat(UART) ofπ      uNoUART: Writeln(' not present');π      uBadUART: Writeln(' broken');π      u8250: Writeln(' 8250B');π      u16450: Writeln(' 16450');π      u16550: Writeln(' 16550');π      u16550a: Writeln(' 16550A');π      else Writeln(' unknown');π    end {|case UARTat(UART)};πend {|DisplayUARTat};ππvarπ  i               : Integer;π  BIOSPortTab     : array [1 .. 4] of Word absolute $40: 0;πbegin {|ShowUARTs}π  Writeln; Writeln;π  Writeln('COM Port Detector');π  Writeln;π  for i := 1 to 4 doπ    DisplayUARTat($02E8 + $100 * (i and 1) + $10 * Ord(i < 3), 'Standard COM',π        i);π  Writeln;π  for i := 3 to 8 doπ    DisplayUARTat($3220 + $1000 * ((i - 3) div 2) + $8 * Ord(not Odd(i)),π        'PS/2 COM', i);π  Writeln;π  for i := 1 to 4 doπ    DisplayUARTat(BIOSPortTab[i], 'BIOS COM', i);πend {|ShowUARTs}.ππm7utillo is a general utility unit I use a lot; all you need is this routine:ππfunction Hex(v: Longint; w: Integer): String;πvarπ  s               : String;π  i               : Integer;πconstπ  hexc            : array [0 .. 15] of Char= '0123456789abcdef';πbeginπ  s[0] := Chr(w);π  for i := w downto 1 do beginπ    s[i] := hexc[v and $F];π    v := v shr 4π  end;π  Hex := s;πend {Hex};π                                                 17     08-17-9308:44ALL                      STEVE CONNET             Very Complete FOSSIL UnitIMPORT              90     ╣J¼     Unit FWizard;ππ{/π      Fossil Wizard Unit v1.0 by Steve Connet - Tuesday, Jan. 19, 1993ππ       This program provides an easy interface to access the routinesπ       provided by a fossil driver.π//}ππINTERFACEπFunction SetBaud(Port, Baud : Word; Parms : Byte) : Boolean;πFunction OutBufferFull(Port : Word) : Boolean;πFunction CharWaiting(Port : Word) : Boolean;πFunction ComReadChar(Port : Word) : Char;πFunction CarrierDetected(Port : Word) : Boolean;πFunction ModemRinging(Port : Word) : Boolean;πFunction FossilPresent : Boolean;πFunction RemoteAnsiDetected(Port : Word) : Boolean;πFunction LocalAnsiDetected : Boolean;πFunction RemoteAvatarDetected(Port : Word) : Boolean;ππProcedure ActivatePort(Port : Word);πProcedure DTR(Port : Word; Action : Byte);πProcedure ReBoot(Action : Byte);πProcedure DeActivatePort(Port : Word);πProcedure ComWriteChar(Port : Word; Ch : Char);πProcedure ClearOutBuffer(Port : Word);πProcedure ClearInBuffer(Port : Word);πProcedure FlowControl(Port : Word; XON_XOFFR, XON_XOFFT, RTS_CTS : Boolean);πProcedure WatchDog(Port : Word; Action : Byte);πProcedure Chat(Port : Word);πProcedure ComWrite(Port : Word; Msg : String);πProcedure ComWriteln(Port : Word; Msg : String);πProcedure Wait(Seconds : Word);πProcedure GetCursor(VAR x, y : Byte);πProcedure SetCursor(Port : Word; x, y : Byte);πProcedure SendBreak(Port : Word);πProcedure ComReadln(Port : Word; VAR Msg : String; Count : Byte);πProcedure CLS(Port : Word);ππCONSTπ  N81=$03; E81 =$1b; O81 =$0b; LOWER=$00; CTS =$10; RDA =$01; XONR=$01;π  N82=$07; E82 =$1f; O82 =$0f; RAISE=$01; DSR =$20; THRE=$20; XONT=$08;π  N71=$02; E71 =$1a; O71 =$0a; COLD =$00; RI  =$40; TSRE=$40; RTS =$02;π  N72=$06; E72 =$1e; O72 =$0e; WARM =$01; DCD =$80; ON  =$01; OFF =$00;π  Esc=#27; COM1=$00; COM2=$01; COM3 =$02; COM4=$03;ππIMPLEMENTATIONπUses Crt;ππFunction SetBaud(Port, Baud : Word; Parms : Byte) : Boolean;πVAR Dummy : Word;πBeginπ  Case Baud ofπ    300:   Baud := $40;    { 01000000 }π    600:   Baud := $60;    { 01100000 }π    1200:  Baud := $80;    { 10000000 }π    2400:  Baud := $a0;    { 10100000 }π    4800:  Baud := $c0;    { 11000000 }π    9600:  Baud := $e0;    { 11100000 }π    19200: Baud := $00;    { 00000000 }π    38400,π    14400,π    16800: Baud := $20;    { 00100000 }π  End;π  Parms := Parms OR Baud;  { merge baud bits with parm bits }π  Asmπ    mov ah,00hπ    mov al,parmsπ    mov dx,portπ    int 14hπ    mov dummy,axπ  End;π  SetBaud := ((Dummy AND CTS) = CTS) or     { clear to send }π             ((Dummy AND DSR) = DSR) or     { data set ready }π             ((Dummy AND RI)  = RI)  or     { ring indicator }π             ((Dummy AND DCD) = DCD)        { data carrier detect }πEnd;ππFunction OutBufferFull(Port : Word) : Boolean;πVAR Dummy : Byte;πBeginπ  Asmπ    mov ah,03hπ    mov dx,portπ    int 14hπ    mov dummy,ahπ  End;π  OutBufferFull := ((Dummy AND THRE) <> THRE) or  { room in out buffer }π                   ((Dummy AND TSRE) <> TSRE)     { out buffer empty }πEnd;ππFunction CharWaiting(Port : Word) : Boolean;πVAR Dummy : Byte;πBeginπ  Asmπ    mov ah,03hπ    mov dx,portπ    int 14hπ    mov dummy,ahπ  End;π  CharWaiting := (Dummy AND RDA) = RDA        { character waiting }πEnd;ππFunction ComReadChar(Port : Word) : Char;πVAR Dummy : Byte;πBeginπ  Asmπ    mov ah,02hπ    mov dx,portπ    int 14hπ    mov dummy,alπ  End;π  ComReadChar := Char(Dummy)πEnd;ππFunction CarrierDetected(Port : Word) : Boolean;πVAR Dummy : Byte;πBeginπ  Asmπ    mov ah,03hπ    mov dx,portπ    int 14hπ    mov dummy,alπ  End;π  CarrierDetected := (Dummy AND DCD) = DCD       { carrier detected }πEnd;ππFunction ModemRinging(Port : Word) : Boolean;πVAR Dummy : Byte;πBeginπ  Asmπ    mov ah,03hπ    mov dx,portπ    int 14hπ    mov dummy,alπ  End;π  ModemRinging := (Dummy AND RI) = RI       { ring indicated }πEnd;ππFunction FossilPresent : Boolean;πVAR Dummy : Word;πBeginπ  Asmπ    mov ah,04hπ    mov dx,00ffhπ    int 14hπ    mov dummy,axπ  End;π  FossilPresent := Dummy = $1954;πEnd;ππFunction RemoteAnsiDetected(Port : Word) : Boolean;πVAR Dummy : Char;πBeginπ  If Not OutBufferFull(Port) thenπ  Beginπ    ComWriteChar(Port, #27); ComWriteChar(Port, '[');π    ComWriteChar(Port, '6'); ComWriteChar(Port, 'n')π  End;π  If CharWaiting(Port) thenπ     RemoteAnsiDetected := ComReadChar(Port) in [#27,'0'..'9','[','H'] elseπ     RemoteAnsiDetected := False;π  ClearInBuffer(Port)πEnd;ππFunction LocalAnsiDetected : Boolean;πVAR Dummy : Byte;πBeginπ  Asmπ    mov ah,1ah                { detect ANSI.SYS device driver }π    mov al,00hπ    int 2fhπ    mov dummy,alπ  End;π  LocalAnsiDetected := Dummy = $FFπEnd;ππFunction RemoteAvatarDetected(Port : Word) : Boolean;πBeginπ  If Not OutBufferFull(Port) thenπ  Beginπ    ComWriteChar(Port, ' '); ComWriteChar(Port, ' ');π    ComWriteChar(Port, ' ');π  End;π  If CharWaiting(Port) thenπ     RemoteAvatarDetected := ComReadChar(Port) in ['A','V','T'] elseπ     RemoteAvatarDetected := False;π  ClearInBuffer(Port)πEnd;πππProcedure ActivatePort(Port : Word); Assembler;πAsmπ  mov ah,04hπ  mov dx,portπ  int 14hπEnd;ππProcedure DTR(Port : Word; Action : Byte); Assembler;πAsmπ  mov ah,06hπ  mov al,actionπ  mov dx,portπ  int 14hπEnd;ππProcedure ReBoot(Action : Byte); Assembler;πAsmπ  mov ah,17hπ  mov al,actionπ  int 14hπEnd;ππProcedure DeActivatePort(Port : Word); Assembler;πAsmπ  mov ax,05hπ  mov dx,portπ  int 14hπEnd;ππProcedure ComWriteChar(Port : Word; Ch : Char);πVAR Dummy : Byte;πBeginπ  Dummy := Ord(Ch);π  Asmπ    mov ah,01hπ    mov al,dummyπ    mov dx,portπ    int 14hπ  End;πEnd;ππProcedure ClearOutBuffer(Port : Word); Assembler;πAsmπ  mov ah,09hπ  mov dx,portπ  int 14hπEnd;ππProcedure ClearInBuffer(Port : Word); Assembler;πAsmπ  mov ah,0ahπ  mov dx,portπ  int 14hπEnd;ππProcedure FlowControl(Port : Word; XON_XOFFR, XON_XOFFT, RTS_CTS : Boolean);πVAR Dummy : Byte;πBeginπ  Dummy := $00;π  If XON_XOFFR then                 { Xon/Xoff receive enable }π     Dummy := Dummy OR XONR else    { set bit 0 on }π     Dummy := Dummy AND XONR;       { set bit 0 off }π  If XON_XOFFT then                 { Xon/Xoff transmit enable }π     Dummy := Dummy OR XONT else    { set bit 3 on }π     Dummy := Dummy AND XONT;       { set bit 3 off }π  If RTS_CTS then                   { RTS_CTS enabled }π     Dummy := Dummy OR RTS else     { set bit 1 on }π     Dummy := Dummy AND RTS;        { set bit 1 off }π  Asmπ    mov ah,0fhπ    mov al,dummyπ    mov dx,portπ    int 14hπ  EndπEnd;ππProcedure WatchDog(Port : Word; Action : Byte); Assembler;πAsmπ  mov ah,14hπ  mov al,actionπ  mov dx,portπ  int 14hπEnd;ππProcedure Chat(Port : Word);ππVAR Ch,π  AnsiCh : Char;π  Ansi   : Text;πBeginπ  Assign(Ansi,'');π  ReWrite(Ansi);π  Repeatπ     If Keypressed thenπ     Beginπ       Ch := Readkey;π       If Ch <> Esc thenπ          ComWriteChar(Port,ch)π     End;π     If CharWaiting(Port) thenπ     Beginπ        AnsiCh := ComReadChar(Port);π        If FossilPresent thenπ        Asmπ          mov ah,13hπ          mov al,ansichπ          int 14hπ        End elseπ        Write(Ansi,AnsiCh)          { no fossil driver }π     Endπ  Until Ch = Esc;π  Close(Ansi)πEnd;ππProcedure ComWrite(Port : Word; Msg : String);πVAR Dummy, x,π    SegMsg,π    OfsMsg : Word;π    Ansich : Char;π    Ansi   : Text;πBeginπ  Assign(Ansi,'');π  ReWrite(Ansi);π  Dummy := Ord(Msg[0]);             { length (msg) }π  If FossilPresent thenπ  Beginπ    SegMsg := Seg(Msg);π    OfsMsg := Ofs(Msg) + 1;           { don't include length of msg }π    Asm                               { use fossil driver }π      mov ah,19hπ      mov dx,portπ      mov cx,dummyπ      mov es,SegMsgπ      mov di,OfsMsgπ      int 14hπ    End;π    While CharWaiting(Port) doπ    Beginπ      AnsiCh := ComReadChar(Port);π      Asmπ        mov ah,13hπ        mov al,ansichπ        int 14hπ      Endπ    Endπ  End elseπ  For x := 1 to dummy doπ  Beginπ    ComWriteChar(Port,Msg[x]);π    If CharWaiting(Port) thenπ      Write(Ansi,ComReadChar(Port))π  End;π  Close(Ansi)πEnd;ππProcedure ComWriteln(Port : Word; Msg : String);πBeginπ   Msg := Msg + #13 + #10;π   ComWrite(Port, Msg)πEnd;ππProcedure Wait(Seconds : Word);πVAR Delay : Word;πBeginπ   Delay := ((976 SHL 10) * Seconds) SHR 16;  { (976*1024*seconds)/65536 }π   Asmπ     mov ah,86hπ     mov cx,delayπ     mov dx,0π     int 15hπ   EndπEnd;ππProcedure GetCursor(VAR x, y : Byte);πVAR x1, y1 : Byte;πBeginπ  If FossilPresent thenπ  Asmπ    mov ah,12hπ    int 14hπ    mov x1,dlπ    mov y1,dhπ  End elseπ  Asmπ    mov ah,03hπ    mov bh,00hπ    int 10hπ    mov x1,dlπ    mov y1,dhπ  End;π  x := x1; y := y1πEnd;ππProcedure SetCursor(Port : Word; x, y : Byte);πVAR x1,y1 : String;πBeginπ  If FossilPresent thenπ  Asmπ    mov ah,11hπ    mov dh,yπ    mov dl,xπ    int 14hπ  End elseπ  Asmπ    mov ah,02hπ    mov bh,00hπ    mov dh,yπ    mov dl,xπ    int 10hπ  End;π  If (CarrierDetected(port)) and (RemoteAnsiDetected(Port)) thenπ  Beginπ    Str(x,x1);π    Str(y,y1);π    ComWrite(Port,' ['+y1+';'+x1+'H')     { ESC[y;xH }π  EndπEnd;ππProcedure SendBreak(Port : Word); Assembler;πAsmπ  mov ah,1ah             {; start sending break }π  mov al,01hπ  mov dx,portπ  int 14hπ  mov ah,86h             {; wait 1 second }π  mov cx,0fhπ  mov dx,00hπ  int 15hπ  mov ah,1ah             {; stop sending break }π  mov al,00hπ  mov dx,portπ  int 14hπ  mov ah,0ah             {; purge input buffer }π  mov dx,portπ  int 14hπEnd;ππProcedure ComReadln(Port : Word; VAR Msg : String; Count : Byte);πVAR WLength,π    SegMsg,π    OfsMsg : Word;πBeginπ   SegMsg := Seg(Msg);π   OfsMsg := Ofs(Msg);π   WLength := Count;π   Asmπ     mov ah,18hπ     mov di,ofsmsgπ     mov es,segmsgπ     mov cx,wlengthπ     mov dx,portπ     int 14hπ   End;πEnd;ππProcedure CLS(Port : Word);πBeginπ  ClrScr;π  If CarrierDetected(Port) thenπ     If RemoteAnsiDetected(Port) thenπ        ComWrite(Port,' [2J') elseπ        ComWriteChar(Port,' ');πEnd;ππBeginπ   Writeln('Fossil Wizard v1.0 by Steve Connet - Jan. 19, 1993');π   Writeln('This is removed when you register.');π   Wait(2)πEnd.πππ(* This is an example of how to use Fossil Wizard *)ππUses FWizard, Crt;ππVARπ         Ch : Char;π       Baud : Word;ππBeginπ  Baud := 2400;    { change this to the appropriate baud }π  ClrScr;ππ  SetCursor(Com2,50,19);π  If FossilPresent thenπ  Beginπ    ActivatePort(Com2);                { wake up fossil driver }π    Write('[FOSSIL PRESENT]')π  End elseπ  Write('[FOSSIL NOT PRESENT]');ππ  SetCursor(Com2,50,20);π  If SetBaud(Com2,Baud,N81) then       { set baud rate }π     Write('[MODEM READY]') elseπ     Write('[MODEM NOT RESPONDING]');ππ  SetCursor(Com2,50,21);π  If CarrierDetected(Com2) thenπ     Write('[CARRIER DETECTED]') elseπ     Write('[NO CARRIER]');ππ  SetCursor(Com2,50,22);π  If (CarrierDetected(Com2)) and (RemoteAvatarDetected(Com2)) thenπ    Write('[REMOTE AVATAR DETECTED]') elseπ    Write('[REMOTE AVATAR NOT DETECTED]');ππ  SetCursor(Com2,50,23);π  If (CarrierDetected(Com2)) and (RemoteAnsiDetected(Com2)) thenπ    Write('[REMOTE ANSI DETECTED]') elseπ    Write('[REMOTE ANSI NOT DETECTED]');ππ  SetCursor(Com2,50,24);π  If LocalAnsiDetected thenπ     Write('[LOCAL ANSI DETECTED]') elseπ     Write('[LOCAL ANSI NOT DETECTED]');ππ  SetCursor(Com2,0,0);π  Chat(Com2);              { built in chat mode }π  DTR(Com2,Lower);         { lower data terminal ready }π  DeActivatePort(Com2);    { put fossil driver to sleep }π  ClrScrπEnd.π                                                       18     08-18-9312:29ALL                      JOSE ALMEIDA             Serial Base Addresses    IMPORT              5      ╣J├∩ FUNCTION Serial_Base_Addr(COM_Port : byte) : word;π{ DESCRIPTION:π    Base address for four serial ports.π  SAMPLE CALL:π    NW := Serial_Base_Addr(1);π  RETURNS:π    The base address for the specified serial port.π  NOTES:π    If the port is not used, then the returned value will be 0 (zero).π    The aceptable values for COM_Port are: 1,2,3 and 4. }ππBEGIN { Serial_Base_Addr }π  Serial_Base_Addr := MemW[$0000:$0400 + Pred(COM_Port) * 2];πEND; { Serial_Base_Addr }π                                           19     08-18-9312:29ALL                      JOSE ALMEIDA             Get number of RS232 PortsIMPORT              3      ╣J├! FUNCTION Serial_Ports : byte;π{ DESCRIPTION:π    Gets the number of RS232 ports available in a system.π  SAMPLE CALL:π    NB := Serial_Ports; }ππBEGIN { Serial_Ports }π  Serial_Ports := (MemW[$0000:$0410] shl 4) shr 13;πEND; { Serial_Ports }π              20     08-18-9312:30ALL                      JOSE ALMEIDA             Get Serial Port Timeout  IMPORT              4      ╣J² FUNCTION Serial_Time_Out(COM : byte) : byte;π{ DESCRIPTION:π    Time-Out values for RS232 communications lines.π  SAMPLE CALL:π    NB := Serial_Time_Out(1);π  NOTES:π    The allowed values for COM are: 1,2,3 or 4. }ππBEGIN { Serial_Time_Out }π  Serial_Time_Out := Mem[$0000:$047C + Pred(COM)];πEND; { Serial_Time_Out }π                                                                 21     08-23-9309:16ALL                      ERIC GIVLER              Get Device Function      IMPORT              15     ╣JΓ/ {π===========================================================================π BBS: Canada Remote SystemsπDate: 08-16-93 (19:59)             Number: 34567πFrom: ERIC GIVLER                  Refer#: NONEπ  To: ALL                           Recvd: NOπSubj: PROBLEM                        Conf: (1221) F-PASCALπ---------------------------------------------------------------------------πWhen I start up the BBS and it has the wrong port# (ie Com1 instead of 2),πthe machine will lockup trying to write to the modem.  If the port isπcorrect, there are NO problems as long as the modem is on.  Is there aπgraceful way of detecting this and remedying it - ie.  Even an abortπto DOS with an errorlevel would be nicer than a LOCKUP!  The followingπidea is what I've tried.  It DOES appear to work!π}πUSES CRT,DOS;ππfunction is_device_ready( devicename:string) : boolean;πvar r      : registers; handle : word; ready  : byte;πbeginπ     ready := 0;π     r.ds := seg(devicename);π     r.dx := ofs(devicename[1]);π     r.ax := $3d01;π     msdos(r);π     if (r.flags and fCarry) <> fCarry thenπ     beginπ         handle := r.ax;π         ready  := 1;π         r.ax := $4407;π         r.bx := handle;π         msdos(r);π         ready := ready and r.AL;π         r.ah := $3e;π         r.bx := handle;π         msdos(r);π     end;π     is_device_ready := ( ready = 1 );πend; { is_device_ready }ππbeginπ   ClrScr;π   writeln('COM2 is ready ..', is_device_ready('COM2'+#00) );π   writeln('COM1 is ready ..', is_device_ready('COM1'+#00) );π   writeln('LPT1 is ready ..', is_device_ready('PRN' + #00) );πend.ππ--- msgedsq 2.1π * Origin: Noname Consultants (717)561-8033 (1:270/101.15)π                                                                                                                            22     08-27-9320:06ALL                      SEAN PALMER              Simple Avatar code       IMPORT              24     ╣J╠° w{πSEAN PALMERππUsing the state-driven approach, I came up With this simplisticπAvatar/0 interpreter as an example. Do With it as you wish...ππby Sean L. PalmerπPublic Domainπ}ππProgram avtWrite;π{ example to do avatar/0 (FSC-0025) interpretation }π{ could easily be extended to handle /0+ and /1 codes }ππUsesπ  Crt;ππ{ this part of the Program controls the state-driven part of the displayπ  handler. }ππVarπ  saveAdr : Pointer;  { where state handler is now }π  c       : Char;     { Char accessed by state handler }π  b       : Byte Absolute c;ππProcedure avtWriteCh(c2 : Char); Inline(π  $8F/$06/>C/            { pop Byte ptr [>c] }π  $FF/$1E/>SAVEADR);     { call dWord ptr [>saveAdr] }π                         { continue where handler lππ                           call this Procedure from StateHandler toπ                           suspend execution Until next timeπ}ππProcedure wait; near; Assembler;πAsm                             { wait For next Char }π  pop Word ptr saveAdr          { save where to continue next time }π  retF                          { simulate Exit from calling proc }πend;ππ{π a stateHandler Procedure should never ever Exit (only by calling 'wait'),π shouldn't have any local Variables or parameters, and shouldn't callπ 'wait' With anything on the stack (like from a subroutine).π This routine is using the caller's stack, so be carefulπ}ππVarπ  avc : Char;π  avb : Byte Absolute avc;ππProcedure stateHandler;πbeginππ  Repeatππ    Case c ofππ      ^L :π        beginπ          ClrScr;π          Textattr := 3;π        end;ππ      ^Y :π        beginπ          wait;π          avc := c;π          wait;π          While c <> #0 doπ          beginπ            dec(c);π            Write(avc);π          end;π        end;ππ      ^V :π        beginπ          wait;π          Case c ofππ            ^A :π              beginπ                wait;π                Textattr := Byte(c);π              end;π            ^B : Textattr := Textattr or $80;π            ^C : if whereY > 1  then GotoXY(whereX, whereY - 1);π            ^D : if whereY < 25 then GotoXY(whereX, whereY + 1);π            ^E : if whereX > 1  then GotoXY(whereX - 1,whereY);π            ^F : if whereX < 80 then GotoXY(whereX + 1,whereY);π            ^G : clreol;π            ^H :π              beginπ                wait;π                avb := b;π                wait;π                GotoXY(b + 1, avb + 1);π              end;π            elseπ              Write(^V, c);π          end;π        end;π      elseπ        Write(c);π   end;π   wait;π   Until False;πend;ππVarπ  i : Integer;πConstπ  s : String = 'Oh my'^V^D^V^D^V^F^V^A#1'it works'^V^A#4',see?';πbegin  {could do something like attach it to Output's InOutFunc...}π  saveAdr := ptr(seg(stateHandler), ofs(stateHandler) + 3); {skip header}π  For i := 1 to length(s) doπ    avtWriteCh(s[i]);πend.π                                                                                         23     08-27-9321:24ALL                      RONEN MAGID              Fossil unit              IMPORT              78     ╣J<$ {π                     Version 1.2  26-August-1989ππ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄π█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█π█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█π█▒▒▒▒▒▒▒▒█████████████████████████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█π█▒▒▒▒▒▒▒ ███                         ▒▒▒▒▒▒▒▒▒▒▒▒▒███▒▒▒▒┌──────────────────┐▒█π█▒▒▒▒▒▒▒ ███▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ███▒▒▒▒│   Ronen Magid's  │▒█π█▒▒▒▒▒▒▒ ███▒▒▒▒▒████████▒▒███████▒▒███████▒▒███▒ ███▒▒▒▒│                  │▒█π█▒▒▒▒▒▒▒ ███▒▒▒▒ ███  ███▒ ███   ▒▒ ███   ▒▒ ███▒ ███▒▒▒▒│      Fossil      │▒█π█▒▒▒▒▒▒▒ ██████▒ ███▒ ███▒ ███▒▒▒▒▒ ███▒▒▒▒▒ ███▒ ███▒▒▒▒│      support     │▒█π█▒▒▒▒▒▒▒ ███  ▒▒ ███▒ ███▒ ███████▒ ███████▒ ███▒ ███▒▒▒▒│     Unit For     │▒█π█▒▒▒▒▒▒▒ ███▒▒▒▒ ███▒ ███▒     ███▒     ███▒ ███▒ ███▒▒▒▒│                  │▒█π█▒▒▒▒▒▒▒ ███▒▒▒▒ ███▒ ███▒▒▒▒  ███▒▒▒▒  ███▒ ███▒ ███▒▒▒▒│   TURBO PASCAL   │▒█π█▒▒▒▒▒▒▒ ███▒▒▒▒ ████████▒▒███████▒▒███████▒ ███▒ ███▒▒▒▒│     versions     │▒█π█▒▒▒▒▒▒▒   ▒▒▒▒▒        ▒▒       ▒▒       ▒▒   ▒▒   ▒▒▒▒▒│       4,5        │▒█π█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒└──────────────────┘▒█π█▒▒▒████████████████████████████████████████████████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█π█▒▒                                                    ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█π█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█π▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ππ          Copyright (c) 1989 by Ronen Magid. Tel (972)-52-917663 VOICEπ                             972-52-27271 2400 24hrsπππ}ππUnit FOSCOM;ππInterfaceππUsesπ  Dos, Crt;ππVarπ  Regs : Registers;                    {Registers used by Intr and Ms-Dos}ππππ{             Available user Procedures and Functions                     }ππProcedure Fos_Init       (Comport: Byte);πProcedure Fos_Close      (Comport: Byte);πProcedure Fos_Parms      (Comport: Byte; Baud: Integer; DataBits: Byte;π                          Parity: Char; StopBit: Byte);πProcedure Fos_Dtr        (Comport: Byte; State: Boolean);πProcedure Fos_Flow       (Comport: Byte; State: Boolean);πFunction  Fos_CD         (Comport: Byte) : Boolean;πProcedure Fos_Kill_Out   (Comport: Byte);πProcedure Fos_Kill_In    (Comport: Byte);πProcedure Fos_Flush      (Comport: Byte);πFunction  Fos_Avail      (Comport: Byte) : Boolean;πFunction  Fos_OkToSend   (Comport: Byte) : Boolean;πFunction  Fos_Empty      (Comport: Byte) : Boolean;πProcedure Fos_Write      (Comport: Byte; Character: Char);πProcedure Fos_String     (Comport: Byte; OutString: String);πProcedure Fos_StringCRLF (Comport: Byte; OutString: String);πProcedure Fos_Ansi       (Character: Char);πProcedure Fos_Bios       (Character: Char);πProcedure Fos_WatchDog   (Comport: Byte; State: Boolean);πFunction  Fos_Receive    (Comport: Byte) : Char;πFunction  Fos_Hangup     (Comport: Byte) : Boolean;πProcedure Fos_Reboot;πFunction  Fos_CheckModem (Comport: Byte) : Boolean;πFunction  Fos_AtCmd      (Comport: Byte; Command: String)  : Boolean;πProcedure Fos_Clear_Regs;πππImplementationππProcedure Fos_Clear_Regs;πbeginπ  FillChar (Regs, SizeOf (Regs), 0);πend;ππProcedure Fos_Init  (Comport: Byte);πbeginπ Fos_Clear_Regs;π With Regs Doπ beginπ    AH := 4;π    DX := (ComPort-1);π    Intr ($14, Regs);π    if AX <> $1954 thenπ    beginπ      Writeln;π      Writeln (' Fossil driver is not loaded.');π      halt (1);π    end;π  end;πend;ππProcedure Fos_Close (Comport: Byte);πbeginπ  Fos_Clear_Regs;π  Fos_Dtr(Comport,False);ππ  With Regs Doπ  beginπ    AH := 5;π    DX := (ComPort-1);π    Intr ($14, Regs);π  end;πend;πππProcedure Fos_Parms (ComPort: Byte; Baud: Integer; DataBits: Byte;π                                    Parity: Char; StopBit: Byte);πVarπ Code: Integer;πbeginπ  Code:=0;π  Fos_Clear_Regs;π  Case Baud ofπ      0 : Exit;π    100 : code:=code+000+00+00;π    150 : code:=code+000+00+32;π    300 : code:=code+000+64+00;π    600 : code:=code+000+64+32;π    1200: code:=code+128+00+00;π    2400: code:=code+128+00+32;π    4800: code:=code+128+64+00;π    9600: code:=code+128+64+32;π  end;ππ  Case DataBits ofπ    5: code:=code+0+0;π    6: code:=code+0+1;π    7: code:=code+2+0;π    8: code:=code+2+1;π  end;ππ  Case Parity ofπ    'N','n': code:=code+00+0;π    'O','o': code:=code+00+8;π    'E','e': code:=code+16+8;π  end;ππ  Case StopBit ofπ    1: code := code + 0;π    2: code := code + 4;π  end;ππ  With Regs doπ  beginπ    AH := 0;π    AL := Code;π    DX := (ComPort-1);π    Intr ($14, Regs);π  end;πend;ππProcedure Fos_Dtr   (Comport: Byte; State: Boolean);πbeginπ  Fos_Clear_Regs;π  With Regs doπ  beginπ    AH := 6;π    DX := (ComPort-1);π    Case State ofπ    True : AL := 1;π    False: AL := 0;π    end;π    Intr ($14, Regs);π  end;πend;πππFunction  Fos_CD    (Comport: Byte) : Boolean;πbeginπ  Fos_Clear_Regs;π  With Regs doπ  beginπ    AH := 3;π    DX := (ComPort-1);π    Intr ($14, Regs);π    Fos_Cd := ((AL and 128) = 128);π  end;πend;πππProcedure Fos_Flow  (Comport: Byte; State: Boolean);πbeginπ  Fos_Clear_Regs;π    With Regs doπ    beginπ    AH := 15;π    DX := ComPort-1;π    Case State ofπ      True:  AL := 255;π      False: AL := 0;π    end;π    Intr ($14, Regs);π  end;πend;ππProcedure Fos_Kill_Out (Comport: Byte);πbeginπ  Fos_Clear_Regs;π    With Regs doπ    beginπ    AH := 9;π    DX := ComPort-1;π    Intr ($14, Regs);π  end;πend;πππProcedure Fos_Kill_In  (Comport: Byte);πbeginπ  Fos_Clear_Regs;π  With Regs doπ  beginπ    AH := 10;π    DX := ComPort-1;π    Intr ($14, Regs);π  end;πend;ππProcedure Fos_Flush    (Comport: Byte);πbeginπ  Fos_Clear_Regs;π  With Regs doπ  beginπ    AH := 8;π    DX := ComPort-1;π    Intr ($14, Regs);π  end;πend;ππFunction  Fos_Avail    (Comport: Byte) : Boolean;πbeginπ  Fos_Clear_Regs;π  With Regs doπ  beginπ    AH := 3;π    DX := ComPort-1;π    Intr ($14, Regs);π    Fos_Avail:= ((AH and 1) = 1);π  end;πend;ππFunction  Fos_OkToSend (Comport: Byte) : Boolean;πbeginπ  Fos_Clear_Regs;π  With Regs doπ  beginπ    AH := 3;π    DX := ComPort-1;π    Intr ($14, Regs);π    Fos_OkToSend := ((AH and 32) = 32);π  end;πend;πππFunction  Fos_Empty (Comport: Byte) : Boolean;πbeginπ  Fos_Clear_Regs;π  With Regs doπ  beginπ    AH := 3;π    DX := ComPort-1;π    Intr ($14, Regs);π    Fos_Empty := ((AH and 64) = 64);π  end;πend;ππProcedure Fos_Write     (Comport: Byte; Character: Char);πbeginπ  Fos_Clear_Regs;π  With Regs doπ  beginπ    AH := 1;π    DX := ComPort-1;π    AL := ORD (Character);π    Intr ($14, Regs);π  end;πend;πππProcedure Fos_String   (Comport: Byte; OutString: String);πVarπ  Pos: Byte;πbeginπ  For Pos := 1 to Length(OutString) doπ  beginπ     Fos_Write(Comport,OutString[Pos]);π   end;πOutString:='';πend;πππProcedure Fos_StringCRLF  (Comport: Byte; OutString: String);πVarπ  Pos: Byte;πbeginπ  For Pos := 1 to Length(OutString) doπ    Fos_Write(ComPort,OutString[Pos]);π  Fos_Write(ComPort,Char(13));π  Fos_Write(ComPort,Char(10));π  OutString:='';πend;ππProcedure Fos_Bios     (Character: Char);π beginπ   Fos_Clear_Regs;π   With Regs doπ   beginπ     AH := 21;π     AL := ORD (Character);π     Intr ($14, Regs);π  end;πend;πππProcedure Fos_Ansi     (Character: Char);πbeginπ  Fos_Clear_Regs;π  With Regs doπ  beginπ    AH := 2;π    DL := ORD (Character);π    Intr ($21, Regs);π  end;πend;πππProcedure Fos_WatchDog (Comport: Byte; State: Boolean);πbeginπ  Fos_Clear_Regs;π  With Regs doπ  beginπ    AH := 20;π    DX := ComPort-1;π    Case State ofπ      True  : AL := 1;π      False : AL := 0;π    end;π    Intr ($14, Regs);π  end;πend;πππFunction Fos_Receive  (Comport: Byte) : Char;πbeginπ  Fos_Clear_Regs;π  With Regs doπ  beginπ    AH := 2;π    DX := ComPort-1;π    Intr ($14, Regs);π    Fos_Receive := Chr(AL);π  end;πend;πππFunction Fos_Hangup   (Comport: Byte) : Boolean;πVarπ  Tcount : Integer;πbeginπ  Fos_Dtr(Comport,False);π  Delay (600);π  Fos_Dtr(Comport,True);π  if FOS_CD (ComPort)=True thenπ  beginπ    Tcount:=1;π    Repeatπ      Fos_String (Comport,'+++');π      Delay (3000);π      Fos_StringCRLF (Comport,'ATH0');π      Delay(3000);π      if Fos_CD (ComPort)=False thenπ        tcount:=3;π      Tcount:=Tcount+1;π    Until Tcount=4;π  end;ππ  if Fos_Cd (ComPort)=True thenπ    Fos_Hangup:=Falseπ  elseπ    Fos_Hangup:=True;πend;πππProcedure Fos_Reboot;πbeginπ  Fos_Clear_Regs;π  With Regs doπ  beginπ    AH := 23;π    AL := 1;π    Intr ($14, Regs);π  end;πend;ππFunction Fos_CheckModem (Comport: Byte) : Boolean;πVarπ  Ch     :   Char;π  Result :   String[10];π  I,Z    :   Integer;ππbeginπ  Fos_CheckModem:=False;π  Result:='';π  For Z:=1 to 3 doπ  beginπ    Delay(500);π    Fos_Write (Comport,Char(13));π    Delay(1000);π    Fos_StringCRLF (Comport,'AT');π    Delay(1000);π    Repeatπ      if Fos_Avail (Comport) thenπ      beginπ        Ch:=Fos_Receive(Comport);π        Result:=Result+Ch;π      end;π    Until Fos_Avail(1)=False;π    For I:=1 to Length(Result) doπ    beginπ      if Copy(Result,I,2)='OK' thenπ      beginπ        Fos_CheckModem:=True;π        Exit;π      end;π    end;π  end;πend;πππFunction Fos_AtCmd (Comport: Byte; Command: String) : Boolean;πVarπ  Ch     :   Char;π  Result :   String[10];π  I,Z    :   Integer;πbeginπ  Fos_AtCmd:=False;π  Result:='';π  For Z:=1 to 3 doπ  beginπ    Delay(500);π    Fos_Write (Comport,Char(13));π    Delay(1000);π    Fos_StringCRLF (Comport,Command);π    Delay(1000);π    Repeatπ      if Fos_Avail (Comport) thenπ      beginπ        Ch:=Fos_Receive(Comport);π        Result:=Result+Ch;π      end;π    Until Fos_Avail(1)=False;π    For I:=1 to Length(Result) doπ    beginπ      if Copy(Result,I,2)='OK' thenπ      beginπ        Fos_AtCmd:=True;π       Exit;π      end;π    end;π  end;πend;ππend.ππ                                                                                                   24     08-27-9321:25ALL                      STEVE GABRILOWIZ         Another Fossil Unit      IMPORT              95     ╣JΣà {πSTEVE GABRILOWITZππ> I was wondering if anyone had any routines they could send me or tellπ> me where to find some routines that show you have to use theπ> fossil I have a file on my BBS called TPIO_100.ZIP,π}ππUnit IO;πππ              { FOSSIL communications I/O routines }π              { Turbo Pascal Version by Tony Hsieh }ππ  {}{}{}{ Copyright (c) 1989 by Tony Hsieh, All Rights Reserved. }{}{}{}πππ{ The following routines are basic input/output routines, using a }π{ fossil driver.  These are NOT all the routines that a fossil    }π{ driver can do!  These are just a portion of the functions that  }π{ fossil drivers can do.  However, these are the only ones most   }π{ people will need.  I highly recommend for those that use this   }π{ to download an arced copy of the X00.SYS driver.  In the arc    }π{ is a file called "FOSSIL.DOC", which is where I derived my      }π{ routines from.  If there are any routines that you see are not  }π{ implemented here, use FOSSIL.DOC to add/make your own!  I've    }π{ listed enough examples here for you to figure out how to do it  }π{ yourself.                                                       }π{ This file was written as a unit for Turbo Pascal v4.0.  You     }π{ should compile it to DISK, and then in your own program type    }π{ this right after your program heading (before Vars and Types)   }π{ this: "uses IO;"                                                }π{ EXAMPLE: }π{ππProgram Communications;ππuses IO;ππbeginπ  InitializeDriver;π  Writeln ('Driver is initalized!');π  ModemSettings (1200,8,'N',1); Baud := 1200;π  DTR (0); Delay (1000); DTR (1);π  Writeln ('DTR is now true!');π  CloseDriver;π  Writeln ('Driver is closed!');πend.ππ}ππ{ Feel free to use these routines in your programs; copy this  }π{ file freely, but PLEASE DO NOT MODIFY IT.  If you do use     }π{ these routines in your program, please give proper credit to }π{ the author.                                                  }π{                                                              }π{ Thanks, and enjoy!                                           }π{                                                              }π{ Tony Hsieh                                                   }πππππINTERFACEππusesπ  DOS;ππ  { These are communications routines }π  { that utilize a FOSSIL driver.  A  }π  { FOSSIL driver MUST be installed,  }π  { such as X00.SYS and OPUS!COM...   }ππtypeπ  String255 = String [255];ππvarπ  Port : Integer;                { I decided to make 'Port' a global    }π                                 { variable to make life easier.        }ππ  Baud : Word;                   { Same with Baud                       }ππ  RegistersRecord: Registers;    { DOS registers AX, BX, CX, DX, and Flags }πππprocedure BlankRegisters;πprocedure ModemSettings(Baud, DataBits : Integer; Parity : Char;π                         Stopbits : Integer);πprocedure InitializeDriver;πprocedure CloseDriver;πprocedure ReadKeyAhead (var First, Second : Char);πfunction  ReceiveAhead (var Character : CHAR) : Boolean;πfunction  Online : boolean;πprocedure DTR(DTRState : Integer);πprocedure Reboot;πprocedure BiosScreenWrite(Character: CHAR);πprocedure WatchDog(INPUT : Boolean);πprocedure WhereCursor(var Row : Integer; var Column : Integer);πprocedure MoveCursor(Row : Integer; Column : Integer);πprocedure KillInputBuffer;πprocedure KillOutputBuffer;πprocedure FlushOutput;πfunction  InputAvailable : Boolean;πfunction  OutputOkay : Boolean;πprocedure ReceiveCharacter(var Character : CHAR);πprocedure TransmitCharacter(Character : CHAR; var Status : Integer);πprocedure FlowControl(Control : Boolean);πprocedure CharacterOut(Character : CHAR);πprocedure StringOut(Message : String255);πprocedure LineOut(Message : String255);πprocedure CrOut;πππIMPLEMENTATIONππprocedure BlankRegisters;πbeginπ  Fillchar(RegistersRecord, SizeOf(RegistersRecord), 0);πend;ππprocedure ModemSettings (Baud, DataBits : Integer; Parity : Char;π                         StopBits : Integer);π                                               { Do this after initializing }π                                               { the FOSSIL driver and also }π                                               { when somebody logs on      }πvarπ  GoingOut: Integer;πbeginπ  GoingOut := 0;π  Case Baud ofπ      0 : Exit;π    100 : GoingOut := GoingOut + 000 + 00 + 00;π    150 : GoingOut := GoingOut + 000 + 00 + 32;π    300 : GoingOut := GoingOut + 000 + 64 + 00;π    600 : GoingOut := GoingOut + 000 + 64 + 32;π    1200: GoingOut := GoingOut + 128 + 00 + 00;π    2400: GoingOut := GoingOut + 128 + 00 + 32;π    4800: GoingOut := GoingOut + 128 + 64 + 00;π    9600: GoingOut := GoingOut + 128 + 64 + 32;π  end;π  Case DataBits ofπ    5: GoingOut := GoingOut + 0 + 0;π    6: GoingOut := GoingOut + 0 + 1;π    7: GoingOut := GoingOut + 2 + 0;π    8: GoingOut := GoingOut + 2 + 1;π  end;π  Case Parity ofπ    'N'    : GoingOut := GoingOut + 00 + 0;π    'O','o': GoingOut := GoingOut + 00 + 8;π    'n'    : GoingOut := GoingOut + 16 + 0;π    'E','e': GoingOut := GoingOut + 16 + 8;π  end;π  Case StopBits ofπ    1: GoingOut := GoingOut + 0;π    2: GoingOut := GoingOut + 4;π  end;π  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 0;π    AL := GoingOut;π    DX := (Port);π    Intr($14, RegistersRecord);π  end;πend;ππprocedure InitializeDriver;                         { Do this before doing }πbegin                                               { any IO routines!!!   }π  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 4;π    DX := (Port);π    Intr($14, RegistersRecord);π    If AX <> $1954 thenπ    beginπ      Writeln('* FOSSIL DRIVER NOT RESPONDING!  OPERATION HALTED!');π      halt(1);π    end;π  end;πend;ππprocedure CloseDriver;  { Run this after all I/O routines are done with }πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 5;π    DX := (Port);π    Intr($14, RegistersRecord);π  end;π  BlankRegisters;πend;ππprocedure ReadKeyAhead (var First, Second: Char); { This procedure is via  }π                                                  { the FOSSIL driver, not }π                                                  { DOS!                   }πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := $0D;π    Intr($14,RegistersRecord);π    First := chr(lo(AX));π    Second := chr(hi(AX));π  end;πend;ππfunction ReceiveAhead (var Character: CHAR): Boolean;  { Non-destructive }πbeginπ  If Baud=0 then exit;π  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := $0C;π    DX := Port;π    Intr ($14,RegistersRecord);π    Character := CHR (AL);π    ReceiveAhead := AX <> $FFFF;π  end;πend;ππfunction OnLine: Boolean;πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 3;π    DX := (Port);π    Intr ($14, RegistersRecord);π    OnLine := ((AL AND 128) = 128);π  end;πend;ππprocedure DTR (DTRState: Integer);    { 1=ON, 0=OFF }π                                      { Be sure that the modem dip switches }π                                      { are set properly... when DTR is off }π                                      { it usually drops carrier if online  }πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 6;π    DX := (Port);π    AL := DTRState;π    Intr ($14, RegistersRecord);π  end;πend;ππprocedure Reboot;                  { For EXTREME emergencies... Hmmm... }πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 23;π    AL := 1;π    Intr ($14, RegistersRecord);π  end;πend;ππ{       This is ANSI Screen Write via Fossil Driver }π{πprocedure ANSIScreenWrite (Character: CHAR);πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 19;π(100 min left), (H)elp, More?     AL := ORD (Character);π    Intr ($14, RegistersRecord);π  end;πend;π}ππ{ This is ANSI Screen Write via DOS! }ππprocedure ANSIScreenWrite (Character: CHAR);πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 2;π    DL := ORD (Character);π    Intr ($21, RegistersRecord);π  end;πend;πππprocedure BIOSScreenWrite (Character: CHAR); { Through the FOSSIL driver }πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 21;π    AL := ORD (Character);π    Intr ($14, RegistersRecord);π  end;πend;ππprocedure WatchDog (INPUT: Boolean);πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 20;π    DX := Port;π    Case INPUT ofπ      TRUE:  AL := 1;π      FALSE: AL := 0;π    end;π    Intr ($14, RegistersRecord);π  end;πend;ππprocedure WhereCursor (var Row: Integer; var Column: Integer);πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 18;π    Intr ($14, RegistersRecord);π    Row := DH;π    Column := DL;π  end;πend;ππprocedure MoveCursor (Row: Integer; Column: Integer);πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 17;π    DH := Row;π    DL := Column;π    Intr ($14, RegistersRecord);π  end;πend;ππprocedure KillInputBuffer;   { Kills all remaining input that has not been }π                             { read in yet }πbeginπ  If Baud=0 then exit;π  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 10;π    DX := Port;π    Intr ($14, RegistersRecord);π  end;πend;ππprocedure KillOutputBuffer;  { Kills all pending output that has not been }π                             { send yet }πbeginπ  If Baud=0 then exit;π  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 9;π    DX := Port;π    Intr ($14, RegistersRecord);π  end;πend;ππprocedure FlushOutput;       { Flushes the output buffer }πbeginπ  If Baud=0 then exit;π  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 8;π    DX := Port;π    Intr ($14, RegistersRecord);π  end;πend;ππfunction InputAvailable: Boolean;   { Returns true if there's input }π                                    { from the modem.               }πbeginπ  InputAvailable := False;π  If Baud=0 then exit;π  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 3;π    DX := Port;π    Intr ($14, RegistersRecord);π    InputAvailable := ((AH AND 1) = 1);π  end;πend;ππfunction OutputOkay: Boolean;     { Returns true if output buffer isn't full }πbeginπ  OutputOkay := True;π  If Baud=0 then exit;π  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 3;π    DX := Port;π    Intr ($14, RegistersRecord);π    OutputOkay := ((AH AND 32) = 32);π  end;πend;ππprocedure ReceiveCharacter (var Character: CHAR);   { Takes a character }π                                                    { out of the input  }π                                                    { buffer }πbeginπ  Character := #0;π  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 2;π    DX := Port;π    Intr ($14, RegistersRecord);π    Character := CHR (AL);π  end;πend;ππprocedure TransmitCharacter (Character: CHAR; var Status: Integer);πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 1;π    DX := Port;π    AL := ORD (Character);π    Intr ($14, RegistersRecord);π    Status := AX;        { Refer to FOSSIL.DOC about the STATUS var }π  end;πend;ππprocedure FlowControl (Control: Boolean);πbeginπ  BlankRegisters;π  With RegistersRecord doπ  beginπ    AH := 15;π    DX := Port;π    Case Control ofπ     TRUE:  AL := 255;π     FALSE: AL := 0;π    end;π    Intr ($14, RegistersRecord);π  end;πend;ππprocedure CharacterOut (Character: CHAR);πvarπ  Status: INTEGER;πbeginπ  { If SNOOP is on then }π    ANSIScreenWrite (Character);π  TransmitCharacter (Character, Status);πend;ππprocedure StringOut (Message: String255);πvarπ  CharPos: Byte;πbeginπ  CharPos := 0;π  If Length(Message) <> 0 thenπ  beginπ    Repeatπ      If NOT Online then exit;π      CharPos := CharPos + 1;π      CharacterOut (Message [CharPos]);π    Until CharPos = Length (Message);π  end;πend;ππprocedure LineOut (Message: String255);πbeginπ  StringOut (Message);π  CharacterOut (#13);π  CharacterOut (#10);πend;ππprocedure CrOut; { Outputs a carriage return and a line feed }πbeginπ  CharacterOut (#13);π  CharacterOut (#10);πend;ππend.π                                                                               25     08-27-9321:37ALL                      GINA DAVIS               A Simple Int14 Unit      IMPORT              14     ╣J"▄ {πGINA DAVISππI have used routines to read/write the comm ports and read Status usingπthe Port instruction, but mostly I have used BIOS calls (Int $14).  Whatπyou need is a technical reference book spelling out the Registers andπthe use of each bit.  (I have a book called "DOS Programmers Reference")πI have source code which accesses a modem on Com1 or Com2 to dial phoneπnumbers as part of my name & address database / dialer prog (Shareware).ππHere's an example of calling INT 14 to set up the serial port:-π}ππFUNCTION Init_Port(serialport, params : word) : word;πBEGINπ  regs.AX := params;π  regs.DX := port;π  regs.AH := 0;π  intr($14, regs);πEND;ππ{π The "serialport" is 0 for Com1 or 1 for Com2.π "params" determines baud, parity, stop bits, etc.π $43 for 300, $A3 gives 2400, $83 gives 1200,8,N,1 (p468 DOS Prog Ref)π (baudbits SHL 5) OR OtherBits - 110,150,300,600,1200,2400,4800,9600ππ The function returns the Status, ie. whether the operation was successful.π And an example of using "Port" to directly access the a port register toπ toggle the DTR bit to hangup the modem:-π}ππPROCEDURE Hang_Up_Modem(serialport : word);πVARπ  portaddress : word;π  dummychar   : char;πBEGINπ  IF serialport = 0 THENπ    portaddress := $3FCπ  ELSEπ    portaddress := $2FC;ππ  port[portaddress] := port[portaddress] xor $01;π  DELAY(10);π  port[portaddress] := port[portaddress] xor $01;π  DELAY(10);π  port[portaddress] := port[portaddress] AND $FE;ππ  REPEATπ    dummychar := read_modem(serialport)π  UNTIL regs.AH <> 0;πEND;    { Hang_Up_Modem }ππ                                                                                                                     26     08-27-9321:51ALL                      HERB BROWN               Detect Phone Ringing     IMPORT              10     ╣J≤ {πHERB BROWNππAnybody using any of the public domain fossil units?  You are? Great! Here isπa procedure to add ring detection to them.ππFos_ringing works by "peeking" into the buffers for a carriage return. Afterπa ring is detected by your modem, the CR will be the last character in yourπbuffer.  You could re-write the following to retrieve a connect string, ifπyou wanted. Since the fossil takes care of the dirty bussiness, at the momentπI wasn't worried about it.ππOnce you establish the phone rang, simply send an ATA to the modem and delayπfor about 11-15 seconds for connection. (maybe more for higher speed modems.)ππWhat really has me puzzled, though, of all the PD code for fossils, nothingπlike this was ever included.π}ππFunction Fos_Ringing(ComPort : Byte) : Boolean;πvarπ  CC : Char;πbeginπ  Fos_Ringing := False;π  Regs.Ah := $0C;π  Regs.Dx := ComPort - 1;π  Intr($14, Regs);ππ  if regs.ax = $FFFF thenπ    Fos_ringing := falseπ  elseπ  beginπ    cc := chr(regs.al);π    if cc = #13 thenπ      Fos_ringing := true;π  end;πend;ππ                                                                                                            27     08-27-9321:52ALL                      MIKE MOSSERI             Another Ring Detect      IMPORT              11     ╣Jï┴ {πMIKE MOSSERIππ>  Does anyone have any bbs routines that they recommend.  I'd prefer ifπ>it came With source but one that doesn't is good.  Mostly I want theπ>modem routines.  Also does anyone have a routine to answer the phone andπ>tell the baud rate of connection?  I working on a bbs Program (mostlyπ>just For myself, small and quick) and Im doing it from scratch.  Im haveπ>some communication routines but Im looking For others made For bbs's.π}πππUsesπ  Dos, Crt;ππVarπ  REGS : Registers;ππFunction CheckRing(Comport : Byte) : Boolean;πbeginπ  fill(Regs, SizeOf(Regs), 0);    {Reset All Registers}π  Regs.AH := 3;π  Regs.DX := Comport - 1;π  Intr($14, Regs);π  CheckRing:= ((Regs.Al and $40) = $40);πend;ππ{π The Function comes back True only when a ring is currently happening soπyou can:π}ππbeginπ  Repeatπ  Until CheckRing(2);      {Or Whatever comport}π  Delay(1000);             {Give it a sec}π  Writeln_Fossil('ATA'); {Or Whatever you use to Interface w/ the fossil}π  While not CarrierDetect do Delay(250); {Suffecient Time}ππ{π  Well that should answer the phone, now if you want to check the baudπyou can read a line from the modem or something.π}π                                                                                                                    28     09-26-9308:45ALL                      GARY GORDON              Small,Good ASYNC routinesIMPORT              65     ╣Js" {$B-} { Short circuit boolean ON }π{$I-} { I/O checking OFF }π{$R-} { Range checking OFF }π{$S-} { Stack checking OFF }π{$V-} { Var-str checking OFF}ππUNIT ASYNC2;π  {PD async unit debugged and modified for doorgame use by Joel Bergen}π  {added com3 & com4 support and xon/xoff handshaking                 }π  {various bug fixes by Gary Gordon & Joel Bergen Jan 1990}π  {Last revised:  1/14/90}π  {still needs check for existance of comm port in Async_Open routine}ππINTERFACEππUSES DOS, CRT;ππVARπ  Async_CheckCTS  : BOOLEAN;ππPROCEDURE Async_Init;π  { initialize variables, call first to initialize }ππPROCEDURE Async_Close;π  { reset the interrupt system when UART interrupts no longer needed }π  { Turn off the COM port interrupts.                                }π  { **MUST** BE CALLED BEFORE EXITING YOUR PROGRAM; otherwise you    }π  { will see some really strange errors and have to re-boot.         }ππFUNCTION Async_Open(ComPort,BaudRate : WORD) : BOOLEAN;π  { open a communications port at 8/n/1 with supplied port & baud   }π  { Sets up interrupt vector, initialies the COM port for           }π  { processing, sets pointers to the buffer.  Returns FALSE if COM  }π  { port not installed.                                             }ππFUNCTION Async_Buffer_Check : BOOLEAN;π  { see if a character has been received        }π  { If a character is available, returns TRUE   }π  { Otherwise, returns FALSE                    }ππFUNCTION Async_Read : CHAR;π  { read a character, assuming it is ready}ππPROCEDURE Async_Send(C : CHAR);π  { transmit a character }ππPROCEDURE Async_Hangup;π  { drop carrier by dropping DTR}ππFUNCTION Async_CarrierDetect : BOOLEAN;π  { true if carrier detected }ππ{----------------------------------------------------------------------------}ππIMPLEMENTATIONππCONSTπ  I8088_IMR = $21;   { port address of the Interrupt Mask Register }π  AsyncBasePort  : ARRAY[1..4] OF WORD = ($03F8,$02F8,$03E8,$02E8);π  AsyncIRQ       : ARRAY[1..4] OF WORD = (4,3,4,3);π  Async_Buffer_Max = 1024;          { size of input buffer }π  Ier = 1;π  Lcr = 3;π  Mcr = 4;π  Lsr = 5;π  Msr = 6;ππVARπ  Async_OriginalVector : POINTER;π  Async_OriginalLcr    : INTEGER;π  Async_OriginalImr    : INTEGER;π  Async_OriginalIer    : INTEGER;ππ  Async_Buffer         : ARRAY[0..Async_Buffer_Max] OF CHAR;ππ  Async_Open_Flag      : BOOLEAN;   { true if Open but no Close }π  Async_Pause          : BOOLEAN;   { true if paused (Xoff received) }π  Async_Port           : INTEGER;   { current Open port number (1..4) }π  Async_Base           : INTEGER;   { base for current open port }π  Async_Irq            : INTEGER;   { irq for current open port }ππ  Async_Buffer_Overflow: BOOLEAN;   { True if buffer overflow has happened }π  Async_Buffer_Used    : WORD;      { number of characters in input buffer }ππ  { Async_Buffer is empty if Head = Tail }π  Async_Buffer_Head    : WORD;   { Locn in Async_Buffer to put next char }π  Async_Buffer_Tail    : WORD;   { Locn in Async_Buffer to get next char }ππPROCEDURE DisableInterrupts; INLINE($FA {cli} );     {MACROS}πPROCEDURE EnableInterrupts;  INLINE($FB {sti} );ππPROCEDURE Async_Isr;  INTERRUPT;π{ Interrupt Service Routineπ  Invoked when the UART has received a byte of data from theπ  communication line }πCONSTπ  Xon  = #17;  {^q resume}π  Xoff = #19;  {^s pause}πVARπ  c : CHAR;πBEGINπ  EnableInterrupts;π  IF Async_Buffer_Used < Async_Buffer_Max THEN BEGINπ    c := CHR(PORT[Async_Base]);π    CASE c OFπ      Xoff : Async_Pause:=TRUE;π      Xon  : Async_Pause:=FALSE;π      ELSE BEGINπ        Async_Pause:=FALSE;π        Async_Buffer[Async_Buffer_Head] := c;π        IF Async_Buffer_Head < Async_Buffer_Max THENπ          INC(Async_Buffer_Head)π        ELSEπ          Async_Buffer_Head := 0;π        INC(Async_Buffer_Used);π      END;π    END;π  END ELSE Async_Buffer_Overflow := TRUE;π  DisableInterrupts;π  PORT[$20] := $20;πEND; { Async_Isr }ππPROCEDURE Async_Init;π{ initialize variables }πBEGINπ  Async_Open_Flag       := FALSE;π  Async_Buffer_Head     := 0;π  Async_Buffer_Tail     := 0;π  Async_Buffer_Overflow := FALSE;π  Async_Buffer_Used     := 0;π  Async_Pause           := FALSE;π  Async_CheckCTS        := TRUE;πEND; { Async_Init }ππPROCEDURE Async_Close;π{ reset the interrupt system when UART interrupts no longer needed }πVARπ  i, m : INTEGER;πBEGINπ  IF Async_Open_Flag THEN BEGINπ    DisableInterrupts;             { disable IRQ on 8259 }π    PORT[Async_Base + Ier] := Async_OriginalIer;π    PORT[Async_Base+Lcr]   := Async_OriginalLcr;π    PORT[I8088_IMR]        := Async_OriginalImr;π    EnableInterrupts;π    SETINTVEC(Async_Irq + 8,Async_OriginalVector);π    Async_Open_Flag := FALSE     { flag port as closed }π  ENDπEND; { Async_Close }ππFUNCTION Async_Open(ComPort,BaudRate : WORD) : BOOLEAN;πVARπ  i, m : INTEGER;π  b    : BYTE;πBEGINπ    IF Async_Open_Flag THEN Async_Close;π    Async_Port := ComPort;π    Async_Base := AsyncBasePort[Async_Port];π    Async_Irq  := AsyncIRQ[Async_Port];π      { set comm parameters }π    Async_OriginalLcr := PORT[Async_Base+Lcr];ππ    PORT[Async_Base+Lcr] := $03;  {set 8/n/1. This shouldn't be hardcoded}π      { set ISR vector }π    GETINTVEC(Async_Irq+8, Async_OriginalVector);π    SETINTVEC(Async_Irq+8, @Async_Isr);π      { read the RBR and reset any possible pending error conditions }π      { first turn off the Divisor Access Latch Bit to allow access to RBR, etc. }π    DisableInterrupts;π    PORT[Async_Base+Lcr] := PORT[Async_Base+Lcr] AND $7F;π      { read the Line Status Register to reset any errors it indicates }π    i := PORT[Async_Base+Lsr];π      { read the Receiver Buffer Register in case it contains a character }π    i := PORT[Async_Base];π      { enable the irq on the 8259 controller }π    i := PORT[I8088_IMR];  { get the interrupt mask register }ππ    Async_OriginalImr := i;ππ    m := (1 shl Async_Irq) XOR $00FF;π    PORT[I8088_IMR] := i AND m;π      { enable the data ready interrupt on the 8250 }ππ    Async_OriginalIer := PORT[Async_Base + Ier];ππ    Port[Async_Base + Ier] := $01; { enable data ready interrupt }π      { enable OUT2 on 8250 }π    i := PORT[Async_Base + Mcr];π    PORT[Async_Base + Mcr] := i OR $08;π    EnableInterrupts;π      { Set baudrate}π    b := PORT[Async_Base+Lcr] OR 128;π    PORT[Async_Base+Lcr]:= b;π    PORT[Async_Base  ]  := LO(TRUNC(115200.0/BaudRate));π    PORT[Async_Base+1]  := HI(TRUNC(115200.0/BaudRate));π    PORT[Async_Base+Lcr]:= b AND 127;π      { set flags }π    Async_Open_Flag := TRUE;π    Async_Open := TRUE;πEND; { Async_Open }ππFUNCTION Async_Buffer_Check : BOOLEAN;π{ return true if character ready to receive }πBEGINπ  Async_Buffer_Check := (Async_Buffer_Used <> 0);πEND; { Async_Buffer_Check }ππFUNCTION Async_Read : CHAR;π{ return char, use Async_Buffer_Check first! }πBEGINπ  Async_Read := Async_Buffer[Async_Buffer_Tail];π  INC(Async_Buffer_Tail);π  IF Async_Buffer_Tail > Async_Buffer_Max THENπ    Async_Buffer_Tail := 0;π  DEC(Async_Buffer_Used);πEND; { Async_Buffer_Check }ππPROCEDURE Async_Send(c : CHAR);π{ transmit a character }πBEGINπ  PORT[Async_Base + Mcr] := $0B;                 {turn on OUT2, DTR, and RTS}π  IF Async_CheckCTS THENπ    WHILE (Port[Async_Base + Msr] AND $10) = 0 DO;  {wait for CTS}π  WHILE (Port[Async_Base + Lsr] AND $20) = 0 DO; {wait for Tx Holding Reg Empty}π  WHILE Async_Pause AND Async_CarrierDetect DO;  {wait for Xon}π  DisableInterrupts;π  PORT[Async_Base] := ORD(c);                    {send the character}π  EnableInterrupts;πEND; { Async_Send }ππPROCEDURE Async_Hangup;πBEGINπ  PORT[Async_Base+Mcr] := $00;  {dtr off}π  DELAY(1000);                  {wait 1 second}π  PORT[Async_Base+Mcr] := $03;  {dtr on}πEND;ππFUNCTION Async_CarrierDetect : BOOLEAN;π{true if carrier}πVARπ  b : BOOLEAN;π  w : WORD;πBEGINπ  w:=0; b:=TRUE;π  WHILE (w<500) AND b DO BEGIN              {make sure carrier stays down}π    INC(w);                                 {and is not just a fluke     }π    b:=(PORT[Async_Base+Msr] AND 128) <> 128; {true = no carrier};π  END;π  Async_CarrierDetect := NOT b;πEND;ππBEGINπ  Async_Init;πEND. { ASYNC UNIT }π                                                                                                                     29     10-28-9311:40ALL                      DAVID CRUGER             UART Detection           IMPORT              64     ╣Jà {-------------------------------------------------------------------------π !                                                                       !π !  UARD.PAS   : Uart Detection Program        Ver 1.0                   !π !                                                                       !π !  Created    : 09-23-93        Changed: 09-23-93                       !π !                                                                       !π !  Converted To Turbo Pascal 6.0 By: David D. Cruger                    !π !                                                                       !π !  Original Program By:      National Semiconductor Corporation         !π !  NS1655.ZIP                Microcomputer Systems Division             !π !                            Microcontroller Applications Group         !π !                            Written By: Louis Shay / 01/11/89          !π !                            Originaly Written in some form of 'C'.     !π !                            This program only does the 'detection'.    !π !                            The original program ran some tests on     !π !                            the Uarts.                                 !π !                                                                       !π !  SAVE/RESTORE Uart Registers Routines from Form Message #195739       !π !  by Michael Day (TeamB)                                               !π !                                                                       !π !  *NOTE*  This program is just an example of how to detect Uarts and   !π !          is not intended to be a stand alone program.  I here by      !π !          release this program to the public domain.  Use at your own  !π !          risk.                                                        !π !                                                                       !π !   0: No Uart at Port Address                                          !π !   1: INS8250, INS8250-B                                               !π !   2: INS8250A, INS82C50A, NS16450, NS16C450                           !π !   3: NS16550A                                                         !π !   4: NS16C552                                                         !π !                                                                       !π !------------------------------------------------------------------------}ππProgram UartD;ππ  {π     A =  Align Dataπ     B =  Boolean Shortπ     D =  Debug Onπ     E =  Emulate 80287π     F =  Far Callsπ     G =  Generate 286 Codeπ     L =  Local Symbol Informationπ     N =  Numeric Processing Switchπ     O =  Overlayπ     R =  Range Checking Onπ     S =  Stack-Overflowπ     V =  Var-String Checkingπ  }ππ{$a+,b-,d-,e-,f-,g-,l-,n-,o-,r-,s-,v-}                                 {}π{$M 2500,0,0}ππUses Dos;ππType Uart_Registers=Array[0..9] OF Byte;  { Uart Registers              }ππVar  URegs: Uart_Registers;      { Uart Register Array                  }π     PA   : Word;                { Port Address Com1=$3F8  Com2=$2F8..  }ππ     RBR,THR,IER,IIR,FCR,LCR,MCR,LSR,MSR,SCR,DLL,DLM,AFR: Word;ππ{-------- Save Uart Registers --------}πProcedure Save_Uart_Registers(BaseAdd: Word; Var URegs: Uart_Registers);πVar I: Byte;πBeginπ  ASM CLI; END;π  For I:=1 to 6 Do URegs[I]:=Port[BaseAdd+I];π  Port[BaseAdd+3]:=Port[BaseAdd+3] or $80;π  URegs[7]:=Port[BaseAdd+0];π  URegs[8]:=Port[BaseAdd+1];π  Port[BaseAdd+3]:=Port[BaseAdd+3] and $7F;π  ASM STI; END;πEnd; { End Procedure }ππ{------ Restore Uart Registers --------}πProcedure Restore_Uart_Registers(BaseAdd: Word; URegs: Uart_Registers);πVar I: Byte;πBeginπ  ASM CLI; END;π  Port[BaseAdd+3]:=Port[BaseAdd+3] or $80;π  Port[BaseAdd+0]:=URegs[7];π  Port[BaseAdd+1]:=URegs[8];π  Port[BaseAdd+3]:=Port[BaseAdd+3] and $7F;π  For I:=1 to 6 Do Port[BaseAdd+I]:=URegs[I];π  ASM STI; END;πEnd; { End Procedure }ππProcedure Return_Code(C: Byte);πBeginππ  Case C ofπ   0:Writeln('No Uart at Port Address');π   1:Writeln('INS8250, INS8250-B');π   2:Writeln('INS8250A, INS82C50A, NS16450, NS16C450');π   3:Writeln('NS16550A');π   4:Writeln('NS16C552');π   End;ππ   Restore_Uart_Registers(PA,URegs);ππ   Halt(C);  { Halt with Errorlevel of Uart }ππEnd; { End Procedure }ππProcedure Set_Uart_Register_Values(PA: Word);πBeginππRBR:=PA+0;         { Receive Buffer Registers          (R  ) (DLAB=0)     }πTHR:=PA+0;         { Transmitter Holding Register      (  W) (DLAB=0)     }πIER:=PA+1;         { Interrupt Enable Register         (R/W) (DLAB=0)     }πIIR:=PA+2;         { Interrupt Ident. Register         (R  )              }πFCR:=PA+2;         { FIFO Control Register             (  W)              }πLCR:=PA+3;         { Line Control Register             (R/W)              }πMCR:=PA+4;         { MODEM Control Register            (R/W)              }πLSR:=PA+5;         { Line Status Register              (R  )              }πMSR:=PA+6;         { MODEM Status Register             (R/W)              }πSCR:=PA+7;         { Scratch Register                  (R/W)              }πDLL:=PA+0;         { Divisor Latch (LSB)               (R/W) (DLAB=1)     }πDLM:=PA+1;         { Divisor Latch (MSB)               (R/W) (DLAB=1)     }πAFR:=PA+2;         { Alternate Function Register       (R/W)              }ππEnd; { End Procedure }ππBegin  { Main Section of Program }ππPA:=$3F8; { Com1/ This can be changed to any port address you want }πWrite('Com1: $3F8 : Uart:=');ππSave_Uart_Registers(PA,URegs);  { Saves State of Current Uart Registers    }πSet_Uart_Register_Values(PA);   { Return_Code() Restores Uart Registers    }ππPort[LCR]:=$AA;                         { Test LCR Registers               }πIf $AA<>Port[LCR] Then Return_Code(0);ππPort[DLM]:=$55;                         { Test DLM Present 8-bits          }πIf $55<>Port[DLM] Then Return_Code(0);ππPort[LCR]:=$55;                         { LCR/ DLAB=0                      }πIf $55<>Port[LCR] Then Return_Code(0);ππPort[IER]:=$55;                         { Test IER Present 4-bits          }πIf $05<>Port[IER] Then Return_Code(0);ππPort[FCR]:=$0;                          { FIFO's Off, If Present           }πPort[IER]:=$0;                          { Interrupts Off, IIR Should be 01 }πIf $1<>Port[IIR] Then Return_Code(0);ππ{----- Test Modem Control Register Address. Should be 5-bits Wide -----}πPort[MCR]:=$F5;                         { 8-bit Write                      }πIf $15<>Port[MCR] Then Return_Code(0);ππ{------ Test MCR/MSR Loopback Functions ------}ππPort[MCR]:=$10;                         { Set Loop Mode                    }πPort[MSR]:=$0;                          { Clear out Delta Bits             }πIf ($F0 and Port[MSR])<>0 Then Return_Code(0); { Check State Bits          }ππPort[MCR]:=$1F;                         { Toggle Modem Control Lines       }πIf ($F0 and Port[MSR])<>$F0 Then Return_Code(0); { Check State Bits        }ππPort[MCR]:=$03;                         { Exit Loop Mode, DTR, RTS Active  }ππ{---- Port Id Successful at this point. determine port type ----}ππPort[SCR]:=$55;                         { Is There a Scratch Register?    }πIf $55<>Port[SCR] Then Return_Code(1);  { No SCR, Type = INS8250          }ππPort[FCR]:=$CF;                         { Enable FIFO's, If Present       }πIf ($C0 and Port[IIR])<>$C0 Then Return_Code(2); { Check FIFO ID bits     }πPort[FCR]:=$0;                          { Turn Off FIFO's                 }ππPort[LCR]:=$80;                         { Set DLAB                        }πPort[AFR]:=$07;                         { Write to AFR                    }πIf $07<>Port[AFR] Then                  { Read AFR                        }π  Beginπ    Port[LCR]:=$0;                      { Reset DLAB                      }π    Return_Code(3);                     { If Not Type=NS16550A            }π  End;ππPort[AFR]:=$0;                          { Clear AFR                       }πPort[LCR]:=$0;                          { Reset DLAB                      }πReturn_Code(4);ππEnd.π                                                                                       30     11-02-9305:56ALL                      CHRISTIAN PHILIPPS       Very GOOD Async package  IMPORT              98     ╣J╧ {πFRANCK DUMONTππ------------------------------------------ ASM ------------------------------ππ;//////////////////////////////////////////////////////////////////////////π;///                                                                    ///π;///           Turbo-Pascal V24-Interrupt-Support      V2.00            ///π;///                                                                    ///π;///                 (c) Christian Philipps, Moers                      ///π;///                    June 1988 / West-Germany                        ///π;///                                                                    ///π;///                Turbo Pascal 4.0 or above required                  ///π;///                                                                    ///π;//////////////////////////////////////////////////////////////////////////ππ; This module is hereby donated to the public domain.ππ;─────────────────────────────────────────────────────────────────────────π;                    Datensegmentπ;─────────────────────────────────────────────────────────────────────────ππDATA     SEGMENT BYTE PUBLICππ         ; Turbo-Pascal Variableπ         EXTRN V24HP      : WORDπ         EXTRN V24TP      : WORDπ         EXTRN V24BuffEnd : WORDπ         EXTRN V24Buff    : BYTEπ         EXTRN ComBase    : WORDππDATA     ENDSππ;─────────────────────────────────────────────────────────────────────────π;                        Codesegmentπ;─────────────────────────────────────────────────────────────────────────ππCODE     SEGMENT BYTE PUBLICππ         ASSUME CS:CODE, DS:DATAππ         PUBLIC V24Intππ;─────────────────────────────────────────────────────────────────────────ππ;CS-relative Datenππ_Turbo_DS DW  DATA                              ; Turbo data segmentπ      ; (inserted by linkage editor)ππ;─────────────────────────────────────────────────────────────────────────π;                    Codebereichπ;─────────────────────────────────────────────────────────────────────────π;PROCEDURE V24Int; interrupt;π;  this routine is executed whenever a character arrivesππV24Int   PROC  FAR                               ; Interrupt-RoutineπππV24Int   ENDPππ  push ds                                 ; save registersπ         push axπ         push bxπ         push dxπ  mov  ds,CS:_Turbo_DS                    ; set Turbo DSππ  mov  bx,V24TP                           ; ds:bx -> next free slotπ  mov  dx,ComBase                         ; dx = port base-addressπ         in   al,dx                              ; RBR -> alπ  mov  byte ptr [bx],al                   ; move byte into bufferπ  inc  bx                                 ; pointer to next slotπ  cmp  bx,V24BuffEnd                      ; past the end of the buffer?π  jle  L1                                 ; noπ  mov  bx,OFFSET V24Buff                  ; yes, so wrap aroundππL1:      cmp  bx,V24HP                           ; TP=HP --> overflow!π  jz   L2                                 ; yes, ignore characterπ  mov  V24TP,bx                           ; no, save new tail pointerππL2:      mov  al,20H                             ; EOI -> 8259π         out  20H,alπ  pop  dx                                 ; restore registersπ         pop  bxπ         pop  axπ         pop  dsπ         iretππCODE     ENDSππENDπ}π(*////////////////////////////////////////////////////////////////////////////π///                                                                        ///π///         T U R B O  -  P A S C A L  V24-Interrupt-Support V2.00         ///π///                (c) Copyright June 1988 by C.Philipps                   ///π///                                                                        ///π///               (Turbo Pascal V4.0  or higher required)                  ///π///                                                                        ///π//////////////////////////////////////////////////////////////////////////////π///                                                                        ///π///            Low-level interrupt-handling for the serial ports. Speeds   ///π///            up to 115200 bps are supportet, one port at a time.         ///π///            Parts of the basics were taken from Mike Halliday's pop-    ///π///            ular ASYNC-package (Turbo Pascal 3.0, PD).                  ///π///                                                                        ///π///       This module is hereby donated to the public domain.              ///π///                                                                        ///π///       Christian Philipps                                               ///π///       Düsseldorfer Str. 316                                            ///π///       4130 Moers 1                                                     ///π///       West-Germany                                                     ///π///                                                                        ///π///       Last modified: 07/89                                             ///π///                                                                        ///π////////////////////////////////////////////////////////////////////////////*)ππ{$R-,S-,I-,D-,F-,V-,B-,N-,L- }ππUNIT V24;ππINTERFACEππUSESπ  DOS;ππTYPEπ  ComType      = (com1, com2, com3, com4, com5, com6);π  BaudType     = (b110, b150, b300, b600, b1200, b2400, b4800,π                  b9600, b19200, b38400, b57600, b115200);π  ParityType   = (Space, Odd, Mark, Even, None);π  DataBitsType = (d5, d6, d7, d8);π  StopBitsType = (s1, s2);ππCONSTπ  V24Timeout : BOOLEAN = FALSE;  {SendByte-Timeout}π  IntMasks   : ARRAY [Com1..Com6] OF WORD = ($EF,$F7,$EF,$F7,$EF,$F7);π  IntVect    : ARRAY [Com1..Com6] OF BYTE = ($0C,$0B,$0C,$0B,$0C,$0B);ππVARπ  V24TP      : WORD; {Buffer Tail-Pointer Im Interface-Teil, da zurπ                      Ereignis-steuerung im Multi-Tasking benötigt.}π  ComBaseAdr : ARRAY [Com1..Com6] OF WORD;ππFUNCTION  V24DataAvail : BOOLEAN;πFUNCTION  V24GetByte : BYTE;πPROCEDURE InitCom(ComPort : ComType; Baudrate : BaudType; Parity : ParityType;π                  Bits : DataBitsType; Stop : StopBitsType);πPROCEDURE DisableCom;πPROCEDURE SendByte(Data : BYTE);πππIMPLEMENTATIONππCONSTπ  Regs : Registers =π    (AX : 0; BX : 0; CX : 0; DX : 0; BP : 0;π     SI : 0; DI : 0; DS : 0; ES : 0; FLAGS : 0);π  RBR = $00;          {xF8 Receive Buffer Register            }π  THR = $00;          {xF8 Transmitter Holding Register       }π  IER = $01;          {xF9 Interrupt Enable Register          }π  IIR = $02;          {xFA Interrupt Identification Register  }π  LCR = $03;          {xFB Line Control Register              }π  MCR = $04;          {xFC Modem Control Register             }π  LSR = $05;          {xFD Line Status Register               }π  MSR = $06;          {xFE Modem Status Register              }π                                  {--- if LCR Bit 7 = 1  ---              }π  DLL = $00;          {xF8 Divisor Latch Low Byte             }π  DLH = $01;          {xF9 Divisor Latch Hi  Byte             }π  CMD8259 = $20;      {Interrupt Controller Command Register  }π  IMR8259 = $21;      {Interrupt Controller Mask Register     }π                      {Should be evaluated by any higher-level send-routine}π  LoopLimit   = 1000; {When does a timeout-error occur        }π  V24BuffSize = 2048; { Ringpuffer 2 KB }ππVARπ  BiosComBaseAdr : ARRAY [Com1..Com2] OF WORD ABSOLUTE $0040:$0000;π  ActivePort     : ComType;π  { The Com-Port base adresses are taken from the BIOS data area }π  ComBase        : WORD;         {Hardware Com-Port Base Adress          }π  OldV24         : Pointer;π  V24HP          : WORD;         {Buffer Head-Pointer                    }π  V24BuffEnd     : WORD;         {Buffer End-Adress                      }π  V24Buff        : ARRAY [0..V24BuffSize] OF BYTE;π  OExitHandler   : Pointer;    {Save-Area für Zeiger auf Org.-Exit-Proc}πππPROCEDURE V24Int; external;π{$L v24.obj}πππPROCEDURE ClearPendingInterrupts;πVARπ  N : BYTE;πBEGINπ  WHILE (PORT[ComBase + IIR] AND 1) = 0 DO  {While Interrupts are pending}π  BEGINπ    N := PORT[ComBase + LSR];               {Read Line Status}π    N := PORT[ComBase + MSR];               {Read Modem Status}π    N := PORT[ComBase + RBR];               {Read Receive Buffer Register}π    PORT[CMD8259] := $20;                   {End of Interrupt}π  END;πEND;πππFUNCTION V24DataAvail:BOOLEAN;π{ This function checks, whether there are characters in the buffer }πBEGINπ  V24DataAvail := (V24HP <> V24TP);πEND;πππFUNCTION V24GetByte:BYTE;π{ Take a byte out of the ring-buffer and return it to the caller.π  This function assumes, that the application has called V24DataAvailπ  before to assure, that there are characters available!!!!π  The ISR only reads the current head-pointer value, so this routineπ  may modify the head-pointer with interrupts enabled. }πBEGINπ  V24GetByte := Mem[DSeg:V24HP];π  Inc(V24HP);π  IF V24HP > V24BuffEnd THENπ    V24HP := Ofs(V24Buff);πEND;πππPROCEDURE SendByte(Data:BYTE);πVARπ  Count : BYTE;πBEGINπ  Count := 0;π  V24Timeout := FALSE;π  IF ComBase > 0 THENπ  BEGINπ    REPEATπ      Count := SUCC(Count);π    UNTIL ((PORT[ComBase + LSR] AND $20) <> 0) OR (Count > LoopLimit);π    IF Count > LoopLimit THENπ      V24Timeout := TRUEπ    ELSEπ      PORT[ComBase+THR] := Data;π  END;πEND;πππPROCEDURE InitCom(ComPort : ComType; Baudrate : BaudType; Parity : ParityType;π                  Bits : DataBitsType; Stop : StopBitsType);πCONSTπ  BaudConst   : ARRAY [b110..b115200] OF WORD =π    ($417,$300,$180,$C0,$60,$30,$18,$0C,$06,$03,$02,$01);π  ParityConst : ARRAY [Space..None] OF BYTE = ($38,$08,$28,$18,$00);π  BitsConst   : ARRAY [d5..d8] OF BYTE = ($00,$01,$02,$03);π  StopConst   : ARRAY [s1..s2] OF BYTE = ($00,$04);πBEGINπ  V24HP       := Ofs(V24Buff);π  V24TP       := V24HP;π  V24BuffEnd  := V24HP + V24BuffSize;π  FillChar(V24Buff, Succ(V24BuffSize), #0);π  V24Timeout := FALSE;                           {Reset Timeout-Marker}π  ComBase := ComBaseAdr[ComPort];                {Get Com-Port base adress}π  ActivePort := ComPort;                         {Keep Active-Port for EOI}π  ClearPendingInterrupts;π  GetIntVec(IntVect[ComPort], OldV24);π  SetIntVec(IntVect[ComPort], @V24Int);π                                                 {Install interrupt routine}π  INLINE($FA);                                   {CLI}π  PORT[ComBase + LCR] := $80;                    {Adress Divisor Latch}π  PORT[ComBase + DLH] := Hi(BaudConst[Baudrate]);{Set Baud rate}π  PORT[COMBase + DLL] := Lo(BaudConst[Baudrate]);π  PORT[ComBase + LCR] := ($00 OR ParityConst[Parity] {Setup Parity}π                            OR BitsConst[Bits]   {Setup number of databits}π                            OR StopConst[Stop]); {Setup number of stopbits}π  PORT[ComBase + MCR] := $0B;                    {Set RTS,DTR,OUT2}π(*π  PORT[ComBase+MCR] := $1B;                      {Set RTS,DTR,OUT2,Loop}π*)π  PORT[ComBase + IER] := $01; {Enable Data-Available Interrupts}π  PORT[IMR8259] := PORT[IMR8259] AND IntMasks[ComPort]; {Enable V24-Interrups}π  INLINE($FB);  {STI}πEND;πππPROCEDURE DisableCom;πBEGINπ  IF ComBase = 0 THENπ    Exit;π  INLINE($FA);                           {CLI}π  PORT[ComBase + MCR] := 00;             {Disable Interrupts, Reset MCR}π  PORT[IMR8259] := PORT[IMR8259] OR $18; {Disable Interrupt Level 3 and 4}π  PORT[ComBase + IER] := 0;              {Disable 8250-Interrupts}π  ClearPendingInterrupts;                {Clean up}π  ComBase := 0;                          {Reset Combase}π  SetIntVec(IntVect[ActivePort], OldV24);{Reset old IV}π  INLINE($FB);                           {STI}πEND;ππ{$F+}πPROCEDURE V24ExitProc;ππBEGIN {V24ExitProc}π  DisableCom;π  ExitProc := OExitHandler;                 { alten Exit-Handler reaktivieren }πEND;  {V24ExitProc}π{$F-}πππBEGINπ  {Grund-Init, damit irrtümliche Aufrufe von V24DataAvail nicht zuπ   endlosen Ausgaben von Speicherschrott führen!}π  Move(BiosComBaseAdr, ComBaseAdr[Com1], SizeOf(BiosComBaseAdr));π  Move(BiosComBaseAdr, ComBaseAdr[Com3], SizeOf(BiosComBaseAdr));π  Move(BiosComBaseAdr, ComBaseAdr[Com5], SizeOf(BiosComBaseAdr));π  ComBase    := 0;π  V24HP      := Ofs(V24Buff);π  V24TP      := V24HP;π  V24BuffEnd := V24HP + V24BuffSize;ππ  OExitHandler := ExitProc;π  ExitProc     := @V24ExitProc;πEND.ππ                                                                                                                31     11-02-9310:26ALL                      HELGE HELGESEN           Access PCBOARD Users     IMPORT              46     ╣Jkε {πHELGE HELGESENππ-> Currently I am writing the USERS File to a  Temp File While imπ-> reading it (or atleast I try to), but pascal  does not allowπ-> me to Write a full Record to a File.ππI suppose you're running a on a network, and that you haveπproblems accessing the USERS File directly?ππFirst of all, do you open the File in shared mode, which isπnecessary if multiple Programs to access the File simultaneous.ππ-> So could you  tell me an easier way Write back theπ-> modifications that I have  done. A little example would beπ-> Really cool..ππSure... Here's a little example. Tested With PCBoard configuredπfor use on network, With DESQview.ππif you'd relly try this you should reWrite the proc "ModifyRecord" first ;)π}ππProgram AccessUsersFile;ππUsesπ  Dos;ππTypeπ  bdReal = Array [0..7] of Byte; { I'm not sure of this one... }π  bsReal = Array [0..3] of Byte; { have conversion routines For this one if you need }ππ  TUser = Record { declare user Record }π    Name              : Array[ 1..25] of Char;π    City              : Array [1..24] of Char;π    PassWord          : Array [1..12] of Char;π    Phone             : Array [1..2] of Array [1..13] of Char;π    LastDateOn        : Array [1..6] of Char;π    LastTimeOn        : Array [1..5] of Char;π    Expert            : Char;π    Protocol          : Char;π    SomeBitFlags      : Byte;π    DateOfLastDirScan : Array [1..6] of Char;π    Level             : Byte;π    TimesOn           : Word;π    PageLen           : Byte;π    FilesUploaded,π    FilesDownloaded   : Word;π    DownloadToday     : bdReal;π    Comment           : Array [1..2] of Array [1..30] of Char;π    ElapsedOn         : Word;π    RegExpDate        : Array [1..6] of Char;π    ExpLevel          : Byte;π    OldLastConfIn     : Byte;π    ConfRegBitFlags,π    ExpRegBitFlags,π    UserSelBitFlags   : Array [0..4] of Byte;π    TotBytesDown,π    TotBytesUp        : bdReal;π    DeleteFlag        : Char;π    LRP               : Array [0..39] of bsReal; { last read Pointers }π    RecNoInUsersInf   : LongInt;π    MoreBitFlags      : Byte;π    RFU               : Array [1..8] of Char;π    LastConfIn        : Word;π  end;ππ  TIndex = Record { PCBNDX Files }π    RecNo : Word;π    Name  : Array [1..25] of Char;π  end;ππVarπ  UsersFile     : File of TUser;π  PathToIndexes : String; { path to index Files, With 'PCBNDX.' added }π  Users         : TUser; { global Record - users Record }ππProcedure OpenUsersFile;πVarπ  t : Text;π  s : String;π  x : Byte;πbeginπ  s := GetEnv('PCBDAT');π  if length(s) = 0 thenπ    halt; { if I can't find PCBOARD.DAT I can't find USERS File either }π  assign(t, s); {$I+}π  reset(t); { open File, will terminate if any error }π  For x := 1 to 28 doπ    readln(t, s);π  PathToIndexes := s + 'PCBNDX.';π  FileMode := 66;π  readln(t, s);π  assign(UsersFile, s);π  reset(UsersFile);π  close(t);πend;ππFunction FindUserRec: Word;π{ Searches thru index File For name. if not found, $FFFF is returned. }πVarπ  name      : String;π  IndexFile : File of TIndex;π  x         : Byte;π  Found     : Boolean;π  Index     : TIndex;πbeginπ  Write('Enter name of user to modify: ');π  readln(name);π  FindUserRec := $ffff;π  x := length(name);π  name[0] := #25; { make 25 Char name }π  For x := x + 1 to 25 doπ    name[x] := #32;π  For x := 1 to 25 doπ    name[x] := UpCase(name[x]); { make upper Case }π{ since PCBoard v15.0 supports national Chars, you should do it too. Ifπ  you need, I have something on this too... ;) }π  assign(IndexFile, PathToIndexes + name[1]);π  reset(IndexFile);π  Repeatπ    read(IndexFile, Index); { read name }π    x := 1;π    While (x <= 25) and (name[x] = Index.Name[x]) doπ      inc(x);π    Found := x = 26;π  Until eof(IndexFile) or Found;π  if Found thenπ    FindUserRec := Index.RecNo - 1;π{ Please note that I subtract 1 here. This is becase PCBoard was written inπ  Basic (when the File format was made) and that Basic threats Record 1 asπ  the first Record. In Pascal, Record 0 is the first Record! This may confuseπ  a bit since some Files Within PCBoard are 1-based, and some are 0-based. }π  close(IndexFile);πend;ππProcedure ModifyRecord;π{ Let's modify the Record... }πVarπ  x : Byte;πbeginπ  Write('Users name: ');π  For x := 1 to 25 doπ    Write(Users.Name[x]);π  Writeln; { For verification only... }π  Users.Protocol:='Z'; { let's make him use Zmodem }π  inc(Users.PassWord[1]); { and give him some headache }π  Users.PageLen := 0; { and make the screen go non-stop, when he gets on again... }πend;ππVarπ  x : Word;πbeginπ  OpenUsersFile;π  x := FindUserRec;π  if x = $ffff thenπ  beginπ    Writeln('Can''t locate user, sorry...');π    close(UsersFile);π    halt; { can't find user... }π  end;π  seek(UsersFile, x); { seek to the Record }π  read(UsersFile, Users); { and read the Record }π  seek(UsersFile, x); { seek back to the Record }π  ModifyRecord; { make some modificatios... }π  Write(UsersFile, Users); Writeln('Modifiations written back...');π  close(UsersFile);πend.ππππVarπ  Cnames  : File;π  PCBConf : PCBConfType; { your declaration }ππbeginπ  { And now we need to open it }π  assign(Cnames, 'CNAMES.@@@'); { I assume is't local }π  FileMode := 66; { open in shared mode }π  reset(Cnames, 1); { NB! Make RecSize = 1! }ππ  { Now, let's read the Record length. I assume X is an Word! }π  blockread(Cnames, x, sizeof(x));ππ  { And now it's time to seek to conference Y(also a Word). }π  seek(Cnames, 2 + y * x);ππ  { And read the Record. }π  blockread(Cnames, PCBConf, sizeof(PCBConf));ππ  { There. if you want to Write back some modifications, }π  seek(Cnames, 2 + x * y); { seek back to Record }π  blockWrite(Cnames, PCBConf, sizeof(PCBConf));ππ                                                                                                       32     11-02-9310:31ALL                      HELGE HELGESEN           PCBOARD Data             IMPORT              27     ╣J*É {πHELGE HELGESENππ> but i don't know how to change the user informationπ> (Like users City/State For instance).ππLet's see... I'm not sure if it works if the user you want toπmodify is on-line, but if he isn't, this should work.ππFirst, locate the user in the index Files. It's organized asπthis. if the name is less than 25 Chars, it's filled up Withπspaces.π}ππTypeπ  TUserIndex = Recordπ    RecNo : Word;π    Name  : Array[1..25] of Char;π  end;ππ{πThe first letter of name is used as extention to the index Files.πTo find me, you have to look into the File "PCBNDX.H". It'sπstored as FIRSTNAME LASTNAME. (The path to the user indexes areπlocated in line 28 of "PCBOARD.DAT".)ππWhen you have found the Record no, simply seek to the Record inπthe File specified in line 29 of "PCBOARD.DAT". The layout looksπlike this:ππ    Offset   Type   Length  Descriptionπ    ------  ------  ------  -----------π       0    str       25    Full Nameπ      25    str       24    Cityπ      49    str       12    PassWordπ      61    str       13    Business / Data Phone Numberπ      74    str       13    Home / Voice Phone Numberπ      87    str        6    Last Date On (format:  YYMMDD)π      93    str        5    Last Time On (format HH:MM)π      98    Char       1    Expert Mode (Y or N)π      99    Char       1    Default Transfer Protocol (A-Z, 0-9)π     100    bitmap     1    Bit Flags (see below)π     101    str        6    Date of Last DIR Scan (most recent File found)π     107    Char       1    Security Level (0-255)π     108    int        2    Number of Times Onπ     110    Char       1    Page Length (# lines displayed before prompt)π     111    int        2    Number of Files Uploadedπ     113    int        2    Number of Files Downloadedπ     115    bdReal     8    Total Bytes Downloaded Todayπ     123    str       30    Comment Field #1 (user comment)π     153    str       30    Comment Field #2 (sysop comment - user can't see)π     183    int        2    Elapsed Time On (in minutes)π     185    str        6    Registration Expiration Date (YYMMDD)π     191    Char       1    Expired Registration - Security Levelπ     192    Char       1    Last Conference In (used For v14.x compatibility)π     193    bitmap     5    Conference Registration Flags (conf 0-39)π     198    bitmap     5    Expired Registration Conference Flags (conf 0-39)π     203    bitmap     5    User Selected Conference Flags (conf 0-39)π     208    bdReal     8    Total Bytes Downloadedπ     216    bdReal     8    Total Bytes Uploadedπ     224    Char       1    Delete Flag (Y or N)π     225    bsReal     4    Last Message Read Pointer (conference 0)π     229    bsReal     4    Last Message Read Pointer (conference 1)π     ...    bsReal     4    (continued each conference)π     381    bsReal     4    Last Message Read Pointer (conference 39)π     385    long       4    Record Number of USERS.INF Recordπ     389    bitmap     1    Bit Flags 2 (see below)π     390    str        8    Reserved (do not use)π     398    int        2    Last Conference In (used instead of offset 192)ππSo all you have to do is to read the Record, make theπmodifications and Write it back.ππJust remember to open the Files in shared mode! (FileMode:=66;).π}π                                                                                   33     01-27-9411:53ALL                      REUBEN NELSON            Bluewave Structures      IMPORT              24     ╣JR% {πI created the following purly from my observations of the Bluewave files thatπI have reiceived. There are parts that I believe to be incorrect, such as theπlast five variables in the MIXRec record. I have worked very hard on this, soπif you use the following please give me my due creidit in the program orπdocumentation.ππThe BBSNAME.FTI file is made up of FTIRec records.ππThe BBSNAME.INF file is made up of one INFRec record and an unknown numberπof ConfRec records.ππThe BBSNAME.MIX file is made up of an unknown number of MIXRec records.ππThe BBSNAME.DAT file is a file of char indexed by the FTIRec records.π}ππ  FTIRec = Recordπ    FromName : Array[1..36] of Char;π    ToName   : Array[1..36] of Char;π    Subject  : Array[1..72] of Char;π    Date     : Array[1..10] of Char;π    Time     : Array[1..10] of Char;π    MsgNum        : Word;π    BackThread    : Word; { I'm not sure if this is the offset in }π    ForwardThread : Word; { the FTI file or the message number }π    MsgOfs    : LongInt; { Offset in DAT file (bytes) }π    MsgLength : LongInt; { Length of msg in DAT file (bytes) }π    Flags  : Word; { Bit 1  = Privateπ                     Bit 2  = Crashπ                     Bit 3  = Rec'dπ                     Bit 4  = Sentπ                     Bit 5  = File Attachπ                     Bit 6  =π                     Bit 7  =π                     Bit 8  = Kill Sentπ                     Bit 9  = Localπ                     Bit 10 =π                     Bit 12 =π                     Bit 13 = Req Receiptπ                     Bit 14 =π                     Bit 15 = Return Receiptπ                     Bit 16 = Audit Req }π    Zone   : Word; { Fidonet Zone }π    Net    : Word; { Fidonet Net }π    Node   : Word; { Fidonet Node }π  end; { Total length of record is 186 }ππ  INFRec = Recordπ    UnKnown    : Byte; { I don't know what this is seems to always be 2 }π    InfoFiles  : Array[1..5] of Array[1..15] of Char;π    UserName   : Array[1..43] of Char;π    UserAlias  : Array[1..65] of Char;π    Zone, Net, Node, Point : Word; { The BBS's fidonet address }π    SysOpName  : Array[1..43] of Char;π    SystemName : Array[1..65] of Char;π    { The rest of this record is just a shot in the dark }π    NumMacros  : Word; { The number of macros allowed by the door }π    Extra1     : Array[1..7] of Char;π    KeyWords   : Array[1..10] of Array[1..21] of Char; { The keywords }π    Filters    : Array[1..10] of Array[1..21] of Char; { The filters }π    Macros     : Array[1..3]  of Array[1..75] of Char; { The macros }π  end;ππ  ConfRec = Recordπ    Number   : Array[1..6] of Char;π    Label    : Array[1..21] of Char;π    Title    : Array[1..50] of Char;π    ConfType : Byte;π    Extra    : Word;π  end;ππ  MIXRec = Recordπ    AreaNumber   : Array[1..6] of Char;π    NumMsgs      : Word;π    PersonalMsgs : Word;π    OffsetInFTI  : LongInt;π  end;π                                                                              34     01-27-9411:56ALL                      NORBERT IGL              Uart Detection           IMPORT              12     ╣J{µ {π> I'm looking for a pascal V6 program to detect the UART-type installed.π}ππprogram ComType;ππ{ Detect the type/presence of a comport-chip.π  Norbert Igl, 5/92 }ππusesπ  crt;ππConst ComPortText :π    Array[0..4] of String[11] =π         ('    N/A    ',π          '8250/8250B ',π          '8250A/16450',π          '   16550A  ',π          '   16550N  ');π    IIR     = 2;π    SCRATCH = 7;ππVar   PortAdr : Array[1..4] of Word absolute $40:0;ππfunction ComPortType(ComX:byte):byte;ππBEGINπ  ComPortType:=0;π  if (PortAdr[ComX] =0)π  or (Port[PortAdr[ComX]+ IIR ] and $30 <> 0)π     then exit;                                       {No ComPort !}π  Port[PortAdr[ComX]+ IIR ] := 1;                     {Test: enable FIFO}π  if (Port[PortAdr[ComX]+IIR] and $C0) = $C0          {enabled ?}π  then ComPortType := 3π  else If (Port[PortAdr[ComX]+IIR] and $80) = $80     {16550,old version..}π       then ComPortType := 4π       else beginπ       Port[Portadr[ComX]+SCRATCH]:=$AA;π       if Port [Portadr[ComX]+SCRATCH]=$AA            {w/ scratch reg. ?}π           then ComPortType:= 2π           else ComPortType:= 1;π       end;πEND;ππvar com : byte;ππbeginπ  clrscr;π  writeln('COMPORT  Chiptest':75);π  writeln('Freeware by Norbert Igl, Germany':75);π  writeln;π  for com := 1 to 4 doπ     writeln('COM:',com,':  ', ComPortText[ComPortType(com)]);πend.π                                                         35     01-27-9412:24ALL                      MAYNARD PHILBROOK        Uart Info                IMPORT              13     ╣Jé {πI can give you a brief run on a UART of the 8250 line.ππReg 0 used for sending or Recieving a byte;πReg 1 Interrupt Enable: Bits 0= RX, 1=TX, 2=Serial ERROR, 3=ModemInputStatusπReg 2 Interrupt ID : if Bit 0 set then no interrupt has happen elseπ      Bits 1=RXready,2=TxEmty,3=Serial error, 4= ModemInputStatus;ππReg 3 Data Format Line Control;π       Bits 0,1 Select Word Size 0=5,1=6,2=7,3=8π            2   Stops Bits On = 2, oFf - 1;π            3,4,5 :Parity 0=none,1=odd,3=even,5=mark,7=space;π            6   Break Control off = off, on = onπ            7   Devisor latch control;π                 Must set this on to have reg 0,1 used as 16 bit value toπ                BAUD Rate;π                divisor =(1843200 div (16 * desired baud rate));π(89 min left), (H)elp, More?                When done set bit 7 to off.πreg 4 OutputControlπ        0 = DTR,1= RTS, 2,3 = GPO, 4 = LoopBack Test;πReg 5 Serial Status reg;π       0 = Data Ready on RX line;π       1 = over run, 2= parity errro,3= frame error, 4= break detected,π         5= TXbuffer empty, 6 = Tx Output Reg empty.πReg 6 Modem INputsπ       0-3 are Delta Bits, meaning they  are set when a change has happenπ        in the state of the DRS,CTS,RI,DCD since last time, when read theseπ        bits will clear.π       4 = CTS , 5 = DSR, 6 RI. 7 DCD;π       { ^^^ Reports the current logit level of these inputs }π       { all Delta Bits are in the same alignment bit wise. }π{ Hope this helps }ππ                                                                       36     01-27-9412:24ALL                      BJORN FELTEN             Uart Detection           IMPORT              18     ╣JD° {π > I'm looking for a small pascal V6 program to detectπ > the UART-type installed.ππ   Sure. How small do you need it? Here's one that'll compile to something justπbelow 3kb, will that do?π }ππfunction UART(Port: word): word; assembler;π{ Checks for UART, and, if one is present, what type.         }π{ Returns  0 if no UART,  1 if UART but no 16550,  2 if 16550 }π{ Donated to the public domain by Björn Felten @ 2:203/208    }π{ Partly from an asm program by Anders Danielsson @ 2:203/101 }πasmπ   mov  cx,Port          {1..4}π   push dsπ   mov  ds,seg0040       {Use BIOS table to find port addr}π   xor  si,si            {Offset 0 in BIOS table segment}π   rep  lodsw            {Get the right one}π   pop  dsπ   or   ax,ax            {Test port address}π   jz   @no_uart         {If zero --> no port}π   mov  dx,ax            {Base address}π   add  dx,4             {Base+4}π   cliπ   in   al,dx            {Modem Control Register}π   and  al,11100000b     {Check bit 5-7}π   jnz  @no_uart         {Non-zero --> no UART}π   sub  dx,2             {Base+2}π   jmp  @1               {Give hardware some time}π@1:π   in   al,dx            {Interrupt Identification Register}π   and  al,11110000b     {Check bit 4-7}π   cmp  al,11000000b     {FIFO enabled?}π   jz   @is16550         {Yes, it is a 16550}π   and  al,00110000b     {Check reserved bits}π   jnz  @no_uart         {Non-zero --> No UART}π   mov  al,00000111b     {16550 FIFO enable}π   out  dx,al            {FIFO control register}π   jmp  @2π@2:π   in   al,dx            {FIFO control register}π   and  al,11110000b     {Check bit 4-7}π   mov  ah,al            {Save for later}π   jmp  @3π@3:π   mov  al,00000110b     {16550 FIFO disable}π   out  dx,al            {FIFO control register}π   cmp  ah,11000000b     {FIFO still not enabled?}π   jz   @is16550         {Yes, it is a 16550}π   mov  ax,1π   jmp  @quitπ@is16550:π   mov  ax,2π   jmp  @quitπ@no_uart:π   xor  ax,axπ@quit:π   stiπend;ππvar P: word;πbeginπ  for P:=1 to 4 doπ  case UART(P) ofπ    0: writeln('No UART on port COM',P);π    1: writeln('UART, but not 16550, on port COM',P);π    2: writeln('16550 UART on port COM',P);π  endπend.π             37     01-27-9417:33ALL                      NORBERT IGL              Carrier Detect           IMPORT              9      ╣J) πunit cdchk;ππInterfaceππ Function CarrierDetected( ComPort : byte ) : Boolean;ππImplementationππ Function CarrierDetected( ComPort : byte ) : Boolean;ππ Const MSR      = 6;ππ VARπ       BASEPORT : Array[0..3] Of Word absolute $40:0;ππ VAR   P : Word;ππ beginπ   CarrierDetected := FALSE;    { Assume no Carrier }π   dec( ComPort );π   if ComPort in [0..3] then    { range check for COMx }π   begin                        { ... not valid ? }π     P := BasePort[ComPort];    { Bios-Var for COMx... }π     If P <> 0 then             { ... not assigned ?! }π     beginπ       CarrierDetected := (Port[P+ MSR] And $80) = 0;π     end;π   endπ end;π { No Initializing ... }π end.ππ-------------------------------------------------------------π P.S.:  If P=0 ...π   Port[P+MSR] ==> Port[6]π   this would read the DMA Channel#3-LowAdress-Byte .... (:-))π-------------------------------------------------------------π                                                                                                                    38     01-27-9417:34ALL                      ELAD NACHMAN             Simple COM I/O           IMPORT              27     ╣J══ {πFrom: ELAD NACHMANπSubj: High Speed COM I/Oπ---------------------------------------------------------------------------π RL> Dose anyone know how a humble young TP programmer can accessπ RL> modems at speeds of say 57,600 baud rates? I would love evenπ RL> 14,400 routines. I had a set of simple I/O routines, but speedsπ RL> over 2400 term programs would lose characters. I would like toπ RL> write some doors for a BBS but can't break the 2400 limit.ππYou probably use a very simple way, which doesn't envolves capturing theπmodem's Com port IRQ. That's why you use chars over faster transmitions.πTo make sure the program will be fast, optimize it to assembler, or at leastπuse I/O Ports manipulations (If you odn't use it already).πA cut from a source I have here (Design for com1, if you need support for otherπports use a guide such as Helppc. If you want To write Doors for BBSes youπbetter use Fossil functions, For that either use Fsildoc.??? (It's in severalπFTP sites) or Ralf Brown's Interrupt list):π}ππconstππ{ 8250 IRQ Registers }ππData=$03f8; { Contains 8 bits for send/receive }ππIER=$03f9; { Enables Serial Port when set to 1 }ππLCR=$03fb; { Sets communication Parameters }ππMCR=$03FC; { bits 1,2,4 are turned on to ready modems }ππLSR=$3FD; { when bit 6 is on, it is safe to send a byte }ππMDMMSR=$03FE; { initialized to $80 when starting }ππENBLRDY=$01; { initial value for port[IER] }ππMDMMOD=$0b; { initial value for port[MCR] }ππMDMCD=$80; { initial value for port[MDMMSR] }ππINTCTLR=$21; { port for 8259 interrupt controller }ππvarππmybyte:byte;πvector:pointer;πππprocedure asyncint; interrupt;πbeginπinline($FB); {STI}πmybyte:=port[dataport];πinline($FA); {CLI}ππPort[$20]:=$20;ππend;ππprocedure setmodem;πvarπregs: registers;πparm : byte;ππbeginππparm:=3+4+0+$d0;π{8 databits,1 stopbit,no parity,9600 baud}π{databits: values 0,1,2,3 represent 5,6,7,8 databitsπstopbits: value 4 is for 1 stopbits, 0 for noneπparity: value 0 or $10 for none, $8 for odd, $18 for evenπbaud: $d0 for 9600, $b0 for 4800, $a0 for 2400, $80 for 1200, $60 for 600, $40πfor 300 add all this values and get the correct byte parameter}ππwith regs doπbeginπdx:=0; { comport -1 }πah:=0;πal:=parm;πflags:=0;πintr($14,regs);πend;πend;ππprocedure EnablePorts;πvarπb: byte;πbeginπgetintvec($0c,Vector); { $0c is for com1/com3 - IRQ 4 }πsetintvec($0c,@AsyncInt);πb:=port[INTCTLR];πb:=b and $0ef;πport[INTCTLR]:=b;πb:=port[LCR];πb:=b and $7f;ππport[lcr]:=b;πport[ier]:=enblrdy;πport[mcr]:=$08 or MDMMOD;πport[mdmmsr]:=mdmcd;πport[$20]:=$20;ππ{ when: port[MDMMSR] and $80 = $80 then there's carrier }ππprocedure sendchartoport(b: byte);πbeginπwhile ( (port[lsr] and $20) <> $20 ) doπbeginπend;πport[dataport]:=b;πend;ππprocedure sendstringtoport(s: string);πvarπi:integer;πbeginπfor i:=1 to length(s) doπsendchartoport(ord(S[i]));πsnedchartoport(13);πend;ππprocedure disableports;πvarπb: byte;πbeginπsendstringtoport('ATC0');πb:=port[intctlr];πb:=b or $10;πport[intctlr]:=b;πb:=port[lcr];πb:=b and $7f;πport[lcr]:=b;πport[ier]:=$0;ππport[mcr]:=$0;πport[$20]:=$20;πsetintvec($0c,vector);πend;ππ{ How the program itself should generally be }ππbeginππsetmodem;πenableports;πsend strings or charsπdisableports;ππend.π                                                                                                                           39     01-27-9417:36ALL                      MIGUEL MARTINEZ          Accessing The Phone      IMPORT              9      ╣J═W {πFrom: MIGUEL MARTINEZπSubj: Accessing the phoneπ---------------------------------------------------------------------------π ▒ I am a novice programmer and I am writing an address book type programπ ▒ in TP 6.0. How can I send the phone a number to be dialed? Thanx.ππTry this routines:π}ππUSES CRT;ππProcedure DialNumber(Number:String);πVar ComPort:Text;π    ComName:String;πBeginπ  ComName:='COM2';   (* Assuming your modem is located there *)π  Assign(ComPort,ComName);π  ReWrite(ComPort);π  Writeln(ComPort,'ATDT'+Number);π  Close(ComPort);πEnd;ππProcedure Hangup;πVar ComPort:Text;π    ComName:String;πBeginπ  ComName:='COM2';   (* Assuming your modem is located there *)π  Assign(ComPort,ComName);π  ReWrite(ComPort);π  Writeln(ComPort,'ATH0M1');π  Close(ComPort);πEnd;ππ{An example of how to use this routines, is this fragment of code:}πBEGINπ   DialNumber('345554323');π   Repeat Until Keypressed;π   Hangup;πEND.ππIf you don't hang up, guess... You'll get a funny noise if you don'tπconnect. :)ππ                40     01-27-9417:36ALL                      WIN VAN DER VEGT         Simple Phone Dialer      IMPORT              11     ╣J═W {πFrom: WIM VAN DER VEGTπSubj: Accessing the phoneπ---------------------------------------------------------------------------πThanks, works great and is quite simple. Have modified it a litte so itπattaches the ATDT command and waits for the user to pick up the phone.πAfter that it hangs-up the modem. I forgot how easy it is to sendπSOME characters to the serial port.π}ππUsesπ  Crt;ππPROCEDURE PhoneDialler (Number : String; Port : Byte);ππvarπ   SerialPort  : text;   { Yes, a text file! }ππbeginπ   Case Port ofπ      1 : Assign (SerialPort, 'COM1');π      2 : Assign (SerialPort, 'COM2');π      3 : Assign (SerialPort, 'COM3');π      4 : Assign (SerialPort, 'COM4');π   end; { CASE }π   Rewrite (SerialPort);ππ   Writeln('Tone dialing ',Number,'.');π   Writeln (SerialPort, 'ATDT'+Number);ππ {----Should be large enough to dial the longest number}π   Delay(6*1000);ππ   Write('Pick up the phone, then press space ');π   WHILE NOT(Keypressed AND (Readkey=#32)) DOπ     Beginπ       Write('.');π       Delay(1000);π     End;π   Writeln;ππ   Writeln('Shuting down modem.');π   Writeln (SerialPort,'ATH0');π   Close (SerialPort)πend; { of PROCEDURE 'Phone Dialler' }ππBeginπ  PhoneDialler('045-762288',2);πEnd.π                                                                  41     02-05-9407:56ALL                      KELLY SMALL              Baud Rates               IMPORT              27     ╣J8 {πCan anyone tell me how you would set the baud rate for a speed above 9600 BPπin the bit mask for int 14h. also how you could do a Null modem typeπconnection.ππYou can't.  You must program the divisor in the uart your selfπfor those higher baudrates.  Here's part of a serial routine Iπuse:π}ππUnit SerialIn;π{F+}πInterfaceπUses Crt,Dos;πConst  CommPort   = $3F8;   { normally com1 = $3F8 and com2 = $2F8 }π       CommIrq    = 4;      { normally com1 = 4 and com2 = 3 }π       BaudRate   = 9600;   { 300 - 9600 }π       Parameters = $03;    { 7 6 5  4 3  2  1 0π                              +-+-+  +-+  |  +-+--- width 10 = 7 bitsπ                              don't    |  |               11 = 8 bitsπ                              care     |  +------- stopbit 0 = 1 bitπ                                       |                   1 = 2 bitπ                                       +---------- parity X0 = noneπ                                                          01 = oddπ                                                          11 = even    }ππ       BufferSize = 1000; { Size of receiver buffer }π       IntMask    : Array[2..5] of Byte = ($FB,$F7,$EF,$DF);ππVar ComBuffer  : Array[0..Buffersize] of Byte;π    HeadPtr,π    TailPtr    : Integer;π    OldCommInt : Pointer;ππProcedure ComInit;                    { Initialize serial port }πProcedure ComDisable;                 { Disable serial port }πProcedure SendChar(Ch:Char);          { Send character to serial port }πProcedure SendString(Message:String); { Send string to serial port}πFunction  GetChar:Char;               { Get character from serial port }πFunction  GetCharWait:Char;           { Wait for character ready, then get }πFunction  CharReady:Boolean;          { Returns true if character has been }π                                      { received through serial port }ππImplementationππProcedure ComInit;         { get the serial port ready for use }πVar Divisor : Integer;     { this routine MUST be called before }π    Dummy   : Integer;     { using serial port! }π  Beginπ  Case BaudRate ofπ     300 : Divisor := 384;π    1200 : Divisor := 96;π    2400 : Divisor := 48;π    9600 : Divisor := 12;π   19200 : Divisor := 6;π    3840 : Divisor := 3;π    5760 : Divisor := 2;π   11520 : Divisor := 1;π    Else WriteLn('Illegal Baudrate');π    End;π  Port[CommPort+3] := $80;                 { Set divisor latch bit }π  Port[CommPort] := Lo(Divisor);           { Set lower divisor }ππ  Port[CommPort+1] := Hi(Divisor);         { set upper divisor }π  Port[CommPort+3] := Parameters;          { clear divisor latch and }π                                           { set data parameters }π  HeadPtr := 0;                            { reset buffer pointers }π  TailPtr := 0;π  GetIntVec(CommIrq+8,OldCommInt);         { Save the old vector }π  SetIntVec(CommIrq+8,@ComIntHandler);     { Install interrupt handler }π  Port[CommPort+1] := 1;                   { Enable receiver interrupt }π  Port[CommPort+4] := 9;                   { Enable DTR and OUT2 }π  Port[$21] := Port[$21] Andπ                         IntMask[CommIrq]; { Program 8259 Int mask }π  Dummy := Port[CommPort];                 { Read the receiver register }π  End;                                     { to clear status flags }π                                                               42     02-15-9407:43ALL                      SWAG SUPPORT TEAM        Check ALL COM ports      IMPORT              16     ╣J$⌡ πPROGRAM ComChk;ππUSES Crt;ππ  FUNCTION HexWord(a : Word) : String;π  CONSTπ    Digit          : ARRAY[$0..$F] OF Char = '0123456789ABCDEF';π  VARπ    I              : Byte;π    HexStr         : String;ππ  BEGINπ    HexStr := '';π    FOR I := 1 TO 4 DOπ    BEGINπ      Insert(Digit[a AND $000F], HexStr, 1);π      a := a SHR 4π    END;π    HexWord := HexStr;π  END;                            {hex}πππPROCEDURE UncodePort(NR : integer);π  VARπ    B, M, V1, V2, TLRC, D, MSB, LSB : integer;π    S, CO : integer;π    Baud : real;π    Answer : string[10];π    ComList : array[1..4] OF word ABSOLUTE $0000:$0400;π  BEGINπ    CO := ComList[NR];π    WriteLn;π    WriteLn ('Communications Port ', NR, ':');π    IF CO = 0 THENπ      BEGINπ        WriteLn ('  Not installed.');π        Exit;π      END;ππ    S := Port[CO + 3];π    TLRC := Port[CO + 3];π    Port[CO + 3] := TLRC OR $80;π    LSB := Port[CO];π    MSB := Port[CO + 1];π    D := 256 * MSB + LSB;π    Baud := 115200.0 / D;π    Port[CO + 3] := TLRC AND $7F;ππ    {Display port address}π    WriteLn ('  Port address: ', HexWord (ComList[NR]));ππ    {Display baud rate}π    WriteLn ('     Baud rate: ', Baud:5:0);ππ    {Display data bits}π    IF (S AND 3) = 3 THENπ      B := 8π    ELSE IF (S AND 2) = 2 THENπ      B := 7π    ELSE IF (S AND 1) = 1 THENπ      B := 6π    ELSEπ      B := 5;π    WriteLn ('     Data bits: ', B:5);ππ    {Display stop bits}π    IF (S AND 4) = 4 THENπ      B := 2π    ELSEπ      B := 1;π    WriteLn ('     Stop bits: ', B:5);ππ    IF (S AND 24) = 24 THENπ      Answer := 'Even'π    ELSE IF (S AND 8) = 8 THENπ      Answer := 'Odd'π    ELSEπ      Answer := 'None';π    WriteLn ('        Parity: ', Answer:5);π  END; {procedure Uncode_Setup_Of_Port}ππBEGINπ  ClrScr;π  WriteLn ('Communications Port Status--------------------------');π  UncodePort (1);π  UncodePort (2);π  UncodePort (3);π  UncodePort (4);πEND.ππ                                43     05-25-9408:14ALL                      GREG VIGNEAULT           Reading UART baud rate...SWAG9405            22     ╣Jⁿv π{π Here's a TP function that will report the current UART baud rate forπ any serial port device (modem, mouse, etc.) ...π}ππ(*************************** GETBAUD.PAS ***************************)πPROGRAM GetBaud;                      { compiler: Turbo Pascal 4.0+ }π                                      { Mar.23.94 Greg Vigneault    }ππ(*-----------------------------------------------------------------*)π{ get the current baud rate of a serial i/o port (reads the UART)...}ππFUNCTION SioRate (ComPort :WORD; VAR Baud :LONGINT) :BOOLEAN;π  CONST DLAB = $80;                   { divisor latch access bit    }π  VAR   BaseIO,                       { COM base i/o port address   }π        BRGdiv,                       { baud rate generator divisor }π        regDLL,                       { BRG divisor, latched LSB    }π        regDLM,                       { BRG divisor, latched MSB    }π        regLCR :WORD;                 { line control register       }π  BEGINπ    Baud := 0;                                { assume nothing      }π    IF (ComPort IN [1..4]) THEN BEGIN         { must be 1..4        }π      BaseIO := MemW[$40:(ComPort-1) SHL 1];  { fetch base i/o port }π      IF (BaseIO <> 0) THEN BEGIN             { has BIOS seen it?   }π        regDLL := BaseIO;                     { BRGdiv, latched LSB }π        regDLM := BaseIO + 1;                 { BRGdiv, latched MSB }π        regLCR := BaseIO + 3;                 { line control reg    }π        Port[regLCR] := Port[regLCR] OR DLAB;         { set DLAB    }π        BRGdiv := WORD(Port[regDLL]);                 { BRGdiv LSB  }π        BRGdiv := BRGdiv OR WORD(Port[regDLM]) SHL 8; { BRGdiv MSB  }π        Port[regLCR] := Port[regLCR] AND NOT DLAB;    { reset DLAB  }π        IF (BRGdiv <> 0) THENπ          Baud := 1843200 DIV (LONGINT(BRGdiv) SHL 4);  { calc bps  }π      END; {IF BaseIO}π    END; {IF ComPort}π    SioRate := (Baud <> 0);                   { success || failure  }π  END {SioRate};ππ(*-----------------------------------------------------------------*)ππVAR ComPort : WORD;                         { will be 1..4          }π    Baud    : LONGINT;                      { as high as 115200 bps }ππBEGIN {GetBaud}ππ  REPEATπ    WriteLn; Write ('Read baud rate for which COM port [1..4] ?: ');π    ReadLn (ComPort);π    IF NOT SioRate (ComPort, Baud) THEN BEGINπ      Write ('!',CHR(7)); {!beep}π      CASE ComPort OFπ        1..4 : WriteLn ('COM',ComPort,' is absent; try another...');π        ELSE WriteLn ('Choose a number: 1 through 4...');π      END; {CASE}π    END; {IF}π  UNTIL (Baud <> 0);ππ  WriteLn ('-> COM',ComPort,' is set for ',Baud,' bits-per-second');ππEND {GetBaud}.π                     44     05-25-9408:24ALL                      JONAS MALMSTEN           UART                     SWAG9405            32     ╣JT▌ π{πI've read some questions latelly with questions about how to use a com-port inπpascal. I've written a couple of procedures for doing this. The followingπroutines can be improved, for example they can be satt to run on interruptsπand a few other thing, but... I'm not supposed to do all the job for you, amπI??π}ππUSES CRT,DOS;πππCONSTπ     Com1 : WORD = 1;π     Com2 : WORD = 2;ππtypeπ    port = objectπ       port: byte;π       base: word;π       baud: longint;π       inter: byte;π       function init(comport: word; baudrate: longint): boolean;π       function sendchar(c: char): boolean;π       function getchar(var c: char): boolean;π    end;ππfunction port.init(comport: word; baudrate: longint): boolean;πvarπ   tmp: word;π   bas: word;π   test: byte;πbeginπ     if odd(comport) then inter:=$C else inter:=$B;π                          {This is for later use with interrupts...}π     init:=false;π     if comport<5 thenπ     beginπ          asm {get port base address}π             mov bx,40hπ             mov es,bxπ             mov bx,comportπ             dec bxπ             shl bx,1π             mov ax,es:[bx]π             mov bas,axπ          end;π          if bas=0 thenπ          beginπ               writeln('Could''n find selected com-port!');π               exit;π          end;π     endπ     elseπ     beginπ          case comport of {don't know where to find ps/2 etdπ                           bios, standard base is supposed}π            5: bas:=$4220;π            6: bas:=$4228;π            7: bas:=$5220;π            8: bas:=$5228;π          end;π     end;π     base:=bas;π     tmp:=115200 div baudrate; {baudrate divisor}π     asm {lower DTS and DSR}π        mov dx,basπ        add dx,4π        xor al,alπ        out dx,alπ     end;π     delay(50);π     asm {raise DTS and DSR}π        mov dx,basπ        add dx,4π        mov al,11bπ        out dx,alπ     end;π     asm {set baudrate and N,8,1}π        mov dx,basπ        add dx,3π        mov al,10000011b {N,8,1, set baudrate divisor}π        out dx,alπ        mov ax,tmp {baudrate divisor}π        mov dx,basπ        out dx,alπ        inc dxπ        mov al,ahπ        out dx,alπ        mov dx,basπ        add dx,3π        mov al,00000011b {N,8,1}π        out dx,alπ     end;π     asm {interrupt enable, no interrupts enabled --> gain time}π        mov dx,basπ        inc dxπ        xor al,alπ        out dx,alπ     end;π     asm {raise DTS and DSR}π        mov dx,basπ        add dx,4π        mov al,11bπ        out dx,alπ        in al,dxπ        and al,11bπ        mov test,alπ     end;π     if test<>3 thenπ     beginπ          writeln('Some error....');π          exit;π     end;π     init:=true;πend;ππfunction port.sendchar(c: char): boolean;πvarπ   bas: word;π   cts: byte;πlabelπ     no_send;πbeginπ     cts:=0;π     bas:=base;π     asmπ        mov dx,basπ        add dx,5π        in al,dxπ        and al,00100000b {test CTS (Clear To Send status)}π        jz no_sendπ        mov cts,1π        mov dx,basπ        mov al,cπ        out dx,alπ     no_send:π     end;π     if cts=0 then sendchar:=false else sendchar:=true;πend;ππfunction port.getchar(var c: char): boolean;πvarπ   bas: word;π   rts: byte;π   c2: char;πlabelπ     no_data;πbeginπ     rts:=0;π     bas:=base;π     asmπ        mov dx,basπ        add dx,5π        in al,dxπ        and al,00000001b {test for data ready}π        jz no_dataπ        mov rts,1π        mov dx,basπ        in al,dxπ     no_data:π        mov c2,alπ     end;π     c:=c2;π     if rts=0 then getchar:=false else getchar:=true;πend;πππvarπ   modem: port;π   s: string;π   a: byte;π   c : Char;ππbeginπ     if not modem.init(com2,38400) thenπ     beginπ          writeln('Couldn''t initialize modem...');π          halt;π     end;π     s:='atz'+#13;π     for a:=1 to length(s) do modem.sendchar(s[a]);ππend.πππIf you think these routines are just great and you decide to use them as theyπare I wouldn't mind if you gave me a credit.π                 45     05-26-9407:29ALL                      SCOTT BAKER              Fossil Driver            IMPORT              40     ╣J╣Ü unit ddfossil;π{$S-,V-,R-}ππinterfaceπuses dos;ππconstπ name='Fossil drivers for TP 4.0';π author='Scott Baker';πtypeπ fossildatatype = recordπ                   strsize: word;π                   majver: byte;π                   minver: byte;π                   ident: pointer;π                   ibufr: word;π                   ifree: word;π                   obufr: word;π                   ofree: word;π                   swidth: byte;π                   sheight: byte;π                   baud: byte;π                  end;πvarπ port_num: integer;π fossildata: fossildatatype;ππprocedure async_send(ch: char);πprocedure async_send_string(s: string);πfunction async_receive(var ch: char): boolean;πfunction async_carrier_drop: boolean;πfunction async_carrier_present: boolean;πfunction async_buffer_check: boolean;πfunction async_init_fossil: boolean;πprocedure async_deinit_fossil;πprocedure async_flush_output;πprocedure async_purge_output;πprocedure async_purge_input;πprocedure async_set_dtr(state: boolean);πprocedure async_watchdog_on;πprocedure async_watchdog_off;πprocedure async_warm_reboot;πprocedure async_cold_reboot;πprocedure async_Set_baud(n: integer);πprocedure async_set_flow(SoftTran,Hard,SoftRecv: boolean);πprocedure Async_Buffer_Status(var Insize,Infree,OutSize,Outfree: word);ππimplementationππprocedure async_send(ch: char);πvarπ regs: registers;πbegin;π regs.al:=ord(ch);π regs.dx:=port_num;π regs.ah:=1;π intr($14,regs);πend;ππprocedure async_send_string(s: string);πvarπ a: integer;πbegin;π for a:=1 to length(s) do async_send(s[a]);πend;ππfunction async_receive(var ch: char): boolean;πvarπ regs: registers;πbegin;π ch:=#0;π regs.ah:=3;π regs.dx:=port_num;π intr($14,regs);π if (regs.ah and 1)=1 then begin;π  regs.ah:=2;π  regs.dx:=port_num;π  intr($14,regs);π  ch:=chr(regs.al);π  async_receive:=true;π end else async_receive:=false;πend;ππfunction async_carrier_drop: boolean;πvarπ regs: registers;πbegin;π regs.ah:=3;π regs.dx:=port_num;π intr($14,regs);π if (regs.al and $80)<>0 then async_carrier_drop:=false else async_carrier_drop:=true;πend;ππfunction async_carrier_present: boolean;πvarπ regs: registers;πbegin;π regs.ah:=3;π regs.dx:=port_num;π intr($14,regs);π if (regs.al and $80)<>0 then async_carrier_present:=true else async_carrier_present:=false;πend;ππfunction async_buffer_check: boolean;πvarπ regs: registers;πbegin;π regs.ah:=3;π regs.dx:=port_num;π intr($14,regs);π if (regs.ah and 1)=1 then async_buffer_check:=true else async_buffer_check:=false;πend;ππfunction async_init_fossil: boolean;πvarπ regs: registers;πbegin;π regs.ah:=4;π regs.bx:=0;π regs.dx:=port_num;π intr($14,regs);π if regs.ax=$1954 then async_init_fossil:=true else async_init_fossil:=false;πend;ππprocedure async_deinit_fossil;πvarπ regs: registers;πbegin;π regs.ah:=5;π regs.dx:=port_num;π intr($14,regs);πend;ππprocedure async_set_dtr(state: boolean);πvarπ regs: registers;πbegin;π regs.ah:=6;π if state then regs.al:=1 else regs.al:=0;π regs.dx:=port_num;π intr($14,regs);πend;ππprocedure async_flush_output;πvarπ regs: registers;πbegin;π regs.ah:=8;π regs.dx:=port_num;π intr($14,regs);πend;ππprocedure async_purge_output;πvarπ regs: registers;πbegin;π regs.ah:=9;π regs.dx:=port_num;π intr($14,regs);πend;ππprocedure async_purge_input;πvarπ regs: registers;πbegin;π regs.ah:=$0a;π regs.dx:=port_num;π intr($14,regs);πend;ππprocedure async_watchdog_on;πvarπ regs: registers;πbegin;π regs.ah:=$14;π regs.al:=01;π regs.dx:=port_num;π intr($14,regs);πend;ππprocedure async_watchdog_off;πvarπ regs: registers;πbegin;π regs.ah:=$14;π regs.al:=00;π regs.dx:=port_num;π intr($14,regs);πend;ππprocedure async_warm_reboot;πvarπ regs: registers;πbegin;π regs.ah:=$17;π regs.al:=01;π intr($14,regs);πend;ππprocedure async_cold_reboot;πvarπ regs: registers;πbegin;π regs.ah:=$17;π regs.al:=00;π intr($14,regs);πend;ππprocedure async_set_baud(n: integer);πvarπ regs: registers;πbegin;π regs.ah:=00;π regs.al:=3;π regs.dx:=port_num;π case n ofπ  300: regs.al:=regs.al or $40;π  1200: regs.al:=regs.al or $80;π  2400: regs.al:=regs.al or $A0;π  4800: regs.al:=regs.al or $C0;π  9600: regs.al:=regs.al or $E0;π  19200: regs.al:=regs.al or $00;π end;π intr($14,regs);πend;ππprocedure async_set_flow(SoftTran,Hard,SoftRecv: boolean);πvarπ regs: registers;πbegin;π regs.ah:=$0F;π regs.al:=00;π if softtran then regs.al:=regs.al or $01;π if Hard then regs.al:=regs.al or $02;π if SoftRecv then regs.al:=regs.al or $08;π regs.al:=regs.al or $F0;π Intr($14,regs);πend;ππprocedure async_get_fossil_data;πvarπ regs: registers;πbegin;π regs.ah:=$1B;π regs.cx:=sizeof(fossildata);π regs.dx:=port_num;π regs.es:=seg(fossildata);π regs.di:=ofs(fossildata);π intr($14,regs);πend;ππprocedure Async_Buffer_Status(var Insize,Infree,OutSize,Outfree: word);πbegin;π async_get_fossil_data;π insize:=fossildata.ibufr;π infree:=fossildata.ifree;π outsize:=fossildata.obufr;π outfree:=fossildata.ofree;πend;ππend.π