;
format PE GUI 4.0
entry Start

include '\INCLUDE\win32ax.inc'
include '\INCLUDE\opengl.inc'

macro mycall fxn,arg1,arg2,arg3 {
 if arg1 eq
	call  fxn
 else if arg2 eq
	 mov  eax,arg1
	call  fxn
 else if arg3 eq
	 mov  eax,arg1
	 mov  ebx,arg2
	call  fxn
 else
	 mov  eax,arg1
	 mov  ebx,arg2
	 mov  ecx,arg3
	call  fxn
 end if }

macro my_dpps a,b,t {	     ; either -> dpps a,b,0x7F
 ; or ->
       mulps  a,b	     ; a = 0  z  y  x
      pshufd  t,a,10110001b  ; t = z  0  x  y
       addps  a,t	     ; a = 0z 0z xy yx
      pshufd  t,a,00001111b  ; t = yx yx 0z 0z
       addps  a,t }	     ; a = 0zyx ...

; Data
MAX_SYMBOL_LENGTH   = 16
STATUSWINDOW_HEIGHT = 22
INITIAL_WINDOW_WIDTH  = 640
INITIAL_WINDOW_HEIGHT = 480
INITIAL_COLOR = 0x000000FF
INIT_CONST_TABLE_ENTRIES = 1024  ; number of values (32 bytes)
INIT_VAR_TABLE_ENTRIES	 = 1024  ; number of values
INIT_DEF_TABLE_ENTRIES	 = 1024  ; number of values
INITIAL_INPUT_BASE  = 10	 ;  2 <= <= 16
INITIAL_OUTPUT_BASE = 10	 ;  2 <= <= 16
INITIAL_OUTPUT_BITS = 54	 ; 20 <= <= 70
MIN_DIVISIONS = 16
MAX_DIVISIONS = 1024
LOW_DIVISIONS = 128
MED_DIVISIONS = 256
HI_DIVISIONS  = 384
 ; assume average density of 1.5 triangles per cublet, don't need more triangles than this 
TWICE_TRIANGLE_MAX_AVERAGE_DENSITY = 3
MIN_DIVISIONS_CONTOURPLOT = 16
MAX_DIVISIONS_CONTOURPLOT = 128
LOW_DIVISIONS_CONTOURPLOT = 32
MED_DIVISIONS_CONTOURPLOT = 64
HI_DIVISIONS_CONTOURPLOT  = 96
DEF_SIZE	   = 1024  ; number of dwords
EVAL_STACK_ENTRIES = 1024  ; number of values
HISTORY_ENTRIES    = 1024  
IDM_OPEN	 = 101	   
IDM_EVALUATE	 = 103
IDM_CLEAR	 = 104
IDM_HELP	 = 105
IDM_EXIT	 = 107
IDM_VIEW_SYMBOLS = 108
IDM_DEMO1	 = 111
IDM_DEMO2	 = 112
IDM_DEMO3	 = 113
IDM_DEMO4	 = 114
IDM_DEMO5	 = 115
IDM_DEMO6	 = 116
IDM_DEMO7	 = 117
IDM_FONT_SMALL	 = 130
IDM_FONT_MEDIUM  = 131
IDM_FONT_LARGE	 = 132
IDM_GRAPHICS_LOW = 140
IDM_GRAPHICS_MED = 141
IDM_GRAPHICS_HI  = 142
MOVE_FORWARD = 0x00000001
MOVE_BACK    = 0x00000002
STRAFE_RIGHT = 0x00000004
STRAFE_LEFT  = 0x00000008
LOOK_UP      = 0x00000010
LOOK_DOWN    = 0x00000020
LOOK_LEFT    = 0x00000040
LOOK_RIGHT   = 0x00000080

section '.text' code readable executable

PlotStart:
      invoke  GetModuleHandle,0
	 mov  [Plotwc.hInstance],eax
      invoke  LoadIcon,eax,17
	 mov  [Plotwc.hIcon],eax
      invoke  LoadCursor,0,IDC_ARROW
	 mov  [Plotwc.hCursor],eax
      invoke  RegisterClass,Plotwc
      invoke  CreateWindowEx,0,string_PlotClass,string_PlotTitle,WS_VISIBLE+WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS,16,16,600,500,NULL,NULL,[Plotwc.hInstance],NULL
	 mov  [hPlotWindow],eax

PlotMsgLoop:
      invoke  PeekMessage,Plotmsg,NULL,0,0,PM_REMOVE
	test  eax,eax
	  jz  @f
	 cmp  [Plotmsg.message],WM_QUIT
	  je  PlotEndLoop
      invoke  TranslateMessage,Plotmsg
      invoke  DispatchMessage,Plotmsg
	 jmp  PlotMsgLoop
  @@:	 mov  al,byte[plotQ]
	  or  al,byte[CameraMove]
	  jz  PlotMsgLoop
	call  Render
	 jmp  PlotMsgLoop

PlotEndLoop:
      invoke  VirtualFree,dword[VertexCoorNormalColorTable],0,MEM_RELEASE
	 mov  dword[VertexCoorNormalColorTable],0
      invoke  VirtualFree,dword[ContourVertexCoorNormalColorTable],0,MEM_RELEASE
	 mov  dword[ContourVertexCoorNormalColorTable],0
	 mov  dword[hPlotWindow],0
      invoke  ExitThread,0

Render:
	 cmp  byte[updatingplotQ],0
	 jne  .Done
      invoke  glClear,GL_COLOR_BUFFER_BIT+GL_DEPTH_BUFFER_BIT
      invoke  glMatrixMode,GL_MODELVIEW
      invoke  glLoadIdentity
      invoke  QueryPerformanceCounter,PlotTime1
	call  UpdateCamera
	call  Camera
	 cmp  byte[boxQ],0
	  je  .BoxDone
.Box:
      invoke  glPushMatrix
      invoke  glTranslatef,0.0,0.0,0.0
      invoke  glColor3f,0.4,0.4,0.4
      invoke  glBegin,GL_LINES
      invoke  glVertex3f, -9.0,-10.0,-10.0
      invoke  glVertex3f,  9.0,-10.0,-10.0
      invoke  glVertex3f, -9.0,-10.0, 10.0
      invoke  glVertex3f,  9.0,-10.0, 10.0
      invoke  glVertex3f, -9.0, 10.0,-10.0
      invoke  glVertex3f,  9.0, 10.0,-10.0
      invoke  glVertex3f, -9.0, 10.0, 10.0
      invoke  glVertex3f,  9.0, 10.0, 10.0
      invoke  glVertex3f,-10.0, -9.0,-10.0
      invoke  glVertex3f,-10.0, 9.0, -10.0
      invoke  glVertex3f,-10.0, -9.0, 10.0
      invoke  glVertex3f,-10.0,  9.0, 10.0
      invoke  glVertex3f, 10.0, -9.0,-10.0
      invoke  glVertex3f, 10.0, 9.0, -10.0
      invoke  glVertex3f, 10.0, -9.0, 10.0
      invoke  glVertex3f, 10.0,  9.0, 10.0
      invoke  glVertex3f,-10.0,-10.0, -9.0
      invoke  glVertex3f,-10.0,-10.0,  9.0
      invoke  glVertex3f,-10.0, 10.0, -9.0
      invoke  glVertex3f,-10.0, 10.0,  9.0
      invoke  glVertex3f, 10.0,-10.0, -9.0
      invoke  glVertex3f, 10.0,-10.0,  9.0
      invoke  glVertex3f, 10.0, 10.0, -9.0
      invoke  glVertex3f, 10.0, 10.0,  9.0
      invoke  glEnd
      invoke  glPopMatrix
.BoxDone:
	 cmp  byte[plotmode],0
	  je  .ParametricPoly
	 mov  ebx,dword[TriangleCount]
	test  ebx,ebx
	  jz  .PolyDone
.ContourPoly:
	call  ContourShade
	push  ebp
	 mov  ebp,esp
	 and  esp,-16
	 mov  esi,dword[ContourVertexCoorNormalColorTable]
      invoke  glBegin,GL_TRIANGLES
.l0:
	 sub  esp,16*6
      movaps  xmm0,dqword[esi+48*0+4*0]
      movaps  xmm1,dqword[esi+48*0+4*8]
      movaps  xmm2,dqword[esi+48*1+4*0]
      movaps  xmm3,dqword[esi+48*1+4*8]
      movaps  xmm4,dqword[esi+48*2+4*0]
      movaps  xmm5,dqword[esi+48*2+4*8]
      movaps  dqword[esp+16*0],xmm1
      movaps  dqword[esp+16*1],xmm0
      movaps  dqword[esp+16*2],xmm3
      movaps  dqword[esp+16*3],xmm2
      movaps  dqword[esp+16*4],xmm5
      movaps  dqword[esp+16*5],xmm4
      invoke  glColor3f
	 pop  eax
      invoke  glVertex3f
	 pop  eax
      invoke  glColor3f
	 pop  eax
      invoke  glVertex3f
	 pop  eax
      invoke  glColor3f
	 pop  eax
      invoke  glVertex3f
	 pop  eax
	 add  esi,48*3
	 sub  ebx,3
	  ja  .l0
      invoke  glEnd
	 mov  esp,ebp
	 pop  ebp
	 jmp  .PolyDone
.ParametricPoly:
	call  Shade
	 mov  esi,dword[VertexCoorNormalColorTable]
	imul  edi,dword[u_div],48
	 mov  ecx,dword[v_div]
	 sub  ecx,1
	push  ebp
	 mov  ebp,esp
	 and  esp,-16
	 sub  esp,4*2
.l1:
	push  ecx
	push  esi
	 mov  ebx,dword[u_div]
      invoke  glBegin,GL_QUAD_STRIP
.l2:
	 sub  esp,16*4
      movaps  xmm0,dqword[esi+4*0]
      movaps  xmm1,dqword[esi+4*8]
      movaps  xmm2,dqword[esi+edi+4*0]
      movaps  xmm3,dqword[esi+edi+4*8]
      movaps  dqword[esp+16*0],xmm1
      movaps  dqword[esp+16*1],xmm0
      movaps  dqword[esp+16*2],xmm3
      movaps  dqword[esp+16*3],xmm2
      invoke  glColor3f
	 pop  eax
      invoke  glVertex3f
	 pop  eax
      invoke  glColor3f
	 pop  eax
      invoke  glVertex3f
	 pop  eax
	 add  esi,4*12
	 sub  ebx,1
	  ja  .l2
      invoke  glEnd
	 pop  esi
	 add  esi,edi
	 pop  ecx
	 sub  ecx,1
	  ja  .l1
	 mov  esp,ebp
	 pop  ebp
.PolyDone:
	 cmp  byte[normalsQ],0
	  je  .NormDone
	 cmp  byte[plotmode],0
	  je  .ParametricNorm
	 mov  ebx,dword[TriangleCount]
	test  ebx,ebx
	  jz  .NormDone
.ContourNorm:
      invoke  glBegin,GL_LINES
      invoke  glColor3f,0.1,0.1,0.1
	 mov  esi,dword[ContourVertexCoorNormalColorTable]
 @@:  invoke  glVertex3f,dword[esi+4*0],dword[esi+4*1],dword[esi+4*2]
      movdqa  xmm0,dqword[esi+4*0]
       addps  xmm0,dqword[esi+4*4]
	 sub  esp,4*4
      movdqu  dqword[esp],xmm0
      invoke  glVertex3f
	 add  esp,4*1
	 add  esi,4*12
	 sub  ebx,1
	  ja  @b
      invoke  glEnd
	 jmp  .NormDone
.ParametricNorm:
      invoke  glBegin,GL_LINES
      invoke  glColor3f,0.1,0.1,0.1
	 mov  esi,dword[VertexCoorNormalColorTable]
	 mov  ebx,dword[u_div]
	imul  ebx,dword[v_div]
 @@:  invoke  glVertex3f,dword[esi+4*0],dword[esi+4*1],dword[esi+4*2]
      movdqa  xmm0,dqword[esi+4*0]
       addps  xmm0,dqword[esi+4*4]
	 sub  esp,4*4
      movdqu  dqword[esp],xmm0
      invoke  glVertex3f
	 add  esp,4*1
	 add  esi,4*12
	 sub  ebx,1
	  ja  @b
      invoke  glEnd
	 jmp  .NormDone
.NormDone:
      invoke  QueryPerformanceCounter,PlotTime2
	fild  qword[PlotTime2]
	fild  qword[PlotTime1]	;cycles
       fsubp  st1,st0
	fild  qword[Frequency] ;cycles/sec
      fdivrp  st1,st0
	 mov  edi,StatusString
	 mov  eax,'Time'
       stosd
	 mov  ax,': '
       stosw
	push  dword[OutputBits]
	 mov  dword[OutputBits],15
	push  dword[OutputBase]
	 mov  dword[OutputBase],10
	call  PrintFloat
	 pop  dword[OutputBase]
	 pop  dword[OutputBits]
	 mov  eax,' /se'
       stosd
	 mov  eax,'c'
       stosd
      invoke  SendMessage,[hPlotStatusWnd],SB_SETTEXT,0,StatusString
	 cmp  byte[helpQ],0
	  je  @f
      invoke  SendMessage,[hPlotStatusWnd],SB_SETTEXT,0,string_PlotHelp
	 mov  byte[helpQ],0
 @@:  invoke  SwapBuffers,[hPlotdc]
	 mov  byte[plotQ],0
.Done:	 ret

Shade:
	 mov  esi,dword[VertexCoorNormalColorTable]
	 mov  eax,dword[u_div]
	 mul  dword[v_div]
      movaps  xmm7,dqword[lightdirection]
.l1:  movaps  xmm0,dqword[CameraPos.x]
       subps  xmm0,dqword[esi+4*0]     ; vertex coor
      movaps  xmm3,dqword[esi+4*4]     ; vertex normal
      movdqa  xmm1,xmm0
     my_dpps  xmm0,xmm0,xmm2
     rsqrtps  xmm0,xmm0
       mulps  xmm1,xmm0 	       ; xmm1 = view direction
      movaps  xmm0,xmm3
     my_dpps  xmm0,xmm1,xmm2	; ;
     cmpleps  xmm0,dqword[const_False]
      movaps  xmm2,xmm0
       andps  xmm2,dqword[const_f4v4_neg]
	pxor  xmm3,xmm2
      movaps  xmm4,dqword[BackColor]
       andps  xmm4,xmm0
      andnps  xmm0,dqword[FrontColor]
       addps  xmm4,xmm0
      movaps  xmm2,xmm7
     my_dpps  xmm2,xmm3,xmm0
       addps  xmm2,xmm2
       mulps  xmm2,xmm3
       subps  xmm2,xmm7
     my_dpps  xmm2,xmm1,xmm0
      movaps  xmm0,xmm2
       mulps  xmm2,xmm2
       mulps  xmm2,xmm2
       mulps  xmm2,xmm2
       mulps  xmm0,dqword[white]
       mulps  xmm2,xmm0 	      ; xmm2 = specular
     my_dpps  xmm3,xmm7,xmm0
       maxps  xmm3,dqword[ambientlightintensity]  ; xmm3 = max(diffuse,ambient)
       mulps  xmm3,xmm4
       maxps  xmm3,xmm2 	      ; xmm3 = max(diffuse,ambient,specular)
      movaps  dqword[esi+4*8],xmm3    ; vertex color
	 add  esi,4*12
	 sub  eax,1
	 jae  .l1
	 ret

ContourShade:
	 mov  esi,dword[ContourVertexCoorNormalColorTable]
	 mov  eax,dword[TriangleCount]
	test  eax,eax
	  jz  .done
      movaps  xmm7,dqword[lightdirection]
.l1:
      movaps  xmm0,dqword[CameraPos.x]
       subps  xmm0,dqword[esi+4*0]	; vertex coord.
      movaps  xmm3,dqword[esi+4*4]	; vertex normal
      movdqa  xmm1,xmm0
     my_dpps  xmm0,xmm0,xmm2
     rsqrtps  xmm0,xmm0
       mulps  xmm1,xmm0  ; xmm1 = view direction
      movaps  xmm0,xmm3
     my_dpps  xmm0,xmm1,xmm2
     cmpleps  xmm0,dqword[const_False]
      movaps  xmm2,xmm0
       andps  xmm2,dqword[const_f4v4_neg]
	pxor  xmm3,xmm2
      movaps  xmm4,dqword[BackColor]
       andps  xmm4,xmm0
      andnps  xmm0,dqword[FrontColor]
       addps  xmm4,xmm0
      movaps  xmm2,xmm7
     my_dpps  xmm2,xmm3,xmm0
       addps  xmm2,xmm2
       mulps  xmm2,xmm3
       subps  xmm2,xmm7
     my_dpps  xmm2,xmm1,xmm0
      movaps  xmm0,xmm2
       mulps  xmm2,xmm2
       mulps  xmm2,xmm2
       mulps  xmm2,xmm2
       mulps  xmm0,dqword[white]
       mulps  xmm2,xmm0 	      ; xmm2 = specular
     my_dpps  xmm3,xmm7,xmm0
       maxps  xmm3,dqword[ambientlightintensity]  ; xmm3 = max(diffuse,ambient)
       mulps  xmm3,xmm4
       maxps  xmm3,xmm2 	      ; xmm3 = max(diffuse,ambient,specular)
      movaps  dqword[esi+4*8],xmm3    ; vertex color
	 add  esi,4*12
	 sub  eax,1
	 jae  .l1
.done:	 ret

PlotWindowProc:  ; proc PlotWindowProc ; hwnd,wmsg,wparam,lparam
	push  ebp
	 mov  ebp,esp

     virtual  at ebp
	  dd  ?,?
 .hwnd	  dd  ?
 .wmsg	  dd  ?
 .wparam  dd  ?
 .lparam  dd  ?
	 end  virtual

	push  ebx esi edi
	 cmp  [.wmsg],WM_CREATE
	  je  .wmcreate
	 cmp  [.wmsg],WM_SIZE
	  je  .wmsize
	 cmp  [.wmsg],WM_PAINT
	  je  .wmpaint
	 cmp  [.wmsg],WM_KEYUP
	  je  .wmkeyup
	 cmp  [.wmsg],WM_KEYDOWN
	  je  .wmkeydown
	 cmp  [.wmsg],WM_DESTROY
	  je  .wmdestroy
.defwndproc:
      invoke  DefWindowProc,[.hwnd],[.wmsg],[.wparam],[.lparam]
	 jmp  .finish
.wmkeydown:
       movzx  eax,word[.wparam]
	 mov  byte[plotQ],-1
	 cmp  eax,'W'
	  je  .keydown_w
	 cmp  eax,'A'
	  je  .keydown_a
	 cmp  eax,'S'
	  je  .keydown_s
	 cmp  eax,'D'
	  je  .keydown_d
	 cmp  eax,'I'
	  je  .keydown_i
	 cmp  eax,'J'
	  je  .keydown_j
	 cmp  eax,'K'
	  je  .keydown_k
	 cmp  eax,'L'
	  je  .keydown_l
	 cmp  eax,'B'
	  je  .keydown_b
	 cmp  eax,'N'
	  je  .keydown_n
	 cmp  eax,'C'
	  je  .keydown_c
	 cmp  eax,'X'
	  je  .keydown_x
	 cmp  eax,'M'
	  je  .keydown_m
	 cmp  eax,VK_ESCAPE
	  je  .wmdestroy
	 jmp  .zfinish
.keydown_m:
	 xor  edx,edx
	 lea  ecx,[edx+3]
       movzx  eax,byte[polymode]
	 inc  eax
	 div  ecx
	 mov  byte[polymode],dl
	 add  edx,GL_POINT
      invoke  glPolygonMode,GL_FRONT_AND_BACK,edx
	 mov  byte[plotQ],-1
	 jmp  .zfinish
.keydown_x:
.keydown_c:
	 mov  dword[CameraMove],0
	 mov  [cc.hInstance],0
	 mov  [cc.lpCustColors],CustomColors
	 mov  [cc.Flags],CC_ANYCOLOR+CC_RGBINIT+CC_FULLOPEN
      invoke  ChooseColor,cc
       xorps  xmm5,xmm5
      movups  dqword[esp-16],xmm5
	 mov  ecx,[cc.rgbResult]
	 mov  byte[esp-16+4*0],cl
	 shr  ecx,8
	 mov  byte[esp-16+4*1],cl
	 shr  ecx,8
	 mov  byte[esp-16+4*2],cl
      movups  xmm5,dqword[esp-16]
    cvtdq2ps  xmm5,xmm5
       divps  xmm5,dqword[const_f4v4_255]
	 cmp  word[.wparam],'X'
	  je  @f
      movaps  dqword[FrontColor],xmm5
	 jmp  .zfinish
 @@:  movaps  dqword[BackColor],xmm5
	 jmp  .zfinish
.keydown_b:
	 not  byte[boxQ]
	 jmp  .zfinish
.keydown_n:
	 not  byte[normalsQ]
	 jmp  .zfinish
.keydown_w:
	  or  dword[CameraMove],MOVE_FORWARD
	 jmp  .zfinish
.keydown_a:
	  or  dword[CameraMove],STRAFE_LEFT
	 jmp  .zfinish
.keydown_s:
	  or  dword[CameraMove],MOVE_BACK
	 jmp  .zfinish
.keydown_d:
	  or  dword[CameraMove],STRAFE_RIGHT
	 jmp  .zfinish
.keydown_i:
	  or  dword[CameraMove],LOOK_UP
	 jmp  .zfinish
.keydown_j:
	  or  dword[CameraMove],LOOK_LEFT
	 jmp  .zfinish
.keydown_k:
	  or  dword[CameraMove],LOOK_DOWN
	 jmp  .zfinish
.keydown_l:
	  or  dword[CameraMove],LOOK_RIGHT
	 jmp  .zfinish
.wmkeyup:
       movzx  eax,word[.wparam]
	 cmp  eax,'W'
	  je  .keyup_w
	 cmp  eax,'A'
	  je  .keyup_a
	 cmp  eax,'S'
	  je  .keyup_s
	 cmp  eax,'D'
	  je  .keyup_d
	 cmp  eax,'I'
	  je  .keyup_i
	 cmp  eax,'J'
	  je  .keyup_j
	 cmp  eax,'K'
	  je  .keyup_k
	 cmp  eax,'L'
	  je  .keyup_l
	 jmp  .zfinish
.keyup_w:
	 and  dword[CameraMove],not MOVE_FORWARD
	 jmp  .zfinish
.keyup_a:
	 and  dword[CameraMove],not STRAFE_LEFT
	 jmp  .zfinish
.keyup_s:
	 and  dword[CameraMove],not MOVE_BACK
	 jmp  .zfinish
.keyup_d:
	 and  dword[CameraMove],not STRAFE_RIGHT
	 jmp  .zfinish
.keyup_i:
	 and  dword[CameraMove],not LOOK_UP
	 jmp  .zfinish
.keyup_j:
	 and  dword[CameraMove],not LOOK_LEFT
	 jmp  .zfinish
.keyup_k:
	 and  dword[CameraMove],not LOOK_DOWN
	 jmp  .zfinish
.keyup_l:
	 and  dword[CameraMove],not LOOK_RIGHT
	 jmp  .zfinish
.wmcreate:
      invoke  CreateStatusWindow,WS_CHILD+WS_VISIBLE+SBS_SIZEGRIP,NULL,[.hwnd],0
	 mov  [hPlotStatusWnd],eax
	 mov  byte[helpQ],-1
      invoke  GetDC,[.hwnd]
	 mov  [hPlotdc],eax
	 mov  edi,Plotpfd
	 mov  ecx,sizeof.PIXELFORMATDESCRIPTOR shr 2
	 xor  eax,eax
	 rep  stosd
	 mov  [Plotpfd.nSize],sizeof.PIXELFORMATDESCRIPTOR
	 mov  [Plotpfd.nVersion],1
	 mov  [Plotpfd.dwFlags],PFD_SUPPORT_OPENGL+PFD_DOUBLEBUFFER+PFD_DRAW_TO_WINDOW
	 mov  [Plotpfd.iLayerType],PFD_MAIN_PLANE
	 mov  [Plotpfd.iPixelType],PFD_TYPE_RGBA
	 mov  [Plotpfd.cColorBits],16
	 mov  [Plotpfd.cDepthBits],16
	 mov  [Plotpfd.cAccumBits],0
	 mov  [Plotpfd.cStencilBits],0
      invoke  ChoosePixelFormat,[hPlotdc],Plotpfd
      invoke  SetPixelFormat,[hPlotdc],eax,Plotpfd
      invoke  wglCreateContext,[hPlotdc]
	 mov  [hPlotrc],eax
      invoke  wglMakeCurrent,[hPlotdc],[hPlotrc]
	call  PlotInitialize
	 jmp  .zfinish
.wmsize:
      invoke  GetClientRect,[.hwnd],rc
	call  Reshape
      invoke  MoveWindow,[hPlotStatusWnd],0,0,0,0,TRUE
	 mov  byte[plotQ],-1
	 jmp  .zfinish
.wmpaint:
      invoke  ValidateRect,[.hwnd],NULL
	 mov  byte[plotQ],-1
	 jmp  .zfinish
.wmdestroy:
      invoke  wglMakeCurrent,0,0
      invoke  wglDeleteContext,[hPlotrc]
      invoke  ReleaseDC,[.hwnd],[hPlotdc]
      invoke  PostQuitMessage,0
.zfinish:
	 xor  eax,eax
.finish:
	 pop  edi esi ebx
	 mov  esp,ebp
	 pop  ebp
	 ret

Reshape:
	 sub  [rc.bottom],STATUSWINDOW_HEIGHT
      invoke  glViewport, 0,STATUSWINDOW_HEIGHT,[rc.right],[rc.bottom]
      invoke  glMatrixMode, GL_PROJECTION
      invoke  glLoadIdentity
	fild  [rc.right]
       fidiv  [rc.bottom]
	fstp  qword[Perspective+8*1]
      invoke  gluPerspective,double[Perspective+8*0],double[Perspective+8*1],double[Perspective+8*2],double[Perspective+8*3]
	 mov  byte[plotQ],-1
	 ret

PlotInitialize:
      invoke  glClearColor, dword  0.0, dword  0.0, dword  0.0, dword  0.0
      invoke  GetClientRect,[hPlotWindow],rc
	call  Reshape
      invoke  glMatrixMode,GL_MODELVIEW
      invoke  glLoadIdentity
      invoke  glEnable,GL_DEPTH_TEST
      invoke  glEnable,GL_BLEND
       movzx  edx,byte[polymode]
	 add  edx,GL_POINT
      invoke  glPolygonMode,GL_FRONT_AND_BACK,edx
	 mov  byte[plotQ],-1
	 ret

Camera: 
      invoke  glRotatef,dword[CameraAngle.x],dword 1.0,dword 0.0,dword 0.0
      invoke  glRotatef,dword[CameraAngle.y],dword 0.0,dword 1.0,dword 0.0
	 sub  esp,4*3
	 fld  dword[CameraPos.z]
	 fld  dword[CameraPos.y]
	 fld  dword[CameraPos.x]
	fchs
	fstp  dword[esp+4*0]
	fchs
	fstp  dword[esp+4*1]
	fchs
	fstp  dword[esp+4*2]
      invoke  glTranslatef
	 ret

UpdateCamera:
	 mov  eax,[CameraMove]
	fldz
	 fld  [CameraAngle.y]
	 fld  [anglestep]
	test  eax,LOOK_RIGHT
	  jz  @f
	fadd  st1,st0
 @@:	test  eax,LOOK_LEFT
	  jz  @f
	fsub  st1,st0
 @@:	fstp  st0
	 fld  [f4_360]
       fcomi  st1
     fcmovnb  st0,st2
       fsubp  st2,st0
       faddp  st1,st0
	fstp  [CameraAngle.y]
	 fld  [f4_m80]
	 fld  [f4_80]
	 fld  [CameraAngle.x]
	 fld  [anglestep]
	test  eax,LOOK_DOWN
	  jz  @f
	fadd  st1,st0
 @@:	test  eax,LOOK_UP
	  jz  @f
	fsub  st1,st0
 @@:	fstp  st0
       fcomi  st1
     fcmovnb  st0,st1
	fstp  st1
       fcomi  st1
      fcmovb  st0,st1
	fstp  [CameraAngle.x]
	fstp  st0
	 and  eax,MOVE_FORWARD+MOVE_BACK+STRAFE_LEFT+STRAFE_RIGHT
	 cmp  eax,MOVE_FORWARD
	 jne  @f
	 fld  [CameraAngle.x]
	fmul  [f4_deg]
     fsincos
	fxch  st1
	fmul  [speed]
       fsubr  [CameraPos.y]
	fstp  [CameraPos.y]
	fmul  [speed]
	 fld  [CameraAngle.y]
	fmul  [f4_deg]
     fsincos
	fmul  st0,st2
       fsubr  [CameraPos.z]
	fstp  [CameraPos.z]
       fmulp  st1,st0
	fadd  [CameraPos.x]
	fstp  [CameraPos.x]
 @@:	 cmp  eax,MOVE_FORWARD+STRAFE_RIGHT
	 jne  @f
	 fld  [CameraAngle.x]
	fmul  [f4_deg]
     fsincos
	fxch  st1
	fmul  [speed2]
       fsubr  [CameraPos.y]
	fstp  [CameraPos.y]
	 fld  [CameraAngle.y]
	fmul  [f4_deg]
     fsincos
	 fld  st1
	fmul  st0,st3
	 fld  st1
       fmulp  st4,st0
       faddp  st1,st0
	fmul  [speed2]
	fadd  [CameraPos.x]
	fstp  [CameraPos.x]
       fsubp  st1,st0
	fmul  [speed2]
       fsubr  [CameraPos.z]
	fstp  [CameraPos.z]
 @@:	 cmp  eax,STRAFE_RIGHT
	 jne  @f
	 fld  [CameraAngle.y]
	fmul  [f4_deg]
     fsincos
	fmul  [speed]
	fadd  [CameraPos.x]
	fstp  [CameraPos.x]
	fmul  [speed]
	fadd  [CameraPos.z]
	fstp  [CameraPos.z]
 @@:	 cmp  eax,STRAFE_RIGHT+MOVE_BACK
	 jne  @f
	 fld  [CameraAngle.x]
	fmul  [f4_deg]
     fsincos
	fxch  st1
	fmul  [speed2]
       fsubr  [CameraPos.y]
	fstp  [CameraPos.y]
	 fld  [CameraAngle.y]
	fmul  [f4_deg]
     fsincos
	 fld  st1
	fmul  st0,st3
	 fld  st1
       fmulp  st4,st0
       fsubp  st1,st0
	fmul  [speed2]
	fadd  [CameraPos.x]
	fstp  [CameraPos.x]
       faddp  st1,st0
	fmul  [speed2]
	fadd  [CameraPos.z]
	fstp  [CameraPos.z]
 @@:	 cmp  eax,MOVE_BACK
	 jne  @f
	 fld  [CameraAngle.x]
	fmul  [f4_deg]
     fsincos
	fxch  st1
	fmul  [speed]
	fadd  [CameraPos.y]
	fstp  [CameraPos.y]
	fmul  [speed]
	 fld  [CameraAngle.y]
	fmul  [f4_deg]
     fsincos
	fmul  st0,st2
	fadd  [CameraPos.z]
	fstp  [CameraPos.z]
       fmulp  st1,st0
       fsubr  [CameraPos.x]
	fstp  [CameraPos.x]
 @@:	 cmp  eax,MOVE_BACK+STRAFE_LEFT
	 jne  @f
	 fld  [CameraAngle.x]
	fmul  [f4_deg]
     fsincos
	fxch  st1
	fmul  [speed2]
	fadd  [CameraPos.y]
	fstp  [CameraPos.y]
	 fld  [CameraAngle.y]
	fmul  [f4_deg]
     fsincos
	 fld  st1
	fmul  st0,st3
	 fld  st1
       fmulp  st4,st0
       faddp  st1,st0
	fmul  [speed2]
       fsubr  [CameraPos.x]
	fstp  [CameraPos.x]
       fsubp  st1,st0
	fmul  [speed2]
	fadd  [CameraPos.z]
	fstp  [CameraPos.z]
 @@:	 cmp  eax,STRAFE_LEFT
	 jne  @f
	 fld  [CameraAngle.y]
	fmul  [f4_deg]
     fsincos
	fmul  [speed]
       fsubr  [CameraPos.x]
	fstp  [CameraPos.x]
	fmul  [speed]
       fsubr  [CameraPos.z]
	fstp  [CameraPos.z]
 @@:	 cmp  eax,STRAFE_LEFT+MOVE_FORWARD
	 jne  @f
	 fld  [CameraAngle.x]
	fmul  [f4_deg]
     fsincos
	fxch  st1
	fmul  [speed2]
	fadd  [CameraPos.y]
	fstp  [CameraPos.y]
	 fld  [CameraAngle.y]
	fmul  [f4_deg]
     fsincos
	 fld  st1
	fmul  st0,st3
	 fld  st1
       fmulp  st4,st0
       fsubp  st1,st0
	fmul  [speed2]
       fsubr  [CameraPos.x]
	fstp  [CameraPos.x]
       faddp  st1,st0
	fmul  [speed2]
       fsubr  [CameraPos.z]
	fstp  [CameraPos.z]
 @@:	 ret

Start:
       fldcw  word[fpcw_Prec64]
      invoke  QueryPerformanceFrequency,Frequency
	 mov  dword[VertexCoorNormalColorTable],0
	 mov  dword[ContourVertexCoorNormalColorTable],0
      invoke  VirtualAlloc,0,32*INIT_CONST_TABLE_ENTRIES,MEM_COMMIT,PAGE_READWRITE
	 mov  dword[ConstTable],eax
	 sub  eax,32
	 mov  dword[ConstTableTop],eax
	 mov  dword[ConstTableSizeB],32*INIT_CONST_TABLE_ENTRIES
      invoke  VirtualAlloc,0,16*INIT_VAR_TABLE_ENTRIES,MEM_COMMIT,PAGE_READWRITE
	 mov  dword[VarStringTable],eax
	pxor  xmm0,xmm0
      movdqa  xword[eax],xmm0
	 mov  dword[VarTableEntries],0
      invoke  VirtualAlloc,0,32*INIT_VAR_TABLE_ENTRIES,MEM_COMMIT,PAGE_READWRITE
	 mov  dword[VarValueTable],eax
	 mov  dword[VarValueTableSizeB],32*INIT_VAR_TABLE_ENTRIES
      invoke  VirtualAlloc,0,16*INIT_VAR_TABLE_ENTRIES,MEM_COMMIT,PAGE_READWRITE
	 mov  dword[DefStringTable],eax
	pxor  xmm0,xmm0
      movdqa  dqword[eax],xmm0
	 mov  dword[DefStringTableSizeB],16*INIT_VAR_TABLE_ENTRIES
      invoke  VirtualAlloc,0,16*INIT_VAR_TABLE_ENTRIES,MEM_COMMIT,PAGE_READWRITE
	 mov  dword[DefIndexArgAddressTable],eax
	pxor  xmm0,xmm0
      movdqa  dqword[eax],xmm0
	 mov  dword[DefIndexArgAddressTableSizeB],16*INIT_VAR_TABLE_ENTRIES
	 mov  cl,0x80
	movd  xmm7,ecx
      pslldq  xmm7,15
      movdqa  xmm0,xword[string_InputBase]
	call  GetVarAddress
	movd  xmm6,dword[InputBase]
      movdqa  dqword[eax+16*0],xmm6
      movdqa  dqword[eax+16*1],xmm7
      movdqa  xmm0,xword[string_OutputBase]
	call  GetVarAddress
	movd  xmm6,dword[OutputBase]
      movdqa  dqword[eax+16*0],xmm6
      movdqa  dqword[eax+16*1],xmm7
      movdqa  xmm0,xword[string_OutputBits]
	call  GetVarAddress
	movd  xmm6,dword[OutputBits]
      movdqa  dqword[eax+16*0],xmm6
      movdqa  dqword[eax+16*1],xmm7
      movdqa  xmm0,xword[string_Pi]
	call  GetVarAddress
       fldpi
	fldz
	 mov  byte[eax+31],0x00
	fstp  tword[eax+10]
	fstp  tword[eax]
      movdqa  xmm0,xword[string_E]
	call  GetVarAddress
	 fld  tword[const_f10_e]
	fldz
	 mov  byte[eax+31],0x00
	fstp  tword[eax+10]
	fstp  tword[eax]
      movdqa  xmm0,xword[string_I]
	call  GetVarAddress
	fldz
	fld1
	 mov  byte[eax+31],0x00
	fstp  tword[eax+10]
	fstp  tword[eax]
	 mov  [cc.lStructSize],sizeof.CHOOSECOLOR
	 mov  [cc.rgbResult],INITIAL_COLOR
      invoke  GetModuleHandle,0
	 mov  [wc.hInstance],eax
      invoke  LoadIcon,eax,17
	 mov  [wc.hIcon],eax
      invoke  LoadCursor,0,IDC_ARROW
	 mov  [wc.hCursor],eax
      invoke  RegisterClass,wc
      invoke  LoadMenu,[wc.hInstance],37
      invoke  CreateWindowEx,0,string_Class,string_Title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,150,150,INITIAL_WINDOW_WIDTH,INITIAL_WINDOW_HEIGHT,NULL,eax,[wc.hInstance],NULL
	 mov  [hMainWindow],eax

