Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;Attempts to convert the TI float in OP1 into an unsigned integer in HL.
- ;
- ;Throws:
- ; - A data type error if OP1 doesn't hold a nonnegative real number.
- ; - A domain error if the value cannot be exactly converted to an unsigned
- ; 16-bit integer.
- ;
- ;Don't try to hijack this routine with a pointer other than OP1. It won't work.
- ;
- ; I: (OP1)=float
- ; O: A=0, BC=?, DE=OP1+8, HL=(uint)(OP1)
- ;FO: S=0, Z=1, H=0, P/V=0, N=1, C=0
- ;CC: 69 + 154*((d+1)/2) + 131*(d/2) + (d%2 ? 21 : 12) + 43*(7-((d+1)/2)
- ; d = (OP1)!=0 ? floor(log10((OP1))) + 1 : 1
- ConvOP1:
- ;Throws an error if OP1 doesn't hold a nonnegative real number.
- ld de,OP1
- ld a,(de)
- or a
- jr nz,ErrDataType
- ;Initializes the 16-bit accumulator to 0 and reads the exponent.
- ld h,a
- ld l,a
- inc e
- ld a,(de)
- ConvOP1_Loop:
- ;Saves the exponent.
- push af
- ;Reads the high nibble/digit of the next mantissa byte.
- inc e
- ld a,(de)
- ;Multiplies the 16-bit accumulator by 10, checking for overflow where necessary,
- ;and shifts the high digit right by 4 bits into normal position.
- ld b,h
- ld c,l
- add hl,hl
- rra
- add hl,hl
- rra
- add hl,bc ;9999*4=39996+9999=49995, cannot overflow yet
- rra
- add hl,hl ;9999*5=49995*2=99990, can now overflow
- jr c,ErrDomain
- rra
- ;Adds the now shifted high digit to the 16-bit accumulator, checking for
- ;overflow.
- ld b,0
- ld c,a
- add hl,bc
- jr c,ErrDomain ;65530+9=65539, can still overflow
- ;Restores the exponent, decrements it, and breaks out if it becomes $7F. Doesn't
- ;care about bad exponents, as the 16-bit accumulator would overflow eventually.
- pop af
- dec a
- jp pe,ConvOP1_DoneMidByte
- ;Multiplies the 16-bit accumulator by 10, checking for overflow where necessary.
- add hl,hl ;40000*2=80000, can still overflow
- jr c,ErrDomain
- ld b,h
- ld c,l
- add hl,hl ;20000*2=40000*2=80000, can still overflow
- jr c,ErrDomain
- add hl,hl ;10000*4=40000*2=80000, can still overflow
- jr c,ErrDomain
- add hl,bc ;any 5-digit number has already overflowed
- ;Reads the low nibble/digit of the current mantissa byte and adds it to the
- ;16-bit accumulator.
- ld b,a
- ld a,(de)
- and $0F
- ld c,a
- ld a,b
- ld b,0
- add hl,bc
- ;Decrements the exponent and continues looping if it doesn't become $7F.
- dec a
- jp po,ConvOP1_Loop
- ;Skips conversion-finished-mid-byte code.
- jr ConvOP1_CheckIntLoop
- ConvOP1_DoneMidByte:
- ;Throws an error if the low nibble/digit of this mantissa byte is nonzero.
- ld a,(de)
- and $0F
- jr nz,ErrDomain
- ConvOP1_CheckIntLoop:
- ;Returns successfully if the last byte of the mantissa has been checked.
- #ifdef 83p
- or e
- ret m
- #else
- ld a,(OP1+8)&$FF
- sub e
- ret z
- #endif
- ;Continues if the next byte of the mantissa is zero.
- inc e
- ld a,(de)
- or a
- jr z,ConvOP1_CheckIntLoop
- ErrDomain:
- ;Throws a domain error.
- B_CALL(_ErrDomain)
- ErrDataType:
- ;Throws a data type error.
- B_CALL(_ErrDataType)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement