; vi:filetype=nasm ts=8 sts=8 sw=8: ; ; list of functions ; ----------------- ; init_gfx ; initializes the video hardware and graphics routines ; clear ; clears the framebuffer (not vmem) ; clobbers: ax, cx, di ; swap_buffers ; copies the framebuffer to video memory ; clobbers: ax, cx, di, si ; wait_vsync ; clobbers: al, dx ; set_palette_entry(idx[al], r[ah], g[bl], b[bh]) ; colors are 0-255 VIDMEM_SEG equ 0a000h FRAMEBUF_SEG equ 09000h REG_CRTC_STATUS equ 3dah CRTC_VBLANK_BIT equ 08h REG_DAC_ADDR equ 3c8h REG_DAC_DATA equ 3c9h init_gfx: ; video mode 13h (320x200 8bpp) mov ax, 13h int 10h call clear ; setup the spritesheet palette mov si, sprsheet_cmap xor cl, cl .cmaploop: mov al, cl mov ah, [si] mov bl, [si + 1] mov bh, [si + 2] add si, 3 call set_palette_entry dec cl jnz .cmaploop ret clear: push es mov ax, FRAMEBUF_SEG mov es, ax xor di, di xor ax, ax mov cx, 16000 rep stosd pop es ret swap_buffers: push ds push es mov ax, FRAMEBUF_SEG mov ds, ax xor si, si mov ax, VIDMEM_SEG mov es, ax xor di, di mov cx, 16000 rep movsd pop es pop ds ret wait_vsync: mov dx, REG_CRTC_STATUS .wait_vblank_end: in al, dx and al, CRTC_VBLANK_BIT jnz .wait_vblank_end .wait_vblank_start: in al, dx and al, CRTC_VBLANK_BIT jz .wait_vblank_start ret set_palette_entry: push dx mov dx, REG_DAC_ADDR out dx, al inc dx ; dx <- REG_DAC_DATA mov al, ah shr al, 2 out dx, al mov al, bl shr al, 2 out dx, al mov al, bh shr al, 2 out dx, al pop dx ret ; slow_sprite(short id, short x, short y) ; assumptions: 32x32, one after the other, 0 is transparent ; XXX sprsheet needs to go to its own segment slow_sprite: push bp mov bp, sp pusha mov ax, FRAMEBUF_SEG mov es, ax mov ax, [bp + 8] ; ax <- y sub ax, 16 ; ax <- y - 16 (center sprite vertically) mov bx, ax shl ax, 8 shl bx, 6 add ax, bx ; ax <- (y - 16) * 320 mov di, [bp + 6] ; di <- x sub di, 16 ; di <- x - 16 (center sprite horizontally) add di, ax ; di <- (y - 16) * 320 + (x - 16) mov si, sprsheet_tiles ; calculate sprite id offset (each spr is 32*32=1k) mov ax, [bp + 4] shl ax, 10 add si, ax mov cx, 32 .yloop: xor bx, bx .xloop: mov al, [si] cmp al, 0 ;jz .skip_pixel mov [es:di + bx], al .skip_pixel: inc si inc bx cmp bx, 32 jnz .xloop add di, 320 dec cx jnz .yloop popa pop bp ret