MREV: DB 33H ; 9/13/81 A. BENDER ADD PIDGIN ENTRY POINTS ;MREV: DB 32H ; 06/08/79 R. CURTISS FIX DMUL10 MOV D,H ; ;MREV: DB 31H ; 05/31/79 R. CURTISS SIGNED OPERATIONS ; ; DOUBLE SUBTRACT (HL) = (HL) - (DE) ; ENTRY ?ISUB ?ISUB: DSUB: MOV A,L SUB E ; SUBTRACT LOW BYTE MOV L,A MOV A,H SBB D ; SUBTRACT HIGH BYTE WITH BORROW MOV H,A RET ; ; ---------------------------------------- CMPEQ ; DOUBLE COMPARE (HL) - (DE) ; ; IF HL = DE THEN Z=1 ; CMPEQ: MOV A,H CMP D RNZ MOV A,L CMP E RET ; ; ; IF HL < DE THEN CY=1 -- SIGNED ?CDEHL: CMPLT: MOV A,H XRA D MOV A,H RLC ; SET CY = SIGN OF HL RM ; RETURN IF SIGNS DIFFERENT ; ; IF HL < DE THEN CY=1 -- UNSIGNED ; ENTRY ?CDEHL UCMPLT: MOV A,H CMP D RNZ MOV A,L CMP E RET ; ; ----------------------------------------- SPECIAL ; SPECIAL MULTIPLY AND DIVIDE ; ; HL = HL * 10 -- SIGNED ; DMUL10: MVI B,0 ; MINUS SIGN COUNTER CALL ICOMP ; COMPLEMENT IF NECESSARY MOV D,H MOV E,L DAD H DAD H DAD D DAD H DCR B RNZ ; RETURN IF POSITIVE JMP COMP ; COMPLEMENT RESULT ; ; ; HL = HL / 10 -- SIGNED ; DDIV10: MVI B,0 ; MINUS SIGN COUNTER CALL ICOMP PUSH B CALL UDIV10 POP B DCR B RNZ ; RETURN IF POSITIVE XCHG CALL COMP XCHG JMP COMP ; ; ; HL = HL / 10 -- UNSIGNED ; DE = HL MOD 10 ; UDIV10: LXI D,0 LXI B,05000H+12 ; B=10 C=LOOP COUNT JMP UDV10B UDV10A: XCHG DAD H ; SHIFT DE LEFT 1 BIT XCHG DAD H ; SHIFT HL LEFT 1 BIT UDV10B: MOV A,H SUB B JC UDV10C ; JUMP IF CAN'T SUBTRACT 10 MOV H,A INR E ; SET LSB OF DE TO 1 UDV10C: DCR C ; LOOP COUNT JNZ UDV10A XCHG MOV A,D RRC RRC RRC RRC ANI 0FH MOV E,A ; REMAINDER MVI D,0 RET ; ; ; HL = HL / 4 -- UNSIGNED ; UDIV4: MOV A,H DAD H DAD H DAD H DAD H DAD H DAD H MOV L,H RRC RRC ANI 3FH MOV H,A RET ; ; ------------------------------------------ NORMAL ; NORMAL MULTIPLY AND DIVIDE ; ; HL = HL * DE -- SIGNED ; ENTRY ?IMUL ?IMUL: DMULT: MVI B,0 ; MINUS SIGN COUNTER XCHG CALL ICOMP XCHG CALL ICOMP PUSH B ; SAVE MINUS SIGN COUNTER CALL UMULT POP PSW ; RECALL MINUS SIGN COUNTER ANI 1 RZ ; RETURN IF RESULT POSITIVE JMP COMP ; ; ; DOUBLE MULTIPLY (HL) = (HL) * (DE) -- UNSIGNED ; UMULT: MOV B,H ; MOVE MULTIPLICAND TO BC MOV C,L LXI H,0 ; INITIALIZE RESULT MVI A,16 ; INITIALIZE LOOP COUNT ORA A ; CLEAR CARRY PUSH PSW ; SAVE COUNT AND ZERO CARRY ; MLOOP: MOV A,D ; GET MULTIPLIER BIT RLC JNC OVER ; JUMP IF BIT ZERO DAD B OVER: POP PSW ; RECALL LOOP COUNT AND CLEAR CARRY DCR A ; DECREMENT LOOP COUNT RZ ; RETURN IF COUNT ZERO PUSH PSW ; SAVE COUNT AND ZERO CARRY DAD H ; SHIFT RESULT LEFT XCHG DAD H ; SHIFT MULTIPLIER LEFT XCHG JMP MLOOP ; ; ; HL = HL / DE -- SIGNED ; DE = HL MOD DE ; ENTRY ?IDIV ?IDIV: DDIV: MVI B,0 ; MINUS SIGN COUNTER CALL ICOMP XCHG CALL ICOMP PUSH B CALL DIV80 XCHG POP PSW ANI 1 RZ ; RETURN IF RESULT POSITIVE XCHG CALL COMP XCHG JMP COMP ; ; ; DOUBLE DIVIDE (HL) = (HL) / (DE) ; UDIV: XCHG CALL DIV80 XCHG RET ; ; DIV80: SHLD TEMP ; SAVE DIVIDEND IN TEMPORARY LXI H,BNUM ; STORE MVI M,17 ; BIT COUNT LXI B,0 ; INITIALIZE RESULT PUSH B ; SAVE RESULT ON STACK ; LOOP: MOV A,E ; GET LOW DIVISOR BYTE RAL MOV E,A ; SHIFT DIVISOR LEFT ONE BIT MOV A,D RAL MOV D,A DCR M ; DECREMENT BIT COUNT POP H ; RESTORE TEMP RESULT RZ ; RETURN IF COUNT ZERO MVI A,0 ; ADD IN CARRY ACI 0 DAD H ; SHIFT TEMP RESULT LEFT MOV B,H ; COPY HL TO AC ADD L LHLD TEMP ; GET DIVIDEND SUB L ; SUBTRACT FROM MOV C,A MOV A,B SBB H ; TEMPORARY RESULT MOV B,A PUSH B ; SAVE TEMP RESULT ON STACK JNC SKIP ; NO BORROW FROM SUBRRACT ; DAD B ; ADD DIVIDEND BACK IN XTHL ; REPLACE TEMP RESULT ON STACK ; SKIP: LXI H,BNUM ; RESTORE HL CMC ; COMPLEMENT CARRY JMP LOOP ; ; TEMP: DS 2 ; FOR M DIVIDE BNUM: DS 1 ; FOR DIVIDE ; ; ------------------------------------------- ICOMP, COMP ; TWO'S COMPLEMENT ROUTINE FOR (HL) ; ICOMP: MOV A,H ; CHECK SIGN BIT ORA A RP ; RETURN IF POSITIVE INR B ; COUNT NEGATIVE ; ENTRY ?ICOMP ?ICOMP: COMP: MOV A,H CMA ; COMPLEMENT HIGH BYTE MOV H,A MOV A,L CMA ; COMPLEMENT LOW BYTE MOV L,A INX H ; TWO'S COMPLEMENT RET ; ; END