This is a modification of something I posted ages ago to the list.  It
is a C version of the code that will run in HQ to do VGA text mode.
We should argue about it a bit, then check it into SVN, and start
hacking it until it works and is also structured how it needs to be to
run in HQ.  For instance, all global variables should be offsets into
an explicit scratch array with 512 words in it.




/* CGA text is 2 bytes per character.  The first byte is the glyph number.
The second byte is color.  I'm doing this from memory, and this is probably
wrong, but for this code, I'm going to assume this for the color byte:
   [3:0] foreground color
   [6:4] background color
   [7]   blink

The colors are as follows (also probably wrong):
   0 - black        #000000
   1 - dk red       #AA0000
   2 - dk green     #00AA00
   3 - brown        #AAAA00 (definitely wrong, but whatever)
   4 - dk blue      #0000AA
   5 - dk magenta   #AA00AA
   6 - dk cyan      #00AAAA
   7 - lt gray      #AAAAAA
   8 - dk gray      #555555
   9 - lt red       #FF5555
  10 - lt green     #55FF55
  11 - yellow       #FFFF55
  12 - lt blue      #5555FF
  13 - lt magenta   #FF55FF
  14 - lt cyan      #55FFFF
  15 - white        #FFFFFF
*/

/* Base address of where the text is stored in graphics memory */
int text_base;

/* Width and height in characters of the character display */
int text_width, text_height;

/* Base address of where the font is stored */
int font_base;

/* Font is assumed to be 8x16 (not always correct), where a character
   is found as:  font_addr + glyph_num*16 */
int glyph_height;

/* Base address of where pixels are stored for the video framebuffer */
int pixel_base;

/* Actual size of glyph in graphics buffer.  Different from 8x16 if scaled */
int cell_width, cell_height;

/* Size of whole graphics screen */
int screen_width, screen_height;


/* This is a pointer into the scratch space where we temporarily store
   row of text */
int *text_line;



/* Poll for PCI accesses to service */
void poll_pci()
{
    while (memory or engine reg writes) {
        /* get the write and forward it to the bridge */
    }
    if (memory or engine reg read) {
        /* forward the read addr and count to the bridge */
        /* wait for read data to arrive and forward it all back to
address_decode */
    }
    while (vga io writes) {
        /* process them, storing appropriate data in scratch space */
    }
    if (vga io read) {
        /* fetch data from scratch space and return it */
    }
}


/* Draw a glyph whose bitmap has been queued */
void draw_glyph(int pixel_addr, int fg, int bg)
{
    int px, py, i, bit, g;

    /* Outer loop for the rows of the glyph */
    for (py=0; py<glyph_height; py+=4) {
        /* Read four rows of the glyph */
        g = read_io(BRIDGE_READ_QUEUE_DATA);

        /* Process four rows of the glyph */
        for (i=0; i<4; i++) {
            /* Make sure there's room on the write queue */
            while (read_io(BRIDGE_CMD_QUEUE_FREE) < 9);

            write_io(BRIDGE_WRITE_MEM_ADDR, pixel_addr)

            /* Write out a row of pixels */
            for (px=0; px<cell_width; px++) {
                bit = g&1;
                g >>= 1;
                pixel = bit ? fg : bg;
                write_io(BRIDGE_WRITE_DATA_1111, pixel);
                pixel_addr++;
            }

            /* Move left and down to the next row of the glyph */
            pixel_addr += screen_width - cell_width;
        }
    }
}


/* Convert the whole 80x25 screen from text to pixels */
void convert_text_to_pixels()
{
    int cx, cy, *buf, i, j;
    int glyph0, color0, bg0, fg0;
    int pixel_addr;

    pixel_addr = pixel_base;

    for (cy=0; cy<text_height; cy++) {
        /* Read a line of text.  This is 80 character, stored in 160 bytes,
           or 40 words.  Since we don't know where a 128-word boundary
might be crossed,
           we request words in lots of 8 */


        buf = text_line;
        cx = 0;
        while (cx < text_width) {
            poll_pci();

            /* Make sure bridge is not busy and not in read mode */
            while (read_io(BRIDGE_BUSY));

            write_io(BRIDGE_READ_MEM_ADDR, text_base + cy*text_width/2);
            write_io(BRIDGE_READ_COUNT, 8);
            i = 0;
            while (i < 8) {
                j = read_io(BRIDGE_READ_QUEUE_COUNT);
                i += j;
                cx += j;
                switch (j) {
                    7: *buf++ = read_io(BRIDGE_READ_QUEUE_DATA);
                    6: *buf++ = read_io(BRIDGE_READ_QUEUE_DATA);
                    5: *buf++ = read_io(BRIDGE_READ_QUEUE_DATA);
                    4: *buf++ = read_io(BRIDGE_READ_QUEUE_DATA);
                    3: *buf++ = read_io(BRIDGE_READ_QUEUE_DATA);
                    2: *buf++ = read_io(BRIDGE_READ_QUEUE_DATA);
                    1: *buf++ = read_io(BRIDGE_READ_QUEUE_DATA);
                }
            }
        }

        poll_pci();

        /* Now convert the line of text to pixels */
        buf = text_line;
        for (cx=0; cx<text_width; cx++) {
            poll_pci();

            /* Get a character from the buffer */
            /* If we're on the odd glyph, shift to get it */
            w = *buf;
            if (cx & 1) {
                w >>= 16;
                buf++;
            }

            /* Request font data for each character */
            glyph0 = w & 255;
            while (read_io(BRIDGE_BUSY));
            write_io(BRIDGE_READ_MEM_ADDR, font_base + glyph0*16);
            write_io(BRIDGE_READ_COUNT, 4);

            /* Compute colors */
            /* If these are configurable, read them from scratch space */
            color0 = (w >> 8) & 255;
            fg0  = (color0 & 1) ? 0xAA0000 : 0;
            fg0 |= (color0 & 2) ? 0x00AA00 : 0;
            fg0 |= (color0 & 4) ? 0x0000AA : 0;
            fg0 += (color0 & 8) ? 0x555555 : 0;
            bg0  = (color0 & 16) ? 0xAA0000 : 0;
            bg0 |= (color0 & 32) ? 0x00AA00 : 0;
            bg0 |= (color0 & 64) ? 0x0000AA : 0;
            if (blink_cycle && (color0 & 128)) fg0 = bg0;

            /* Wait for all four reads to appear in queue */
            while (read_io(BRIDGE_READ_QUEUE_COUNT) < 4);

            /* Process glyph */
            draw_glyph(pixel_addr, fg0, bg0);

            pixel_addr += cell_width;
        }

        pixel_addr += screen_width * (cell_height - 1);
    }

    poll_pci();
}


void main()
{
    /* All I do is translate over and over and over again */
    while (1) {
        convert_text_to_pixels();
    }
}



-- 
Timothy Normand Miller
http://www.cse.ohio-state.edu/~millerti
Open Graphics Project
_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)

Reply via email to