 HED " SPECIFICATION
**********************************
*     QTYPE HANDLES "-CONVERSION *
**********************************
QTYPE CLA           SET FOR NO
      STA DBLNK      SKIPPING 
      STA DCOMA 
      LDA FCR       SAVE FCR FOR
      STA TEMP2     REPEATS 
QLOOP JSB FCHAR     GET FORMAT CHARACTER
      CPA QUOTE     CHECK FOR QUOTE 
      JMP QUOT1     JMP FOR SPECIAL HANDLIG 
      JSB IOCHK 
      JMP *+3 
      JSB INCHR 
      JMP QLOOP 
      JSB OUTCR 
      JMP QLOOP 
QUOT1 JSB RFCHK     CHECK THE REPEAT COUNT
      LDA TEMP2     RESTORE FCR 
      STA FCR         AND 
      JMP QLOOP         LOOP
 HED PARENTHESIS MANIPULATION 
******************************************************* 
* LPTYP AND RPTYP HANDLE THE PARENTHESIS MANIPULATION * 
******************************************************* 
LPTYP ISZ NEST      ADVANCE THE DEPTH COUNTER 
      RSS 
      JMP ERR2      IF TOO DEEP THEN TAKE GAS 
      LDA NEST
      LDB FCR 
      CPA MIN2      IF NEST IS -2 (OUTER PARENS)
      STB PREN2       THEN STORE FCR IN PREN2 
      STB PREN1     ALWAYS STORE IT IN PREN1
      LDB RF        SAVE RF IN
      STB RF2         RF2 FOR LATER RECOVERY
      STB RF1           AND RF1 FOR LOOPING 
      JMP FORMT 
RPTYP LDA NEST      IF NEST IS
      INA,SZA,RSS   EQUAL TO 1 THEN 
      JMP RPTY1     GO TO RPTY1 
      INA,SZA       IF NEST NEQ -2 THEN 
      JMP ERR2      TAKE GAS
      JSB F2LST     RETURN TO THE CALLING SEQUENCE
      JSB DTA       IF WE GET BACK, I/O THE RECORD
      LDA RF2       RESET RF1 FOR REPEATING 
      STA RF1         THE FORMAT
      CCA           SET SKIPL TO AVOID A SPURIOUS 
      STA SKIPL     RETURN TO THE CALLING SEQUENCE. 
      LDB PREN1     IF PREN1=PREN2, THERE ARE NO
      CPB PREN2     INNER PARENS, SO LEAVE NEST 
      LDA NEST      ALONE. IF THEY'RE DIFFERENT THEN
      STA NEST      SET IT TO -1. 
RPTY2 STB FCR       RESET FCR TO PREN1
      JMP FORMT     RETURN
RPTY1 LDB PREN1 
      ISZ RF1       IF RF1 DOESN'T GO TO ZERO, THEN 
      JMP RPTY2       RESET FCR TO PREN1
      LDA MIN2      OTHERWISE JUST SET NEST TO -2.
      STA NEST
      JMP FORMT 
*************************************** 
* INOUT HANDLES THE SLASH IN A FORMAT * 
*************************************** 
INOUT JSB DTA 
      JSB RFCHK 
      JMP INOUT 
 HED NUMERICAL CONVERSIONS
********************************************************************
*     THE NUMERICAL CONVERSIONS ARE ALL PERFORMED USING FLOATING   *
*     ARITHMETIC. THE USUAL FLOATING POINT ROUTINES, WHICH WORK ON *
*     23 BIT FRACTIONS, ARE BYPASSED IN FAVOR OF UNPACKED ROUTINES.*
*     THESE OPERATE ON 31 BITS AND THEREBY PROVIDE MUCH BETTER     *
*     ACCURACY.  THE ENTRY POINTS TO THE FLOATING POINT            *
*     PACKAGE THAT ARE USED ARE:                                   *
*                                                                  *
*         .FLUN     UNPACK ROUTINE                                 *
*         FLOAT     FLOAT ROUTINE                                  *
*         .PACK     PACK AND ROUND ROUTINE                         *
*         IFIX      UNFLOAT ROUTINE                                *
********************************************************************
*                                                                  *
* FOLLOWING ARE SOME UTILITY ROUTINES FOR OBTAINING THE W AND D    *
* FIELDS, AND DOING A FEW OTHER LITTLE THINGS.                     *
*                                                                  *
********************************************************************
WGET  NOP 
      JSB INT       GET NUMBER IN FORMAT
      CMA,INA       NEGATE. 
      ADA SIGN      =4 FOR E-FORMAT OUT, 0 OTHERWISE
      SSA,RSS       IF NOT NEGATIVE THEN
      JMP ERR1      TAKE GAS. 
      STA WSAVE 
      JMP WGET,I