MsgLoop:
      invoke  GetMessage,msg,NULL,0,0
	 cmp  eax,1
	  jb  EndLoop
	 jne  MsgLoop
      invoke  TranslateMessage,msg
      invoke  DispatchMessage,msg
	 jmp  MsgLoop

Error:
      invoke  MessageBoxA,NULL,string_Error,NULL,MB_ICONERROR+MB_OK

EndLoop:
	 mov  ebx,[DefIndexArgAddressTable]
	 jmp  .w2
.w1:
      invoke  VirtualFree,dword[ebx+8],0,MEM_RELEASE
	 add  ebx,16
.w2:
	 cmp  dword[ebx+0],0
	 jne  .w1
      invoke  VirtualFree,dword[ConstTable],0,MEM_RELEASE
      invoke  VirtualFree,dword[VarStringTable],0,MEM_RELEASE
      invoke  VirtualFree,dword[VarValueTable],0,MEM_RELEASE
      invoke  VirtualFree,dword[DefStringTable],0,MEM_RELEASE
      invoke  VirtualFree,dword[DefIndexArgAddressTable],0,MEM_RELEASE
      invoke  ExitProcess,[msg.wParam]

WindowProc:   ; proc WindowProc hwnd,wmsg,wparam,lparam
	push  ebp
	 mov  ebp,esp

  virtual at  ebp
	  dd  ?,?
 .hwnd	  dd  ?
 .wmsg	  dd  ?
 .wparam  dd  ?
 .lparam  dd  ?
	 end  virtual

	push  esi edi ebx ebp
	 cmp  [.wmsg],WM_CREATE
	  je  .wmcreate
	 cmp  [.wmsg],WM_SIZE
	  je  .wmsize
	 cmp  [.wmsg],WM_SETFOCUS
	  je  .wmsetfocus
	 cmp  [.wmsg],WM_COMMAND
	  je  .wmcommand
	 cmp  [.wmsg],WM_DESTROY
	  je  .wmdestroy
.defwndproc:
      invoke  DefWindowProc,[.hwnd],[.wmsg],[.wparam],[.lparam]
	 jmp  .finish
.wmcreate:
      invoke  GetClientRect,[.hwnd],rc
	 mov  eax,3
	 mul  [rc.bottom]
	 shr  eax,3
	 add  eax,[rc.top]
	 mov  [rc.bottom],eax
      invoke  CreateWindowEx,WS_EX_CLIENTEDGE,string_Edit,0,WS_SIZEBOX+WS_VISIBLE+WS_CHILD+WS_VSCROLL+ES_AUTOVSCROLL+ES_MULTILINE,[rc.left],[rc.top],[rc.right],[rc.bottom],[.hwnd],0,[wc.hInstance],NULL
	 mov  [hInputWindow],eax
      invoke  GetClientRect,[.hwnd],rc
	 mov  eax,3
	 mul  [rc.bottom]
	 shr  eax,3
	 add  [rc.top],eax
	 add  eax,STATUSWINDOW_HEIGHT
	 sub  [rc.bottom],eax
      invoke  CreateWindowEx,WS_EX_CLIENTEDGE,string_Edit,0,WS_SIZEBOX+WS_VISIBLE+WS_CHILD+WS_VSCROLL+ES_AUTOVSCROLL+ES_MULTILINE,[rc.left],[rc.top],[rc.right],[rc.bottom],[.hwnd],0,[wc.hInstance],NULL
	 mov  [hOutputWindow],eax
      invoke  CreateFont,16,0,0,0,FW_BOLD,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL
	 mov  [hInputFont],eax
      invoke  CreateFont,15,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL
	 mov  [hOutputFont],eax
      invoke  SendMessage,[hInputWindow],WM_SETFONT,[hInputFont],FALSE
      invoke  SendMessage,[hOutputWindow],WM_SETFONT,[hOutputFont],FALSE
      invoke  CreateStatusWindow,WS_CHILD+WS_VISIBLE+SBS_SIZEGRIP,NULL,[.hwnd],0
	 mov  [hStatusWnd],eax
      invoke  SendMessage,[hStatusWnd],SB_SETTEXT,0,string_Greeting
	 jmp  .zfinish
.wmsize:
      invoke  GetClientRect,[.hwnd],rc
	 mov  eax,3
	 mul  [rc.bottom]
	 shr  eax,3
	 add  eax,[rc.top]
	 mov  [rc.bottom],eax
      invoke  MoveWindow,[hInputWindow],[rc.left],[rc.top],[rc.right],[rc.bottom],TRUE
      invoke  GetClientRect,[.hwnd],rc
	 mov  eax,3
	 mul  [rc.bottom]
	 shr  eax,3
	 add  [rc.top],eax
	 add  eax,STATUSWINDOW_HEIGHT
	 sub  [rc.bottom],eax
      invoke  MoveWindow,[hOutputWindow],[rc.left],[rc.top],[rc.right],[rc.bottom],TRUE
      invoke  MoveWindow,[hStatusWnd],0,0,0,0,TRUE
	 jmp  .zfinish
.wmsetfocus:
      invoke  SetFocus,[hInputWindow]
	 xor  eax,eax
	 jmp  .finish
.wmcommand:
       movzx  eax,word[.wparam]
	 cmp  eax,IDM_OPEN
	  je  .open
	 cmp  eax,IDM_VIEW_SYMBOLS
	  je  .viewsymbols
	 cmp  eax,IDM_EVALUATE
	  je  .evaluate
	 cmp  eax,IDM_CLEAR
	  je  .clear
	 cmp  eax,IDM_DEMO1
	  je  .demo1
	 cmp  eax,IDM_DEMO2
	  je  .demo2
	 cmp  eax,IDM_DEMO3
	  je  .demo3
	 cmp  eax,IDM_DEMO4
	  je  .demo4
	 cmp  eax,IDM_DEMO5
	  je  .demo5
	 cmp  eax,IDM_DEMO6
	  je  .demo6
	 cmp  eax,IDM_DEMO7
	  je  .demo7
	 cmp  eax,IDM_FONT_SMALL
	  je  .fontsmall
	 cmp  eax,IDM_FONT_MEDIUM
	  je  .fontmedium
	 cmp  eax,IDM_FONT_LARGE
	  je  .fontlarge
	 cmp  eax,IDM_GRAPHICS_LOW
	  je  .graphicslow
	 cmp  eax,IDM_GRAPHICS_MED
	  je  .graphicsmed
	 cmp  eax,IDM_GRAPHICS_HI
	  je  .graphicshi
	 cmp  eax,IDM_HELP
	  je  .help
	 cmp  eax,IDM_EXIT
	  je  .wmdestroy
	 jmp  .defwndproc
.clear:
      invoke  SendMessage,[hInputWindow],WM_SETTEXT,0,0
	 jmp  .zfinish
.demo1:
      invoke  SendMessage,[hInputWindow],WM_SETTEXT,0,string_Demo1
	 jmp  .zfinish
.demo2:
      invoke  SendMessage,[hInputWindow],WM_SETTEXT,0,string_Demo2
	 jmp  .zfinish
.demo3:
      invoke  SendMessage,[hInputWindow],WM_SETTEXT,0,string_Demo3
	 jmp  .zfinish
.demo4:
      invoke  SendMessage,[hInputWindow],WM_SETTEXT,0,string_Demo4
	 jmp  .zfinish
.demo5:
      invoke  SendMessage,[hInputWindow],WM_SETTEXT,0,string_Demo5
	 jmp  .zfinish
.demo6:
      invoke  SendMessage,[hInputWindow],WM_SETTEXT,0,string_Demo6
	 jmp  .zfinish
.demo7:
      invoke  SendMessage,[hInputWindow],WM_SETTEXT,0,string_Demo7
	 jmp  .zfinish
.graphicslow:
	 mov  dword[ParametricPlotDefaultDivisions],LOW_DIVISIONS
	 mov  dword[ContourPlotDefaultDivisions],LOW_DIVISIONS_CONTOURPLOT
	 jmp  .zfinish
.graphicsmed:
	 mov  dword[ParametricPlotDefaultDivisions],MED_DIVISIONS
	 mov  dword[ContourPlotDefaultDivisions],MED_DIVISIONS_CONTOURPLOT
	 jmp  .zfinish
.graphicshi:
	 mov  dword[ParametricPlotDefaultDivisions],HI_DIVISIONS
	 mov  dword[ContourPlotDefaultDivisions],HI_DIVISIONS_CONTOURPLOT
	 jmp  .zfinish
.fontsmall:
      invoke  DeleteObject,[hInputFont]
      invoke  DeleteObject,[hOutputFont]
      invoke  CreateFont,16,8,0,0,FW_BOLD,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL
	 mov  [hInputFont],eax
      invoke  CreateFont,15,7,0,0,FW_NORMAL,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL
	 mov  [hOutputFont],eax
	 jmp  .font
.fontmedium:
      invoke  DeleteObject,[hInputFont]
      invoke  DeleteObject,[hOutputFont]
      invoke  CreateFont,24,12,0,0,FW_BOLD,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL
	 mov  [hInputFont],eax
      invoke  CreateFont,20,10,0,0,FW_NORMAL,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL
	 mov  [hOutputFont],eax
	 jmp  .font
.fontlarge:
      invoke  DeleteObject,[hInputFont]
      invoke  DeleteObject,[hOutputFont]
      invoke  CreateFont,30,15,0,0,FW_BOLD,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL
	 mov  [hInputFont],eax
      invoke  CreateFont,25,12,0,0,FW_NORMAL,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL
	 mov  [hOutputFont],eax
.font:
     invoke  SendMessage,[hOutputWindow],WM_SETFONT,[hOutputFont],FALSE
     invoke  SendMessage,[hInputWindow],WM_SETFONT,[hInputFont],FALSE
     invoke  SendMessage,[hOutputWindow],WM_GETTEXTLENGTH,0,0
	lea  esi,[eax+1]
     invoke  VirtualAlloc,0,esi,MEM_COMMIT,PAGE_READWRITE
       test  eax,eax
	 jz  .memoryerror
	mov  dword[OutputString],eax
     invoke  SendMessage,[hOutputWindow],WM_GETTEXT,esi,dword[OutputString]
     invoke  SendMessage,[hOutputWindow],WM_SETTEXT,0,dword[OutputString]
     invoke  VirtualFree,dword[OutputString],0,MEM_RELEASE
     invoke  SendMessage,[hInputWindow],WM_GETTEXTLENGTH,0,0
	lea  esi,[eax+1]
     invoke  VirtualAlloc,0,esi,MEM_COMMIT,PAGE_READWRITE
       test  eax,eax
	 jz  .memoryerror
	mov  dword[InputString],eax
     invoke  SendMessage,[hInputWindow],WM_GETTEXT,esi,dword[InputString]
     invoke  SendMessage,[hInputWindow],WM_SETTEXT,0,dword[InputString]
     invoke  VirtualFree,dword[InputString],0,MEM_RELEASE
	jmp  .zfinish
.help:
     invoke  ShellExecute,hMainWindow,"open","readme.txt","","", SW_SHOW
	jmp  .zfinish
.open:
	mov  dword[of.lStructSize],sizeof.OPENFILENAME
	mov  dword[of.lpstrFile],OpenFileString
	mov  dword[of.nMaxFile],1024
     invoke  GetOpenFileNameA,of
       test  eax,eax
	 jz  .zfinish
     invoke  CreateFileA,OpenFileString,GENERIC_READ,0,0,OPEN_EXISTING,0,0
	mov  esi,eax
       test  eax,eax
	 jz  .zfinish
     invoke  GetFileSize,esi,Temp1
	lea  ebx,[eax+1]
     invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
       test  eax,eax
	 jz  .memoryerror
	mov  dword[InputString],eax
     invoke  ReadFile,esi,dword[InputString],ebx,Temp1,0
     invoke  CloseHandle,esi
	mov  eax,dword[InputString]
	mov  byte[eax+ebx],0
     invoke  SendMessage,[hInputWindow],WM_SETTEXT,0,dword[InputString]
     invoke  VirtualFree,dword[InputString],0,MEM_RELEASE
	jmp  .zfinish
.viewsymbols:
     invoke  SendMessage,[hOutputWindow],WM_GETTEXTLENGTH,0,0
	lea  esi,[eax+1]
	lea  eax,[ebx+esi+500]
     invoke  VirtualAlloc,0,esi,MEM_COMMIT,PAGE_READWRITE
       test  eax,eax
	 jz  .memoryerror
	mov  dword[OutputString],eax
     invoke  SendMessage,[hOutputWindow],WM_GETTEXT,esi,dword[OutputString]
     invoke  SendMessage,[hOutputWindow],WM_GETTEXTLENGTH,0,0
	lea  esi,[eax+1]
	mov  eax,dword[ConstTableSizeB]
	add  eax,dword[VarValueTableSizeB]
	mov  ecx,dword[DefIndexArgAddressTableSizeB]
	shl  ecx,9
	add  ecx,esi
	lea  eax,[ecx+4*eax]
     invoke  VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE
       test  eax,eax
	 jz  .memoryerror
	mov  dword[InputString],eax
       push  dword[OutputBase]
	mov  dword[OutputBase],10
	mov  edi,dword[InputString]
	mov  eax,'****'
	mov  ecx,8
      repnz  stosd
	mov  eax,0x0a0d
      stosw
	mov  esi,dword[ConstTable]
	cmp  esi,dword[ConstTableTop]
	 ja  .constdone
	mov  eax,'    '
      stosd
	mov  eax,'Cons'
      stosd
	mov  eax,'tant'
      stosd
	mov  eax,'s: ('
      stosd
	mov  eax,dword[ConstTableTop]
	sub  eax,dword[ConstTable]
	shr  eax,5
	inc  eax
       call PrintInteger
	mov  eax,') '+(0x0a0d shl 16)
      stosd
.nextconst:
       call  PrintComplex
	mov  ax,0x0a0d
      stosw
	add  esi,32
	cmp  esi,dword[ConstTableTop]
	jbe  .nextconst
	mov  ax,0x0a0d
      stosw
.constdone:
	mov  eax,'    '
      stosd
	mov  eax,'Vari'
      stosd
	mov  eax,'able'
      stosd
	mov  eax,'s: ('
      stosd
	mov  eax,dword[VarTableEntries]
       call  PrintInteger
	mov  eax,') '+(0x0a0d shl 16)
      stosd
	mov  esi,dword[VarValueTable]
	mov  ebx,dword[VarStringTable]
       pxor  xmm7,xmm7
     movdqa  xmm0,dqword[ebx]
     movdqu  xword[edi],xmm0
.nextvar:
	mov  ecx,MAX_SYMBOL_LENGTH+2
	xor  al,al
	mov  byte[esi+16],al
      repnz  scasb
	mov  byte[edi-1],':'
	mov  al,' '
      repnz
      stosb
       push  ebx
       call  PrintComplex
	pop  ebx
	mov  ax,0x0a0d
      stosw
	add  esi,32
	add  ebx,16
     movdqa  xmm0,dqword[ebx]
     movdqu  dqword[edi],xmm0
    pcmpeqb  xmm0,xmm7
   pmovmskb  ecx,xmm0
	cmp  cx,-1
	jne  .nextvar
	mov  ebx,dword[DefIndexArgAddressTable]
.nextdef:
	 cmp  dword[ebx],0
	  je  .defdone
	 cmp  dword[ebx+8],0
	  je  .skip
	 mov  ax,0x0a0d
       stosw
	 mov  eax,'    '
       stosd
	 mov  eax,dword[ebx]
      movdqa  xmm0,xword[eax]
      movdqu  xword[edi],xmm0
	 mov  ecx,MAX_SYMBOL_LENGTH+2
	 xor  al,al
	 mov  byte[esi+16],al
       repnz  scasb
	 mov  byte[edi-1],'['
	 mov  ecx,dword[ebx+4]
	 mov  ax,0xb7+("," shl 8)
       repnz  stosw
	 dec  edi
	 mov  eax,dword[ebx+8]
	 mov  ecx,dword[eax+4]
	test  ecx,ecx
	  jz  @f
	 mov  al,':'
       stosb
	 mov  ax,0xb7+("," shl 8)
       repnz  stosw
	 dec  edi
 @@:	 mov  eax,']:  '
       stosd
	 mov  esi,dword[ebx+8]
	 add  esi,8
	push  ebx
	call  PrintCode
	 mov  ax,0x0a0d
       stosw
	 pop  ebx
.skip:
	 add  ebx,16
	 jmp  .nextdef
.defdone:
	 mov  eax,'****'
	 mov  ecx,8
       repnz
       stosd
	 mov  eax,0x0a0d
       stosw
	 pop  dword[OutputBase]
	 mov  esi,dword[OutputString]
 @@:   lodsb
       stosb
	test  al,al
	 jnz  @b
      invoke  SendMessage,[hOutputWindow],WM_SETTEXT,0,dword[InputString]
      invoke  VirtualFree,dword[InputString],0,MEM_RELEASE
      invoke  VirtualFree,dword[OutputString],0,MEM_RELEASE
	 jmp  .zfinish
.evaluate:
      invoke  SendMessage,[hInputWindow],WM_GETTEXTLENGTH,0,0
	 lea  ebx,[eax+100]
      invoke  SendMessage,[hOutputWindow],WM_GETTEXTLENGTH,0,0
	 lea  esi,[eax+100]
	 lea  eax,[ebx+esi+500]
      invoke  VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  .memoryerror
	 mov  dword[InputString],eax
      invoke  VirtualAlloc,0,esi,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  .memoryerror
	 mov  dword[OutputString],eax
      invoke  SendMessage,[hInputWindow],WM_GETTEXT,ebx,dword[InputString]
      invoke  SendMessage,[hOutputWindow],WM_GETTEXT,esi,dword[OutputString]
	 xor  eax,eax
	 mov  ecx,esi
	 mov  edi,dword[InputString]
       repnz  scasb
	 mov  dword[Caret],edi
	 lea  ebx,[8*ebx]
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  .memoryerror
	 mov  dword[Buffer1],eax
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  .memoryerror
	 mov  dword[Buffer2],eax
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  .memoryerror
	 mov  dword[Buffer3],eax
       fldcw  word[fpcw_Prec64]   ; reset the control word in case something messed it up
      movdqa  xmm0,xword[string_InputBase]
	call  GetVarAddress
	 mov  esi,eax
	call  CVT2INT
	 mov  edx,dword[esi+4*0]
	 mov  ecx,INITIAL_INPUT_BASE
	 cmp  edx,16
       cmova  edx,ecx
	 cmp  edx,2
       cmovb  edx,ecx
	 mov  dword[InputBase],edx
	movd  xmm0,edx
	pxor  xmm1,xmm1
      movdqa  xword[esi+16*0],xmm0
      movdqa  xword[esi+16*1],xmm1
	 mov  byte[esi+31],0x80
	 mov  ecx,6
	 mov  edi,DigitStringJTable+4*97
	 mov  eax,Parse.Letter
       repnz  stosd
	 mov  edi,DigitStringJTable+4*97
	 mov  ecx,dword[InputBase]
	 sub  ecx,10
	 jbe  @f
	 mov  eax,Parse.Digit
       repnz  stosd
 @@:	call  ProcessInput
	 mov  esi,dword[OutputString]
	 mov  edi,dword[Caret]
	 mov  word[edi-1],0x0a0d
	 inc  edi
 @@:   lodsb
       stosb
	test  al,al
	 jnz  @b
      invoke  SendMessage,[hOutputWindow],WM_SETTEXT,0,dword[InputString]
      invoke  SendMessage,[hStatusWnd],SB_SETTEXT,0,StatusString
      invoke  VirtualFree,dword[InputString],0,MEM_RELEASE
      invoke  VirtualFree,dword[OutputString],0,MEM_RELEASE
      invoke  VirtualFree,dword[Buffer1],0,MEM_RELEASE
      invoke  VirtualFree,dword[Buffer2],0,MEM_RELEASE
      invoke  VirtualFree,dword[Buffer3],0,MEM_RELEASE
	pxor  xmm0,xmm0
      movdqu  dqword[Buffer1],xmm0
	 jmp  .zfinish
.wmdestroy:
      invoke  DeleteObject,[hInputFont]
      invoke  DeleteObject,[hOutputFont]
      invoke  PostQuitMessage,0
	 jmp  .zfinish
.memoryerror:
      invoke  MessageBoxA,NULL,string_MemoryErrorMessage,string_MemoryErrorCaption,MB_ICONERROR+MB_OK
 .zfinish:
	 xor  eax,eax
 .finish:
	 pop  ebp ebx edi esi
	 mov  esp,ebp
	 pop  ebp
	 ret

PrintInteger:
	push  ebp
	 mov  ebp,esp
	test  eax,eax
	 jns  .l1
	 mov  byte[edi],'-'
	 inc  edi
	 neg  eax
.l1:
	 xor  edx,edx
	 div  dword[OutputBase]
	push  edx
	test  eax,eax
	 jnz  .l1
.l2:	 pop  eax
	 mov  dl,9
	 sub  dl,al
	 sar  dl,7
	 add  al,'0'
	 and  dl,39
	 add  al,dl
       stosb
	 cmp  esp,ebp
	  jb  .l2
	 pop  ebp
	 ret

PrintComplex:
	 mov  al,byte[esi+31]
	test  al,al
	  js  .Integer
	fldz
	 fld  tword[esi]
      fcomip  st1
	fstp  st0
	  jp  .ReNZ
	  je  .ReZ
.ReNZ:
	 fld  tword[esi]
	call  PrintFloat
	fldz
	 fld  tword[esi+10]
      fcomip  st1
	fstp  st0
	  jp  .ReNZImNZ
	  jb  @f
	  je  .Done
.ReNZImNZ:
	 mov  al,'+'
       stosb
 @@:	  bt  word[esi+8],15
	 sbb  edi,0
	 fld  tword[esi+10]
	call  PrintFloat
	 mov  eax,'*I'
       stosw
.Done:
	 ret
.ReZ:
	fldz
	 fld  tword[esi+10]
      fcomip  st1
	fstp  st0
	  jp  .ReZImNZ
	  je  .ReZImZ
.ReZImNZ:
	 fld  tword[esi+10]
	call  PrintFloat
	 mov  eax,'*I'
       stosw
	 ret
.ReZImZ:
	 mov  ax,'0.'
       stosw
	 ret
.Integer:
	  bt  eax,6
	  jc  .Neg
.Pos:
	 mov  eax,dword[esi+4*0]
	 mov  ecx,dword[esi+4*1]
	 mov  dword[Temp1+4*0],eax
	 mov  dword[Temp1+4*1],ecx
	 mov  eax,dword[esi+4*2]
	 mov  ecx,dword[esi+4*3]
	 mov  dword[Temp1+4*2],eax
	 mov  dword[Temp1+4*3],ecx
	 mov  eax,dword[esi+4*4]
	 mov  ecx,dword[esi+4*5]
	 mov  dword[Temp1+4*4],eax
	 mov  dword[Temp1+4*5],ecx
	 mov  eax,dword[esi+4*6]
	 mov  ecx,dword[esi+4*7]
	 mov  dword[Temp1+4*6],eax
	 btr  ecx,31
	 mov  dword[Temp1+4*7],ecx
	 jmp  .IntCont
.Neg:
	 mov  al,'-'
       stosb
	 xor  ecx,ecx
	 mov  eax,ecx
	 sub  eax,dword[esi+4*0]
	 mov  dword[Temp1+4*0],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*1]
	 mov  dword[Temp1+4*1],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*2]
	 mov  dword[Temp1+4*2],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*3]
	 mov  dword[Temp1+4*3],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*4]
	 mov  dword[Temp1+4*4],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*5]
	 mov  dword[Temp1+4*5],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*6]
	 mov  dword[Temp1+4*6],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*7]
	 mov  dword[Temp1+4*7],eax
.IntCont:
	 mov  ebp,esp
.ComputeDigits:
	 xor  edx,edx
	 mov  eax,dword[Temp1+4*7]
	 div  dword[OutputBase]
	 mov  dword[Temp1+4*7],eax
	 mov  ecx,eax
	 mov  eax,dword[Temp1+4*6]
	 div  dword[OutputBase]
	 mov  dword[Temp1+4*6],eax
	  or  ecx,eax
	 mov  eax,dword[Temp1+4*5]
	 div  dword[OutputBase]
	 mov  dword[Temp1+4*5],eax
	  or  ecx,eax
	 mov  eax,dword[Temp1+4*4]
	 div  dword[OutputBase]
	 mov  dword[Temp1+4*4],eax
	  or  ecx,eax
	 mov  eax,dword[Temp1+4*3]
	 div  dword[OutputBase]
	 mov  dword[Temp1+4*3],eax
	  or  ecx,eax
	 mov  eax,dword[Temp1+4*2]
	 div  dword[OutputBase]
	 mov  dword[Temp1+4*2],eax
	  or  ecx,eax
	 mov  eax,dword[Temp1+4*1]
	 div  dword[OutputBase]
	 mov  dword[Temp1+4*1],eax
	  or  ecx,eax
	 mov  eax,dword[Temp1+4*0]
	 div  dword[OutputBase]
	 mov  dword[Temp1+4*0],eax
	  or  ecx,eax
	push  edx
	 jnz  .ComputeDigits
.PrintDigits:
	 pop  eax
	 mov  dl,9
	 sub  dl,al
	 sar  dl,7
	 add  al,'0'
	 and  dl,39
	 add  al,dl
       stosb
	 cmp  esp,ebp
	  jb  .PrintDigits
	 ret

PrintFloat:
.DisplayDigits equ  Temp6+4*0
.e	 equ  Temp6+4*1
.n	 equ  Temp6+4*2
	 fld  st0
	fstp  tword[Temp1+4]
	 mov  byte[edi],'-'
	 mov  ax,word[Temp1+12]
	  bt  eax,15
	 adc  edi,0
	 and  ax,0x7FFF
	  jz  .Zero
	 cmp  ax,0x7FFF
	  je  .Infinity
	push  esi
	 sub  ax,16383
       movsx  eax,ax
	 mov  dword[.e],eax
	fld1
	 fld  st1
	fabs
       fyl2x
	fld1
	fild  dword[OutputBase]
       fyl2x
       fdivp  st1,st0
	 fld  tword[const_f10_1o2]
       fsubp  st1,st0
       fistp  dword[.n]
.Try:
	 fld  st0
	fstp  tword[Temp1+4]
	 mov  dword[Temp1+0],0
	 mov  dword[Temp1+12],0
	push  edi
	 mov  esi,dword[.e]
	 sub  esi,63
	fld1
	fild  dword[OutputBase]
       fyl2x
	fild  dword[OutputBits]
      fdivrp  st1,st0
	 fld  tword[const_f10_1o2]
       faddp  st1,st0
       fistp  dword[esp-4]
	 mov  edi,dword[esp-4]
	 mov  dword[.DisplayDigits],edi
	 sub  edi,dword[.n]
.Shift:
	 mov  eax,dword[Temp1+12]
	test  esi,esi
	  js  .ANeg
	  jz  .AZero
.APos:
	test  eax,eax
	  js  .DivByBase
	 jmp  .MulByTwo
.ANeg:
	 cmp  edi,0
	 jle  .DivByTwo
	 shr  eax,32-4
	  jz  .MulByBase
	 jmp  .DivByTwo
.AZero:
	test  edi,edi
	  js  .DivByBase
	  jz  .ShiftDone
	 jmp  .MulByBase
.MulByTwo:
	 dec  esi
	 clc
	 rcl  dword[Temp1+0],1
	 rcl  dword[Temp1+4],1
	 rcl  dword[Temp1+8],1
	 rcl  dword[Temp1+12],1
	  jc  InternalError
	 jmp  .Shift
.DivByTwo:
	 inc  esi
	 clc
	 rcr  dword[Temp1+12],1
	 rcr  dword[Temp1+8],1
	 rcr  dword[Temp1+4],1
	 rcr  dword[Temp1+0],1
	 jmp  .Shift
.MulByBase:
	 dec  edi
	 mov  eax,dword[Temp1+0]
	 mul  dword[OutputBase]
	 mov  dword[Temp1+0],eax
	 mov  ebx,edx
	 xor  ecx,ecx
	 mov  eax,dword[Temp1+4]
	 mul  dword[OutputBase]
	 add  ebx,eax
	 adc  ecx,edx
	 mov  dword[Temp1+4],ebx
	 xor  ebx,ebx
	 mov  eax,dword[Temp1+8]
	 mul  dword[OutputBase]
	 add  ecx,eax
	 adc  ebx,edx
	 mov  dword[Temp1+8],ecx
	 xor  ecx,ecx
	 mov  eax,dword[Temp1+12]
	 mul  dword[OutputBase]
	 add  ebx,eax
	 adc  ecx,edx
	 mov  dword[Temp1+12],ebx
	 jnz  InternalError
	 jmp  .Shift
.DivByBase:
	 inc  edi
	 xor  edx,edx
	 mov  eax,dword[Temp1+12]
	 div  dword[OutputBase]
	 mov  dword[Temp1+12],eax
	 mov  eax,dword[Temp1+8]
	 div  dword[OutputBase]
	 mov  dword[Temp1+8],eax
	 mov  eax,dword[Temp1+4]
	 div  dword[OutputBase]
	 mov  dword[Temp1+4],eax
	 mov  eax,dword[Temp1+0]
	 div  dword[OutputBase]
	 mov  dword[Temp1+0],eax
	 jmp  .Shift
.ShiftDone:
	 pop  edi
	 mov  eax,dword[Temp1+0]
	 rcl  eax,1
	 adc  dword[Temp1+4],0
	 adc  dword[Temp1+8],0
	 adc  dword[Temp1+12],0
	  jc  InternalError
	 mov  ebp,esp
.ComputeDigits:
	 xor  edx,edx
	 mov  eax,dword[Temp1+12]
	 div  dword[OutputBase]
	 mov  dword[Temp1+12],eax
	 mov  ecx,eax
	 mov  eax,dword[Temp1+8]
	 div  dword[OutputBase]
	 mov  dword[Temp1+8],eax
	  or  ecx,eax
	 mov  eax,dword[Temp1+4]
	 div  dword[OutputBase]
	 mov  dword[Temp1+4],eax
	  or  ecx,eax
	push  edx
	 jnz  .ComputeDigits
	 mov  eax,ebp
	 sub  eax,esp
	 sar  eax,2
	 dec  eax
	 cmp  eax,dword[.DisplayDigits]
	  je  .Good
	 mov  esp,ebp
	  jb  .DecN
	 ;ja  .IncN
.IncN:
	 inc  dword[.n]
	 jmp  .Try
.DecN:
	 dec  dword[.n]
	 jmp  .Try
.Good:
	fstp  st0
	 lea  ecx,[esi+1]
	 mov  edx,dword[.n]
	 cmp  edx,12
	  jg  .PrintDigits
	 cmp  edx,-12
	  jl  .PrintDigits
	  or  esi,-1
	 lea  ecx,[edx+1]
	 cmp  edx,0
	 jge  .PrintDigits
	 mov  al,'0'
       stosb
	 mov  al,'.'
       stosb
	 mov  al,'0'
	 neg  ecx
       repnz  stosb
.PrintDigits:
	 pop  eax
	 mov  dl,9
	 sub  dl,al
	 sar  dl,7
	 add  al,'0'
	 and  dl,39
	 add  al,dl
       stosb
	 dec  ecx
	 jnz  .NoPoint
	 mov  al,'.'
       stosb
.NoPoint:
	 cmp  esp,ebp
	  jb  .PrintDigits
	 cmp  ecx,0
	 jle  .NoExtras
	 mov  al,'0'
       repnz  stosb
	 mov  al,'.'
       stosb
.NoExtras:
	 cmp  byte[edi-1],'0'
	 jne  .NoMore
	 dec  edi
	 jmp  .NoExtras
.NoMore:
	test  esi,esi
	 jnz  .NoExp
	 mov  ax,'*^'
       stosw
	 mov  eax,dword[.n]
	call  PrintInteger
.NoExp:
	 pop  esi
	 ret
.Zero:
	 mov  al,'0'
       stosb
	fstp  st0
	 ret
.Infinity:
	 mov  eax,'Infi'
       stosd
	 mov  eax,'nity'
       stosd
	fstp  st0
	 ret

PrintPointer:  ; prints the pointer qword[esi]
	push  ebp
	push  ebx
	push  ecx
	push  edx
	 mov  eax,dword[esi+4*0]
	 cmp  eax,0
	  je  .Var
	 cmp  eax,-1
	  je  .Arg
	 mov  eax,'????'
       stosd
.done:
	 pop  edx
	 pop  ecx
	 pop  ebx
	 pop  ebp
	 ret
.Var:
	 mov  eax,dword[esi+4*1]
	call  GetVarString
	 jmp  .done
.Arg:
	 mov  ax,'st'
       stosw
	 mov  eax,dword[esi+4*1]
	 shr  eax,5
	call  PrintInteger
	 jmp  .done

PrintCode:
.NewLine:
	 mov  ax,0x0a0d
       stosw
.Current:
	 mov  eax,dword[esi+4*0]
	 mov  ecx,dword[esi+4*1]
	 mov  ebp,eax
       movzx  eax,al
	 sar  ebp,8
	 jmp  dword[@f+4*eax]
align 4
 @@:	  dd  .UND,.MOV,.FXN,.DEF,.RET,.HLT
	  dd  .JF,.JT,.J,.JP
.MOV:
	 add  esi,4*5
	push  esi
	 sub  esi,8
	call  PrintPointer
	 mov  eax,' = '
       stosd
	 dec  edi
	 sub  esi,8
	call  PrintPointer
	 pop  esi
	 mov  al,';'
       stosb
	 jmp  .NewLine
.FXN:
	 add  esi,8
	call  PrintPointer
	 mov  eax,' = '
       stosd
	 dec  edi
	 mov  eax,ecx
	call  GetFxnString
	 mov  al,'['
       stosb
	 lea  esi,[esi+8*ebp+8]
	push  esi
.l1:
	 sub  esi,8
	call  PrintPointer
	 mov  ax,', '
       stosw
	 sub  ebp,1
	  ja  .l1
	 mov  word[edi-2],"];"
	 pop  esi
	 jmp  .NewLine
.DEF:
	 mov  ax,'st'
       stosw
	 mov  eax,dword[esi+4*2]
	 shr  eax,5
	call  PrintInteger
	 mov  eax,' =  '
       stosd
	 mov  eax,ecx
	call  GetDefStringFromAddress
	 mov  al,'['
       stosb
	 lea  esi,[esi+8*ebp+12]
	push  esi
.l2:
	 sub  esi,8
	call  PrintPointer
	 mov  ax,', '
       stosw
	 sub  ebp,1
	  ja  .l2
	 mov  word[edi-2],"];"
	 pop  esi
	 jmp  .NewLine
.RET:
	 mov  eax,'Retu'
       stosd
	 mov  eax,'rn['
       stosd
	 dec  edi
	 add  esi,4
	call  PrintPointer
	 mov  ax,'];'
       stosw
	 ret
.HLT:
	 mov  eax,'Halt'
       stosd
	 ret
.JT:
	 mov  eax,'If['
       stosd
	 dec  edi
	 add  esi,4
	call  PrintPointer
	 add  esi,8
	 mov  eax,', Ju'
       stosd
	 mov  eax,'mp['
       stosd
	 dec  edi
	 mov  eax,ebp
	call  PrintInteger
	 mov  eax,']];'
       stosd
	 dec  edi
	 jmp  .NewLine
.JF:
	 mov  eax,'If[~'
       stosd
	 add  esi,4
	call  PrintPointer
	 add  esi,8
	 mov  eax,', Ju'
       stosd
	 mov  eax,'mp['
       stosd
	 dec  edi
	 mov  eax,ebp
	 sar  eax,2
	call  PrintInteger
	 mov  eax,']];'
       stosd
	 dec  edi
	 jmp  .NewLine
.J:
	 mov  eax,'Jump'
       stosd
	 mov  eax,'['
       stosb
	 mov  eax,ebp
	call  PrintInteger
	 mov  ax,'];'
       stosw
	 jmp  .NewLine
.JP:
	 add  esi,4*3
	call  PrintPointer
	 mov  eax,' = '
       stosd
	 dec  edi
	 sub  esi,4*2
	call  PrintPointer
	 mov  eax,'; Ju'
       stosd
	 mov  eax,'mp['
       stosd
	 dec  edi
	 mov  eax,ebp
	 shr  eax,2
	call  PrintInteger
	 mov  ax,'];'
       stosw
	 add  esi,4*4
	 jmp  .NewLine
.UND:
	 mov  eax,'unde'
       stosd
	 mov  eax,'fine'
       stosd
	 mov  al,'d'
       stosb
	 ret

InternalError:
      invoke  MessageBox,NULL,string_InternalError,NULL,MB_ICONERROR+MB_OK
	 mov  esp,dword[espSave]
	 ret
EvalError_OutOfMemory:
	 mov  esi,string_EvalError_OutOfMemory
	 jmp  CompileError
EvalError_Stack:
	 mov  esi,string_EvalError_Stack
	 jmp  CompileError
CompileError_Set:
	 mov  esi,string_CompileError_BadAss
	 jmp  CompileError
CompileError_DefArg:
	 mov  esi,string_CompileError_DefArg
	 jmp  CompileError
CompileError_DefSep:
	 mov  esi,string_CompileError_DefSep
	 jmp  CompileError
CompileError_Def2Large:
	 mov  esi,string_CompileError_Def2Large
	 jmp  CompileError
CompileError_MustRet1:
	 mov  esi,string_CompileError_MustRet1
	 jmp  CompileError
CompileError_Plot_Ret3:
	 mov  esi,string_CompileError_Plot_Ret3
	 jmp  CompileError
CompileError_ContourPlot_Ret1:
	 mov  esi,string_CompileError_ContourPlot_Ret1
	 jmp  CompileError
CompileError_Plot_3Arg:
	 mov  esi,string_CompileError_Plot_3Arg
	 jmp  CompileError
CompileError_ContourPlot_4Arg:
	 mov  esi,string_CompileError_ContourPlot_4Arg
	 jmp  CompileError
CompileError_Plot_Arg2:
	 mov  esi,string_CompileError_Plot_Arg2
	 jmp  CompileError
CompileError_Plot_Arg3:
	 mov  esi,string_CompileError_Plot_Arg3
	 jmp  CompileError
CompileError_ContourPlot_Arg2:
	 mov  esi,string_CompileError_ContourPlot_Arg2
	 jmp  CompileError
CompileError_ContourPlot_Arg3:
	 mov  esi,string_CompileError_ContourPlot_Arg3
	 jmp  CompileError
CompileError_ContourPlot_Arg4:
	 mov  esi,string_CompileError_ContourPlot_Arg4
	 jmp  CompileError
CompileError_Iter_Var:
	 mov  esi,string_CompileError_Iter_Var
	 jmp  CompileError
CompileError_Plot:
	 mov  esi,string_CompileError_Plot
	 jmp  CompileError
CompileError_ContourPlot:
	 mov  esi,string_CompileError_ContourPlot
	 jmp  CompileError
CompileError_Def:
	 mov  esi,string_CompileError_Def
CompileError:
	 jmp  InputErrorCommon
CompileError_Scale:
	 mov  dword[string_CompileError_ArgCount+38],'Scal'
	 mov  dword[string_CompileError_ArgCount+38+4*1],'e'
	 jmp  CompileError_ArgCount
CompileError_Exp:
	 mov  dword[string_CompileError_ArgCount+38],'Exp'
	 jmp  CompileError_ArgCount
CompileError_Log:
	 mov  dword[string_CompileError_ArgCount+38],'Log'
	 jmp  CompileError_ArgCount
CompileError_Out:
	 mov  dword[string_CompileError_ArgCount+38],'Out'
	 jmp  CompileError_ArgCount
CompileError_Sin:
	 mov  dword[string_CompileError_ArgCount+38],'Sin'
	 jmp  CompileError_ArgCount
CompileError_Cos:
	 mov  dword[string_CompileError_ArgCount+38],'Cos'
	 jmp  CompileError_ArgCount
CompileError_Tan:
	 mov  dword[string_CompileError_ArgCount+38],'Tan'
	 jmp  CompileError_ArgCount
CompileError_Factorial:
	 mov  dword[string_CompileError_ArgCount+38],'Fact'
	 mov  dword[string_CompileError_ArgCount+38+4*1],'oria'
	 mov  word[string_CompileError_ArgCount+38+4*2],'l'
	 jmp  CompileError_ArgCount
CompileError_Sqrt:
	 mov  dword[string_CompileError_ArgCount+38],'Sqrt'
	 mov  byte[string_CompileError_ArgCount+38+4*1],0
	 jmp  CompileError_ArgCount
CompileError_Greater:
	 mov  dword[string_CompileError_ArgCount+38],'Grea'
	 mov  dword[string_CompileError_ArgCount+38+4*1],'ter'
	 jmp  CompileError_ArgCount
CompileError_GreaterEqual:
	 mov  dword[string_CompileError_ArgCount+38],'Grea'
	 mov  dword[string_CompileError_ArgCount+38+4*1],'terE'
	 mov  dword[string_CompileError_ArgCount+38+4*2],'qual'
	 mov  byte[string_CompileError_ArgCount+38+4*3],0
	 jmp  CompileError_ArgCount
CompileError_Less:
	 mov  dword[string_CompileError_ArgCount+38],'Less'
	 mov  byte[string_CompileError_ArgCount+38+4*1],0
	 jmp  CompileError_ArgCount
CompileError_LessEqual:
	 mov  dword[string_CompileError_ArgCount+38],'Less'
	 mov  dword[string_CompileError_ArgCount+38+4*1],'Equa'
	 mov  word[string_CompileError_ArgCount+38+4*2],'l'
	 jmp  CompileError_ArgCount
CompileError_Equal:
	 mov  dword[string_CompileError_ArgCount+38],'Equa'
	 mov  word[string_CompileError_ArgCount+38+4*1],'l'
	 jmp  CompileError_ArgCount
CompileError_While:
	 mov  dword[string_CompileError_ArgCount+38],'Whil'
	 mov  word[string_CompileError_ArgCount+38+4*1],'e'
	 jmp  CompileError_ArgCount
CompileError_Loop:
	 mov  dword[string_CompileError_ArgCount+38],'Loop'
	 mov  byte[string_CompileError_ArgCount+38+4*1],0
	 jmp  CompileError_ArgCount
CompileError_If:
	 mov  dword[string_CompileError_ArgCount+38],'If'
	 jmp  CompileError_ArgCount
CompileError_ArgCount:
	 mov  esi,string_CompileError_ArgCount
	 jmp  InputErrorCommon
SyntaxError_Uknown:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],eax
	 jmp  SyntaxError_Unexpected
SyntaxError_Number:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'numb'
	 mov  dword[string_SyntaxError_Unexpected+25+4*1],'er'
	 jmp  SyntaxError_Unexpected
SyntaxError_Var:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'vari'
	 mov  dword[string_SyntaxError_Unexpected+25+4*1],'able'
	 mov  byte[string_SyntaxError_Unexpected+25+4*2],0
	 jmp  SyntaxError_Unexpected
SyntaxError_UnitaryCmpdExpr:
	 SyntaxError_UnitaryCmp:
	 SyntaxError_UnitarySet:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'unar'
	 mov  dword[string_SyntaxError_Unexpected+25+4*1],'y op'
	 mov  dword[string_SyntaxError_Unexpected+25+4*2],'erat'
	 mov  dword[string_SyntaxError_Unexpected+25+4*3],'or'
	 jmp  SyntaxError_Unexpected
SyntaxError_Infix:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'infi'
	 mov  dword[string_SyntaxError_Unexpected+25+4*1],'x op'
	 mov  dword[string_SyntaxError_Unexpected+25+4*2],'erat'
	 mov  dword[string_SyntaxError_Unexpected+25+4*3],'or'
	 jmp  SyntaxError_Unexpected
SyntaxError_PostFix:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'post'
	 mov  dword[string_SyntaxError_Unexpected+25+4*1],'fix '
	 mov  dword[string_SyntaxError_Unexpected+25+4*2],'oper'
	 mov  dword[string_SyntaxError_Unexpected+25+4*3],'ator'
	 mov  byte[string_SyntaxError_Unexpected+25+4*4],0
	 jmp  SyntaxError_Unexpected
SyntaxError_OpenBra:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'"["'
	 jmp  SyntaxError_Unexpected
SyntaxError_Dot:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'"."'
	 jmp  SyntaxError_Unexpected
SyntaxError_CloseBra:

SyntaxError_Bra:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'"]"'
	 jmp  SyntaxError_Unexpected
SyntaxError_Sep:

SyntaxError_SepBra:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'"|"'
	 jmp  SyntaxError_Unexpected
SyntaxError_OpenPar:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'"("'
	 jmp  SyntaxError_Unexpected
SyntaxError_ClosePar:

SyntaxError_Par:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'")"'
	 jmp  SyntaxError_Unexpected
SyntaxError_OpenList:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'"{"'
	 jmp  SyntaxError_Unexpected
SyntaxError_CloseList:

SyntaxError_List:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'"}"'
	 jmp  SyntaxError_Unexpected
SyntaxError_Comma:

SyntaxError_CommaBra:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'","'
	 jmp  SyntaxError_Unexpected
SyntaxError_Null:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'end '
	 mov  dword[string_SyntaxError_Unexpected+25+4*1],'of i'
	 mov  dword[string_SyntaxError_Unexpected+25+4*2],'nput'
	 mov  byte[string_SyntaxError_Unexpected+25+4*3],0
	 jmp  SyntaxError_Unexpected
SyntaxError_UnexpectedNumber:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'numb'
	 mov  dword[string_SyntaxError_Unexpected+25+4*1],'er'
	 jmp  SyntaxError_Unexpected
SyntaxError_UnexpectedSymbol:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'symb'
	 mov  dword[string_SyntaxError_Unexpected+25+4*1],'ol'
	 jmp  SyntaxError_Unexpected
SyntaxError_Letter:
	 mov  dword[string_SyntaxError_Unexpected+25+4*0],'lett'
	 mov  dword[string_SyntaxError_Unexpected+25+4*1],'er'
	 jmp  SyntaxError_Unexpected
SyntaxError_Unexpected:
	 mov  esi,string_SyntaxError_Unexpected
	 jmp  InputErrorCommon
SyntaxError_StringLength:
	 mov  esi,string_SyntaxError_StringLength
	 jmp  SyntaxError
SyntaxError_Digits:
	 mov  esi,string_SyntaxError_Digits
	 jmp  SyntaxError
SyntaxError:

InputErrorCommon:
	 mov  edi,StatusString
	 mov  ecx,80
       repnz  movsb
	 mov  esp,dword[espSave]
      invoke  FlashWindow,dword[hMainWindow],TRUE
	 ret

GetArgHead:
	push  edx   ;  [esi] = head, eax = arg number
	 mov  ecx,dword[esi+4*0]
	 shr  ecx,8
	 jmp  .w2
.w1:
	 sub  esi,8
	 sub  ecx,1
	 mov  edx,dword[esi+4*0]
	 shr  edx,8
	 add  ecx,edx
.w2:
	 cmp  ecx,eax
	  ja  .w1
	 sub  esi,8	 ; [esi] = head of argument number eax
	 pop  edx
	 ret

GetConstAddress: 
	 mov  eax,dword[ConstTable] ; eax: addresse of value
	 jmp  .w2
.w1:  movdqa  xmm2,dqword[eax+16*0]
      movdqa  xmm3,dqword[eax+16*1]
     pcmpeqb  xmm2,xmm0 ; xmm0:xmm1: input value
     pcmpeqb  xmm3,xmm1
	pand  xmm2,xmm3
    pmovmskb  ecx,xmm2
	 cmp  cx,-1
	  je  .found
	 add  eax,32	  ; if ne +32
.w2:
	 cmp  eax,dword[ConstTableTop]
	 jbe  .w1
	 mov  dword[ConstTableTop],eax
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 lea  ecx,[eax+64]
	 sub  ecx,dword[ConstTable]
	 cmp  ecx,dword[ConstTableSizeB]
	 jae  MovConstTable
.found:  ret

MovConstTable:
	push  esi
	push  edi
	push  ebx
	push  ebp
	 mov  ebx,dword[ConstTableSizeB]
	 add  ebx,32*INIT_CONST_TABLE_ENTRIES
	 mov  dword[ConstTableSizeB],ebx
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  ebp,eax
	 mov  esi,dword[ConstTable]
	 mov  edi,ebp
	 lea  ecx,[ebx-32*INIT_CONST_TABLE_ENTRIES]
	 shr  ecx,2
       repnz  movsd
      invoke  VirtualFree,dword[ConstTable],0,MEM_RELEASE
	 mov  edi,ebp
	 sub  edi,dword[ConstTable]
	 mov  esi,dword[Buffer1]
	 jmp  .readconst
.const:
	 mov  eax,dword[esi+4*1]
	 cmp  eax,dword[ConstTable]
	  jb  .nextconst
	 cmp  eax,dword[ConstTableTop]
	  ja  .nextconst
	 add  eax,edi
	 mov  dword[esi+4*1],eax
.nextconst:
	 add  esi,8
.readconst:
	 cmp  dword[esi+4*0],VAR_BENC
	  je  .const
	 cmp  dword[esi+4*0],0
	 jne  .nextconst
	 mov  esi,[DefIndexArgAddressTable]
	 jmp  .readdef
.def:
	push  esi
	 mov  esi,dword[esi+4*2]
	 add  esi,4*2
	 jmp  .defsearchz
.deffoundz:
	 mov  eax,dword[esi+4*1]
	 add  esi,4*2
	test  eax,eax
	  jz  .defsearchdone
	 cmp  eax,dword[ConstTable]
	  jb  .defsearchz
	 cmp  eax,dword[ConstTableTop]
	  ja  .defsearchz
	 add  eax,edi
	 mov  dword[esi-4*1],eax
.defsearchz:
	 cmp  dword[esi+4*0],0
	  je  .deffoundz
	 add  esi,4
	 jmp  .defsearchz
.defsearchdone:
	 pop  esi
	 add  esi,4*4
.readdef:
	 cmp  dword[esi+4*0],0
	 jne  .def
	 mov  eax,dword[ConstTableTop]
	 sub  eax,dword[ConstTable]
	 add  eax,ebp
	 mov  dword[ConstTableTop],eax
	 mov  dword[ConstTable],ebp
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 pop  ebp
	 pop  ebx
	 pop  edi
	 pop  esi
	 ret

GetVarAddress:	   
	 mov  eax,dword[VarStringTable] ; eax: address of var
	pxor  xmm2,xmm2
.l1:
      movdqa  xmm1,dqword[eax]
     pcmpeqb  xmm1,xmm0     ; xmm0: input string 
    pmovmskb  ecx,xmm1
	 cmp  cx,-1
	  je  .found
      movdqa  xmm1,dqword[eax]
     pcmpeqb  xmm1,xmm2
    pmovmskb  ecx,xmm1
	 add  eax,16
	 cmp  cx,-1
	 jne  .l1
.new:
      movdqa  xword[eax],xmm2
      movdqa  xword[eax-16],xmm0
	 sub  eax,16
	 inc  dword[VarTableEntries]
.found:
	 sub  eax,dword[VarStringTable]
	 shr  eax,1
	 lea  eax,[4*eax]
	 lea  ecx,[eax+64]
	 add  eax,dword[VarValueTable]
	 cmp  ecx,dword[VarValueTableSizeB]
	 jae  MovVarTable
	 ret

MovVarTable:
	push  esi
	push  edi
	push  ebx
	push  ebp
	push  eax
	 mov  ebx,dword[VarValueTableSizeB]
	 add  ebx,32*INIT_VAR_TABLE_ENTRIES
	 mov  dword[VarValueTableSizeB],ebx
	 shr  ebx,1
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  ebp,eax
	 mov  esi,dword[VarStringTable]
	 mov  edi,ebp
	 lea  ecx,[ebx-16*INIT_VAR_TABLE_ENTRIES]
	 shr  ecx,2
       repnz  movsd
      invoke  VirtualFree,dword[VarStringTable],0,MEM_RELEASE
	 mov  dword[VarStringTable],ebp
	 shl  ebx,1
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  ebp,eax
	 mov  esi,dword[VarValueTable]
	 mov  edi,ebp
	 lea  ecx,[ebx-32*INIT_VAR_TABLE_ENTRIES]
	 shr  ecx,2
       repnz  movsd
      invoke  VirtualFree,dword[VarValueTable],0,MEM_RELEASE
	 mov  edi,ebp
	 sub  edi,dword[VarValueTable]
	 mov  esi,dword[Buffer1]
	test  esi,esi
	  jz  .defstart
	 jmp  .readvar
.var:
	 mov  eax,dword[esi+4*1]
	 cmp  eax,dword[ConstTable]
	  jb  @f
	 cmp  eax,dword[ConstTableTop]
	 jbe  .nextvar
 @@:	 add  eax,edi
	 mov  dword[esi+4*1],eax
.nextvar:
	 add  esi,8
.readvar:
	 cmp  dword[esi+4*0],VAR_BENC
	  je  .var
	 cmp  dword[esi+4*0],0
	 jne  .nextvar
.defstart:
	 mov  esi,[DefIndexArgAddressTable]
	 jmp  .readdef
.def:
	push  esi
	 mov  esi,dword[esi+4*2]
	 add  esi,4*2
	 jmp  .defsearchz
.deffoundz:
	 mov  eax,dword[esi+4*1]
	 add  esi,4*2
	test  eax,eax
	  jz  .defsearchdone
	 cmp  eax,dword[ConstTable]
	  jb  @f
	 cmp  eax,dword[ConstTableTop]
	 jbe  .defsearchz
 @@:	 add  eax,edi
	 mov  dword[esi-4*1],eax
.defsearchz:
	 cmp  dword[esi+4*0],0
	  je  .deffoundz
	 add  esi,4
	 jmp  .defsearchz
.defsearchdone:
	 pop  esi
	 add  esi,4*4
.readdef:
	 cmp  dword[esi+4*0],0
	 jne  .def
	 mov  dword[VarValueTable],ebp
	 pop  eax
	 add  eax,edi
	 pop  ebp
	 pop  ebx
	 pop  edi
	 pop  esi
	 ret

GetVarString:	
	push  esi
	 cmp  eax,dword[VarValueTable] ; eax: address of var
	  jb  .const
	 mov  edx,dword[ConstTable]  ; - [edi]..: string
	 cmp  edx,dword[VarValueTable]
	  jb  @f
	 cmp  eax,dword[ConstTable]
	 jae  .const
 @@:	 sub  eax,dword[VarValueTable]
	 shr  eax,1
	 add  eax,dword[VarStringTable]
      movdqa  xmm0,dqword[eax]
      movdqu  xword[edi],xmm0
	 mov  ecx,MAX_SYMBOL_LENGTH
	 xor  al,al
       repnz  scasb
	 dec  edi
	test  cl,cl
	 jnz  @f
	 inc  edi
	 dec  ecx
 @@:	 pop  esi
	 ret
.const:
	 mov  esi,eax
	push  dword[OutputBits]
	 mov  dword[OutputBits],20
	call  PrintComplex
	 pop  dword[OutputBits]
	 pop  esi
	 ret

GetFxnAddress:
	 lea  eax,[FxnStringTable]  ; eax: address of function, or NULL if fxn is not in table
	pxor  xmm2,xmm2
.l1:
      movdqa  xmm1,xword[eax]
     pcmpeqb  xmm1,xmm0  ; xmm0: input string
    pmovmskb  ecx,xmm1
	 cmp  cx,-1
	  je  .found
      movdqa  xmm1,xword[eax]
     pcmpeqb  xmm1,xmm2
    pmovmskb  ecx,xmm1
	 add  eax,16
	 cmp  cx,-1
	 jne  .l1
	 xor  eax,eax
	 ret
.found:
	 sub  eax,FxnStringTable
	 shr  eax,2
	 mov  eax,dword[eax+FxnAddressTable]
	 ret

GetFxnString:
	push  ecx      ; ?? [edi]: string
	 lea  ecx,[FxnAddressTable]  ; eax: address of fxn
.l1:
	 cmp  dword[ecx],eax
	  je  .found
	 cmp  dword[ecx],0
	 lea  ecx,[ecx+4]
	 jne  .l1
	 mov  eax,'????'
       stosd
	 ret
.found:
	 sub  ecx,FxnAddressTable
	 lea  ecx,[4*ecx]
	 add  ecx,FxnStringTable
      movdqa  xmm0,xword[ecx]
      movdqu  xword[edi],xmm0
	 mov  ecx,MAX_SYMBOL_LENGTH
	 xor  eax,eax
       repnz  scasb
	 dec  edi
	 pop  ecx
	 ret

GetDefIndex:	       ; a new entry is made if it doesn't exist
	 mov  eax,dword[DefStringTable]  ; eax: address in table
	pxor  xmm2,xmm2
.l1:
      movdqa  xmm1,xword[eax]
     pcmpeqb  xmm1,xmm0   ; xmm0: string
    pmovmskb  ecx,xmm1
	 cmp  cx,-1
	  je  .Found
      movdqa  xmm1,xword[eax]
     pcmpeqb  xmm1,xmm2
    pmovmskb  ecx,xmm1
	 add  eax,16
	 cmp  cx,-1
	 jne  .l1
.New:
      movdqa  xword[eax],xmm2
      movdqa  xword[eax-16],xmm0
	 mov  ecx,eax
	 sub  ecx,dword[DefStringTable]
	 sub  eax,16
	 cmp  ecx,dword[DefStringTableSizeB]
	 jae  MovDefStringTable
.Found:  ret

MovDefStringTable:
	push  esi
	push  edi
	push  ebx
	push  ebp
	push  eax
	 mov  ebx,dword[DefStringTableSizeB]
	 add  ebx,16*INIT_DEF_TABLE_ENTRIES
	 mov  dword[DefStringTableSizeB],ebx
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  ebp,eax
	 mov  esi,dword[DefStringTable]
	 mov  edi,ebp
	 lea  ecx,[ebx-16*INIT_DEF_TABLE_ENTRIES]
	 shr  ecx,2
       repnz movsd
      invoke  VirtualFree,dword[DefStringTable],0,MEM_RELEASE
	 mov  edi,ebp
	 sub  edi,dword[DefStringTable]
	 mov  esi,dword[Buffer1]
	 jmp  .readdef
.def:
	 add  dword[esi+4*1],edi
.nextdef:
	 add  esi,8
.readdef:
	 cmp  byte[esi+4*0],DEF_BENC
	  je  .def
	 cmp  dword[esi+4*0],0
	 jne  .nextdef
	 mov  dword[DefStringTable],ebp
	 mov  esi,dword[DefIndexArgAddressTable]
	 jmp  .readindex
.index:
	 add  dword[esi+4*0],edi
	 add  esi,4*4
.readindex:
	 cmp  dword[esi+4*0],0
	 jne  .index
	 pop  eax
	 add  eax,edi
	 pop  ebp
	 pop  ebx
	 pop  edi
	 pop  esi
	 ret

GetDefStringFromIndex:
      movdqa  xmm0,dqword[eax]	; eax: index of definition
      movdqu  xword[edi],xmm0	  ; [edi]..:string
	 mov  ecx,MAX_SYMBOL_LENGTH
	 xor  al,al
       repnz  scasb
	 dec  edi
	test  cl,cl
	 jnz  @f
	 inc  edi
	 dec  ecx
 @@:	 ret

GetDefStringFromAddress:    ; [edi]..:string
	 sub  eax,8	    ; eax: address of definition code
	 mov  ebx,dword[DefIndexArgAddressTable]
	 sub  ebx,16
.Next:
	 add  ebx,16
	 mov  ecx,dword[ebx]
	test  ecx,ecx
	  jz  .New
	 cmp  eax,dword[ebx+8]
	 jne  .Next
.Found:
	 mov  eax,ecx
	 jmp  GetDefStringFromIndex
.New:
	 mov  eax,'????'
       stosd
	 ret

GetDefIndexFromIndexAndArgCount:
	push  edx  ; edx: size of definition in dwords
	 mov  ebx,dword[DefIndexArgAddressTable]
	 sub  ebx,16
.Next:
	 add  ebx,16
	 mov  edx,dword[ebx+4*0]
	test  edx,edx
	  jz  .New
	 cmp  eax,edx  ; eax: index address of definition
	 jne  .Next
	 cmp  ecx,dword[ebx+4*1]  ; ecx: argc
	 jne  .Next
.Found:
	 pop  edx
	 ret
.New:
	 mov  dword[ebx+4*0],eax
	 mov  dword[ebx+4*1],ecx
      invoke  VirtualAlloc,0,4*DEF_SIZE,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  dword[ebx+4*2],eax
	pxor  xmm0,xmm0
      movdqa  xword[ebx+16],xmm0
	 lea  ecx,[ebx+16]
	 sub  ecx,dword[DefIndexArgAddressTable]
	 cmp  ecx,dword[DefIndexArgAddressTableSizeB]
	 jae  MovDefIndexArgAddressTable
	 pop  edx
	 ret

MovDefIndexArgAddressTable:
	push  esi
	push  edi
	push  ebp
	push  eax
	push  ebx
	 mov  ebx,dword[DefIndexArgAddressTableSizeB]
	 add  ebx,16*INIT_DEF_TABLE_ENTRIES
	 mov  dword[DefIndexArgAddressTableSizeB],ebx
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  ebp,eax
	 mov  esi,dword[DefIndexArgAddressTable]
	 mov  edi,ebp
	 lea  ecx,[ebx-16*INIT_DEF_TABLE_ENTRIES]
	 shr  ecx,2
       repnz  movsd
      invoke  VirtualFree,dword[DefIndexArgAddressTable],0,MEM_RELEASE
	 pop  ebx
	 sub  ebx,dword[DefIndexArgAddressTable]
	 add  ebx,ebp
	 mov  dword[DefIndexArgAddressTable],ebp
	 pop  eax
	 pop  ebp
	 pop  edi
	 pop  esi
	 pop  edx
	 ret

ImpliedTimes:
	 mov  eax,Fxn_Times
	call  FromInfix.entry
	 sub  ebp,8
	 mov  dword[ebp+4*0],eax
	 mov  dword[ebp+4*1],0
	 ret

FromInfix:
	 mov  edx,1
	 cmp  dword[ebp+4],1
	  je  .unitary
	 cmp  ecx,eax	 ; eax: input precedence
	 jbe  .ret
.l1:
	 add  edx,1
	 cmp  ecx,dword[ebp+8]
	 jne  .unitary
	 cmp  dword[ebp+8+4*1],1
	  je  .unitary
	 add  ebp,8
	 jmp  .l1
.unitary:
	 add  ebp,8
	 shl  edx,8
	 mov  dl,FXN_BENC
	 mov  dword[edi+4*0],edx
	 mov  dword[edi+4*1],ecx
	 lea  edi,[edi+8]
	 cmp  ecx,Fxn_CmpdExpr
	  je  .cmpdexpr
	 shr  edx,8
	 sub  edx,1
	 cmp  ecx,Fxn_Set
	  je  .set
.entry:
	 mov  ecx,dword[ebp+4*0]
	 cmp  ecx,127
	  ja  FromInfix
.ret:	 ret
.cmpdexpr:
	 lea  edx,[2*edx-256-FXN_BENC]
	 mov  dword[edi-8+4*0],edx
	 mov  ecx,dword[ebp+4*0]
	 cmp  ecx,127
	  ja  FromInfix
	 ret
.l2:
	 add  edi,8
.set:
	 mov  dword[edi-8+4*0],FXN_BENC+(2 shl 8)
	 mov  dword[edi-8+4*1],ecx
	 sub  edx,1
	  ja  .l2
	 mov  ecx,dword[ebp+4*0]
	 cmp  ecx,127
	  ja  FromInfix
	 ret

ProcessInput:
    invoke  QueryPerformanceCounter,Count1

Parse:
 ; Data
NUMBER	  = 0x00000001
PREFIX	  = 0x00000002
INFIX	  = 0x00000004
POSTFIX   = 0x00000008
LEFT_BRA  = 0x00000010
RIGHT_BRA = 0x00000020
LEFT_PAR  = 0x00000040
RIGHT_PAR = 0x00000080
COMMA	  = 0x00000100
ENDER	  = 0x00000200
LEFT_CUR  = 0x00000400
RIGHT_CUR = 0x00000800
UNARY	  = 0x80000000

DigitsAfterDot equ esp-248
 ; Code
	 mov  dword[espSave],esp
	 lea  ebp,[esp-256]
	 mov  esi,dword[InputString]
	 mov  edi,dword[Buffer1]
	 xor  eax,eax
	 mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+LEFT_CUR+UNARY
	 mov  dword[ebp],eax
.Read:
	 xor  edx,edx
.ReadChar:
       lodsb
	 and  eax,0x07F
	 jmp  dword[DigitStringJTable+4*eax]
.Symbol:
	 cmp  dl,1
	  je  lex_Number
	 cmp  dl,2
	  je  lex_String
	 jmp  dword[SymbolJTable+4*eax]
.Dot:
	 cmp  dl,1
	  jb  SyntaxError_Dot
	  ja  .ContString
	 bts  ebx,30
	  jc  SyntaxError_Dot
	 jmp  .ReadChar
.Letter:
	 cmp  dl,1
	  jb  .StartString
	  je  lex_Number
.ContString:
	 cmp  ecx,16
	 jae  SyntaxError_StringLength
	 mov  byte[Temp1+ecx],al
	 inc  ecx
	 jmp  .ReadChar
.StartString:
	 mov  ecx,1
	 mov  edx,2
	pxor  xmm0,xmm0
      movdqu  xword[Temp1],xmm0
	 mov  byte[Temp1],al
	 jmp  .ReadChar
.Digit:
	 cmp  dl,1
	  ja  .ContString
	 mov  cl,'a'-1
	 sub  cl,al
	 sar  cl,7
	 and  cl,10+'0'-'a'
	 add  al,cl
       movzx  eax,al
	 cmp  dl,1
	  jb  .StartNumber
.ContNumber:
	  bt  ebx,30
	 sbb  dword[DigitsAfterDot],0
	push  edx
	push  ebx
	 sub  eax,'0'
	push  eax
	 mov  ecx,eax
	 mov  eax,dword[Temp1+4*0]
	 mul  dword[InputBase]
	 pop  ecx
	 add  eax,ecx
	 adc  edx,0
	 mov  dword[Temp1+4*0],eax
	 mov  ebx,edx
	 xor  ecx,ecx
	 mov  eax,dword[Temp1+4*1]
	 mul  dword[InputBase]
	 add  ebx,eax
	 adc  ecx,edx
	 mov  dword[Temp1+4*1],ebx
	 xor  ebx,ebx
	 mov  eax,dword[Temp1+4*2]
	 mul  dword[InputBase]
	 add  ecx,eax
	 adc  ebx,edx
	 mov  dword[Temp1+4*2],ecx
	 xor  ecx,ecx
	 mov  eax,dword[Temp1+4*3]
	 mul  dword[InputBase]
	 add  ebx,eax
	 adc  ecx,edx
	 mov  dword[Temp1+4*3],ebx
	 xor  ebx,ebx
	 mov  eax,dword[Temp1+4*4]
	 mul  dword[InputBase]
	 add  ecx,eax
	 adc  ebx,edx
	 mov  dword[Temp1+4*4],ecx
	 xor  ecx,ecx
	 mov  eax,dword[Temp1+4*5]
	 mul  dword[InputBase]
	 add  ebx,eax
	 adc  ecx,edx
	 mov  dword[Temp1+4*5],ebx
	 xor  ebx,ebx
	 mov  eax,dword[Temp1+4*6]
	 mul  dword[InputBase]
	 add  ecx,eax
	 adc  ebx,edx
	 mov  dword[Temp1+4*6],ecx
	 xor  ecx,ecx
	 mov  eax,dword[Temp1+4*7]
	 mul  dword[InputBase]
	 add  ebx,eax
	 adc  ecx,edx
	 mov  dword[Temp1+4*7],ebx
	test  ecx,ecx
	 jnz  SyntaxError_Digits
	 and  ebx,0xC0000000
	 jnz  SyntaxError_Digits
	 pop  ebx
	 pop  edx
	 jmp  .ReadChar
.StartNumber:
	 sub  eax,'0'
	 mov  dword[DigitsAfterDot],0
	 btr  ebx,30
	movd  xmm0,eax
	pxor  xmm1,xmm1
      movdqa  dqword[Temp1+16*0],xmm0
      movdqa  dqword[Temp1+16*1],xmm1
	 mov  edx,1
	 jmp  .ReadChar

lex_Number:
	 sub  esi,1
	  bt  ebx,0+16
	 jnc  @f
	call  ImpliedTimes
 @@:	  bt  ebx,0
	 jnc  SyntaxError_UnexpectedNumber
	 bts  dword[Temp1+4*7],31
	  bt  ebx,30
	 jnc  .Transfer
	push  esi
	 mov  esi,Temp1
	call  CVT2FP
	 pop  esi
	fld1
	fild  dword[InputBase]
       fyl2x
	fild  dword[DigitsAfterDot]
       fmulp  st1,st0
	 fld  st0
     frndint
	fxch  st1
	fsub  st0,st1
       f2xm1
	fld1
       faddp  st1,st0
      fscale
	fstp  st1
	 fld  tword[Temp1]
       fmulp  st1,st0
	fstp  tword[Temp1+10*0]
	fldz
	fstp  tword[Temp1+10*1]
	 mov  byte[Temp1+31],0
.Transfer:
      movdqa  xmm0,dqword[Temp1+16*0]
      movdqa  xmm1,dqword[Temp1+16*1]
	call  GetConstAddress
	 mov  ebx,65537*NUMBER+65537*PREFIX+INFIX+POSTFIX+RIGHT_BRA+RIGHT_PAR+65537*LEFT_PAR+COMMA+ENDER+RIGHT_CUR+65537*LEFT_CUR
	 mov  dword[edi+4*0],VAR_BENC+(0 shl 8)
	 mov  dword[edi+4*1],eax
	 add  edi,8
	 jmp  Parse.Read

lex_String:
	 sub  esi,1
      movdqa  xmm0,dqword[Temp1]

lex_Prefix:
	  bt  ebx,1+16
	 jnc  @f
	call  ImpliedTimes
 @@:	  bt  ebx,1
	 jnc  SyntaxError_UnexpectedSymbol
	 cmp  byte[esi],'['
	 jne  .Var
	 mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+LEFT_CUR+UNARY
	 add  esi,1
	call  GetFxnAddress
	test  eax,eax
	  jz  .Def
.Fxn:
	 mov  edx,CTR_WA_BENC
	 cmp  eax,Fxn_While
	  je  .push
	 mov  edx,CTR_LA_BENC
	 cmp  eax,Fxn_Loop
	 je  .push
	 jmp  .put
.push:
	 mov  dword[edi+4*0],CTR_BENC+(0 shl 8)
	 mov  dword[edi+4*1],edx
	 add  edi,8
.put:
	 sub  ebp,16
	 mov  dword[ebp+0],"["
	 mov  dword[ebp+8],eax
	 mov  dword[ebp+12],1
	 jmp  Parse.Read
