.MCALL .MODULE .MODULE JDIV,VERSION=04,COMMENT=,IDENT=NO,LIB=YES ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion of the above copyright notice. This software, or ; any other copies thereof, may not be provided or otherwise ; made available to any other person except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. .SBTTL Module Declaration .NLIST .ENABL LC .DSABL GBL .NLIST CND .LIST ; ++ ; FACILITY: ; ; RT-11 System Subroutine Library ; ; CALLABLE ENTRIES: ; ; JDIV ; ; ENVIRONMENT: ; ; This routine can be used by any job running in a single-job or ; multi-job environment . It uses "TRAP" to provide error processing. ; ; ; INCLUDE FILES: ; ; SYSMAC.SML ; RT-11 system macro library. ; ; MACROS: ; ; No macros defined in this module. ; ; OWN STORAGE: ; ; No local storage allocated in this module. ; ; EXTERNAL REFERENCES: ; .GLOBL $SYSLB ; Include system library work area. .GLOBL $SETR0 ; Entry point to SET R0 routine .SBTTL JDIV - Fortran-callable Routine ; ; ++ ; FUNCTIONAL DESCRIPTION: ; ; The JDIV function computes the quotient of two INTEGER*4 values ; ; CALLING SEQUENCE: ; ; i = JDIV( jopr1, jopr2,jres[,jrem]) ; ; INPUT PARAMETERS: ; ; R5 - address of JDIV's argument block ; ; 0(R5) - argument count of JDIV call ; 2(R5) - address of an INTEGER*4 variable that is the dividend ; 4(R5) - address of an INTEGER*4 variable that is the divisior ; 6(R5) - address of an INTEGER*4 variable that receives the quotient ; of the operation ; 10(R5) - address of an INTEGER*4 variable that receives the remainder ; of the operation ; ; IMPLICIT INPUTS: ; ; ** None ** ; ; OUTPUT PARAMETERS: ; ; ; IMPLICIT OUTPUTS: ; ; ** None ** ; ; ROUTINE VALUE: ; ; i = -1 normal return; the result is negative ; = 0 normal return; the result is zero ; = 1 normal return; the result is positive ; ; SIDE EFFECTS: ; ; Processor registers R0 & R4-R5 are modified. ; .SBTTL JDIV - Fortran-callable Routine .PSECT SYS$I JDIV:: CLR -(SP) ; set succcessful exit flag MOV (R5)+,-(SP) ; save arg count MOV (R5)+,R4 ; addr of numerator MOV (R5)+,R1 ; addr of denominator MOV R5,-(SP) ; save addr of result MOV #33.,-(SP) ; set shift counter MOV (R1)+,R0 ; get low order denom MOV @R1,R1 ; get high order denom BPL 10$ ; branch if positive NEG R1 ; take absolute value NEG R0 SBC R1 ADD #100000,@SP ; and set sign flag 10$: BNE 20$ ; branch if denom can't be 0 TST R0 ; make sure low denom isn't 0 BEQ ZDIV ; branch if zero divide 20$: MOV (R4)+,R2 ; low order of num MOV @R4,R3 ; high order of num BPL 30$ ; branch if positive ADD #40000,@SP ; set sign flag NEG R3 ; and take absolute value NEG R2 SBC R3 30$: CLR R5 ; quotient ends up in r3:r2 CLR R4 ; remainder ends up in r5:r4 40$: ROL R4 ; expose new bit of numerator ROL R5 CMP R1,R5 ; does denom fit? BHI 60$ ; branch if not, c=0 BNE 50$ ; branch if yes CMP R0,R4 ; high parts same, check low BHI 60$ ; branch if not, c=0 50$: SUB R0,R4 ; subtract denom from remainder SBC R5 SUB R1,R5 SEC ; indicate new quotient bit 60$: ROL R2 ; shift in new bit of quotient ROL R3 DECB @SP ; check loop count BGT 40$ ; branch to loop ENDCOD: ASL @SP ; put quotient result sign in v BVC 10$ ; branch if to be positive NEG R3 ; negate quotient NEG R2 SBC R3 10$: TST (SP)+ ; get remainders sign BPL 20$ ; branch if remainder to be positive NEG R5 ; negate remainder NEG R4 SBC R5 20$: MOV (SP)+,R0 ; get arg list pointer again MOV (R0)+,R1 ; addr of quotient result CMPB #3,(SP)+ ; check number of arguments BEQ 30$ ; branch if only 3 passed MOV @R0,R0 ; get addr remainder result MOV R4,(R0)+ ; store low MOV R5,@R0 ; store high 30$: MOV R2,(R1)+ ; store low quotient result MOV R3,@R1 ; store high MOV (SP)+,R0 ; set r0 for $setr0 routine CALLR $SETR0 ; exit via $setr0 routine ZDIV: CLR R4 ; set remainder to 0 CLR R5 CLR R2 ; set quotient to 0 CLR R3 MOV #-3,6(SP) ; set zdiv error indicator BR ENDCOD ; go set results .END