WDSET NOP           RESTORES W AND D. 
      LDA WSAVE 
      STA W 
      LDA DSAVE 
      STA D 
      JMP WDSET,I 
WDFIX NOP           INITIALIZES W & D. A=POSITIVE D.
      CMA           -D-1
WDFX1 STA DSAVE     SET DSAVE TO INCLUDE POINT
      CMA           D 
      ADA WSAVE     D-W 
      CMA,SSA       W-D-1 
      JMP *+3       JUMP IF W<D+1 
      STA BCNT      NUMBER OF LEADING BLANKS. 
      JMP WDFIX,I 
      LDA WSAVE 
      JMP WDFX1     SET D=W TO GIVE THE GUY A CHANCE
WDGET NOP           OBTAINS BOTH W AND D. 
      JSB WGET      FIRST W 
      JSB FCHAR     MAKE SURE NEXT CHARACTER
      CPA POINT     IS A DECIMAL POINT. 
      RSS           IT IS...OK
      JMP ERR1      IT'S NOT...TOO BAD
      JSB INT       GET D 
      JSB WDFIX     FIX UP
      JMP WDGET,I 
LODEM NOP           LOADS MANTISSA INTO A&B.
      LDA MANT
      LDB MANT+1
      JMP LODEM,I 
STORM NOP           STORES MANTISSA INTO MANT.
      STA MANT
      STB MANT+1
      JMP STORM,I 
MBY10 NOP           MULTIPLIES MANTISSA BY 10 
      LDA MANT      IF NUMBER IS ZERO,
      SZA,RSS 
      JMP MBY10,I    RETURN.
      LDB EXP       MULTIPLY BY 8.
      ADB ....3 
      STB EXP 
      LDB MANT+1    GET MANTISSA
      CLE,ERA       DIVIDE
      ERB            BY 
      CLE,ERA         4.
      ERB,CLE 
      ADB MANT+1    DOUBLE ADD, PRODUCING 1.25*MANT.
      SEZ 
      INA 
      ADA MANT
      SSA,RSS       IF OVERFLOW,
      JMP *+5 
      CLE,ERA        SHIFT RIGHT
      ERB              AND
      ISZ EXP         BUMP EXP. 
      NOP 
      STA MANT
      STB MANT+1
      JMP MBY10,I 
DBY10 NOP           DIVIDES MANTISSA BY 10
      LDA MANT      IF NUMBER IS ZERO,
      SZA,RSS 
      JMP DBY10,I    RETURN.
      LDB MIN2      ADJUST
      ADB EXP        EXPONENT 
      STB EXP 
      LDA MANT+1    MULTIPLY LOWER MANTISSA 
      CLE,ERA        BY 63146 AFTER SHIFTING SO THAT
      MPY TENTH       SIGN BIT IS ZERO. 
      CLE,ELA       SHIFT BACK
      ELB,CLE 
      ADA B         ADD HIGH PART OF RESULT TO LOW
      SEZ            PART FOR THE CROSS PRODUCT.
      INB 
      STB MANT+1
      LDA MANT      NOW MULTIPLY HIGH MANTISSA THE
      MPY TENTH      SAME WAY.
      CLE 
      ADA B 
      ADA MANT+1
      SEZ 
      INB 
      STB MANT      EXCHANGE
      STA B          REGISTERS
      LDA MANT        AND 
      JSB NORML        NORMALIZE. 
      JMP DBY10,I 
 HED I,F, E SPECIFICATIONS
************************************* 
ITYPE CLA           SIGN IS SET TO
      STA SIGN      ZERO FOR THE USE OF 
      JSB WGET      WGET.D=-1 FOR INTEGERS OUT, 0 
      JSB IOCHK     FOR INTEGERS IN.
      CCA,RSS 
      CLA 
      JSB WDFIX 
      JMP FCONV 
FTYPE CLA           SET SIGN=0 FOR WGET 
      STA SIGN
      JSB WDGET 
FCONV JSB F2LST     CHECK CALLING SEQUENCE
      JSB WDSET     RESET W&D 
      CMA 
      JSB WDFIX 
      JSB IOCHK     IN OR OUT ? 
      JMP FOUT      OUT 
FIN   JSB INPUT     IN
FIN1  JSB RFCHK     CHECK REPEATS 
      JMP FCONV     LOOP
FOUT  JSB FLABS     SET ABSOLUTE
      LDA BCNT
      JSB OUTPT 