.Def:
	call  GetDefIndex
	 jmp  .put
.Var:
	  bt  ebx,0
	 jnc  SyntaxError_Var
	call  GetVarAddress
	 mov  ebx,65537*NUMBER+65537*PREFIX+INFIX+POSTFIX+RIGHT_BRA+RIGHT_PAR+65537*LEFT_PAR+COMMA+ENDER+RIGHT_CUR+65537*LEFT_CUR
	 mov  dword[edi+4*0],VAR_BENC + (0 shl 8)
	 mov  dword[edi+4*1],eax
	 add  edi,8
	 jmp  Parse.Read

lex_cmpdexpr:
	 mov  eax,Fxn_CmpdExpr
	  bt  ebx,31
	  jc  SyntaxError_UnitaryCmpdExpr
	 jmp  lex_Infix

lex_set:
	 mov  eax,Fxn_Set
	  bt  ebx,31
	  jc  SyntaxError_UnitarySet
	 cmp  byte[esi],'='
	 jne  lex_Infix

lex_equal:		
	 inc  esi
	 mov  eax,Fxn_Equal
	 jmp  lex_Infix

lex_plus:
	 mov  eax,Fxn_Plus
	 jmp  lex_Infix

lex_minus:
	 mov  eax,Fxn_Minus
	 jmp  lex_Infix
 
lex_times:
	 mov  eax,Fxn_Times
	 cmp  byte[esi],'^'
	 jne  lex_Infix
	 inc  esi
	 mov  eax,Fxn_Scale
	 jmp  lex_Infix

lex_divide:
	 mov  eax,Fxn_Divide
	 jmp  lex_Infix

lex_power:
	 mov  eax,Fxn_Power
	 jmp  lex_Infix

lex_and:
	 mov  eax,Fxn_And
	 jmp  lex_Infix

lex_tilde:
	 mov  eax,Fxn_Xor
	 jmp  lex_Infix

lex_or:
	 mov  eax,Fxn_Or
	 jmp  lex_Infix

lex_greater:
	 mov  eax,Fxn_Greater
	  bt  ebx,31
	  jc  SyntaxError_UnitaryCmp
	 cmp  byte[esi],'='
	 jne  lex_Infix
	 inc  esi
	 mov  eax,Fxn_GreaterEqual
	 jmp  lex_Infix

lex_less:
	 mov  eax,Fxn_Less
	  bt  ebx,31
	  jc  SyntaxError_UnitaryCmp
	 cmp  byte[esi],'='
	 jne  lex_Infix
	 inc  esi
	 mov  eax,Fxn_LessEqual
	 jmp  lex_Infix

lex_Infix:
	  bt  ebx,2
	 jnc  SyntaxError_Infix
	  bt  ebx,31
	  jc  .Unary
	call  FromInfix.entry
	 mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+LEFT_CUR+UNARY
	 mov  dword[edi+4*0],POP_BENC + (0 shl 8)
	 cmp  eax,Fxn_CmpdExpr
	 jne  @f
	 add  edi,8
 @@:	 sub  ebp,8
	 mov  dword[ebp+4*0],eax
	 mov  dword[ebp+4*1],0
	 jmp  Parse.Read
.Unary:
	 mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+LEFT_BRA+UNARY
	 sub  ebp,8
	 mov  dword[ebp+4*0],eax
	 mov  dword[ebp+4*1],1
	 jmp  Parse.Read

lex_factorial:
	 mov  eax,Fxn_Factorial
	 jmp  lex_Postfix

lex_Postfix:
	  bt  ebx,3
	 jnc  SyntaxError_PostFix
	 mov  ebx,INFIX+POSTFIX+RIGHT_BRA+RIGHT_PAR+COMMA+ENDER+RIGHT_CUR
	 mov  dword[edi+4*0],FXN_BENC + (1 shl 8)
	 mov  dword[edi+4*1],eax
	 add  edi,8
	 jmp  Parse.Read

lex_OpenBra:
	  bt  ebx,4
	 jnc  SyntaxError_OpenBra
	 mov  ebx,PREFIX+INFIX+LEFT_PAR+LEFT_CUR+UNARY
	 sub  ebp,8
	 mov  dword[ebp+4*0],"["
	 jmp  Parse.Read

lex_CloseBra:
	  bt  ebx,5
	 jnc  SyntaxError_CloseBra
	 xor  eax,eax
	call  FromInfix.entry
	 cmp  dword[ebp+4*0],"["
	 jne  SyntaxError_Bra
	 mov  ebx,65537*NUMBER+65537*PREFIX+INFIX+POSTFIX+RIGHT_BRA+RIGHT_PAR+65537*LEFT_PAR+COMMA+ENDER+RIGHT_CUR+65537*LEFT_CUR
	 add  ebp,16
	 mov  eax,dword[ebp-8+4*0] ; eax = fxn
	 mov  ecx,dword[ebp-8+4*1] ; ecx = arg count
	 cmp  eax,Fxn_Equal
	  je  .Equal
	 cmp  eax,Fxn_GreaterEqual
	  je  .GreaterEqual
	 cmp  eax,Fxn_LessEqual
	  je  .LessEqual
	 cmp  eax,Fxn_Greater
	  je  .Greater
	 cmp  eax,Fxn_Less
	  je  .Less
	 cmp  eax,Fxn_While
	  je  .While
	 cmp  eax,Fxn_Loop
	  je  .Loop
	 cmp  eax,Fxn_If
	  je  .If
	 cmp  eax,Fxn_Set
	  je  .Set
	 shl  ecx,8
	 lea  edx,[ecx+DEF_BENC]
	 add  ecx,FXN_BENC
	 cmp  eax,EndFunctions
       cmova  ecx,edx
	 cmp  eax,StartFunctions
       cmovb  ecx,edx
	 mov  dword[edi+4*0],ecx
	 mov  dword[edi+4*1],eax
	 add  edi,8
	 jmp  Parse.Read
.Set:
	 sub  ecx,1
	 jbe  SyntaxError_UnitarySet
 @@:	 mov  dword[edi+4*0],FXN_BENC+(2 shl 8)
	 mov  dword[edi+4*1],eax
	 add  edi,8
	 sub  ecx,1
	  ja  @b
	 jmp  Parse.Read
.Fxn:
	 shl  ecx,8
	 mov  cl,FXN_BENC
	 mov  dword[edi+4*0],ecx
	 mov  dword[edi+4*1],eax
	 add  edi,8
	 jmp  Parse.Read
.Equal:
	 cmp  ecx,1
	 jbe  CompileError_Equal
	 jmp  .Fxn
.Greater:
	 cmp  ecx,1
	 jbe  CompileError_Greater
.Less:
	 cmp  ecx,1
	 jbe  CompileError_Less
	 jmp  .Fxn
.GreaterEqual:
	 cmp  ecx,1
	 jbe  CompileError_GreaterEqual
.LessEqual:
	 cmp  ecx,1
	 jbe  CompileError_LessEqual
	 jmp  .Fxn
.While:
	 mov  dword[edi+4*0],FXN_BENC + (4 shl 8)
	 mov  dword[edi+4*1],eax
	 add  edi,8
	 cmp  ecx,2
	 jne  CompileError_While
	 jmp  Parse.Read
.Loop:
	 mov  dword[edi+4*0],FXN_BENC + (2 shl 8)
	 mov  dword[edi+4*1],eax
	 add  edi,8
	 cmp  ecx,1
	 jne  CompileError_Loop
	 jmp  Parse.Read
.If:
	 cmp  ecx,2
	  jb  CompileError_If
	 cmp  ecx,3
	  ja  CompileError_If
	 lea  ecx,[2*ecx-1]
	 shl  ecx,8
	 mov  cl,FXN_BENC
	 mov  dword[edi+4*0],ecx
	 mov  dword[edi+4*1],eax
	 add  edi,8
	 jmp  Parse.Read

lex_OpenPar:
	  bt  ebx,6+16
	 jnc  @f
	call  ImpliedTimes
 @@:	  bt  ebx,6
	 jnc  SyntaxError_OpenPar
	 mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+LEFT_CUR+UNARY
	 sub  ebp,8
	 mov  dword[ebp+4*0],"("
	 jmp  Parse.Read

lex_ClosePar:
	  bt  ebx,7
	 jnc  SyntaxError_ClosePar
	 xor  eax,eax
	call  FromInfix.entry
	 cmp  dword[ebp],"("
	 jne  SyntaxError_Par
	 mov  ebx,65537*NUMBER+65537*PREFIX+INFIX+POSTFIX+RIGHT_BRA+RIGHT_PAR+65537*LEFT_PAR+COMMA+ENDER+RIGHT_CUR+65537*LEFT_CUR
	 add  ebp,8
	 jmp  Parse.Read

lex_Comma:
	  bt  ebx,8
	 jnc  SyntaxError_Comma
	 xor  eax,eax
	call  FromInfix.entry
	 cmp  dword[ebp],"["
	  je  .OK
	 cmp  dword[ebp],"{"
	  je  .OK
	 jmp  SyntaxError_CommaBra
.OK:
	 mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+LEFT_CUR+UNARY
	 cmp  dword[ebp+8],Fxn_While
	  je  .WB
	 cmp  dword[ebp+8],Fxn_If
	  je  .IAB
	 cmp  dword[ebp+8],Fxn_CmpdExpr
	  je  .pop
	 add  dword[ebp+8+4],1
	 jmp  Parse.Read
.WB:
	 mov  dword[edi+4*0],CTR_BENC + (0 shl 8)
	 mov  dword[edi+4*1],CTR_WB_BENC
	 add  edi,8
	 add  dword[ebp+8+4*1],1
	 jmp  Parse.Read
.IAB:
	 mov  dword[edi+4*0],CTR_BENC + (0 shl 8)
	 mov  eax,dword[ebp+8+4]
	 add  eax,CTR_IA_BENC-1
	 mov  dword[edi+4*1],eax
	 add  edi,8
	 add  dword[ebp+8+4*1],1
	 jmp  Parse.Read
.pop:
	 mov  dword[edi+4*0],POP_BENC + (0 shl 8)
	 add  edi,8
	 add  dword[ebp+8+4*1],1
	 jmp  Parse.Read

lex_Sep:
	  bt  ebx,8
	 jnc  SyntaxError_Sep
	 xor  eax,eax
	call  FromInfix.entry
	 cmp  dword[ebp],"["
	 jne  SyntaxError_SepBra
	 mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+LEFT_CUR+UNARY
	 mov  dword[edi+4*0],SEP_BENC + (0 shl 8)
	 add  edi,8
	 add  dword[ebp+8+4*1],2
	 jmp  Parse.Read

lex_OpenList:
	  bt  ebx,10+16
	 jnc  @f
	call  ImpliedTimes
 @@:	  bt  ebx,10
	 jnc  SyntaxError_OpenList
	 mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+LEFT_CUR+UNARY
	 sub  ebp,16
	 mov  dword[ebp+0],"{"
	 mov  dword[ebp+8],Fxn_List
	 mov  dword[ebp+12],1
	 jmp  Parse.Read

lex_CloseList:
	  bt  ebx,11
	 jnc  SyntaxError_CloseList
	 xor  eax,eax
	call  FromInfix.entry
	 cmp  dword[ebp+4*0],"{"
	 jne  SyntaxError_List
	 mov  ebx,65537*NUMBER+65537*PREFIX+INFIX+POSTFIX+RIGHT_BRA+RIGHT_PAR+65537*LEFT_PAR+COMMA+ENDER+RIGHT_CUR+65537*RIGHT_CUR
	 add  ebp,16
	 mov  eax,dword[ebp-8+4*0] ; eax = fxn
	 mov  ecx,dword[ebp-8+4*1] ; ecx = arg count
	 shl  ecx,8
	 mov  cl,FXN_BENC
	 mov  dword[edi+4*0],ecx
	 mov  dword[edi+4*1],eax
	 add  edi,8
	 jmp  Parse.Read

lex_Null:
	  bt  ebx,9
	 jnc  SyntaxError_Null
	 xor  eax,eax
	call  FromInfix.entry
	 cmp  dword[ebp],0
	 jne  SyntaxError_Null
     
Compute:   ;  [[Buffer1]] = start of input, [edi] = null terminal
	 mov  word[esi-1],0x0a0d
	 inc  esi
	 mov  dword[Caret],esi
	 xor  eax,eax
	push  eax
	 sub  edi,8
	 cmp  dword[edi+4*1],Fxn_CmpdExpr
	 jne  EvaluateFromHead
	 mov  eax,dword[edi+4*0]
	 cmp  al,FXN_BENC
	 jne  EvaluateFromHead
	 shr  eax,8
.Next:
	 mov  esi,edi
	Call  GetArgHead
	push  esi
	 sub  eax,2
	 jae  .Next
	 pop  edi

EvaluateFromHead: ; [edi]: head of epression to be evaluated
		  ; must either be a def. or an expr. that is free from defs.
	 xor  eax,eax
	 mov  edx,ArgLocTableSpace
	 mov  dword[edx],eax
	 mov  dword[ArgCount],eax
	 mov  dword[LocCount],eax
	 mov  esi,edi
	 cmp  dword[esi+4*1],Fxn_Set
	 jne  DoNotMakeDef
	 cmp  byte[esi],FXN_BENC
	 jne  DoNotMakeDef
	 mov  eax,1
	call  GetArgHead
	 cmp  byte[esi],DEF_BENC
	 jne  DoNotMakeDef

MakeDef:
	push  edi
	 mov  edi,esi
	 mov  eax,1
	call  GetArgHead
.l1:
	 cmp  byte[esi+4*0],SEP_BENC
	  je  .l2
	 cmp  byte[esi+4*0],VAR_BENC
	 jne  CompileError_DefArg
	 mov  eax,dword[esi+4*1]
	 mov  dword[edx],eax
	 add  edx,4
	 add  dword[ArgCount],1
	 add  esi,8
	 cmp  esi,edi
	  jb  .l1
	 jmp  .Ready
.l2:
	 add  esi,8
.l3:
	 cmp  byte[esi+4*0],SEP_BENC
	  je  CompileError_DefSep
	 cmp  byte[esi+4*0],VAR_BENC
	 jne  CompileError_DefArg
	 mov  eax,dword[esi+4*1]
	 mov  dword[edx],eax
	 add  edx,4
	 add  dword[LocCount],1
	 add  esi,8
	 cmp  esi,edi
	  jb  .l3
.Ready:
	 mov  dword[edx],0
	 mov  eax,dword[edi+4*1]
	 mov  dword[DefIndex],eax
	 pop  ebx
	 add  esi,8
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	push  edx
	 mov  esi,dword[Buffer3]
	 mov  edx,edi
	 sub  edx,esi
	 sar  edx,2
	 cmp  edx,DEF_SIZE-4
	 jae  CompileError_Def2Large
	 mov  eax,dword[DefIndex]
	 mov  ecx,dword[ArgCount]
	call  GetDefIndexFromIndexAndArgCount
	 mov  edi,dword[ebx+4*2]
	 mov  eax,dword[ArgCount]
       stosd  
	 mov  eax,dword[LocCount]
       stosd
	 mov  ecx,edx
	 rep  movsd
	 pop  edx
	 shl  edx,8
	 mov  dl,RET_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	 mov  edi,dword[Caret]
	 mov  eax,'Defi'
       stosd
	 mov  eax,'niti'
       stosd
	 mov  eax,'on m'
       stosd
	 mov  eax,'ade '
       stosd
	 mov  eax,'for '
       stosd
	 mov  eax,dword[DefIndex]
	call  GetDefStringFromIndex
	 mov  ecx,dword[ArgCount]
	 mov  eax,'['
       stosb
	 mov  ax,0xb7+("," shl 8)
       repnz stosw
	 dec  edi
	 mov  eax,'].'+(0x0a0d shl 16)
       stosd
	 mov  dword[Caret],edi
	 pop  edi
	test  edi,edi
	 jnz  EvaluateFromHead
	 jmp  EvaluateHeadEnd

DoNotMakeDef:
	 mov  esi,edi
	 cmp  byte[esi],FXN_BENC
	 jne  @f
	 cmp  dword[esi+4*1],Fxn_ParametricPlot3D
	  je  MakePlot
	 cmp  dword[esi+4*1],Fxn_ContourPlot3D
	  je  MakeContourPlot
 @@:	 mov  eax,0
	call  GetArgHead
	 lea  esi,[esi+8]
	 lea  ebx,[edi+8]
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	 cmp  esi,EvalStackSpace
	 jne  InternalError
      movdqa  xmm0,xword[string_OutputBase]
	call  GetVarAddress
	 mov  esi,eax
	call  CVT2INT
	 mov  edx,dword[esi+4*0]
	 mov  ecx,INITIAL_OUTPUT_BASE
	 cmp  edx,16
       cmova  edx,ecx
	 cmp  edx,2
       cmovb  edx,ecx
	 mov  dword[OutputBase],edx
	movd  xmm0,edx
	pxor  xmm1,xmm1
      movdqa  xword[esi+16*0],xmm0
      movdqa  xword[esi+16*1],xmm1
	 mov  byte[esi+31],0x80
      movdqa  xmm0,xword[string_OutputBits]
	call  GetVarAddress
	 mov  esi,eax
	call  CVT2INT
	 mov  edx,dword[esi+4*0]
	 mov  ecx,INITIAL_OUTPUT_BITS
	 cmp  edx,70
       cmova  edx,ecx
	 cmp  edx,20
       cmovb  edx,ecx
	 mov  dword[OutputBits],edx
	movd  xmm0,edx
	pxor  xmm1,xmm1
      movdqa  xword[esi+16*0],xmm0
      movdqa  xword[esi+16*1],xmm1
	 mov  byte[esi+31],0x80
	 mov  esi,EvalStackSpace
	 cmp  dword[esp],0
	 jne  .DontPrint
	 mov  edi,dword[Caret]
	 mov  eax,'Out['
       stosd
	 mov  eax,dword[OutputLineNumber]
      movdqa  xmm0,dqword[esi+16*0]
      movdqa  xmm1,dqword[esi+16*1]
	 shl  eax,5
      movdqa  dqword[HistorySpace+eax+16*0],xmm0
      movdqa  dqword[HistorySpace+eax+16*1],xmm1
	 shr  eax,5
	push  dword[OutputBase]
	 mov  dword[OutputBase],10
	call  PrintInteger
	 pop  dword[OutputBase]
	 mov  eax,']: '
       stosd
	 dec  edi
	 mov  eax,dword[OutputLineNumber]
	 add  eax,1
	 cdq
	 mov  ecx,HISTORY_ENTRIES
	 div  ecx
	 mov  dword[OutputLineNumber],edx
	call  PrintComplex
	 mov  eax,0x0a0d
       stosw
	 mov  dword[Caret],edi
.DontPrint:
	 pop  edi
	test  edi,edi
	 jnz  EvaluateFromHead
	 jmp  EvaluateHeadEnd

MakePlot:
	 mov  byte[updatingplotQ],-1
      invoke  VirtualFree,dword[VertexCoorNormalColorTable],0,MEM_RELEASE
	 mov  dword[VertexCoorNormalColorTable],0
      invoke  VirtualFree,dword[ContourVertexCoorNormalColorTable],0,MEM_RELEASE
	 mov  dword[ContourVertexCoorNormalColorTable],0
	 cmp  dword[edi+4*0],FXN_BENC+(3 shl 8)
	 jne  CompileError_Plot_3Arg
	 sub  esp,10*16
	 mov  dword[esp+4*7],edi
	 mov  esi,dword[esp+4*7]
	 mov  eax,2
	call  GetArgHead
	 mov  dword[esp+4*0],esi
	 cmp  dword[esi+4*1],Fxn_List
	 jne  CompileError_Plot_Arg2
	  or  edx,-1
	 cmp  dword[esi+4*0],FXN_BENC+(4 shl 8)
	  je  .no_def_u
	 cmp  dword[esi+4*0],FXN_BENC+(3 shl 8)
	 jne  CompileError_Plot_Arg2
	 xor  edx,edx
.no_def_u:
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,1
	 mov  dword[esp+4*1],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,2
	 mov  dword[esp+4*2],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,3
	 mov  dword[esp+4*3],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,4
	 and  esi,edx
	 mov  dword[esp+4*4],esi
	 mov  esi,dword[esp+4*1]
	 cmp  byte[esi+4*0],VAR_BENC
	 jne  CompileError_Iter_Var
	 mov  eax,dword[esi+4*1]
	 mov  dword[u_var],eax
	 mov  esi,dword[esp+4*1]
	 mov  ebx,dword[esp+4*2]
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2FP
	 fld  tword[esi]
	fstp  tword[u_min]
	 mov  esi,dword[esp+4*2]
	 mov  ebx,dword[esp+4*3]
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2FP
	 fld  tword[esi]
	fstp  tword[u_max]
	 mov  eax,dword[ParametricPlotDefaultDivisions]
	 mov  esi,dword[esp+4*3]
	 mov  ebx,dword[esp+4*4]
	test  ebx,ebx
	  jz  .set_u_div
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2INT
	 mov  eax,dword[esi]
	 mov  ecx,MIN_DIVISIONS
	 cmp  eax,ecx
       cmovl  eax,ecx
	 mov  ecx,MAX_DIVISIONS
	 cmp  eax,ecx
       cmovg  eax,ecx
.set_u_div:
	 mov  dword[u_div],eax
	 mov  esi,dword[esp+4*7]
      mycall  GetArgHead,3
	 mov  dword[esp+4*0],esi
	 cmp  dword[esi+4*1],Fxn_List
	 jne  CompileError_Plot_Arg3
	  or  edx,-1
	 cmp  dword[esi+4*0],FXN_BENC+(4 shl 8)
	  je  .no_def_v
	 cmp  dword[esi+4*0],FXN_BENC+(3 shl 8)
	 jne  CompileError_Plot_Arg3
	 xor  edx,edx
.no_def_v:
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,1
	 mov  dword[esp+4*1],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,2
	 mov  dword[esp+4*2],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,3
	 mov  dword[esp+4*3],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,4
	 and  esi,edx
	 mov  dword[esp+4*4],esi
	 mov  esi,dword[esp+4*1]
	 cmp  byte[esi+4*0],VAR_BENC
	 jne  CompileError_Iter_Var
	 mov  eax,dword[esi+4*1]
	 mov  dword[v_var],eax
	 mov  esi,dword[esp+4*1]
	 mov  ebx,dword[esp+4*2]
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2FP
	 fld  tword[esi]
	fstp  tword[v_min]
	 mov  esi,dword[esp+4*2]
	 mov  ebx,dword[esp+4*3]
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2FP
	 fld  tword[esi]
	fstp  tword[v_max]
	 mov  eax,dword[ParametricPlotDefaultDivisions]
	 mov  esi,dword[esp+4*3]
	 mov  ebx,dword[esp+4*4]
	test  ebx,ebx
	  jz  .set_v_div
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2INT
	 mov  eax,dword[esi]
	 mov  ecx,MIN_DIVISIONS
	 cmp  eax,ecx
       cmovl  eax,ecx
	 mov  ecx,MAX_DIVISIONS
	 cmp  eax,ecx
       cmovg  eax,ecx
.set_v_div:
	 mov  dword[v_div],eax
	 mov  esi,dword[esp+4*7]
      mycall  GetArgHead,1
	 add  esi,8
	 mov  dword[esp+4*6],esi
	 mov  esi,dword[esp+4*7]
      mycall  GetArgHead,0
	 add  esi,8
	 mov  ebx,[esp+4*6]
	 mov  dword[ArgCount],2
	 mov  dword[LocCount],0
	 mov  eax,dword[u_var]
	 mov  ecx,dword[v_var]
	 mov  dword[ArgLocTableSpace+4*0],eax
	 mov  dword[ArgLocTableSpace+4*1],ecx
	 mov  dword[ArgLocTableSpace+4*2],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,3
	 jne  CompileError_Plot_Ret3
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp-8*2]
	movq  xmm1,qword[ebp-8*1]
	movq  xmm2,qword[ebp-8*0]
	movq  qword[edi+4*1],xmm0
	movq  qword[edi+4*3],xmm1
	movq  qword[edi+4*5],xmm2
	 mov  eax,48
	 mul  dword[u_div]
	 mul  dword[v_div]
	 add  eax,100
      invoke  VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  dword[VertexCoorNormalColorTable],eax
	 mov  eax,32
	 mov  ecx,dword[u_div]
	 add  ecx,2
	 mul  ecx
	 mov  ecx,dword[v_div]
	 add  ecx,2
	 mul  ecx
	 add  eax,100
      invoke  VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  dword[VertexTable],eax
	 mov  ebp,eax
	  or  esi,-1
.lv:	  or  edi,-1
.lu:	 mov  dword[esp+4*0],esi
	 mov  dword[esp+4*1],edi
	 fld  tword[v_min]
	 fld  tword[v_max]
	fild  dword[v_div]
	fld1
       fsubp  st1,st0
	fild  dword[esp+4*0]
      fdivrp  st1,st0
	fmul  st1,st0
	fld1
      fsubrp  st1,st0
       fmulp  st2,st0
       faddp  st1,st0
	 fld  tword[u_min]
	 fld  tword[u_max]
	fild  dword[u_div]
	fld1
       fsubp  st1,st0
	fild  dword[esp+4*1]
      fdivrp  st1,st0
	fmul  st1,st0
	fld1
      fsubrp  st1,st0
       fmulp  st2,st0
       faddp  st1,st0
	push  esi
	push  edi
	push  ebp
	 mov  esi,EvalStackSpace
	fstp  tword[esi+32*0+10*0]   ; u
	fldz
	fstp  tword[esi+32*0+10*1]
	 mov  byte[esi+32*0+31],0x00
	fstp  tword[esi+32*1+10*0]   ; v
	fldz
	fstp  tword[esi+32*1+10*1]
	 mov  byte[esi+32*1+31],0x00
	call  Evaluate
	 mov  al,byte[esi+32*0+31]
	  or  al,byte[esi+32*1+31]
	  or  al,byte[esi+32*2+31]
	 cmp  al,0x80
	 jae  .cvt2fp
	 fld  tword[esi+32*0+10*0]   ; x
	 fld  tword[esi+32*1+10*0]   ; y
	 fld  tword[esi+32*2+10*0]   ; z
.cvt2fp_ret:
	 pop  ebp
	 pop  edi
	 pop  esi
	fstp  tword[ebp+10*2]
	fstp  tword[ebp+10*1]
	fstp  tword[ebp+10*0]
	 add  ebp,32
	 add  edi,1
	 cmp  edi,dword[u_div]
	 jbe  .lu
	 add  esi,1
	 cmp  esi,dword[v_div]
	 jbe  .lv

macro fpAddVector c {
	 fld  tword[c+10*2]
	 fld  tword[c+10*1]
	 fld  tword[c+10*0]
       faddp  st3,st0
       faddp  st3,st0
       faddp  st3,st0 }

macro fpSubVector a,b  {
	 fld  tword[b+10*2]
	fsub  st0,st3
	 fld  tword[b+10*1]
	fsub  st0,st3
	 fld  tword[b+10*0]
	fsub  st0,st3
	fstp  tword[a+10*0]
	fstp  tword[a+10*1]
	fstp  tword[a+10*2] }

macro fpNormalizeVector {
	 fld  st2
	fmul  st0,st0
	 fld  st2
	fmul  st0,st0
	 fld  st2
	fmul  st0,st0
       faddp  st1,st0
       faddp  st1,st0
       fsqrt
	fdiv  st1,st0
	fdiv  st2,st0
       fdivp  st3,st0 }

macro fpCrossVector b,c {
	 fld  tword[b+10*0]
	 fld  tword[c+10*1]
       fmulp  st1,st0
	 fld  tword[b+10*1]
	 fld  tword[c+10*0]
       fmulp  st1,st0
       fsubp  st1,st0
	 fld  tword[b+10*2]
	 fld  tword[c+10*0]
       fmulp  st1,st0
	 fld  tword[b+10*0]
	 fld  tword[c+10*2]
       fmulp  st1,st0
       fsubp  st1,st0
	 fld  tword[b+10*1]
	 fld  tword[c+10*2]
       fmulp  st1,st0
	 fld  tword[b+10*2]
	 fld  tword[c+10*1]
       fmulp  st1,st0
       fsubp  st1,st0 }
 point_a equ  esp+10*0
 point_b equ  esp+10*3
 point_c equ  esp+10*6
 point_d equ  esp+10*9
 point_e equ  esp+10*12
	 mov  edi,dword[VertexCoorNormalColorTable]
	 mov  ebp,dword[VertexTable]
	 add  ebp,32
	 mov  eax,32
	 mov  ecx,dword[u_div]
	 add  ecx,2
	 mul  ecx
	 lea  esi,[ebp+1*eax]
	 lea  ebx,[ebp+2*eax]
	 xor  edx,edx
.l2v: 
	 xor  ecx,ecx
.l2u:
	 fld  tword[esi+10*2]
	 fld  tword[esi+10*1]
	 fld  tword[esi+10*0]
	 fld  tword[ebx+10*2]
	fsub  st0,st3
	 fld  tword[ebx+10*1]
	fsub  st0,st3
	 fld  tword[ebx+10*0]
	fsub  st0,st3
	fstp  tword[point_a+10*0]
	fstp  tword[point_a+10*1]
	fstp  tword[point_a+10*2]
	 fld  tword[esi+32+10*2]
	fsub  st0,st3
	 fld  tword[esi+32+10*1]
	fsub  st0,st3
	 fld  tword[esi+32+10*0]
	fsub  st0,st3
	fstp  tword[point_b+10*0]
	fstp  tword[point_b+10*1]
	fstp  tword[point_b+10*2]
	 fld  tword[ebp+10*2]
	fsub  st0,st3
	 fld  tword[ebp+10*1]
	fsub  st0,st3
	 fld  tword[ebp+10*0]
	fsub  st0,st3
	fstp  tword[point_c+10*0]
	fstp  tword[point_c+10*1]
	fstp  tword[point_c+10*2]
	 fld  tword[esi-32+10*2]
	 fld  tword[esi-32+10*1]
	 fld  tword[esi-32+10*0]
      fsubrp  st3,st0
      fsubrp  st3,st0
      fsubrp  st3,st0
	fstp  tword[point_d+10*0]
	fstp  tword[point_d+10*1]
	fstp  tword[point_d+10*2]
 fpCrossVector	point_b,point_a
	fstp  tword[point_e+10*0]
	fstp  tword[point_e+10*1]
	fstp  tword[point_e+10*2]
 fpCrossVector	point_c,point_b
	fstp  tword[point_a+10*0]
	fstp  tword[point_a+10*1]
	fstp  tword[point_a+10*2]
 fpCrossVector	point_d,point_c
	fstp  tword[point_b+10*0]
	fstp  tword[point_b+10*1]
	fstp  tword[point_b+10*2]
 fpCrossVector	point_a,point_d
 fpAddVector  point_a
 fpAddVector  point_b
 fpAddVector  point_e
 fpNormalizeVector
	 fld  tword[esi+10*2]
	 fld  tword[esi+10*1]
	 fld  tword[esi+10*0]
	fstp  dword[edi+4*0]
	fstp  dword[edi+4*1]
	fstp  dword[edi+4*2]
	fstp  dword[edi+4*4]
	fstp  dword[edi+4*5]
	fstp  dword[edi+4*6]
	 add  ebp,32
	 add  esi,32
	 add  ebx,32
	 add  edi,48
	 add  ecx,1
	 cmp  ecx,dword[u_div]
	  jb  .l2u
	 add  ebp,32*2
	 add  esi,32*2
	 add  ebx,32*2
	 add  edx,1
	 cmp  edx,dword[v_div]
	  jb  .l2v
	 add  esp,10*16
      invoke  VirtualFree,dword[VertexTable],0,MEM_RELEASE
	 mov  byte[updatingplotQ],0
	 mov  edi,dword[Caret]
	 mov  eax,'Plot'
       stosd
	 mov  eax,' mad'
       stosd
	 mov  eax,'e.  '
       stosd
	 mov  eax,dword[u_div]
	 mul  dword[v_div]
	push  dword[OutputBase]
	 mov  dword[OutputBase],10
	call  PrintInteger
	 pop  dword[OutputBase]
	 mov  eax,' ver'
       stosd
	 mov  eax,'tici'
       stosd
	 mov  eax,'es'+ (0x0a0d shl 16)
       stosd
	 mov  dword[Caret],edi
	 cmp  dword[hPlotWindow],0
	 mov  byte[plotmode],0
	 jnz  @f
      invoke  CreateThread,NULL,NULL,PlotStart,NULL,NULL,NULL
 @@:  invoke  SendMessage,dword[hPlotWindow],WM_PAINT,0,0
	 pop  edi
	test  edi,edi
	 jnz  EvaluateFromHead
	 jmp  EvaluateHeadEnd
.cvt2fp:
	call  CVT2FP
	 fld  tword[esi]
	 add  esi,32
	call  CVT2FP
	 fld  tword[esi]
	 add  esi,32
	call  CVT2FP
	 fld  tword[esi]
	 sub  esi,2*32
	 jmp  .cvt2fp_ret

MakeContourPlot:
	 mov  byte[updatingplotQ],-1
      invoke  VirtualFree,dword[VertexCoorNormalColorTable],0,MEM_RELEASE
	 mov  dword[VertexCoorNormalColorTable],0
      invoke  VirtualFree,dword[ContourVertexCoorNormalColorTable],0,MEM_RELEASE
	 mov  dword[ContourVertexCoorNormalColorTable],0
	 mov  dword[TriangleCount],0
	 cmp  dword[edi+4*0],FXN_BENC+(4 shl 8)
	 jne  CompileError_ContourPlot_4Arg
	 sub  esp,10*32
	 mov  dword[esp+4*7],edi
	 mov  esi,dword[esp+4*7]
	 mov  eax,2
	call  GetArgHead
	 mov  dword[esp+4*0],esi
	 cmp  dword[esi+4*1],Fxn_List
	 jne  CompileError_ContourPlot_Arg2
	  or  edx,-1
	 cmp  dword[esi+4*0],FXN_BENC+(4 shl 8)
	  je  .no_def_x
	 cmp  dword[esi+4*0],FXN_BENC+(3 shl 8)
	 jne  CompileError_ContourPlot_Arg2
	 xor  edx,edx
.no_def_x:
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,1
	 mov  dword[esp+4*1],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,2
	 mov  dword[esp+4*2],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,3
	 mov  dword[esp+4*3],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,4
	 and  esi,edx
	 mov  dword[esp+4*4],esi
	 mov  esi,dword[esp+4*1]
	 cmp  byte[esi+4*0],VAR_BENC
	 jne  CompileError_Iter_Var
	 mov  eax,dword[esi+4*1]
	 mov  dword[u_var],eax
	 mov  esi,dword[esp+4*1]
	 mov  ebx,dword[esp+4*2]
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2FP
	 fld  tword[esi]
	fstp  tword[u_min]
	 mov  esi,dword[esp+4*2]
	 mov  ebx,dword[esp+4*3]
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2FP
	 fld  tword[esi]
	fstp  tword[u_max]
	 mov  eax,dword[ContourPlotDefaultDivisions]
	 mov  esi,dword[esp+4*3]
	 mov  ebx,dword[esp+4*4]
	test  ebx,ebx
	  jz  .set_x_div
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2INT
	 mov  eax,dword[esi]
	 mov  ecx,MIN_DIVISIONS_CONTOURPLOT
	 cmp  eax,ecx
       cmovl  eax,ecx
	 mov  ecx,MAX_DIVISIONS_CONTOURPLOT
	 cmp  eax,ecx
       cmovg  eax,ecx
.set_x_div:
	 mov  dword[u_div],eax
	 mov  esi,dword[esp+4*7]
      mycall  GetArgHead,3
	 mov  dword[esp+4*0],esi
	 cmp  dword[esi+4*1],Fxn_List
	 jne  CompileError_ContourPlot_Arg3
	  or  edx,-1
	 cmp  dword[esi+4*0],FXN_BENC+(4 shl 8)
	  je  .no_def_y
	 cmp  dword[esi+4*0],FXN_BENC+(3 shl 8)
	 jne  CompileError_ContourPlot_Arg3
	 xor  edx,edx
