Login

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

 ifndef included_xmod1
 define included_xmod1
 include "../common/pushpop.asm"
 include "../common/mov.asm"
 include "routines/sla64.asm"
 include "routines/normalizexOP1.asm"
 include "constantsx.asm"
 include "xadd.asm"


;This routine performs `x mod 1`, returning a non-negative value.
;+inf -> NaN
;-inf -> NaN
;NaN  -> NaN

xmod1:
  call pushpop
  push bc
  ld de,xOP1
  call mov10

;Take care of special cases
  ld hl,(xOP1+8)
  ld a,h
  and $7F
  ld h,a
  or l
  jp z,xmod1_special

;If H<0x40, then there is no integer part!
  ld a,h
  sub $40
  jr c,xmod1_end

;if A is non-zero, then this number is too big to have stored an integer part
  jp nz,xmod1_return_0

;If L is >=63, then this number is too big to have stored an integer part
  ld a,l
  cp 63
  jp nc,xmod1_return_0
  inc a
;Now we need to shift the mantissa up to remove the integer part
  cp 32
  jr c,xmod1less32;+_
  sub 32
  ld hl,(xOP1+2) : ld (xOP1+6),hl
  ld hl,(xOP1) : ld (xOP1+4),hl
  ld hl,0
  ld (xOP1),hl : ld (xOP1+2),hl
xmod1less32;_:
  cp 16
  jr c,xmod1less16;+_
  sub 16
  ld hl,(xOP1+4) : ld (xOP1+6),hl
  ld hl,(xOP1+2) : ld (xOP1+4),hl
  ld hl,(xOP1) : ld (xOP1+2),hl
  ld hl,0
  ld (xOP1),hl
xmod1less16;_:
  cp 8
  jr c,xmod1less8;+_
  ld hl,(xOP1+5) : ld (xOP1+6),hl
  ld hl,(xOP1+3) : ld (xOP1+4),hl
  ld hl,(xOP1+1) : ld (xOP1+2),hl
  ld hl,(xOP1)
  ld l,0
  ld (xOP1),hl
xmod1less8;_:
  and 7
  jr z,xmod1_normalize
  ld b,a
;_:
  call sla64_xOP1
  djnz $-3;-_
xmod1_normalize:
  ld a,(xOP1+9)
  add a,a
  ld hl,$7FFF
  rr h
  ld (xOP1+8),hl
  call normalizexOP1
xmod1_end:
;If it is negative, add 1
  ld a,(xOP1+9)
  add a,a
  jr nc,return_xOP1
  ld hl,xOP1
  ld de,xconst_1
  ld b,h
  ld c,l
  call xadd
return_xOP1:
  ld hl,xOP1
  pop de
  jp mov10
xmod1_special:
  ld a,(xOP1+7)
  add a,a
  jr nc,return_xOP1
  ld a,$40
  ld (xOP1+7),a
  jr return_xOP1
xmod1_return_0:
  xor a
  ld h,a
  ld l,a
  ld (xOP1+7),a
  ld (xOP1+8),hl
  jr return_xOP1
 endif