Not code comments exactly, but comments none the less.
Timothy Normand Miller wrote:
> 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. :)
>
My first response is *ouch*! :)
How big a penalty are we going to take for memory reads and writes?
Well, reads anyway? Are we still looking at perhaps a 20 clock delay in
the 200Mhz domain for a read to return data?
>
>
>
> /* 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
>
>
You have to be able to look up the colors as you can change the color
palette for text. Still limited to 16 colors of course, but just like
16 color graphics modes, you can adjust what those colors map to.
> 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;
>
>
>From a memory access perspective would it be more efficient to draw one
vertical row of each glyph in a row? If writes don't impose a real
penalty or less of a penalty than reads, then probably not. But it is
something to think about.
> /* 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;
> }
> }
> }
>
>
I still haven't figured out how to do blinking text without doing this
in a continuous loop yet. *sigh* Do we have any ability for the
nanocontroller to tell time? At least by counting clock cycles or some
such thing. Best would be able to have an time based interrupt, but
that may require more hardware than we want to allocate.
> /* 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();
> }
> }
>
>
>
>
_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)