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

  1. MREV:    DB 33H ; 9/13/81 A. BENDER  ADD PIDGIN ENTRY POINTS
  2. ;MREV: DB 32H ;    06/08/79  R. CURTISS    FIX DMUL10  MOV D,H
  3. ;
  4. ;MREV: DB 31H ;    05/31/79  R. CURTISS    SIGNED OPERATIONS
  5. ;
  6. ;  DOUBLE SUBTRACT  (HL) = (HL) - (DE)
  7. ;
  8.     ENTRY    ?ISUB
  9. ?ISUB:
  10. DSUB:    MOV    A,L
  11.     SUB    E    ; SUBTRACT LOW BYTE
  12.     MOV    L,A
  13.     MOV    A,H
  14.     SBB    D    ; SUBTRACT HIGH BYTE WITH BORROW
  15.     MOV    H,A
  16.     RET    
  17. ;
  18. ; ---------------------------------------- CMPEQ
  19. ; DOUBLE COMPARE (HL) - (DE)
  20. ;
  21. ;    IF HL = DE THEN Z=1
  22. ;
  23. CMPEQ:    MOV    A,H
  24.     CMP    D
  25.     RNZ
  26.  
  27.     MOV    A,L
  28.     CMP    E
  29.     RET
  30. ;
  31. ;
  32. ;    IF HL < DE THEN CY=1  --  SIGNED
  33. ?CDEHL:
  34. CMPLT:    MOV    A,H
  35.     XRA    D
  36.     MOV    A,H
  37.     RLC        ; SET CY = SIGN OF HL
  38.     RM        ; RETURN IF SIGNS DIFFERENT
  39. ;
  40. ;    IF HL < DE THEN CY=1  --  UNSIGNED
  41. ;
  42.     ENTRY    ?CDEHL
  43. UCMPLT:    MOV    A,H
  44.     CMP    D
  45.     RNZ
  46.  
  47.     MOV    A,L
  48.     CMP    E
  49.     RET
  50. ;
  51. ; ----------------------------------------- SPECIAL
  52. ;  SPECIAL MULTIPLY AND DIVIDE
  53. ;
  54. ;    HL = HL * 10  --  SIGNED
  55. ;
  56. DMUL10:    MVI    B,0    ; MINUS SIGN COUNTER
  57.     CALL    ICOMP    ; COMPLEMENT IF NECESSARY
  58.     MOV    D,H
  59.     MOV    E,L
  60.     DAD    H
  61.     DAD    H
  62.     DAD    D
  63.     DAD    H
  64.     DCR    B
  65.     RNZ        ; RETURN IF POSITIVE
  66.  
  67.     JMP    COMP    ; COMPLEMENT RESULT
  68. ;
  69. ;
  70. ;    HL = HL / 10  -- SIGNED
  71. ;
  72. DDIV10:    MVI    B,0    ; MINUS SIGN COUNTER
  73.     CALL    ICOMP
  74.     PUSH    B
  75.     CALL    UDIV10
  76.     POP    B
  77.     DCR    B
  78.     RNZ        ; RETURN IF POSITIVE
  79.  
  80.     XCHG
  81.     CALL    COMP
  82.     XCHG
  83.     JMP    COMP
  84. ;
  85. ;
  86. ;    HL = HL / 10  --  UNSIGNED
  87. ;    DE = HL MOD 10
  88. ;
  89. UDIV10:    LXI    D,0
  90.     LXI    B,05000H+12  ; B=10  C=LOOP COUNT
  91.     JMP    UDV10B
  92.  
  93. UDV10A:    XCHG
  94.     DAD    H    ; SHIFT DE LEFT 1 BIT
  95.     XCHG
  96.     DAD    H    ; SHIFT HL LEFT 1 BIT
  97.  
  98. UDV10B:    MOV    A,H
  99.     SUB    B
  100.     JC    UDV10C    ; JUMP IF CAN'T SUBTRACT 10
  101.  
  102.     MOV    H,A
  103.     INR    E    ; SET LSB OF DE TO 1
  104.  
  105. UDV10C:    DCR    C    ; LOOP COUNT
  106.     JNZ    UDV10A
  107.  
  108.     XCHG
  109.     MOV    A,D
  110.     RRC
  111.     RRC
  112.     RRC
  113.     RRC
  114.     ANI    0FH
  115.     MOV    E,A    ; REMAINDER
  116.     MVI    D,0
  117.     RET
  118. ;
  119. ;
  120. ;    HL = HL / 4  --  UNSIGNED
  121. ;
  122. UDIV4:    MOV    A,H
  123.     DAD    H
  124.     DAD    H
  125.     DAD    H
  126.     DAD    H
  127.     DAD    H
  128.     DAD    H
  129.     MOV    L,H
  130.     RRC
  131.     RRC
  132.     ANI    3FH
  133.     MOV    H,A
  134.     RET
  135. ;
  136. ; ------------------------------------------ NORMAL
  137. ;    NORMAL MULTIPLY AND DIVIDE
  138. ;
  139. ;    HL = HL * DE  --  SIGNED
  140. ;
  141.     ENTRY    ?IMUL
  142. ?IMUL:
  143. DMULT:    MVI    B,0    ; MINUS SIGN COUNTER
  144.     XCHG
  145.     CALL    ICOMP
  146.     XCHG
  147.     CALL    ICOMP
  148.     PUSH    B    ; SAVE MINUS SIGN COUNTER
  149.     CALL    UMULT
  150.     POP    PSW    ; RECALL MINUS SIGN COUNTER
  151.     ANI    1
  152.     RZ        ; RETURN IF RESULT POSITIVE
  153.  
  154.     JMP    COMP
  155. ;
  156. ;
  157. ;  DOUBLE MULTIPLY  (HL) = (HL) * (DE)  --  UNSIGNED
  158. ;
  159. UMULT:    MOV    B,H    ; MOVE MULTIPLICAND TO BC
  160.     MOV    C,L
  161.     LXI    H,0    ; INITIALIZE RESULT
  162.     MVI    A,16    ; INITIALIZE LOOP COUNT
  163.     ORA    A    ; CLEAR CARRY
  164.     PUSH    PSW    ; SAVE COUNT AND ZERO CARRY
  165. ;
  166. MLOOP:    MOV    A,D    ; GET MULTIPLIER BIT
  167.     RLC    
  168.     JNC    OVER    ; JUMP IF BIT ZERO
  169.  
  170.     DAD    B
  171.  
  172. OVER:    POP    PSW    ; RECALL LOOP COUNT AND CLEAR CARRY
  173.     DCR    A    ; DECREMENT LOOP COUNT
  174.     RZ        ; RETURN IF COUNT ZERO
  175.  
  176.     PUSH    PSW    ; SAVE COUNT AND ZERO CARRY
  177.     DAD    H    ; SHIFT RESULT LEFT
  178.     XCHG    
  179.     DAD    H    ; SHIFT MULTIPLIER LEFT
  180.     XCHG    
  181.     JMP    MLOOP
  182. ;
  183. ;
  184. ;    HL = HL / DE  --  SIGNED
  185. ;    DE = HL MOD DE
  186. ;
  187.     ENTRY    ?IDIV
  188. ?IDIV:
  189. DDIV:    MVI    B,0    ; MINUS SIGN COUNTER
  190.     CALL    ICOMP
  191.     XCHG
  192.     CALL    ICOMP
  193.     PUSH    B
  194.     CALL    DIV80
  195.     XCHG
  196.     POP    PSW
  197.     ANI    1
  198.     RZ        ; RETURN IF RESULT POSITIVE
  199.  
  200.     XCHG
  201.     CALL    COMP
  202.     XCHG
  203.     JMP    COMP
  204. ;
  205. ;
  206. ;  DOUBLE DIVIDE    (HL) = (HL) / (DE)
  207. ;
  208. UDIV:    XCHG    
  209.     CALL    DIV80
  210.     XCHG    
  211.     RET    
  212. ;
  213. ;
  214. DIV80:    SHLD    TEMP    ; SAVE DIVIDEND IN TEMPORARY
  215.     LXI    H,BNUM    ; STORE
  216.     MVI    M,17    ; BIT COUNT
  217.     LXI    B,0    ; INITIALIZE RESULT
  218.     PUSH    B    ; SAVE RESULT ON STACK
  219. ;
  220. LOOP:    MOV    A,E    ; GET LOW DIVISOR BYTE
  221.     RAL    
  222.     MOV    E,A    ; SHIFT DIVISOR LEFT ONE BIT
  223.     MOV    A,D
  224.     RAL    
  225.     MOV    D,A
  226.     DCR    M    ; DECREMENT BIT COUNT
  227.     POP    H    ; RESTORE TEMP RESULT
  228.     RZ        ; RETURN IF COUNT ZERO
  229.  
  230.     MVI    A,0    ; ADD IN CARRY
  231.     ACI    0
  232.     DAD    H    ; SHIFT TEMP RESULT LEFT
  233.     MOV    B,H    ; COPY HL TO AC
  234.     ADD    L
  235.     LHLD    TEMP    ; GET DIVIDEND
  236.     SUB    L    ; SUBTRACT FROM
  237.     MOV    C,A
  238.     MOV    A,B
  239.     SBB    H    ; TEMPORARY RESULT
  240.     MOV    B,A
  241.     PUSH    B    ; SAVE TEMP RESULT ON STACK
  242.     JNC    SKIP    ; NO BORROW FROM SUBRRACT
  243. ;
  244.     DAD    B    ; ADD DIVIDEND BACK IN
  245.     XTHL        ; REPLACE TEMP RESULT ON STACK
  246. ;
  247. SKIP:    LXI    H,BNUM    ; RESTORE HL
  248.     CMC        ; COMPLEMENT CARRY
  249.     JMP    LOOP
  250. ;
  251. ;
  252. TEMP:    DS    2    ; FOR M   DIVIDE
  253. BNUM:    DS    1    ; FOR DIVIDE
  254. ;
  255. ; ------------------------------------------- ICOMP, COMP
  256. ;  TWO'S COMPLEMENT ROUTINE FOR (HL)
  257. ;
  258. ICOMP:    MOV    A,H    ; CHECK SIGN BIT
  259.     ORA    A
  260.     RP        ; RETURN IF POSITIVE
  261.  
  262.     INR    B    ; COUNT NEGATIVE
  263. ;
  264.     ENTRY    ?ICOMP
  265. ?ICOMP:
  266. COMP:    MOV    A,H
  267.     CMA        ; COMPLEMENT HIGH BYTE
  268.     MOV    H,A
  269.     MOV    A,L
  270.     CMA        ; COMPLEMENT LOW BYTE
  271.     MOV    L,A
  272.     INX    H    ; TWO'S COMPLEMENT
  273.     RET    
  274. ;
  275. ;
  276.     END
  277.