home *** CD-ROM | disk | FTP | other *** search
- 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
-