
      HED  FORMATTER UTILITY ROUTINES 
      ORG 56000B
**                               ** 
***  MAKE A NUMBER LESS THAN 1  *** 
**                               ** 
* 
*  MULTIPLY AN UNPACKED FLOATING POINT
*  NUMBER IN MANT1, MANT2 AND EXP BY 10 UNTIL 
*  IT IS GREATER THAN 1.  THEN DIVIDE BY 10 
* 
#MTG1 JSB MBY10 
      LDA EXP         MULTIPLY
      CMA,SSA,INA,SZA   NUMBER BY 10
      JMP *+3             UNTIL IT IS 
      ISZ EXPON             GREATER 
      JMP MTG1+1              THAN 1
      JSB DBY10     DIVIDE BY 10
      JMP MTG1,I
* 
*  DIVIDE AN UNPACKED FLOATING POINT NUMBER 
*  IN MANT1, MANT2 AND EXP BY 10 UNTIL IT IS
*  LESS THAN 1
* 
#DTL1 LDA EXPON 
DTL10 LDB EXP       DIVIDE
      CMB,INB         NUMBER
      SSB,RSS           BY 10 
      JMP DTL1,I          UNTIL 
      STA EXPON             IT IS 
      JSB DBY10               LESS
      CCA                       THAN
      ADA EXPON                   1 
      JMP DTL10 
      SKP 
**                        **
***  ROUND ASCII NUMBER  ***
**                        **
* 
*  NUMBER STORED ONE ASCII DIGIT PER WORD IN
*  HOLDING BUFFER.  ROUTINE GETS NEXT DIGIT 
*  AND ROUNDS IF IT IS >= 5.
*  IF THERE IS A CARRY TO AN EXTRA DIGIT AND NO 
*  ROOM EXISTS, EXIT IS TO (P+1).  OTHERWISE RETURN 
*  TO (P+2).
* 
#RUND JSB GETDG     GET NEXT DIGIT
      ADA .-5       IS IT >= 5 ?
      SSA 
      JMP ROUND,I 
      CCA           DECREMENT HOLD
      ADA HBP         BUFFER POINTER
ROND1 LDB 0,I       LOAD NEXT DIGIT 
      INB           INCREMENT IT
      CPB .58       WAS IT A 9 ?
      JMP *+3       YES 
      STB 0,I       NO, SAVE IT 
      JMP ROUND,I     AND RETURN
      LDB .+60B     OVERLAY 
      STB 0,I         A 0 
      CPA IHB       LEADING DIGIT ? 
      JMP *+3       YES 
      ADA .-1       NO, DECREMENT POINTER 
      JMP ROND1 
      LDB .+61B     OVERLAY A 
      STB 0,I         ONE 
      LDB .+60B     LOAD
      STB HBP,I       EXTRA ZERO
      LDB EFLAG     FLOATING POINT
      SZB             SPECIFICATION ? 
      JMP ROND2     NO
      ISZ EXPON     INCREMENT EXPONENT
      NOP 
      JMP ROUND,I 
ROND2 CCB          IS NBLK
      ADB NBLK        LESS
      SSB               THAN 1 ?
      ISZ ROUND     NO, RETURN TO (P+2) 
      STB NBLK      YES, KEEP DECREMENTED VALUE 
      JMP ROUND,I 
      SKP 
**                   ** 
***  OUTPUT BLANKS  *** 
**                   ** 
* 
*  OUTPUTS THE NUMBER OF BLANKS SPECIFIED 
*  BY THE NEGATIVE OF REPCT.  THE STACK POINTER 
*  IS INCREMENTED AND REPCT HAS THE VALUE ZERO
*  UPON EXIT. 
* 
#OTBL ISZ FSP       INCREMENT STACK POINTER 
      LDA BLANK     OUTPUT A
      JSB OUTCR       BLANK 
      ISZ REPCT     REPCT USED UP ? 
      JMP *-3 
      JMP OUTBL,I 
* 
*     OUTPUT X-OFF, CARRIAGE RETURN, LINE FEED
* 
#OTCL EQU * 
      LDA .+23B 
      JSB OUTCR 
      LDA .+15B 
      JSB OUTCR 
      LDA .+12B 
      JSB OUTCR 
      CLA 
      STA CHRCT 
      JMP OUTCL,I 
      SKP 
