home *** CD-ROM | disk | FTP | other *** search
/ ticalc.org / ticalc_org_rev_b.iso / archives / 85 / asm / source / routines / cosintan.asm < prev    next >
Encoding:
Assembly Source File  |  2001-07-01  |  8.5 KB  |  273 lines

  1. ; Date:     Wed, 15 May 1996 22:27:55 -0400 (EDT)
  2. ; From:     Jingyang Xu  [br00416@bingsuns.cc.binghamton.edu]
  3. ; Subject:  LZ: Trig Routines: SIN/COS/TAN
  4.  
  5. ; Someone asked me about these and here are the bug-free version of my
  6. ; sin/cos/tan routines:
  7.  
  8. ; Note that sin and cos uses the same table and tan uses its own table.
  9. ; The arguments to sinx and cosx are: a=multiplier bc=angle
  10. ; and the return is now in bc: b=integer part c=fractional part.
  11. ; So bc is a 16 bit signed number, the key here is signed - if the high bit
  12. ; of b is set, that means bc is the twos complement of the positive value
  13. ; of bc.
  14. ; For the tangent routine. de is the multiplier (this is a 16 bit
  15. ; multiplier) and hl is the angle. I think it returns the result in hl, in
  16. ; the same format as that for bc.
  17.  
  18. AdjustAngleinBC:
  19.     xor     a
  20.     cp      b
  21.     jr      z,Alldone
  22.     ld      h,b
  23.     ld      l,c
  24.     ld      bc,360
  25.     and     a
  26.     sbc     hl,bc
  27.     jr      nc,AAHalfDone
  28.     add     hl,bc
  29. AAHalfDone:
  30.     ld      b,h
  31.     ld      c,l
  32.     jr      Alldone
  33. Alldone:
  34.     ret
  35.  
  36. sinx:
  37.     push    af              ;save argument
  38.     ld      d,1             ;d=1, use for later
  39.     ld      hl,180
  40.     and     a               ;clear carry
  41.     sbc     hl,bc
  42.     jr      nc,LessE180    ;is angle greater than 180 degrees?
  43.  
  44. Great180:            
  45.     ld      h,b             ;
  46.     ld      l,c             ;load bc into hl
  47.     ld      bc,180          ;
  48.     and     a               ; bc=bc-180
  49.     sbc     hl,bc           ;
  50.     ld      b,h             ; 
  51.     ld      c,l             ;load hl into bc
  52.     inc     d               ; d=2, remember negated
  53. LessE180:          ;0<=bc<=180 -> 0 is in b and 0<=c<=180
  54.     ld      a,d             ;save d
  55.     ld      de,(PROGRAM_ADDR)
  56.     ld      hl,Trig_Look_Up ;hl=addr of table
  57.     add     hl,de
  58.     ld      d,a             ;restore d
  59.     ld      a,c             ;load angle into accumulator
  60.     cp      90              ;is it 90 degrees?
  61.     jr      nz,not90
  62.     ld      a,128           ;if 90 degrees, sin90=1
  63.     jr      sinloaded
  64. not90:
  65.     sub     90
  66.     jr      nc,Greater90    ;is angle less than or greater than 90
  67. Less90:
  68.     add     hl,bc           ;if less than, go directly to table
  69.     ld      a,(hl)
  70.     jr      sinloaded
  71. Greater90:
  72.     ld      a,180           ;if greater, sin(x)=sin(180-x)
  73.     sub     c               ;subtract from 180
  74.     ld      c,a
  75.     add     hl,bc           ;read from table
  76.     ld      a,(hl)
  77. sinloaded:                      ;x/128 is in a, d will determine sign
  78.     ld      b,a             ;save result
  79.     pop     af              ;get multiplicand back
  80.     bit     7,a             ;test to see if a is negative
  81.     jr      z,apositive
  82.     neg                     ;if negative, negate
  83.     inc     d               ;store negative memory in d
  84. apositive:                      ;now we want a*b/128
  85.     ld      e,a             ;save a
  86.     ld      a,b             ;
  87.     cp      0               ;see if e=0
  88.     jr      z,multiplyby0   ;
  89.     ld      c,0
  90.     xor     a
  91. sinmultiplyloop:
  92.     add     a,e
  93.     jr      nc,nocarry      ;multipy a by b
  94.     inc     c               ;16bit result in ca
  95. nocarry:
  96.     djnz    sinmultiplyloop         
  97.     rl      a               ;shift ca to the left
  98.     rl      c               ;ca/128 now in c
  99.     ld      b,c
  100.     ld      c,a
  101.     dec     d
  102.         jr      z,sinxend
  103.         and     a
  104.         ld      hl,0
  105.         sbc     hl,bc
  106.         ld      b,h
  107.         ld      c,l
  108.     dec     d
  109.         jr      z,sinxend
  110.         and     a
  111.         ld      hl,0
  112.         sbc     hl,bc
  113.         ld      b,h
  114.         ld      c,l
  115.     dec     d
  116.     jr      z,sinxend
  117. multiplyby0:
  118.     ld      bc,0
  119. sinxend:
  120.     ret
  121.  
  122. cosx:
  123.     ld      hl,90
  124.     add     hl,bc
  125.     ld      b,h
  126.     ld      c,l
  127.     ld      d,a
  128.     CALL_(AdjustAngleinBC)
  129.     ld      a,d
  130.     CALL_(sinx)
  131.     ret           
  132.  
  133. Trig_Look_Up:
  134.     .db     0,2,4,6,8,11,13,15,17,20
  135.     .db     22,24,26,28,30,33,35,37,39,41
  136.     .db     43,45,47,50,52,54,56,58,60,62
  137.     .db     64,65,67,69,71,73,75,77,78,80
  138.     .db     82,83,85,87,88,90,92,93,95,96
  139.     .db     98,99,100,102,103,104,106,107,108,109
  140.     .db     110,111,113,114,115,116,116,117,118,119
  141.     .db     120,121,121,122,123,123,124,124,125,125
  142.     .db     126,126,126,127,127,127,127,127,127,127
  143.  
  144. tanx:                                   ;multiplier in de, angle in hl
  145.         push    de
  146.         push    de                      ;save multiplier
  147.         
  148.         ld      b,h                     ;make another copy of angle in bc
  149.         ld      c,l                     ;
  150.         
  151.         ld      de,180                  ;subtract 180 from
  152.         and     a                       ;angle to see if it is
  153.         sbc     hl,de                   ;greater than 180
  154.  
  155.         jr      c,tanLess180            ;if not, goto tanless180
  156.         
  157.         ld      b,h                     ;if greater than 180, load angle
  158.         ld      c,l                     ;minus 180 into bc
  159. tanLess180:                             ;bc has the semi-reference
  160.         inc     d                       ;load 1 into d
  161.         ld      hl,90                   ;subtract angle from 90
  162.         and     a                       ;to see if it is less than
  163.         sbc     hl,bc                   ;90
  164.         jr      nc,tanLess90            ;if so, jump to tanless90
  165.         ld      hl,180                  ;if greater, load 180 into hl
  166.         and     a                       ;subtract angle from it
  167.         sbc     hl,bc                   ;
  168.         inc     d                       ;load 2 into d
  169.         ld      b,h                     ;save final reference in bc
  170.         ld      c,l                     ;
  171. tanLess90:                              ;already has reference angle
  172.         sla     c                       ;multiply bc by 2
  173.         rl      b                       ;
  174.         ld      a,d                     ;preserves d
  175.         ld      de,(PROGRAM_ADDR)       ;reference the table
  176.         ld      hl,Tan_Table            ;
  177.         add     hl,de                   ;
  178.         add     hl,bc                   ;
  179.         ld      d,(hl)                  ;
  180.         inc     hl                      ;load result into de
  181.         ld      e,(hl)                  ;
  182.         ld      h,a                     ;whatever we had in d before
  183.         dec     h                       ;see if h=1 or 2
  184.         jr      z,tanNotNegative        ;if 1, positive
  185.         set     7,d                     ;if result negative, then tell it so
  186. tanNotNegative:                         ;guess what
  187.         pop     hl                      ;get multiplier
  188.         CALL_(MulDEbyHL)                ;multiply the result by the multiplier
  189.         push    af
  190.         ld      h,c
  191.         ld      l,d
  192.         bit     7,e
  193.         jr      z,TanRoundDown
  194.         inc     hl
  195. TanRoundDown:
  196.         pop     af
  197.         jr      z,ResPositive
  198.         ex      de,hl
  199.         ld      hl,0
  200.         and     a
  201.         sbc     hl,de
  202.         pop     de
  203.         ret
  204. ResPositive:                  
  205.         pop     de
  206.         ret
  207.  
  208. MulDEbyHL:
  209.         ld      ix,TempLine
  210.         bit     7,d
  211.         jr      z,DEPositive
  212.         res     7,d
  213.         bit     7,h
  214.         jr      z,HLPositive
  215.         res     7,h
  216.         jr      DEPositive
  217. HLPositive:
  218.         set     7,h
  219. DEPositive:
  220.         ld      (ix+0),h
  221.         ld      (ix+1),l
  222.         ld      b,8
  223.         xor     a
  224.         ld      c,a
  225.         ld      hl,0
  226. MulLoop1:        
  227.         rrc     (ix+1)
  228.         jr      nc,NoAdd1
  229.         add     hl,de
  230.         adc     a,c
  231. NoAdd1:
  232.         sla     e
  233.         rl      d
  234.         rl      c
  235.         djnz    MulLoop1
  236.         ld      b,7
  237.         ld      e,d
  238.         ld      d,c
  239.         ld      c,0
  240.         rl      c
  241.         ld      (ix+5),l
  242.         ld      l,h
  243.         ld      h,a
  244.         xor     a
  245. MulLoop2:        
  246.         rrc     (ix+0)
  247.         jr      nc,NoAdd2
  248.         add     hl,de
  249.         adc     a,c
  250. NoAdd2:
  251.         sla     e
  252.         rl      d
  253.         rl      c
  254.         djnz    MulLoop2
  255.         ld      b,a
  256.         ld      c,h
  257.         ld      d,l
  258.         ld      e,(ix+5)
  259.         bit     0,(ix+0)
  260.         ret
  261.         
  262. Tan_Table:
  263.         .db     0,0,0,4,0,9,0,13,0,18,0,22,0,27,0,31,0,36,0,41
  264.         .db     0,45,0,50,0,54,0,59,0,64,0,69,0,73,0,78,0,83,0,88
  265.         .db     0,93,0,98,0,103,0,109,0,114,0,119,0,125,0,130,0,136,0,142
  266.         .db     0,148,0,154,0,160,0,166,0,173,0,179,0,186,0,193,0,200,0,207
  267.         .db     0,215,0,223,0,231,0,239,0,247,1,0,1,9,1,19,1,28,1,38
  268.         .db     1,49,1,60,1,72,1,84,1,96,1,110,1,124,1,138,1,154,1,170
  269.         .db     1,187,1,206,1,225,1,246,2,13,2,37,2,63,2,91,2,122,2,155
  270.         .db     2,191,2,231,3,20,3,69,3,125,3,187,4,3,4,85,4,180,5,37
  271.         .db     5,172,6,80,7,30,8,37,9,132,11,110,14,77,19,21,28,163,57,74
  272.  
  273.