;Copyright (C) 2002 Paul Furber ; ;$Id: fire256.asm,v 1.8 2006/02/09 07:47:05 konst Exp $ ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; Updated version 12-2002 Paul Furber ;; * Much better palette - I'm surprised I didn't get more emails ;; saying the first one sucked so badly :) ;; * the average fps is displayed at the end - my Ghz PIII notebook running ;; a geForce 2 Go! gets 600+ fps with the kernel's VESA driver ;; TODO: Restore the colour map on exit ;; Convert my 50 fps mandel zoomer in time for the next asmutils %include "system.inc" CPU 586 %assign SIZE_X 640 %assign SIZE_Y 480 %assign BPP 8 %assign VMEM_SIZE SIZE_X*SIZE_Y*BPP/8 %assign FRAMES 1000 CODESEG ALIGN 16 START: mov edi, VMEM_SIZE mov ebp, Params lea ebx, [ebp] ;fb-Params sys_open EMPTY, O_RDWR ; open the framebuffer device test eax, eax ;have we opened file? js near my_exit ;; get the fixed screen info mov [fd], eax ; save our file descriptor mov ebp, fix_label lea ebx, [ebp] ; point ebx to fix sys_ioctl eax, FBIOGET_FSCREENINFO, ebp; from the kernel source test eax, eax ; did we get the screen info? js near my_exit ;; get the variable screen info mov eax, [fd] ; get our file descriptor mov ebp, var_label lea ebx, [ebp] ; point ebx to var sys_ioctl eax, FBIOGET_VSCREENINFO, ebp test eax, eax ; did we get the screen info? js near my_exit ;; memory map the screen mem mov eax, [fd] ; get saved fd mov ecx, VMEM_SIZE sys_mmap 0,EMPTY,PROT_READ|PROT_WRITE,MAP_SHARED,eax,0 test eax, eax ;have we mmaped it? js near my_exit ; argh mov [fix.mmio_start],eax ; save this mov [fix.mmio_len], edi ; and this ;; we want to change to this mode mov [var.xres], dword SIZE_X mov [var.yres], dword SIZE_Y mov [var.xres_virtual], dword SIZE_X mov [var.yres_virtual], dword SIZE_Y ; only one page mov [var.bits_per_pixel], dword BPP ;; set the variable screen info mov eax, [fd] ; get our file descriptor mov ebp, var_label lea ebx, [ebp] ; point ebx to var sys_ioctl eax, FBIOPUT_VSCREENINFO, ebp; set mode to our new parms test eax, eax ; did we set the screen info? js near my_exit ; nope :( mov [cmap.start], dword 0 mov [cmap.len], dword 256 lea eax, [r_val_label] mov [cmap.r_ptr], eax lea eax, [g_val_label] mov [cmap.g_ptr], eax lea eax, [b_val_label] mov [cmap.b_ptr], eax mov [cmap.t_ptr], dword 0 mov eax, [fd] mov ebp, cmap_label lea ebx, [ebp] sys_ioctl eax, FBIOGETCMAP, ebp; grab the colour map and ;; save the values test eax, eax ; did we get the colour map? js near my_exit ; nope - bomb ;; point cmap to our new colour map values lea eax, [r_val_label] mov [cmap.r_ptr], eax lea eax, [g_val_label] mov [cmap.g_ptr], eax lea eax, [b_val_label] mov [cmap.b_ptr], eax ;------------------------------------------------------------------------- ; set the palette ;------------------------------------------------------------------------- mov esi, [cmap.r_ptr] mov edi, [cmap.g_ptr] mov ebx, [cmap.b_ptr] xor ebp, ebp xor edx, edx mov ecx, edx .wloop1: mov eax, ecx shl eax, 8 ; colourmap values need to be shifted mov [esi], ax ; fade black to red mov [edi], dx ; 0 in g component mov [ebx], dx ; 0 in b component mov [esi+64*2],word 63<<8 ; fade red to yellow mov [edi+64*2],ax ; bring in the green component mov [ebx+64*2],dx ; 0 in b component mov [esi+128*2],word 63<<8 ; yellow->white mov [edi+128*2],word 63<<8 ; yellow = r+g add ax, ax ; funky blue hot effect mov [ebx+128*2],ax ; start fading it in mov [esi+192*2],word 63<<8 ; mov [edi+192*2],word 63<<8 ; mov [ebx+192*2],word 63<<8 ; add esi, 2 add edi, 2 add ebx, 2 inc ecx cmp ecx, 64 jnz .wloop1 mov eax, [fd] mov ebp, cmap_label lea ebx, [ebp] sys_ioctl eax, FBIOPUTCMAP, ebp; set the new colour map test eax, eax ; did we set the colour map? js near my_exit ; nope - bomb mov eax, 0x08088405 mov [randfactor], eax mov eax, 0x1234567 mov [randseed], eax sys_gettimeofday start_time,NULL; start measuring mov ecx, FRAMES mainloop: push ecx ;------------------------------------------------------------------------- ; seed the bottom ;------------------------------------------------------------------------- lea esi, [screen_buffer] push esi add esi, SIZE_X*(SIZE_Y-1) mov ecx, SIZE_X/4 ;------------------------------------------------------------------------- ; random routine courtesy of LSD a.k.a Mark Webster - thanks! .randloop: mov eax, [randseed] mul dword [randfactor] inc eax mov [randseed],eax mov [esi], eax add esi, 4 dec ecx jnz .randloop ;------------------------------------------------------------------------- ; do the fire ;------------------------------------------------------------------------- pop esi ; esi points to screen buffer mov edi, [fix.mmio_start] ; mmaped mem mov ecx, SIZE_X*(SIZE_Y-1)/8 ; no of pixels to do movq mm7, [shr1mask] movq mm6, [sub_value] .fireloop: movq mm0, [esi+(SIZE_X)] paddusb mm0, [esi+(SIZE_X*2)-1] paddusb mm0, [esi+(SIZE_X*2)] paddusb mm0, [esi+(SIZE_X*2)+1] movq [edi], mm0 mov ebp, ecx and ebp, 3 jnz .skip_subtract psubusb mm0, mm6 .skip_subtract: psrlq mm0, 2 pand mm0, mm7 movq [esi], mm0 add esi, 8 add edi, 8 dec ecx jnz .fireloop ;------------------------------------------------------------------------- pop ecx dec ecx jnz near mainloop ;------------------------------------------------------------------------- sys_gettimeofday end_time,NULL mov eax, [end_time.tv_sec] sub eax, [start_time.tv_sec] mov ecx, 1000 mul ecx mov ebx, eax xor edx, edx mov eax, [end_time.tv_usec] sub eax, [start_time.tv_usec] cdq idiv ecx add eax, ebx ; eax now has milliseconds elapsed ;------------------------------------------------------------------------- mov ebx, eax mov eax, FRAMES*1000 xor edx, edx div ebx lea ecx, [dummy] call write_num sys_write STDOUT,nl,1 ;------------------------------------------------------------------------- emms xor ebx, ebx ; no error sys_exit my_exit: mov ebx, eax sys_exit ;------------------------------------------------------------------------- write_num: pushad xor ebx, ebx push ebx ; length counter mov bl, 10 ; radix .l: dec ecx ; point ecx at the output buffer inc dword [esp] xor edx, edx div ebx or dl, '0' mov [ecx], dl test eax, eax jnz .l pop edx ; count syswrite: sys_write STDOUT popad ret ;------------------------------------------------------------------------- nl db __n ALIGN 16 shr1mask dd 3f3f3f3fh,3f3f3f3fh sub_value dd 00010101h, 00000100h Params: fb db "/dev/fb0",EOL ;------------------------------------------------------------------------- UDATASEG ALIGN 4, resb 1 screen_buffer: U8 SIZE_X*SIZE_Y ; off screen buffer fix_label: fix I_STRUC fb_fix .id CHAR 16 .smem_start ULONG 1 .smem_len U32 1 .type U32 1 .type_aux U32 1 .visual U32 1 .xpanstep U16 1 .ypanstep U16 1 .ywrapstep U16 1 .line_length U32 1 .mmio_start ULONG 1 .mmio_len U32 1 .accel U32 1 .reserved U16 3 I_END var_label: var I_STRUC fb_var .xres U32 1 .yres U32 1 .xres_virtual U32 1 .yres_virtual U32 1 .xoffset U32 1 .yoffset U32 1 .bits_per_pixel U32 1 .grayscale U32 1 .red_offset U32 1 .red_length U32 1 .red_msb_right U32 1 .green_offset U32 1 .green_length U32 1 .green_msb_right U32 1 .blue_offset U32 1 .blue_length U32 1 .blue_msb_right U32 1 .transp_offset U32 1 .transp_length U32 1 .transp_msb_right U32 1 .nonstd U32 1 .activate U32 1 .height U32 1 .width U32 1 .accel_flags U32 1 .pixclock U32 1 .left_margin U32 1 .right_margin U32 1 .upper_margin U32 1 .lower_margin U32 1 .hsync_len U32 1 .vsync_len U32 1 .sync U32 1 .vmode U32 1 .reserved U32 6 I_END cmap_label: cmap I_STRUC fb_cmap .start U32 1 .len U32 1 .r_ptr U32 1 .g_ptr U32 1 .b_ptr U32 1 .t_ptr U32 1 I_END r_val_label: r_vals U16 256 g_val_label: g_vals U16 256 b_val_label: b_vals U16 256 start_time I_STRUC timeval .tv_sec ULONG 1 .tv_usec ULONG 1 I_END end_time I_STRUC timeval .tv_sec ULONG 1 .tv_usec ULONG 1 I_END fd UINT 1 randfactor U32 1 randseed U32 1 outbuf: resd 3 ; 12 digits for time display dummy: resd 2 ; END