**                                       ** 
***  SEARCH FOR A DELIMITING CHARACTER  *** 
**                                       ** 
* 
*  BEGINS SEARCH AT CHARACTER DP.  WHEN A COMMA 
*  OR SLASH IS FOUND, DP IS SET TO POINT TO THAT
*  CHARACTER.  CHARACTERS ARE COUNTED AND IF THE
*  END OF THE STRING IS ENCOUNTERED BEFORE A
*  DELIMITER IS FOUND, A FLAG IS SET
* 
#DSCH LDA DP        SET STRING POINTER TO 
      STA FST         FIRST CHARACTER 
      CLO           DON'T IGNORE BLANKS 
SER1  JSB MCHAR     GET STRING CHARACTER
      CPA .+54B     IS IT A COMMA ? 
      JMP DSRCH,I   YES 
      CPA .+57B     NO, IS IT A SLASH ? 
      JMP DSRCH,I   YES 
      CPA .+51B     NO, IS IT A RIGHT PARENTHESIS ? 
      JMP DSRCH,I   YES 
      ISZ DP        NO,INCREMENT DELIMITER POINTER
      ISZ CC        AND CHARACTER COUNTER 
      LDA DP
      LDB CC
      CPB NCH       ALL CHARACTERS USED ? 
      JMP DSRCH,I   YES 
      JMP SER1      NO
**                          **
***  MASK OUT A CHARACTER  ***
**                          **
* 
*  GET NEXT CHARACTER FROM FORMAT STRING
*  ADDRESS OF CHARACTER IS IN (A).  CHARACTER IS
*  RETURNED IN (A)
* 
#MCHR CLE,ERA       SHIFT ADDRESS RIGHT 
      LDB 0,I       LOAD WORD FROM STRING 
      SEZ,RSS       HIGH CHARACTER ?
      BLF,BLF       YES, SWITCH POSITIONS 
      LDA 1         NO
      AND B377      MASK OUT LOW CHARACTER
      SOS           SHOULD BLANKS BE IGNORED ?
      JMP MCHAR,I 
      CPA BLANK     YES, IS CHARACTER A BLANK ? 
      JMP MCHR1     YES 
      ADA M96       NO
      SSA,RSS       LOWER CASE? 
      ADA M32       YES 
      ADA .140      NO
      JMP MCHAR,I 
MCHR1 EQU * 
      ISZ FST       INCREMENT STRING POINTER
      LDA FST       NEXT CHARACTER
      CPA DP          A DELIMITER ? 
      JMP MCHAR,I   YES, RETURN 
      JMP MCHAR+1   IGNORE THE BLANK
**                         ** 
***  EVALUATE EXPRESSION  *** 
**                         ** 
* 
*  EXTRACT THE NEXT VARIABLE TO BE OUTPUT BY THE FORMATTER. IF
*  NONE FOUND, EXIT TO (P+1).  IF A STRING IS FOUND, EXIT TO
*  (P+2) AFTER PREPARING THE STRING FOR OUTPUT.  IF A NUMERIC 
*  QUANTITY IS FOUND, EXIT TO (P+3) WITH THE NUMBER IF (A) AND (B). 
*  EDSTA IS SET TO 0 IF THIS IS THE LAST VARIABLE IN THE STATEMENT. 
* 
#EVEP EQU * 
      LDA FFLG      MAT 
      SSA             PRINT?
      JMP EVEX5     YES 
EVEX0 LDB TEMP1 
      CPB PRGCT     END OF STATEMENT? 
      JMP EVEXP,I   YES 
      CCA           TURN OFF
      STA EOL         FUNCTION FLAG 
      JSB FORMX     EVALUATE FORMULA
      LDB OPDST,I   IS IT A 
      SSB             STRING VARIABLE ? 
      JMP EVEX3     YES 
      JSB OPCHK     NO, UNSTACK VALUE ADDRESS 
      ISZ EOL       A FUNCTION ?
      JMP EVEX0 
      LDA TEMP1     LAST VARIABLE?
      CPA PRGCT 
      CLA           YES 
      STA EDSTA     NO
      DLD 1,I       NO, LOAD NUMBER 
      ISZ EVEXP     RETURN TO (P+3) 
      JMP EVEX4 
