Advertisement
Runer112

ConvOP1_fast

May 3rd, 2015
605
0
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)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement