10     REM **** APPL #SA0043
20     REM **** DB MODULE - POLL COS MODE
30     REM **** REVISION 1  04/27/2005
40     REM **** SMARTEYE CORPORATION

50     REM **** VARIABLES
60     REM $(1) = RESTART
70     REM $(2) = BOX POLL
80     REM $(3) = ACK
90     REM TIMO = MESSAGE TIMEOUT VALUE
100    REM ML = MESSAGE LENGTH
110    REM POLL = POLL DELAY TIME (SEC)
120    REM TER = MESSAGE TIMEOUT/LENGTH ERROR
130    REM CER = MESSAGE CHECKSUM ERROR
140    REM RN = READER NUMBER
150    REM MT = MESSAGE TYPE
160    REM ST = SMARTEYE COMMUNICATION STATUS
170    REM EV = READER/ERROR EVENT FLAG
180    REM NUM = LABEL/ERROR NUMBER OUTPUT WORD
190    REM PCNT = POLL TIMEOUT COUNT
200    REM PMAX = MAXIMUM POLL COUNT FOR RESTART
210    REM IO(x) = BLOCK TRANSFER BUFFER POSITION NUMBER
220    REM T(x) = SMARTEYE MESSAGE ARRAY
230    REM L(x) = LABEL NUMBER ARRAY
240    REM ER(x) = ERROR NUMBER ARRAY
250    REM SCS = CALCULATED MESSAGE CHECKSUM
260    REM CS = SMARTEYE TRANSMITTED CHECKSUM
270    REM MTMO = SMARTEYE MESSAGE TIMEOUT VALUE
280    REM SER = SUPPRESS ERROR MESSAGES
290    REM HB =  BASIC MODULE HEARTBEAT

300    REM **** INITIALIZATION
310    STRING 0,0 :  STRING 2000,50 :  CLOCK 0
320    MODE (PRT1,19200,N,8,1,N,) :  CLOCK 1
330    PUSH 8 :  CALL 5 :  PUSH 8 :  CALL 4
340    DIM IO(8) :  DIM T(72) :  DIM L(8) :  DIM ER(8)
350    EV=0 : ML=0 : DA=0 : ER=0 : LN=0 : POLL=0
360    RN=0 : G=0 : TIME=0 : CS=0 : SCS=0
370    CER=0 : MT=0 : PCNT=0 : PMAX=5 : TER=0
380    IO(1)=1 : IO(2)=2 : IO(3)=3 : IO(4)=4
390    IO(5)=5 : IO(6)=6 : IO(7)=7 : IO(8)=8
400    $(1)="xxR" : ASC($(1),1)=10 : ASC($(1),2)=48
410    $(2)="xxB" : ASC($(2),1)=10 : ASC($(2),2)=48
420    $(3)="xxA" : ASC($(3),1)=10 : ASC($(3),2)=48

430    PRINT "PROGRAM START"
440    REM **** ESTABLISH PLC COMMUNICATION
450    PRINT "ESTABLISH PLC COMMUNICATION"
460    FOR I=1 TO 8 :  PUSH 0 :  PUSH IO(I) :  CALL 21 :  NEXT I
470    CALL 6
480    PUSH IO(2) :  CALL 11 :  POP DA
490    DA=DA+1
500    PUSH DA :  PUSH IO(2) :  CALL 21
510    CALL 7
520    PUSH IO(3) :  CALL 11 :  POP POLL : POLL=POLL/100
530    PRINT "POLL RATE:",POLL
540    PUSH IO(5) :  CALL 11 :  POP MTMO : MTMO=MTMO/100
550    PRINT "MESSAGE TIMEOUT:",MTMO

