📄 scr_prsm.c
字号:
/* * scr_prsm.c * * Microwindows screen driver for the Isicad Prisma diskless workstation * by George Harvey. * * This is mostly 'glue' code, the real work is done by assembler routines * in asm_prsm.s. * * The Prisma has a custom graphics controller with a fixed resolution * 1280 x 1024, 256 color display. This would be great except that it * was desgined for CAD work, not graphical desktops. The only interface * to the the video display is through a set of control registers. These * support line drawing in hardware (any angle, any length, any colour) * but there is no way to access the video memory as a frame buffer. * There is a way to read and write individual pixels but it is VERY * slow so blitting is bad news. * * 26/02/00 first tests with Microwindows 0.87 * 24/03/00 added blitter code * */#include <stdio.h>#include <stdlib.h>#include "device.h"#ifdef _MINIX#include <sys/types.h>#endif#include "genfont.h"#include "genmem.h"#define MY_PSD_ADDR 0x01000000 /* dummy video memory addr *//* VB driver entry points*/static PSD VB_open(PSD psd);static void VB_close(PSD psd);static void VB_getscreeninfo(PSD psd,PMWSCREENINFO psi);;static void VB_setpalette(PSD psd,int first,int count,MWPALENTRY *pal);static void VB_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c);static MWPIXELVAL VB_readpixel(PSD psd,MWCOORD x, MWCOORD y);static void VB_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c);static void VB_drawvline(PSD psd,MWCOORD x,MWCOORD y1,MWCOORD y2,MWPIXELVAL c);static void VB_fillrect(PSD psd,MWCOORD x1,MWCOORD y1,MWCOORD x2,MWCOORD y2, MWPIXELVAL c);static void VB_blit(PSD destpsd,MWCOORD destx,MWCOORD desty,MWCOORD w,MWCOORD h, PSD srcpsd,MWCOORD srcx,MWCOORD srcy,long op);/* low-level routines in asm_prsm.s */void init_scr(void);void c_pcmap(int cnt, int *map);void c_ldraw4(int x1, int y1, int x2, int y2, int inten, int sel);/* optimised block drawing routines */void c_ldraw5y(int x1, int y1, int x2, int y2, int inten);void c_ldraw5x(int x1, int y1, int x2, int y2, int inten);int r1pix3(int x, int y, int selmask);void rd_rect2(int x1, int x2, int y1, int y2, unsigned char *buf);void w1pix3(int x, int y, int selmask, int pixdata);void wr_rect2(int x1, int x2, int y1, int y2, unsigned char *buf);/* dummy routines for now */static MWBOOL VB_mapmemgc(PSD mempsd,MWCOORD w,MWCOORD h,int planes,int bpp, int linelen,int size,void *addr);SCREENDEVICE scrdev = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, VB_open, VB_close, VB_getscreeninfo, VB_setpalette, VB_drawpixel, VB_readpixel, VB_drawhline, VB_drawvline, VB_fillrect, gen_fonts, VB_blit, NULL, /* preSelect */ NULL, /* DrawArea */ NULL, /* SetIOPermissions */ gen_allocatememgc, VB_mapmemgc, gen_freememgc};static int *pr_cmap; /* Prisma colour map */static PSDVB_open(PSD psd){ /* allocate space for the colour map */ if ((pr_cmap = (int *)malloc((size_t)(256 * sizeof(int)))) == NULL) { perror("malloc cmap"); return(0); } memset(pr_cmap, 0, (256 * sizeof(int))); /* clear colour map */ /* init driver variables */ psd->xres = psd->xvirtres = 1280; psd->yres = psd->yvirtres = 1024; psd->planes = 1; psd->bpp = 8; psd->ncolors = 256; psd->pixtype = MWPF_PALETTE;#if HAVEBLIT psd->flags = PSF_SCREEN | PSF_HAVEBLIT;#else psd->flags = PSF_SCREEN;#endif psd->addr = (void *)MY_PSD_ADDR; /* dummy addr. */ psd->linelen = 1280; init_scr(); /* init VB and clear screen */ printf("VB_open: finished open\n"); /* DEBUG */ return psd;}static voidVB_close(PSD psd){ /* should probably restore the default palette here */ /* empty for now */}static voidVB_getscreeninfo(PSD psd,PMWSCREENINFO psi){ psi->rows = psd->yvirtres; psi->cols = psd->xvirtres; psi->planes = psd->planes; psi->bpp = psd->bpp; psi->ncolors = psd->ncolors; psi->pixtype = psd->pixtype; psi->fonts = 1; /* 1280 x 1024 on a 16in monitor */ psi->xdpcm = 40; /* assumes screen width of 32 cm*/ psi->ydpcm = 43; /* assumes screen height of 24 cm*/}static voidVB_setpalette(PSD psd,int first,int count,MWPALENTRY *pal){ int i, ind; MWPALENTRY *p; ind = first; for (i = 0; i < count; i++) { p = &pal[i]; if (ind > 255) { fprintf(stderr, "VB_setpalette: index out of range: %d\n", ind); return; } *(pr_cmap + ind) = (ind << 24) | (p->r << 16) | (p->g << 8) | (p->b); ind++; } /* to try and debug palette code in VNC... *//* if (count == 1) { printf("VB_setpalette: setting %d to %08x\n", first, \ *(pr_cmap + first)); } */ /* write a maximum of 16 entries at a time, any more doesn't work * reliably (no idea why not) */ ind = first; while (count) { if (count >= 16) { c_pcmap(16, (pr_cmap + ind)); count -= 16; ind += 16; } else { c_pcmap(count, (pr_cmap + ind)); count = 0; } }}static voidVB_drawpixel(PSD psd,MWCOORD x, MWCOORD y, MWPIXELVAL c){ w1pix3(x, y, 255, (int)c);}static MWPIXELVALVB_readpixel(PSD psd,MWCOORD x, MWCOORD y){ return((MWPIXELVAL)r1pix3(x, y, 255));}/* Draw horizontal line from x1,y to x2,y including final point*/static voidVB_drawhline(PSD psd,MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c){/* ++x2; /* draw final point*/ y = 1023 - y; /* flip y axis */ c_ldraw4(x1, y, x2, y, (int)c, 255);}/* Draw a vertical line from x,y1 to x,y2 including final point*/static voidVB_drawvline(PSD psd,MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c){/* ++y2; /* draw final point*/ y1 = 1023 - y1; y2 = 1023 - y2; c_ldraw4(x, y1, x, y2, (int)c, 255);}static voidVB_fillrect(PSD psd, MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2, MWPIXELVAL c){ register int w, h; w = ((x2 - x1) >= 0) ? (x2 - x1) : (x1 - x2); /* abs width */ h = ((y2 - y1) >= 0) ? (y2 - y1) : (y1 - y2); /* abs height */ /* sanity check */ if ((w > 1279) || (h > 1023)) return; y1 = 1023 - y1; /* flip origin to top corner */ y2 = 1023 - y2; if (w >= h) { /* width is greater, draw horizontal lines */#if 0 while(y2 <= y1) { c_ldraw4(x1, y2, x2, y2, (int)c, 255); y2++; }#endif c_ldraw5y(x1, y2, x2, y1, (int)c); } else { /* height is greater, draw vertical lines */#if 0 while(x1 <= x2) { c_ldraw4(x1, y2, x1, y1, (int)c, 255); x1++; }#endif c_ldraw5x(x1, y2, x2, y1, (int)c); }}/* * Blitting is going to be very slow on the Prisma! */static voidVB_blit(PSD destpsd,MWCOORD destx,MWCOORD desty,MWCOORD w,MWCOORD h, PSD srcpsd,MWCOORD srcx,MWCOORD srcy,long op){ int x1s, x1e, x2s, x2e, y1s, y1e, y2s, y2e; unsigned char *rect;/* printf("VB_blit\n"); /* DEBUG */ if ((rect = (unsigned char *)malloc((size_t)(w * h * sizeof(char)))) == NULL) { perror("malloc rect"); return; } /* always copy in +ve direction */ x1s = (w >= 0) ? srcx : (srcx + w); x2s = (w >= 0) ? destx : (destx + w); x1e = (w >= 0) ? (srcx + w) : srcx; x2e = (w >= 0) ? (destx + w) : destx; y1s = (h >= 0) ? srcy : (srcy + h); y2s = (h >= 0) ? desty : (desty + h); y1e = (h >= 0) ? (srcy + h) : srcy; y2e = (h >= 0) ? (desty + h) : desty; /* determine which PSD is the screen */ if ((srcpsd->addr == MY_PSD_ADDR) && (destpsd->addr == MY_PSD_ADDR)) { /* screen to screen copy */ /* copy rectangle into buffer */ rd_rect2(x1s, y1s, x1e, y1e, rect); /* copy rectangle out of buffer */ wr_rect2(x2s, y2s, x2e, y2e, rect); } else if (srcpsd->addr == MY_PSD_ADDR) { /* screen to off-screen */ } else if (destpsd->addr == MY_PSD_ADDR) { /* off-screen to screen */ } else { /* error ! */ printf("VB_blit with no screen!\n"); } free(rect);}static MWBOOLVB_mapmemgc(PSD mempsd,MWCOORD w,MWCOORD h,int planes,int bpp,int linelen, int size,void *addr){ return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -