/4. 8 TO 8 MODEM LINK HANDLER. 5/7/79 / /THIS HANDLER RESPOND TO STANDARD OS/8 DEVICE CALLS, AND USES /ANY SERIAL I/O PORT (e.g. KL8J,PT08,ETC.) FOR COMMUNICATION /WITH ANOTHER OS/8 SYSTEM RUNNING THE SLAVE PROGRAM, NSXX.SV /FOR FULL ACCESS TO ITS OS/8 DEVICES. SEE WRITUP FOR DETAILS. /COPYRIGHT 1977,1978,1979 /D.G.HENDERSON AND D.S.HARMER /SMALL COMPUTER LABORATORY /GEORGIA TECH, ATLANTA GA. 30332 /THIS SOFTWARE MAY BE USED ON ANY SYSTEM,AND COPIED FOR SUCH USE /PRVIDED THE ABOVE COPYRIGHT NOTICE IS INCLUDED AND APPROPRIATE /REFERENCE MADE. VNUM="2&77 /VERSION NUMBER VLET="A&77 /VERSION LETTER VE=VNUM^100+VLET /VERSION 1B FROM JULY 26, '77 / /SAVED ONE LOC IN READA 4/25/79 DSH / /COSMETIC EDIT 5/3/79 DSH / / CHECKSUM STYLE: A = CMA[SUM BYTES SENT] / NOT A = CMA[# BYTES + SUM BYTES] IFZERO VLET-01 IFNDEF V1A / / FALSE=0 /SET TO IGNORE 177 CHAR ON READ.. / / IFZERO VNUM-61 /SEE SLAVE FOR COMMENTS IFNDEF BLKSIZ / / DLY=00 /SET TO DELAY 15 MS AFTER EACH CHAR SENT /FOR TEST PURPOSES ONLY / TO RECONFIGURE THIS HANDLER: / THERE ARE 12 POSSIBLE ENTRY POINTS / THEY ARE NAMED DEV1 THRU DEV9,DEV10,DEV11,DEV12 / AN APPROPRIATE DEVICE NAME MUST BE PICKED ON / THE SYSTEM THAT USES THIS HANDLER / AND AN APPROPRIATE HANDLER DESCRIPTOR TABLE ENTRY FOR / BUILD MUST BE MADE (SEE EXAMPLE BELOW) / / / AN ADDITIONAL ENTRY POINT, DEV0, MAY BE USED BY / A PROGRAM WISHING TO RECONFIGURE THE SLAVE / THIS ENTRY POINT IS NOT ACCESSABLE TO BUILD, BUT / A SMART PROGRAM MAY REALIZE ITS THERE AND USE IT / / ON A READ TO DEV0, THE SLAVE SENDS ITS CURRENT CONFIGURATION TABLE. / ON A WRITE TO DEV0, A NEW CONFIGURATION TABLE IS SENT TO THE / SLAVE. THIS NEW TABLE IS USED TO FETCH THE / APPROPRIATE DEVICE HANDLERS FOR SUBSEQUENT USE BY THE SLAVE. / / FORMAT OF THE CONFIGURATION TABLE: / WORD 0: -NUMBER OF DEVICE NAMES IN TABLE / WORD 1&2 DEVICE NAME USED WITH ENTRY POINT 1 / WORD 2&3 DEVICE NAME USED WITH ENTRY POINT 2 / ETC / / / / THERE IS A 1 TO 1 CORRESPONDENCE BETWEEN DEVICE NAMES / GIVEN IN THE BUILD TABLE ENTRIES AND THE PHYSICAL DEVICE / NAMES TO BE USED IN THE SLAVE PROGRAM / / / TEST=0 /TO REMOVE TEST FACILITIES /DEFINE SOME USEFUL CONSTANTS S6000=CLA CLL CML IAC RTR S7775=CLA CLL CMA RTL S7776=CLA CLL CMA RAL S7777=CLA CMA S0003=CLA CLL CML IAC RAL IFNDEF XDEV /SERIAL IO DEVICE ADDRESS XKSF=XDEV+1 /ASSUME MINIMUM TTY INSTR XKCC=XDEV+2 XKRB=XDEV+6 XTSF=XDEV+11 XTCF=XDEV+12 XTLS=XDEV+16 IFDEF KL8J< XKIR=XDEV+5> /TO ENABLE KL8J ERROR READ ON KRB /AC0-3 GET ERROR BITS /MODIFY CODE APPROPRIATELY IF USED /IN INTERRUPT DISABLE MODE !!!! /THE CODE BELOW ENABLES KL8J INTERRUPT /I.E. XKIR WITH AC=3 INSTEAD OF 2 /NOTE: SWD JUMPER MUST BE INSTALLED /AND BOTH ENDS DO THE PARITY TEST /IN THE SAME WAY, IF ENABLED, BY ND /JUMPER ON KL8J. / THESE CODES WERE SELECTED BY TWO CRITERIA: / CODING CONVENIENCE AND SINGLE BIT ERROR DETECTION RESTR=153 /RESTART OPERATION FROM SLAVE ABORT=RESTR-3 /GIVE HANDLER ERR TO CALLER; RCV'ED FROM SLV NACK= 130 /NOT ACK CHAR ACK= NACK-1 /ACK CHAR / *0 /THE HEADER FOR BUILD -NENT / / / NOW SET UP D1, D2 FOR OS8 BUILD FORMAT D1=1510 /TEXT OF 'MH' D3=XDEV&700 /FIRST DIGIT OF NAME D4=XDEV%10&7 /SECOND DIGIT OF NAME D2=D3+D4+6060 /FORM TEXT OF MIDDLE TWO DIGITS OF DEVICE ADDR IFNDEF TABLE IFZERO TABLE-01 < /USE TABLE A D1; D2; DEVICE LTA0; 4030; DEV1&177+4000; 0; 0 D1; D2; DEVICE LTA1; 4030; DEV2&177+4000; 0; 0 D1; D2; DEVICE DTA0; 4030; DEV3&177+4000; 0; 0 D1; D2; DEVICE DTA1; 4030; DEV4&177+4000; 0; 0 D1; D2; DEVICE MTA ; 4200; DEV5&177+4000; 0; 0 D1; D2; DEVICE D8I ; 4030; DEV6&177+4000; 0; 0 D1; D2; DEVICE D12 ; 4030; DEV7&177+4000; 0; 0 D1; D2; DEVICE DSCI; 4030; DEV8&177+4000; 0; 0 D1; D2; DEVICE PTR ; 0010; DEV9&177+4000; 0; 0 D1; D2; DEVICE PTP ; 0020; DEV10&177+4000; 0; 0 D1; D2; DEVICE MTA0; 0200; DEV11&177+4000; 0; 0 D1; D2; DEVICE MTA1; 0200; DEV12&177+4000; 0; 0 /END TABLE A> IFZERO TABLE-02< /USE TABLE B D1; D2; DEVICE LTA0; 4170; DEV1&177+4000; 0; 0 /ON 12 D1; D2; DEVICE LTA1; 4170; DEV2&177+4000; 0; 0 /ON 12 D1; D2; DEVICE DTA2; 4160; DEV3&177+4000; 0; 0 /OTHER DTA0 D1; D2; DEVICE DTA3; 4160; DEV4&177+4000; 0; 0 /OTHER DTA1 D1; D2; DEVICE D8I ; 4050; DEV5&177+4000; 0; 0 /SYS 8I#3 D1; D2; DEVICE D12 ; 4050; DEV6&177+4000; 0; 0 /SYS 12 D1; D2; DEVICE RKA4; 4050; DEV7&177+4000; 0; 0 /RKA1 ON 12 D1; D2; DEVICE DSCI; 4050; DEV8&177+4000; 0; 0 /SYS 8I#1 D1; D2; DEVICE RKA5; 4050; DEV9&177+4000; 0; 0 /RKA1 8I#1 D1; D2; DEVICE PTR ; 2010; DEV10&177+4000; 0; 0 /OTHER PTR D1; D2; DEVICE PTP ; 1020; DEV11&177+4000; 0; 0 /OTHER PTP D1; D2; DEVICE TTY1; 3000; DEV12&177+4000; 0; 0 /OTHER CONSOLE /END TABLE B> NENT=.%10 /NUMBER OF ENTRY POINTS TO THIS HANDLER *200 HAND, /MUST BE AT LOCATION 200 /BECOMES RETURN ADDRESS ENTER, VE /VERSION NUMBER - KEPT IN THIS LOCATION S7776 /SUBTRACT 2 TAD ENTER /RESTORE CLOBBERED JMS AND C177 /GET PAGE ADDRESS OF JMS TAD C3200 /FORM DCA TO ACTUAL ENTRY POINT DCA DCAX /PUT IN DCAX S6000 TAD DCAX /-2000+DCA=TAD ENTRY POINT DCA TADX /MAKE TAD POINT OF CALL TADX, HLT /GET RETURN ADDRESS FROM ENTRY POINT C3200, DCA HAND /HAND NOW CONTAINS RETURN ADDRESS TAD JMSE /RESTORE ENTRY POINT TO JMS ENTER DCAX, HLT /CONTENTS OF DCAX GIVES ENTRY NUMBER RDF TAD CDFCIF /FIX UP EXIT FIELDS DCA EXIT TAD I HAND /TRANSFER PARAMETERS NOW, DCA FUNC /BEFORE CHANGE TO BUFFER DF ISZ HAND STXMSK, 117 /MASK TO EXTRACT ENTRY POINT AND STX TAD I HAND DCA CAPERM /PERMANENT CURRENT ADDR FOR OPERATION ISZ HAND C760, 760 /MASK TO EXTRACT PAGE COUNT TAD I HAND DCA BLK ISZ HAND C177, 177 RESEND, /RESTART OPERATION ALL OVER AGAIN CCDF, CDF 00 INITX, JMP INIT /ONE TIME PAGE INITIALIZE DCA I CKSUMX /ZAP CHECKSUM TAD DCAX AND STXMSK /FORM DEV # AND STX JMS I SENDCX /SEND START OF MSG BYTE /= 100+DEV N0. (100-117) TAD FBX DCA I ADDRX XKCC TAD FUNC AND C70 TAD CCDF DCA FLD /SET TO GO TO BUFFER FLD TAD FUNC CLL RTR AND C760 /MASK OFF # OF PAGES TO TRANSFER CLL RTR IFZERO BLKSIZ-200 /NUMBER OF SEGMENTS TO TRANSFER SZA /KEEP LINK ZERO IF ZERO LENGTH CML /SET LINK FOR TIMEOUT IF NONZERO LENGTH CMA /GET 1'S COMPL OF # OF SEGMENTS DCA SEGCNT /NOW HAVE NUMBER OF SEGMENTS TO XFER IFDEF KL8J< S0003 /SET AC=3 XKIR /AND ENABLE INTERRUPT AND ERROR READ!!!> C70, 70 /A USEFUL CONSTANT AND A NOP,IF PTO8 /USED.I.E.KIA=XKSF + XKRS,COULD SKIP HERE S7776 /-2 FOR HEADER,2 WORDS, FUNC. & BLOCK /# OF WORDS TO SEND,LINK SET FOR NON-Z PAGES JMS I SENDX /SEND TWO WORDS- FUNC AND BLK JMP RESEND /ERROR EXIT FOR NAK RESPONSE DCA I TIMEX /SAY NO TIMEOUT ON FIRST READ TAD CAPERM /GET STARTING CORE ADDR DCA I ADDRX /PLACE WHERE CKEND WILL FIND IT JMP CKEND /CHECK FOR NULL TRANSFER NOW /CALL TO SEND RESETS TTIMEOUT ANYWAY NEXT, /NEXT PAGE TO TRANSFER IN BUFFER REDO, /CHECKSUM/NAK FROM SLAVE CDFCIF, CIF CDF 00 /CURRENT FIELD DCA I CKSUMX /ZAP CHECKSUM TAD CA DCA I ADDRX /SET ADDRESS TO READ/WRITE XCT, FLD, -1 /BECOMES CDF TO BUFFER FIELD TAD FUNC SMA CLA /READ/WRITE TEST JMP RD /IT'S A READ / / ITS A WRITE / ON LAST PAGE OF WRITE, DONT TIME OUT ON ACK/NACK RESP / THIS GIVES THE SLAVE TIME TO CMPLETE THE OPERATION TAD SEGCNT /CHECK FOR SEGCNT=-1; =LAST SEGMENT CLL CML IAC /RESET LINK IF AC=-1 (NO TIMEOUT ALLOWED) KM200, 7600 /NOW JUST CLEAR THE AC TAD KNBLK /GET # OF WORDS TO TRANSFER PER BLOCK JMS I SENDX JMP REDO /NAK RESPONSE FROM SLAVE, RESEND PAGE CKEND, CDF 00 TAD I ADDRX /GET UPDATED CORE ADDRESS DCA CA ISZ SEGCNT /UPDATE SEGMENT COUNTER JMP NEXT /NOT DONE YET, SEND ANOTHER SEGMENT NULL, ISZ HAND /POINT TO 1 BEYOND ERROR EXIT ERR, EXIT, HLT /RETURN TO CALLERS FIELD JMP I HAND PTR, /BECOMES INITIALIZATION TEMP INIT, DCA INITX /ONE TIME INIT CODE CA, /TEMP USED AFTER INITIALIZATION JMS . /FIND OUT WHERE WE ARE INITB, TAD .-1 TAD TBL1P /OFFSET FOR TBL1 DCA PTR XA, TAD I PTR /FIX UP POINTERS FOR CROSS-PAGE REF. SNA /0 ENDS TABLE JMP X /NOW DO TABLE 2 TAD PTR DCA I PTR ISZ PTR JMP XA /LOOP UNTIL DONE TBL1P, TBL1-INITB IFZERO BLKSIZ-200 IFNZRO BLKSIZ-200 /SMALL BLOCK SIZE IFNZRO 340-.&7000 <+=TOO BIG> *340 /THIS LOCATION IS TO GET DEV CODE WITH AND OF 117 DEV0, JMS ENTER /ENTRY POINT FOR RECONFIGURATION DEV1, JMS ENTER DEV2, JMS ENTER DEV3, JMS ENTER DEV4, JMS ENTER DEV5, JMS ENTER DEV6, JMS ENTER DEV7, JMS ENTER DEV8, JMS ENTER DEV9, JMS ENTER DEV10, JMS ENTER DEV11, JMS ENTER DEV12, JMS ENTER JMSE, JMS ENTER TBL2P, TBL2-TBL1 CAPERM, 0 /HOLDS STARTING CORE ADDR FOR OPERATION FUNC, 0 /FUNC AND BLK MUST BE CONTIGUOUS, BLK, 0 /AND IN THIS ORDER RD, /RD ASSUMES A FIXED LENGTH BLOCK SIZE JMS I READX /READ 1 BLOCK JMP REDO /CKSUM ERROR FROM SLV, RESTART OP JMP CKEND /UPDATE BUFFER PNT, PGE CNT ETC / / TAIL END OF INIT, MOVED HERE TO COMPACTIFY X, ISZ XCT /SKIP WHEN NOT DONE JMP INITX /FINISHED INITIALIZING TAD TBL2P /NOW FOR TABL2 ON OTHER PAGE SEGCNT, /TEMP USED AFTER INITIALIZATION JMP INITB /SEGMENT COUNT=PAGE COUNT FOR 200 BLKSIZ IFNZRO 371-.&7000 <+=TOO BIG> *371 /THIS STRANGE LOCATION IS TO GET READC ENTRY TO STOP XFER TABLE TBL1, /THIS TABLE IS THE POINTERS TO 2ND PAGE SENDCX, SENDC-. FBX, FUNC-. ADDRX, ADDR-. SENDX, SEND-. TIMEX, TIME-. READX, READ-. CKSUMX, CKSUM-. PAGE / / READC,SENDC - READ/SEND SINGLE CHARACTERS / KEEPING TRACK OF CHECKSUM / / /READ/SEND - READ AND SEND BUFFERS / ENTER WITH AC=-COUNT / ADDRX=BUFFER ADDRESS / EXIT TO CALL+1 IF ERROR / EXIT TO CALL+2 IF CHECKSUM OK / / /PECULARITIES FOR READ SEND: / SEND: / / EXIT+1 IF NAK RESP / EXIT+2 IF ACK REAP / JMP TO RESEND IF ??? RESP / IF LINK=1 ON ENTRY, ALLOW TIMEOUT OF ACK READ FROM SLV / / / READ: / EXIT+1 IF CKSUM BAD / EXIT+2 IF CKSUM OK / JMP TO ERR (HANDLER ERR) IF ABORT / JMP TO RESEND IF RESTR CODE RECEIVED / JMP TO ERR IF LINE TIMEOUT / TIMEOUT IS DISABLED FOR 1 BYTE BY / SETTING TIME ZERO FOR A DELAY OF 4.5 MIN / / READC, 0 DCA TIMET /ZAP TIMET, ASSUM TIME IS SET RC0, XKSF JMP RC1 XKRB /IF KL8J AVAILABLE, USE ITS STATUS IFDEF KL8J< /STATUS ENABLE MUST HAVE BEEN /SET BY A XKIR,WITH AC10=1 /XKRB READS STATUS TO AC0-3 /AC0 IS "OR" OF ERROR BITS 1-3 SPA /NO ERROR IF POSITIVE /WILL WORK O.K. ON PT08, ALWAYS /SKIPS, NO ERROR TEST JMP RC0 /ERROR, REJECT THIS CHAR /WILL CATCH FALSE HIT & OTHERS /NOTE:BOTH ENDS MUST DO PARITY /OR DO NOT INSTALL NP JUMPER > /END CONDITIONAL AND K177 /USE 7 BITS ONLY DCA SENDC / /A POOR MAN'S SIMULATION OF A FRAMING ERROR,MOST CAUSED /BY A NOISE SPIKE SENSED AS A START BIT,FOLLOWED BY /A RETURN TO MARK..SEEN AS 377, OR RUBBOUT /CHECK FOR FALSE HIT: 177 RCV'D. IGNORE THIS CHAR /MOST OF THE TIME THE REAL CHAR COMES ALONG IFNDEF KL8J< IFNZRO FALSE< TAD SENDC /GET CHAR BACK TAD KM177 /CHECK FOR 177 RCVED SNA CLA /SKIP IF NOT FALSE HIT JMP RC0 /TRY FOR REAL CHAR NOW> > S7775 /NOW RESET TIME TO -3 DCA TIME /FOR NEXT TIME AROUND / THIS SHOULD ALLOW A 10CPS LINE TO RUN OK TAD SENDC TAD CKSUM IFZERO V1A /IF NOT V1A, BUMP CKSUM ONCE PER CHAR DCA CKSUM TAD SENDC TAD MABORT /CHECK FOR ABORT CODE SNA /SKIP IF NOT ABORT JMP EXAB /GIVE HAND ERR TAD AMR /CONST=ABORT-RESTR M130, SNA CLA /HANDY CONSTANT TO HAVE JMP I DOOVER /RESTART CODE TAD SENDC JMP I READC /TIME OUT LOOP TO PRECLUDE SYTEM HANGUPS IF NO RESPONSE / WITHIN A REASONABLE TIME, 0.25 SEC FOR / ACK, NACK DURING BLOCK TRANSFER / MUCH LONGER FOR FIRST READ AND LAST / WRITE TO ALLOW OTHER SYSTEM TO DO THE / WORK. EVEN WORKS WITH CASSETTE AND MTA. RC1, ISZ TIMET JMP RC0 / TAD TIME /IF TIME=0, NEVER TIME OUT / SZA CLA / NOTE THIS SHOULD BE INSERTED FOR / CRITICAL CASES ONLY, ABOVE DOUBLE / ISZ LOOP TAKES CARE OF MOST TIMING / SITUATIONS. ISZ TIME JMP RC0 / / TIME OUT !!! / / EXAB, CLA CMA /SET AC=-1 JMP I RETURN /GIVE HANDLER ERROR SENDC, 0 XTLS XTSF JMP .-1 TAD CKSUM IFZERO V1A /IF NOT V1A, BUMP CKSUM ONCE PER CHAR DCA CKSUM XTCF /CLEAR XMIT FLAG NOW TO SAVE 1 WORD IN OTHER PAGE /A POSSIBLE DELAY FOR TEST PURPOSES ONLY, BETWEEN CHARACTERS IFNZRO DLY< DCA READC ISZ READC JMP .-1> / / / NOW CHECK FOR ^C KSF SKP CLA KRS /READ STATIC.. AND K177 /SCRUB OFF PARITY TAD MCC /CHECK FOR ^C M140, SZA CLA /SKIP IF I FOUND ^C JMP I SENDC /DONE IF NOT ^C CIF CDF 0 /MONITOR IS IN FIELD 0 JMP I (7600 /OS8 MONITOR EXIT SEND2, 0 DCA READ2 TAD READ2 CLL RTR RTR RTR AND K77 JMS SENDC TAD READ2 AND K77 JMS SENDC JMP I SEND2 READ2, 0 JMS READC AND K77 CLL RTL RTL RTL DCA SEND2 JMS READC AND K77 TAD SEND2 JMP I READ2 WC2R, /TEMP FOR READ ROUTINE SEND, 0 DCA WC2S /SAVE WORD COUNT IN TEMP / LINK=1 -> SET TIME TO -3 / LINK=0 -> SET TIME TO 0 SZL CLA S7775 /SET AC=-3 DCA TIME /SET TIMEOUT WORD FOR READ SENDA, TAD I ADDR JMS SEND2 ISZ ADDR K177, 177 ISZ WC2S /CHECK FOR END OF BUFFER JMP SENDA TAD CKSUM CMA /SEND 1'S COMPLEMENT CHECKSUM JMS SEND2 JMS READC /GET RESPONSE TAD MNACK /CHECK FOR NACK SNA JMP I SEND /NAK RETURN ISZ SEND /NOW TRY FOR ACK NMAI /SET AC=0 IF ACK RECV'D SNA CLA JMP I SEND /OK RESPONSE JMP I DOOVER /DONT UNDERSTAND RESP WC2S, /TEMP FOR SEND ROUTINE READ, 0 TAD (-BLKSIZ /ALWAYS TRANSFER BLKSIZ WORDS ON READ DCA WC2R /SAVE WORD COUNT IN TEMP READA, JMS READ2 DCA I ADDR ISZ ADDR K77, 77 ISZ WC2R /TEST FOR END OF BUFFER JMP READA TAD CKSUM /GET CKSUM SO FAR DCA WC2R /SAVE IN WC TEMP JMS READ2 /GET SLAVES CKSUM TAD WC2R /SHOULD BE 7777 CLL IAC /REMEMBER, I USE A 1S COMP CHECKSUM / M150, SZL CLA /IF LINK ZERO RESULT NOT 7777 ISZ READ /BUMP RETURN IF READ OK CML RAL / NOTE LINK=1 IF AC=0 FROM ABOVE IAC / TAD (ACK /ACK RESPONSE /OTHERWISE ACK+1=NACK JMS SENDC /SEND RESPONSE JMP I READ /DONE M3,MCC, -3 /USEFUL CONSTANT TIME, 0 ADDR, 0 CKSUM, 0 TBL2, RETURN, ERR-. DOOVER, RESEND-. TIMET, 0 /ZERO TERMINATES THE TABLE IFNZRO FALSE /FALSE HIT DETECTOR / / NOW DEFINE SOME CONSTANTS FOR ACK/NACK RESTR/ABORT CHECKS / MAKE CLEVER USE OF EXISTING CONSTANTS. IFZERO NACK-130 IFZERO RESTR-ABORT-3 IFZERO ABORT-150 / / IF I GOOFED... IFNDEF MNACK IFNDEF AMR IFNDEF MABORT / / FINALLY NACK-ACK DIFFERENCE: IFZERO NACK-ACK-1 IFNDEF NMAI / PAGE /A QUICK TESTER, ASSEMBLE ,LOAD AND SAVE MH WITH THIS ACTIVATED IFDEF TEST > $