560    REM **** ISSUE RESTART
570    PRINT "RESTART"
580    TER=0 : CER=0 : PCNT=0 : CSTAT=0
590    GOSUB 1770 :  REM HEARTBEAT SERVICE
600    GOSUB 1170 :  REM RESTART COMMAND
610    GOSUB 1330 :  REM RETRIEVE MESSAGE
620    IF TER<>0 THEN 710
630    GOSUB 1430 :  REM CALCULATE CHECKSUM
640    IF CER<>0 THEN 710
650    PUSH CSTAT :  PUSH IO(4) :  CALL 21
660    CALL 6
670    PUSH IO(2) :  CALL 11 :  POP DA
680    PUSH DA :  PUSH IO(2) :  CALL 21
690    CALL 7
700    GOTO 730
710    PRINT "COMM ERROR ON STARTUP" :  PRINT
720    GOTO 350

730    REM **** MAIN LOOP
740    PRINT "MAIN LOOP"
750    MT=0 : NUM=0 : TIME=0 : HB=0
760    TER=0 : CER=0 : P_DLY=TIME+POLL
770    IF PCNT<PMAX THEN 790
780    PRINT "POLL COUNT RESTART" :  GOTO 570
790    A=GET :  IF A=77 THEN  GOSUB 1300
800    CALL 3 :  POP Y :  IF Y<>0 THEN 1140
810    PUSH IO(2) :  CALL 11 :  POP DA
820    PUSH DA :  PUSH IO(2) :  CALL 21
830    CALL 2 :  POP Y :  IF Y<>0 THEN 1140
840    IF TIME<P_DLY.AND.T(3)=90 THEN 790
850    GOSUB 1250 :  REM BOX POLL COMMAND
860    GOSUB 1330 :  REM RETRIEVE MESSAGE
870    GOSUB 1770 :  REM HEARTBEAT SERVICE
880    IF T(3)=69.AND.SER=1 THEN  GOSUB 1210 :  GOTO 750
890    IF TER=0 THEN 910
900    PCNT=PCNT+1 :  GOTO 750
910    IF T(3)=90 THEN 750
920    GOSUB 1430 :  REM CALCULATE CHECKSUM
930    IF CER=0 THEN 950
940    PCNT=PCNT+1 :  GOTO 750
950    RN=T(2)-48
960    IF T(3)<>90 THEN  GOSUB 1210 :  REM ACK COMMAND
970    IF T(3)=76 THEN  GOSUB 1510 :  REM LABEL MESSAGE
980    IF T(3)=77 THEN  GOSUB 1510 :  REM MAN LABEL MESSAGE
990    IF T(3)=69 THEN  GOSUB 1580 :  REM ERROR MESSAGE
1000   IF T(3)=67 THEN  GOSUB 1640 :  REM CAL MESSAGE
1010   CALL 3 :  POP Y :  IF Y<>0 THEN 1140
1020   PUSH IO(2) :  CALL 11 :  POP DA
1030   DA=DA+1
1040   PUSH IO(4) :  CALL 11 :  POP HB : HB=16384*(HB.AND.1)
1050   PUSH DA :  PUSH IO(2) :  CALL 21
1060   PUSH EV :  PUSH IO(3) :  CALL 21
1070   PUSH MT.OR.RN :  PUSH IO(4) :  CALL 21
1080   PUSH NUM :  PUSH IO(5) :  CALL 21
1090   PUSH (BCAL*256).OR.ACAL :  PUSH IO(6) :  CALL 21
1100   PUSH (XCAL*256).OR.CCAL :  PUSH IO(7) :  CALL 21
1110   PUSH YCAL.OR.CSTAT.OR.HB :  PUSH IO(8) :  CALL 21
1120   CALL 2 :  POP Y :  IF Y<>0 THEN 1140
1130   GOTO 750
1140   PRINT "PLC COMM TIMEOUT"
1150   GOTO 350
1160   END

1170   REM ****  RESTART COMMAND  SUBROUTINE
1180   PCNT=0 :  PUSH 2 :  CALL 37 :  PRINT #$(1), CR ,
1190   IF G=77 THEN  PRINT $(1)
1200   RETURN

1210   REM ****  ACK COMMAND  SUBROUTINE
1220   PUSH 2 :  CALL 37 : ASC($(3),2)=T(2) :  PRINT #$(3), CR ,
1230   IF G=77 THEN  PRINT $(3)
1240   RETURN

