// Excel 2002 trace for formatting 850*77.1+1 = 65536-2^(-37)
//

// divisor table

// table starts at word_3005FE00, and 16 bits per entry
//.text:3005FE00  01 00 0A 00 64 00 E8 03  10 27 FF FF 07 24 00 00
byte DivTbl[] = {01 00 0A 00 64 00 E8 03  10 27 FF FF};

// ECX rounding table
//.text:3005FE10  49 68 01 00 E1 12 0E 00  CC BC 8C 00 F8 5F 7F 05
//.text:3005FE20  B3 BF F9 36 00 00 00 00  00 00 00 00 00 00 00 00
//.text:3005FE30  00 00 00 00 00 00 00 A0  02 40 04 00 00 00 00 00
byte RndTbl[] = 
    {
0x49, 0x68, 0x01, 0x00, // digits = 1
0xE1, 0x12, 0x0E, 0x00, // digits = 2
0xCC, 0xBC, 0x8C, 0x00, // digits = 3
0xF8, 0x5F, 0x7F, 0x05, // digits = 4
0xB3, 0xBF, 0xF9, 0x36  // digits = 5 - this value=0x36F9BFB3
// above seems to be end of table based on Excel 2002 version of table
    };

// trace

ST0= 7.1510092812520145735e-3921 ST1=-1.8318425593494863852e583 
ST2= 6.4477652123115469025e-4051 ST3= 7.2305206786858568894e2850 
ST4= 0.0 ST5= 0.0 ST6= 1.0 ST7= 1.0 
CTRL=137F CS=1B DS=23 ES=23 FS=3B GS=0 SS=23 
EAX=8 EBX=FFEC0C02 ECX=F EDX=3 ESI=30803E10 EDI=13F3FE EBP=13FC00 
ESP=13F348 EFL=212  

Format mov   ax, [esi+6]    EAX=40EF      // result value - assume 0                    
       mov   dx, ax         EDX=40EF      // 
       and   ax, 7FF0h      EAX=40E0      // 
       jz    loc_30175BFF                 // 
       shr   ax, 4          EAX=40E       // 
       sub   ax, 3FEh       EAX=10        // 
       mov   bx, ax         EBX=FFEC0010  // 
       cwde                               // 
       imul  eax, 9A21h     EAX=9A210     // 
       sar   eax, 11h       EAX=4         // 
       add   ax, 4001h      EAX=4005      // 
       and   dx, 8000h      EDX=0         // 
       or    dx, ax         EDX=4005      // 
       mov   [edi+20h], dx                // 
       sub   ax, 4000h      EAX=5         // 
       or    bx, bx                       // 
       jl    loc_30180554                 // 
       cmp   bx, 10h                      // 
       jle   short Bit16                  // 
Bit16  push  edi            ESP=13F344    // 
       push  ecx            ESP=13F340    // 
       mov   edx, [esi]     EDX=FFFFFFFF  // 
       mov   esi, [esi+4]   ESI=40EFFFFF  // 
       xchg  eax, esi       EAX=40EFFFFF ESI=5 // 
       and   eax, 0FFFFFh   EAX=FFFFF     // 
       or    eax, 100000h   EAX=1FFFFF    // 
       mov   cl, 15h        ECX=15        // 
       sub   cl, bl         ECX=5         // 
       mov   ebx, eax       EBX=1FFFFF    // 
       shr   eax, cl        EAX=FFFF      // 
       neg   cl             ECX=FB        // 
       shld  ebx, edx, cl   EBX=FFFFFFFF  // 
       shl   edx, cl        EDX=F8000000  // 
       mov   ecx, edx       ECX=F8000000  // 
       dec   si             ESI=4         // 
       shl   si, 1          ESI=8         // 
       cmp   ax, DivTbl[esi]              // 
       jnb   short tag2                   // 
tag2   jecxz short loc_300337C0           // 
       jmp   tag2a                        // 
