IMPLEMENTATION (*ADO*) MODULE TraceVW; (* Amadeus *) IMPORT AttrWindow, Events, NumberConversion, Resource, Windows2; FROM Windows2 IMPORT Colour; (* Application *) FROM RS232ADT IMPORT LineStatus, LineStatusSet, ErrorCodes, ErrorCodeSet; IMPORT RS232ADT, ItemQueues, LnMsg; FROM HardError IMPORT Assert; IMPORT HardError; CONST (* --- COM 1 --- *) DefaultPort = 03F8H; DefaultIrq = 4; TYPE ByteSet = SET OF [0..7]; ByteCard = SHORTCARD[0..255]; VAR traceWin : Windows2.Window; firstLine : BOOLEAN; serialPort : RS232ADT.Port; workSpace :ARRAY[0..2000H] OF WORD; display : ItemQueues.ItemQueue; oldPollExternal: Events.EventPollProc; PROCEDURE Protocol(); TYPE States = ( WAIT, OPCN, MSG ); VAR state : States; len : CARDINAL[0..127]; expectedLen : CARDINAL[0..127]; m : LnMsg.LoconetMessage; b : BYTE; bv : BOOLEAN; opc : BOOLEAN; err : BOOLEAN; PROCEDURE PutMessage(); BEGIN IF NOT ItemQueues.IsFull( display ) THEN ItemQueues.Insert( display, m ); ELSE Windows2.WriteString( traceWin, "Queue full" ); Windows2.WriteLn( traceWin ); END; len := 0; END PutMessage; PROCEDURE PutCompleteMessage(); BEGIN m.length := len; PutMessage(); END PutCompleteMessage; PROCEDURE PutIncompleteMessage(); BEGIN m.length := -VAL(INTEGER,len); PutMessage(); END PutIncompleteMessage; PROCEDURE PutLineError(*Message*)( error : RS232ADT.ErrorCodeSet ); BEGIN m.length := 0; m.message[0] := error; PutMessage(); len := 0; END PutLineError; PROCEDURE HandleByteError(); (* b contains a valid (but unexpected) byte, handle it *) BEGIN IF opc THEN (* assume start of new message *) PutIncompleteMessage(); m.message[len] := b; INC(len); CASE (ByteCard(b) DIV 32) MOD 4 OF | 0 : state := MSG; expectedLen := 2; | 1 : state := MSG; expectedLen := 4; | 2 : state := MSG; expectedLen := 6; | 3 : state := OPCN; END (*CASE*); ELSE m.message[len] := b; INC(len); PutIncompleteMessage(); state := WAIT; END; END HandleByteError; PROCEDURE GetByte; VAR ch : CHAR; error : RS232ADT.ErrorCodeSet; BEGIN REPEAT RS232ADT.BusyRead ( serialPort, ch , bv, error ); IF NOT bv AND (error=ErrorCodeSet{}) THEN RS232ADT.SleepUntilNextChar( serialPort ); RS232ADT.BusyRead( serialPort, ch, bv, error ); END; b := ch; opc := bv & (7 IN ByteSet(b)); err := error # ErrorCodeSet{}; (* now we have got a byte or errorcond from the serial controller *) Assert( bv OR err ); IF err THEN IF bv THEN (* add byte, iff any *) m.message[len] := b; INC(len); END; IF len>0 THEN (* enqueue anything in the buffer *) PutIncompleteMessage(); END; (* now enqueue the errormessage *) PutLineError( error ); state := WAIT; END (*IF*); UNTIL ~err; Assert( bv & ~err ); END GetByte; BEGIN len := 0; state := WAIT; (* waiting on opcode *) LOOP GetByte(); (* now: bv & ~err *) CASE state OF | WAIT : IF opc THEN m.message[len] := b; INC(len); CASE (ByteCard(b) DIV 32) MOD 4 OF | 0 : state := MSG; expectedLen := 2; | 1 : state := MSG; expectedLen := 4; | 2 : state := MSG; expectedLen := 6; | 3 : state := OPCN; END (*CASE*); ELSE HandleByteError(); END (*IF*); | OPCN : IF ~opc & (ByteCard(b)>2) THEN m.message[len] := b; INC(len); expectedLen := VAL(CARDINAL,ByteCard(b)); state := MSG; ELSE HandleByteError(); END; | MSG : IF ~opc THEN m.message[len] := b; INC(len); IF len