1250   REM ****  BOX POLL COMMAND  SUBROUTINE
1260   PUSH 2 :  CALL 37 :  PRINT #$(2), CR ,
1270   IF G=77 THEN  PRINT $(2)
1280   RETURN

1290   REM **** MONITOR TOGGLE SUBROUTINE
1300   G=G.XOR.A
1310   IF G=A THEN  PRINT "MONITOR ON" ELSE  PRINT "MONITOR OFF"
1320   RETURN

1330   REM **** RETRIEVE MESSAGE FROM SEA SUBROUTINE
1340   TIMO=TIME+MTMO : ML=0
1350   IF TIME<TIMO THEN 1370
1360   TER=1 :  PRINT "MESSAGE TIMEOUT" :  RETURN
1370   X=GET# :  IF X=0 THEN 1350 ELSE ML=ML+1 : T(ML)=X
1380   IF X<>13.AND.ML<72 THEN 1350
1390   IF ML<72 THEN 1400 ELSE TER=1 :  PRINT "MESSAGE LENGTH ERROR" :  RETURN
1400   IF G=77 THEN  FOR J=2 TO ML :  PRINT CHR(T(J)), :  NEXT J :  PRINT
1410   CSTAT=32768 : PCNT=0
1420   RETURN

1430   REM **** CHECKSUM CALCULATION SUBROUTINE
1440   CER=0 : CS=0 : SCS=0
1450   FOR I=1 TO ML-3 : CS=CS.XOR.T(I) :  NEXT I
1460   SCS=(T(ML-2)-97)*16
1470   SCS=(T(ML-1)-97)+SCS
1480   IF CS=SCS THEN 1500
1490   CER=1 :  PRINT "CHECKSUM ERROR"
1500   RETURN

1510   REM ****  PROCESS LABEL MESSAGE SUBROUTINE
1520   LN=10000*(T(4)-48)+1000*(T(5)-48)+100*(T(6)-48)+10*(T(7)-48)+(T(8)-48)
1530   IF LN=L(RN).AND.T(9)=82 THEN 1570
1540   L(RN)=LN : NUM=LN : EV=EV.XOR.(2**(RN))
1550   IF T(9)=82 THEN MT=2304 ELSE MT=256
1560   IF T(3)=77 THEN MT=MT.OR.4096
1570   RETURN

1580   REM ****  PROCESS ERROR MESSAGE SUBROUTINE
1590   ER=10*(T(4)-48)+(T(5)-48)
1600   IF (ER=ER(RN).AND.T(9)=82).OR.ER=0 THEN 1630
1610   ER(RN)=ER : NUM=ER : EV=EV.XOR.((2**(RN))*256)
1620   IF T(6)=82 THEN MT=2560 ELSE MT=512
1630   RETURN

1640   REM ****  PROCESS CALIBRATION MESSAGE SUBROUTINE
1650   ACAL=10*(T(7)-48)+(T(8)-48)
1660   IF T(6)=45 THEN ACAL=ACAL.OR.128
1670   BCAL=10*(T(12)-48)+(T(13)-48)
1680   IF T(11)=45 THEN BCAL=BCAL.OR.128
1690   CCAL=10*(T(17)-48)+(T(18)-48)
1700   IF T(16)=45 THEN CCAL=CCAL.OR.128
1710   XCAL=10*(T(22)-48)+(T(23)-48)
1720   IF T(21)=45 THEN XCAL=XCAL.OR.128
1730   YCAL=10*(T(27)-48)+(T(28)-48)
1740   IF T(26)=45 THEN YCAL=YCAL.OR.128
1750   IF T(29)=82 THEN MT=3072 ELSE MT=1024
1760   RETURN

1770   REM ****  HEARTBEAT SERVICE SUBROUTINE
1780   CALL 3 :  POP Y
1790   PUSH IO(4) :  CALL 11 :  POP TEM
1800   HB=16384*(TEM.AND.1) : SER=(TEM.AND.2)/2
1810   PUSH CSTAT.OR.HB.OR.YCAL :  PUSH IO(8) :  CALL 21
1820   CALL 2 :  POP Y
1830   RETURN
