home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol043
/
pidmath.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
4KB
|
277 lines
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