.NLIST R0 = %0 R1 = %1 R2 = %2 R3 = %3 R4 = %4 R5 = %5 SP = %6 PC = %7 PS = 177776 ; PROCESSOR STATUS BR0 = 0 ; PRIORITIES BR1 = 40 BR2 = 100 BR3 = 140 BR4 = 200 BR5 = 240 BR6 = 300 BR7 = 340 .MACRO PRINT$,ARG ; REQUEST IMMEDIATE MSG PRINT .NARG COUNT .IF NE,COUNT ; ARGUMENT ? .IIF DIF,ARG, MOV ARG,R0 .ENDC CALL PRINT$ ; CALL PRINT ROUTINE .ENDM .MACRO SWITCH,ARG1,ARG2 MOV ARG1,-(SP) MOV ARG2,ARG1 MOV (SP)+,ARG2 .ENDM .MACRO PUSH,ARG MOV ARG,-(SP) .ENDM .MACRO POP,ARG MOV (SP)+,ARG .ENDM .MACRO SAVE ARG1,ARG2,ARG3,ARG4,ARG5,ARG6 .NARG NUM .IF EQ NUM ;IF NUMBER OF ARGUMENTS IS 0 SAVE ALL REGISTERS PUSH R0 PUSH R1 PUSH R2 PUSH R3 PUSH R4 PUSH R5 .IFF ;IF NUMBER OF ARGUMENTS .NE. 0 THEN FOLLOWING .IIF NB,ARG1,PUSH ARG1 ;IF ARG1 NOT BLANK PUSH .IIF NB,ARG2,PUSH ARG2 ;IF NOT BLANK PUSH IT .IIF NB,ARG3,PUSH ARG3 ; .IIF NB,ARG4,PUSH ARG4 ; .IIF NB,ARG5,PUSH ARG5 ; .IIF NB,ARG6,PUSH ARG6 ; .ENDC .ENDM .MACRO RESTORE ARG1,ARG2,ARG3,ARG4,ARG5,ARG6 .NARG NUM ;NUMBER OF ARGUMENTS .IF EQ NUM ;NO ARGUMENTS SPECIFIED RESTORE ALL REGISTERS POP R5 POP R4 POP R3 POP R2 POP R1 POP R0 .IFF ;IF ARGUMENTS SPECIFIED RESTORE THE ARGUMENTS .IIF NB,ARG1,POP ARG1 ;IF ARGUMENT 1 NOT BLANK POP IT. .IIF NB,ARG2,POP ARG2 ; .IIF NB,ARG3,POP ARG3 ; .IIF NB,ARG4,POP ARG4 ; .IIF NB,ARG5,POP ARG5 ; .IIF NB,ARG6,POP ARG6 ; .ENDC .ENDM .MACRO CALL,ARG,PASSING,A,B,C,D,E,F .NARG COUNT .IF EQ,COUNT-1 ;ONE ARGUMENT .IIF NE,TRACE&SUBS MOV #12525,-(SP) ; FLAG FOR SUBROUTINE CALL JSR PC,ARG .IFF SAVE R5 ; SAVE PARAMETER POINTER PASSING A,B,C,D,E,F ; SET UP PARAMETER LSRT .IIF NE,TRACE&SUBS MOV #12525,-(SP) JSR PC,ARG RESTORE R5 .ENDC .ENDM .MACRO PASSING,A,B,C,D,E,F,?BYPASS MOV #.+6,R5 ; PARAMETER POINTER BR BYPASS ; JUMP AROUND LIST .WORD COUNT-2 ;NUMBER OF ARGUMENTS .IIF NB,A .WORD A .IIF NB,B .WORD B .IIF NB,C .WORD C .IIF NB,D .WORD D .IIF NB,E .WORD E .IIF NB,F .WORD F BYPASS: .ENDM .MACRO RETURN .IFNE TRACE&SUBS ;IF TRACE ON MOV (SP)+,(SP) ; MOV RETURN ADDRESS UP ERASING FLAG .ENDC RTS PC .ENDM .MACRO LSHIFT ARG,COUNT ; LEFT SHIFT THE ARGUMENT COUNT PLACES .IF GE,COUNT-16. ;MUST BE <16 .ERROR ;COUNT FOR LSHIFT >= 16 .ENDC .IF EQ,COUNT/4-3 ;IF >=12 CONVERT TO RIGHT SHIFT RSHIFT ARG,16.-COUNT .ENDC .IF EQ,COUNT/4-2 ;IF >=8 AND <12 USE SWAB FOR EFFICIENCY SWAB ARG ; SHIFT 8 LSHIFT ARG,COUNT-8. ; LEFT SHIFT THE REST .ENDC .IF EQ,*/25.-1 ;REDUCE TO SWAB AND RIGHT SHIFTS ; IF COUNT BETWEEN 5 AND 7 SWAB ARG ; SHIFT 8 RSHIFT ARG,8.-COUNT .ENDC .IF LE,COUNT-4 ;IF 4 OR LESS USE REPEAT .REPT COUNT ASL ARG .ENDR .ENDC .ENDM .MACRO MUL$10,ARG ; MULTIPLY ARG BY 10 LSHIFT ARG,1 ; MULTIPLY BY 2 PUSH ARG ; SAVE 2*ARG LSHIFT ARG,2 ; 8*ARG ADD (SP)+,ARG ; 10*ARG=8*ARG+2*ARG .ENDM .MACRO RSHIFT ARG,COUNT ; RIGHT SHIFT THE ARGUMENT COUNT PLACES .IF GE,COUNT-16. ;MUST BE <16 .ERROR ;COUNT FOR RSHIFT >= 16 .ENDC .IF EQ,COUNT/4-3 ;CONVERT TO LEFT SHIFT IF BETWEEN 12 AND 15 LSHIFT ARG,16.-COUNT .ENDC .IF EQ,COUNT/4-2 ;OPTIMIZE SHIFTS IF BETWEEN 8 AND 11 SWAB ARG ; SHIFT 8 RSHIFT ARG,COUNT-8. ; RIGHT SHIFT THE REST .ENDC .IF EQ,*/25.-1 ;CONVERT TO SWAB AND LEFT SHIFT ; IF BETWEEN 5 AND 7 LSHIFT ARG,8.-COUNT ; LEFT SHIFT THE REST SWAB ARG ; SHIFT 8 .ENDC .IF LE,COUNT-4 ;IF LE 4 .REPT COUNT ASR ARG .ENDR .ENDC .ENDM ;;;; DIVIDE MACROS CONTROLLED BY EIS - FLAG FOR EXTENDED INSTRUCTION SET(FIXED POINT KE11-E. ;;;; IF HARDWARE EXISTS FOR DIVIDE IT IS DONE IN THE HARDWARE. OTHERWISE ;;; IT IS DONE BY SUCCESSIVE SUBTRACTIONS OF THE POWERS OF THE DIVISOR. ;;;; USING THE BINARY EXPANSION OF THE FRACTION WOULD BE SLIGHTLY ;;; FASTER. IT USES LESS ITERATIONS BUT EACH ITERATION IS LONGER THAN THE ;;; THE COMPARABLE ITERATION IN A SUBTRACT SEQUENCE. THE TWO MAJOR ADVANTAGES ;;; OF THE SUBTRACT SEQUENCE ARE THE ABILITY TO USE THE ;;; SAME MACRO SEQUENCE WITH A DIFFERENT POWER TABLE AND THAT IT WORKS FOR ;;; THE FULL RANGE OF UNSIGNED NUMBERS CONTAINED IN A SINGLE PDP WORD. ;;; THE BINARY METHOD BREAKS DOWN AT SUFFICIENTLY HIGH NUMBERS. ;;; ALSO THE ALGORITHM CHANGES WITH EACH DIVISOR AND DOESN'T PRODUCE THE ;;; MODULUS IMMEDIATELY AS DOES THE SUBTRACTION METHOD. .MACRO DIV$10 ARG ; DIVIDE BY 10. $$DIV ARG,#10.,#$TENS ; POWER LIST EQ 10000,1000,100,10,1 .ENDM .MACRO $$DIV ARG,DIVISOR,POWERLIST ; DETERMINE HARDWARE OR SOFTWARE DIVIDE .NTYPE TYP,ARG ;TYPE OF ARGUMENT .IF DF,EIS ;IF HARDWARE EXISTS HARD$DIVIDE ARG,DIVISOR ; DO HARDWARE DIV .IFF ;ELSE SOFT$DIVIDE ARG,POWERLIST ; SOFTWARE DIVIDE USING SUBTRACTION .ENDC .ENDM .MACRO HARD$DIVIDE ARG,DIVISOR ; HARDWARE DIVIDE .IF EQ,TYP&70 ;IF REGISTER MODE REG$DIV ARG,DIVISOR ; .IFF ;ELSE MEM$DIV ARG,DIVISOR ; DIVIDE WITH MEMORY ADDRESS ARGUMENT .ENDC .ENDM .MACRO MEM$DIVIDE ARG,DIVISOR ; DIVIDE WITH MEMORY ARGUMENT SAVE PS,R0,R1 ; SAVE REGISTERS AND PS MOV ARG,R0 ; SET UP FOR HARDWARE DIV MOV ARG+2,R1 ; DIV DIVISOR,R0 ; DO THE DIVIDE MOV @#PS,4(SP) ; SAVE STATUS BITS CORRECTLY MOV R0,ARG ; MOVE RESULTS TO ARG MOV R1,ARG+2 ; RESTORE R1,R0,@#PS ; RESTORE REGISTERS AND PS .ENDM .MACRO REG$DIVIDE ARG,DIVISOR ; DIVIDE IN REGISTERS $OFF=0 .IF NE,TYP&1 ;CHECK FOR ODD REGISTER $OFF=1 ; IF SO SAVE AND RESTORE REG-1 SAVE ARG-1 CLR ARG-1 ; SET UP FOR DIVIDE .ENDC DIV DIVISOR,ARG-$OFF ; CORRECT DIVIDE .IF NE,TYP&1 ;IF WE MUST RESTORE ARG-1 RESTORE ARG-1 .ENDC .ENDM .MACRO SOFT$DIVIDE ARG,POWERLIST ; SUCCESSIVE SUBTRACTIONS .IF EQ,TYP&70 ;REGISTER MODE $OFF = 1 ; DIFFERENTIAL =1 FOR REGISTERS $REG=4 ; TRY R4 IF FREE .IIF GE,TYP-4,$REG=0 ;ELSE R0 .IFF ;ELSE IF NOT REGISTER $OFF = 2 ; FOR MEMORY DIFFERENTIAL = 2 $REG=0 .ENDC SAVE R0+$REG ; SAVE LIST POINTER REG MOV POWERLIST,R0+$REG ; SET UP POINTER TO POWER LIST $DIV ARG,$REG ; DIVIDE BY SUCCESSIVE SUBTRACTIONS RESTORE R0+$REG .ENDM .MACRO $DIV ARG,$REG,?L1,?L2,?L3 ; SOFTWARE DIVIDE CLR ARG ; CLR QUOTIENT AREA SUMMER L1: IF ARG+$OFF LO ($REG) L2 ; IF LT CURRENT POWER OF DIVISOR SUB ($REG),ARG+$OFF ; DECREASE DIVIDEND ADD 2($REG),ARG ; ADD DIVISOR TO ONE LESS POWER BR L1 ; LOOP L2: IF 2($REG) EQ #1 L3 ; IF DONE EXIT LEAVING MODULUS IN ARG+$OFF TST ($REG)+ ; ELSE NEXT LOWER POWER OF DIVISOR BR L1 ; SUBTRACT SEQUENCE AGAIN L3: ; DONE. QUOTIENT IN ARG, REMAINDER IN ARG+$OFF .ENDM ;THE FOLLOWING SERIES OF MACROS ALLOWS THE USE OF AN ;IF STATEMENT IN A VERY HIGH LEVEL. ALSO ALLOWED IS THE ;USE OF A GOTO STATEMENT ;; ;L E G A L F O R M A T S ;-------------------------- ; ; IF ARG1 REL DEST ;TESTING ARG1 IF REL HOLD GOTO DEST ; IF ARG1 REL GOTO DEST ;SAME AS ABOVE BUT USES A JMP ; IF ARG1 REL ARG2 DEST ;IF REL EXISTS BETWEEN ARG1 AND ARG2 GOTO DEST ; IF ARG1 REL ARG2 GOTO DEST ;SAME AS ABOVE BUT BRANCHES VIA JMP ; IF ARG1 AND ARG2 REL DEST ;IF REL HOLDS ON LOGICAL PRODUCT GO TO DEST ; IF ARG1 AND ARG2 REL GOTO DEST ; SAME AS ABOVE BUT BRANCH IS VIA JMP ; ; GOTO DEST ; JMP DEST ;; ; ALL OF THE AVOVE CAN ALSO BE DONE IN BYTE MODE BY SUBSTITUTING IFBYTE FOR IF. ;NOTE BECAUSE OF LIMITATIONS IN ASSEMBLER GENERATED SYMBOLS ANY MODULE ;CAN HAVE UP TO 64 USES OF THE GOTO STATEMENT OR GOTO VARIATION OF THE ;IF STATEMENT. ; ; ARG1 = 1ST ARGUMENT ; ARG2 = 2ND ARGUMENT ; REL = RELATIONSHIP ; DEST = DESTINATION ; DUMMY = ; MODE = WORD OR BYTE MODE ; .MACRO GO.TO,REL,DEST,?BYPASS B'REL .+4 BR BYPASS JMP DEST BYPASS: .ENDM .MACRO GOTO,REL,DEST .NARG COUNT .IF EQ COUNT-1 ;IF ONE PARAMETER JMP REL ; GO TO THE DEST .IFF ;OTHERWISE TWO PARAMETERS GO.TO REL,DEST .ENDC .ENDM .MACRO IF3ARG,ARG1,REL,DEST,MODE TST'MODE ARG1 B'REL DEST .ENDM .MACRO IF4ARG,ARG1,REL,ARG2,DEST,GO.2,MODE .IF IDN ARG2,GO.2 ;IF GOTO TYPE TST'MODE ARG1 GOTO REL,DEST .IFF CMP'MODE ARG1,ARG2 B'REL DEST .ENDC .ENDM .MACRO IF5ARG,ARG1,REL,ARG2,DUMMY,DEST,GO.2,MODE .IF IDN DUMMY,GO.2 CMP'MODE ARG1,ARG2 GOTO REL,DEST .IFF BIT'MODE ARG1,ARG2 B'DUMMY DEST .ENDC .ENDM .MACRO IF6ARG,ARG1,AND,ARG2,REL,GO.2,DEST,MODE BIT'MODE ARG1,ARG2 GOTO REL,DEST .ENDM .MACRO IFBYTE,ARG1,REL,ARG2,DUMMY,DEST,GO.2 .NARG COUNT .IF EQ COUNT - 3 IF3ARG ARG1,REL,ARG2,B .ENDC .IF EQ COUNT - 4 IF4ARG ARG1,REL,ARG2,DUMMY,GOTO,B .ENDC .IF EQ COUNT - 5 IF5ARG ARG1,REL,ARG2,DUMMY,DEST,GOTO,B .ENDC .IF EQ COUNT-6 IF6ARG ARG1,REL,ARG2,DUMMY,DEST,GO.2,B .ENDC .ENDM .MACRO IF,ARG1,REL,ARG2,DUMMY,DEST,GO.2 .NARG COUNT .IF EQ COUNT - 3 IF3ARG ARG1,REL,ARG2 .ENDC .IF EQ COUNT - 4 IF4ARG ARG1,REL,ARG2,DUMMY,GOTO .ENDC .IF EQ COUNT - 5 IF5ARG ARG1,REL,ARG2,DUMMY,DEST,GOTO .ENDC .IF EQ COUNT-6 IF6ARG ARG1,REL,ARG2,DUMMY,DEST,GO.2 .ENDC .ENDM .MACRO DADD,ARG1,ARG2 ; DOUBLE PRECISION ADD- REQUIRES 2 WORD ARGUMENTS IN MEMORY ADD ARG1,ARG2 ADC 2+ARG2 ADD 2+ARG1,2+ARG2 .ENDM .MACRO DSUB,ARG1,ARG2 ; DOUBLE SUBTRACT SUB ARG1,ARG2 SBC 2+ARG2 SUB 2+ARG1,2+ARG2 .ENDM .MACRO DINC,ARG ; DOUBLE PRECISION INCREMENT ADD #1,ARG ; INCREMENT THAT PROPERLY SETS C BIT ADC 2+ARG .ENDM .MACRO DDEC,ARG ; DOUBLE PRECISION DECREMENT SUB #1,ARG ; DEC THAT PROPERLY SETS C BIT SBC 2+ARG .ENDM .MACRO DMOV,ARG1,ARG2 ; DOUBLE PRECISION MOVE OF TWO WORDS MOV ARG1,ARG2 MOV 2+ARG1,2+ARG2 .ENDM .MACRO .DOUBLE,NUM .NARG C .IF EQ C COUNT = 1 .IFF COUNT = NUM .ENDC .REPT COUNT .WORD 0,0 .ENDR .ENDM .MACRO SET,ARG ; SET FLAG TO NON-ZERO MOV #1,ARG .ENDM .MACRO AND,ARG1,ARG2,MODE .NTYPE TYP,ARG2 .IF NE,TYP-27 MOV'MODE ARG2,-(SP) COM'MODE (SP) BIC'MODE (SP)+,ARG1 .IFF BIC'MODE ARG2*<-1>-1,ARG1 .ENDC .ENDM .MACRO OR,ARG1,ARG2,MODE BIS'MODE ARG2,ARG1 .ENDM .MACRO PLUS,ARG1,ARG2,MODE .IF IDN,ARG2,<#1> INC ARG1 .IFF ADD ARG2,ARG1 .ENDC .ENDM .MACRO MINUS,ARG1,ARG2,MODE .IF IDN,ARG2,<#1> DEC ARG1 .IFF SUB ARG2,ARG1 .ENDC .ENDM .MACRO SHIFT,ARG,COUNT,MODE .IF GE,COUNT LSHIFT ARG,COUNT .IFF SHIFT = 0-COUNT RSHIFT ARG,SHIFT .ENDC .ENDM .MACRO COMPUTE A,O2,C,O3,D,O4,E,O5,F,O6,G ; COMPUTE MACRO .NCHR CHARS,O2 ;CHECK IF SINGLE CHAR .IIF EQ,CHARS .MEXIT ;IF NO ARGUMENT EXIT FROM MACRO .IF EQ,CHARS-1 .IIF IDN,O2,<&> AND A,C .IIF IDN,O2, OR A,C .IIF IDN,O2,<+> PLUS A,C .IIF IDN,O2,<-> MINUS A,C .IFF O2 A,C .ENDC .IF NB,O3 ;IF MORE TO DO COMPUTE A,O3,D,O4,E,O5,F,O6,G ; DO THE REST .ENDC .ENDM .MACRO LET A,O1,B,O2,C,O3,D,O4,E,O5,F,O6,G ; ALLOW UP TO 6 OPERATIONS .IF IDN,O1,<=> ;FIRST OPERATOR MUST BE = .IF IDN,O2,<=> ;IF 2 = DOUBLE REPLACE LET B,O2,C,O3,D,O4,E,O5,F,O6,G MOV B,A ; MOV RESULT TO A .IFF ;ELSE .IIF DIF,A,B MOV B,A COMPUTE A,O2,C,O3,D,O4,E,O5,F,O6,G .ENDC .ENDC .IF DIF,O1,<=> .ERROR ;NO = IN LET MACRO .ENDC .ENDM ;;;;;; FOR MAT OF DO MACRO ; DO INDEX = LO,HI,INC ; ENDDO INDEX ; ; LO HI AND INC ARE INTEGER CONSTANTS ; $LEV =0 $$$$LB =1 .MACRO DO,INDEX,DUMMY,LO,HI,INC $LEV =$LEV+1 MOV #'LO,INDEX $SETDO LO,HI,INC,\$LEV $SETLB \$$$$LB,\$LEV .ENDM .MACRO $SETLB,LAB,LEV $PC'LAB = . $L'LAB: $LB'LEV =LAB $$$$LB =$$$$LB+1 .ENDM .MACRO $SETDO,LOW,HI,INC,$LEV $REL'$LEV =-1 .IF LT,HI-LOW .IIF GE,HI,$REL'$LEV=-1 .IIF LT,HI,$REL'$LEV=1 .IFF .IIF GE,HI,$REL'$LEV=1 .IIF LT,HI,$REL'$LEV=-1 .ENDC $INC'$LEV =INC $LAB'$LEV =$$$$LB $LIM'$LEV =HI .ENDM .MACRO ENDDO INDEX $$ENDDO INDEX,\$LEV .ENDM .MACRO $$ENDDO,INDEX,LEV .NTYPE $$$TYP,INDEX .IF EQ,<$LIM'LEV-1>!<$$$TYP&70>!<$INC'LEV+1>! $SOB INDEX,\<$LB'LEV> .IFF $ENDDO INDEX,\$LEV .ENDC $LEV =$LEV-1 .ENDM .MACRO $SOB,INDEX,DEST $$$DST =126.+$L'DEST-. .IF GT,126.+$L'DEST-. ; IF NOT TOO FAR SOB INDEX,$L'DEST .IFF BR .+6 ; BR TO SOB JMP @#$L'DEST SOB INDEX,.-4 .ENDC .ENDM .MACRO $ENDDO INDEX,LEV $$$FLG =0 .IF EQ,$INC'LEV-1 ; IF INCREMENT IS BETTER $$$FLG = 1 INC INDEX .ENDC .IF EQ,$INC'LEV+1 ; IF DECREMENT IS BETTER $$$FLG = 1 DEC INDEX .ENDC .IF EQ,$$$FLG ; IF NO OPTIMIZATION DONE ADD #$INC'LEV,INDEX .ENDC $$$FLG = 0 .IF EQ,$LIM'LEV ; COMPARE TO ZERO $$$FLG = 1 ; NO TEST NEED BE DONE .ENDC .IF EQ,$$$FLG ; OTHERWISE MUST TEST CMP INDEX,#$LIM'LEV .ENDC $DST'LEV =.-$PC'LEV .IF LT,$REL'LEV $JMP \<$LB'LEV>,HIS .IFF $JMP \<$LB'LEV>,LOS .ENDC .ENDM .MACRO $JMP DEST,REL .IF GT,256.+$L'DEST-. ; BRANCH LEGAL B'REL $L'DEST .IFF B'REL .+4 BR .+6 JMP @#$L'DEST .ENDC .ENDM TRACE = 0 SUBS = 0 .LIST