.IIF NDF RSX RSX = 0 ;Assume RT11 ;01 + .TITLE AEISBX .ident /X01.03/ .NLIST BEX, CND .ENABL LC, GBL .LIST MEB ; ; C COMPILER. ; EIS BOX SIMULATION. ; ; DAVID G. CONROY 04-MAR-78 ; ; Edit history ; 01 01-Aug-79 MM Added RT11 support ; 02 01-Aug-79 MM "Fixed" divide routine for neg. arguments ; 03 01-Jul-80 MM Fixed divide routine again ; ; Note: ; This routine is used only in the compiler/assember library ; .GLOBL $MULR1 .GLOBL $DIVR0 ;+ ; ** $MULR1 - (SP) * R1 -> R1 ; ; INPUTS: ; 2(SP)=ONE NUMBER ; R1=THE OTHER NUMBER ; ; OUTPUTS: ; R1=PRODUCT ;- $MULR1: MOV R0,-(SP) ;SAVE REGISTERS MOV R2,-(SP) ; MOV R3,-(SP) ; MOV R4,-(SP) ; CLR R2 ;SET UP CORRECT SIGNS TST R1 ;TEST MULTIPLICAND BPL 10$ ; NEG R1 ; COM R2 ; 10$: MOV 12(SP),R3 ;THEN MULTIPLIER BPL 20$ ; NEG R3 ; COM R2 ; 20$: CLR R0 ;TOP HALF OF PRODUCT MOV #16.,R4 ;STEPCOUNTERPR 30$: BIT #1,R1 ;DO THE MULTIPLY BEQ 40$ ; ADD R3,R0 ; 40$: CLC ; ROR R0 ; ROR R1 ; DEC R4 ; BNE 30$ ; TST R2 ;RECOMPLEMENT IF REQUIRED BEQ 50$ ; NEG R1 ; 50$: MOV (SP)+,R4 ;DONE MOV (SP)+,R3 ; MOV (SP)+,R2 ; MOV (SP)+,R0 ; RETURN ; ;+ ; ** $DIVR0 -- R0:R1 / (SP) -> R0 (Q) R1 (R) ; ; INPUTS: ; R0=HIGH HALF OF THE DIVIDEND ; R1=LOW HALF OF THE DIVIDEND ; 2(SP)=DIVISOR ; ; OUTPUTS: ; R0=QUOTIENT ; R1=REMAINDER ; $DIVR0: ; ;03+ ; Note: the code is -- except for register allocations -- identical ; with the DVI routine in the floating-point math package ; (and with div$i in eis.mac in the run-time library). ; ; Register usage: ; r0 gets quotient ; r1 gets remainder ; r2 divisor ; r3 loop counter ; r4 flag for negative arguments ; mov r4,-(sp) ; Save mov r3,-(sp) ; working mov r2,-(sp) ; registers. clr r4 ; R4 = sign of result mov 10(sp),r2 ; divisor bgt 10$ ; br if divisor > 0 beq 60$ ; Error if zero mov #100000,r4 ; Set flag neg r2 ; and negate divisor 10$: mov #16.,r3 ; 16 iterations tst r0 ; High-order dividend bmi 15$ ; Nope, it's negative bgt 20$ ; Br if dividend > 0 tst r1 ; Is low-order zero beq 70$ ; Yes, exit br 20$ ; continue 15$: bis #40000,r4 ; Negative, set flag neg r0 ; negate dividend neg r1 ; Low-order, too sbc r0 ; fix high-order 20$: asl r1 ; Double left rol r0 ; shift beq 40$ ; Br if no change inc r1 ; Assume it will go sub r2,r0 ; Trial step bhis 40$ ; Br if ok add r2,r0 ; Nope, dividend not big enough dec r1 ; Remove quotient bit 40$: dec r3 ; Iteration count bgt 20$ ; Keep on dividing asl r4 ; Look at the negative flag bvc 50$ ; Continue if either/both were neg. neg r1 ; Negate quotient 50$: tst r4 ; Look at remainder sign bpl 80$ neg r0 ; Negate remainder br 80$ ; Just exit ; ; Branch here if divide by zero ; 60$: ; Br here if divide by zero 70$: ; Br here if dividend is zero clr r0 ; Return zero quotient clr r1 ; and remainder 80$: mov r0,r2 ; Switch quotient mov r1,r0 ; and remainder mov r2,r1 ; to the correct registers mov (sp)+,r2 ; Restore mov (sp)+,r3 ; working mov (sp)+,r4 ; registers ;03- return .END