.no_def_y:
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,1
	 mov  dword[esp+4*1],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,2
	 mov  dword[esp+4*2],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,3
	 mov  dword[esp+4*3],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,4
	 and  esi,edx
	 mov  dword[esp+4*4],esi
	 mov  esi,dword[esp+4*1]
	 cmp  byte[esi+4*0],VAR_BENC
	 jne  CompileError_Iter_Var
	 mov  eax,dword[esi+4*1]
	 mov  dword[v_var],eax
	 mov  esi,dword[esp+4*1]
	 mov  ebx,dword[esp+4*2]
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2FP
	 fld  tword[esi]
	fstp  tword[v_min]
	 mov  esi,dword[esp+4*2]
	 mov  ebx,dword[esp+4*3]
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2FP
	 fld  tword[esi]
	fstp  tword[v_max]
	 mov  eax,dword[ContourPlotDefaultDivisions]
	 mov  esi,dword[esp+4*3]
	 mov  ebx,dword[esp+4*4]
	test  ebx,ebx
	  jz  .set_y_div
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2INT
	 mov  eax,dword[esi]
	 mov  ecx,MIN_DIVISIONS_CONTOURPLOT
	 cmp  eax,ecx
       cmovl  eax,ecx
	 mov  ecx,MAX_DIVISIONS_CONTOURPLOT
	 cmp  eax,ecx
       cmovg  eax,ecx
.set_y_div:
	 mov  dword[v_div],eax
	 mov  esi,dword[esp+4*7]
      mycall  GetArgHead,4
	 mov  dword[esp+4*0],esi
	 cmp  dword[esi+4*1],Fxn_List
	 jne  CompileError_ContourPlot_Arg4
	  or  edx,-1
	 cmp  dword[esi+4*0],FXN_BENC+(4 shl 8)
	  je  .no_def_z
	 cmp  dword[esi+4*0],FXN_BENC+(3 shl 8)
	 jne  CompileError_ContourPlot_Arg4
	 xor  edx,edx
.no_def_z:
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,1
	 mov  dword[esp+4*1],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,2
	 mov  dword[esp+4*2],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,3
	 mov  dword[esp+4*3],esi
	 mov  esi,dword[esp+4*0]
      mycall  GetArgHead,4
	 and  esi,edx
	 mov  dword[esp+4*4],esi
	 mov  esi,dword[esp+4*1]
	 cmp  byte[esi+4*0],VAR_BENC
	 jne  CompileError_Iter_Var
	 mov  eax,dword[esi+4*1]
	 mov  dword[w_var],eax
	 mov  esi,dword[esp+4*1]
	 mov  ebx,dword[esp+4*2]
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2FP
	 fld  tword[esi]
	fstp  tword[w_min]
	 mov  esi,dword[esp+4*2]
	 mov  ebx,dword[esp+4*3]
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2FP
	 fld  tword[esi]
	fstp  tword[w_max]
	 mov  eax,dword[ContourPlotDefaultDivisions]
	 mov  esi,dword[esp+4*3]
	 mov  ebx,dword[esp+4*4]
	test  ebx,ebx
	  jz  .set_z_div
	 add  esi,8
	 add  ebx,8
	 mov  dword[ArgCount],0
	 mov  dword[LocCount],0
	 mov  dword[ArgLocTableSpace],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_MustRet1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
	call  Evaluate
	call  CVT2INT
	 mov  eax,dword[esi]
	 mov  ecx,MIN_DIVISIONS_CONTOURPLOT
	 cmp  eax,ecx
       cmovl  eax,ecx
	 mov  ecx,MAX_DIVISIONS_CONTOURPLOT
	 cmp  eax,ecx
       cmovg  eax,ecx
.set_z_div:
	 mov  dword[w_div],eax
	 mov  esi,dword[esp+4*7]
      mycall  GetArgHead,1
	 add  esi,8
	 mov  dword[esp+4*6],esi
	 mov  esi,dword[esp+4*7]
      mycall  GetArgHead,0
	 add  esi,8
	 mov  ebx,[esp+4*6]
	 mov  dword[ArgCount],3
	 mov  dword[LocCount],0
	 mov  eax,dword[u_var]
	 mov  ecx,dword[v_var]
	 mov  dword[ArgLocTableSpace+4*0],eax
	 mov  dword[ArgLocTableSpace+4*1],ecx
	 mov  eax,dword[w_var]
	 mov  dword[ArgLocTableSpace+4*2],eax
	 mov  dword[ArgLocTableSpace+4*3],0
	call  Compile
	 sub  edx,dword[ArgCount]
	 sub  edx,dword[LocCount]
	 add  edx,1
	 cmp  edx,1
	 jne  CompileError_ContourPlot_Ret1
	 shl  edx,8
	 mov  dl,HLT_ENC
	 mov  dword[edi+4*0],edx
	movq  xmm0,qword[ebp]
	movq  qword[edi+4*1],xmm0
 ; Data
