*DECK,NP$N2D *IF,DEF,XFR IDENT NP$N2D ENTRY NP$N2D NP$N2D BSS 1 * * THIS TRANSLATION ROUTINE TAKES ONE CHARACTER AT A TIME * FROM THE NETWORK BUFFER, AND CONVERTS IT TO DISPLAY CODE * IN THE DISK BUFFER. * * ENTRY PARAMETERS : * - ADDRESS OF NETWORK FET * - ADDRESS OF DISK BUFFER FET * - ADDRESS OF CONVERTION TABLE PARAMETER BLOCK. * * THE STRUCTURE OF THE PARAMETER BLOCK IS : * +------------------+ * 1 1 NBUF EMPTY FLAG 1 * + -----------------+ * 2 1 DISKBUF FULL FLAG1 * +------------------+ * 3 1 NCOUNT 1 NO. OF REMAINING CHARS. IN NET BUFFER * +------------------+ * 4 1 NBYTE 1 * +------------------+ * 5 1 DBIT 1 * +------------------+ * 6 1 STATE OF CONVER. 1 * +------------------+ * 7 1 CONVER. TBL ADDR.1 * +------------------+ * 8 1 STEPSIZE (6/12) 1 * +------------------+ * * NBYTE - NUMBER OF BITS TO SHIFT CURRENT NETWORK WORD TO GET * CURRENT CHARACTER AT RIGHT MOST LOCATION. * COUNTS FROM 8 (12 IF WORD BEGINS WITH HALF CHARACTER) * STEP 8 UNTIL 64 (60) * DBIT - NUMBER OF BITS TO SHIFT A CHARACTER FROM RIGHTMOST * LOCATION TO CURRENT REQUIRED IN DISKBUF. * FOR DISPLAY CODE FILES : STARTS WITH 54 STEP -6 UNTIL 0 * DISK ASCII FILES : STARTS WITH 48 STEP -12 TILL 0 * STATE - 0 = ALL DONE IN PREVIOUS ENTRY. * 1 = ZERO WORD REQUIRED * 2 = LAST CHARACTER WRITTEN WAS (:) (SO THAT IF A *US* * ARRIVES WE FIRST WRITE A BLANK, THAN A Z-BYTE) * * * THE PRESETTING INCLUDES : * * A1 - ADDRESS OF NET FET+1 (*IN* POINTER) * A2 - ADDRESS OF DISK FET+1 (*IN* POINTER) * A4 - POINTER TO DISK BUFFER *IN* WORD. * A5 - POINTER TO NET BUFFER *OUT* WORD. * * X4 - ACCUMULATING THE WORD TO BE WRITTEN TO DISKBUF * X5 - CURRENT NETBUF WORD POINTED BY *OUT* (WORKING WORD) * * B1 - 1 * B2 - ADDRESS OF FIRST ENTRY IN CONVERSION TABLE * B3 - STATE OF CONVERSION * B4 - DBIT * B5 - NBYTE * B6 - COUNT * SB1 1 SA2 A1+B1 SA3 A2+B1 * * THE PARAMETERS PASSED ARE WORDS CONTAINING THE A D D R E S S * OF THE REQUIRED PARAMETERS (FETS,PARAMETER-BLOCK) * SA1 X1 GET POINTER TO ACTUAL PARAMETER SA2 X2 SA3 X3 SA1 X1+B1 POINT TO NFET WORD CONTAINING *IN* SA5 A1+B1 NFET WORD CONTAINING *OUT* SA5 X5 ADDRESS OF *OUT* OURD IN NETBUF SA2 X2+B1 POINT TO DFET WORD CONTAINING *IN* SA4 X2 ADDRESS OF *IN* WORD OF DISK BUF BX6 X3 SAVE PARAM TABLE ADDRESS SA6 PARAM MX6 0 SA6 X3 SET TO 'NETBUF AVAILABLE' INITIAL STATE SA3 X3+B1 GET THE 'DISKFULL' INDICATOR SA6 A3 SET TO 'DISK AVAILABLE' INITIAL STATE SA3 A3+B1 WORD NUMBER 3 IN TABLE SB6 X3 NCOUNT SA3 A3+B1 WORD NUMBER 4 IN TABLE SB5 X3 NBYTE SA3 A3+B1 SB4 X3 DBIT (WORD 5 ) SA3 A3+B1 STATE INTO X3 FROM WORD 6 SB3 X3 B3=1 IS Z-WORD REQUIRED * B3=2 IS LAST CHAR IN NETBUF WAS : * SA6 A3 RESET THE STATE IN PARAMETER BLOCK SA3 A3+B1 WORD 7 - CONVERSION TABLE ADDRESS SB2 X3 SA3 A3+B1 WORD 8 = STEP SIZE IN DISKBUF (6 OR 12) BX6 X3 SA6 STEP * COMPARE *OUT* AND *FIRST* TO SEE IF IT IS FIRST TIME ENTRY SA3 A1-B1 POINT AT FET WORD CONTAINING *FIRST* SB7 X3 *FIRST* ADDRESS IN B7 SB7 A5-B7 *NETBUF *OUT* - *FIRST* NE B0,B7,READBLK0 * * YES,IT IS FIRST TIME ENTRY. FIRST BLOCK HAS A TBH(6 OCTETS) * MX0 48 BX5 -X0*X5 SB6 X5 NUMBER OF CHARS FROM ABH SB6 B6-6 DECREMENT THE NBH SIZE SB5 56 SA5 A5+B1 MOVE *OUT* TO FIRST WORD OF DATA READBLK0 BSS 0 ******* * * CHECK IF WE STILL HAVE ROOM IN *DISKBUF* SO THAT WE CAN GO * ON WITH THE PROCESS. * 1. CHECK IF *B4* SHOWS NEW CHARACTER IN WORD. * 2. CHECK IF *IN+1* = *OUT*. * * IF B O T H CONDITIONS OCCUR THAN WE USED ALL DISK SPACE WE * COULD, WE FLAG THE *DISKFULL* AND QUIT. ******** SX0 A4+B1 *IN+1* (X0) SA3 A2+B1 POINT TO DFET CONTAINING *OUT* POINTER MX6 42 BX0 -X6*X0 BX7 -X6*X3 ADDRESS OF DISKBUF *OUT* WORD (X7) SA3 A3+B1 POINT TO DFET CONTAINING *LIMIT* POINTER BX3 -X6*X3 ADDRESS OF DISKBUF *LIMIT* POINTER (X3) BX3 X0-X3 DISKBUF *IN+1* - *LIMIT* NZ X3,ENDW2 SKIP THE FOLLOWING IF *IN+1*.NE.*LIMIT* SA3 A2-B1 POINT TO DFET WORD CONTAINING *FIRST* BX0 -X6*X3 ADDRESS OF *FIRST* REPLACES *IN+1* ENDW2 BX6 X0-X7 CHECK IF *IN+1* = *OUT* * NEW *IN+1* ADDRESS NOW IN X0 BX7 X0 SA7 NEXTIN SAVE FOR NEXT WORD ADVANCE SA3 STEP SB7 X3 SB7 B7-60 SETTING FOR FIRST CHARACTER IN DISK WRITE SB7 B0-B7 NE B4,B7,ENTER1 IF NOT 1ST CHARACTER OF A WORD NZ X6,ENTER1 IF *IN+1* .NE. *OUT* * DISK FULL, SO WE CAN NOT GO TO NEXT WORD FOR WRITE DISKFUL SX6 1 SA3 PARAM SA6 X3+B1 SET FLAG OF *DISK BUFFER FULL* (WORD 2) MX6 0 SA6 A4 CLEAN WORD WE HAD NO CHANCE TO WRITE EQ NEXIT * ********** * * IF COUNT=0 READ NEXT BLOCK (OR RETURN IF LAST BLOCK) * ENTER1 BSS 0 * * CHECK FOR SPECIAL ENTRIES : * B3 = 1 - A ZERO WORD IS REQUIRED IN *DISKBUF* * B3 = 2 - LAST CHARACTER IN *DISKBUF* WAS A COLON (:) * EQ B3,B1,ZRBYT1 TO WRITE A ZERO WORD READBLK NE B6,B0,NEXT SB7 X1 NETBUF *IN* ADDRESS SX6 A5-B7 NETBUF *OUT* - *IN* NZ X6,NEXT2 * *IN* = *OUT* - NETWORK BUFFER EMPTIED. SA3 PARAM SX6 1 SET FLAG 'NETWORK BUFFER EMPTY' SA6 X3 ADDRESS ON FLAG LOCATION BX7 X4 SA7 A4 FLUSH OUT LAST CHARACTERS ACCUMULATED EQ NEXIT * ANOTHER BLOCK EXISTS IN NETBUF (BLK OR MSG) NEXT2 SA5 A5+B1 ADVANCE THE POINTER TO NETBUF *OUT* WORD MX0 48 BX5 -X0*X5 EXTRAXT TLC FROM BIT 48 THR 59 SB6 X5 GET COUNT FROM TLC OF ABH SA5 A5+B1 POINT TO FIRST WORD OF DATA AREA SB5 8 SET TO 1ST CHARACTER IN WORD * *********** * GET THE NEXT CHARACTER TO BE TRANSLATED NEXT SB7 64 NE B5,B7,REGBYTE IF NBYTE.NE.64 GO TO REGBYTE * * WE HAVE A BYTE SPLIT BETWEEN TWO WORDS (NBYTE = 64) * MX0 56 BX3 -X0*X5 SAVE RIGHTMOST 4 BITS (BIT 7 FORCED TO 0) LX3 4 AND PUT THEM IN BITS 4-7 SA5 A5+B1 ADVANCE TO NEXT WORD FOR 2ND HALF * * NOW COMBINE WITH PREVIOUS 4 BITS * MX0 4 BX6 X5*X0 LX6 4 TO MOVE THEM FROM LEFT TO RIGHT BX7 X3+X6 COMBINE AND REMEMBER IN *X7* SB5 12 START COUNTING FROM 12 (NOT 8) EQ TBLENT * * REGULAR ASCII BYTE (ALL IN THE SAME WORD) * REGBYTE LX3 B5,X5 GET ASCII CHAR TO RIGHTMOST BYTE MX0 52 KEEP LEFTMOST PARITY BIT BX7 -X0*X3 CHAR MASKED AT RIGHTMOST BITS OF *X7* SB5 B5+8 GET READY FOR NEXT BYTE * * IF NBYTE BECAME 68 RESET AND MOVE TO NEXT WORD OF NETBUF * SB7 B5-68 LT B7,B0,TBLENT ***** * WE ARE AT THE LAST CHARACTER IN THE WORD * SB7 X1 NETBUF *IN* WORD ADDRESS SB7 A5-B7 NETBUF *OUT* - *IN* EQ B7,B0,TBLENT GO TO TBLENT IF NETBUF EMPTY(IN=OUT) * * NOT END OF BUFFER YET. GET NEXT WORD AND POSITION READY * SA5 A5+B1 SB5 8 ***** * GET CHAR USING OFFSET OF CHARACTER STORED IN X7 PREVIOUSLY * TBLENT SB6 B6-B1 DECREMENT CHARACTER COUNTER SA3 STEP SX3 X3-6 ZR X3,TBLENT1 8/8 TO DISPLAY CODE (6) CONV. * * ASCII (12 BITS) CONVERSION. * SB7 X7-37B 37B IS ASCII *UNIT SEPARATOR* EQ B0,B7,ZRBYT * * ONLY SPECIAL CASING IS NULL THAT GOES FROM 0000 TO 4000 * NZ X7,NORM MX7 1 LX7 12 X7 = 4000B EQ NORM TBLENT1 SA3 X7+B2 CONV. TBL. ADDR. + THE OFFSET FOUND MX0 12 BX6 X3*X0 FUNCTION INTO X6 MX0 48 BX7 -X0*X3 VALUE OF DISPLAY CODE/ASCII12 INTO X7 NG X6,SPECIAL SB3 B0 CLEAR POSSIBLE 'COLON READ' INDICATOR NORM LX7 B4 SHIFT VALUE TO CURRENT LOCATION BX4 X7+X4 ADD NEW CHARACTER EQ B0,B4,ENDW * NOT E-O-L YET. JUST GET NEXT LOCATION SA3 STEP SB7 X3 STEP 6 OR 12 DEPENDING ON TRANSLATION MOD SB4 B4-B7 EQ READBLK FOR NEXT CHARACTER FROM NETWORK ENDW BX7 X4 SA7 A4 STORE WORD JUST COMPOSED INTO DISKBUF SA4 NEXTIN SA4 X4 ADVANCE FOR NEXT WORD TO USE MX4 0 PRESET FOR NEXT ACCUMULATION * * SET *B4* TO THE FIRST CHARACTER SHIFT AMOUNT FOR NEXT WORD * SA3 STEP SB7 X3 SB4 60 SB4 B4-B7 STEP 6 OR 12 DEPENDING ON TRANSLATION MOD EQ READBLK0 * * SPECIAL CASES SECTION * SPECIAL MX0 1 BX3 -X0*X6 CLEAR LEFTMOST BIT OF FUNCTION (X'800') NZ X3,SP1 * CODE = '800' JUST DELETE CHARACTER SB3 B0 CLEAR THE 'COLON READ' INDICATOR EQ READBLK GET NEXT CHARACTER SP1 LX3 11 X'001' BX3 -X0*X3 NZ X3,COLON ONLY POSSIBILITY LEFT (X'803') *---------- CODE IS X'801' = Z-BYTE ----------------- ZRBYT SB7 B1+B1 NE B3,B7,ZRBYT1 IF LAST CHAR WAS NOT COLON SX7 55B LAST CHAR COLON. SUFFIX A BLANK CHAR LX7 B4 MOVE TO CURRENT REQUESTED LOCATION BX4 X7+X4 INSERT INTO WORKING OUTPUT REGISTER. SA3 STEP SB7 X3 STEP 6 OR 12 DEPENDING ON TRANSLATION MOD SB4 B4-B7 GET READY FOR NEXT LOCATION ZRBYT1 SB3 B0 CLEAR POSSIBLE 'LAST CHAR WAS COLON' SA3 STEP SX3 X3-12 TO CHECK IF ASCII MOD ZR X3,ENDW ONLY ONE ASCII CHAR WILL DO AS A Z-BYTE GE B4,B1,ENDW OR AT LEAST 2 DISPLAY CODE SB3 1 SIGNAL ANOTHER ZERO WORD IS REQUIRED EQ ENDW COLON SB3 B1+B1 RECORD INTERNALLY THE EVENT EQ NORM GO INSERT CHARACTER * * STORE VARIABLES IN TABLES AND RETURN * NEXIT SA3 PARAM RESERVE VARIABLES IN TABLE SX6 B6 SA6 X3+2 SAVE NCOUNT ( WORD 3 OF PARAM TABLE) SX6 B5 SA6 A6+B1 SAVE NBYTE (IN WORD 4) SX6 B4 SA6 A6+B1 SAVE DBIT (IN WORD 5) SX6 B3 RECORD THE STATE OF DISKBUF SA6 A6+B1 STORE IN WORD 6 OF PARAMETER BLOCK * * SAVE A4 (*IN* POINTER OF DISKBUF) BACK IN FET * NEXIT2 MX0 42 SA2 A2 ADDRESS OF DFET WORD WITH *IN* POINTER BX2 X2*X0 MASK OUT OLD POINTER MX3 0 SX3 A4 NEW *IN* ADDRESS BX7 X2+X3 INSERT ADDRESS TO WORD SA7 A2 WRITE BACK * * SAVE A5 (*OUT* POINTER OF NETBUF) BACK INTO FET * SA3 A1+B1 NFET WORD CONTAINING *OUT* BX3 X3*X0 MASK OUT OLD ADDRESS MX2 0 SX2 A5 NEW ADDRESS BX6 X2+X3 INSERT NEW ADDRESS TO WORD SA6 A3 WRITE BACK EQ NP$N2D PARAM BSSZ 1 STEP BSSZ 1 NEXTIN BSSZ 1 END *ENDIF