123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 |
- /*
- * QEMU VGA Emulator templates
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
- static inline void vga_draw_glyph_line(uint8_t *d, uint32_t font_data,
- uint32_t xorcol, uint32_t bgcol)
- {
- ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
- }
- static void vga_draw_glyph8(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol)
- {
- uint32_t font_data, xorcol;
- xorcol = bgcol ^ fgcol;
- do {
- font_data = font_ptr[0];
- vga_draw_glyph_line(d, font_data, xorcol, bgcol);
- font_ptr += 4;
- d += linesize;
- } while (--h);
- }
- static void vga_draw_glyph16(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol)
- {
- uint32_t font_data, xorcol;
- xorcol = bgcol ^ fgcol;
- do {
- font_data = font_ptr[0];
- vga_draw_glyph_line(d, expand4to8[font_data >> 4],
- xorcol, bgcol);
- vga_draw_glyph_line(d + 32, expand4to8[font_data & 0x0f],
- xorcol, bgcol);
- font_ptr += 4;
- d += linesize;
- } while (--h);
- }
- static void vga_draw_glyph9(uint8_t *d, int linesize,
- const uint8_t *font_ptr, int h,
- uint32_t fgcol, uint32_t bgcol, int dup9)
- {
- uint32_t font_data, xorcol, v;
- xorcol = bgcol ^ fgcol;
- do {
- font_data = font_ptr[0];
- ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
- v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[7] = v;
- if (dup9)
- ((uint32_t *)d)[8] = v;
- else
- ((uint32_t *)d)[8] = bgcol;
- font_ptr += 4;
- d += linesize;
- } while (--h);
- }
- /*
- * 4 color mode
- */
- static void *vga_draw_line2(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- uint32_t plane_mask, *palette, data, v;
- int x;
- palette = vga->last_palette;
- plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
- hpel &= 7;
- if (hpel) {
- width += 8;
- d = vga->panning_buf;
- }
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
- data &= plane_mask;
- v = expand2[GET_PLANE(data, 0)];
- v |= expand2[GET_PLANE(data, 2)] << 2;
- ((uint32_t *)d)[0] = palette[v >> 12];
- ((uint32_t *)d)[1] = palette[(v >> 8) & 0xf];
- ((uint32_t *)d)[2] = palette[(v >> 4) & 0xf];
- ((uint32_t *)d)[3] = palette[(v >> 0) & 0xf];
- v = expand2[GET_PLANE(data, 1)];
- v |= expand2[GET_PLANE(data, 3)] << 2;
- ((uint32_t *)d)[4] = palette[v >> 12];
- ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
- ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
- ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
- d += 32;
- addr += 4;
- }
- return hpel ? vga->panning_buf + 4 * hpel : NULL;
- }
- #define PUT_PIXEL2(d, n, v) \
- ((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
- /*
- * 4 color mode, dup2 horizontal
- */
- static void *vga_draw_line2d2(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- uint32_t plane_mask, *palette, data, v;
- int x;
- palette = vga->last_palette;
- plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
- hpel &= 7;
- if (hpel) {
- width += 8;
- d = vga->panning_buf;
- }
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
- data &= plane_mask;
- v = expand2[GET_PLANE(data, 0)];
- v |= expand2[GET_PLANE(data, 2)] << 2;
- PUT_PIXEL2(d, 0, palette[v >> 12]);
- PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
- PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
- PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
- v = expand2[GET_PLANE(data, 1)];
- v |= expand2[GET_PLANE(data, 3)] << 2;
- PUT_PIXEL2(d, 4, palette[v >> 12]);
- PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
- PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
- PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
- d += 64;
- addr += 4;
- }
- return hpel ? vga->panning_buf + 8 * hpel : NULL;
- }
- /*
- * 16 color mode
- */
- static void *vga_draw_line4(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- uint32_t plane_mask, data, v, *palette;
- int x;
- palette = vga->last_palette;
- plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
- hpel &= 7;
- if (hpel) {
- width += 8;
- d = vga->panning_buf;
- }
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
- data &= plane_mask;
- v = expand4[GET_PLANE(data, 0)];
- v |= expand4[GET_PLANE(data, 1)] << 1;
- v |= expand4[GET_PLANE(data, 2)] << 2;
- v |= expand4[GET_PLANE(data, 3)] << 3;
- ((uint32_t *)d)[0] = palette[v >> 28];
- ((uint32_t *)d)[1] = palette[(v >> 24) & 0xf];
- ((uint32_t *)d)[2] = palette[(v >> 20) & 0xf];
- ((uint32_t *)d)[3] = palette[(v >> 16) & 0xf];
- ((uint32_t *)d)[4] = palette[(v >> 12) & 0xf];
- ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
- ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
- ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
- d += 32;
- addr += 4;
- }
- return hpel ? vga->panning_buf + 4 * hpel : NULL;
- }
- /*
- * 16 color mode, dup2 horizontal
- */
- static void *vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- uint32_t plane_mask, data, v, *palette;
- int x;
- palette = vga->last_palette;
- plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
- hpel &= 7;
- if (hpel) {
- width += 8;
- d = vga->panning_buf;
- }
- width >>= 3;
- for(x = 0; x < width; x++) {
- data = vga_read_dword_le(vga, addr & (VGA_VRAM_SIZE - 1));
- data &= plane_mask;
- v = expand4[GET_PLANE(data, 0)];
- v |= expand4[GET_PLANE(data, 1)] << 1;
- v |= expand4[GET_PLANE(data, 2)] << 2;
- v |= expand4[GET_PLANE(data, 3)] << 3;
- PUT_PIXEL2(d, 0, palette[v >> 28]);
- PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
- PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
- PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
- PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
- PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
- PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
- PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
- d += 64;
- addr += 4;
- }
- return hpel ? vga->panning_buf + 8 * hpel : NULL;
- }
- /*
- * 256 color mode, double pixels
- *
- * XXX: add plane_mask support (never used in standard VGA modes)
- */
- static void *vga_draw_line8d2(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- uint32_t *palette;
- int x;
- palette = vga->last_palette;
- hpel = (hpel >> 1) & 3;
- /* For 256 color modes, we can adjust the source address and write directly
- * to the destination, even if horizontal pel panning is active. However,
- * the loop below assumes that the address does not wrap in the middle of a
- * plane. If that happens...
- */
- if (addr + (width >> 3) * 4 < VGA_VRAM_SIZE) {
- addr += hpel * 4;
- hpel = 0;
- }
- /* ... use the panning buffer as in planar modes. */
- if (hpel) {
- width += 8;
- d = vga->panning_buf;
- }
- width >>= 3;
- for(x = 0; x < width; x++) {
- addr &= VGA_VRAM_SIZE - 1;
- PUT_PIXEL2(d, 0, palette[vga_read_byte(vga, addr + 0)]);
- PUT_PIXEL2(d, 1, palette[vga_read_byte(vga, addr + 1)]);
- PUT_PIXEL2(d, 2, palette[vga_read_byte(vga, addr + 2)]);
- PUT_PIXEL2(d, 3, palette[vga_read_byte(vga, addr + 3)]);
- d += 32;
- addr += 4;
- }
- return hpel ? vga->panning_buf + 8 * hpel : NULL;
- }
- /*
- * standard 256 color mode
- *
- * XXX: add plane_mask support (never used in standard VGA modes)
- */
- static void *vga_draw_line8(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- uint32_t *palette;
- int x;
- palette = vga->last_palette;
- hpel = (hpel >> 1) & 3;
- if (hpel) {
- width += 8;
- d = vga->panning_buf;
- }
- width >>= 3;
- for(x = 0; x < width; x++) {
- ((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)];
- ((uint32_t *)d)[1] = palette[vga_read_byte(vga, addr + 1)];
- ((uint32_t *)d)[2] = palette[vga_read_byte(vga, addr + 2)];
- ((uint32_t *)d)[3] = palette[vga_read_byte(vga, addr + 3)];
- ((uint32_t *)d)[4] = palette[vga_read_byte(vga, addr + 4)];
- ((uint32_t *)d)[5] = palette[vga_read_byte(vga, addr + 5)];
- ((uint32_t *)d)[6] = palette[vga_read_byte(vga, addr + 6)];
- ((uint32_t *)d)[7] = palette[vga_read_byte(vga, addr + 7)];
- d += 32;
- addr += 8;
- }
- return hpel ? vga->panning_buf + 4 * hpel : NULL;
- }
- /*
- * 15 bit color
- */
- static void *vga_draw_line15_le(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- int w;
- uint32_t v, r, g, b;
- w = width;
- do {
- v = vga_read_word_le(vga, addr);
- r = (v >> 7) & 0xf8;
- g = (v >> 2) & 0xf8;
- b = (v << 3) & 0xf8;
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- addr += 2;
- d += 4;
- } while (--w != 0);
- return NULL;
- }
- static void *vga_draw_line15_be(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- int w;
- uint32_t v, r, g, b;
- w = width;
- do {
- v = vga_read_word_be(vga, addr);
- r = (v >> 7) & 0xf8;
- g = (v >> 2) & 0xf8;
- b = (v << 3) & 0xf8;
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- addr += 2;
- d += 4;
- } while (--w != 0);
- return NULL;
- }
- /*
- * 16 bit color
- */
- static void *vga_draw_line16_le(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- int w;
- uint32_t v, r, g, b;
- w = width;
- do {
- v = vga_read_word_le(vga, addr);
- r = (v >> 8) & 0xf8;
- g = (v >> 3) & 0xfc;
- b = (v << 3) & 0xf8;
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- addr += 2;
- d += 4;
- } while (--w != 0);
- return NULL;
- }
- static void *vga_draw_line16_be(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- int w;
- uint32_t v, r, g, b;
- w = width;
- do {
- v = vga_read_word_be(vga, addr);
- r = (v >> 8) & 0xf8;
- g = (v >> 3) & 0xfc;
- b = (v << 3) & 0xf8;
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- addr += 2;
- d += 4;
- } while (--w != 0);
- return NULL;
- }
- /*
- * 24 bit color
- */
- static void *vga_draw_line24_le(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- int w;
- uint32_t r, g, b;
- w = width;
- do {
- b = vga_read_byte(vga, addr + 0);
- g = vga_read_byte(vga, addr + 1);
- r = vga_read_byte(vga, addr + 2);
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- addr += 3;
- d += 4;
- } while (--w != 0);
- return NULL;
- }
- static void *vga_draw_line24_be(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- int w;
- uint32_t r, g, b;
- w = width;
- do {
- r = vga_read_byte(vga, addr + 0);
- g = vga_read_byte(vga, addr + 1);
- b = vga_read_byte(vga, addr + 2);
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- addr += 3;
- d += 4;
- } while (--w != 0);
- return NULL;
- }
- /*
- * 32 bit color
- */
- static void *vga_draw_line32_le(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- int w;
- uint32_t r, g, b;
- w = width;
- do {
- b = vga_read_byte(vga, addr + 0);
- g = vga_read_byte(vga, addr + 1);
- r = vga_read_byte(vga, addr + 2);
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- addr += 4;
- d += 4;
- } while (--w != 0);
- return NULL;
- }
- static void *vga_draw_line32_be(VGACommonState *vga, uint8_t *d,
- uint32_t addr, int width, int hpel)
- {
- int w;
- uint32_t r, g, b;
- w = width;
- do {
- r = vga_read_byte(vga, addr + 1);
- g = vga_read_byte(vga, addr + 2);
- b = vga_read_byte(vga, addr + 3);
- ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
- addr += 4;
- d += 4;
- } while (--w != 0);
- return NULL;
- }
|