irps coor, u v w  {
	 fld  tword[coor#_max]
	 fld  tword[coor#_min]
       fsubp  st1,st0
	fild  dword[coor#_div]
       fdivp  st1,st0
	fstp  tword[coor#_delta] }

u_div_inc equ esp+10*2-4
      p1 equ  esp+10*2
      p2 equ  esp+10*5
     p12 equ  esp+10*8
      pp equ  esp+10*11
    norm equ  esp+10*14
     fp1 equ  esp+10*17
     fp2 equ  esp+10*18
    fp12 equ  esp+10*19
   delta equ  esp+10*20
    temp equ  esp+10*22
    pt_a equ  esp+4*11
    pt_b equ  esp+4*12
    pt_c equ  esp+4*13
    pt_d equ  esp+4*14
    pt_e equ  esp+4*15
    pt_f equ  esp+4*16
    pt_g equ  esp+4*17
    pt_h equ  esp+4*18
    pt_l equ  esp+4*19
    pt_m equ  esp+4*20
    pt_n equ  esp+4*21
    pt_p equ  esp+4*22
 ; Code
	 mov  eax,32
	 mov  ecx,dword[u_div]
	 add  ecx,1
	 mul  ecx
	 mov  ecx,dword[v_div]
	 add  ecx,1
	 mul  ecx
	 mov  ebx,eax
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  dword[zint],eax
	 shl  ebx,1
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  dword[xyintb],eax
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  dword[xyintt],eax
	 mov  eax,10
	 mov  ecx,dword[u_div]
	 add  ecx,2
	 mul  ecx
	 mov  ecx,dword[v_div]
	 add  ecx,2
	 mul  ecx
	 mov  ebx,eax
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  dword[ftabb],eax
      invoke  VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  dword[ftabt],eax
	 mov  eax,24*3*TWICE_TRIANGLE_MAX_AVERAGE_DENSITY  ; 48*3*TRIANGLE_MAX_AVERAGE_DENSITY
	 mul  dword[u_div]
	 mul  dword[v_div]
	 mul  dword[w_div]
	 mov  ebx,eax
      invoke  VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE
	test  eax,eax
	  jz  EvalError_OutOfMemory
	 mov  dword[ContourVertexCoorNormalColorTable],eax
	 mov  dword[ContourVertexCoorNormalColorTableCaret],eax
	 lea  eax,[eax+ebx-48*3*36-1]
	 mov  dword[ContourVertexCoorNormalColorTableMaxCaret],eax
	  mov  ebx,dword[ftabt]
	  xor  ebp,ebp
	 xor  esi,esi
.loop1_y:
	 xor  edi,edi
.loop1_x:
	 mov  dword[esp+4*0],edi
	 mov  dword[esp+4*1],esi
	 mov  dword[esp+4*2],ebp
	 fld  tword[w_min]
	 fld  tword[w_delta]
       fimul  dword[esp+4*2]
       faddp  st1,st0
	 fld  tword[v_min]
	 fld  tword[v_delta]
       fimul  dword[esp+4*1]
       faddp  st1,st0
	 fld  tword[u_min]
	 fld  tword[u_delta]
       fimul  dword[esp+4*0]
       faddp  st1,st0
	call  Getf
	fstp  tword[ebx]
	 add  ebx,10
	 cmp  edi,dword[u_div]
	 lea  edi,[edi+1]
	 jbe  .loop1_x
	 cmp  esi,dword[v_div]
	 lea  esi,[esi+1]
	 jbe  .loop1_y
	 mov  eax,10
	 mov  ecx,dword[u_div]
	 add  ecx,2
	 mul  ecx
	 mov  dword[u_div_inc],eax
	 mov  ebx,dword[xyintt]
	 mov  edx,dword[ftabt]
	 xor  ebp,ebp
	 xor  esi,esi
.loop2_y:
	 xor  edi,edi
.loop2_x:
	 mov  dword[esp+4*0],edi
	 mov  dword[esp+4*1],esi
	 mov  dword[esp+4*2],ebp
	 fld  tword[w_delta]
	 fld  tword[v_delta]
	 fld  tword[u_delta]
	 fld  tword[w_min]
	fild  dword[esp+4*2]
	fmul  st0,st4
       faddp  st1,st0
	 fld  tword[v_min]
	fild  dword[esp+4*1]
	fmul  st0,st4
       faddp  st1,st0
	 fld  tword[u_min]
	fild  dword[esp+4*0]
	fmul  st0,st4
       faddp  st1,st0
	 fld  st0
	fadd  st0,st4
	fstp  tword[p2+10*0]
	fstp  tword[p1+10*0]
	 fld  st0
       ;fadd  st0,st4
	fstp  tword[p2+10*1]
	fstp  tword[p1+10*1]
	 fld  st0
       ;fadd  st0,st4
	fstp  tword[p2+10*2]
	fstp  tword[p1+10*2]
	fstp  st0
	fstp  st0
	fstp  st0
	 fld  tword[edx]
	fstp  tword[fp1]
	 fld  tword[edx+10]
	fstp  tword[fp2]
	call  Subdivide
      movaps  dqword[ebx+16*0],xmm0
      movaps  dqword[ebx+16*1],xmm1
	 add  ebx,32
	 fld  tword[w_delta]
	 fld  tword[v_delta]
	 fld  tword[u_delta]
	 fld  tword[w_min]
	fild  dword[esp+4*2]
	fmul  st0,st4
       faddp  st1,st0
	 fld  tword[v_min]
	fild  dword[esp+4*1]
	fmul  st0,st4
       faddp  st1,st0
	 fld  tword[u_min]
	fild  dword[esp+4*0]
	fmul  st0,st4
       faddp  st1,st0
	 fld  st0
       ;fadd  st0,st4
	fstp  tword[p2+10*0]
	fstp  tword[p1+10*0]
	 fld  st0
	fadd  st0,st4
	fstp  tword[p2+10*1]
	fstp  tword[p1+10*1]
	 fld  st0
       ;fadd  st0,st4
	fstp  tword[p2+10*2]
	fstp  tword[p1+10*2]
	fstp  st0
	fstp  st0
	fstp  st0
	 mov  eax,edx
	 add  eax,dword[u_div_inc]
	 fld  tword[edx]
	fstp  tword[fp1]
	 fld  tword[eax]
	fstp  tword[fp2]
	call  Subdivide
      movaps  dqword[ebx+16*0],xmm0
      movaps  dqword[ebx+16*1],xmm1
	 add  ebx,32
	 add  edx,10
	 add  edi,1
	 cmp  edi,dword[u_div]
	 jbe  .loop2_x
	 add  edx,10
	 add  esi,1
	 cmp  esi,dword[v_div]
	 jbe  .loop2_y
	 mov  ebp,1
.loop3_z:
	 mov  eax,dword[ftabt]
	 mov  ecx,dword[ftabb]
	 mov  dword[ftabb],eax
	 mov  dword[ftabt],ecx
	 mov  eax,dword[xyintt]
	 mov  ecx,dword[xyintb]
	 mov  dword[xyintb],eax
	 mov  dword[xyintt],ecx
	 mov  ebx,dword[ftabt]
	 xor  esi,esi
.loop31_y:
	 xor  edi,edi
.loop31_x:
	 mov  dword[esp+4*0],edi
	 mov  dword[esp+4*1],esi
	 mov  dword[esp+4*2],ebp
	 fld  tword[w_min]
	 fld  tword[w_delta]
       fimul  dword[esp+4*2]
       faddp  st1,st0
	 fld  tword[v_min]
	 fld  tword[v_delta]
       fimul  dword[esp+4*1]
       faddp  st1,st0
	 fld  tword[u_min]
	 fld  tword[u_delta]
       fimul  dword[esp+4*0]
       faddp  st1,st0
	call  Getf
	fstp  tword[ebx]
	 add  ebx,10
	 cmp  edi,dword[u_div]
	 lea  edi,[edi+1]
	 jbe  .loop31_x
	 cmp  esi,dword[v_div]
	 lea  esi,[esi+1]
	 jbe  .loop31_y
	 mov  eax,10
	 mov  ecx,dword[u_div]
	 add  ecx,2
	 mul  ecx
	 mov  dword[u_div_inc],eax
	 mov  ebx,dword[xyintt]
	 mov  edx,dword[ftabt]
	 xor  esi,esi
.loop32_y:
	 xor  edi,edi
.loop32_x:
	 mov  dword[esp+4*0],edi
	 mov  dword[esp+4*1],esi
	 mov  dword[esp+4*2],ebp
	 fld  tword[w_delta]
	 fld  tword[v_delta]
	 fld  tword[u_delta]
	 fld  tword[w_min]
	fild  dword[esp+4*2]
	fmul  st0,st4
       faddp  st1,st0
	 fld  tword[v_min]
	fild  dword[esp+4*1]
	fmul  st0,st4
       faddp  st1,st0
	 fld  tword[u_min]
	fild  dword[esp+4*0]
	fmul  st0,st4
       faddp  st1,st0
	 fld  st0
	fadd  st0,st4
	fstp  tword[p2+10*0]
	fstp  tword[p1+10*0]
	 fld  st0
       ;fadd  st0,st4
	fstp  tword[p2+10*1]
	fstp  tword[p1+10*1]
	 fld  st0
       ;fadd  st0,st4
	fstp  tword[p2+10*2]
	fstp  tword[p1+10*2]
	fstp  st0
	fstp  st0
	fstp  st0
	 fld  tword[edx]
	fstp  tword[fp1]
	 fld  tword[edx+10]
	fstp  tword[fp2]
	call  Subdivide
      movaps  dqword[ebx+16*0],xmm0
      movaps  dqword[ebx+16*1],xmm1
	 add  ebx,32
	 fld  tword[w_delta]
	 fld  tword[v_delta]
	 fld  tword[u_delta]
	 fld  tword[w_min]
	fild  dword[esp+4*2]
	fmul  st0,st4
       faddp  st1,st0
	 fld  tword[v_min]
	fild  dword[esp+4*1]
	fmul  st0,st4
       faddp  st1,st0
	 fld  tword[u_min]
	fild  dword[esp+4*0]
	fmul  st0,st4
       faddp  st1,st0
	 fld  st0
       ;fadd  st0,st4
	fstp  tword[p2+10*0]
	fstp  tword[p1+10*0]
	 fld  st0
	fadd  st0,st4
	fstp  tword[p2+10*1]
	fstp  tword[p1+10*1]
	 fld  st0
       ;fadd  st0,st4
	fstp  tword[p2+10*2]
	fstp  tword[p1+10*2]
	fstp  st0
	fstp  st0
	fstp  st0
	 mov  eax,edx
	 add  eax,dword[u_div_inc]
	 fld  tword[edx]
	fstp  tword[fp1]
	 fld  tword[eax]
	fstp  tword[fp2]
	call  Subdivide
      movaps  dqword[ebx+16*0],xmm0
      movaps  dqword[ebx+16*1],xmm1
	 add  ebx,32
	 add  edx,10
	 add  edi,1
	 cmp  edi,dword[u_div]
	 jbe  .loop32_x
	 add  edx,10
	 add  esi,1
	 cmp  esi,dword[v_div]
	 jbe  .loop32_y
	 mov  ebx,dword[zint]
	 mov  edx,dword[ftabt]
	 xor  esi,esi
.loop33_y:
	 xor  edi,edi
.loop33_x:
	 mov  dword[esp+4*0],edi
	 mov  dword[esp+4*1],esi
	 mov  dword[esp+4*2],ebp
	 fld  tword[w_delta]
	 fld  tword[v_delta]
	 fld  tword[u_delta]
	 fld  tword[w_min]
	fild  dword[esp+4*2]
	fmul  st0,st4
       faddp  st1,st0
	 fld  tword[v_min]
	fild  dword[esp+4*1]
	fmul  st0,st4
       faddp  st1,st0
	 fld  tword[u_min]
	fild  dword[esp+4*0]
	fmul  st0,st4
       faddp  st1,st0
	 fld  st0
       ;fadd  st0,st4
	fstp  tword[p2+10*0]
	fstp  tword[p1+10*0]
	 fld  st0
       ;fadd  st0,st4
	fstp  tword[p2+10*1]
	fstp  tword[p1+10*1]
	 fld  st0
	fsub  st0,st4
	fstp  tword[p1+10*2]
	fstp  tword[p2+10*2]
	fstp  st0
	fstp  st0
	fstp  st0
	 mov  eax,edx
	 sub  eax,dword[ftabt]
	 add  eax,dword[ftabb]
	 fld  tword[eax]
	fstp  tword[fp1]
	 fld  tword[edx]
	fstp  tword[fp2]
	call  Subdivide
      movaps  dqword[ebx+16*0],xmm0
      movaps  dqword[ebx+16*1],xmm1
	 add  ebx,32
	 add  edx,10
	 add  edi,1
	 cmp  edi,dword[u_div]
	 jbe  .loop33_x
	 add  edx,10
	 add  esi,1
	 cmp  esi,dword[v_div]
	 jbe  .loop33_y
	 mov  ecx,dword[u_div]
	 shl  ecx,5
	 mov  eax,dword[zint]
	 mov  dword[pt_d],eax
	 add  eax,32
	 mov  dword[pt_b],eax
	 add  eax,ecx
	 mov  dword[pt_p],eax
	 add  eax,32
	 mov  dword[pt_m],eax
	 shl  ecx,1
	 mov  eax,dword[xyintb]
	 mov  dword[pt_a],eax
	 add  eax,32
	 mov  dword[pt_h],eax
	 add  eax,32*2
	 mov  dword[pt_e],eax
	 add  eax,ecx
	 sub  eax,32
	 mov  dword[pt_l],eax
	 mov  eax,dword[xyintt]
	 mov  dword[pt_c],eax
	 add  eax,32
	 mov  dword[pt_g],eax
	 add  eax,32*2
	 mov  dword[pt_f],eax
	 add  eax,ecx
	 sub  eax,32
	 mov  dword[pt_n],eax
	 mov  ebx,dword[ContourVertexCoorNormalColorTableCaret]
	 xor  esi,esi
.loop3_y:
	 xor  edi,edi
.loop3_x:
	 xor  ecx,ecx
       xorps  xmm4,xmm4
       xorps  xmm5,xmm5
       xorps  xmm0,xmm0

irps letter, a b c d e f g h l m n p {
	 mov  eax,dword[pt_#letter]
	 cmp  dword[eax+4*3],0
	 jne  @f
	 inc  ecx
       addps  xmm0,dqword[const_f4v4_1]
       addps  xmm4,dqword[eax+4*0]
       addps  xmm5,dqword[eax+4*4]
 @@:	      }
	test  ecx,ecx
	  jz  .loop3_done
       divps  xmm4,xmm0
       divps  xmm5,xmm0
	 mov  eax,dword[pt_p]
	 cmp  dword[eax+4*3],0
	 jne  .no_p
      movaps  xmm0,dqword[eax+4*0]
      movaps  xmm1,dqword[eax+4*4]
irps letter, g n h l m d {
	 mov  ecx,dword[pt_#letter]
	 cmp  dword[ecx+4*3],0
	 jne  @f
      movaps  xmm2,dqword[ecx+4*0]
      movaps  xmm3,dqword[ecx+4*4]
      movaps  dqword[ebx+48*0+4*0],xmm0
      movaps  dqword[ebx+48*0+4*4],xmm1
      movaps  dqword[ebx+48*1+4*0],xmm2
      movaps  dqword[ebx+48*1+4*4],xmm3
      movaps  dqword[ebx+48*2+4*0],xmm4
      movaps  dqword[ebx+48*2+4*4],xmm5
	 add  ebx,48*3
	 add  dword[TriangleCount],3
 @@:	      }
.no_p:
	 mov  eax,dword[pt_l]
	 cmp  dword[eax+4*3],0
	 jne  .no_l
      movaps  xmm0,dqword[eax+4*0]
      movaps  xmm1,dqword[eax+4*4]
irps letter, h m e n a {
	 mov  ecx,dword[pt_#letter]
	 cmp  dword[ecx+4*3],0
	 jne  @f
      movaps  xmm2,dqword[ecx+4*0]
      movaps  xmm3,dqword[ecx+4*4]
      movaps  dqword[ebx+48*0+4*0],xmm0
      movaps  dqword[ebx+48*0+4*4],xmm1
      movaps  dqword[ebx+48*1+4*0],xmm2
      movaps  dqword[ebx+48*1+4*4],xmm3
      movaps  dqword[ebx+48*2+4*0],xmm4
      movaps  dqword[ebx+48*2+4*4],xmm5
	 add  ebx,48*3
	 add  dword[TriangleCount],3
 @@:	      }
.no_l:
	 mov  eax,dword[pt_n]
	 cmp  dword[eax+4*3],0
	 jne  .no_n
      movaps  xmm0,dqword[eax+4*0]
      movaps  xmm1,dqword[eax+4*4]
irps letter, g f m c {
	 mov  ecx,dword[pt_#letter]
	 cmp  dword[ecx+4*3],0
	 jne  @f
      movaps  xmm2,dqword[ecx+4*0]
      movaps  xmm3,dqword[ecx+4*4]
      movaps  dqword[ebx+48*0+4*0],xmm0
      movaps  dqword[ebx+48*0+4*4],xmm1
      movaps  dqword[ebx+48*1+4*0],xmm2
      movaps  dqword[ebx+48*1+4*4],xmm3
      movaps  dqword[ebx+48*2+4*0],xmm4
      movaps  dqword[ebx+48*2+4*4],xmm5
	 add  ebx,48*3
	 add  dword[TriangleCount],3
 @@:	      }
.no_n:
	 mov  eax,dword[pt_m]
	 cmp  dword[eax+4*3],0
	 jne  .no_m
      movaps  xmm0,dqword[eax+4*0]
      movaps  xmm1,dqword[eax+4*4]
irps letter, f e b {
	 mov  ecx,dword[pt_#letter]
	 cmp  dword[ecx+4*3],0
	 jne  @f
      movaps  xmm2,dqword[ecx+4*0]
      movaps  xmm3,dqword[ecx+4*4]
      movaps  dqword[ebx+48*0+4*0],xmm0
      movaps  dqword[ebx+48*0+4*4],xmm1
      movaps  dqword[ebx+48*1+4*0],xmm2
      movaps  dqword[ebx+48*1+4*4],xmm3
      movaps  dqword[ebx+48*2+4*0],xmm4
      movaps  dqword[ebx+48*2+4*4],xmm5
	 add  ebx,48*3
	 add  dword[TriangleCount],3
 @@:	      }
.no_m:
	 mov  eax,dword[pt_e]
	 cmp  dword[eax+4*3],0
	 jne  .no_e
      movaps  xmm0,dqword[eax+4*0]
      movaps  xmm1,dqword[eax+4*4]
irps letter, b a f h {
	 mov  ecx,dword[pt_#letter]
	 cmp  dword[ecx+4*3],0
	 jne  @f
      movaps  xmm2,dqword[ecx+4*0]
      movaps  xmm3,dqword[ecx+4*4]
      movaps  dqword[ebx+48*0+4*0],xmm0
      movaps  dqword[ebx+48*0+4*4],xmm1
      movaps  dqword[ebx+48*1+4*0],xmm2
      movaps  dqword[ebx+48*1+4*4],xmm3
      movaps  dqword[ebx+48*2+4*0],xmm4
      movaps  dqword[ebx+48*2+4*4],xmm5
	 add  ebx,48*3
	 add  dword[TriangleCount],3
 @@:	      }
.no_e:
	 mov  eax,dword[pt_f]
	 cmp  dword[eax+4*3],0
	 jne  .no_f
      movaps  xmm0,dqword[eax+4*0]
      movaps  xmm1,dqword[eax+4*4]
irps letter, c b g {
	 mov  ecx,dword[pt_#letter]
	 cmp  dword[ecx+4*3],0
	 jne  @f
      movaps  xmm2,dqword[ecx+4*0]
      movaps  xmm3,dqword[ecx+4*4]
      movaps  dqword[ebx+48*0+4*0],xmm0
      movaps  dqword[ebx+48*0+4*4],xmm1
      movaps  dqword[ebx+48*1+4*0],xmm2
      movaps  dqword[ebx+48*1+4*4],xmm3
      movaps  dqword[ebx+48*2+4*0],xmm4
      movaps  dqword[ebx+48*2+4*4],xmm5
	 add  ebx,48*3
	 add  dword[TriangleCount],3
@@:	      }
.no_f:
	 mov  eax,dword[pt_g]
	 cmp  dword[eax+4*3],0
	 jne  .no_g
      movaps  xmm0,dqword[eax+4*0]
      movaps  xmm1,dqword[eax+4*4]
irps letter, c d h {
	 mov  ecx,dword[pt_#letter]
	 cmp  dword[ecx+4*3],0
	 jne  @f
      movaps  xmm2,dqword[ecx+4*0]
      movaps  xmm3,dqword[ecx+4*4]
      movaps  dqword[ebx+48*0+4*0],xmm0
      movaps  dqword[ebx+48*0+4*4],xmm1
      movaps  dqword[ebx+48*1+4*0],xmm2
      movaps  dqword[ebx+48*1+4*4],xmm3
      movaps  dqword[ebx+48*2+4*0],xmm4
      movaps  dqword[ebx+48*2+4*4],xmm5
	 add  ebx,48*3
	 add  dword[TriangleCount],3
 @@:	      }
.no_g:
	 mov  eax,dword[pt_h]
	 cmp  dword[eax+4*3],0
	 jne  .no_h
      movaps  xmm0,dqword[eax+4*0]
      movaps  xmm1,dqword[eax+4*4]
irps letter, d a {
	 mov  ecx,dword[pt_#letter]
	 cmp  dword[ecx+4*3],0
	 jne  @f
      movaps  xmm2,dqword[ecx+4*0]
      movaps  xmm3,dqword[ecx+4*4]
      movaps  dqword[ebx+48*0+4*0],xmm0
      movaps  dqword[ebx+48*0+4*4],xmm1
      movaps  dqword[ebx+48*1+4*0],xmm2
      movaps  dqword[ebx+48*1+4*4],xmm3
      movaps  dqword[ebx+48*2+4*0],xmm4
      movaps  dqword[ebx+48*2+4*4],xmm5
	 add  ebx,48*3
	 add  dword[TriangleCount],3
 @@:	      }
.no_h:
	 mov  eax,dword[pt_b]
	 cmp  dword[eax+4*3],0
	 jne  .no_b
      movaps  xmm0,dqword[eax+4*0]
      movaps  xmm1,dqword[eax+4*4]
irps letter, c a d {
	 mov  ecx,dword[pt_#letter]
	 cmp  dword[ecx+4*3],0
	 jne  @f
      movaps  xmm2,dqword[ecx+4*0]
      movaps  xmm3,dqword[ecx+4*4]
      movaps  dqword[ebx+48*0+4*0],xmm0
      movaps  dqword[ebx+48*0+4*4],xmm1
      movaps  dqword[ebx+48*1+4*0],xmm2
      movaps  dqword[ebx+48*1+4*4],xmm3
      movaps  dqword[ebx+48*2+4*0],xmm4
      movaps  dqword[ebx+48*2+4*4],xmm5
	 add  ebx,48*3
	 add  dword[TriangleCount],3
 @@:	      }
.no_b:
	 mov  eax,dword[pt_c]
	 cmp  dword[eax+4*3],0
	 jne  .no_c
      movaps  xmm0,dqword[eax+4*0]
      movaps  xmm1,dqword[eax+4*4]
irps letter, d a {
	 mov  ecx,dword[pt_#letter]
	 cmp  dword[ecx+4*3],0
	 jne  @f
      movaps  xmm2,dqword[ecx+4*0]
      movaps  xmm3,dqword[ecx+4*4]
      movaps  dqword[ebx+48*0+4*0],xmm0
      movaps  dqword[ebx+48*0+4*4],xmm1
      movaps  dqword[ebx+48*1+4*0],xmm2
      movaps  dqword[ebx+48*1+4*4],xmm3
      movaps  dqword[ebx+48*2+4*0],xmm4
      movaps  dqword[ebx+48*2+4*4],xmm5
	 add  ebx,48*3
	 add  dword[TriangleCount],3
 @@:	      }
.no_c:
	 mov  eax,dword[pt_d]
	 cmp  dword[eax+4*3],0
	 jne  .no_d
      movaps  xmm0,dqword[eax+4*0]
      movaps  xmm1,dqword[eax+4*4]
irps letter, a {
	 mov  ecx,dword[pt_#letter]
	 cmp  dword[ecx+4*3],0
	 jne  @f
      movaps  xmm2,dqword[ecx+4*0]
      movaps  xmm3,dqword[ecx+4*4]
      movaps  dqword[ebx+48*0+4*0],xmm0
      movaps  dqword[ebx+48*0+4*4],xmm1
      movaps  dqword[ebx+48*1+4*0],xmm2
      movaps  dqword[ebx+48*1+4*4],xmm3
      movaps  dqword[ebx+48*2+4*0],xmm4
      movaps  dqword[ebx+48*2+4*4],xmm5
	 add  ebx,48*3
	 add  dword[TriangleCount],3
 @@:	      }
.no_d:
.loop3_done:
	 add  dword[pt_a],32*2
	 add  dword[pt_b],32*1
	 add  dword[pt_c],32*2
	 add  dword[pt_d],32*1
	 add  dword[pt_e],32*2
	 add  dword[pt_f],32*2
	 add  dword[pt_g],32*2
	 add  dword[pt_h],32*2
	 add  dword[pt_l],32*2
	 add  dword[pt_m],32*1
	 add  dword[pt_n],32*2
	 add  dword[pt_p],32*1
	 cmp  ebx,dword[ContourVertexCoorNormalColorTableMaxCaret]
	 jae  .break
	 add  edi,1
	 cmp  edi,dword[u_div]
	  jb  .loop3_x
	 add  dword[pt_a],32*2
	 add  dword[pt_b],32*1
	 add  dword[pt_c],32*2
	 add  dword[pt_d],32*1
	 add  dword[pt_e],32*2
	 add  dword[pt_f],32*2
	 add  dword[pt_g],32*2
	 add  dword[pt_h],32*2
	 add  dword[pt_l],32*2
	 add  dword[pt_m],32*1
	 add  dword[pt_n],32*2
	 add  dword[pt_p],32*1
	 add  esi,1
	 cmp  esi,dword[v_div]
	  jb  .loop3_y
	 mov  dword[ContourVertexCoorNormalColorTableCaret],ebx
	 add  ebp,1
	 cmp  ebp,dword[w_div]
	 jbe  .loop3_z
.break:
      invoke  VirtualFree,dword[ftabt],0,MEM_RELEASE
      invoke  VirtualFree,dword[ftabb],0,MEM_RELEASE
      invoke  VirtualFree,dword[xyintt],0,MEM_RELEASE
      invoke  VirtualFree,dword[xyintb],0,MEM_RELEASE
      invoke  VirtualFree,dword[zint],0,MEM_RELEASE
	 mov  byte[updatingplotQ],0
	 add  esp,10*32
	 mov  edi,dword[Caret]
	 mov  eax,'Plot'
       stosd
	 mov  eax,' mad'
       stosd
	 mov  eax,'e.  '
       stosd
	 xor  edx,edx
	 lea  ecx,[edx+3]
	 mov  eax,[TriangleCount]
	 div  ecx
	call  PrintInteger
	 mov  eax,' tri'
       stosd
	 mov  eax,'angl'
       stosd
	 mov  eax,'es'+(0x0a0d shl 16)
       stosd
	 mov  dword[Caret],edi
	 cmp  dword[hPlotWindow],0
	 mov  byte[plotmode],1
	 jnz  @f
      invoke  CreateThread,NULL,NULL,PlotStart,NULL,NULL,NULL
 @@:  invoke  SendMessage,dword[hPlotWindow],WM_PAINT,0,0
	 pop  edi
	test  edi,edi
	 jnz  EvaluateFromHead
	 jmp  EvaluateHeadEnd

EvaluateHeadEnd:
	 mov  edi,dword[Caret]
	 mov  ax,0x0a0d
       stosw
	 mov  dword[Caret],edi
	 sub  dword[Caret],1
      invoke  QueryPerformanceCounter,Count2
	fild  qword[Count2]
	fild  qword[Count1]  ;cycles
       fsubp  st1,st0
	fild  qword[Frequency] ;cycles/sec
       fdivp  st1,st0
	 mov  edi,StatusString
	 mov  eax,'Time'
       stosd
	 mov  eax,': '
       stosw
	push  dword[OutputBits]
	 mov  dword[OutputBits],15
	push  dword[OutputBase]
	 mov  dword[OutputBase],10
	call  PrintFloat
	 pop  dword[OutputBase]
	 pop  dword[OutputBits]
	 mov  eax,' sec'
       stosd
	 mov  byte[edi],0
	 ret

Getf:
	push  esi
	push  edi
	push  ebp
	push  ebx
	 mov  esi,EvalStackSpace
	fstp  tword[esi+32*0+10*0]  ; x
	fldz
	fstp  tword[esi+32*0+10*1]
	 mov  byte[esi+32*0+31],0x00
	fstp  tword[esi+32*1+10*0]  ; y
	fldz
	fstp  tword[esi+32*1+10*1]
	 mov  byte[esi+32*1+31],0x00
	fstp  tword[esi+32*2+10*0]  ; z
	fldz
	fstp  tword[esi+32*2+10*1]
	 mov  byte[esi+32*2+31],0x00
	call  Evaluate
	 cmp  byte[esi+32*0+31],0x80
	 jae  .cvt2fp
	 fld  tword[esi+32*0+10*0]  ; f[x,y,z]
	 pop  ebx
	 pop  ebp
	 pop  edi
	 pop  esi
	 ret
.cvt2fp:
	call  CVT2FP
	 fld  tword[esi+32*0+10*0]  ; f[x,y,z]
	 pop  ebx
	 pop  ebp
	 pop  edi
	 pop  esi
	 ret

Subdivide:
	 mov  ax,word[4+fp1+8]
	 mov  cx,word[4+fp2+8]
	test  ax,ax
	  jz  .throw_p1
	test  cx,cx
	  jz  .throw_p2
	 xor  ax,cx
	  js  .found
      movaps  xmm0,dqword[const_True]
	 ret
.found: ; int3
	 fld  tword[4+p2+10*2]
	 fld  tword[4+p2+10*1]
	 fld  tword[4+p2+10*0]
	 fld  tword[4+fp1]
	fmul  st3,st0
	fmul  st2,st0
	fmul  st1,st0
	 fld  tword[4+p1+10*2]
	 fld  tword[4+p1+10*1]
	 fld  tword[4+p1+10*0]
	 fld  tword[4+fp2]
	fmul  st3,st0
	fmul  st2,st0
	fmul  st1,st0
       fsubp  st4,st0
       fsubp  st4,st0
       fsubp  st4,st0
       fsubp  st4,st0
	fdiv  st3,st0
	fdiv  st2,st0
       fdivp  st1,st0
	fstp  tword[4+pp+10*0]
	fstp  tword[4+pp+10*1]
	fstp  tword[4+pp+10*2]
.return:
	fldz
	 fld  tword[4+pp+10*2]
	 fld  tword[4+pp+10*1]
	 fld  tword[4+pp+10*0]
	fstp  dword[4+temp+4*0]
	fstp  dword[4+temp+4*1]
	fstp  dword[4+temp+4*2]
	fstp  dword[4+temp+4*3]
	 fld  tword[u_max]
	 fld  tword[u_min]
       fsubp  st1,st0
	fild  dword[u_div]
       fdivp  st1,st0
	fstp  tword[4+delta]
	 fld  tword[4+pp+10*2]
	 fld  tword[4+pp+10*1]
	 fld  tword[4+pp+10*0]
	 fld  tword[4+delta]
       faddp  st1,st0
	call  Getf
	fstp  tword[4+norm+10*0]
	 fld  tword[4+pp+10*2]
	 fld  tword[4+pp+10*1]
	 fld  tword[4+pp+10*0]
	 fld  tword[4+delta]
       fsubp  st1,st0
	call  Getf
	 fld  tword[4+norm+10*0]
      fsubrp  st1,st0
	 fld  tword[4+delta]
       fdivp  st1,st0
	fstp  tword[4+norm+10*0]
	 fld  tword[v_max]
	 fld  tword[v_min]
       fsubp  st1,st0
	fild  dword[v_div]
       fdivp  st1,st0
	fstp  tword[4+delta]
	 fld  tword[4+pp+10*2]
	 fld  tword[4+pp+10*1]
	 fld  tword[4+pp+10*0]
	 fld  tword[4+delta]
       faddp  st2,st0
	call  Getf
	fstp  tword[4+norm+10*1]
	 fld  tword[4+pp+10*2]
	 fld  tword[4+pp+10*1]
	 fld  tword[4+pp+10*0]
	 fld  tword[4+delta]
       fsubp  st2,st0
	call  Getf
	 fld  tword[4+norm+10*1]
      fsubrp  st1,st0
	 fld  tword[4+delta]
       fdivp  st1,st0
	fstp  tword[4+norm+10*1]
	 fld  tword[w_max]
	 fld  tword[w_min]
       fsubp  st1,st0
	fild  dword[w_div]
       fdivp  st1,st0
	fstp  tword[4+delta]
	 fld  tword[4+pp+10*2]
	 fld  tword[4+pp+10*1]
	 fld  tword[4+pp+10*0]
	 fld  tword[4+delta]
       faddp  st3,st0
	call  Getf
	fstp  tword[4+norm+10*2]
	 fld  tword[4+pp+10*2]
	 fld  tword[4+pp+10*1]
	 fld  tword[4+pp+10*0]
	 fld  tword[4+delta]
       fsubp  st3,st0
	call  Getf
	 fld  tword[4+norm+10*2]
      fsubrp  st1,st0
	 fld  tword[4+delta]
       fdivp  st1,st0
	fstp  tword[4+norm+10*2]
	fldz
	 fld  tword[4+norm+10*2]
	 fld  tword[4+norm+10*1]
	 fld  tword[4+norm+10*0]
       fpNormalizeVector
	fstp  dword[4+temp+4*4]
	fstp  dword[4+temp+4*5]
	fstp  dword[4+temp+4*6]
	fstp  dword[4+temp+4*7]
      movups  xmm0,dqword[4+temp+16*0]
      movups  xmm1,dqword[4+temp+16*1]
	 ret
.throw_p1:
	 fld  tword[4+p1+10*2]
	 fld  tword[4+p1+10*1]
	 fld  tword[4+p1+10*0]
	fstp  tword[4+pp+10*0]
	fstp  tword[4+pp+10*1]
	fstp  tword[4+pp+10*2]
	 jmp  .return
.throw_p2:
	 fld  tword[4+p2+10*2]
	 fld  tword[4+p2+10*1]
	 fld  tword[4+p2+10*0]
	fstp  tword[4+pp+10*0]
	fstp  tword[4+pp+10*1]
	fstp  tword[4+pp+10*2]
	 jmp  .return
 ; Data
NOP_BENC  = 1
VAR_BENC  = 2
ARG_BENC  = 3
POP_BENC  = 4
SETA_BENC = 5
SETV_BENC = 6
CTR_BENC  = 7
CTR_LA_BENC = 1
CTR_WA_BENC = 2
CTR_WB_BENC = 3
CTR_IA_BENC = 4
CTR_IB_BENC = 5
FXN_BENC = 8
DEF_BENC = 9
SEP_BENC = 10
 ; Code
Compile: ; [esi]....[ebx-8]: input
	 ; ArgLocTable: table of arguments and local variables

Compile_VarArg:
	 mov  edi,dword[Buffer2]
	 jmp  .Read
.Next:
	movq  xmm0,qword[esi]
	movq  qword[edi],xmm0
.Inc:
	 add  esi,8
	 add  edi,8
.Read:
	 cmp  esi,ebx
	 jae  .Done  
	 cmp  byte[esi+4*0],VAR_BENC
	 jne  .Next
	 mov  eax,dword[esi+4*1]
	 mov  edx,ArgLocTableSpace
.l1:
	 cmp  eax,dword[edx]
	  je  .Found
	 cmp  dword[edx],0
	 lea  edx,[edx+4]
	 jne  .l1
	 jmp  .Next
.Found:
	 sub  edx,ArgLocTableSpace
	 ror  edx,2
	 mov  dword[edi+4*0],ARG_BENC + (0 shl 8)
	 mov  dword[edi+4*1],edx
	 jmp  .Inc
.Done:
	 mov  dword[edi+4*0],0	; [[Buffer2]] = input with arg and loc

Compile_Set:
	movq  xmm7,qword[NOP_BINST]
	 jmp  .Read
.AssignToArg:
	 por  xmm0,xword[SETA_BINST]
.Replace:
	movq  qword[edi],xmm0
	movq  qword[esi],xmm7
.Read:
	 sub  edi,8
	 cmp  edi,dword[Buffer2]
	 jbe  .Done			  
	 cmp  dword[edi+4*1],Fxn_Set
	 jne  .Read
	 cmp  byte[edi+4*0],FXN_BENC
	 jne  .Read
	 mov  esi,edi
	 mov  eax,1
	call  GetArgHead
	movd  xmm0,dword[esi+4*1]
      pslldq  xmm0,4
	 cmp  byte[esi],ARG_BENC
	  je  .AssignToArg
	 cmp  byte[esi],VAR_BENC
	 jne  CompileError_Set
.AssignToVar:
	 por  xmm0,xword[SETV_BINST]
	 jmp  .Replace
.Done:	   ;  [[Buffer2]] = input with assignments

Compile_MakeCode:
	 mov  esi,dword[Buffer2]
	 mov  edi,dword[Buffer3]
	 mov  ebp,ArgStackSpace-8
	 mov  edx,dword[ArgCount]
	 add  edx,dword[LocCount]
	 sub  edx,1
	 jmp  .Read
.Next:
	 add  esi,8
.Read:
	 mov  eax,dword[esi+4*0]
	 mov  ecx,dword[esi+4*1]
       movzx  ebx,al
	 jmp  dword[@f+4*ebx]
align 4
 @@: dd .END,.NOP,.VAR,.ARG,.POP,.SETA,.SETV,.CTR,.FXN,.DEF,.SEP,InternalError
.END:	 ret
.NOP:	 jmp  .Next
.VAR:
	 add  edx,1
	 add  ebp,8
	 mov  dword[ebp+4*0],0
	 mov  dword[ebp+4*1],ecx
	 jmp  .Next
.ARG:
	 add  edx,1
	 add  ebp,8
	 shl  ecx,5
	 mov  dword[ebp+4*0],-1
	 mov  dword[ebp+4*1],ecx
	 jmp  .Next
.POP:
	 sub  edx,1
	 sub  ebp,8
	 jmp  .Next
.SETA:
	  or  eax,-1
	 shl  ecx,5
	 cmp  eax,dword[ebp+4*0]
	 jne  .outMOV
	 cmp  ecx,dword[ebp+4*1]
	 jne  .outMOV
	 jmp  .Next
.SETV:
	 xor  eax,eax
	 cmp  eax,dword[ebp+4*0]
	 jne  .outMOV
	 cmp  ecx,dword[ebp+4*1]
	 jne  .outMOV
	 jmp  .Next
.outMOV:
	movq  xmm0,qword[ebp+4*0]
	 mov  dword[edi+4*0],MOV_ENC
	movq  qword[edi+4*1],xmm0
	 mov  dword[edi+4*3],eax
	 mov  dword[edi+4*4],ecx
	 add  edi,4*5
	 jmp  .Next
.FXN:
	 cmp  ecx,Fxn_CmpdExpr
	  je  .Next
	 cmp  ecx,Fxn_List
	  je  .Next
	 cmp  ecx,Fxn_ParametricPlot3D
	  je  CompileError_Plot
	 cmp  ecx,Fxn_ContourPlot3D
	  je  CompileError_ContourPlot
	 cmp  ecx,Fxn_Loop
	  je  .L2
	 cmp  ecx,Fxn_While
	  je  .W4
	 cmp  ecx,Fxn_If
	  je  .I35
	 cmp  byte[esi+4*2],SETA_BENC
	  je  .FXN_SETA
	 cmp  byte[esi+4*2],SETV_BENC
	  je  .FXN_SETV
.DEFAULT:
	 mov  al,FXN_ENC
       stosd
	 mov  dword[edi],ecx
	 add  edi,4
	 cmp  ecx,Fxn_Power
	  je  .FXN_POWER
	 cmp  eax,FXN_ENC + (2 shl 8)
	  je  @f
	 cmp  ecx,Fxn_Scale
	  je  CompileError_Scale
 @@:	 cmp  eax,FXN_ENC + (1 shl 8)
	  je  .DEFAULT_OK
	 cmp  ecx,Fxn_Cos
	  je  CompileError_Cos
	 cmp  ecx,Fxn_Exp
	  je  CompileError_Exp
	 cmp  ecx,Fxn_Factorial
	  je  CompileError_Factorial
	 cmp  ecx,Fxn_Log
	  je  CompileError_Log
	 cmp  ecx,Fxn_Out
	  je  CompileError_Out
	 cmp  ecx,Fxn_Sin
	  je  CompileError_Sin
	 cmp  ecx,Fxn_Sqrt
	  je  CompileError_Sqrt
	 cmp  ecx,Fxn_Tan
	  je  CompileError_Tan
.DEFAULT_OK:
	 add  edx,1
.DEFAULT_OK2:
	 shr  eax,8
	 sub  edx,eax
	 mov  ebx,edi
	 add  edi,8
 @@:	movq  xmm0,qword[ebp]
	 sub  ebp,8
	movq  qword[edi],xmm0
	 add  edi,8
	 sub  eax,1
	 jnz  @b
	 shl  edx,5
	 mov  dword[ebx+4*0],-1
	 mov  dword[ebx+4*1],edx
	 add  ebp,8
	 mov  dword[ebp+4*0],-1
	 mov  dword[ebp+4*1],edx
	 shr  edx,5
	 jmp  .Next
.FXN_POWER:
	 cmp  eax,FXN_ENC + (2 shl 8)
	 jne  .DEFAULT_OK
	 mov  ebx,dword[ebp+4*0]
	 mov  ecx,dword[ebp+4*1]
	test  ebx,ebx
	 jnz  .DEFAULT_OK
      movdqa  xmm0,dqword[const_False+16*0]
      movdqa  xmm1,dqword[const_False+16*1]
	 cmp  ecx,dword[ConstTable]
	  jb  .DEFAULT_OK
	 cmp  ecx,dword[ConstTableTop]
	  ja  .DEFAULT_OK
     pcmpeqb  xmm1,dqword[ecx+16*1]
    pmovmskb  ebx,xmm1
	 cmp  bx,-1
	 jne  .DEFAULT_OK
     pcmpeqb  xmm0,dqword[ecx+16*0]
    pmovmskb  ebx,xmm0
	 and  ebx,0xFFFE
	 cmp  bx,0xFFFE
	 jne  .DEFAULT_OK
	 cmp  dword[ecx+4*0],2
	  je  .FXN_POWER2
	 cmp  dword[ecx+4*0],3
	  je  .FXN_POWER3
	 cmp  dword[ecx+4*0],4
	  je  .FXN_POWER4
	 jmp  .DEFAULT_OK
.FXN_POWER2:
	 sub  eax,(1 shl 8)
	 sub  ebp,8
	 mov  dword[edi-8+4*0],eax
	 mov  dword[edi-8+4*1],Fxn_Power2
	 jmp  .DEFAULT_OK2
.FXN_POWER3:
	 sub  eax,(1 shl 8)
	 sub  ebp,8
	 mov  dword[edi-8+4*0],eax
	 mov  dword[edi-8+4*1],Fxn_Power3
	 jmp  .DEFAULT_OK2
	.FXN_POWER4:	sub  eax,(1 shl 8)
	 sub  ebp,8
	 mov  dword[edi-8+4*0],eax
	 mov  dword[edi-8+4*1],Fxn_Power4
	 jmp  .DEFAULT_OK2
.FXN_SETV:
	 mov  al,FXN_ENC
       stosd
	 mov  dword[edi],ecx
	 add  edi,4
	 shr  eax,8
	 sub  edx,eax
	 add  edx,1
	 mov  ebx,edi
	 add  edi,8
 @@:	movq  xmm0,qword[ebp]
	 sub  ebp,8
	movq  qword[edi],xmm0
	 add  edi,8
	 sub  eax,1
	 jnz  @b
	 mov  eax,dword[esi+4*3]
	 mov  dword[ebx+4*0],0
	 mov  dword[ebx+4*1],eax
	 add  ebp,8
	 mov  dword[ebp+4*0],0
	 mov  dword[ebp+4*1],eax
	 add  esi,8
	 jmp  .Next
.FXN_SETA:
	 mov  al,FXN_ENC
       stosd
	 mov  dword[edi],ecx
	 add  edi,4
	 shr  eax,8
	 sub  edx,eax
	 add  edx,1
	 mov  ebx,edi
	 add  edi,8
 @@:	movq  xmm0,qword[ebp]
	 sub  ebp,8
	movq  qword[edi],xmm0
	 add  edi,8
	 sub  eax,1
	 jnz  @b
	 mov  eax,dword[esi+4*3]
	 shl  eax,5
	 mov  dword[ebx+4*0],-1
	 mov  dword[ebx+4*1],eax
	 add  ebp,8
	 mov  dword[ebp+4*0],-1
	 mov  dword[ebp+4*1],eax
	 add  esi,8
	 jmp  .Next
.CTR:		
	 cmp  cl,CTR_LA_BENC
	  je  .LA
	 cmp  cl,CTR_WA_BENC
	  je  .WA
	 cmp  cl,CTR_WB_BENC
	  je  .WB
	 cmp  cl,CTR_IA_BENC
	  je  .IA
	 cmp  cl,CTR_IB_BENC
	  je  .IB
	 jmp  InternalError
.LA:
.WA:
	push  edi
	 jmp  .Next
.IB:
	push  edi
	movq  xmm0,qword[ebp]
	 sub  ebp,8
	movq  qword[edi+4*1],xmm0
	 sub  edx,1
	 add  edi,4*5
	 jmp  .Next
.WB:
.IA:	
	push  edi
	movq  xmm0,qword[ebp]
	 sub  ebp,8
	movq  qword[edi+4*1],xmm0
	 sub  edx,1
	 add  edi,4*3
	 jmp  .Next
.L2:
	 pop  eax
	 sub  eax,edi
	 shl  eax,8
	 mov  al,JT_ENC
       stosd
	movq  xmm0,qword[ebp]
	movq  qword[edi],xmm0
	 add  edi,8
	 jmp  .Next
.W4:
	 pop  ecx
	 lea  eax,[edi+4*1]
	 sub  eax,ecx
	 shl  eax,8
	 mov  al,JF_ENC
	 mov  dword[ecx],eax
	 pop  eax
	 sub  eax,edi
	 shl  eax,8
	 mov  al,J_ENC
       stosd
	 jmp  .Next
.I35:
	 cmp  eax,FXN_BENC + (3 shl 8)
	  je  .I3
	 cmp  eax,FXN_BENC + (5 shl 8)
	  je  .I5
	 jmp  InternalError
.I3:
	 pop  ecx
	 mov  eax,edi
	 sub  eax,ecx
	 shl  eax,8
	 mov  al,JF_ENC
	 mov  dword[ecx],eax
	 jmp  .Next
.I5:
	 pop  ecx
	 pop  ebx
	 lea  eax,[ecx+4*5]
	 sub  eax,ebx
	 shl  eax,8
	 mov  al,JF_ENC
	 mov  dword[ebx],eax
	 lea  eax,[edi+4*5]
	 sub  eax,ecx
	 shl  eax,8
	 mov  al,JP_ENC
	 mov  dword[ecx+4*0],eax
	 mov  eax,edx
	 shl  eax,5
	 mov  dword[ecx+4*3],-1
	 mov  dword[ecx+4*4],eax
	movq  xmm0,qword[ebp]
	 mov  dword[edi+4*0],MOV_ENC
	movq  qword[edi+4*1],xmm0
	 mov  dword[edi+4*3],-1
	 mov  dword[edi+4*4],eax
	 mov  dword[ebp+4*0],-1
	 mov  dword[ebp+4*1],eax
	 add  edi,4*5
	 jmp  .Next
.DEF:	
	 mov  al,DEF_ENC
       stosd
	 shr  eax,8
	xchg  eax,ecx
	call  GetDefIndexFromIndexAndArgCount
	 mov  eax,dword[ebx+8]
	 add  eax,8
       stosd
	 add  edx,1
	 shl  edx,5
	 mov  dword[edi],edx
	 add  edi,4
	 mov  eax,dword[esi]
	 shr  eax,8
 @@:	movq  xmm0,qword[ebp]
	 sub  ebp,8
	movq  qword[edi],xmm0
	 add  edi,8
	 sub  eax,1
	  ja  @b
	 mov  eax,MOV_ENC
       stosd
	 mov  dword[edi+4*0],-1
	 mov  dword[edi+4*1],edx
	 mov  eax,dword[esi]
	 shr  eax,8
	 shl  eax,5
	 sub  edx,eax
	 mov  dword[edi+4*2],-1
	 mov  dword[edi+4*3],edx
	 add  edi,4*4
	 add  ebp,8
	 mov  dword[ebp+4*0],-1
	 mov  dword[ebp+4*1],edx
	 shr  edx,5
	 jmp  .Next
.SEP:
	 jmp  CompileError_DefSep

 ; Data, instruction encodings:
MOV_ENC = 1   ; MOV a,b      dd MOV_ENC + 0, dq b, dq a
FXN_ENC = 2   ; f bn,.,b1,a  dd FXN_ENC + n<<8, dd f, dq a, dq bn,..., dq b1
DEF_ENC = 3   ; f bn,.,b1    dd FXN_ENC + n<<8, dd f, dd stack_depth, dq bn,..., dq b1
RET_ENC = 4   ;              dd RET_ENC, dq value
HLT_ENC = 5   ;
JF_ENC	= 6   ;              dd JF_ENC + off<<8, dq x
JT_ENC	= 7   ;              dd JT_ENC + off<<8, dq x
 J_ENC	= 8   ;              dd  J_ENC + off<<8, dq x, dq s
JP_ENC	= 9   ;
 ; Code
Evaluate:     ; int3
   mov	esi,EvalStackSpace
   mov	edi,dword[Buffer3]
.Current:
	 mov  eax,dword[edi+4*0]
	 mov  ecx,dword[edi+4*1]
	 mov  ebp,eax
       movzx  eax,al
	 sar  ebp,8
	 jmp  dword[@f+4*eax]
align 4
 @@: dd .UND,.MOV,.FXN,.DEF,.RET,.HLT
     dd .JF,.JT,.J,.JP
.MOV:
	 mov  eax,esi
	 and  eax,dword[edi+4*1]
	 add  eax,dword[edi+4*2]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
	 mov  eax,esi
	 and  eax,dword[edi+4*3]
	 add  eax,dword[edi+4*4]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 add  edi,4*5
	 jmp  .Current
.FXN:
	 shl  ebp,3
	 lea  edi,[edi+ebp+16]
	call  ecx
	 jmp  .Current
.DEF:
	 mov  ebx,esi
	push  esi
	 add  esi,dword[edi+4*2]
	 add  edi,4*3
	push  esi
	 cmp  esi,EvalStackSpace+32*(EVAL_STACK_ENTRIES-100)
	 jae  EvalError_Stack
	 shl  ebp,5
	 lea  esi,[esi+ebp-32]
.l1:
	 mov  eax,ebx
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	 sub  esi,32
	 add  edi,8
	 sub  ebp,32
	  ja  .l1
	 pop  esi
	push  edi
	 mov  edi,ecx
	 jmp  .Current
.JT:
	 mov  eax,esi
	 and  eax,dword[edi+4*1]
	 add  eax,dword[edi+4*2]
	 lea  ecx,[edi+ebp]
	 add  edi,4*3
	 cmp  byte[eax],0
      cmovnz  edi,ecx
	 jmp  .Current
.JF:
	 mov  eax,esi
	 and  eax,dword[edi+4*1]
	 add  eax,dword[edi+4*2]
	 lea  ecx,[edi+ebp]
	 add  edi,4*3
	 cmp  byte[eax],0
       cmovz  edi,ecx
	 jmp  .Current
.J:
	 add  edi,ebp
	 jmp  .Current
.JP:
	 mov  eax,esi
	 and  eax,dword[edi+4*1]
	 add  eax,dword[edi+4*2]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
	 mov  eax,esi
	 and  eax,dword[edi+4*3]
	 add  eax,dword[edi+4*4]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 add  edi,ebp
	 jmp  .Current
.RET:
	 mov  eax,esi
	 and  eax,dword[edi+4*1]
	 add  eax,dword[edi+4*2]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
	 cmp  ebp,1
	  je  .RET_1
	 mov  eax,esi
	 and  eax,dword[edi+4*3]
	 add  eax,dword[edi+4*4]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
	 cmp  ebp,2
	  je  .RET_2
	 mov  eax,esi
	 and  eax,dword[edi+4*5]
	 add  eax,dword[edi+4*6]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
	 cmp  ebp,3
	  je  .RET_3
	 mov  eax,esi
	 and  eax,dword[edi+4*7]
	 add  eax,dword[edi+4*8]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
.RET_4:
      movdqa  dqword[esi+16*2],xmm6
      movdqa  dqword[esi+16*3],xmm7
.RET_3:
      movdqa  dqword[esi+16*4],xmm4
      movdqa  dqword[esi+16*5],xmm5
.RET_2:
      movdqa  dqword[esi+16*6],xmm2
      movdqa  dqword[esi+16*7],xmm3
.RET_1:
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	 pop  edi
	 pop  esi
	 jmp  .Current
.HLT:
	 mov  eax,esi
	 and  eax,dword[edi+4*1]
	 add  eax,dword[edi+4*2]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
	 cmp  ebp,1
	  je  .HLT_1
	 mov  eax,esi
	 and  eax,dword[edi+4*3]
	 add  eax,dword[edi+4*4]
      movdqa  xmm2,dqword[eax+16*0]
      movdqa  xmm3,dqword[eax+16*1]
	 cmp  ebp,2
	  je  .HLT_2
	 mov  eax,esi
	 and  eax,dword[edi+4*5]
	 add  eax,dword[edi+4*6]
      movdqa  xmm4,dqword[eax+16*0]
      movdqa  xmm5,dqword[eax+16*1]
	 cmp  ebp,3
	  je  .HLT_3
	 mov  eax,esi
	 and  eax,dword[edi+4*7]
	 add  eax,dword[edi+4*8]
      movdqa  xmm6,dqword[eax+16*0]
      movdqa  xmm7,dqword[eax+16*1]
.HLT_4:
      movdqa  dqword[esi+16*6],xmm6
      movdqa  dqword[esi+16*7],xmm7
.HLT_3:
      movdqa  dqword[esi+16*4],xmm4
      movdqa  dqword[esi+16*5],xmm5
.HLT_2:
      movdqa  dqword[esi+16*2],xmm2
      movdqa  dqword[esi+16*3],xmm3
.HLT_1:
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	 ret
.UND:	 jmp  CompileError_Def

;;;;;;;;;;;;;;;;;;;;;;;;;
;   built-in functions  ;
;
; To add in a prefix function: put the name of it in "FxnStringTable" and "FxnAddressTable"
; To add in an infix function: put a jump for it in "SymbolJTable" and make sure that 
;   "lex_Infix" is hit with address of function in eax 
;    the msb of ebx is 1 if it's used as an unary operator
;    byte[esi] contains the next character to be read
;    precedence is determined by function address
; To add in a postfix function: put a jump for it in "SymbolJTable" and make sure that 
;   "lex_Postfix" is hit with the address of the function in eax
;
; The function address should lie between "StartFunctions" and "EndFunctions"
;
; When the function is called with n arguments,
; (I)
; the pointers to the arguments and return values are arranged as:
;  qword[edi-8*(n+1)] return
;  qword[edi-8*(n)]   argument # n
;  qword[edi-8*(n-1)] argument # n-1
;  ...
;  qword[edi-8*(2)]   argument # 2
;  qword[edi-8*(1)]   argument # 1
;
; (II)
; ebp contains 8*n
;
; (III)
; the first 4 bytes of a pointer are a mask of 0's or 1's indicating if esi (the global stack pointer) 
; is used in the address the last 4 bytes of a pointer are the offset
; For example,
;         sub  edi,8
;         mov  eax,esi
;         and  eax,dword[edi+4*0]
;         add  eax,dword[edi+4*1]
;      movdqa  xmm0,dqword[eax+16*0]
;      movdqa  xmm1,dqword[eax+16*1]     will get the first argument in xmm0:xmm1 (32 bytes)
;
; (IV)
; esi,edi,esp and the floating point control word are preserved by the function

StartFunctions:

InfixFunctions:

Fxn_CmpdExpr:
	int3
Fxn_Or:
	push  edi
	 sub  edi,8
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
	 sub  edi,8
	 sub  ebp,8
	  jz  .l1
.l0:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	 por  xmm0,dqword[eax+16*0]
	 por  xmm1,dqword[eax+16*1]
	 sub  edi,8
	 sub  ebp,8
	 jnz  .l0
.l1:	       ; por  xmm1,dqword[const_False+16*1]
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 pop  edi
	 ret

Fxn_Xor:
	push  edi
	 sub  edi,8
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  xmm0,dqword[eax+16*0]
     movdqa  xmm1,dqword[eax+16*1]
	 sub  edi,8
	 sub  ebp,8
	  jz  .l1
.l0:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	pxor  xmm0,dqword[eax+16*0]
	pxor  xmm1,dqword[eax+16*1]
	 sub  edi,8
	 sub  ebp,8
	 jnz  .l0
	 por  xmm1,dqword[const_False+16*1]
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 pop  edi
	 ret
.l1:
	pxor  xmm0,dqword[const_True+16*0]
	pxor  xmm1,dqword[const_True+16*1]
	 por  xmm1,dqword[const_False+16*1]
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 pop  edi
	 ret

Fxn_And:
	push  edi
	 sub  edi,8
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
	 sub  edi,8
	 sub  ebp,8
	  jz  .l1
.l0:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	pand  xmm0,dqword[eax+16*0]
	pand  xmm1,dqword[eax+16*1]
	 sub  edi,8
	 sub  ebp,8
	 jnz  .l0
.l1:
	;por  xmm1,dqword[const_False+16*1]
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 pop  edi
	 ret
; EQ  LT  GT
Fxn_Equal:
      movdqa  xmm0,xword[const_True+16*0]
      movdqa  xmm1,xword[const_True+16*1]
      movdqa  xmm2,xword[const_False+16*0]
      movdqa  xmm3,xword[const_False+16*1]
      movdqa  xmm4,xword[const_False+16*0]
      movdqa  xmm5,xword[const_False+16*1]
	 jmp  Compare
Fxn_Greater:
      movdqa  xmm0,xword[const_False+16*0]
      movdqa  xmm1,xword[const_False+16*1]
      movdqa  xmm2,xword[const_False+16*0]
      movdqa  xmm3,xword[const_False+16*1]
      movdqa  xmm4,xword[const_True+16*0]
      movdqa  xmm5,xword[const_True+16*1]
	 jmp  Compare
Fxn_GreaterEqual:
      movdqa  xmm0,xword[const_True+16*0]
      movdqa  xmm1,xword[const_True+16*1]
      movdqa  xmm2,xword[const_False+16*0]
      movdqa  xmm3,xword[const_False+16*1]
      movdqa  xmm4,xword[const_True+16*0]
      movdqa  xmm5,xword[const_True+16*1]
	 jmp  Compare
Fxn_LessEqual:
      movdqa  xmm0,xword[const_True+16*0]
      movdqa  xmm1,xword[const_True+16*1]
      movdqa  xmm2,xword[const_True+16*0]
      movdqa  xmm3,xword[const_True+16*1]
      movdqa  xmm4,xword[const_False+16*0]
      movdqa  xmm5,xword[const_False+16*1]
	 jmp  Compare
Fxn_Less:
      movdqa  xmm0,xword[const_False+16*0]
      movdqa  xmm1,xword[const_False+16*1]
      movdqa  xmm2,xword[const_True+16*0]
      movdqa  xmm3,xword[const_True+16*1]
      movdqa  xmm4,xword[const_False+16*0]
      movdqa  xmm5,xword[const_False+16*1]
	 jmp  Compare

Compare:
	push  edi
	 sub  edi,16
	 sub  ebp,8
      movdqa  xmm6,xword[const_True+16*0]
      movdqa  xmm7,xword[const_True+16*1]
.Next:
	 mov  eax,esi
	 and  eax,dword[edi+4*2]
	 add  eax,dword[edi+4*3]
	 mov  ebx,esi
	 and  ebx,dword[edi+4*0]
	 add  ebx,dword[edi+4*1]
	 cmp  byte[eax+31],0x80
	 jae  .INT_
	 cmp  byte[ebx+31],0x80
	 jae  .FP_INT
.FP_FP: 
	 fld  tword[ebx]
	 fld  tword[eax]
      fcomip  st1
	fstp  st0
	  jp  .FAIL
	  ja  .GT
	  jb  .LT
	  je  .EQU
	int3
.INT_:
	 cmp  byte[ebx+31],0x80
	  jb  .INT_FP
.INT_INT:
	 mov  ecx,dword[eax+4*7]
	 shl  ecx,1
	 mov  edx,dword[ebx+4*7]
	 shl  edx,1
	 cmp  ecx,edx
	  jg  .GT
	  jl  .LT
	 mov  ecx,dword[eax+4*6]
	 cmp  ecx,dword[ebx+4*6]
	  jg  .GT
	  jl  .LT
	 mov  ecx,dword[eax+4*5]
	 cmp  ecx,dword[ebx+4*5]
	  jg  .GT
	  jl  .LT
	 mov  ecx,dword[eax+4*4]
	 cmp  ecx,dword[ebx+4*4]
	  jg  .GT
	  jl  .LT
	 mov  ecx,dword[eax+4*3]
	 cmp  ecx,dword[ebx+4*3]
	  jg  .GT
	  jl  .LT
	 mov  ecx,dword[eax+4*2]
	 cmp  ecx,dword[ebx+4*2]
	  jg  .GT
	  jl  .LT
	 mov  ecx,dword[eax+4*1]
	 cmp  ecx,dword[ebx+4*1]
	  jg  .GT
	  jl  .LT
	 mov  ecx,dword[eax+4*0]
	 cmp  ecx,dword[ebx+4*0]
	  jg  .GT
	  jl  .LT
.EQU:
	pand  xmm6,xmm0
	pand  xmm7,xmm1
	 sub  edi,8
	 sub  ebp,8
	  ja  .Next
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  xword[eax+16*0],xmm6
      movdqa  xword[eax+16*1],xmm7
	 pop  edi
	 ret
.LT:
	pand  xmm6,xmm2
	pand  xmm7,xmm3
	 sub  edi,8
	 sub  ebp,8
	  ja  .Next
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  xword[eax+16*0],xmm6
      movdqa  xword[eax+16*1],xmm7
	 pop  edi
	 ret
.GT:
	pand  xmm6,xmm4
	pand  xmm7,xmm5
	 sub  edi,8
	 sub  ebp,8
	  ja  .Next
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  xword[eax+16*0],xmm6
      movdqa  xword[eax+16*1],xmm7
	 pop  edi
	 ret
.FAIL:
	pand  xmm6,dqword[const_False+16*0]
	pand  xmm7,dqword[const_False+16*1]
	 sub  edi,8
	 sub  ebp,8
	  ja  .Next
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  xword[eax+16*0],xmm6
      movdqa  xword[eax+16*1],xmm7
	 pop  edi
	 ret
.FP_INT:
	push  esi
	 mov  esi,Temp1
	 mov  ecx,dword[ebx+4*0]
	 mov  edx,dword[ebx+4*1]
	 mov  dword[esi+4*0],ecx
	 mov  dword[esi+4*1],edx
	 mov  ecx,dword[ebx+4*2]
	 mov  edx,dword[ebx+4*3]
	 mov  dword[esi+4*2],ecx
	 mov  dword[esi+4*3],edx
	 mov  ecx,dword[ebx+4*4]
	 mov  edx,dword[ebx+4*5]
	 mov  dword[esi+4*4],ecx
	 mov  dword[esi+4*5],edx
	 mov  ecx,dword[ebx+4*6]
	 mov  edx,dword[ebx+4*7]
	 mov  dword[esi+4*6],ecx
	 mov  dword[esi+4*7],edx
	call  CVT2FP
	 fld  tword[esi]
	 fld  tword[eax]
	 pop  esi
      fcomip  st1
	fstp  st0
	  jp  .FAIL
	  ja  .GT
	  jb  .LT
	  je  .EQU
	int3
.INT_FP:
	push  esi
	 mov  esi,Temp1
	 mov  ecx,dword[eax+4*0]
	 mov  edx,dword[eax+4*1]
	 mov  dword[esi+4*0],ecx
	 mov  dword[esi+4*1],edx
	 mov  ecx,dword[eax+4*2]
	 mov  edx,dword[eax+4*3]
	 mov  dword[esi+4*2],ecx
	 mov  dword[esi+4*3],edx
	 mov  ecx,dword[eax+4*4]
	 mov  edx,dword[eax+4*5]
	 mov  dword[esi+4*4],ecx
	 mov  dword[esi+4*5],edx
	 mov  ecx,dword[eax+4*6]
	 mov  edx,dword[eax+4*7]
	 mov  dword[esi+4*6],ecx
	 mov  dword[esi+4*7],edx
	call  CVT2FP
	 fld  tword[ebx]
	 fld  tword[esi]
	 pop  esi
      fcomip  st1
	fstp  st0
	  jp  .FAIL
	  ja  .GT
	  jb  .LT
	  je  .EQU

Fxn_Set:
	int3
Fxn_Plus:
	push  edi
	 sub  edi,8
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	 cmp  byte[eax+31],0x80
	 jae  .i0
.f0:
	 fld  tword[eax+10*0]
	 fld  tword[eax+10*1]
	 sub  edi,8
	 sub  ebp,8
	 jna  .f2
.f1:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	 cmp  byte[eax+31],0x80
	 jae  .c1
.r1:
	 fld  tword[eax+10*0]
	 fld  tword[eax+10*1]
       faddp  st2,st0
       faddp  st2,st0
	 sub  edi,8
	 sub  ebp,8
	  ja  .f1
.f2:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	fstp  tword[eax+10*1]
	fstp  tword[eax+10*0]
	 mov  byte[eax+31],0
	 pop  edi
	 ret
.i0:
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
      movdqa  dqword[Temp1+16*0],xmm0
      movdqa  dqword[Temp1+16*1],xmm1
	 sub  edi,8
	 sub  ebp,8
	 jna  .i2
.i1:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	 cmp  byte[eax+31],0x80
	  jb  .c2
	 mov  ebx,dword[eax+4*0]
	 mov  ecx,dword[eax+4*1]
	 add  dword[Temp1+4*0],ebx
	 adc  dword[Temp1+4*1],ecx
	 mov  ebx,dword[eax+4*2]
	 mov  ecx,dword[eax+4*3]
	 adc  dword[Temp1+4*2],ebx
	 adc  dword[Temp1+4*3],ecx
	 mov  ebx,dword[eax+4*4]
	 mov  ecx,dword[eax+4*5]
	 adc  dword[Temp1+4*4],ebx
	 adc  dword[Temp1+4*5],ecx
	 mov  ebx,dword[eax+4*6]
	 mov  ecx,dword[eax+4*7]
	 adc  dword[Temp1+4*6],ebx
	 adc  dword[Temp1+4*7],ecx
	 sub  edi,8
	 sub  ebp,8
	  ja  .i1
.i2:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  xmm0,dqword[Temp1+16*0]
      movdqa  xmm1,dqword[Temp1+16*1]
	 por  xmm1,dqword[const_False+16*1]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 pop  edi
	 ret
.c1:
	push  esi
	 mov  esi,Temp1
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 mov  eax,esi
	 pop  esi
	 jmp  .r1
.c2:
	push  esi
	 mov  esi,Temp1
	  or  byte[esi+31],0x80
	call  CVT2FP
	 fld  tword[Temp1+10*0]
	fldz
	 pop  esi
	 jmp  .r1

Fxn_Minus:
	push  edi
	 sub  edi,8
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	 cmp  byte[eax+31],0x80
	 jae  .i0
.f0:
	 fld  tword[eax+10*0]
	 fld  tword[eax+10*1]
	 sub  edi,8
	 sub  ebp,8
	 jna  .f3
.f1:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	 cmp  byte[eax+31],0x80
	 jae  .c1
.r1:
	 fld  tword[eax+10*0]
	 fld  tword[eax+10*1]
       fsubp  st2,st0
       fsubp  st2,st0
	 sub  edi,8
	 sub  ebp,8
	  ja  .f1
.f2:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	fstp  tword[eax+10*1]
	fstp  tword[eax+10*0]
	 mov  byte[eax+31],0
	 pop  edi
	 ret
.f3:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	fchs
	fstp  tword[eax+10*1]
	fchs
	fstp  tword[eax+10*0]
	 mov  byte[eax+31],0
	 pop  edi
	 ret
.i0:
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
      movdqa  dqword[Temp1+16*0],xmm0
      movdqa  dqword[Temp1+16*1],xmm1
	 sub  edi,8
	 sub  ebp,8
	 jna  .i3
.i1:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	 cmp  byte[eax+31],0x80
	  jb  .c2
	 mov  ebx,dword[eax+4*0]
	 mov  ecx,dword[eax+4*1]
	 sub  dword[Temp1+4*0],ebx
	 sbb  dword[Temp1+4*1],ecx
	 mov  ebx,dword[eax+4*2]
	 mov  ecx,dword[eax+4*3]
	 sbb  dword[Temp1+4*2],ebx
	 sbb  dword[Temp1+4*3],ecx
	 mov  ebx,dword[eax+4*4]
	 mov  ecx,dword[eax+4*5]
	 sbb  dword[Temp1+4*4],ebx
	 sbb  dword[Temp1+4*5],ecx
	 mov  ebx,dword[eax+4*6]
	 mov  ecx,dword[eax+4*7]
	 sbb  dword[Temp1+4*6],ebx
	 sbb  dword[Temp1+4*7],ecx
	 sub  edi,8
	 sub  ebp,8
	  ja  .i1
.i2:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  xmm0,dqword[Temp1+16*0]
      movdqa  xmm1,dqword[Temp1+16*1]
	 por  xmm1,dqword[const_False+16*1]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 pop  edi
	 ret
.i3:
	 xor  edx,edx
	 mov  ebx,edx
	 mov  ecx,edx
	 sub  ebx,dword[eax+4*0]
	 sbb  ecx,dword[eax+4*1]
	 mov  dword[Temp1+4*0],ebx
	 mov  dword[Temp1+4*1],ecx
	 mov  ebx,edx
	 mov  ecx,edx
	 sbb  ebx,dword[eax+4*2]
	 sbb  ecx,dword[eax+4*3]
	 mov  dword[Temp1+4*2],ebx
	 mov  dword[Temp1+4*3],ecx
	 mov  ebx,edx
	 mov  ecx,edx
	 sbb  ebx,dword[eax+4*4]
	 sbb  ecx,dword[eax+4*5]
	 mov  dword[Temp1+4*4],ebx
	 mov  dword[Temp1+4*5],ecx
	 mov  ebx,edx
	 mov  ecx,edx
	 sbb  ebx,dword[eax+4*6]
	 sbb  ecx,dword[eax+4*7]
	 mov  dword[Temp1+4*6],ebx
	 bts  ecx,31
	 mov  dword[Temp1+4*7],ecx
      movdqa  xmm0,dqword[Temp1+16*0]
      movdqa  xmm1,dqword[Temp1+16*1]
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 pop  edi
	 ret
.c1:
	push  esi
	 mov  esi,Temp1
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 mov  eax,esi
	 pop  esi
	 jmp  .r1
.c2:
	push  esi
	 mov  esi,Temp1
	  or  byte[esi+31],0x80
	call  CVT2FP
	 fld  tword[Temp1+10*0]
	fldz
	 pop  esi
	 jmp  .r1

Fxn_Times:
	push  edi
	 sub  edi,8
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	 cmp  byte[eax+31],0x80
	 jae  .i0
.f0:
	 fld  tword[eax+10*0]
	 fld  tword[eax+10*1]
	 sub  edi,8
	 sub  ebp,8
	 jna  .f2
.f1:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	 cmp  byte[eax+31],0x80
	 jae  .c1
.r1:
	 fld  tword[eax+10*0]
	 fld  tword[eax+10*1]
	 fld  st3
	fmul  st0,st2
	 fld  st3
	fmul  st0,st2
       fsubp  st1,st0
	fstp  st5
       fmulp  st3,st0
       fmulp  st1,st0
       faddp  st1,st0
	 sub  edi,8
	 sub  ebp,8
	  ja  .f1
.f2:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	fstp  tword[eax+10*1]
	fstp  tword[eax+10*0]
	 mov  byte[eax+31],0
	 pop  edi
	 ret
.i0:
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
      movdqa  dqword[Temp1+16*0],xmm0
      movdqa  dqword[Temp1+16*1],xmm1
	 sub  edi,8
	 sub  ebp,8
	 jna  .i2
.i1:
	 mov  ebx,esi
	 and  ebx,dword[edi+4*0]
	 add  ebx,dword[edi+4*1]
	 cmp  byte[ebx+31],0x80
	  jb  .c2
	 mov  eax,Temp1
	 mov  ecx,eax
	call  IMUL2
	 sub  edi,8
	 sub  ebp,8
	  ja  .i1
.i2:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  xmm0,dqword[Temp1+16*0]
      movdqa  xmm1,dqword[Temp1+16*1]
	 por  xmm1,dqword[const_False+16*1]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 pop  edi
	 ret
.c1:
	push  esi
	 mov  esi,Temp1
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 mov  eax,esi
	 pop  esi
	 jmp  .r1
.c2:
	push  esi
	 mov  esi,Temp1
	  or  byte[esi+31],0x80
	call  CVT2FP
	 fld  tword[esi+10*0]
	fldz
	 mov  eax,ebx
	 pop  esi
	 jmp  .r1

Fxn_Divide:
	push  edi
	 sub  edi,8
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	 cmp  byte[eax+31],0x80
	 jae  .c0
.f0:
	 fld  tword[eax+10*0]
	 fld  tword[eax+10*1]
	 sub  edi,8
	 sub  ebp,8
	 jna  .f3
.f1:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	 cmp  byte[eax+31],0x80
	 jae  .c1
.r1:
	 fld  tword[eax+10*0]
	 fld  tword[eax+10*1]
	 fld  st1
	fmul  st0,st0
	 fld  st1
	fmul  st0,st0
       faddp  st1,st0
	 fld  st4
	fmul  st0,st3
	 fld  st4
	fmul  st0,st3
       faddp  st1,st0
	fdiv  st0,st1
	fxch  st5
       fmulp  st2,st0
	fxch  st3
       fmulp  st2,st0
       fsubp  st1,st0
      fdivrp  st1,st0
	 sub  edi,8
	 sub  ebp,8
	  ja  .f1
.f2:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	fstp  tword[eax+10*1]
	fstp  tword[eax+10*0]
	 mov  byte[eax+31],0
	 pop  edi
	 ret
.f3:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	fchs
	 fld  st1
	fmul  st0,st0
	 fld  st1
	fmul  st0,st0
       faddp  st1,st0
	fdiv  st1,st0
       fdivp  st2,st0
	fstp  tword[eax+10*1]
	fstp  tword[eax+10*0]
	 mov  byte[eax+31],0
	 pop  edi
	 ret
.c0:
	call  .cvt
jmp  .f0
.c1:
	call  .cvt
	 jmp  .r1
.cvt:
	push  esi
	 mov  esi,Temp1
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 mov  eax,esi
	 pop  esi
	 ret

Fxn_Power2:
	 mov  ebx,esi
	 and  ebx,dword[edi-8*1+4*0]
	 add  ebx,dword[edi-8*1+4*1]
	 mov  eax,esi
	 and  eax,dword[edi-8*2+4*0]
	 add  eax,dword[edi-8*2+4*1]
	 cmp  byte[ebx+31],0x80
	 jae  .c1
	 fld  tword[ebx+10*0]
	 fld  tword[ebx+10*1]
	 fld  st1
	fmul  st0,st0
	 fld  st1
	fmul  st0,st0
       fsubp  st1,st0
	fstp  tword[eax+10*0]
       fmulp  st1,st0
	fadd  st0,st0
	fstp  tword[eax+10*1]
	 mov  byte[eax+31],0
	 ret
.c1:
	 mov  ecx,ebx
	call  IMUL2
	 ret

Fxn_Power3:
	 mov  ebx,esi
	 and  ebx,dword[edi-8*1+4*0]
	 add  ebx,dword[edi-8*1+4*1]
	 mov  eax,esi
	 and  eax,dword[edi-8*2+4*0]
	 add  eax,dword[edi-8*2+4*1]
	 cmp  byte[ebx+31],0x80
	 jae  .c1
	 fld  tword[ebx+10*0]
	 fld  tword[ebx+10*1]
	 fld  st1
	fmul  st0,st0
	 fld  st1
	fmul  st0,st0
	 fld  tword[const_f10_3]
	 fld  st0
	fmul  st0,st2
	fxch  st1
	fmul  st0,st3
      fsubrp  st2,st0
       fsubp  st2,st0
       fmulp  st2,st0
       fmulp  st2,st0
	fstp  tword[eax+10*1]
	fstp  tword[eax+10*0]
	 mov  byte[eax+31],0
	 ret
.c1:
	 mov  ecx,ebx
	call  IMUL2
	 mov  ecx,eax
	call  IMUL2
	 ret

Fxn_Power4:
	 mov  ebx,esi
	 and  ebx,dword[edi-8*1+4*0]
	 add  ebx,dword[edi-8*1+4*1]
	 mov  eax,esi
	 and  eax,dword[edi-8*2+4*0]
	 add  eax,dword[edi-8*2+4*1]
	 cmp  byte[ebx+31],0x80
	 jae  .c1
	 fld  tword[ebx+10*0]
	 fld  tword[ebx+10*1]
	 fld  st1
	fmul  st0,st0
	 fld  st1
	fmul  st0,st0
       fsubp  st1,st0
	fstp  st3
       fmulp  st1,st0
	fadd  st0,st0
	 fld  st1
	fmul  st0,st0
	 fld  st1
	fmul  st0,st0
       fsubp  st1,st0
	fstp  tword[eax+10*0]
       fmulp  st1,st0
	fadd  st0,st0
	fstp  tword[eax+10*1]
	 mov  byte[eax+31],0
	 ret
.c1:
	 mov  ecx,ebx
	call  IMUL2
	 mov  ecx,eax
	 mov  ebx,eax
	call  IMUL2
	 ret

Fxn_Power:
	push  edi
	 sub  edi,ebp
	push  edi
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
	 cmp  byte[eax+31],0x80
	 jae  .i0
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
      movdqa  dqword[Temp1+16*0],xmm0
      movdqa  dqword[Temp1+16*1],xmm1
	 add  edi,8
	 sub  ebp,8
	  je  .f3
.f1:
	 mov  ebx,esi
	 and  ebx,dword[edi+4*0]
	 add  ebx,dword[edi+4*1]
.f15:
	 cmp  byte[ebx+31],0x80
	 jae  .c1
.f2:
	 mov  eax,Temp2
	fldz
	 fld  tword[ebx+10*0]
      fcomip  st1
	fstp  st0
	 jne  .f24
	fldz
	 fld  tword[ebx+10*1]
      fcomip  st1
	fstp  st0
	 jne  .f24
	fldz
	 fld  tword[Temp1+10*1]
      fcomip  st1
	fstp  st0
	 jne  .f24
	fldz
	 fld  tword[Temp1+10*0]
      fcomip  st1
	fstp  st0
	  jb  .f24
	  je  .f23
	fldz
	fldz
	fstp  tword[Temp1+10*0]
	fstp  tword[Temp1+10*1]
	 mov  byte[Temp1+31],0
	 jmp  .f25
.f23:
	fldz
	fld1
	fstp  tword[Temp1+10*0]
	fstp  tword[Temp1+10*1]
	 mov  byte[Temp1+31],0
	 jmp  .f25
.f24:
	call  LOG1
	 mov  eax,Temp1
	 mov  ebx,Temp2
	 mov  ecx,Temp1
	call  MUL2
	 mov  eax,Temp1
	 mov  ebx,Temp1
	call  EXP1
.f25:
	 add  edi,8
	 sub  ebp,8
	  ja  .f1
.f3:
	 pop  edi
	 mov  eax,esi
	 and  eax,dword[edi-8+4*0]
	 add  eax,dword[edi-8+4*1]
      movdqa  xmm0,dqword[Temp1+16*0]
      movdqa  xmm1,dqword[Temp1+16*1]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 pop  edi
	 ret
.c1:
      movdqa  xmm0,dqword[ebx+16*0]
      movdqa  xmm1,dqword[ebx+16*1]
	 mov  ebx,Temp2
      movdqa  dqword[ebx+16*0],xmm0
      movdqa  dqword[ebx+16*1],xmm1
	push  esi
	 mov  esi,ebx
	call  CVT2FP
	 pop  esi
	 jmp  .f2
.c2p:
	fstp  st0
.c2:
	push  esi
	 mov  esi,Temp1
	call  CVT2FP
	 pop  esi
	 jmp  .f15
.i0:
	 mov  eax,esi
	 and  eax,dword[edi+4*0]
	 add  eax,dword[edi+4*1]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
      movdqa  dqword[Temp1+16*0],xmm0
      movdqa  dqword[Temp1+16*1],xmm1
	 add  edi,8
	 sub  ebp,8
	 jna  .i3
.i1:
	 mov  ebx,esi
	 and  ebx,dword[edi+4*0]
	 add  ebx,dword[edi+4*1]
	 cmp  byte[ebx+31],0x80
	  jb  .c2
	push  esi
	 mov  esi,Temp2
      movdqa  xmm0,dqword[Temp1+16*0]
      movdqa  xmm1,dqword[Temp1+16*1]
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 fld  tword[esi]
      movdqa  xmm0,dqword[ebx+16*0]
      movdqa  xmm1,dqword[ebx+16*1]
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 fld  tword[esi]
	 pop  esi
	fldz
      fcomip  st1
	  je  .l0
	fabs
       fyl2x
	 mov  dword[esp-4],254
	fild  dword[esp-4]
      fcomip  st1
	  jc  .c2p
	fldz
      fcomip  st1
	  ja  .c2p
	 jmp  .l1
.l0:
	fstp  st0
.l1:
	fstp  st0
	push  ebp
	 mov  ebp,dword[Temp1+4*0]
      movdqa  xmm0,dqword[ebx+16*0]
      movdqa  xmm1,dqword[ebx+16*1]
      movdqa  dqword[Temp3+16*0],xmm0
      movdqa  dqword[Temp3+16*1],xmm1
	 mov  ecx,1
	movd  xmm0,ecx
	 mov  cl,0x80
	movd  xmm1,ecx
      pslldq  xmm1,15
      movdqa  dqword[Temp1+16*0],xmm0
      movdqa  dqword[Temp1+16*1],xmm1
	 jmp  .SHR
.MUL:
	 mov  eax,Temp1
	 mov  ebx,Temp3
	 mov  ecx,eax
	call  IMUL2
.SQR:
	 mov  eax,Temp3
	 mov  ebx,eax
	 mov  ecx,eax
	call  IMUL2
.SHR:
	 shr  ebp,1
	  jc  .MUL
	 jnz  .SQR
	 pop  ebp
	 add  edi,8
	 sub  ebp,8
	  ja  .i1
.i3:
	 pop  edi
	 mov  eax,esi
	 and  eax,dword[edi-8+4*0]
	 add  eax,dword[edi-8+4*1]
      movdqa  xmm0,dqword[Temp1+16*0]
      movdqa  xmm1,dqword[Temp1+16*1]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 pop  edi
	 ret

Fxn_Scale:
	 mov  eax,esi
	 and  eax,dword[edi-8*1+4*0]
	 add  eax,dword[edi-8*1+4*1]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
	push  esi
	 mov  esi,Temp1
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 pop  esi
	 mov  eax,esi
	 and  eax,dword[edi-8*2+4*0]
	 add  eax,dword[edi-8*2+4*1]
      movdqa  xmm0,dqword[eax+16*0]
      movdqa  xmm1,dqword[eax+16*1]
	push  esi
	 mov  esi,Temp2
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 pop  esi
	 fld  tword[Temp2+10*1]
	 fld  tword[Temp2+10*0]
      fldln2
	fild  dword[InputBase]
       fyl2x
	fmul  st1,st0
       fmulp  st2,st0
	fstp  tword[Temp2+10*0]
	fstp  tword[Temp2+10*1]
	 mov  eax,Temp2
	 mov  ebx,eax
	call  EXP1
	 mov  ecx,Temp1
	call  MUL2
	 mov  eax,esi
	 and  eax,dword[edi-8*3+4*0]
	 add  eax,dword[edi-8*3+4*1]
      movdqa  xmm0,dqword[Temp2+16*0]
      movdqa  xmm1,dqword[Temp2+16*1]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 ret

LD1:	    ; a = st1 + st0 I
	 mov  byte[eax+31],0x00
	fstp  tword[eax+10*1]
	fstp  tword[eax+10*0]
	 ret

MOV1:	    ; a = b
	 fld  tword[ebx]
	 fld  tword[ebx+10]
	fstp  tword[eax+10]
	fstp  tword[eax]
	 ret

MULFx:	    ; a = b * (st0 + 0 I)
	 fld  tword[ebx]
	 fld  tword[ebx+10]
	fmul  st0,st2
	fstp  tword[eax+10]
       fmulp  st1,st0
	fstp  tword[eax]
	 ret

MULxADD2:   ; a = b * (st0 + 0 I) + c
	 fld  tword[ebx+10*0]
	 fld  tword[ebx+10*1]
	fmul  st0,st2
	 fld  tword[ecx+10*1]
       faddp
	fstp  tword[eax+10*1]
       fmulp  st1,st0
	 fld  tword[ecx+10*0]
       faddp
	fstp  tword[eax+10*0]
	 ret

ADD_x:	    ; a = b + (st0 + 0 I)
	 fld  tword[ebx+10*0]
	 fld  tword[ebx+10*1]
	fstp  tword[eax+10*1]
       faddp  st1,st0
	fstp  tword[eax+10*0]
	 ret

NEG1:	    ; a = - b
	 fld  tword[ebx+10*0]
	 fld  tword[ebx+10*1]
	fchs
	 mov  byte[eax+31],0x00
	fstp  tword[eax+10*1]
	fchs
	fstp  tword[eax+10*0]
	 ret

ADD2:	    ; a = b + c
	 fld  tword[ebx+10*0]
	 fld  tword[ebx+10*1]
	 fld  tword[ecx+10*0]
	 fld  tword[ecx+10*1]
       faddp  st2,st0
       faddp  st2,st0
	 mov  byte[eax+31],0x00
	fstp  tword[eax+10*1]
	fstp  tword[eax+10*0]
	 ret

SUB2:	    ; a = b - c
	 fld  tword[ebx+10*0]
	 fld  tword[ebx+10*1]
	 fld  tword[ecx+10*0]
	 fld  tword[ecx+10*1]
       fsubp  st2,st0
       fsubp  st2,st0
	 mov  byte[eax+31],0x00
	fstp  tword[eax+10*1]
	fstp  tword[eax+10*0]
	 ret
PostfixFunctions:
Fxn_Factorial:
	push  edi
	push  esi
	 mov  eax,esi
	 and  eax,dword[edi-8*2+4*0]
	 add  eax,dword[edi-8*2+4*1]
	 and  esi,dword[edi-8*1+4*0]
	 add  esi,dword[edi-8*1+4*1]
	 mov  edi,eax
	 cmp  byte[esi+31],0x80
	 jae  .INT
.FP:
      movdqa  xmm0,dqword[esi+16*0]
      movdqa  xmm1,dqword[esi+16*1]
	 mov  esi,Temp0
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	  jb  @f
	call  CVT2FP
 @@:
	fld1
	fldz
      mycall  LD1,Temp3
	 jmp  .cmp

.inc:
	fld1
      mycall  ADD_x,Temp0,Temp0
      mycall  MUL2,Temp3,Temp3,Temp0
.cmp:
	 fld  tword[Temp0]
	 fld  tword[const_f10_10]
      fcomip  st0,st1
	fstp  st0
	  ja  .inc
	 fld  tword[const_f10_1o2]
      mycall  ADD_x,Temp1,Temp0
      mycall  LOG1,Temp2,Temp0
      mycall  MUL2,Temp1,Temp1,Temp2
      mycall  EXP1,Temp1,Temp1
      mycall  NEG1,Temp2,Temp0
      mycall  EXP1,Temp2,Temp2
      mycall  MUL2,Temp1,Temp1,Temp2
	 fld  tword[const_f10_sqrt2tpi]
      mycall  MULFx,Temp1,Temp1
      mycall  DIV2,Temp1,Temp1,Temp3
      mycall  MUL2,Temp2,Temp0,Temp0 ; x^2
      mycall  MUL2,Temp3,Temp2,Temp2 ; x^4
      mycall  MUL2,Temp4,Temp3,Temp2 ; x^6
      mycall  MUL2,Temp5,Temp3,Temp3 ; x^8
	 fld  tword[const_f10_a9]
	fldz
      mycall  LD1,Temp6
	 fld  tword[const_f10_a7]
      mycall  MULxADD2,Temp6,Temp2,Temp6
	 fld  tword[const_f10_a5]
      mycall  MULxADD2,Temp6,Temp3,Temp6
	 fld  tword[const_f10_a3]
      mycall  MULxADD2,Temp6,Temp4,Temp6
	 fld  tword[const_f10_a1]
      mycall  MULxADD2,Temp6,Temp5,Temp6
	 fld  tword[const_f10_a8]
      mycall  ADD_x,Temp5,Temp5
	 fld  tword[const_f10_a6]
      mycall  MULxADD2,Temp5,Temp2,Temp5
	 fld  tword[const_f10_a4]
      mycall  MULxADD2,Temp5,Temp3,Temp5
	 fld  tword[const_f10_a2]
      mycall  MULxADD2,Temp5,Temp4,Temp5
      mycall  MUL2,Temp5,Temp0,Temp5
      mycall  ADD2,Temp2,Temp5,Temp6
      mycall  SUB2,Temp3,Temp5,Temp6
      mycall  DIV2,Temp2,Temp2,Temp3
      mycall  MUL2,Temp1,Temp1,Temp2
      mycall  MOV1,Temp0,Temp1
      movdqa  xmm0,dqword[Temp0+16*0]
      movdqa  xmm1,dqword[Temp0+16*1]
      movdqa  dqword[edi+16*0],xmm0
      movdqa  dqword[edi+16*1],xmm1
	 pop  esi
	 pop  edi
	 ret
.INT:
	  bt  dword[esi+31],6
	  jc  .Infinity
	 cmp  dword[esi+4*0],56
	  ja  .FP
	 cmp  dword[esi+4*1],0
	 jne  .FP
	 cmp  dword[esi+4*2],0
	 jne  .FP
	 cmp  dword[esi+4*3],0
	 jne  .FP
	 cmp  dword[esi+4*4],0
	 jne  .FP
	 cmp  dword[esi+4*5],0
	 jne  .FP
	 cmp  dword[esi+4*6],0
	 jne  .FP
	 cmp  dword[esi+4*7],0x80000000
	 jne  .FP
	 mov  ebp,dword[esi+4*0]
	 mov  eax,1
	movd  xmm0,eax
	 mov  al,0x80
	movd  xmm1,eax
      pslldq  xmm1,15
      movdqa  dqword[Temp1+16*0],xmm0
      movdqa  dqword[Temp1+16*1],xmm1
	 cmp  ebp,1
	 jbe  .w2
.w1:
	 mov  eax,dword[Temp1+4*0]
	 mul  ebp
	 mov  dword[Temp1+4*0],eax
	 mov  ebx,edx
	 xor  ecx,ecx
	 mov  eax,dword[Temp1+4*1]
	 mul  ebp
	 add  ebx,eax
	 adc  ecx,edx
	 mov  dword[Temp1+4*1],ebx
	 xor  ebx,ebx
	 mov  eax,dword[Temp1+4*2]
	 mul  ebp
	 add  ecx,eax
	 adc  ebx,edx
	 mov  dword[Temp1+4*2],ecx
	 xor  ecx,ecx
	 mov  eax,dword[Temp1+4*3]
	 mul  ebp
	 add  ebx,eax
	 adc  ecx,edx
	 mov  dword[Temp1+4*3],ebx
	 xor  ebx,ebx
	 mov  eax,dword[Temp1+4*4]
	 mul  ebp
	 add  ecx,eax
	 adc  ebx,edx
	 mov  dword[Temp1+4*4],ecx
	 xor  ecx,ecx
	 mov  eax,dword[Temp1+4*5]
	 mul  ebp
	 add  ebx,eax
	 adc  ecx,edx
	 mov  dword[Temp1+4*5],ebx
	 xor  ebx,ebx
	 mov  eax,dword[Temp1+4*6]
	 mul  ebp
	 add  ecx,eax
	 adc  ebx,edx
	 mov  dword[Temp1+4*6],ecx
	 xor  ecx,ecx
	 mov  eax,dword[Temp1+4*7]
	 mul  ebp
	 add  ebx,eax
	 mov  dword[Temp1+4*7],ebx
	 sub  ebp,1
	  ja  .w1
.w2:	
	 bts  dword[Temp1+4*7],31
      movdqa  xmm0,dqword[Temp1+16*0]
      movdqa  xmm1,dqword[Temp1+16*1]
      movdqa  dqword[edi+16*0],xmm0
      movdqa  dqword[edi+16*1],xmm1
	 pop  esi
	 pop  edi
	 ret
.Infinity:
	 fld  tword[const_f10_pinf]
	 fld  st0
	fstp  tword[edi+10*0]
	fstp  tword[edi+10*1]
	 mov  byte[edi+31],0x00
	 pop  esi
	 pop  edi
	 ret
PrefixFunctions:
 ;
Fxn_If:    int3
Fxn_While: int3
Fxn_Loop:  int3
Fxn_List:  int3
Fxn_ContourPlot3D: int3 	   ; <>
Fxn_ParametricPlot3D: int3

Fxn_Out:
	 mov  ecx,esi
	 and  ecx,dword[edi-8*1+4*0]
	 add  ecx,dword[edi-8*1+4*1]
      movdqa  xmm0,dqword[ecx+16*0]
      movdqa  xmm1,dqword[ecx+16*1]
	push  esi
	 mov  esi,Temp1
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2INT
	 mov  eax,dword[esi]
	 pop  esi
	 cdq
	 mov  ecx,HISTORY_ENTRIES
	idiv  ecx
	 shl  edx,5
      movdqa  xmm0,dqword[HistorySpace+edx+16*0]
      movdqa  xmm1,dqword[HistorySpace+edx+16*1]
	 mov  ecx,esi
	 and  ecx,dword[edi-8*2+4*0]
	 add  ecx,dword[edi-8*2+4*1]
      movdqa  dqword[ecx+16*0],xmm0
      movdqa  dqword[ecx+16*1],xmm1
	 ret
Fxn_Cos:
	 mov  eax,Temp2
	 mov  ecx,esi
	 and  ecx,dword[edi-8*1+4*0]
	 add  ecx,dword[edi-8*1+4*1]
	 mov  ebx,esi
	 and  ebx,dword[edi-8*2+4*0]
	 add  ebx,dword[edi-8*2+4*1]
	 cmp  byte[ecx+31],0x80
	 jae  .c1
	call  SINCOS1
	 ret
.c1:
      movdqa  xmm0,dqword[ecx+16*0]
      movdqa  xmm1,dqword[ecx+16*1]
	push  esi
	 mov  esi,Temp1
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 mov  ecx,esi
	 pop  esi
	call  SINCOS1
	 ret
Fxn_Exp:
	 mov  ebx,esi
	 and  ebx,dword[edi-8*1+4*0]
	 add  ebx,dword[edi-8*1+4*1]
	 mov  eax,esi
	 and  eax,dword[edi-8*2+4*0]
	 add  eax,dword[edi-8*2+4*1]
	 cmp  byte[ebx+31],0x80
	 jae  .c1
	call  EXP1
	 ret
.c1:
      movdqa  xmm0,dqword[ebx+16*0]
      movdqa  xmm1,dqword[ebx+16*1]
	push  esi
	 mov  esi,Temp1
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 mov  ebx,esi
	 pop  esi
	call  EXP1
	 ret
Fxn_Log:
	 mov  ebx,esi
	 and  ebx,dword[edi-8*1+4*0]
	 add  ebx,dword[edi-8*1+4*1]
	 mov  eax,esi
	 and  eax,dword[edi-8*2+4*0]
	 add  eax,dword[edi-8*2+4*1]
	 cmp  byte[ebx+31],0x80
	 jae  .c1
	call  LOG1
	 ret
.c1:
      movdqa  xmm0,dqword[ebx+16*0]
      movdqa  xmm1,dqword[ebx+16*1]
	push  esi
	 mov  esi,Temp1
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 mov  ebx,esi
	 pop  esi
	call  LOG1
	 ret
Fxn_Sin:
	 mov  ebx,Temp2
	 mov  ecx,esi
	 and  ecx,dword[edi-8*1+4*0]
	 add  ecx,dword[edi-8*1+4*1]
	 mov  eax,esi
	 and  eax,dword[edi-8*2+4*0]
	 add  eax,dword[edi-8*2+4*1]
	 cmp  byte[ecx+31],0x80
	 jae  .c1
	call  SINCOS1
	 ret
.c1:
      movdqa  xmm0,dqword[ecx+16*0]
      movdqa  xmm1,dqword[ecx+16*1]
	push  esi
	 mov  esi,Temp1
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 mov  ecx,esi
	 pop  esi
	call  SINCOS1
	 ret

Fxn_Sqrt:
	 mov  ebx,esi
	 and  ebx,dword[edi-8*1+4*0]
	 add  ebx,dword[edi-8*1+4*1]
	 mov  eax,esi
	 and  eax,dword[edi-8*2+4*0]
	 add  eax,dword[edi-8*2+4*1]
	 cmp  byte[ebx+31],0x80
	 jae  .c1
	call  SQRT1
	 ret
.c1:
      movdqa  xmm0,dqword[ebx+16*0]
      movdqa  xmm1,dqword[ebx+16*1]
	push  esi
	 mov  esi,Temp1
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 mov  ebx,esi
	 pop  esi
	call  SQRT1
	 ret

Fxn_Tan:
	 mov  eax,Temp1
	 mov  ebx,Temp2
	 mov  ecx,esi
	 and  ecx,dword[edi-8*1+4*0]
	 add  ecx,dword[edi-8*1+4*1]
	 cmp  byte[ecx+31],0x80
	 jae  .c1
.f1:
	call  SINCOS1
	 mov  eax,esi
	 and  eax,dword[edi-8*2+4*0]
	 add  eax,dword[edi-8*2+4*1]
	 mov  ebx,Temp1
	 mov  ecx,Temp2
	call  DIV2
	 ret
.c1:
      movdqa  xmm0,dqword[ecx+16*0]
      movdqa  xmm1,dqword[ecx+16*1]
	push  esi
	 mov  esi,Temp1
      movdqa  dqword[esi+16*0],xmm0
      movdqa  dqword[esi+16*1],xmm1
	call  CVT2FP
	 mov  ecx,esi
	 pop  esi
	 jmp  .f1

EndFunctions:
;;;;;;;;;;;;;;;;;;
; Base Functions ;
;
CVT2INT:
	push  eax
	 mov  al,byte[esi+31]
	test  al,al
	  js  .done
	push  edx
	 fld  tword[esi+0]
       fistp  qword[esp-8]
	 mov  eax,dword[esp-8+0]
	 mov  edx,dword[esp-8+4]
	 mov  dword[esi+4*0],eax
	 mov  dword[esi+4*1],edx
	 sar  edx,31
	 mov  dword[esi+4*2],edx
	 mov  dword[esi+4*3],edx
	 mov  dword[esi+4*4],edx
	 mov  dword[esi+4*5],edx
	 mov  dword[esi+4*6],edx
	 bts  edx,31
	 mov  dword[esi+4*7],edx
	 pop  edx
.done:
	 pop  eax
	 ret

CVT2FP:
	push  eax
	 mov  al,byte[esi+31]
	test  al,al
	 jns  .done
	push  ecx
	push  edx
	 xor  ecx,ecx
	 xor  edx,edx
	 clc
	 rcl  dword[esi+4*0],1
	 rcl  dword[esi+4*1],1
	 rcl  dword[esi+4*2],1
	 rcl  dword[esi+4*3],1
	 rcl  dword[esi+4*4],1
	 rcl  dword[esi+4*5],1
	 rcl  dword[esi+4*6],1
	 rcl  dword[esi+4*7],1
	 mov  eax,dword[esi+4*7]
	test  eax,eax
	 jns  .pos
	 mov  dx,0x8000
	 mov  eax,ecx
	 sub  eax,dword[esi+4*0]
	 mov  dword[esi+4*0],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*1]
	 mov  dword[esi+4*1],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*2]
	 mov  dword[esi+4*2],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*3]
	 mov  dword[esi+4*3],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*4]
	 mov  dword[esi+4*4],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*5]
	 mov  dword[esi+4*5],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*6]
	 mov  dword[esi+4*6],eax
	 mov  eax,ecx
	 sbb  eax,dword[esi+4*7]
	 mov  dword[esi+4*7],eax
.pos:
	 inc  ecx
	 clc
	 rcl  dword[esi+4*0],1
	 rcl  dword[esi+4*1],1
	 rcl  dword[esi+4*2],1
	 rcl  dword[esi+4*3],1
	 rcl  dword[esi+4*4],1
	 rcl  dword[esi+4*5],1
	 rcl  dword[esi+4*6],1
	 rcl  dword[esi+4*7],1
	 cmp  ecx,255
	 jae  .zero
	 mov  eax,dword[esi+4*7]
	test  eax,eax
	 jns  .pos
	 sub  cx,16573+64
	 neg  cx
	  or  cx,dx
	 mov  eax,dword[esi+4*6]
	 mov  edx,dword[esi+4*7]
	 mov  dword[esi+0],eax
	 mov  dword[esi+4],edx
	 mov  word[esi+8],cx
	fldz
	fstp  tword[esi+10]
	 mov  byte[esi+31],0x00
	 pop  edx
	 pop  ecx
.done:
	 pop  eax
	 ret
.zero:
	fldz
	fldz
	fstp  tword[esi+00]
	fstp  tword[esi+10]
	 mov  byte[esi+31],0x00
	 pop  edx
	 pop  ecx
	 pop  eax
	 ret

IMUL2:
	 push  esi
	 push  edi
	 push  ebp
	 push  eax
	 push  ebx
	 push  ecx
	 mov  esi,ebx
	 mov  edi,ecx
	 mov  eax,dword[esi+4*0]
	 mul  dword[edi+4*0]
	 mov  dword[Temp2+4*0],eax
	 mov  ebx,edx
	 xor  ecx,ecx
	 xor  ebp,ebp
	 mov  eax,dword[esi+4*1]
	 mul  dword[edi+4*0]
	 add  ebx,eax
	 adc  ecx,edx
	 adc  ebp,0
	 mov  eax,dword[esi+4*0]
	 mul  dword[edi+4*1]
	 add  ebx,eax
	 adc  ecx,edx
	 adc  ebp,0
	 mov  dword[Temp2+4*1],ebx
	 xor  ebx,ebx
	 mov  eax,dword[esi+4*2]
	 mul  dword[edi+4*0]
	 add  ecx,eax
	 adc  ebp,edx
	 adc  ebx,0
	 mov  eax,dword[esi+4*1]
	 mul  dword[edi+4*1]
	 add  ecx,eax
	 adc  ebp,edx
	 adc  ebx,0
	 mov  eax,dword[esi+4*0]
	 mul  dword[edi+4*2]
	 add  ecx,eax
	 adc  ebp,edx
	 adc  ebx,0
	 mov  dword[Temp2+4*2],ecx
	 xor  ecx,ecx
	 mov  eax,dword[esi+4*3]
	 mul  dword[edi+4*0]
	 add  ebp,eax
	 adc  ebx,edx
	 adc  ecx,0
	 mov  eax,dword[esi+4*2]
	 mul  dword[edi+4*1]
	 add  ebp,eax
	 adc  ebx,edx
	 adc  ecx,0
	 mov  eax,dword[esi+4*1]
	 mul  dword[edi+4*2]
	 add  ebp,eax
	 adc  ebx,edx
	 adc  ecx,0
	 mov  eax,dword[esi+4*0]
	 mul  dword[edi+4*3]
	 add  ebp,eax
	 adc  ebx,edx
	 adc  ecx,0
	 mov  dword[Temp2+4*3],ebp
	 xor  ebp,ebp
	 mov  eax,dword[esi+4*4]
	 mul  dword[edi+4*0]
	 add  ebx,eax
	 adc  ecx,edx
	 adc  ebp,0
	 mov  eax,dword[esi+4*3]
	 mul  dword[edi+4*1]
	 add  ebx,eax
	 adc  ecx,edx
	 adc  ebp,0
	 mov  eax,dword[esi+4*2]
	 mul  dword[edi+4*2]
	 add  ebx,eax
	 adc  ecx,edx
	 adc  ebp,0
	 mov  eax,dword[esi+4*1]
	 mul  dword[edi+4*3]
	 add  ebx,eax
	 adc  ecx,edx
	 adc  ebp,0
	 mov  eax,dword[esi+4*0]
	 mul  dword[edi+4*4]
	 add  ebx,eax
	 adc  ecx,edx
	 adc  ebp,0
	 mov  dword[Temp2+4*4],ebx
	 xor  ebx,ebx
	 mov  eax,dword[esi+4*5]
	 mul  dword[edi+4*0]
	 add  ecx,eax
	 adc  ebp,edx
	 adc  ebx,0
	 mov  eax,dword[esi+4*4]
	 mul  dword[edi+4*1]
	 add  ecx,eax
	 adc  ebp,edx
	 adc  ebx,0
	 mov  eax,dword[esi+4*3]
	 mul  dword[edi+4*2]
	 add  ecx,eax
	 adc  ebp,edx
	 adc  ebx,0
	 mov  eax,dword[esi+4*2]
	 mul  dword[edi+4*3]
	 add  ecx,eax
	 adc  ebp,edx
	 adc  ebx,0
	 mov  eax,dword[esi+4*1]
	 mul  dword[edi+4*4]
	 add  ecx,eax
	 adc  ebp,edx
	 adc  ebx,0
	 mov  eax,dword[esi+4*0]
	 mul  dword[edi+4*5]
	 add  ecx,eax
	 adc  ebp,edx
	 adc  ebx,0
	 mov  dword[Temp2+4*5],ecx
	 mov  eax,dword[esi+4*6]
	 mul  dword[edi+4*0]
	 add  ebp,eax
	 adc  ebx,edx
	 mov  eax,dword[esi+4*5]
	 mul  dword[edi+4*1]
	 add  ebp,eax
	 adc  ebx,edx
	 mov  eax,dword[esi+4*4]
	 mul  dword[edi+4*2]
	 add  ebp,eax
	 adc  ebx,edx
	 mov  eax,dword[esi+4*3]
	 mul  dword[edi+4*3]
	 add  ebp,eax
	 adc  ebx,edx
	 mov  eax,dword[esi+4*2]
	 mul  dword[edi+4*4]
	 add  ebp,eax
	 adc  ebx,edx
	 mov  eax,dword[esi+4*1]
	 mul  dword[edi+4*5]
	 add  ebp,eax
	 adc  ebx,edx
	 mov  eax,dword[esi+4*0]
	 mul  dword[edi+4*6]
	 add  ebp,eax
	 adc  ebx,edx
	 mov  dword[Temp2+4*6],ebp
	 mov  eax,dword[esi+4*7]
	 sal  eax,1
	 mov  ecx,eax
	 sar  eax,1
	 sar  ecx,31
	 xor  eax,ecx
	 sub  eax,ecx
	 mul  dword[edi+4*0]
	 xor  eax,ecx
	 sub  eax,ecx
	 add  ebx,eax
	 mov  eax,dword[esi+4*6]
	 mul  dword[edi+4*1]
	 add  ebx,eax
	 mov  eax,dword[esi+4*5]
	 mul  dword[edi+4*2]
	 add  ebx,eax
	 mov  eax,dword[esi+4*4]
	 mul  dword[edi+4*3]
	 add  ebx,eax
	 mov  eax,dword[esi+4*3]
	 mul  dword[edi+4*4]
	 add  ebx,eax
	 mov  eax,dword[esi+4*2]
	 mul  dword[edi+4*5]
	 add  ebx,eax
	 mov  eax,dword[esi+4*1]
	 mul  dword[edi+4*6]
	 add  ebx,eax
	 mov  eax,dword[edi+4*7]
	 sal  eax,1
	 mov  ecx,eax
	 sar  eax,1
	 sar  ecx,31
	 xor  eax,ecx
	 sub  eax,ecx
	 mul  dword[esi+4*0]
	 xor  eax,ecx
	 sub  eax,ecx
	 add  ebx,eax
	 bts  ebx,31
	 mov  dword[Temp2+4*7],ebx
	 pop  ecx
	 pop  ebx
	 pop  eax
      movdqa  xmm0,dqword[Temp2+16*0]
      movdqa  xmm1,dqword[Temp2+16*1]
      movdqa  dqword[eax+16*0],xmm0
      movdqa  dqword[eax+16*1],xmm1
	 pop  ebp
	 pop  edi
	 pop  esi
	 ret

EXP1: ; a = Exp[b]
       fldpi
	fadd  st0,st0
	 fld  tword[ebx+10]
      fprem1
	fstp  st1
     fsincos
	 fld  tword[ebx]
      fldl2e
       fmulp  st1,st0
	 fld  st0
     frndint
	fxch  st1
	fsub  st0,st1
       f2xm1
	fld1
       faddp  st1,st0
      fscale
	fstp  st1
	fmul  st1,st0
       fmulp  st2,st0
	fstp  tword[eax]
	fstp  tword[eax+10]
	 mov  byte[eax+31],0x00
	 ret

SINCOS1:    ; {a,b} = {Sin[c],Cos[c]}
	 fld  tword[ecx+10]
	fldz
      fcomip  st1
	 jne  .complex
	fstp  st0
	 fld  tword[ecx]
     fsincos
	fstp  tword[ebx]
	fldz
	fstp  tword[ebx+10]
	 mov  byte[ebx+31],0x00
	fstp  tword[eax]
	fldz
	fstp  tword[eax+10]
	 mov  byte[eax+31],0x00
	 ret
.complex:
      fldl2e
       fmulp
	 fld  st0
	 fld  st0
     frndint	      ; [x],x,x,...
	fldz
      fcomip  st0,st1
	  jz  .small
	fxch  st1     ; x,[x],x,...
	fsub  st0,st1 ; x-[x],[x],x,...
       f2xm1
	fld1
       faddp  st1,st0
      fscale	      ; 2^x,[x],x,...
	fxch  st2     ; x,[x],2^x,...
       fsubr  st0,st1
	fxch  st1
	fchs
	fxch  st1     ; [x]-x,-[x],2^x,...
       f2xm1
	fld1
       faddp  st1,st0
      fscale	      ; 2^-x,-[x],2^x
	 fst  st1     ; 2^-x,2^-x,2^x
	fadd  st0,st2
	fxch  st2
       fsubp  st1,st0
	 jmp  .cont   ; -sinh,cosh,...
.small:
	fstp  st0
	fchs	      ; -x,x
       f2xm1
	fxch  st1
       f2xm1	      ; 2^x-1,2^-x-1,...
	 fld  st1
	 fld  st1
	fld1
	fadd  st1,st0
	fadd  st2,st0
       faddp  st2,st0
       fmulp  st3,st0
	fadd  st1,st0
       fmulp  st2,st0
	fxch  st1
.cont:
       fldpi
	fadd  st0,st0
	 fld  tword[ecx]
      fprem1
	fstp  st1
     fsincos
	 fld  tword[const_f10_1o2]
	fmul  st1,st0
       fmulp  st2,st0
	 fld  st1
	fmul  st0,st4
	fstp  tword[eax]
	 fld  st0
	fmul  st0,st3
	fchs
	fstp  tword[eax+10]
	 mov  byte[eax+31],0x00
       fmulp  st3,st0
       fmulp  st1,st0
	 mov  byte[ebx+31],0x00
	fstp  tword[ebx+10]
	fstp  tword[ebx]
	 ret

LOG1: ; a = Log[b]
	 fld  tword[ebx+10]
	fldz
      fcomip  st1
	 jne  @f	; be careful about the branch cut!
	fabs
 @@:	 fld  tword[ebx]
	 fld  tword[const_f10_log2o2]
	 fld  st2
	fmul  st0,st0
	 fld  st2
	fmul  st0,st0
       faddp  st1,st0
       fyl2x
	fstp  tword[eax]
      fpatan
	fstp  tword[eax+10]
	 mov  byte[eax+31],0x00
	 ret

SQRT1: ; a = Sqrt[b]
	 fld  tword[ebx+10]
	fldz
      fcomip  st0,st1
	 fld  tword[ebx]
	fldz
	  jz  .real
	 sbb  ecx,ecx
      fcomip  st0,st1
	fabs
	 fld  st1
	fmul  st0,st0
	 fld  st1
	fmul  st0,st0
       faddp  st1,st0
       fsqrt
       faddp  st1,st0
	 fld  tword[const_f10_1o2]
	fmul  st1,st0
       fmulp  st2,st0
       fsqrt
	fdiv  st1,st0
	  jc  .l1
	fxch  st1
	test  ecx,ecx
	 jnz  .l1
	fchs
	fxch  st1
	fchs
	fxch  st1
	 jmp  .l1
.real:
      fcomip  st0,st1
	fabs
       fsqrt
	  jc  .l1
	fxch  st1
.l1:
	fstp  tword[eax]
	fstp  tword[eax+10]
	 mov  byte[eax+31],0x00
	 ret

RCP1: ; a = 1 / b
	fld  tword[ebx]
	fld  tword[ebx+10]
	fld  st1
       fmul  st0,st0
	fld  st1
       fmul  st0,st0
      faddp  st1,st0
       fdiv  st2,st0
      fdivp  st1,st0
       fchs
	mov  byte[esi+8*eax+31],0x00
       fstp  tword[esi+8*eax+10]
       fstp  tword[esi+8*eax]
	ret

MUL2: ; a = b * c
	fld  tword[ebx]
	fld  tword[ebx+10]
	fld  tword[ecx]
	fld  tword[ecx+10]
	fld  st3
       fmul  st0,st2
	fld  st3
       fmul  st0,st2
      fsubp  st1,st0
       fstp  tword[eax]
      fmulp  st3,st0
      fmulp  st1,st0
      faddp  st1,st0
       fstp  tword[eax+10]
	mov  byte[eax+31],0x00
	ret

DIV2: ; a = b / c
	fld  tword[ebx]
	fld  tword[ecx]
	fld  tword[ebx+10]
	fld  tword[ecx+10]
	fld  st0
       fmul  st0,st0
	fld  st3
       fmul  st0,st0
      faddp  st1,st0
       fstp  st5
	fld  st3
       fmul  st0,st3
	fld  st2
       fmul  st0,st2
      faddp  st1,st0
       fdiv  st0,st5
       fstp  tword[eax]
      fmulp  st3,st0
      fmulp  st1,st0
     fsubrp  st1,st0
     fdivrp  st1,st0
       fstp  tword[eax+10]
	mov  byte[eax+31],0x00
	ret

;
; ADD MORE FUNCTIONS HERE ;
;

section '.data' data readable writeable

align 16
DigitStringJTable:
  dd  Parse.Symbol, Parse.Symbol, Parse.Symbol, Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  \
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,	Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  \
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,	Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  \
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,	Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  \
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,	Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,\
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,	Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Dot,     Parse.Symbol,\
   Parse.Digit,   Parse.Digit,	 Parse.Digit,	Parse.Digit,   Parse.Digit,   Parse.Digit,   Parse.Digit,   Parse.Digit,\
   Parse.Digit,   Parse.Digit,	 Parse.Symbol,	Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,\
   Parse.Symbol,  Parse.Letter,  Parse.Letter,	Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\
   Parse.Letter,  Parse.Letter,  Parse.Letter,	Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\
   Parse.Letter,  Parse.Letter,  Parse.Letter,	Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\
   Parse.Letter,  Parse.Letter,  Parse.Letter,	Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,\
   Parse.Symbol,  Parse.Letter,  Parse.Letter,	Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\
   Parse.Letter,  Parse.Letter,  Parse.Letter,	Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\
   Parse.Letter,  Parse.Letter,  Parse.Letter,	Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\
   Parse.Letter,  Parse.Letter,  Parse.Letter,	Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol
SymbolJTable:
  dd  lex_Null,       Parse.ReadChar,	 Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,	  Parse.ReadChar,    Parse.ReadChar,	Parse.ReadChar,    \
   Parse.ReadChar,    Parse.ReadChar,	 Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,	  Parse.ReadChar,    Parse.ReadChar,	Parse.ReadChar,    \
   Parse.ReadChar,    Parse.ReadChar,	 Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,	  Parse.ReadChar,    Parse.ReadChar,	Parse.ReadChar,    \
   Parse.ReadChar,    Parse.ReadChar,	 Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,	  Parse.ReadChar,    Parse.ReadChar,	Parse.ReadChar,    \
   Parse.ReadChar,    lex_factorial,	 SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,lex_and	       ,SyntaxError_Uknown,\
   lex_OpenPar,       lex_ClosePar,	 lex_times,	    lex_plus,	       lex_Comma,	  lex_minus,	     SyntaxError_Uknown,lex_divide,	   \
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,lex_Sep,	    lex_cmpdexpr,      lex_less,	  lex_set,	     lex_greater,	SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,lex_OpenBra,       SyntaxError_Uknown,lex_CloseBra,      lex_power, 	SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,lex_OpenList,      lex_or,		  lex_CloseList,     lex_tilde, 	Parse.ReadChar

const_False  dq  0x0000000000000000,0x0000000000000000,0x0000000000000000,0x8000000000000000
const_True   dq  0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF
NOP_BINST    dd  NOP_BENC,0,1,1
SETA_BINST   dd  SETA_BENC,0,1,1
SETV_BINST   dd  SETV_BENC,0,1,1
ConstString  db  'const',0,0,0,0,0,0,0,0,0,0,0

string_E	   db  'E'	    ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
string_I	   db  'I'	    ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
string_InputBase   db  'InputBase'  ,0,0,0,0,0,0,0
string_Pi	   db  'Pi'	    ,0,0,0,0,0,0,0,0,0,0,0,0,0,0
string_OutputBase  db  'OutputBase' ,0,0,0,0,0,0
string_OutputBits  db  'OutputBits' ,0,0,0,0,0,0

FxnStringTable:
	db  'And'	  ,0,0,0,0,0,0,0,0,0,0,0,0,0
	db  'CmpdExpr'	  ,0,0,0,0,0,0,0,0
	db   'ContourPlot3D',0,0,0
	db 'Cos'	  ,0,0,0,0,0,0,0,0,0,0,0,0,0
	db  'Divide'	  ,0,0,0,0,0,0,0,0,0,0
	db  'Exp'	  ,0,0,0,0,0,0,0,0,0,0,0,0,0
	db  'Equal'	  ,0,0,0,0,0,0,0,0,0,0,0
	db  'Factorial'   ,0,0,0,0,0,0,0
	db  'Greater'	  ,0,0,0,0,0,0,0,0,0
	db  'GreaterEqual',0,0,0,0
	db  'If'	  ,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	db  'List'	  ,0,0,0,0,0,0,0,0,0,0,0,0
	db  'Less'	  ,0,0,0,0,0,0,0,0,0,0,0,0
	db  'LessEqual'   ,0,0,0,0,0,0,0
	db  'Log'	  ,0,0,0,0,0,0,0,0,0,0,0,0,0
	db  'Loop'	  ,0,0,0,0,0,0,0,0,0,0,0,0
	db  'Minus'	  ,0,0,0,0,0,0,0,0,0,0,0
	db  'Or'	  ,0,0,0,0,0,0,0,0,0,0,0,0,0,0
	db  'Out'	  ,0,0,0,0,0,0,0,0,0,0,0,0,0
	db  'ParametricPlot3D'
	db  'Plus'	  ,0,0,0,0,0,0,0,0,0,0,0,0
	db  'Power'	  ,0,0,0,0,0,0,0,0,0,0,0
	db  'Power2'	  ,0,0,0,0,0,0,0,0,0,0
	db  'Power3'	  ,0,0,0,0,0,0,0,0,0,0
	db  'Power4'	  ,0,0,0,0,0,0,0,0,0,0
	db  'Scale'	  ,0,0,0,0,0,0,0,0,0,0,0
	db  'Set'	  ,0,0,0,0,0,0,0,0,0,0,0,0,0
	db  'Sin'	  ,0,0,0,0,0,0,0,0,0,0,0,0,0
	db  'Sqrt'	  ,0,0,0,0,0,0,0,0,0,0,0,0
	db  'Tan'	  ,0,0,0,0,0,0,0,0,0,0,0,0,0
	db  'Times'	  ,0,0,0,0,0,0,0,0,0,0,0
	db  'While'	  ,0,0,0,0,0,0,0,0,0,0,0
	db  'Xor'	  ,0,0,0,0,0,0,0,0,0,0,0,0,0
	dq  0,0

FxnAddressTable:
	dd  Fxn_And
	dd  Fxn_CmpdExpr
	dd  Fxn_ContourPlot3D
	dd  Fxn_Cos
	dd  Fxn_Divide
	dd  Fxn_Exp
	dd  Fxn_Equal
	dd  Fxn_Factorial
	dd  Fxn_Greater
	dd  Fxn_GreaterEqual
	dd  Fxn_If
	dd  Fxn_List
	dd  Fxn_Less
	dd  Fxn_LessEqual
	dd  Fxn_Log
	dd  Fxn_Loop
	dd  Fxn_Minus
	dd  Fxn_Or
	dd  Fxn_Out
	dd  Fxn_ParametricPlot3D
	dd  Fxn_Plus
	dd  Fxn_Power
	dd  Fxn_Power2
	dd  Fxn_Power3
	dd  Fxn_Power4
	dd  Fxn_Scale
	dd  Fxn_Set
	dd  Fxn_Sin
	dd  Fxn_Sqrt
	dd  Fxn_Tan
	dd  Fxn_Times
	dd  Fxn_While
	dd  Fxn_Xor
	dd  0

align 16
 Frustum	   dq  -1.0, 1.0,-1.0, 1.0, 1.0, 50.0
 Perspective	   dq  60.0, 1.0, 0.5, 300.0
 lightdirection    dd  0.0, 0.707106781186548, 0.707106781186548,0
 ambientlightintensity dd  0.25,0.25,0.25,0
 white		   dd  1.0,1.0,1.0,0
 const_f4v4_1	   dd  1.0,1.0,1.0,1.0
 const_f4v4_neg    dd  0x80000000,0x80000000,0x80000000,0x80000000
 const_f4v4_255    dd  255.0,255.0,255.0,255.0
 FrontColor	   dd  0.5,0.0,0.5,0.0
 BackColor	   dd  0.0,0.0,1.0,0.0

 CameraPos.x	dd  0.0
 CameraPos.y	dd  0.0
 CameraPos.z	dd  5.0
 CameraPos.w	dd  0
 CameraAngle.x	dd  0.0
 CameraAngle.y	dd  0.0
 CameraMove	dd  0
		dd  0

 CustomColors dd  0
	      dd  0
	      dd  0
	      dd  0
	      dd  0
	      dd  0
	      dd  0
	      dd  0
	      dd  0
	      dd  0
	      dd  0
	      dd  0
	      dd  0
	      dd  0
	      dd  0
	      dd  0

align 4
    Plotwc  WNDCLASS 0,PlotWindowProc,0,0,NULL,NULL,NULL,NULL,NULL,string_PlotClass
	wc  WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,string_Class
       msg  MSG
	rc  RECT
	of  OPENFILENAME
	cc  CHOOSECOLOR
   Plotmsg  MSG
   Plotpfd  PIXELFORMATDESCRIPTOR
    f4_deg  dd	0.0174532925199433
    f4_360  dd	360.0
     f4_80  dd	80.0
    f4_m80  dd	-80.0
     f4_p1  dd	0.1
 anglestep  dd	0.3
     speed  dd	0.04
    speed2  dd	0.03
 InputBase  dd	INITIAL_INPUT_BASE
 OutputBase  dd  INITIAL_OUTPUT_BASE
 OutputBits  dd  INITIAL_OUTPUT_BITS
 ParametricPlotDefaultDivisions  dd  MED_DIVISIONS
 ContourPlotDefaultDivisions  dd  MED_DIVISIONS_CONTOURPLOT
 OutputLineNumber  dd	0

align 2
  fpcw_Prec64:	dw  0x037F
  const_f10_3:	dt  3.0
  const_f10_e:	dt  2.71828182845904523536028747135
  const_f10_1oln2:  dt	1.442695040888963407359924681
  const_f10_pinf:   dw	0,0,0,0,0x7FFF
  const_f10_log2o2: dt	0.346573590279972654708616060729
  const_f10_1o2:    dt	0.5
  const_f10_sqrt2tpi: dt  2.50662827463100050241576528481
  const_f10_10	dt  10.0
  const_f10_a9	dt  0.0947045913630845704789873309848
  const_f10_a8	dt  2.93745064968810576491521896035
  const_f10_a7	dt  1.11842864974962219443572336559
  const_f10_a6	dt  28.0243640171301711347390154049
  const_f10_a5	dt  1.57487525486360507892685909780
  const_f10_a4	dt  38.2158803688353054407392295130
  const_f10_a3	dt  0.525017988890212528128284493279
  const_f10_a2	dt  12.6343437704021377121158648757
  const_f10_a1	dt  0.0416666666666666666666666666667

align 1
  meshQ     db	0
  normalsQ  db	0
  plotQ     db	0
  boxQ	    db	-1
  polymode  db	1
  plotmode  db	0
  helpQ     db	0
  updatingplotQ  db  0
  string_Greeting:  db	'Greetings!',0
  string_PlotHelp:  db	'Movement: wasd  Look: ijkl  FrontColor: c  BackColor: x  Mesh: m  Normals: n  Box: b',0
  string_InternalError:  db  'An unexpected internal error has occured...',0
  string_SyntaxError_Unexpected: db  'Syntax Error: unexpected ???????????',0
  string_CompileError_ArgCount:  db  'Compile Error: number of arguments in ??',0
  string_EvalError_Stack:	 db  'Evaluation Error: stack overflowed',0
  string_EvalError_OutOfMemory:  db  'Evaluation Error: out of memory',0
  string_CompileError_Def:	 db  'Compile Error: unknown function',0
  string_CompileError_DefArg:	 db  'Compile Error: invalid function arguments',0
  string_CompileError_DefSep:	 db  'Compile Error: invalid ":"',0
  string_CompileError_MustRet1	 db  'Compile Error: must return 1 value',0
  string_CompileError_MustRet3	 db  'Compile Error: must return 3 values',0
  string_CompileError_Def2Large: db  'Compile Error: definition too large',0
  string_CompileError_BadAss	 db  'Compile Error: invalid assignment',0
  string_CompileError_Plot	 db  'Compile Error: ParametricPlot3D may only be called in top level',0
  string_CompileError_ContourPlot db  'Compile Error: ContourPlot3D may only be called in top level',0
  string_SyntaxError_StringLength db  'Syntax Error: symbols are restricted to 16 characters or less',0
  string_SyntaxError_Digits	 db  'Syntax Error: too many digits',0
  string_CompileError_Plot_3Arg  db  'Compile Error: 3 arguments expected in ParametricPlot3D',0
  string_CompileError_ContourPlot_4Arg: db  'Compile Error: 4 arguments expected in ContourPlot3D',0
  string_CompileError_Plot_Ret3  db  'Compile Error: 3 return values expected in 1st argument of ParametricPlot3D',0
  string_CompileError_ContourPlot_Ret1: db  'Compile Error: 1 return value expected in 1st argument of ContourPlot3D',0
  string_CompileError_Plot_Arg2  db  'Compile Error: iteration range expected for 2nd argument of ParametricPlot3D',0
  string_CompileError_Plot_Arg3  db  'Compile Error: iteration range expected for 3rd argument of ParametricPlot3D',0
  string_CompileError_ContourPlot_Arg2 db  'Compile Error: iteration range expected for 2nd argument of ContourPlot3D',0
  string_CompileError_ContourPlot_Arg3 db  'Compile Error: iteration range expected for 3rd argument of ContourPlot3D',0
  string_CompileError_ContourPlot_Arg4 db  'Compile Error: iteration range expected for 4rd argument of ContourPlot3D',0
  string_CompileError_Iter_Var	 db 'Compile Error: variable expected for 1st argument of iteration range',0
  string_Demo1	db  'ParametricPlot3D[ r = 2. + 0.2 phi (Pi - phi) Sin[6.th] Sin[7.phi];',0x0d,0x0a
		db  '{r Cos[th] Sin[phi], r Sin[th] Sin[phi], r Cos[phi]},',0x0d,0x0a
		db  '{phi, 0, Pi}, {th, 0, 2Pi}]',0
  string_Demo2	db  'f[n]=If[n<=1,n,f[n-1]+f[n-2]];',0x0d,0x0a
		db  'f[25]',0
  string_Demo3	db  'ParametricPlot3D[{x, (x + I y)!, y}, {y, -3, 3}, {x, -3, 2}]',0
  string_Demo4	db  'Degree = Pi/180;',0x0d,0x0a
		db  'Csc[x] = /Sin[x];',0x0d,0x0a
		db  'Sec[x] = /Cos[x];',0x0d,0x0a
		db  'Cot[x] = /Tan[x];',0x0d,0x0a
		db  'ArcSin[x] = -I*Log[I*x + Sqrt[1 - x^2]];',0x0d,0x0a
		db  'ArcCos[x] = Pi/2 + I*Log[I*x + Sqrt[1 - x^2]];',0x0d,0x0a
		db  'ArcTan[x] = I/2*Log[(I + x)/(I - x)];',0x0d,0x0a
		db  'ArcCsc[x] = (x = /x; -I*Log[I*x + Sqrt[1 - x^2]]);',0x0d,0x0a
		db  'ArcSec[x] = (x = /x; Pi/2 + I*Log[I*x + Sqrt[1 - x^2]]);',0x0d,0x0a
		db  'ArcCot[x] = I/2*Log[(x - I)/(x + I)];',0x0d,0x0a
		db  'Sinh[x] = -I*Sin[I*x];',0x0d,0x0a
		db  'Cosh[x] = Cos[I*x];',0x0d,0x0a
		db  'Tanh[x] = -I*Tan[I*x];',0x0d,0x0a
		db  'Csch[x] = I/(Sin[I*x]);',0x0d,0x0a
		db  'Sech[x] = I/Cos[I*x];',0x0d,0x0a
		db  'Coth[x] = I/(Tan[I*x]);',0x0d,0x0a
		db  'ArcSinh[x] = Log[x + Sqrt[1 + x^2]];',0x0d,0x0a
		db  'ArcCosh[x] = Log[x + Sqrt[x - 1]*Sqrt[x + 1]];',0x0d,0x0a
		db  'ArcTanh[x] = 1/2*Log[(1 + x)/(1 - x)];',0x0d,0x0a
		db  'ArcCsch[x] = (x = /x; Log[x + Sqrt[1 + x^2]]);',0x0d,0x0a
		db  'ArcSech[x] = (x = /x; Log[x + Sqrt[x - 1]*Sqrt[x + 1]]);',0x0d,0x0a
		db  'ArcCoth[x] = /2*Log[(x + 1)/(x - 1)]',0
  string_Demo5	db  'ContourPlot3D[x^4 + y^4 + z^4 - (x^2 + y^2 + z^2)^2 + 3. (x^2 + y^2 + z^2) - 3.,',0x0d,0x0a
		db  '{x, -3, 3}, {y, -3, 3}, {z, -3, 3}]',0	     ; 0.29 seconds
  string_Demo6	db  'ContourPlot3D[ Cos[x] Sin[y] + Cos[y] Sin[z] + Cos[z] Sin[x],',0x0d,0x0a
		db  '{x, -6, 6}, {y, -6, 6}, {z, -6, 6}]',0	     ; 0.54 seconds
  string_Demo7	db  'a = (1 + Sqrt[5]) / 2;',0x0d,0x0a
		db  'ContourPlot3D[',0x0d,0x0a
		db  '  If[ x^2 + y^2 + z^2 < 27.',0x0d,0x0a
		db  '  ,  Cos[x + a*y] + Cos[x - a y] +',0x0d,0x0a
		db  '     Cos[y + a*z] + Cos[y - a z] +',0x0d,0x0a
		db  '     Cos[z + a*x] + Cos[z - a x] - 2.',0x0d,0x0a
		db  '  ,  -1.',0x0d,0x0a
		db  '  ]',0x0d,0x0a
		db  ', {x, -5.2, 5.2, 54}',0x0d,0x0a
		db  ', {y, -5.2, 5.2, 54}',0x0d,0x0a
		db  ', {z, -5.2, 5.2, 54}',0x0d,0x0a
		db  ']',0x0

  string_MemoryErrorMessage  db  'uhohoh the GUI blew out of memory',0
  string_MemoryErrorCaption  db  'Oops',0
  string_Title TCHAR 'ALLAIMS',0
  string_PlotTitle TCHAR '3D-Math Plot',0
  string_Error TCHAR 'The startup failed',0
  string_Class TCHAR 'ALLAIMS',0
  string_PlotClass TCHAR '3D-Math Plot',0
  string_Edit TCHAR 'EDIT',0

align 8
  Frequency  rq  1
  Count1     rq  1
  Count2     rq  1
  PlotTime1  rq  1
  PlotTime2  rq  1

align 4
  Buffer1  rd  1
  Buffer2  rd  1
  Buffer3  rd  1
  Buffer4  rd  1
  VarValueTable    rd  1
  VarStringTable   rd  1
  VarTableEntries  rd  1
  VarValueTableSizeB  rd 1
  ConstTable	   rd  1
  ConstTableTop    rd  1
  ConstTableSizeB  rd  1
  DefStringTable   rd  1
  DefStringTableSizeB  rd  1
  DefIndexArgAddressTable  rd  1
  DefIndexArgAddressTableSizeB	rd  1
  InputString	   rd  1
  OutputString	   rd  1
  VertexCoorNormalColorTable  rd  1
  ContourVertexCoorNormalColorTable  rd  1
  ContourVertexCoorNormalColorTableCaret  rd  1
  ContourVertexCoorNormalColorTableMaxCaret  rd  1
  TriangleCount rd  1
  VertexTable	rd  1
  xyzint  rd  1
  xyintb  rd  1
  xyintt  rd  1
  zint	  rd  1
  ftabt   rd  1
  ftabb   rd  1
  ArgLocCount rd 1
  ArgCount  rd	1
  LocCount  rd	1
  DefIndex  rd	2
  espSave   rd	1
  Caret     rd	1
  hMainWindow	rd  1
  hInputWindow	rd  1
  hOutputWindow rd  1
  hStatusWnd	rd  1
  hInputFont	rd  1
  hOutputFont	rd  1
  hPlotWindow	rd  1
  hPlotStatusWnd rd 1
  hPlotdc  rd  1
  hPlotrc  rd  1
  u_min    rd  3
  u_max    rd  3
  u_delta  rd  3
  u_div    rd  1
  u_var    rd  1
  v_min    rd  3
  v_max    rd  3
  v_delta  rd  3
  v_div    rd  1
  v_var    rd  1
  w_min    rd  3
  w_max    rd  3
  w_delta  rd  3
  w_div    rd  1
  w_var    rd  1

align 16
  Temp0  rd  8
  Temp1  rd  8
  Temp2  rd  8
  Temp3  rd  8
  Temp4  rd  8
  Temp5  rd  8
  Temp6  rd  8

ArgStackSpace:
  ArgLocTableSpace rq  1024
  EvalStackSpace   rb  32*EVAL_STACK_ENTRIES
  HistorySpace	   rb  32*HISTORY_ENTRIES
  StatusString	   rb  1024
  DebugString	   rq  1024
  OpenFileString   rb  1024

section '.idata' import data readable writeable

    library  kernel32,'KERNEL32.DLL',\
	     user32,'USER32.DLL',\
	     gdi32,'GDI32.DLL',\
	     shell32,'SHELL32.DLL',\
	     comctl32,'COMCTL32.DLL',\
	     comdlg32,'COMDLG32.DLL',\
	     opengl32,'OPENGL32.DLL',\
	     glu32,'GLU32.DLL'

    include  '\INCLUDE\api\kernel32.inc'
    include  '\INCLUDE\api\user32.inc'
    include  '\INCLUDE\api\gdi32.inc'
    include  '\INCLUDE\api\shell32.inc'

      import  comctl32,\
	      CreateStatusWindow,'CreateStatusWindowA'

      import  comdlg32,\
	      GetOpenFileNameA,'GetOpenFileNameA',\
	      ChooseColor,'ChooseColorA'

     include  '\INCLUDE\apiopengl.inc'

section '.rsrc' resource data readable
; resource directory
   directory  RT_MENU,menus,\
	      RT_ICON,icons,\
	      RT_GROUP_ICON,group_icons,\
	      RT_VERSION,versions
 ; resource subdirectories
    resource  menus,\
	      37,LANG_ENGLISH+SUBLANG_DEFAULT,main_menu
    resource  icons,\
	      1,LANG_NEUTRAL,icon_data
    resource  group_icons,\
	      17,LANG_NEUTRAL,main_icon
    resource  versions,\
	      1,LANG_NEUTRAL,version
	menu  main_menu
    menuitem  '&File',0,MFR_POPUP
    menuitem  '&Open',IDM_OPEN
    menuitem  'E&xit',IDM_EXIT,MFR_END
    menuitem  '&Evaluate',IDM_EVALUATE
    menuitem  '&Clear',IDM_CLEAR
    menuitem  '&Debug',0,MFR_POPUP
    menuitem  '&View Symbols',IDM_VIEW_SYMBOLS,MFR_END
    menuitem  'E&xamples',0,MFR_POPUP
    menuitem  '&1: Spherical Plot',IDM_DEMO1
    menuitem  '&2: Fibonacci Calculation',IDM_DEMO2
    menuitem  '&3: Complex Plot',IDM_DEMO3
    menuitem  '&4: Elementary Functions',IDM_DEMO4
    menuitem  '&5: Algebraic Variety',IDM_DEMO5
    menuitem  '&6: Transcendental Variety',IDM_DEMO6
    menuitem  '&7: Dodecahedron',IDM_DEMO7,MFR_END
    menuitem  '&Settings',0,MFR_POPUP
    menuitem  '&1: Small Font',IDM_FONT_SMALL
    menuitem  '&2: Medium Font',IDM_FONT_MEDIUM
    menuitem  '&3: Large Font',IDM_FONT_LARGE
    menuitem  '&4: Low Graphics',IDM_GRAPHICS_LOW
    menuitem  '&5: Medium Graphics',IDM_GRAPHICS_MED
    menuitem  '&6: High Graphics',IDM_GRAPHICS_HI,MFR_END
    menuitem  '&Help',0,MFR_POPUP + MFR_END
    menuitem  '&readme...',IDM_HELP,MFR_END
    icon main_icon,icon_data,'image.ico'

  versioninfo  version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,'FileDescr.','ALLAIMS'
;