This is a short explanation, how you can use the linux frame buffer device in assembler language. Not all of my suggestions/tips written here are realized in the example code below (clearing screen, terminal locking, disabling cursor and blanking ...), but i think after reading them you should be able to implement them yourself. If you find mistakes or have suggestions, mail me: karsten.scheibler@bigfoot.de
NOTE: Nearly all of the %assign's and struc's listed here can be found in the kernel source in C syntax.
short procedure:
If you use color depths <= 8 bpp you have to set a color palette in order to see that what you draw (default: first 16 colors are set to the normal terminal ANSI colors, the rest should be black). Linux uses 16 bit for every color component (red, green, blue, transparent).
Suggestions/Tips:
;these are 2 escape sequences see ;man console_codes for more mov dword eax, SYS_WRITE mov dword ebx, STDOUT mov dword ecx, clear_screen mov dword edx, 10 int byte 080h clear_screen: db 01bh, "[1;1H", 01bh, "[2J"
db 01bh, "[9;0]"
db 01bh, "[?25l"
%assign TIOCLINUX 0541ch push dword 12 mov dword eax, SYS_IOCTL mov dword ebx, STDIN mov dword ecx, TIOCLINUX mov dword edx, esp int byte 080h add dword esp, 4 test dword eax, eax js not_on_local_console
%assign SYS_SOCKETCALL 102 %assign SOCK_STREAM 1 %assign AF_UNIX 1 %assign SYS_SOCKET 1 %assign SYS_CONNECT 3 struc tsockaddrun tsockaddrun_family: resw 1 tsockaddrun_path: resb 108 endstruc push dword 0 push dword SOCK_STREAM push dword AF_UNIX mov dword eax, SYS_SOCKETCALL mov dword ebx, SYS_SOCKET mov dword ecx, esp int byte 080h add dword esp, 12 test dword eax, eax js .error push dword tsockaddrun_size push dword gpm_data push dword eax mov dword eax, SYS_SOCKETCALL mov dword ebx, SYS_CONNECT mov dword ecx, esp int byte 080h add dword esp, 12 .error: section .data gpm_data: istruc tsockaddrun at tsockaddrun_familiy, dw AF_UNIX at tsockaddrun_path, db "/dev/gpmctl", 0 iend
%assign VT_GETMODE 05601h %assign VT_SETMODE 05602h %assign VT_PROCESS 1 section .text struc tvtmode alignb 4 tvtmode_mode: resb 1 tvtmode_waitv: resb 1 tvtmode_relsig: resb 1 tvtmode_acqsig: resb 1 tvtmode_frsig: resb 1 endstruc ;perhaps it is better to open /dev/tty and ;and use this file handle instead of STDIN mov dword eax, SYS_IOCTL mov dword ebx, STDIN mov dword ecx, VT_GETMODE mov dword edx, vtmode_data int byte 080h mov byte [vtmode_data + tvtmode_mode], VT_PROCESS mov dword eax, SYS_IOCTL mov dword ebx, STDIN mov dword ecx, VT_SETMODE mov dword edx, vtmode_data int byte 080h section .data vtmode_data: istruc tvtmode iend
-[sample Makefile for this code]--------------------------------------------- NASM=nasm -w+orphan-labels -f elf STRIP=strip -R .note -R .comment LD=ld -s RM=rm -f .PHONY: all clean all: fb fb: fb.nasm ${NASM} fb.nasm ${LD} -e fb_start -o fb fb.o ${STRIP} fb clean: ${RM} *.bak *~ fb fb.o core -----------------------------------------------------------------------------
;**************************************************************************** ;**************************************************************************** ;* ;* USING LINUX FRAME BUFFER DEVICE ;* ;* written by Karsten Scheibler, 2000-JUL-24 ;* ;**************************************************************************** ;**************************************************************************** ;you have to specify this as entry point to the linker, as done above in the ;Makefile global fb_start ;**************************************************************************** ;* some assign's ************************************************************ ;**************************************************************************** %assign SYS_EXIT 1 %assign SYS_READ 3 %assign SYS_WRITE 4 %assign SYS_OPEN 5 %assign SYS_IOCTL 54 %assign SYS_FCNTL 55 %assign SYS_MMAP 90 %assign PROT_READ 1 %assign PROT_WRITE 2 %assign MAP_SHARED 1 %assign STDIN 0 %assign STDERR 2 %assign O_RDWR 000002q %assign FBIOGET_VSCREENINFO 04600h %assign FBIOPUT_VSCREENINFO 04601h %assign FBIOGETCMAP 04604h %assign FBIOPUTCMAP 04605h struc tcmap alignb 4 tcmap_offset: resd 1 tcmap_length: resd 1 tcmap_red: resd 1 tcmap_green: resd 1 tcmap_blue: resd 1 tcmap_transparent: resd 1 endstruc struc tscreen alignb 4 tscreen_x_resolution: resd 1 tscreen_y_resolution: resd 1 tscreen_virtual_x_resolution: resd 1 tscreen_virtual_y_resolution: resd 1 tscreen_x_offset: resd 1 tscreen_y_offset: resd 1 tscreen_bits_per_pixel: resd 1 tscreen_grayscale: resd 1 tscreen_red_offset: resd 1 tscreen_red_length: resd 1 tscreen_red_msb_right: resd 1 tscreen_green_offset: resd 1 tscreen_green_length: resd 1 tscreen_green_msb_right: resd 1 tscreen_blue_offset: resd 1 tscreen_blue_length: resd 1 tscreen_blue_msb_right: resd 1 tscreen_transparent_offset: resd 1 tscreen_transparent_length: resd 1 tscreen_transparent_msb_right: resd 1 tscreen_non_standard_format: resd 1 tscreen_activate: resd 1 tscreen_height: resd 1 tscreen_width: resd 1 tscreen_acceleration_flags: resd 1 tscreen_pixel_clock: resd 1 tscreen_left_margin: resd 1 tscreen_right_margin: resd 1 tscreen_upper_margin: resd 1 tscreen_lower_margin: resd 1 tscreen_hsync_length: resd 1 tscreen_vsync_length: resd 1 tscreen_sync: resd 1 tscreen_vmode: resd 1 tscreen_reserved: resd 6 endstruc %assign FB_SCREENINFO_SAVED 001h %assign FB_COLORMAP_SAVED 002h section .data align 4 fb_flags: dd 0 fb_handle: dd 0 fb_address: dd 0 screeninfo_saved: istruc tscreen iend screeninfo_data: istruc tscreen iend colormap_saved: istruc tcmap at tcmap_offset, dd 0 at tcmap_length, dd 010h at tcmap_red, dd red_saved at tcmap_green, dd green_saved at tcmap_blue, dd blue_saved at tcmap_transparent, dd transparent_saved iend colormap_data: istruc tcmap at tcmap_offset, dd 0 at tcmap_length, dd 010h at tcmap_red, dd grey_scale at tcmap_green, dd grey_scale at tcmap_blue, dd grey_scale at tcmap_transparent, dd transparent_saved iend ;remember: 16 bit components grey_scale: dw 00000h, 01000h, 02000h, 03000h dw 04000h, 05000h, 06000h, 07000h dw 08000h, 09000h, 0a000h, 0b000h dw 0c000h, 0d000h, 0e000h, 0f000h section .bss align 4 red_saved: resw 010h green_saved: resw 010h blue_saved: resw 010h transparent_saved: resw 010h ;**************************************************************************** ;* initialization ********************************************************** ;**************************************************************************** section .text fb_start: ;open mov dword eax, SYS_OPEN mov dword ebx, .device mov dword ecx, O_RDWR int byte 080h test dword eax, eax js near fb_error mov dword [fb_handle], eax mov dword [mmap_data.file_handle], eax ;get screen parameters mov dword ebx, eax mov dword eax, SYS_IOCTL mov dword ecx, FBIOGET_VSCREENINFO mov dword edx, screeninfo_saved int byte 080h test dword eax, eax js near fb_error xor dword eax, eax mov dword [screeninfo_saved + tscreen_x_offset], eax mov dword [screeninfo_saved + tscreen_y_offset], eax mov dword esi, screeninfo_saved mov dword edi, screeninfo_data mov dword ecx, (tscreen_size / 4) cld rep movsd or dword [fb_flags], FB_SCREENINFO_SAVED ;get actual colormap mov dword eax, SYS_IOCTL mov dword ebx, [fb_handle] mov dword ecx, FBIOGETCMAP mov dword edx, colormap_saved int byte 080h test dword eax, eax js .no_colormap_saved or dword [fb_flags], FB_COLORMAP_SAVED .no_colormap_saved: ;set screen parameters mov dword eax, [screeninfo_data + tscreen_x_resolution] mov dword ebx, [screeninfo_data + tscreen_y_resolution] mov dword ecx, 8 mov dword [screeninfo_data + tscreen_virtual_x_resolution], eax mov dword [screeninfo_data + tscreen_virtual_y_resolution], ebx mov dword [screeninfo_data + tscreen_bits_per_pixel], ecx mov dword eax, SYS_IOCTL mov dword ebx, [fb_handle] mov dword ecx, FBIOPUT_VSCREENINFO mov dword edx, screeninfo_data int byte 080h test dword eax, eax js near fb_error cmp dword [screeninfo_data + tscreen_bits_per_pixel], 8 jne near fb_error ;set colormap mov dword eax, SYS_IOCTL mov dword ebx, [fb_handle] mov dword ecx, FBIOPUTCMAP mov dword edx, colormap_data int byte 080h ;mmap mov dword eax, [screeninfo_data + tscreen_y_resolution] mul dword [screeninfo_data + tscreen_virtual_x_resolution] mov dword [mmap_data.length], eax mov dword eax, SYS_MMAP mov dword ebx, mmap_data int byte 080h test dword eax, eax js near fb_error mov dword [fb_address], eax ;draw something mov dword edi, [fb_address] mov dword ebp, [screeninfo_data + tscreen_virtual_x_resolution] xor dword eax, eax xor dword ebx, ebx mov byte bl, 0feh .draw_line: xor dword ecx, ecx mov byte cl, 0feh .draw_pixel: mov byte [edi + ecx], al inc dword eax and byte al, 00fh dec dword ecx jnz .draw_pixel add dword edi, ebp dec dword ebx jnz .draw_line ;"press enter to continue ..." sub dword esp, 00100h mov dword eax, SYS_READ mov dword ebx, STDIN mov dword ecx, esp mov dword edx, 00100h int byte 080h jmp fb_end .device: db "/dev/fb0", 0 section .data align 4 mmap_data: .start: dd 0 .length: dd 0 .protection: dd (PROT_READ | PROT_WRITE) .flags: dd MAP_SHARED .file_handle: dd 0 .offset: dd 0 ;**************************************************************************** ;* restore old values ******************************************************* ;**************************************************************************** section .text fb_restore: test dword [fb_flags], FB_SCREENINFO_SAVED jz .skip_screeninfo mov dword eax, SYS_IOCTL mov dword ebx, [fb_handle] mov dword ecx, FBIOPUT_VSCREENINFO mov dword edx, screeninfo_saved int byte 080h .skip_screeninfo: test dword [fb_flags], FB_COLORMAP_SAVED jz .skip_colormap mov dword eax, SYS_IOCTL mov dword ebx, [fb_handle] mov dword ecx, FBIOPUTCMAP mov dword edx, colormap_saved int byte 080h .skip_colormap: ret ;**************************************************************************** ;* error handler ************************************************************ ;**************************************************************************** section .text fb_error: call fb_restore mov dword eax, SYS_WRITE mov dword ebx, STDERR mov dword ecx, .text mov dword edx, .text_length int byte 080h jmp fb_end .text: db "something went wrong!", 10 .text_length equ $ - .text ;**************************************************************************** ;* end ********************************************************************** ;**************************************************************************** section .text fb_end: call fb_restore xor dword eax, eax mov dword ebx, eax inc dword eax int byte 080h ;********************************************* karsten.scheibler@bigfoot.de *