// File: jkingan[P]ladyheather/heathmsc.cpp
// Function: new_moon(double)
double new_moon(double jd)
{
double start, mid, end;
double p1, p2, p3;
int i;
double start_step, end_step;

   sp_count = 0;
   if(0 && debug_file) {
      gregorian(0, jd);
      fprintf(debug_file, "New moon pinfo for %04d/%02d/%02d\n", pri_year,pri_month,pri_day);
      fprintf(debug_file, "New moon ginfo for %04d/%02d/%02d\n", g_year,g_month,g_day);
   }

   i = lookup_new_moon(jd);
   if(i >= 0) {
      return new_moon_table[i];
   }


   // calculates the julian date of the last new moon (to around 1 second)
   // but probably accurate to around 10 minutes... maybe... perhaps

   mid = jd;
   start = mid - 1.0; // yesterday
   end = mid + 1.0;   // tomorrow

   p1 = MOON_PHASE(start);  // get the moon illumination of the three consecutive days
   p2 = MOON_PHASE(mid);
   p3 = MOON_PHASE(end);

   for(i=0; i<31; i++) {   // check back a little more than a lunar month's worth of days
      if((p3 >= p2) && (p1 >= p2)) goto refine_new_moon;  // illumination is at a minimum this day

      end = mid;           // back up a day and try again
      mid = start;
      start = start - 1.0;
      p3 = p2;
      p2 = p1;
      p1 = MOON_PHASE(start);
   }

if(0 && debug_file) fprintf(debug_file, "No new moon solution at jd:%f\n", start);
   return 0.0;        // something went wrong, no minimum found

   refine_new_moon:

   start_step = 0.6;  // start seaching +/- 0.6 days from daily minimum
   end_step = 0.6;

if(0 && debug_file) fprintf(debug_file, "refine moon %d:%6.2f  ", sp_count, (end-start)*(24.0*60.0*60.0));
   for(i=0; i<40; i++) {  // binary seach for the minimum illumnation down to the second
      if((p1 >= p2) && (p2 >= p3)) {    // move end forward
if(0 && debug_file) fprintf(debug_file, "  fix end:   start:%f end:%f start_step:%f, end_step:%f\n", mid-start,end-mid,start_step,end_step);
         end += end_step / 2.0;
         p3 = MOON_PHASE(end);
      }
      else if((p1 <= p2) && (p2 <= p3)) {  // back uo start
if(0 && debug_file) fprintf(debug_file, "  fix start: start:%f end:%f start_step:%f, end_step:%f\n", mid-start,end-mid,start_step,end_step);
         start -= start_step / 2.0;
         p1 = MOON_PHASE(start);
      }
      else {  // minimum is somewhere between start and end, narrow the range
         start_step = (mid - start) / 1.25;
         end_step = (end - mid) / 1.25;
if(0 && debug_file) fprintf(debug_file, "  fix both:  start:%f end:%f start_step:%f, end_step:%f\n", mid-start,end-mid,start_step,end_step);
         start += start_step;
         end -= end_step;
         p1 = MOON_PHASE(start);
         p3 = MOON_PHASE(end);
      }
if(0 && debug_file) fprintf(debug_file, "refine moon %d :%6.2f  ", sp_count, (end-start)*(24.0*60.0*60.0));

      if(fabs(start-end) < (1.0/(24.0*60.0*60.0))) {  // time lies with a 1 second interval
         mid = (start + end) / 2.0;
if(0 && debug_file) fprintf(debug_file, "\nnoon %d: %.9f\n", sp_count, mid);
         break;  // start end end are within a second
      }

      mid = (start + end) / 2.0;
      p2 = MOON_PHASE(mid);
   }
   return mid;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movsd %xmm0, -0x10(%rbp)
movl $0x0, 0x29f1cd(%rip)    # 0x3d97f4
movsd -0x10(%rbp), %xmm0
callq 0x13f1f0
movl %eax, -0x44(%rbp)
cmpl $0x0, -0x44(%rbp)
jl 0x13a654
movslq -0x44(%rbp), %rcx
leaq 0x9233b(%rip), %rax     # 0x1cc980
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x13a8fb
movsd -0x10(%rbp), %xmm0
movsd %xmm0, -0x20(%rbp)
movsd -0x20(%rbp), %xmm0
movsd 0x349fd(%rip), %xmm1    # 0x16f068
subsd %xmm1, %xmm0
movsd %xmm0, -0x18(%rbp)
movsd 0x349ec(%rip), %xmm0    # 0x16f068
addsd -0x20(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
movsd -0x18(%rbp), %xmm0
callq 0x138e00
movsd %xmm0, -0x30(%rbp)
movsd -0x20(%rbp), %xmm0
callq 0x138e00
movsd %xmm0, -0x38(%rbp)
movsd -0x28(%rbp), %xmm0
callq 0x138e00
movsd %xmm0, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
cmpl $0x1f, -0x44(%rbp)
jge 0x13a732
movsd -0x40(%rbp), %xmm0
ucomisd -0x38(%rbp), %xmm0
jb 0x13a6da
movsd -0x30(%rbp), %xmm0
ucomisd -0x38(%rbp), %xmm0
jb 0x13a6da
jmp 0x13a73f
movsd -0x20(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
movsd -0x18(%rbp), %xmm0
movsd %xmm0, -0x20(%rbp)
movsd -0x18(%rbp), %xmm0
movsd 0x3496d(%rip), %xmm1    # 0x16f068
subsd %xmm1, %xmm0
movsd %xmm0, -0x18(%rbp)
movsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x40(%rbp)
movsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
movsd -0x18(%rbp), %xmm0
callq 0x138e00
movsd %xmm0, -0x30(%rbp)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x13a6ba
xorps %xmm0, %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x13a8fb
movsd 0x37021(%rip), %xmm0    # 0x171768
movsd %xmm0, -0x50(%rbp)
movsd 0x37014(%rip), %xmm0    # 0x171768
movsd %xmm0, -0x58(%rbp)
movl $0x0, -0x44(%rbp)
cmpl $0x28, -0x44(%rbp)
jge 0x13a8f1
movsd -0x30(%rbp), %xmm0
ucomisd -0x38(%rbp), %xmm0
jb 0x13a7b1
movsd -0x38(%rbp), %xmm0
ucomisd -0x40(%rbp), %xmm0
jb 0x13a7b1
movsd -0x58(%rbp), %xmm0
movsd 0x349c1(%rip), %xmm1    # 0x16f150
divsd %xmm1, %xmm0
addsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
movsd -0x28(%rbp), %xmm0
callq 0x138e00
movsd %xmm0, -0x40(%rbp)
jmp 0x13a879
movsd -0x30(%rbp), %xmm1
movsd -0x38(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x13a801
movsd -0x38(%rbp), %xmm1
movsd -0x40(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x13a801
movsd -0x50(%rbp), %xmm1
movsd 0x34972(%rip), %xmm0    # 0x16f150
divsd %xmm0, %xmm1
movsd -0x18(%rbp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, -0x18(%rbp)
movsd -0x18(%rbp), %xmm0
callq 0x138e00
movsd %xmm0, -0x30(%rbp)
jmp 0x13a877
movsd -0x20(%rbp), %xmm0
subsd -0x18(%rbp), %xmm0
movsd 0x53dd5(%rip), %xmm1    # 0x18e5e8
divsd %xmm1, %xmm0
movsd %xmm0, -0x50(%rbp)
movsd -0x28(%rbp), %xmm0
subsd -0x20(%rbp), %xmm0
movsd 0x53dba(%rip), %xmm1    # 0x18e5e8
divsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rbp)
movsd -0x50(%rbp), %xmm0
addsd -0x18(%rbp), %xmm0
movsd %xmm0, -0x18(%rbp)
movsd -0x58(%rbp), %xmm1
movsd -0x28(%rbp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
movsd -0x18(%rbp), %xmm0
callq 0x138e00
movsd %xmm0, -0x30(%rbp)
movsd -0x28(%rbp), %xmm0
callq 0x138e00
movsd %xmm0, -0x40(%rbp)
jmp 0x13a879
movsd -0x18(%rbp), %xmm1
subsd -0x28(%rbp), %xmm1
movaps 0x34a06(%rip), %xmm0    # 0x16f290
pand %xmm0, %xmm1
movsd 0x53f4a(%rip), %xmm0    # 0x18e7e0
ucomisd %xmm1, %xmm0
jbe 0x13a8b9
movsd -0x18(%rbp), %xmm0
addsd -0x28(%rbp), %xmm0
movsd 0x348a2(%rip), %xmm1    # 0x16f150
divsd %xmm1, %xmm0
movsd %xmm0, -0x20(%rbp)
jmp 0x13a8f1
movsd -0x18(%rbp), %xmm0
addsd -0x28(%rbp), %xmm0
movsd 0x34885(%rip), %xmm1    # 0x16f150
divsd %xmm1, %xmm0
movsd %xmm0, -0x20(%rbp)
movsd -0x20(%rbp), %xmm0
callq 0x138e00
movsd %xmm0, -0x38(%rbp)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x13a760
movsd -0x20(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
movsd -0x8(%rbp), %xmm0
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)