*     THE NEXT FEW LINES OF CODE ARE A KLUDGE NECESSARY FOR OUTPUT- 
*     TING THE NUMBER ZERO. IT IS NECESSARY BECAUSE OUTPT WILL HAVE 
*     DELETED ALL LEADING ZEROES, AND THIS FORCES 1 LESS BLANK. 
      STA BCNT
      ADA WSAVE 
      SZA,RSS 
      JMP .OUT. 
      JSB OUTP1 
      JMP FIN1
FLABS NOP           SET NUMBER TO BE OUTPUT TO POSI-
      JSB LODEM     TIVE AND SIGN TO 0 OR -1. 
      CMA,SSA       COMPLEMENT A. 
      JMP POSIT     IT WAS POSITIVE.
      CMB,INB,SZB,RSS TWO'S COMPLEMENT B. 
      INA           IF B=0, MUST BUMP A.
      SSA,RSS       IF A IS NEG. WE HAD MAX NEG.
      JMP NEGIT 
      RAR           THAT GIVES THE RIGHT FRACTION 
      ISZ EXP       BUMP EXPONENT 
      NOP 
NEGIT STA MANT     STORE NEW FRACTION 
      CCA,RSS       SET A=-1 AND SKIP 
POSIT CLA           SET A=0 
      STA SIGN      SET SIGN
      LDA MANT      MAKE SURE MANTISSA
      JSB NORML     IS NORMALIZED 
      JMP FLABS,I   RETURN
ETYPE JSB IOCHK 
      RSS 
      JMP FTYPE     INPUT IS THE SAME AS F-TYPE.
      LDA ....4     SET SIGN=4 FOR WGET.
      STA SIGN
      JSB WDGET 
ELOOP JSB F2LST     CHECK THE LIST
      JSB WDSET     RESET W&D 
      CMA 
      JSB WDFIX 
      JSB FLABS     SET TO POSITIVE 
      CLB 
      STB EXPON     INITIALIZE EXPON TO ZERO
      CPB EXP       IF NUMBER=0, SKIP THIS
      JMP EOUT1         NEXT PART.
******************* ADJUST NUMBER TO BE AT LEAST 0.1 ***************
EOUT2 JSB MBY10     IF 10 TIMES NUMBER
      LDA EXP         IS < 1 (EXP LEQ 0)
      CMA,INA 
      SSA 
      JMP *+3 
      ISZ EXPON     BUMP EXPON AND
      JMP EOUT2     CONTINUE. 
      JSB DBY10     ELSE UNDO THE LAST MULTIPLY 
******************* NOW OUTPUT THE FRACTION PART  ******************
EOUT1 LDA EXPON 
      JSB OUTPT 
      CMA,INA       SAVE FINAL VALUE OF EXPONENT
      STA EXPON 
      JSB OUTP1 
******************* OUTPUT THE EXPONENT PART ***********************
      LDA E         FIRST THE 
      JSB OUTCR       DESCRIPTIVE E 
      LDA MINUS 
      LDB EXPON 
      SSB           SKIP IF POSITIVE
      CMB,INB,RSS   IF NEGATIVE, 2'S COMPLEMENT&SKIP
      LDA PLUS      IF POSITIVE,CHANGE A TO '+' 
      STB EXPON 
      JSB OUTCR     OUTPUT THE SIGN 
******************* OUTPUT THE EXPONENT MAGNITUDE ******************
      LDB EXPON 
      LDA ...60 
      ADB MIN10 
      SSB 
      JMP *+3 
      INA 
      JMP *-4 
      ADB ...72 
      STB EXPON 
      JSB OUTCR 
      LDA EXPON 
      JSB OUTCR     SECOND DIGIT
      JSB RFCHK     CHECK FOR REPEATS 
      JMP ELOOP 
 HED NUMERICAL OUTPUT CONVERSION