EVEX3 LDA .-2       PREPARE 
      JSB PSTR        PRINT 
      STA TEMP4         STRING
      STB TPRME 
      LDB TEMP1     END OF
      CPB PRGCT       STATEMENT?
      CLB           YES 
      STB EDSTA     NO
      LDB TPRME 
EVEX4 EQU * 
      ISZ EVEXP     RETURN TO 
      JMP EVEXP,I     (P+2) 
EVEX5 ISZ ELCNT     FINISHED CURRENT MATRIX?
      JMP EVEX7     NO
EVEX6 LDB TEMP1     YES 
      CPB PRGCT     END OF STATEMENT? 
      JMP EVEXP,I   YES 
      LDA TEMP1,I   GET NEXT OPERAND
      AND OPDMK 
      SZA,RSS       NULL
      JMP EVEXP,I   YES 
      SSA           NO, FUNCTION? 
      JMP EVEX8     YES 
      ALS           NO, LOAD
      ADA SYMTB       BASE ADDRESS
      ADA .-1           OF ARRAY
      LDB A,I 
      ADB .-2       SAVE POINTER TO 
      STB SBPTR       DYNAMIC DIMENSIONS
      JSB VCHK      VALIDATE ARRAY ELEMENTS 
      LDA SBPTR,I   SET POINTER 
      ISZ SBPTR       TO FIRST ELEMENT
      MPY SBPTR,I       OF ARRAY
      ISZ SBPTR           WHILE COMPUTING 
      CMA,INA               NUMBER OF 
      STA ELCNT               ELEMENTS
      ISZ TEMP1     BUMP TO NEXT OPERAND
EVEX7 CCA           LAST
      CPA ELCNT       ELEMENT?
      RSS           YES 
      JMP EVEX9     NO
      LDA TEMP1     END OF
      CPA PRGCT       STATEMENT?
      CLA           YES 
EVEX9 EQU * 
      STA EDSTA     NO
      DLD SBPTR,I   GET NUMBER
      ISZ SBPTR     BUMP TO 
      ISZ SBPTR       NEXT ELEMENT
      ISZ EVEXP 
      JMP EVEX4     EXIT
EVEX8 CCA           TURN OFF
      STA EOL         FUNCTION FLAG 
      JSB FORMX     EVALUATE FUNCTION 
      JSB OPCHK     REMOVE ARGUMENT FROM TEMP STACK 
      JMP EVEX6     GET NEXT OPERAND
* 
*     MESSAGE BUFFER
* 
MSQHD BSS MESBN 
      BSS 0 
* 
RVRSL ASC 1, \
TBITS OCT 160000
B120K OCT 120000
B130K OCT 130000
B160K EQU INI 
BKSPC OCT 137 
TTA   BSS 1 
TTB   BSS 1 
TTE   BSS 1 
TOG   BSS 1 
TADR  BSS 1 
      HED POWER FAIL/RESTART ROUTINE
* THE POWER FAIL/RESTART ROUTINE INSURES A LOGICAL SHUTDOWN AND 
* RESTART OF THE SYSTEM IN CASE OF POWER FAIL.
      SPC 1 
POW   NOP           INTERRUPT ENTRY POINT.
      SFC 4         TEST FOR FAIL OR RESTART. 
      JMP POW1      TRANSFER TO RESTART SECTION.
* 
* POWER FAIL SECTION. 
* 
      DST POWI      SAVE REGISTERS TEMPORARILY. 
      ERB,BLS 
      SOC 
      INB 
      CLA           IF POWFF WAS NONZERO, 
      CPA POWFF      INTERRUPT WAS FROM POWER FAIL. 
      JMP *+3 
      STA POWFF 
      JMP POW2
* 
      LDA POW       TEST FOR INTERRUPT OUT OF 
      ADA POWD1      RESTART SECTION. 
      SSA 
      JMP *+4       NORMAL FAIL.
      ADA POWD2 
      SSA 
      JMP POW2      FAILED FROM RESTART SECTION.
* 
      STB POWEO     NORMAL FAILURE--SAVE REGISTERS. 
      DLD POWI
      DST POWAB 
      LDA POW 
      STA POWP
      LIA 01        LOAD AND SAVE 
      STA POWSW       THE SWITCH REGISTER 
