64-bits version of Dancing Julia
bat-filecls
set masm64_path=\masm64\
set filename=%1
del %filename%.exe
if exist %1.rc (
%masm64_path%bin\RC /r %filename%.rc || exit
%masm64_path%bin\ml64 /Cp /c /I"%masm64_path%Include" %filename%.asm || exit
%masm64_path%bin\link /SUBSYSTEM:WINDOWS /LIBPATH:"%masm64_path%Lib" ^
/entry:WinMain %filename%.obj %filename%.res /LARGEADDRESSAWARE:NO ^
/ALIGN:16 /SECTION:.text,W ^
/BASE:0x400000 /STUB:%masm64_path%\bin\stubby.exe || exit
del %filename%.res
) else (
%masm64_path%bin\ml64 /Cp /c /I"%masm64_path%Include" %filename%.asm || exit
%masm64_path%bin\link /SUBSYSTEM:WINDOWS /LIBPATH:"%masm64_path%Lib" ^
/entry:WinMain %filename%.obj /LARGEADDRESSAWARE:NO ^
/ALIGN:16 /SECTION:.text,W ^
/BASE:0x400000 /STUB:%masm64_path%\bin\stubby.exe || exit
)
del %filename%.obj
asm-fileinclude win64a.inc
include gdi32.inc
IMAGE_BASE equ 400000h
cdXPos equ 128
cdYPos equ 6
cdYSize equ 600
cdXSize equ 800
cdYMSize equ cdYSize/2
cdIdTimer equ 1
cdScrSize equ cdXSize*cdYSize
MAXITER equ 20
.code
WndProc proc hWnd:QWORD, uMsg:QWORD, wParam:QWORD, lParam:QWORD
local hdc:qword
local hOldBmp:qword
local szBuffer[100]:byte
local ps:PAINTSTRUCT
local hOldDIB:qword
local hBackDC:qword
local bufBMP:qword
push rbp
mov ebp,esp
sub esp,(50h+sizeof PAINTSTRUCT+8*6+100+15)and(-16)
mov hWnd,rcx
cmp edx,WM_CREATE
jz wmCREATE
cmp edx,WM_DESTROY
jz wmDESTROY
cmp edx,WM_PAINT
jz wmPAINT
cmp edx,WM_TIMER
jz wmTIMER
leave
jmp DefWindowProc
wmDESTROY::mov rdx,hOldBmp
mov rcx,hBackDC
call SelectObject
mov rcx,bufBMP
call DeleteObject
mov rcx,hBackDC
call DeleteDC
mov rdx,hOldDIB
mov rcx,bufDIBDC
call SelectObject
mov rcx,bufDIBDC
call DeleteDC
mov rcx,hMainDIB
call DeleteObject
mov rcx,hWnd
call DestroyWindow
xor ecx,ecx ; nExitCode
call ExitProcess
wmCREATE:mov rcx,hWnd
call GetDC
mov hdc,rax
mov rcx,rax ; HDC
call CreateCompatibleDC
mov bufDIBDC,rax
mov [rsp+28h],rbx
mov [rsp+20h],rbx
mov r9d,offset pMainDIB
mov r8d,DIB_RGB_COLORS
mov edx,offset bi
mov rcx,hdc
call CreateDIBSection
mov hMainDIB,rax
mov rdx,rax; hMainDIB
mov rcx,bufDIBDC
call SelectObject
mov rax,hOldDIB
mov rdx,hdc
mov rcx,hWnd
call ReleaseDC; // Libera device context
;Indicia-------------------------------------------------
mov eax,cdXSize-1
fld xmax
@@: fst Lx[rax*8]
fsub deltax
dec eax
jns @b
fstp st
mov eax,cdYSize-1
fld ymax
@@: fst Ly[rax*8]
fsub deltay
dec eax
jns @b
;-----------------------------------------------------
call GetTickCount
mov s_time,rax
xor r9,r9
mov r8d,20
mov rdx,cdIdTimer
mov rcx,hWnd
call SetTimer
jmp wmBYE
wmTIMER:call doJulia
inc fps; fps = fps + 1
call GetTickCount
sub rax, s_time
mov ecx, 1000
xor edx, edx
div ecx
cmp eax,1 ;if ((GetTickCount() - s_time)/1000 > 1.0) {
jbe @f
call GetTickCount
mov s_time, rax ;s_time = GetTickCount()
mov r8d,fps
mov edx,offset szTitleFPS
lea ecx,szBuffer
call wsprintf ;wsprintf (szBuffer, szTitleFPS, fps)
lea edx,szBuffer
mov rcx,hWnd
call SetWindowText
mov fps,0
@@: xor r8d,r8d ;FALSE
xor edx,edx ;NULL
mov rcx, hWnd
call InvalidateRect
jmp wmBYE
wmPAINT:lea edx,ps
call BeginPaint
mov hdc,rax
mov qword ptr [rsp+40h],SRCCOPY; rop
xor edx,edx ; x
mov [rsp+38h],rdx ; y1
mov [rsp+30h],rdx ; x1
mov rax,bufDIBDC ; hdcSrc
mov [rsp+28h],rax
mov rax,cdYSize
mov [rsp+20h],rax
mov r9,cdXSize ; cx
xor r8d,r8d ; cy
mov rcx,hdc ; hdc
call BitBlt
lea edx,ps
mov rcx,hWnd
call EndPaint
wmBYE: leave
ret
WndProc endp
WinMain proc
local msg:MSG
push rbp
mov ebp, esp
sub esp,sizeof MSG
xor ebx,ebx
mov esi,IMAGE_BASE
mov edi,offset ClassName
push rbx ;hIconSm
push rdi ;lpszClassName
push rbx ;lpszMenuName
push COLOR_WINDOWTEXT; hbrBackground
push rbx ;hCursor
push rbx ;hIcon
push rsi ;hInstance
push rbx ;cbClsExtra & cbWndExtra
db 68h
dd WndProc ;lpfnWndProc
push sizeof WNDCLASSEX ;cbSize & style
mov ecx,esp ;addr WNDCLASSEX
call RegisterClassEx
push rbx
push rsi ;rsi=400000h
push rbx
push rbx
push cdYSize
push cdXSize
push cdYPos
push cdXPos
mov r9d,WS_VISIBLE
mov r8,rdi ;offset ClassName
mov edx,edi ;offset ClassName
xor ecx,ecx
sub esp,20h ; dwExStyle
call CreateWindowEx
@@: lea ecx,msg
xor edx,edx
xor r8d,r8d
xor r9d,r9d
call GetMessage
cmp msg.wParam,VK_ESCAPE;user press 'Esc'?
je wmDESTROY
lea ecx,msg
call DispatchMessage
jmp @b
WinMain endp
doJulia proc
local i:dword
local red:dword
local green:dword
local blu:dword
local tmp:dword
local px:dword
local py:dword
local i_last:dword
local ztoti:dword
local p:dword
local q:dword
local theta:dword
local x:dword
local y:dword
local xsquare:dword
local ysquare:dword
local ytemp:dword
local ty:dword
local cmagsq:dword
local zmag:dword
local drad_L:dword
local drad_H:dword
local ztot:dword
push rbp
mov ebp, esp
sub esp,(4*23+15)and(-16)
finit
inc frames
and frames, 7FFFFFFFh
fild frames ;frames = (frames + 1) & 0x7fffffff
fmul Pi180
fst theta ;theta = frames * Pi180
fcos ;st(0)=cos(theta)
fld const0_7
fmul theta ;st(0)=theta*0.7 st(1)=cos(theta)
fsin ;st(0)=sin(theta*0.7) st(1)=cos(theta)
fmulp st(1),st ;st(0)=sin(theta*0.7) * cos(theta)
fmul const0_6
fst p ;p=sin(theta*0.7) * cos(theta)*0.6
fmul st,st ;st(0)=p*p
fld theta
fsin
fmul const1_2 ;q = (sin(theta) + sin(theta)) * .6
fst q
fmul st,st ;st(0)=q*q
faddp st(1),st
fst cmagsq ;cmagsq = (p *p + q* q)
fsqrt ;cmag = sqrt(cmagsq)
fld st
fsub drad
fmul st,st
fstp drad_L ;drad_L = (cmag - drad)*(cmag - drad)
fadd drad
fmul st,st
fstp drad_H ;drad_H = (cmag + drad)*(cmag + drad)
mov pIniDib,0 ;pIniDib = 0
mov pFinDib,cdScrSize-1
mov py, 0
@@: mov eax, py
fld Ly[rax*8]
fstp ty ;ty = Ly[py]
mov px, 0
a0: mov eax, px
cmp eax, cdXSize
jb @f
inc py
jmp @b
@@: mov eax, px
fld Lx[rax*8]
fstp x ;x = Lx[px]
fld ty
fstp y
fldz
fst ysquare ;xsquare = ysquare = ztot = 0
fst xsquare
fstp ztot
mov i,ebx ;i = 0
a1: mov eax, i
fld xsquare
fadd ysquare
fld const4 ;(xsquare + ysquare) < MAXSIZE
fucomip st,st(1)
fstp st
jb a2
fld x
fmul st,st
fstp xsquare ;xsquare = x * x
fld y
fmul st,st
fstp ysquare ;ysquare = y * y
fld x
fmul y
fadd st,st
fstp ytemp ;ytemp = x * y * 2
fld xsquare
fsub ysquare
fadd p
fst x ;x = xsquare - ysquare + p
fmul st,st ;st(0)=x*x
fld ytemp
fadd q
fst y ;y = ytemp + q
fmul st,st ;st(0)=y*y st(1)=x*x
faddp st(1),st ;zmag = (x * x + y * y)
fst zmag ;if ( (zmag < drad_H) && (zmag > drad_L) && (i > 0) ) {
fld drad_H
fucomip st,st(1)
fstp st
jb @f
fld drad_L
fld zmag
fucomip st,st(1)
fstp st
jb @f
cmp i, 0
jle @f
fld zmag
fsub cmagsq
fabs
fdiv drad
fld1
fsubrp st(1),st
fadd ztot
fstp ztot ;ztot = ztot + ( 1 - (miAbs(zmag - cmagsq) / drad))
mov eax, i
mov i_last, eax
@@: fld const4
fld zmag
fucomip st,st(1)
fstp st
jnb a2
inc i
cmp i,20
jb a1
a2: mov i, 0
fld ztot
ftst
fnstsw ax
test ah, 45h
jnz @f
fsqrt
fmul const500
fist i ;i = (int)(sqrt(ztot) * 500)
@@: fstp st
mov red, 255
mov eax, i
cmp eax, 256
jae @f
mov red, eax
@@: cmp eax, 512
jae @f
cmp eax, 255
jbe @f
sub eax, 256
mov green, eax
jmp a3
@@: mov green, ebx ;green=0
cmp eax, 512
jb a3
mov green, 255
a3: mov eax, i
cmp eax, 768
ja @f
cmp eax, 511
jbe @f
sub eax, 512
mov blu, eax
jmp a4
@@: mov blu,ebx ; blu=0
cmp i, 768
jl a4
mov blu, 255
a4: mov eax, red
add eax, green
add eax, blu
mov ecx, 3
cdq
idiv ecx
mov tmp, eax
mov eax, red
add eax, green
add eax, tmp
cdq
idiv ecx
mov red, eax
mov eax, green
add eax, blu
add eax, tmp
cdq
idiv ecx
mov green, eax
mov eax, blu
add eax, red
add eax, tmp
cdq
idiv ecx
mov blu, eax
mov eax, i_last ;switch (i_last & 3)
and eax, 3
jp break ;i_last=0 or i_last=3 ?
cmp eax, 1
jnz @f
mov eax, red ;case 1:
mov tmp, eax ;tmp = red
mov eax, green
mov red, eax ;red = grn
mov eax, blu
mov green, eax ;grn = blu
mov eax, tmp
mov blu, eax ;blu = tmp
jmp break
@@: mov eax, red ;case 2:
mov tmp, eax ;tmp = red
mov eax, green
mov blu, eax ;blu = green
mov eax, blu
mov red, eax ;red = blu
mov eax, tmp
mov green, eax ;green = tmp
break: mov rcx, pIniDib
mov rdx, pMainDIB
mov eax, red
shl eax, 8
or eax, green
shl eax, 8
or eax, blu
mov [rdx+rcx*4], eax
mov rcx, pFinDib
mov [rdx+rcx*4], eax;*(pMainDIB + pIniDib) = *(pMainDIB + pFinDib) = (red << 16) | (grn << 8) | blu
inc pIniDib ;pIniDib++
dec pFinDib ;pFinDib--
inc px
cmp py,cdYMSize
jl a0
leave
retn
doJulia endp
;-------------------------------------------------------------------------
.data
ClassName db 'Dancing Julia [Greetings: Lopesoft] - (c) abreojosensamblador.net',0
bi BITMAPINFOHEADER <sizeof BITMAPINFOHEADER,cdXSize,-cdYSize,1,32,>
szTitleFPS db 'Dancing Julia [Greetings: Lopesoft] [fps:%i] - (c) abreojosensamblador.net',0
xmin dq -2.0
xmax dq 2.0
ymin dq -1.5
ymax dq 1.5
deltax dq 0.00500625782227784730913642052;56571
deltay dq 0.00500834724540901502504173622;70451
Pi180 dq 0.01745329251994329576923690768;489
const0_7 dd 0.7
const0_6 dd 0.6
const1_2 dd 1.2
const799 dq 799.0
const599 dq 599.0
const4 dq 4.0
const500 dq 500.0
drad dd 0.04
.data?
bufDIBDC dq ?
pMainDIB dq ?
hMainDIB dq ?
s_time dq ?
pIniDib dq ?
pFinDib dq ?
Lx dq cdXSize dup (?)
Ly dq cdYSize dup (?)
frames dd ?
fps dd ?
end
Source- and exe-files in attachment