home *** CD-ROM | disk | FTP | other *** search
- (*******************************************************************)
- (* *)
- (* SELFTEST.PAS June 1996 *)
- (* *)
- (* SELFTEST requires two serial ports on the same computer. The *)
- (* program transmits a test string on one port (FirstCOM) and *)
- (* receives on a second port (SecondCOM), where the two ports are *)
- (* connected via a null modem adapter. The received string is *)
- (* tested against the transmit string (they should be idenical). *)
- (* *)
- (* Connect the two serial ports (on a single computer) together *)
- (* using a null modem cable. Be sure to modify the configuration *)
- (* section for non-standard PC ports or to setup your multiport *)
- (* board. Note that many multiport boards are either Digiboard or *)
- (* BOCA board compatible. *)
- (* *)
- (*******************************************************************)
-
-
- program selftest;
- uses crt, PCL4P;
-
- const
- PC = 1;
- DB = 2;
- BB = 3;
- TestSize = 63;
- NbrRuns = 16;
- var
- BaudCode : Integer;
- BaudText : String;
- RetCode : Integer;
- Version : Integer;
- C : Char;
- I, N : Integer;
- Port : Integer;
- Reset1st : Boolean;
- Reset2nd : Boolean;
- BufPtr : Pointer;
- BufSeg : Integer;
- TestSet: array[0..62] of Char;
- FirstCOM : Integer;
- SecondCOM : Integer;
- TheSwitch : Integer;
- ComLimit : Integer;
- TestLength: Integer;
- RxBase : Integer;
- TxBase : Integer;
-
- procedure SayError( Code : Integer );
- var
- RetCode : Integer;
- begin
- if Code < 0 then RetCode := SioError( Code )
- else if (Code and (FramingError or ParityError or OverrunError)) <> 0 then
- begin (* Port Error *)
- if (Code and FramingError) <> 0 then WriteLn('Framing Error');
- if (Code and ParityError) <> 0 then WriteLn('Parity Error');
- if (Code and OverrunError) <> 0 then WriteLn('Overrun Error')
- end
- end;
-
- function ErrorCheck(Code : Integer) : Integer;
- begin
- (* trap PCL error codes *)
- if Code < 0 then
- begin
- WriteLn;
- Write('ERROR: ');
- SayError( Code );
- if Reset1st then RetCode := SioDone(FirstCOM);
- if Reset2nd then RetCode := SioDone(SecondCOM);
- WriteLn('*** HALTING ***');
- Halt;
- end;
- ErrorCheck := Code;
- end;
-
- procedure SetFIFO(Port : Integer);
- begin
- if SioFIFO(Port, LEVEL_8) > 0
- then WriteLn('*** COM',1+Port,': [16550]')
- else WriteLn('*** COM',1+Port,': [8250/16450]');
- end;
-
- begin (* main program *)
- Reset1st := FALSE;
- Reset2nd := FALSE;
- BaudCode := Baud115200;
- BaudText := '115200';
- TheSwitch := 0;
- (* build TestSet[] array *)
- for i := 0 to 25 do TestSet[i] := chr(ord('A')+i);
- for i := 0 to 25 do TestSet[26+i] := chr(ord('a')+i);
- for i := 0 to 9 do TestSet[52+i] := chr(ord('0')+i);
- TestSet[62] := chr(10);
- (* fetch PORT # from command line *)
- if ParamCount <> 3 then
- begin
- WriteLn('USAGE: "SELFTEST {PC|DB|BB} 1stCom 2ndCom"');
- halt;
- end;
- (* determine port type *)
- if (ParamStr(1)='pc') OR (ParamStr(1)='PC') then TheSwitch := PC;
- if (ParamStr(1)='db') OR (ParamStr(1)='DB') then TheSwitch := DB;
- if (ParamStr(1)='bb') OR (ParamStr(1)='BB') then TheSwitch := BB;
- (* check switch value *)
- if TheSwitch = 0 then
- begin
- WriteLn('Must specify "PC", "DB" or "BB" as 1st argument');
- WriteLn('EG: SELFTEST PC 1 4');
- Halt
- end;
- (* set port limits *)
- if TheSwitch = PC then ComLimit := COM4;
- if TheSwitch = DB then ComLimit := COM8;
- if TheSwitch = BB then ComLimit := COM16;
- (* get FirstCom *)
- Val( ParamStr(2),FirstCom, RetCode );
- if RetCode <> 0 then
- begin
- WriteLn('1st COM port must be 1 to 20');
- Halt;
- end;
- FirstCom := FirstCom - 1;
- if (FirstCom<COM1) or (FirstCom>COM20) then
- begin
- WriteLn('1st COM port must be 1 to 20');
- Halt
- end;
- WriteLn('FirstCOM =',1+FirstCOM);
- (* get SecondCOM *)
- Val( ParamStr(3),SecondCom, RetCode );
- if RetCode <> 0 then
- begin
- WriteLn('2nd COM port must be 1 to 20');
- Halt;
- end;
- SecondCom := SecondCom - 1;
- if (SecondCom<COM1) or (SecondCom>COM20) then
- begin
- WriteLn('2nd COM port must be 1 to 20');
- Halt
- end;
- WriteLn('SecondCOM =',1+SecondCOM);
- (* check range limits *)
- if FirstCOM < COM1 then
- begin
- WriteLn('1stCom must be >= COM1');
- Halt;
- end;
- if SecondCOM > ComLimit then
- begin
- WriteLn('2ndCom must be <= COM',1+ComLimit);
- Halt;
- end;
- if FirstCOM >= SecondCOM then
- begin
- WriteLn('1stCom must be < 2ndCom');
- Halt;
- end;
- (* configure ports as necessary *)
- if TheSwitch = DB then
- begin
- (*** Custom Configuration: DigiBoard PC/8 ***)
- WriteLn('[ Configuring for DigiBoard PC/8 (IRQ5) ]');
- SioPorts(8,COM1,$140,DIGIBOARD);
- for Port := COM1 to COM8 do
- begin
- (* set DigiBoard UART addresses *)
- ErrorCheck( SioUART(Port,$100+8*Port) );
- (* set DigiBoard IRQ *)
- ErrorCheck( SioIRQ(Port,IRQ5) );
- end;
- end;
- if TheSwitch = BB then
- begin
- (*** Custom Configuration: BOCA BB2016 ***)
- WriteLn('[ Configuring for BOCA Board BB2016 (IRQ15) ]');
- SioPorts(16,COM1,$107,BOCABOARD);
- for Port := COM1 to COM16 do
- begin
- (* set BOCA Board UART addresses *)
- ErrorCheck( SioUART(Port,$100+8*Port) );
- (* set BOCA Board IRQ *)
- ErrorCheck( SioIRQ(Port,IRQ15) );
- end;
- end;
- if TheSwitch = PC then
- begin
- WriteLn('[ Configuring for standard PC ports]');
- end;
- (* setup 1K receive buffers *)
- GetMem(BufPtr,1024+16);
- BufSeg := Seg(BufPtr^) + ((Ofs(BufPtr^)+15) SHR 4);
- RetCode := ErrorCheck( SioRxBuf(FirstCOM, BufSeg, Size1024) );
- GetMem(BufPtr,1024+16);
- BufSeg := Seg(BufPtr^) + ((Ofs(BufPtr^)+15) SHR 4);
- RetCode := ErrorCheck( SioRxBuf(SecondCOM, BufSeg, Size1024) );
- (* using transmit interrupts ? *)
- if SioInfo('I') > 0 then
- begin
- (* setup 1K transmit buffers *)
- WriteLn('Setting up transmit buffers');
- GetMem(BufPtr,1024+16);
- BufSeg := Seg(BufPtr^) + ((Ofs(BufPtr^)+15) SHR 4);
- RetCode := ErrorCheck( SioTxBuf(FirstCOM, BufSeg, Size1024) );
- GetMem(BufPtr,1024+16);
- BufSeg := Seg(BufPtr^) + ((Ofs(BufPtr^)+15) SHR 4);
- RetCode := ErrorCheck( SioTxBuf(SecondCOM, BufSeg, Size1024) );
- end;
- (* reset FirstCOM *)
- RetCode := SioReset(FirstCOM,BaudCode);
- (* if error then try one more time *)
- if RetCode <> 0 then RetCode := ErrorCheck( SioReset(FirstCOM,BaudCode) );
- Reset1st := TRUE;
- (* Port successfully reset *)
- WriteLn('COM',1+FirstCOM,' reset @ ',BaudText);
- (* reset SecondCOM *)
- RetCode := SioReset(SecondCOM,BaudCode);
- (* if error then try one more time *)
- if RetCode <> 0 then RetCode := ErrorCheck( SioReset(SecondCOM,BaudCode) );
- (* SecondCOM successfully reset *)
- WriteLn('COM',1+SecondCOM,' reset @ ',BaudText);
- Reset2nd := TRUE;
- (* set port parmameters *)
- RetCode := ErrorCheck( SioParms(FirstCOM, NoParity, OneStopBit, WordLength8) );
- RetCode := ErrorCheck( SioParms(SecondCOM, NoParity, OneStopBit, WordLength8) );
- WriteLn('*** SELFTEST: 06/05/96 ');
- Version := SioInfo('V');
- WriteLn('*** Library: ',Version SHR 4,'.',15 AND Version);
- (* set FIFO level if have INS16550 *)
- SetFIFO(FirstCOM);
- SetFIFO(SecondCOM);
- if SioInfo('I') > 0
- then WriteLn('*** TX Intr: Enabled')
- else WriteLn('*** TX Intr: Disabled');
- WriteLn;
- (* flush ports *)
- RetCode := ErrorCheck( SioRxClear(FirstCOM) );
- RetCode := ErrorCheck( SioRxClear(SecondCOM) );
- (* get base interrupt counts *)
- RxBase := SioInfo('R');
- TxBase := SioInfo('T');
- (* send string *)
- WriteLn('Test Set: ',TestSet);
- Write(' Sending set: ');
- for I := 1 to NbrRuns do
- begin
- Write(I,' ');
- for N := 0 to TestSize-1 do
- begin
- C := TestSet[N];
- RetCode := ErrorCheck( SioPutc(FirstCOM,C) );
- end;
- end;
- WriteLn;
- (* receive string *)
- Write('Receiving set: ');
- for I:= 1 to NbrRuns do
- begin
- Write(I,' ');
- for N := 0 to TestSize-1 do
- begin
- RetCode := ErrorCheck( SioGetc(SecondCOM,18) );
- (* compare character *)
- if chr(RetCode) <> TestSet[N] then
- begin
- WriteLn; WriteLn;
- Write(' ERROR: Expecting ',TestSet[N],' received ',chr(RetCode));
- WriteLn(' @ index ',N,' in set ',I);
- Write(SioInfo('R')-RxBase,' RX interrupts, ');
- WriteLn(SioInfo('T')-TxBase,' TX interrupts.');
- WriteLn(SioRxQue(Port),' characters in RX queue.');
- if Reset1st then SioDone(FirstCOM);
- if Reset2nd then SioDone(SecondCOM);
- Halt;
- end;
- end;
- end;
- WriteLn;
- (* check FIFO performance *)
- WriteLn;
- TestLength := NbrRuns * TestSize;
- I := SioInfo('R');
- Write(I-RxBase:3,' RX interrupts on ',TestLength,' incoming bytes: ');
- if I-RxBase < TestLength
- then WriteLn('RX FIFO operational')
- else WriteLn('RX FIFO not operational [or not 16550 UART]');
- if SioInfo('I') > 0 then
- begin
- (* check TX FIFO *)
- I := SioInfo('T');
- Write(I-TxBase:3,' TX interrupts on ',TestLength,' outgoing bytes: ');
- if I-TxBase < TestLength
- then WriteLn('TX FIFO operational')
- else WriteLn('TX FIFO not operational [or not 16550 UART]');
- WriteLn; WriteLn('SUCCESS: Test AOK !');
- RetCode := SioDone(FirstCOM);
- RetCode := SioDone(SecondCOM);
- end;
- end.