asm_dip/toolchain/fasmw17332/EXAMPLES/WIN64/MANDEL/MANDEL.ASM
2024-11-24 23:13:28 -05:00

320 lines
5.8 KiB
NASM

format PE64 GUI 5.0
entry start
include 'win64a.inc'
include 'ddraw64.inc'
section '.text' code readable executable
start:
sub rsp,8
and [DDraw],0
and [DDSPrimary],0
and [DDSBack],0
invoke GetModuleHandle,NULL
mov [hinstance],rax
mov [wc.hInstance],rax
invoke LoadIcon,NULL,IDI_APPLICATION
mov [wc.hIcon],rax
invoke LoadCursor,NULL,IDC_ARROW
mov [wc.hCursor],rax
invoke RegisterClassEx,wc
test rax,rax
jz startup_error
invoke CreateWindowEx,\
0,_class,_title,WS_POPUP+WS_VISIBLE,0,0,0,0,NULL,NULL,[hinstance],NULL
test rax,rax
jz startup_error
mov [hwnd],rax
invoke DirectDrawCreate,NULL,DDraw,NULL
test rax,rax
jnz ddraw_error
cominvk DDraw,SetCooperativeLevel,\
[hwnd],DDSCL_EXCLUSIVE+DDSCL_FULLSCREEN
test rax,rax
jnz ddraw_error
cominvk DDraw,SetDisplayMode,\
640,480,32
test rax,rax
jnz ddraw_error
mov [ddsd.dwSize],sizeof.DDSURFACEDESC
mov [ddsd.dwFlags],DDSD_CAPS+DDSD_BACKBUFFERCOUNT
mov [ddsd.ddsCaps.dwCaps],DDSCAPS_PRIMARYSURFACE+DDSCAPS_FLIP+DDSCAPS_COMPLEX
mov [ddsd.dwBackBufferCount],1
cominvk DDraw,CreateSurface,\
ddsd,DDSPrimary,NULL
or eax,eax
jnz ddraw_error
mov [ddscaps.dwCaps],DDSCAPS_BACKBUFFER
cominvk DDSPrimary,GetAttachedSurface,\
ddscaps,DDSBack
or eax,eax
jnz ddraw_error
refresh:
cominvk DDSPrimary,IsLost
test rax,rax
jz paint
cmp eax,DDERR_SURFACELOST
jne end_loop
cominvk DDSPrimary,Restore
paint:
mov [ddsd.dwSize],sizeof.DDSURFACEDESC
mov [ddsd.dwFlags],0
cominvk DDSBack,Lock,NULL,ddsd,DDLOCK_SURFACEMEMORYPTR+DDLOCK_WAIT,NULL
test rax,rax
jnz main_loop
mov rdi,[ddsd.lpSurface]
mov r10d,[ddsd.lPitch]
xor edx,edx
movsd xmm8,[y_top]
screen:
xor ebx,ebx
movsd xmm7,[x_left]
unpcklpd xmm7,xmm8
row:
mov rcx,255
xorpd xmm1,xmm1
iterate:
movapd xmm3,xmm1
unpckhpd xmm3,xmm3
mulsd xmm3,xmm1
addsd xmm3,xmm3
mulpd xmm1,xmm1
movapd xmm2,xmm1 ; for SSE3-capable processor
unpckhpd xmm2,xmm2 ; these three instructions can be
subsd xmm1,xmm2 ; replaced with HSUBPD XMM1,XMM1
unpcklpd xmm1,xmm3
addpd xmm1,xmm7
movapd xmm0,xmm1
mulpd xmm0,xmm0
movapd xmm2,xmm0 ; for SSE3-capable processor
shufpd xmm2,xmm2,1 ; these three instructions can be
addsd xmm0,xmm2 ; replaced with HADDPD XMM0,XMM0
sqrtpd xmm0,xmm0
comisd xmm0,[limit]
ja over
loop iterate
over:
xor al,al
stosb
mov al,cl
stosb
ror al,3
stosb
stosb
movsd xmm0,[x_step]
addpd xmm7,xmm0
inc ebx
cmp ebx,640
jb row
sub rdi,640*4
add rdi,r10
subsd xmm8,[y_step]
inc edx
cmp edx,480
jb screen
mov [refresh_needed],0
cominvk DDSBack,Unlock,NULL
cominvk DDSPrimary,Flip,0,0
main_loop:
invoke PeekMessage,msg,NULL,0,0,PM_NOREMOVE
or eax,eax
jz no_message
invoke GetMessage,msg,NULL,0,0
cmp eax,1
jb end_loop
jne no_message
invoke TranslateMessage,msg
invoke DispatchMessage,msg
cmp [refresh_needed],0
jne refresh
jmp main_loop
no_message:
invoke WaitMessage
jmp main_loop
ddraw_error:
invoke wsprintf,buffer,_ddraw_error,rax
invoke MessageBox,[hwnd],buffer,_error,MB_OK+MB_ICONERROR
invoke DestroyWindow,[hwnd]
invoke PostQuitMessage,2
jmp main_loop
startup_error:
invoke MessageBox,[hwnd],_startup_error,_error,MB_OK+MB_ICONERROR
invoke ExitProcess,1
end_loop:
cominvk DDraw,RestoreDisplayMode
cmp [DDSBack],0
je back_surface_released
cominvk DDSPrimary,DeleteAttachedSurface,0,DDSBack
back_surface_released:
cmp [DDSPrimary],0
je primary_surface_released
cominvk DDSPrimary,Release
primary_surface_released:
cmp [DDraw],0
je ddraw_released
cominvk DDraw,Release
ddraw_released:
invoke ExitProcess,[msg.wParam]
proc WindowProc uses rbx rsi rdi, hwnd,wmsg,wparam,lparam
cmp edx,WM_CREATE
je .wmcreate
cmp edx,WM_DESTROY
je .wmdestroy
cmp edx,WM_LBUTTONDOWN
je .wmlbuttondown
cmp edx,WM_RBUTTONDOWN
je .wmrbuttondown
cmp edx,WM_KEYDOWN
je .wmkeydown
cmp edx,WM_ACTIVATE
je .wmactivate
.defwindowproc:
invoke DefWindowProc,rcx,rdx,r8,r9
jmp .finish
.wmcreate:
xor eax,eax
jmp .finish
.wmactivate:
test r8,r8
jz .finish
or [refresh_needed],1
jmp .finish
.wmlbuttondown:
movapd xmm0,[step]
divpd xmm0,[zoom]
movapd xmm1,xmm0
subpd xmm1,[step]
movapd [step],xmm0
movzx eax,r9w
cvtsi2sd xmm3,eax
shr r9,16
movzx eax,r9w
cvtsi2sd xmm4,eax
unpcklpd xmm3,xmm4
mulpd xmm1,xmm3
xorpd xmm1,[negate]
addpd xmm1,[origin]
movapd [origin],xmm1
or [refresh_needed],1
jmp .finish
.wmrbuttondown:
movapd xmm0,[step]
mulpd xmm0,[zoom]
movapd xmm1,xmm0
subpd xmm1,[step]
movapd [step],xmm0
movzx eax,r9w
cvtsi2sd xmm3,eax
shr r9,16
movzx eax,r9w
cvtsi2sd xmm4,eax
unpcklpd xmm3,xmm4
mulpd xmm1,xmm3
xorpd xmm1,[negate]
addpd xmm1,[origin]
movapd [origin],xmm1
or [refresh_needed],1
jmp .finish
.wmkeydown:
cmp r8d,VK_ESCAPE
jne .finish
.wmdestroy:
invoke PostQuitMessage,0
xor eax,eax
.finish:
ret
endp
section '.data' data readable writeable
wc WNDCLASSEX sizeof.WNDCLASSEX,0,WindowProc,0,0,NULL,NULL,NULL,NULL,NULL,_class,NULL
_title db 'flat assembler DirectDraw application',0
_class db 'FDDRAW64',0
_error db 'Error',0
_startup_error db 'Startup failed',0
_ddraw_error db 'Direct Draw initialization failed (error code 0x%x).',0
align 16 ; SSE data follows
label origin dqword
x_left dq -2.2
y_top dq 1.25
label step dqword
x_step dq 0.0045
y_step dq 0.0052
label zoom dqword
dq 1.2,1.2
label negate dqword
dq 8000000000000000h,0
limit dq 2.5
section '.bss' readable writeable
hinstance dq ?
hwnd dq ?
msg MSG
ddsd DDSURFACEDESC
ddscaps DDSCAPS
DDraw DirectDraw
DDSPrimary DirectDrawSurface
DDSBack DirectDrawSurface
rect RECT
refresh_needed dd ?
buffer rb 100h
section '.idata' import data readable
library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL',\
ddraw,'DDRAW.DLL'
include 'api\kernel32.inc'
include 'api\user32.inc'
import ddraw,\
DirectDrawCreate,'DirectDrawCreate'