1.1 --- a/display.c Tue May 30 00:07:29 2017 +0200
1.2 +++ b/display.c Tue May 30 00:12:14 2017 +0200
1.3 @@ -21,6 +21,37 @@
1.4 #include "mips.h"
1.5 #include "vga.h"
1.6
1.7 +/* The font base and limit are locations containing the first and last codes. */
1.8 +
1.9 +extern uint8_t fontbase, fontlimit;
1.10 +
1.11 +/* The font character data is a list of bitmap bytes. */
1.12 +
1.13 +extern uint8_t fontchars;
1.14 +static uint8_t *fontdata = &fontchars;
1.15 +
1.16 +/*
1.17 +The font table is a list of byte-resolution indexes to be combined with the font
1.18 +character data list address.
1.19 +*/
1.20 +
1.21 +extern uint32_t fonttable;
1.22 +static uint32_t *fontoffsets = &fonttable;
1.23 +
1.24 +
1.25 +
1.26 +/* Wrap addresses around at the end of the screen area. */
1.27 +
1.28 +uint32_t *wrap_address(uint32_t *target)
1.29 +{
1.30 + if (target > (uint32_t *) SCREEN_LIMIT_KSEG0)
1.31 + return target - SCREEN_SIZE / 4;
1.32 + else
1.33 + return target;
1.34 +}
1.35 +
1.36 +/* Framebuffer initialisation using image data. */
1.37 +
1.38 void init_framebuffer(uint32_t *data)
1.39 {
1.40 uint32_t *addr = (uint32_t *) SCREEN_BASE_KSEG0;
1.41 @@ -37,6 +68,8 @@
1.42 }
1.43 }
1.44
1.45 +/* Framebuffer initialisation using a test pattern. */
1.46 +
1.47 void init_framebuffer_with_pattern()
1.48 {
1.49 uint32_t *addr = (uint32_t *) SCREEN_BASE_KSEG0;
1.50 @@ -44,20 +77,33 @@
1.51 uint16_t x, y;
1.52 uint8_t row, offset;
1.53
1.54 + /* For each line in the screen... */
1.55 +
1.56 for (y = 0; y < LINE_COUNT; y++)
1.57 {
1.58 - /* Start each line with a base value. */
1.59 + /*
1.60 + Start each line with a base value.
1.61 + Each byte: 00bbbb00
1.62 + */
1.63
1.64 row = y / 16;
1.65 base = (row << 26) | (row << 18) | (row << 10) | (row << 2);
1.66
1.67 - /* Set the intensity bit on every other palette row. */
1.68 + /*
1.69 + Set the intensity bit on every other palette row.
1.70 + Each byte: i0bbbb00
1.71 + */
1.72
1.73 if (row % 2) base |= 0x80808080;
1.74
1.75 + /* For each word in the line... */
1.76 +
1.77 for (x = 0; x < LINE_LENGTH; x += 4)
1.78 {
1.79 - /* Combine the base value with the offset. */
1.80 + /*
1.81 + Combine the base value with the offset.
1.82 + Each byte: i0bbbboo
1.83 + */
1.84
1.85 offset = x / 20;
1.86 value = base | (offset << 24) | (offset << 16) | (offset << 8) | offset;
1.87 @@ -72,3 +118,87 @@
1.88 }
1.89 }
1.90 }
1.91 +
1.92 +/* Font-related routines. */
1.93 +
1.94 +uint8_t *find_char(uint8_t code)
1.95 +{
1.96 + return &fontdata[fontoffsets[code - fontbase]];
1.97 +}
1.98 +
1.99 +uint32_t rowdata_to_bitmap(uint8_t rowdata, uint8_t mask, uint8_t mask_limit)
1.100 +{
1.101 + uint32_t output = 0;
1.102 +
1.103 + while (mask != mask_limit)
1.104 + {
1.105 + output = output >> 8;
1.106 + if (rowdata & mask)
1.107 + output |= 0xff000000;
1.108 + mask = mask >> 1;
1.109 + }
1.110 +
1.111 + return output;
1.112 +}
1.113 +
1.114 +void blit_char(uint8_t code, uint32_t *target)
1.115 +{
1.116 + /* Get the source address of the character data. */
1.117 +
1.118 + uint8_t *source = find_char(code);
1.119 +
1.120 + /* Get the limit of the character data. */
1.121 +
1.122 + uint8_t *limit = find_char(code + 1);
1.123 + uint8_t rowdata;
1.124 +
1.125 + /*
1.126 + Read each byte of the character data, representing a row of bitmap
1.127 + cells.
1.128 + */
1.129 +
1.130 + while (source < limit)
1.131 + {
1.132 + rowdata = *source;
1.133 +
1.134 + /*
1.135 + Write two consecutive words, one for the upper four bits of the
1.136 + data, one for the lower four bits of the data.
1.137 +
1.138 + For each bit, produce an "on" or "off" byte for the bitmap cell.
1.139 + */
1.140 +
1.141 + *target = rowdata_to_bitmap(rowdata, 0x80, 0x08);
1.142 + *(wrap_address(target + 1)) = rowdata_to_bitmap(rowdata, 0x08, 0x00);
1.143 +
1.144 + /* Move on to the next line. The arithmetic employs words. */
1.145 +
1.146 + target = wrap_address(target + LINE_LENGTH / 4);
1.147 +
1.148 + /* Move on to the next data byte. */
1.149 +
1.150 + source++;
1.151 + }
1.152 +}
1.153 +
1.154 +uint32_t *char_address(uint32_t *base, uint8_t x, uint8_t y)
1.155 +{
1.156 + return wrap_address(base + (x * 2) + (y * LINE_LENGTH / 4));
1.157 +}
1.158 +
1.159 +void blit_string(uint8_t *source, uint32_t *target)
1.160 +{
1.161 + uint8_t c;
1.162 +
1.163 + /* Read byte values until a zero is found. */
1.164 +
1.165 + while ((c = *source) != 0)
1.166 + {
1.167 + blit_char(c, target);
1.168 + source++;
1.169 +
1.170 + /* Move across eight pixels (two words). */
1.171 +
1.172 + target = wrap_address(target + 2);
1.173 + }
1.174 +}