/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/cirrus/cir_alloc.c,v 3.2 1994/09/11 11:15:25 dawes Exp $ */ /* * cir_alloc.c,v 1.2 1994/09/11 05:52:49 scooper Exp * * Copyright 1993 by H. Hanemaayer, Utrecht, The Netherlands * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of H. Hanemaayer not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. H. Hanemaayer makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * * H. HANEMAAYER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL H. HANEMAAYER BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Author: H. Hanemaayer, * Modified: Simon P. Cooper * */ /* * This file implements functions a simple allocator of video memory for * scratch space, patterns etc. * * The allocator can currently only free the last request. More advanced * functionality can be added when it is actually required. */ #include "vga256.h" #include "cfbrrop.h" #include "mergerop.h" #include "vgaBank.h" #include "xf86.h" #include "vga.h" /* For vga256InfoRec */ #include "compiler.h" #include "cir_driver.h" #include "cir_inline.h" #define ROUNDUP8(x) ((x + 7) & ~7) static int allocatebase; /* Video memory address of allocation space. */ static int freespace; /* Number of bytes left for allocation. */ static int currentaddr; /* Video address of first available space. */ static int lastaddr; /* Video address of last allocation. */ static int lastsize; /* Size of the last request. */ /* * Initialize the allocator. * This is called once at server start-up. */ int CirrusInitializeAllocator(base) int base; /* Base video address of allocation space. */ { /* We want to align on a multiple of 8 bytes, should be OK. */ allocatebase = CirrusMemTop; freespace = vga256InfoRec.videoRam * 1024 - allocatebase; currentaddr = allocatebase; lastaddr = -1; return freespace; } /* * Allocate a number of bytes of video memory. */ int CirrusAllocate(size) int size; { if (size > freespace) return -1; lastaddr = currentaddr; size = ROUNDUP8(size); /* Units of 8 bytes. */ lastsize = size; freespace -= size; currentaddr += size; return currentaddr - size; } /* * Allocate space for a cursor. This is allocated from the top of memory as * there are only a fixed number of locations for the cursor. The cursor * must also be aligned on either a 256 or 1024 byte boundary. */ int CirrusCursorAllocate(cursor) cirrusCurRecPtr cursor; { int size; size = (cursor->cur_size == 0) ? 256 : 1024; if (size > freespace) return -1; cursor->cur_addr = (vga256InfoRec.videoRam * 1024) - size; freespace -= size; /* This is the cursor "pattern offset" (SR13) */ cursor->cur_select = (cursor->cur_size == 0) ? 63 : 15; return 0; } /* * Free allocated space. Currently needs to be the last allocated one. */ void CirrusFree(vidaddr) int vidaddr; { if (vidaddr != lastaddr) /* If not allocated right before, */ return; /* do nothing. */ /* Undo the last allocation. */ currentaddr -= lastsize; freespace -= lastsize; lastaddr = -2; } /* * Upload a pattern to video memory. */ void CirrusUploadPattern(pattern, width, height, vidaddr, srcpitch) unsigned char *pattern; int width; /* width of the pattern in bytes. */ int height; /* height of the pattern in scanlines. */ int vidaddr; /* offset into video memory for pattern. */ int srcpitch; /* Offset between scanlines in source. */ { int writebank, destaddr; int i; unsigned char *base; /* Write the image to video memory at offset vidaddr. */ destaddr = vidaddr; CIRRUSSETWRITEB(destaddr, writebank); base = CIRRUSWRITEBASE(); for (i = 0; i < height; i++) { __memcpy( base + destaddr, pattern + i * srcpitch, width ); destaddr += width; CIRRUSCHECKWRITEB(destaddr, writebank); } }