tag2a  shl   esi, 1         ESI=10        // 
       add   ecx, ds:dword_3005FE10[esi] ECX=2EF9BFB3 
       adc   ebx, 0         EBX=0         // 
       jb    tag3                         // 
tag3   xor   ecx, ecx       ECX=0         // 
       sar   esi, 1         ESI=8         // 
       mov   dx, 1          EDX=F8000001  // 
       inc   ax             EAX=0         // 
       jz    skip                         // Excel  2007 fails at this point 
                                          // due to 32 bit extension?
skip   div   DivTbl[esi]    EAX=6 EDX=F80015A0 // divide by 10000
       xor   ah, ah                       // zero byte  in top
       or    al, 30h        EAX=36        // output '6'
       stosw                EDI=13F400    // write 2 byte unicode value
       or    dx, dx                       // test for 0 remainder
       jz    short tag6                   // bail if done
       mov   ax, dx         EAX=15A0      // remainder
       sub   esi, 2         ESI=6         // new 16-bit table value
       ja    short Digits                 // do another digit
                                          // 
Digits xor   dx, dx         EDX=F8000000  // 
skip   div   DivTbl[esi]    EAX=5 EDX=F8000218 // divide by 1000
       xor   ah, ah                       // zero byte  in top
       or    al, 30h        EAX=35        // output '5'
       stosw                EDI=13F402    // write 2 byte unicode value
       or    dx, dx                       // test for 0 remainder
       jz    short tag6                   // bail if done
       mov   ax, dx         EAX=218       // remainder
       sub   esi, 2         ESI=4         // new 16-bit table value
       ja    short Digits                 // do another digit
                                          // 
Digits xor   dx, dx         EDX=F8000000  // 
skip   div   DivTbl[esi]    EAX=5 EDX=F8000024 // divide by 100
       xor   ah, ah                       // zero byte  in top
       or    al, 30h        EAX=35        // output '5'
       stosw                EDI=13F404    // write 2 byte unicode value
       or    dx, dx                       // test for 0 remainder
       jz    short tag6                   // bail if done
       mov   ax, dx         EAX=24        // remainder
       sub   esi, 2         ESI=2         // new 16-bit table value
       ja    short Digits                 // do another digit
                                          // 
Digits xor   dx, dx         EDX=F8000000  //
skip   div   DivTbl[esi]    EAX=3 EDX=F8000006 // divide by 10
       xor   ah, ah                       // zero byte  in top
       or    al, 30h        EAX=33        // output '3'
       stosw                EDI=13F406    // write 2 byte unicode value
       or    dx, dx                       // test for 0 remainder
       jz    short tag6                   // bail if done
       mov   ax, dx         EAX=6         // remainder
       sub   esi, 2         ESI=0         // out of table values
       ja    short Digits                 // no jump

	   or    al, al                       // test 0 remainder
       jz    short tag6                   // 
       jmp   tag5                         // 
tag5   xor   ah, ah                       // 
       or    al, 30h        EAX=36        // one last '6' digit left to do
       stosw                EDI=13F408    // 
       jmp   tag6                         // 
tag6   mov   eax, ebx       EAX=0         // cleanup, return values...
       or    eax, ecx                     // 
       jnz   loc_3017BC33                 // 
       mov   word ptr [edi], 30h          // 
       pop   ecx            ECX=F ESP=13F344 
       pop   ebx            EBX=13F3FE ESP=13F348
       mov   edx, edi       EDX=13F408    // 
       sub   edx, ebx       EDX=A         // 
       sar   edx, 1         EDX=5         // 
       mov   eax, edx       EAX=5         // 
       shl   eax, 10h       EAX=50000     // 
       mov   [ebx+1Eh], dl                // 
       mov   ax, [ebx+20h]  EAX=54005     // 
       and   eax, 0FFFF7FFFh              // 
       sub   ax, 4000h      EAX=50005     // 
       retn                 ESP=13F34C    // 
// end - 2002 trace
