ASMB,L,C * * **************************************************************** * * (C) COPYRIGHT HEWLETT-PACKARD COMPANY 1979. ALL RIGHTS * * * RESERVED. NO PART OF THIS PROGRAM MAY BE PHOTOCOPIED, * * * REPRODUCED OR TRANSLATED TO ANOTHER PROGRAM LANGUAGE WITHOUT * * * THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY. * * **************************************************************** * * NAME: PART OF MATH LIBRARY * SOURCE: 24998-18XXX SEE NAM FOR LAST THREE DIGITS * RELOC: PART OF 24998-12001 * PGMR: BG & JTS * HED ".DDI" - DOUBLE INTEGER DIVIDE. NAM .DDI,7 24998-1X040 REV.2001 781021 * ENT .DDI,.DDIR EXT FLOAT * A EQU 0 B EQU 1 SUP * * .DDI TAKES THE QUOTIENT OF TWO DOUBLE INTEGERS. SEE ".DADS" * FOR THE NUMBER FORMAT. NOTE: THE INSTRUCTION "DIV" IS NOT * COMPATIBLE WITH .DDI . * * CALLING SEQUENCE: * * DLD * JSB <.DDI OR .DDIR> * DEF * RESULT IN (A,B) * * FOR ".DDI", THE RESULT IS ARG1/ARG2. FOR ".DDIR" THE RESULT IS * ARG2/ARG1. THE OVERFLOW BIT IS SET IFF THE DIVISOR IS ZERO OR * THE DIVIDEND IS -2**31 AND THE DIVISOR IS -1. IN THIS CASE * THE VALUE RETURNED IS (077777,177777). THE E-BIT IS PRESERVED. SPC 2 * ENTRY. COPY ARGS, DETERMINE SIGN OF RESULT, TAKE ABS VALUES. * .DDI NOP STA D1 REMEMBER SIGN OF NUMERATOR. ERA REMEMBER "E" STA E LDA D1 SSA,RSS TAKE ABS VALUE. JMP DIVA CMA CMB,INB,SZB,RSS INA DIVA STA N1 (N1,N2) = ABS NUMERATOR STB N2 LDB .DDI,I GET DENOM ADDR. ISZ .DDI LDA B,I COMPUTE SIGN OF RESULT. XOR D1 IOR =B77777 = -1 IFF SIGN RESULT IS "-". STA SIGN DLD B,I SSA,RSS TAKE ABS VALUE JMP DIVB CMA CMB,INB,SZB,RSS INA DIVB STA D1 (D1,D2) = ABS VALUE DENOMINATOR STB D2 SKP * DETERMINE IF EASY OR HARD. IF EASY, DO IT. * SWP ASL 16 DOES DENOM FIT IN ONE WORD ? SOC JMP DIV2 NO. CLB YES. USE EASY WAY. LDA N1 UPPER DIVIDE. DIV D2 SOC DIVIDE BY ZERO ? JMP SPEC2 YES. [ALSO (MAX NEG)/(+-1)] SSA CORRECT FOR DENOM = 2**15. CMA,INA STA Q1 UPPER RESULT. SSB CORRECT FOR DENOM = 2**15. CMB,INB LDA N2 FORM FULL REMAINDER. ASR 1 CAN ONLY GENERATE 15 BITS. DIV D2 FORM THEM. RAL POSITION. STA Q2 LDA N2 FORM REMAINDER. ERA E = LAST BIT QUOTIENT. ELB TACK ON TO REM. CMB,INB FORM DIVISOR - REMAINDER. ADB D2 CMB,SSB,INB,SZB REM >= DIV ? (B = REM - DIV) RSS NO. ISZ Q2 YES. Q <-- Q + 1 JMP FINIS GO ATTACH SIGN. SPC 4 * .DDIR - REVERSE DIVIDE. * .DDIR NOP STA Q1 JUST SET UP CALL TO .DDI STB Q2 LDA .DDIR,I ISZ .DDIR DLD A,I JSB .DDI DEF Q1 JMP .DDIR,I SKP * DIVISOR DOES NOT FIT IN ONE WORD. DO HARD WAY. * DIV2 STA Q1 ZERO OUT UPPER RESULT (A=0) STA Q2 & LOWER IN CASE HAVE 2**15 BIT. LDA D1 GET SHIFT COUNT TO MAKE DIVISOR SINGLE. JSB FLOAT RBR B = COUNT - 1 CPB =D15 WHOLE WORD ? JMP DIV10 YES, BIG DIVISOR, HANDLE SEPARATELY. ADB LSR01 NO. FORM "LSR N" STB DIV3 WILL USE IT FOUR TIMES. STB DIV4 STB DIV5 STB DIV6 LDB D1 RIGHT SHIFT DENOMINATOR. LDA D2 DIV3 LSR 16 LDB D2 STA D1 CLA DIV4 LSR 16 STA D2 LDB N2 RIGHT SHIFT NUMERATOR. CLA DIV5 LSR 16 LDB N2 STA N2 LDA B LDB N1 DIV6 LSR 16 * * (B,A) = (N0,N1). FORM TENTATIVE QUOTIENT. * DIV7 STB N0 STA N1 DIV D1 FORM IT. SOS OFL ? JMP DIV8 NO. LDB N0 YES. GEN FIRST 15 BITS, THEN REST. LDA N1 ASR 15 DIV D1 RAR,SLA IS 1 OR 2: IF 2, JMP SPEC1 (MAX NEG) / (+-32768, +-32769) STA Q2 WAS 1. VALUE IS 2**15. LDA N1 FORM REMAINDER. CLE,ERB RAL,ERA JMP DIV7 TRY AGAIN. (IT BETTER WORK THIS TIME) SKP * FORM TRUE REMAINDER. * DIV8 IOR Q2 ADD 2**15 BIT IF PRESENT. STA Q2 TENTATIVE QUOTIENT. STB N1 (N1,N2) = REMAINDER. MPY D2 ADJUST FOR D2: SUBTRACT Q2*D2 FROM REM. STA N0 (UNSIGNED MPY: UNDO CORRECTIONS FOR SIGNS) LDA Q2 SSA ADB D2 LDA D2 SSA ADB Q2 LDA N0 CMB,CLE NEGATE Q2*D2 CMA,INA (E = CARRY) ADA N2 + (N1,N2) SEZ INB ADB N1 (B,A) = TENTATIVE REMAINDER. * * IF REM < 0, DECREMENT QUOTIENT & ADD DIV TO REM. * DIV8B CLE,SSB,RSS REM < 0 ? JMP FINIS NO. ADA D2 YES. ADD DIVISOR. SEZ INB ADB D1 STB N1 FIX QUOTIENT. CCB ADB Q2 STB Q2 LDB N1 GO RECHECK. JMP DIV8B * * ATTACH SIGN. (B = RESULT LOWER) * FINIS LDB Q2 (B = 2ND WD RESULT) FINI0 LDA Q1 (A = 1ST WD RESULT) ISZ SIGN POS ? JMP FINI1 YES. CMA NO, NEGATE. CMB,INB,SZB,RSS INA FINI1 CLO "O" CLEARED. FINI2 STA Q1 RESTORE "E" & EXIT. LDA E ELA LDA Q1 (A,B) = RESULT. JMP .DDI,I EXIT. SKP * DIVISOR IN [-2**31,-2**30) OR [2**30,2**31). * DIV10 CLB DO DIVISION. D1 MAX BE MAX NEG. LDA N1 DIV D1 (0,N1) / D1 SSA SPECIAL CASE: (MAX NEG) / (MAX NEG) CMA,INA (JUST LET IT GO THRU) JMP DIV8 * * SPECIAL CASE: (MAX NEG) / (32768) = 65536. [REM=0] * (MAX NEG) / (32769) = 65534. [REM=2] * SPEC1 LDB D2 0 IF 32768, 100000 IF 32769. SSB,RSS IF 32768, ISZ Q1 UPPER WORD = 1. (65536) ASR 14 LOWER WORD: 0 OR 65534. JMP FINI0 FINISH UP. * * SPECIAL CASE: DIV BY ZERO * (MAX NEG) / (+-1) [REM=0] * SPEC2 LDB SIGN SEE IF OFL OR NOT. LDA D2 CPA =D1 D2 MUST BE 1. INB,SZB AND SIGN MUST BE < 0. JMP OFL NOPE. RAR (MAX NEG) / 1, RESULT = MAX NEG. JMP FINI1 * * OFL. DIV BY ZERO OR (MAX NEG) / (-1) * OFL LDA =B77777 (A,B) = MAX POS. CCB STO "O" SET. JMP FINI2 RESTORE "E" & EXIT. * * LOCALS. * N0 BSS 1 NUMERATOR & REMAINDER. N1 BSS 1 N2 BSS 1 D1 BSS 1 DENOMINATOR. D2 BSS 1 Q1 BSS 1 QUOTIENT. Q2 BSS 1 E BSS 1 "E" SIGN BSS 1 SIGN OF RESULT. LSR01 LSR 1 CONSTANT. UNS END