📄 vgadraw.c
字号:
/* VGAlib version 1.2 - (c) 1993 Tommy Frandsen *//* *//* This library is free software; you can redistribute it and/or *//* modify it without any restrictions. This library is distributed *//* in the hope that it will be useful, but without any warranty. *//* Multi-chipset support Copyright 1993 Harm Hanemaayer *//* partially copyrighted (C) 1993 by Hartmut Schirmer *//* 21 January 1995 - added vga_readscanline(), added support for *//* non 8-pixel aligned scanlines in 16 color mode. billr@rastergr.com */#include <stdio.h>#include "vga.h"#include "libvga.h"#ifdef BACKGROUND#include "vgabg.h"#endif/* used to decompose color value into bits (for fast scanline drawing) */union bits { struct { unsigned char bit3; unsigned char bit2; unsigned char bit1; unsigned char bit0; } b; unsigned int i;};/* color decompositions */static union bits color16[16] ={ { {0, 0, 0, 0}}, { {0, 0, 0, 1}}, { {0, 0, 1, 0}}, { {0, 0, 1, 1}}, { {0, 1, 0, 0}}, { {0, 1, 0, 1}}, { {0, 1, 1, 0}}, { {0, 1, 1, 1}}, { {1, 0, 0, 0}}, { {1, 0, 0, 1}}, { {1, 0, 1, 0}}, { {1, 0, 1, 1}}, { {1, 1, 0, 0}}, { {1, 1, 0, 1}}, { {1, 1, 1, 0}}, { {1, 1, 1, 1}}};/* mask for end points in plane buffer mode */static unsigned char mask[8] ={ 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};/* display plane buffers (for fast scanline drawing) *//* 256 bytes -> max 2048 pixel per line (2/16 colors) */static unsigned char plane0[256];static unsigned char plane1[256];static unsigned char plane2[256];static unsigned char plane3[256];static inline void shifted_memcpy(void *dest_in, void *source_in, int len){ int *dest = dest_in; int *source = source_in; len >>= 2; while (len--) *dest++ = (*source++ << 8);}/* RGB_swapped_memcopy returns the amount of bytes unhandled */static inline int RGB_swapped_memcpy(char *dest, char *source, int len){ int rest, tmp; tmp = len / 3; rest = len - 3 * tmp; len = tmp; while (len--) { *dest++ = source[2]; *dest++ = source[1]; *dest++ = source[0]; source += 3; } return rest;}int vga_drawscanline(int line, unsigned char *colors){ if ((CI.colors == 2) || (CI.colors > 256)) return vga_drawscansegment(colors, 0, line, CI.xbytes); else return vga_drawscansegment(colors, 0, line, CI.xdim);}#if defined(CONFIG_ALPHA_JENSEN)#define vuip volatile unsigned int *void a_memcpy(unsigned char *dest, unsigned char *src, long n){ long i; if (((unsigned long) src % 4) || ((unsigned long) dest % 4)) { if (((unsigned long) src % 2) || ((unsigned long) dest % 2)) { for (i = 0; i < n; i++) { *(vuip) (dest + (i << 7)) = (*(unsigned char *) (src + i)) * 0x01010101UL; } } else { dest += 0x20UL; for (i = 0; i < n; i += 2) { *(vuip) (dest + (i << 7)) = (*(unsigned short *) (src + i)) * 0x00010001UL; } dest -= 0x20UL; for (i = n - (n % 2); i < n; i++) { *(vuip) (dest + (i << 7)) = (*(unsigned char *) (src + i)) * 0x01010101UL; } } } else { dest += 0x60UL; for (i = 0; i < n; i += 4) { *(vuip) (dest + (i << 7)) = (*(unsigned int *) (src + i)); } dest -= 0x60UL; for (i = n - (n % 4); i < n; i++) { *(vuip) (dest + (i << 7)) = (*(unsigned char *) (src + i)) * 0x01010101UL; } }}#define MEMCPY a_memcpy#define VM SM#else#define MEMCPY memcpy#define VM GM#endif#ifdef BACKGROUNDstatic int _vga_drawscansegment_bg(unsigned char *colors, int x, int y, int length){ /* The easy way */ int count=0; int color; color=COL; while(count<length) { vga_setcolor(*colors); __svgalib_fast_drawpixel(x+count,y); colors++; count++; } vga_setcolor(color); return(0);}#endifint vga_drawscansegment(unsigned char *colors, int x, int y, int length){ /* both length and x must divide with 8 */ /* no longer true (at least for 16 & 256 colors) */#ifdef BACKGROUND __svgalib_dont_switch_vt_yet(); if (!vga_oktowrite()) { /*__svgalib_is_vt_switching_needed(); */ _vga_drawscansegment_bg(colors,x,y,length); __svgalib_is_vt_switching_needed(); return(0); }#endif if (MODEX) goto modeX; switch (CI.colors) { case 16: { int i, j, k, first, last, page, l1, l2; int offset, eoffs, soffs, ioffs; union bits bytes; unsigned char *address; k = 0; soffs = ioffs = (x & 0x7); /* starting offset into first byte */ eoffs = (x + length) & 0x7; /* ending offset into last byte */ for (i = 0; i < length;) { bytes.i = 0; first = i; last = i + 8 - ioffs; if (last > length) last = length; for (j = first; j < last; j++, i++) bytes.i = (bytes.i << 1) | color16[colors[j]].i; plane0[k] = bytes.b.bit0; plane1[k] = bytes.b.bit1; plane2[k] = bytes.b.bit2; plane3[k++] = bytes.b.bit3; ioffs = 0; } if (eoffs) { /* fixup last byte */ k--; bytes.i <<= (8 - eoffs); plane0[k] = bytes.b.bit0; plane1[k] = bytes.b.bit1; plane2[k] = bytes.b.bit2; plane3[k++] = bytes.b.bit3; } offset = (y * CI.xdim + x) / 8; vga_setpage((page = offset >> 16)); l1 = 0x10000 - (offset &= 0xffff); /* k currently contains number of bytes to write */ if (l1 > k) l1 = k; l2 = k - l1; /* make k the index of the last byte to write */ k--;#if defined(CONFIG_ALPHA_JENSEN) address = SM + (offset << 7);#else address = GM + offset;#endif /* disable Set/Reset Register */ port_out(0x01, GRA_I); port_out(0x00, GRA_D); /* write to all bits */ port_out(0x08, GRA_I); port_out(0xFF, GRA_D); /* select write map mask register */ port_out(0x02, SEQ_I); /* write plane 0 */ port_out(0x01, SEQ_D); /* select read map mask register */ port_out(0x04, GRA_I); /* read plane 0 */ port_out(0x00, GRA_D); if (soffs) plane0[0] |= *address & ~mask[soffs]; if (eoffs && l2 == 0) plane0[k] |= *(address + l1 - 1) & mask[eoffs]; MEMCPY(address, plane0, l1); /* write plane 1 */ port_out(0x02, SEQ_I); /* ATI needs resetting that one */ port_out(0x02, SEQ_D); /* read plane 1 */ port_out(0x04, GRA_I); /* ATI needs resetting that one */ port_out(0x01, GRA_D); if (soffs) plane1[0] |= *address & ~mask[soffs]; if (eoffs && l2 == 0) plane1[k] |= *(address + l1 - 1) & mask[eoffs]; MEMCPY(address, plane1, l1); /* write plane 2 */ port_out(0x02, SEQ_I); /* ATI needs resetting that one */ port_out(0x04, SEQ_D); /* read plane 2 */ port_out(0x04, GRA_I); /* ATI needs resetting that one */ port_out(0x02, GRA_D); if (soffs) plane2[0] |= *address & ~mask[soffs]; if (eoffs && l2 == 0) plane2[k] |= *(address + l1 - 1) & mask[eoffs]; MEMCPY(address, plane2, l1); /* write plane 3 */ port_out(0x02, SEQ_I); /* ATI needs resetting that one */ port_out(0x08, SEQ_D); /* read plane 3 */ port_out(0x04, GRA_I); /* ATI needs resetting that one */ port_out(0x03, GRA_D); if (soffs) plane3[0] |= *address & ~mask[soffs]; if (eoffs && l2 == 0) plane3[k] |= *(address + l1 - 1) & mask[eoffs]; MEMCPY(address, plane3, l1); if (l2 > 0) { vga_setpage(page + 1); /* write plane 0 */ port_out(0x02, SEQ_I); /* ATI needs resetting that one */ port_out(0x01, SEQ_D); if (eoffs) { /* read plane 0 */ port_out(0x04, GRA_I); /* ATI needs resetting that one */ port_out(0x00, GRA_D); plane0[k] |= *(GM + l2 - 1) & mask[eoffs]; } MEMCPY(GM, &plane0[l1], l2); /* write plane 1 */ port_out(0x02, SEQ_I); /* ATI needs resetting that one */ port_out(0x02, SEQ_D); if (eoffs) { /* read plane 1 */ port_out(0x04, GRA_I); /* ATI needs resetting that one */ port_out(0x01, GRA_D); plane1[k] |= *(GM + l2 - 1) & mask[eoffs]; } MEMCPY(GM, &plane1[l1], l2); /* write plane 2 */ port_out(0x02, SEQ_I); /* ATI needs resetting that one */ port_out(0x04, SEQ_D); if (eoffs) { /* read plane 2 */ port_out(0x04, GRA_I); /* ATI needs resetting that one */ port_out(0x02, GRA_D); plane2[k] |= *(GM + l2 - 1) & mask[eoffs]; } MEMCPY(GM, &plane2[l1], l2); /* write plane 3 */ port_out(0x02, SEQ_I); /* ATI needs resetting that one */ port_out(0x08, SEQ_D); if (eoffs) { /* read plane 3 */ port_out(0x04, GRA_I); /* ATI needs resetting that one */ port_out(0x03, GRA_D); plane3[k] |= *(GM + l2 - 1) & mask[eoffs]; } MEMCPY(GM, &plane3[l1], l2); } /* restore map mask register */ port_out(0x02, SEQ_I); /* ATI needs resetting that one */ port_out(0x0F, SEQ_D); /* enable Set/Reset Register */ port_out(0x01, GRA_I); port_out(0x0F, GRA_D); } break; case 2: { /* disable Set/Reset Register */ port_out(0x01, GRA_I); port_out(0x00, GRA_D); /* write to all bits */ port_out(0x08, GRA_I); port_out(0xFF, GRA_D);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -