SHARE
TWEET

ConvOP1_fast

Runer112 May 3rd, 2015 (edited) 286 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;Attempts to convert the TI float in OP1 into an unsigned integer in HL.
  2. ;
  3. ;Throws:
  4. ; - A data type error if OP1 doesn't hold a nonnegative real number.
  5. ; - A domain error if the value cannot be exactly converted to an unsigned
  6. ;   16-bit integer.
  7. ;
  8. ;Don't try to hijack this routine with a pointer other than OP1. It won't work.
  9. ;
  10. ; I: (OP1)=float
  11. ; O: A=0, BC=?, DE=OP1+8, HL=(uint)(OP1)
  12. ;FO: S=0, Z=1, H=0, P/V=0, N=1, C=0
  13. ;CC: 69 + 154*((d+1)/2) + 131*(d/2) + (d%2 ? 21 : 12) + 43*(7-((d+1)/2)
  14. ;    d = (OP1)!=0 ? floor(log10((OP1))) + 1 : 1
  15. ConvOP1:
  16. ;Throws an error if OP1 doesn't hold a nonnegative real number.
  17.         ld      de,OP1
  18.         ld      a,(de)
  19.         or      a
  20.         jr      nz,ErrDataType
  21. ;Initializes the 16-bit accumulator to 0 and reads the exponent.
  22.         ld      h,a
  23.         ld      l,a
  24.         inc     e
  25.         ld      a,(de)
  26. ConvOP1_Loop:
  27. ;Saves the exponent.
  28.         push    af
  29. ;Reads the high nibble/digit of the next mantissa byte.
  30.         inc     e
  31.         ld      a,(de)
  32. ;Multiplies the 16-bit accumulator by 10, checking for overflow where necessary,
  33. ;and shifts the high digit right by 4 bits into normal position.
  34.         ld      b,h
  35.         ld      c,l
  36.         add     hl,hl
  37.         rra
  38.         add     hl,hl
  39.         rra
  40.         add     hl,bc           ;9999*4=39996+9999=49995, cannot overflow yet
  41.         rra
  42.         add     hl,hl           ;9999*5=49995*2=99990, can now overflow
  43.         jr      c,ErrDomain
  44.         rra
  45. ;Adds the now shifted high digit to the 16-bit accumulator, checking for
  46. ;overflow.
  47.         ld      b,0
  48.         ld      c,a
  49.         add     hl,bc
  50.         jr      c,ErrDomain     ;65530+9=65539, can still overflow
  51. ;Restores the exponent, decrements it, and breaks out if it becomes $7F. Doesn't
  52. ;care about bad exponents, as the 16-bit accumulator would overflow eventually.
  53.         pop     af
  54.         dec     a
  55.         jp      pe,ConvOP1_DoneMidByte
  56. ;Multiplies the 16-bit accumulator by 10, checking for overflow where necessary.
  57.         add     hl,hl           ;40000*2=80000, can still overflow
  58.         jr      c,ErrDomain
  59.         ld      b,h
  60.         ld      c,l
  61.         add     hl,hl           ;20000*2=40000*2=80000, can still overflow
  62.         jr      c,ErrDomain
  63.         add     hl,hl           ;10000*4=40000*2=80000, can still overflow
  64.         jr      c,ErrDomain
  65.         add     hl,bc           ;any 5-digit number has already overflowed
  66. ;Reads the low nibble/digit of the current mantissa byte and adds it to the
  67. ;16-bit accumulator.
  68.         ld      b,a
  69.         ld      a,(de)
  70.         and     $0F
  71.         ld      c,a
  72.         ld      a,b
  73.         ld      b,0
  74.         add     hl,bc
  75. ;Decrements the exponent and continues looping if it doesn't become $7F.
  76.         dec     a
  77.         jp      po,ConvOP1_Loop
  78. ;Skips conversion-finished-mid-byte code.
  79.         jr      ConvOP1_CheckIntLoop
  80. ConvOP1_DoneMidByte:
  81. ;Throws an error if the low nibble/digit of this mantissa byte is nonzero.
  82.         ld      a,(de)
  83.         and     $0F
  84.         jr      nz,ErrDomain
  85. ConvOP1_CheckIntLoop:
  86. ;Returns successfully if the last byte of the mantissa has been checked.
  87. #ifdef 83p
  88.         or      e
  89.         ret     m
  90. #else
  91.         ld      a,(OP1+8)&$FF
  92.         sub     e
  93.         ret     z
  94. #endif
  95. ;Continues if the next byte of the mantissa is zero.
  96.         inc     e
  97.         ld      a,(de)
  98.         or      a
  99.         jr      z,ConvOP1_CheckIntLoop
  100. ErrDomain:
  101. ;Throws a domain error.
  102.         B_CALL(_ErrDomain)
  103. ErrDataType:
  104. ;Throws a data type error.
  105.         B_CALL(_ErrDataType)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top