Off-list, it was suggested that some pseudocode be written that would
demonstrate the sort of thing that the nanocontroller will actually
DO.  So I've written a small chunk of code to demonstrate.  This
sample C code would be part of the VGA translation program.  Its job
is to continuously transate an 80x25 text display into pixels in
another buffer so that our video controller can read it out.  I'll be
disappointed if I don't get some good questions out of this.  :)




/* 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;
int text_width, text_height;

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

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


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


/* 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) {
        /* Wait for the word to arrive */
        while (read_io(READ_QUEUE_COUNT) < 1);

        /* Read four rows of the glyph */
        g = read_io(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(WRITE_QUEUE_FREE) < 8);

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

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


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

    for (cy=0; cy<text_height; cy++) {
        /* Request 40 32-bit words from the text buffer. */
        write_io(REQ_QUEUE_ADDR, text_base + cy*text_width/2);
        write_io(REQ_QUEUE_COUNT, text_width/2);

        /* Store those words in scratch space */
        buf = text_line;
        cx = 0;
        while (cx < text_width) {
            n = read_io(READ_QUEUE_COUNT);
            while (n) {
                n--;
                *buf++ = read_io(READ_QUEUE_DATA);
                cx += 2;
            }
        }

        /* Now convert the line of text to pixels */
        buf = text_line;
        for (cx=0; cx<text_width; cx+=2) {
            /* Get a pair of characters from the buffer */
            w = *buf++;

            /* Request font data for each character */
            glyph0 = w & 255;
            write_io(REQ_QUEUE_ADDR, font_base + glyph0*16);
            write_io(REQ_QUEUE_COUNT, 4);
            glyph1 = (w >> 16) & 255;
            write_io(REQ_QUEUE_ADDR, font_base + glyph1*16);
            write_io(REQ_QUEUE_COUNT, 4);

            /* Compute colors */
            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;

            color1 = w >> 24;
            fg1  = (color1 & 1) ? 0xAA0000 : 0;
            fg1 |= (color1 & 2) ? 0x00AA00 : 0;
            fg1 |= (color1 & 4) ? 0x0000AA : 0;
            fg1 += (color1 & 8) ? 0x555555 : 0;
            bg1  = (color1 & 16) ? 0xAA0000 : 0;
            bg1 |= (color1 & 32) ? 0x00AA00 : 0;
            bg1 |= (color1 & 64) ? 0x0000AA : 0;
            if (blink_cycle && (color1 & 128)) fg1 = bg1;

            /* Figure out where the pixels are going to go for glyph0 */
            /* In the real code, we could avoid the multiplies entirely
               by computing pixel_addr iteratively as we walk the display */
            pixel_addr = pixel_base + cy * pixel_width * glyph_height +
                cx * 8;

            draw_glyph(pixel_addr, fg0, bg0);

            /* glyph 1 */
            pixel_addr += 8;
            draw_glyph(pixel_addr, fg1, bg1);
        }
    }
}


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