* 
      CLA          GET FLAGS FOR ALL DEVICES THAT 
*                                  CAN INTERRUPT. 
      SFC CH2       CHECK SEND CHANNEL
      IOR .+2       BIT 1 FOR CHANNEL 11
      SFC ?SC      CHECK FLAG ON CONSOLE TTY. 
      IOR .+4       BIT 2 FOR TTY 
      SFC CLOCK    CHECK TIME BASE GENERATOR
      IOR .+20B     BIT 4 FOR TIME BASE GENERATOR 
      STA POWFL 
      CLB 
      SFC 0         IF INTERRUPT IS SET, STORE
      LDB STF0       STF 0 INTO POWND; ELSE NOP.
      STB POWND 
* 
POW2  CLC 4         SET FOR RESTART.
      HLT DEATH+36B 
      SPC 2 
* RESTART SECTION 
      SPC 1 
POW1  STC 4         RESET FOR POWER FAIL. 
      LDA POWSW     FETCH AND RESTORE 
      OTA 01          THE SWITCH REGISTER 
      LDA .+7       INITIALIZE J AS A POWER FAIL POIN-
      STA POWJ       TER AND I AS DMA POINTER.
      INA 
      STA POWI
      LDA .+3       RESET CLOCK FREQUENCY.
      OTA CLOCK 
      LDA POWFL     COPY FLAGS. 
      STA POWF
      LDB TBITS     IF ASR-35 FLAG WAS CLEAR, SET UP
      AND .+4       THE CORRECT STATE OF THE ASR35
      SZA,RSS      OTHERWISE LEAVE IT SET IN THE
      OTB ?SC       INPUT STATE.
* 
* NOW TEST THE INDIVIDUAL IO FLAGS. IF A FLAG WAS CLEAR, WE PERFORM 
* A CLF OPERATION. IF IT WAS SET, WE TAKE STRONGER ACTION.
* 
POW4  LDA POWF      GET WORD CONTAINING FLAGS. THE
      RAR           ONE TO BE TESTED IS IN BIT 0 AND
      STA POWF      I= ITS SELECT CODE. 
      SSA 
      JMP POW5      FLAG SET. 
* 
      LDA POWI      PRODUCE CLF INSTRUCTION.
      ADA CLF0
      STA *+1 
      NOP           EXECUTE CLF.
POW6  LDA POWI      TEST FOR DONE.
      CPA .+14B     CHECK FOR CLOCK LOCATION
      JMP POW14     DONE. 
      ISZ POWI      OTHERWISE, BUMP I AND LOOP. 
      JMP POW4
* 
* FLAG WAS SET. TEST IF ROUTINE HAD ACTUALLY BEEN 
* ENTERED. IF SO, PERFORM A DUMMY INTERRUPT TO PRE- 
* VENT IT FROM BEING REENTERED. 
* 
POW5  LDB POWTB     COMPUTE LOCATION OF RETURN AD-
      ADB POWJ       DRESS OF HIGHEST PRIORITY ROU- 
      LDB 1,I         TINE NOT YET TESTED.
      LDA 1,I       GET ITS RETURN ADDRESS
      LDB POWTB 
      ADB POWI      POINT TO RET.ADR. OF TEST ROUTINE 
      CMA           TEST FOR INTERRUPT OUT OF THAT
      ADA 1,I         ROUTINE.
      SSA,RSS 
      JMP POW6      NO--INTERRUPT WAS PENDING.
ADB5  ADB .+5       BUMP INDEX REGISTER 
      ADA 1,I 
      SSA 
      JMP POW6      NOT INTERRUPTED.
* 
* PERFORM DUMMY INTERRUPT TO PREVENT AN UNWANTED ONE LATER. 
* 
      LDA ADB5      PLACE ADB5 IN INTERRUPT CELL
      STA POWI,I
      LDA POWI
      ADA STC0      SET UP STC AND CLC. 
      STA POWST 
      XOR B4000     CREATE CLC. 
POWST STC 0         SET DEVICE CONTROL
STF0  STF 0         ENABLE INTERRUPT CAUSING ADB5 TO
      STA POWCL     COMPUTE ADR. OF CORRECT INT. VAL) 
