home *** CD-ROM | disk | FTP | other *** search
- /* 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 */
-
- #include <stdio.h>
- #include "vga.h"
- #include "libvga.h"
-
-
- /* 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}};
-
- /* 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];
-
-
- 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);
- }
-
-
- int vga_drawscansegment(unsigned char* colors, int x, int y, int length)
- {
- /* both length and x must divide with 8 */
-
- if (MODEX) goto modeX;
- switch (CI.colors) {
- case 16:
- {
- int i, j, k, first, last, page, l1, l2;
- int offset;
- union bits bytes;
- unsigned char* address;
-
- k = 0;
- for(i = 0; i < length; i += 8) {
- bytes.i = 0;
- first = i;
- last = i+8;
- for(j = first; j < last; j++)
- 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;
- }
-
- offset = (y*CI.xdim + x)/8;
- vga_setpage((page = offset>>16));
- l1 = 0x10000 - (offset &= 0xffff);
- length /= 8;
- if (l1 > length) l1 = length;
- l2 = length - l1;
-
- address = GM + offset;
-
- /* 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 map mask register */
- port_out(0x02, SEQ_I );
-
- /* write plane 0 */
- port_out(0x01, SEQ_D );
- memcpy(address, plane0, l1);
-
- /* write plane 1 */
- port_out(0x02, SEQ_D );
- memcpy(address, plane1, l1);
-
- /* write plane 2 */
- port_out(0x04, SEQ_D );
- memcpy(address, plane2, l1);
-
- /* write plane 3 */
- port_out(0x08, SEQ_D );
- memcpy(address, plane3, l1);
-
- if (l2 > 0) {
- vga_setpage(page+1);
-
- /* write plane 0 */
- port_out(0x01, SEQ_D );
- memcpy( GM, &plane0[l1], l2);
-
- /* write plane 1 */
- port_out(0x02, SEQ_D );
- memcpy( GM, &plane1[l1], l2);
-
- /* write plane 2 */
- port_out(0x04, SEQ_D );
- memcpy( GM, &plane2[l1], l2);
-
- /* write plane 3 */
- port_out(0x08, SEQ_D );
- memcpy( GM, &plane3[l1], l2);
- }
-
- /* restore map mask register */
- 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 );
-
- /* write to all planes */
- port_out(0x02, SEQ_I );
- port_out(0x0F, SEQ_D );
-
- memcpy( GM + (y*CI.xdim + x)/8, colors, length);
-
- /* restore map mask register */
- port_out(0x0F, SEQ_D );
-
- /* enable Set/Reset Register */
- port_out(0x01, GRA_I );
- port_out(0x0F, GRA_D );
- }
- break;
- case 256:
- {
- switch (CM) {
- case G320x200x256: /* linear addressing - easy and fast */
- memcpy(GM+y*CI.xdim+x,colors,length);
- return 0;
- case G320x240x256:
- case G320x400x256:
- case G360x480x256:
- modeX:
- {
- int first, last, offset, pixel, plane;
-
- /* select map mask register */
- port_out(0x02, SEQ_I);
-
- for(plane = 0; plane < 4; plane++) {
- /* select plane */
- port_out(1 << plane, SEQ_D);
-
- pixel = plane;
- first = (y*CI.xdim + x)/4;
- last = (y*CI.xdim + x + length)/4;
- for(offset = first; offset < last; offset++) {
- GM[offset] = colors[pixel];
- pixel += 4;
- }
- }
- }
- return 0;
- }
- {
- unsigned long offset;
- int segment, free;
-
- SegmentedCopy:
- offset = y*CI.xbytes+x;
- segment = offset >> 16;
- free = ((segment+1)<<16)-offset;
- offset &= 0xFFFF;
-
- if (free < length) {
- vga_setpage(segment);
- memcpy(GM + offset, colors, free);
- vga_setpage(segment + 1);
- memcpy(GM, colors+free, length-free);
- } else {
- vga_setpage(segment);
- memcpy(GM + offset, colors, length);
- }
- }
- }
- break;
- case 32768:
- case 65536: x *= 2;
- goto SegmentedCopy;
- case 1<<24: x*=3;
- goto SegmentedCopy;
- }
-
- return 0;
- }
-
-