********************************************************************
*  OUTPT IS THE ROUTINE WHICH PERFORMS ALL THE OUTPUT CONVERSION.  *
*  IT ASSUMES THAT WSAVE, DSAVE, AND BCNT HAVE BEEN PROPERLY INI-  *
*  TIALIZED, AND THAT THE NUMBER IS POSITIVE AND AT LEAST 0.1.     *
*  THIS LATTER CONDITION IS NOT NECESSARY FOR OTHER THAN E-CONVER- *
*  SION, FOR LEADING ZEROES MAY APPEAR IN THE OTHER TYPES OF       *
*  CONVERSIONS. THE MAIN PROCESS IS TO FIRST REDUCE THE NUMBER TO  *
*  LESS THAN 1, THUS BUILDING UP EITHER BCNT OR EXPON, DEPENDING   *
*  UPON WHO IS CALLING. WHEN THIS IS DONE, THIS VALUE IS RETURNED  *
*  TO THE CALLER, WHO THEN STORES IT AND SETS THE CORRECT VALUE    *
*  OF BCNT. THE CALLER THEN RETURNS TO OUTP1, WHICH DOES THE       *
*  ACTUAL BINARY TO DECIMAL CONVERSION BY REPEATEDLY MULTIPLYING   *
*  THE NUMBER BY 10 AND OUTPUTTING THE INTEGER PART, THEN THROWING *
*  IT AWAY. SPECIAL CARE IS TAKEN TO OUTPUT THE SIGN AND DECIMAL   *
*  POINT PROPERLY, AND TO ROUND THE RESULT CORRECTLY.              *
OUTPT NOP 
OUTP3 STA BCTEM     INITIAL VALUE OF BCNT AS PUT- 
*                                       ED BY CALLER
******************  REDUCE NUMBER TO < 1  **************************
      LDB EXP       TEST THE EXPONENT 
      CMB,INB 
      SSB,RSS       IF POSITIVE, THE
      JMP OUTPT,I   REDUCTION IS DONE 
.OUT. JSB DBY10    DIVIDE IT BY 10
      CCA 
      ADA BCTEM     BCTEM.
      JMP OUTP3     LOOP
OUTP1 NOP 
      JSB LODEM 
      STA MANTS     SAVE
      STB MANTS+1    NUMBER 
      LDA EXP 
      STA EXPS
OFTRY LDB BCNT      OUTPUT LEADING BLANKS 
      LDA SIGN
      ADB A         SUBTRACT 1 FOR SIGN IF NEGATIVE 
      SSB,RSS       SKIP IF NEGATIVE
      JMP OUTP4 
*     IF BCNT GEQ D WE CAN STILL OUTPUT THE NUMBER    * 
      CMB           -BCNT-1 
      STB DT        USED FOR OUTPUT FIELD OVERFLOW
      ADB D         D-BCNT-1
      SSB,INB,RSS   SKIP IF BCNT GEQ D&SET B=D-BCNT 
      JMP BUCKS     OUTPUT DOLLARS OTHERWISE
      STB D         SET NEW VALUE OF D
      CMA,INA       BCNT = 0 OR 1 
      STA BCNT
      JMP OUTP6 
OUTP4 LDA BLANK     OUTPUT THE
      JSB MULTO     LEADING BLANKS
OUTP6 ISZ SIGN      OUTPUT A MINUS? 
      JMP OUTP8     NO. 
      ISZ W 
      NOP           JUST IN CASE
      LDA MINUS 
      JSB OUTCR 
***** NOW PRINT THE DIGITS ONE AT A TIME, AS DESCRIBED ABOVE.  *****
OUTP8 LDA D 
      STA DT
OUT15 LDB W 
      SSB,RSS 
      JMP BUCKS     IF W >=0, OVERFLOW
      LDA POINT 
      CPB D         PRINT A DECIMAL POINT.
      JMP OUTDP 
      JSB GETDG     GET THE DIGIT 
      ADA ...60     CONVERT TO ASCII
OUTDP JSB OUTCR 
      ISZ W        SKIP IF DONE 
      JMP OUT15 
******************  GET 1 MORE DIGIT TO ROUND  *********************
      JSB GETDG 
      ADA MIN5
      ISZ OVTOG    IF BUFFER IS BOMBED, FORGET IT!
      SSA           SKIP IF DIGIT WAS 5 OR MORE 
      JMP OUTP1,I 
******************  ROUNDING SECTION  ******************************
      JSB WDSET     RESET W SO WE DON'T BACK TOO FAR FAR
      LDB BCR       GET THE LAST
OUT11 JSB BUF2A     CHARACTER OUTPUT. 
      JSB DIGIT     WAS IT A DIGIT? 
      JMP OUTP9     NO. 
      LDB BCR 
      CPA NINE      YES. WAS IT A NINE. 
      JMP OUT10     YES.
******** SINCE THE DIGIT WAS < 9, WE JUST BUMP IT UP. ************* 
      ADA ...61 
      JMP OUT14 
OUT10 LDA ...60     CHANGE THE NINE TO A ZERO 
      JSB A2BUF 
OUT12 JSB BACKB     BACK UP BUFFER POINTER
      ISZ W         TEST FOR BEGINNING OF FIELD.
      JMP OUT11 
BUCKS LDA .OBUF     PLACE $'S IN THE FIELD. 
      RAL           FIRST RESET CCNT
      CMA,INA         BCR TO POINT AT THE 
      ADA CLEN         BEGINNING OF THE 
      ADA BCRS          FIELD.
      STA CCNT
      LDA BCRS
      STA BCR 
      JSB WDSET     RESET W 
      LDA DT
      SSA,INA       IF NEGATIVE, CAN STILL FIX
      JMP FIXIT 
      LDA MONEY 
      LDB WSAVE 
      CMB,INB 
      JSB MULTO 
      JMP OUTP1,I 
FIXIT STA D         SET D TO 1 LESS THAN BEFORE 
      ISZ BCNT
      LDA MANTS 
      LDB MANTS+1   RESTORE 
      JSB STORM      NUMBER 
      LDA EXPS
      STA EXP 
      LDA SIGN
      ADA MIN1
      STA SIGN      RESTORE SIGN
      JMP OFTRY     TRY AGAIN 
OUTP9 CPA POINT     WAS THE CHARACTER A DECIMAL PT.?
      JMP OUT12     NOTHING TO DO IF IT WAS.
      CPA BLANK     WAS IT A BLANK? 
      JMP OUT13     YES. REST IS EASY 
******** OTHERWISE IT HAS TO BE A MINUS.   ************************ 
      ISZ W         CHECK W/
      RSS           CAN MOVE IT BACK. 
      JMP BUCKS     SORRY ABOUT THAT
      JSB BACKB 
      JSB A2BUF 
      ISZ BCR       NOW PUT IN A '1'. 
OUT13 LDB BCR 
      LDA ...61 
OUT14 JSB A2BUF 
RSTRB LDA WSAVE     PUT BCR BACK AT THE END OF THE
      CMA,INA       FIELD.
      ADA BCRS
      STA BCR 
      JMP OUTP1,I 
******************************* 
BACKB NOP     *     SUBTRACTS 1 FROM BCR
******************************* 
      CCB 
      ADB BCR 
      STB BCR 
      JMP BACKB,I 
******************************* 
MULTO NOP     *     OUTPUTS THE CHARACTER IN A THE
*                             *         NUMBER OF TIMEGIVEN BY B
******************************* 
      CMB,INB       SET B NEGATIVE
      SSB,RSS       SKIP IF B WAS POSITIVE
      JMP MULTO,I   RETURN IF B WAS 0 OR LESS 
      STB MULT2     STORE THE COUNT 
      STA MULT1     SAVE THE CHARACTER
MULTL LDA MULT1 
      JSB OUTCR 
      ISZ W 
ZERO  NOP           JUST IN CASE
      ISZ MULT2 
      JMP MULTL 
      JMP MULTO,I 
******************************* 
GETDG NOP     *     THIS ROUTINE MULTIPLIES THE NUM-
*                             *         BER BY 10 AND PEELS OFF THE 
*******************************       INTEGER PART. 
      JSB MBY10     MULTIPLY BY 10
      LDB EXP       GET THE EXPONENT IN B 
      CMB,INB         AS NEGATIVE.
      AND HIMSK     KEEP HIGH ORDER 5 BITS OF A 
      RAL           NORMALIZE TO BIT 15 
      SSB,INB       ROTATE LEFT UNTIL EXP GETS TO 
      JMP *-2       ZERO:THIS PUTS THE INTEGER IN A 
      AND .177      GET RID OF THE OTHER STUFF
      STA TEMP1 
      LDB EXP       NOW ROTATE BACK 
      CMB,INB 
      RAR 
      SSB,INB 
      JMP *-2 
      XOR MANT       REMOVE THE INTEGER PART
      LDB MANT+1    NORMALIZE THE REMAINDER.
      JSB NORML 
      LDA TEMP1 
      JMP GETDG,I 
NORML NOP           NORMALIZES MANTISSA.
      SZA,RSS       IF A=B=0, 
      SZB 
      JMP NRML1 
      STA EXP        SET EXP=0 ALSO.
NRML3 JSB STORM 
      JMP NORML,I 
NRML1 SSA,RSS       IF SIGN OF A IS SET,
      JMP NRML2 
      CLE,ERA         SHIFT RIGHT,
      ERB 
      ISZ EXP           BUMP EXPONENT & 
      NOP 
      JMP NRML3           RETURN
NRML2 STA MANT       SUBTRACT 
      CCA             ONE 
      ADA EXP          FROM 
      STA EXP           EXP 
      LDA MANT           AND
      CLE,ELB 
      ELA                 SHIFT 
      JMP NRML1 
                                            