CLF0  CLF 0         DISABLE INTERRUPT.
POWCL CLC 0         DISABLE DEVICE. 
      LDA 1,I       GET CORRECT INTERRUPT CONTENTS
      STA POWI,I    STORE IN INTERRUPT CELL.
      LDA POWI      UPDATE INTERRUPT CHAIN
      STA POWJ       POINTER. 
      JMP POW6      GO TEST NEXT DEVICE.
* 
***  HAVE DONE ALL DUMMY INTERRUPTS.
***   SET CONTROL ON CLOCK AND TTY. 
***    AND RESTART INTERCONNECT.
* 
POW14 EQU * 
      STC CH1,C    RESTART FIRST CHANNEL
      LDA SVCH2    PUT WORD BACK OUT ON CH2 
      OTA CH2 
      STF CH2 
      LDA POWFL    LOAD FLAG WORD 
      AND .+2       LEAVE BIT 1 
      SZA,RSS      SKIP IF FLAG SET 
      STC CH2,C    OTHERWISE, TELL OTHER MACHINE
      CLC CH2      WANT NO INTERRUPT
      STC CLOCK 
      STC ?SC 
      LDA TBITS     RE-ESTABLISH PREVIOUS 
      OTA ?SC       STATE OF ASR35
      ISZ POWFF     SET IN CASE OF ANOTHER PF 
      LDA POFFP     GET POINTER TO POWFF
      LDB POWP      GET POWER FAIL LOCATION 
      JSB DREDP,I   GO DO DISC STUFF
      CLA 
      STA POWFF     SAY NOT RESTARTING
***  RESTORE REGISTERS. 
      LDA POWEO     'E' AND OVERFLOW
      CLO 
      SLA,ELA 
      STO 
      DLD POWAB 
***  RESET INTERRUPT SYSTEM TO SAME AS BEFORE FAIL. 
POWND NOP           OR STF 0. 
      JMP POWP,I   RETURN.
POW40 EQU * 
* 
POWFF NOP           SET TO 1 DURING DISC RECALL.
POWI  BSS 1         POINTER TO DEVICE BEING TESTED. 
POWJ  BSS 1         POINTER TO INTERRUPT CHAIN. 
POWAB BSS 2         TEMPS TO HOLD VALUES OF A&B.
POWEO BSS 1         TEMP TO HOLD VALUE OF E&O.
POWP  BSS 1         TEMP TO HOLD VALUE OF P 
POWFL BSS 1         TEMP TO HOLD STATE OF I/O FLAGS.
POWF  BSS 1         COPY OF POWFL.
POWSW BSS 1         TEMP TO HOLD SWITCH REGISTER
* 
POWTB DEF *-6       POINTER TO FOLLOWING TABLE
* 
*         THIS TABLE POINTS TO THE ENTRY POINTS FOR 
*         THE INTERRUPT ROUTINES. 
* 
      DEF POWP      POWER FAIL RTN.ADR. 
      DEF R14CM     INTERCONNECT RETURN ADDRESS 
      DEF R14CM 
      DEF ?TT2      TTY RTN.ADR.
      BSS 1         NO INTERRUPT OCCURS ON THIS CHN.
      DEF CLKIN     CLK RTN.ADR.
* 
* 
*         THIS SECTION GIVES THE LENGTH OF EACH ROUTINE 
*         SO THAT POWER FAIL CAN DETERMINE WHETHER
*         THAT ROUTINES INTERRUPT HAD ACTUALLY OCCURRED 
*         OR WAS STILL PENDING AT THE TIME OF THE POWER FAILURE.
* 
      ABS R14ED-R14CM 
      ABS 0         NO SUCH ROUTINE 
      ABS TTYED-?TT2+1   WITHIN INTERRUPT 
      BSS 1         NO INTERRUPT OCCURS ON THIS CHN.
      ABS CLKED-CLKIN+1   ROUTINES. 
* 
      JSB R14DR,I 
      HLT DEATH+11B 
      JSB T35DR,I 
      CLC 13B,C 
      JSB CLKDR,I 
* 
POWD1 ABS -POW1 
POWD2 ABS POW1-POW40
STC0  STC 0 
POFFP DEF POWFF 
