#ifndef included_f64tof32
 
#define included_f64tof32
 
 
 
#include "routines/rl64.z80"
 
#include "mov.z80"
 
#include "pushpop.z80"
 
 
 
f64tof32:
 
;Inputs:
 
;   HL points to the input double-precision float
 
;   BC points to where to output the result
 
;Outputs:
 
;   The double-precision float (binary64) is converted to an extended-precision
 
;   float at BC.
 
;
 
  call pushpop
 
f64tof32_nopush:
 
; we don't need the bottom 3 bytes except if we need to distinguish between inf
 
; and NaN.
 
  push bc     ;save the pointer to the output
 
  ld a,(hl)
 
  inc hl
 
  or (hl)
 
  inc hl
 
  or (hl)
 
  inc hl
 
  ld e,(hl)
 
  inc hl
 
  ld d,(hl)
 
  inc hl
 
  ld c,(hl)
 
  inc hl
 
  ld b,(hl)
 
  inc hl
 
  ld h,(hl)
 
  ld l,a    ;save the OR of the bottom 3 bytes
 
;HBCDE is the top 5 bytes of the f64 float
 
  ld a,h
 
  add a,a
 
  jr z,f64tof32_check_0
 
  add a,2
 
  jr nz,f64tof32_continue
 
f64tof32_check_infnan:
 
  ld a,b
 
  add a,16
 
  jr nc,f64tof32_continue
 
f64tof32_infnan:
 
  ld a,b
 
  and %00001111
 
  or c
 
  or d
 
  or e
 
  or l
 
  ld d,h
 
  pop hl
 
  ld (hl),a
 
  inc hl
 
  ld (hl),a
 
  inc hl
 
  or %10000000
 
  ld (hl),a
 
  inc hl
 
  ld a,d
 
  or %01111111
 
  ld (hl),a
 
  ret
 
f64tof32_check_0:
 
  ld a,b
 
  and %11110000
 
  jr z,f64tof32_zero
 
f64tof32_continue:
 
; We need to scale down the exponent, subtract 1023 and add 127, net -896
 
  ld a,h
 
  add a,a
 
  rrca
 
  sub 56
 
  jr c,f64tof32_zero_setA
 
  cp 16
 
  jr nc,f64tof32_inf1
 
  ex de,hl
 
;DBCHL
 
  add hl,hl
 
  rl c
 
  rl b
 
  rla
 
 
 
  add hl,hl
 
  rl c
 
  rl b
 
  rla
 
 
 
  add hl,hl
 
  rl c
 
  rl b
 
  rla
 
 
 
  xor d
 
  and %01111111
 
  xor d
 
  ;ABCHL
 
  ; round befoe writing out
 
  sla l
 
  jr nc,f64tof32_rounded
 
  inc h
 
  jr nz,f64tof32_rounded
 
  inc c
 
  jr nz,f64tof32_rounded
 
  inc b
 
  jr nz,f64tof32_rounded
 
  inc a
 
  jr z,f64tof32_inf
 
f64tof32_rounded:
 
  ld d,h
 
  pop hl
 
  ld (hl),d
 
  inc hl
 
  ld (hl),c
 
  inc hl
 
  ld (hl),b
 
  inc hl
 
  ld (hl),a
 
  ret
 
 
 
f64tof32_zero_setA:
 
  xor a
 
f64tof32_zero:
 
  ld d,h
 
  pop hl
 
  ld (hl),a
 
  inc hl
 
  ld (hl),a
 
  inc hl
 
  ld (hl),a
 
  inc hl
 
  ld a,d
 
  and %10000000
 
  ld (hl),a
 
  ret
 
f64tof32_inf1:
 
  ld a,h
 
f64tof32_inf:
 
  pop hl
 
  ld (hl),0
 
  inc hl
 
  ld (hl),0
 
  inc hl
 
  ld (hl),80h
 
  inc hl
 
  or %01111111
 
  ld (hl),a
 
#endif