home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / SVGALIB / SVGALIB1.TAR / svgalib / src / vgaconvplanar.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-26  |  4.8 KB  |  176 lines

  1. /* VGAlib version 1.2 - (c) 1993 Tommy Frandsen            */
  2. /*                                   */
  3. /* This library is free software; you can redistribute it and/or   */
  4. /* modify it without any restrictions. This library is distributed */
  5. /* in the hope that it will be useful, but without any warranty.   */
  6.  
  7. /* These svgalib additions by Harm Hanemaayer. */
  8.  
  9. #include <stdio.h>
  10. #include "vga.h"
  11. #include "libvga.h"
  12.  
  13.  
  14. #define USE_ASM
  15.  
  16.  
  17. /* This function copies a linear virtual screen in system memory to a */
  18. /* planar (Mode X-like) 256 color mode. */
  19.  
  20. /* Note that voffset is the video address of the top of the area to be    */
  21. /* copied, that is, you can only use every fourth pixel as a destination. */
  22. /* Similarly, vpitch is the logical video address width of the screen.    */
  23. /* Also, the width must be a multiple of 4.                      */
  24.  
  25. void vga_copytoplanar256( unsigned char *virtual, int pitch, int voffset,
  26. int vpitch, int w, int h ) {
  27.     unsigned char *virtualp;
  28.     unsigned char *voffsetp;
  29.     int plane, x, y;
  30.  
  31.     for (plane = 0; plane < 4; plane++) {
  32.         /* Copy pixels that belong in plane. */
  33.         outb(SEQ_I, 0x02);
  34.         outb(SEQ_D, 1 << plane);
  35.         virtualp = virtual;
  36.         voffsetp = __svgalib_graph_mem + voffset;
  37.         for (y = 0; y < h; y++) {
  38.             /* Unrolled loop. */
  39. #ifdef USE_ASM
  40.             __asm__ __volatile__(
  41.                 "xorl %0,%0\n\t"
  42.                 "jmp 2f\n\t"
  43.                 ".align 2,0x90\n\t"
  44.  
  45.                 "1:\n\t"
  46.                 "movb (%3,%0,4),%%al\n\t"    /* pixel 0 */
  47.                 "movb 4(%3,%0,4),%%ah\n\t"    /* pixel 1 */
  48.                 "movw %%ax,(%2,%0)\n\t"        /* write */
  49.                 "movb 8(%3,%0,4),%%al\n\t"    /* pixel 2 */
  50.                 "movb 12(%3,%0,4),%%ah\n\t"    /* pixel 3 */
  51.                 "movw %%ax,2(%2,%0)\n\t"
  52.                 "movb 16(%3,%0,4),%%al\n\t"    /* pixel 4 */
  53.                 "movb 20(%3,%0,4),%%ah\n\t"    /* pixel 5 */
  54.                 "movw %%ax,4(%2,%0)\n\t"
  55.                 "movb 24(%3,%0,4),%%al\n\t"    /* pixel 6 */
  56.                 "movb 28(%3,%0,4),%%ah\n\t"    /* pixel 7 */
  57.                 "movw %%ax,6(%2,%0)\n\t"
  58.                 "addl $8,%0\n\t"
  59.  
  60.                 "2:\n\t"
  61.                 "leal 32(,%0,4),%%eax\n\t" /* x * 4 + 32 */
  62.                 "cmpl %4,%%eax\n\t"       /* < w? */
  63.                 "jl 1b\n\t"
  64.  
  65.                 /* Do remaining pixels. */
  66.                 "jmp 3f\n\t"
  67.                 ".align 2,0x90\n\t"
  68.  
  69.                 "4:\n\t"
  70.                 "movb (%3,%0,4),%%al\n\t"
  71.                 "movb %%al,(%2,%0)\n\t"
  72.                 "incl %0\n\t"
  73.                 "3:\n\t"
  74.                 "leal (,%0,4),%%eax\n\t"    /* x * 4 */
  75.                 "cmpl %4,%%eax\n\t"        /* < w? */
  76.                 "jl 4b\n\t"
  77.  
  78.                 : /* output */
  79.                   "=r" (x)
  80.                 : /* input */
  81.                   "0" (x),
  82.                   "r" (voffsetp),
  83.                   "r" (virtualp + plane),
  84.                   "rm" (w), "ax" (0)
  85.                 : /* modified */
  86.                   "ax", "0"
  87.             );
  88. #else
  89.             x = 0;
  90.             while (x * 4 + 32 < w) {
  91.                 voffsetp[x] = virtualp[x * 4 + plane];
  92.                 voffsetp[x + 1] = virtualp[x * 4 + plane + 4];
  93.                 voffsetp[x + 2] = virtualp[x * 4 + plane + 8];
  94.                 voffsetp[x + 3] = virtualp[x * 4 + plane + 12];
  95.                 voffsetp[x + 4] = virtualp[x * 4 + plane + 16];
  96.                 voffsetp[x + 5] = virtualp[x * 4 + plane + 20];
  97.                 voffsetp[x + 6] = virtualp[x * 4 + plane + 24];
  98.                 voffsetp[x + 7] = virtualp[x * 4 + plane + 28];
  99.                 x += 8;
  100.             }
  101.             while (x * 4 < w) {
  102.                 voffsetp[x] = virtualp[x * 4 + plane];
  103.                 x++;
  104.             }
  105. #endif
  106.             virtualp += pitch;    /* Next line. */
  107.             voffsetp += vpitch;
  108.         }
  109.     }
  110. }
  111.  
  112.  
  113. /* This is the equivalent function for planar 16 color modes; pixels are */
  114. /* assumed to be stored in individual bytes ranging from 0 to 15 in the  */
  115. /* virtual screen. It's very slow compared to the Mode X one. */
  116.  
  117. /* Here width must be a multiple of 8; video addresses are in units of 8 */
  118. /* pixels. */
  119.  
  120. void vga_copytoplanar16( unsigned char *virtual, int pitch, int voffset,
  121. int vpitch, int w, int h ) {
  122.     vga_copytoplane(virtual, pitch, voffset, vpitch, w, h, 0);
  123.     vga_copytoplane(virtual, pitch, voffset, vpitch, w, h, 1);
  124.     vga_copytoplane(virtual, pitch, voffset, vpitch, w, h, 2);
  125.     vga_copytoplane(virtual, pitch, voffset, vpitch, w, h, 3);
  126. }
  127.  
  128.  
  129. void vga_copytoplane( unsigned char *virtual, int pitch, int voffset,
  130. int vpitch, int w, int h, int plane ) {
  131.     int x, y;
  132.     unsigned char planemask;
  133.     unsigned char *virtualp;
  134.     unsigned char *voffsetp;
  135.  
  136.     outb(GRA_I, 0x01);    /* Disable set/reset. */
  137.     outb(GRA_D, 0x00);
  138.  
  139.     outb(GRA_I, 0x08);    /* Write to all bits. */
  140.     outb(GRA_D, 0xff);
  141.  
  142.     /* Copy pixels that belong in plane. */
  143.     planemask = 1 << plane;
  144.     virtualp = virtual;
  145.     voffsetp = __svgalib_graph_mem + voffset;
  146.     outb(SEQ_I, 0x02);
  147.     outb(SEQ_D, planemask);
  148.     for (y = 0; y < h; y++) {
  149.         x = 0;
  150.         while (x * 8 < w) {
  151.             unsigned char val;
  152.             val = 0;
  153.             if (virtualp[x * 8] & planemask)
  154.                 val += 0x80;
  155.             if (virtualp[x * 8 + 1] & planemask)
  156.                 val += 0x40;
  157.             if (virtualp[x * 8 + 2] & planemask)
  158.                 val += 0x20;
  159.             if (virtualp[x * 8 + 3] & planemask)
  160.                 val += 0x10;
  161.             if (virtualp[x * 8 + 4] & planemask)
  162.                 val += 0x08;
  163.             if (virtualp[x * 8 + 5] & planemask)
  164.                 val += 0x04;
  165.             if (virtualp[x * 8 + 6] & planemask)
  166.                 val += 0x02;
  167.             if (virtualp[x * 8 + 7] & planemask)
  168.                 val += 0x01;
  169.             voffsetp[x] = val;
  170.             x++;
  171.         }
  172.         virtualp += pitch;    /* Next line. */
  173.         voffsetp += vpitch;
  174.     }
  175. }
  176.