.TITLE QUAMTH QUAD WORD MATH PACKAGE .IDENT /1.01/ ;FILE "QUAMTH.MAR" ; QUAADD,QUASUB,QUAMUL,QUADIV,QUACMP ; COPYRIGHT (C) 1979 ; MANAGEMENT SCIENCE ASSOCIATES, INC. ; 5100 CENTRE AVENUE ; PITTSBURGH, PENNSYLVANIA 15232 ; ; THIS SOFTWARE IS DISTRIBUTED WITHOUT COST, AND MAY BE ; REPRODUCED ONLY WITH THE INCLUSION OF THIS COPYRIGHT ; STATEMENT. MANAGEMENT SCIENCE ASSOCIATES ASSUMES NO ; RESPONSIBILITY FOR THE PERFORMANCE OF THIS SOFTWARE. ; ; BEWARE: QUASUB not designed for input and output to same variable ; ; ; .PAGE .SBTTL QUAADD QUAD ADD .PSECT $CODE,PIC,CON,REL,SHR,LCL,EXE,RD,NOWRT,LONG ;++ ; CALL QUAADD(,,) ; ; ADDEND1, ADDEND2 AND SUM ARE QUADWORDS ; THE FIRST TWO ARE READ, THE LAST WRITTEN ;-- .ENTRY QUAADD ^M<> MOVL 12(AP),R0 ; ADDRESS OF SUM MOVL 8(AP),R1 ; ADDRESS OF ADDEND2 MOVQ @4(AP),(R0) ; SUM IS ADDEND1 (overwrites result ; so can't read and write same location) ADDL (R1),(R0) ; PLUS LOW PART OF ADDEND2 ADWC 4(R1),4(R0) ; PLUS HIGH PART OF ADDEND2 RET ; RETURN TO CALLER .PAGE .SBTTL QUASUB QUAD SUBTRACT .PSECT $CODE,PIC,CON,REL,SHR,LCL,EXE,RD,NOWRT,LONG ;++ ; CALL QUASUB(,,) ; difference=minuend-subtrahend ? ; MINUEND, SUBTRAHEND AND DIFFERENCE ARE QUADWORDS ; THE FIRST TWO ARE READ, THE LAST WRITTEN ;-- .ENTRY QUASUB ^M<> MOVL 12(AP),R0 ; ADDRESS OF DIFFERENCE MOVL 8(AP),R1 ; ADDRESS OF SUBTRAHEND MOVQ @4(AP),(R0) ; DIFFERENCE IS MINUEND (wipes result location ; so this can not be used with same location ; for input and output) SUBL (R1),(R0) ; MINUS LOW PART OF SUBTRAHEND SBWC 4(R1),4(R0) ; MINUS HIGH PART OF SUBTRAHEND RET ; RETURN TO CALLER .PAGE .SBTTL QUAMUL QUAD MULTIPLY .PSECT $CODE,PIC,CON,REL,SHR,LCL,EXE,RD,NOWRT,LONG ;++ ; CALL QUAMUL(,,) ; ; MULTIPLIER, MULTIPLICAND AND PRODUCT ARE QUADWORDS ; THE FIRST TWO ARE READ, THE LAST WRITTEN ;-- .ENTRY QUAMUL ^M MOVL 4(AP),R3 ; ADDRESS OF MULTIPLIER MOVL 8(AP),R4 ; ADDRESS OF MULTIPLICAND EMUL (R3),(R4),#0,R0 ; LOW PRODUCT EMUL (R3),4(R4),R1,R1 ; FIRST CROSS TERM PRODUCT EMUL 4(R3),(R4),R1,R1 ; SECOND CROSS TERM PRODUCT TSTL (R3) ; CHECK SIGN BGEQ 1$ ; NO SIGN PROBLEMS ADDL (R4),R1 ; SIGN COMPENSATION 1$: TSTL (R4) ; CHECK OTHER SIGN BGEQ 2$ ; NO SIGN PROBLEMS ADDL (R3),R1 ; SIGN COMPENSATION 2$: MOVQ R0,@12(AP) ; GIVE THE ANSWER RET ; RETURN TO CALLER .PAGE .SBTTL QUADIV QUAD DIVIDE .PSECT $CODE,PIC,CON,REL,SHR,LCL,EXE,RD,NOWRT,LONG ;++ ; CALL QUADIV (,,{,}) ; ; NUMERATOR, DENOMINATOR, QUOTIENT AND REMAINDER ARE QUADWORDS ; THE FIRST TWO ARGUMENTS ARE READ, THE LAST TWO WRITTEN ; THE REMAINDER ARGUMENT IS OPTIONAL ;-- .ENTRY QUADIV ^M CLRB R6 ; PRESUME POS NUM AND DEN MOVL 12(AP),R8 ; GET QUOTIENT ADDRESS MOVQ @4(AP),(R8) ; GET THE NUMERATOR BGEQ 1$ ; XFER IF POSITIVE MCOML (R8),(R8) ; MAKE TWO'S COMPLEMENT MCOML 4(R8),4(R8) ; INCL (R8) ; ADWC #0,4(R8) ; MOVB #3,R6 ; FLAG THE SIGN SWITCH 1$: MOVQ @8(AP),R0 ; GET THE DENOMINATOR BGEQ 2$ ; XFER IF POSITIVE MCOML R0,R0 ; MAKE TWO'S COMPLEMENT MCOML R1,R1 ; INCL R0 ; ADWC #0,R1 ; XORB #1,R6 ; FLAG THE SIGN SWITCH 2$: CLRQ R2 ; CLEAR QUOTIENT CLRQ R4 ; CLEAR REMAINDER MOVZBL #63,R7 ; SET COUNT AND BIT POINTER 3$: ASHQ #1,R2,R2 ; ROOM FOR NEXT QUOTIENT BIT ASHQ #1,R4,R4 ; ROOM FOR NEXT NUMERATOR BIT BBC R7,(R8),4$ ; CHECK NEXT NUMERATOR BIT INCB R4 ; MOVE IT TO THE REMAINDER 4$: CMPL R5,R1 ; COMPARE REMAINDER AND DENOM BLSS 6$ ; NO SUBTRACT IF REMAINDER LESS BGTR 5$ ; CERTAIN SUBTRACT IF LARGER CMPL R4,R0 ; HIGH PARTS EQUAL SO COMPARE LOW BLSSU 6$ ; NO SUBTRACT IF REMAINDER LESS 5$: SUBL R0,R4 ; SUBTRACT DENOM FROM REMAINDER SBWC R1,R5 ; INCB R2 ; INCREMENT THE QUOTIENT 6$: SOBGEQ R7,3$ ; LOOP FOR EACH BIT BLBC R6,7$ ; CHECK QUOTIENT SIGN SWITCH MCOML R2,R2 ; MAKE QUOTIENT NEGATIVE MCOML R3,R3 ; INCL R2 ; ADWC #0,R3 ; 7$: MOVQ R2,(R8) ; RETURN THE QUOTIENT BBC #2,0(AP),9$ ; CHECK FOR FOUR ARGS BBC #1,R6,8$ ; CHECK REMAINDER SIGN SWITCH MCOML R4,R4 ; MAKE REMAINDER NEGATIVE MCOML R5,R5 ; INCL R4 ; ADWC #0,R5 ; 8$: MOVQ R4,@16(AP) ; RETURN THE REMAINDER 9$: RET ; RETURN TO CALLER .PAGE .SBTTL QUACMP QUAD COMPARE .PSECT $CODE,PIC,CON,REL,SHR,LCL,EXE,RD,NOWRT,LONG ;++ ; STS = QUACMP(QUAD1,QUAD2) ; ; QUAD1 AND QUAD2 ARE QUADWORDS, STS IS A LONGWORD ; THE FIRST TWO ARE READ, THE LAST IS RETURNED IN R0 ; ; STS = -1 IF QUAD1 < QUAD2 ; 0 IF QUAD1 = QUAD2 ; +1 IF QUAD1 > QUAD2 ;-- .ENTRY QUACMP^M<> MOVAL @4(AP),R0 ; ADDRESS OF QUAD1 MOVAL @8(AP),R1 ; ADDRESS OF QUAD2 CMPL 4(R0),4(R1) ; COMPARE HIGH PARTS FIRST BLSS 10$ ; XFER FOR -1 BGTR 30$ ; XFER FOR +1 CMPL (R0),(R1) ; COMPARE LOW PARTS SINCE HIGH SAME BLSSU 10$ ; XFER FOR -1 BGTRU 30$ ; XFER FOR +1 CLRL R0 ; SAME - RETURN 0 RET ; 10$: CVTBL #-1,R0 ; FIRST LESS - RETURN -1 RET ; 30$: MOVZBL #1,R0 ; FIRST GREATER - RETURN +1 RET .END ;THAT'S ALL, FOLKS!