home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / programming / assembly / talinasm.lha / ilog.asm < prev    next >
Encoding:
Assembly Source File  |  1990-03-31  |  8.2 KB  |  200 lines

  1. *==========================================================================*
  2. *  ILog.asm -- Fast integer log and antilog routines                       *
  3. *  By Talin. (c) 1990 Sylvan Technical Arts.                               *
  4. *==========================================================================*
  5. *  Format of lograrithms:                                                  *
  6. *       These routines represent logarithms as a 32-bit value, where the   *
  7. *       upper 16 bits are the characteristic, and the lower 16 bits are    *
  8. *       the mantissa.                                                      *
  9. *       Both routines deal with logs to the base 2. These can be converted *
  10. *       other bases by multiplying by the appropriate constant.            *
  11. *                                                                          *
  12. *  Notes:                                                                  *
  13. *       None of these routines require any data segment references.        *
  14. *==========================================================================*
  15.  
  16.         xdef    _IntLg
  17.         xdef    IntLg
  18.         xdef    _IntAlg
  19.         xdef    IntAlg
  20.  
  21. *==========================================================================*
  22. *  IntLg                                                                   *
  23. *      Inputs:  d0 = 32-bit integer value                                  *
  24. *      Outputs: d0 = logarithm in standard format                          *
  25. *      Scratch: d1,d2,a0                                                   *
  26. *      Max Error: 1 part in 100,000                                        *
  27. *==========================================================================*
  28.  
  29. _IntLg:
  30.         move.l    4(sp),d0
  31. IntLg:
  32.         tst.l    d0                        ; test number to see if it's zero
  33.         beq.s    9$                        ; if number is zero, log is impossible...
  34.  
  35.         moveq    #32,d1                    ; d1 <-- characteristic (init 32)
  36.  
  37.         cmp.l    #$10000,d0                ; if top 16 bits empty
  38.         bhs.s    1$                        ; then
  39.         swap    d0                        ; shift over 16 bits
  40.         clr.w    d0                        ; clear lower bits...
  41.         moveq    #16,d1                    ; and subtract 16 from characteristic.
  42.  
  43. 1$        cmp.l    #$1000000,d0            ; if top 8 bits empty
  44.         bhs.s    2$                        ; then
  45.         lsl.l    #8,d0                    ; shift over 8 bits
  46.         subq.l    #8,d1                    ; subtract 8 from characteristic
  47.  
  48. 2$        subq    #1,d1                    ; subtract 1 from characteristic.
  49.         add.l    d0,d0                    ; shift over by 1
  50.         bcc.s    2$                        ; do until carry is set.
  51.  
  52. ; at this point, the carry is set with the topmost bit.
  53. ; the next 8 bits are in the lookup, and any bits leftover will be used for the
  54. ; interpolation.
  55.  
  56.         lsr.l    #8,d0                    ; d0 <-- 00aabbbb
  57.         move.w    d0,-(sp)                ; save interpolation bits...
  58.         swap    d0                        ; d0 <-- bbbb00aa
  59.         add.w    d0,d0                    ; d0 = lookup value
  60.         lea        logtable2,a0            ; address of log table
  61.         add.w    d0,a0                    ; add offset to table address
  62.         move.w    (a0)+,d0                ; get the log value
  63.         move.w    (a0),d2                    ; get the next log value after that
  64.         sub.w    d0,d2                    ; get difference between table entries.
  65.         mulu.w    (sp)+,d2                ; times the interpolation bits
  66.         swap    d2                        ; get high word
  67.         add.w    d2,d0                    ; add to log value
  68. ; bcs here???
  69.         swap    d0                        ; prepare to insert characteristic
  70.         move.w    d1,d0                    ; insert it
  71.         swap    d0                        ; return.
  72.  
  73.         rts                                ; return a long: cccc.mmmm
  74.  
  75. 9$        moveq    #-1,d0
  76.         rts
  77.  
  78. logtable2:
  79.         dc.w    00000,00369,00736,01102,01466,01829,02190,02551
  80.         dc.w    02909,03267,03623,03978,04331,04683,05034,05384
  81.         dc.w    05732,06079,06425,06769,07112,07454,07795,08134
  82.         dc.w    08473,08810,09146,09480,09814,10146,10477,10807
  83.         dc.w    11136,11464,11791,12116,12440,12764,13086,13407
  84.         dc.w    13727,14046,14363,14680,14996,15311,15624,15937
  85.         dc.w    16248,16559,16868,17177,17484,17791,18096,18401
  86.         dc.w    18704,19007,19308,19609,19909,20207,20505,20802
  87.         dc.w    21098,21393,21687,21980,22272,22564,22854,23144
  88.         dc.w    23433,23720,24007,24293,24579,24863,25146,25429
  89.         dc.w    25711,25992,26272,26551,26830,27108,27384,27660
  90.         dc.w    27936,28210,28484,28757,29029,29300,29571,29840
  91.         dc.w    30109,30378,30645,30912,31178,31443,31707,31971
  92.         dc.w    32234,32496,32758,33019,33279,33538,33797,34055
  93.         dc.w    34312,34569,34825,35080,35334,35588,35841,36094
  94.         dc.w    36346,36597,36847,37097,37346,37595,37842,38090
  95.         dc.w    38336,38582,38827,39072,39316,39559,39802,40044
  96.         dc.w    40286,40527,40767,41006,41246,41484,41722,41959
  97.         dc.w    42196,42432,42667,42902,43137,43370,43603,43836
  98.         dc.w    44068,44300,44530,44761,44991,45220,45448,45676
  99.         dc.w    45904,46131,46357,46583,46809,47034,47258,47482
  100.         dc.w    47705,47928,48150,48372,48593,48813,49034,49253
  101.         dc.w    49472,49691,49909,50127,50344,50560,50776,50992
  102.         dc.w    51207,51422,51636,51850,52063,52276,52488,52700
  103.         dc.w    52911,53122,53332,53542,53751,53960,54169,54377
  104.         dc.w    54584,54791,54998,55204,55410,55615,55820,56025
  105.         dc.w    56229,56432,56635,56838,57040,57242,57443,57644
  106.         dc.w    57845,58045,58245,58444,58643,58841,59039,59237
  107.         dc.w    59434,59631,59827,60023,60219,60414,60609,60803
  108.         dc.w    60997,61190,61384,61576,61769,61961,62152,62343
  109.         dc.w    62534,62725,62915,63104,63294,63483,63671,63859
  110.         dc.w    64047,64234,64421,64608,64794,64980,65166,65351
  111.         dc.w    00000
  112.  
  113. *==========================================================================*
  114. *  IntAlg
  115. *      Inputs:  d0 = logarithm in standard format
  116. *      Outputs: d0 = 32-bit integer value
  117. *      Scratch: d1,d2,a0
  118. *      Max Error: 1 part in 30,000
  119. *==========================================================================*
  120.  
  121. _IntAlg:
  122.         move.l    4(sp),d0
  123. IntAlg:
  124.         move.w    d0,d1                    ; get mantissa
  125.  
  126.         lsr.w    #8,d1                    ; get the "lookup" part.
  127.         add.w    d1,d1                    ; times 2 for table
  128.  
  129.         lea        alogtable,a0            ; address of antilog table
  130.         add.w    d1,a0                    ; plus offset
  131.  
  132.         move.w    (a0)+,d1                ; get the digits to use.
  133.         move.w    (a0),d2                    ; get the next value too
  134.         sub.w    d1,d2                    ; distance between table entries
  135.  
  136. ; now we need to interpolate.
  137.         lsl.w    #8,d0                    ; adjust interpolation bits
  138.         add.w    #128,d0                    ; add rounding factor??
  139.         mulu.w    d0,d2                    ; times interpolation factor
  140.         swap    d2                        ; get high word
  141.         add.w    d2,d1                    ; and adjust result.
  142.  
  143. ; now we have 16 bits in the lower half of d1, and the upper half of d1 is how
  144. ; many to shift them over...
  145.  
  146.         swap    d1                        ; put it in the top
  147.         bset    #0,d1                    ; make the lowest bit a 1
  148.         ror.l    #1,d1                    ; make the leading bit a 1, shift others over
  149.  
  150.         swap    d0                        ; get bits to shift.
  151.         cmp.w    #32,d0                    ; if d0 > 33
  152.         bhs.s    9$                        ; then fail, we can't alog this.
  153.         eor.b    #31,d0                    ; reverse direction of shift
  154.  
  155.         lsr.l    d0,d1                    ; rotate number
  156.         moveq    #0,d0                    ; clear d0
  157.         addx.l    d0,d1                    ; round using carry bit
  158.         move.l    d1,d0                    ; put in d0
  159.         rts                                ; return
  160.  
  161. 9$        moveq    #0,d0                    ; return 0 (value that can neve be logged)
  162.         rts                                ; return
  163.  
  164. alogtable:
  165.         dc.w    00000,00178,00356,00535,00714,00893,01073,01254
  166.         dc.w    01435,01617,01799,01981,02164,02348,02532,02716
  167.         dc.w    02902,03087,03273,03460,03647,03834,04022,04211
  168.         dc.w    04400,04590,04780,04971,05162,05353,05546,05738
  169.         dc.w    05932,06125,06320,06514,06710,06906,07102,07299
  170.         dc.w    07496,07694,07893,08092,08292,08492,08693,08894
  171.         dc.w    09096,09298,09501,09704,09908,10113,10318,10524
  172.         dc.w    10730,10937,11144,11352,11560,11769,11979,12189
  173.         dc.w    12400,12611,12823,13036,13249,13462,13676,13891
  174.         dc.w    14106,14322,14539,14756,14974,15192,15411,15630
  175.         dc.w    15850,16071,16292,16514,16737,16960,17183,17408
  176.         dc.w    17633,17858,18084,18311,18538,18766,18995,19224
  177.         dc.w    19454,19684,19915,20147,20379,20612,20846,21080
  178.         dc.w    21315,21550,21786,22023,22260,22498,22737,22977
  179.         dc.w    23216,23457,23698,23940,24183,24426,24670,24915
  180.         dc.w    25160,25406,25652,25900,26148,26396,26645,26895
  181.         dc.w    27146,27397,27649,27902,28155,28409,28664,28919
  182.         dc.w    29175,29432,29690,29948,30207,30466,30727,30988
  183.         dc.w    31249,31512,31775,32039,32303,32568,32834,33101
  184.         dc.w    33369,33637,33906,34175,34446,34717,34988,35261
  185.         dc.w    35534,35808,36083,36359,36635,36912,37190,37468
  186.         dc.w    37747,38028,38308,38590,38872,39155,39439,39724
  187.         dc.w    40009,40295,40582,40870,41158,41448,41738,42029
  188.         dc.w    42320,42613,42906,43200,43495,43790,44087,44384
  189.         dc.w    44682,44981,45280,45581,45882,46184,46487,46791
  190.         dc.w    47095,47401,47707,48014,48322,48631,48940,49251
  191.         dc.w    49562,49874,50187,50500,50815,51131,51447,51764
  192.         dc.w    52082,52401,52721,53041,53363,53685,54008,54333
  193.         dc.w    54658,54983,55310,55638,55966,56296,56626,56957
  194.         dc.w    57289,57622,57956,58291,58627,58964,59301,59640
  195.         dc.w    59979,60319,60661,61003,61346,61690,62035,62381
  196.         dc.w    62727,63075,63424,63774,64124,64476,64828,65182
  197.         dc.w    00000
  198.  
  199.         end
  200.