[32404] | 1 | /* $Id: DevVGATmpl.h 82109 2019-11-22 20:24:21Z vboxsync $ */
|
---|
[1] | 2 | /** @file
|
---|
[11166] | 3 | * DevVGA - VBox VGA/VESA device, code templates.
|
---|
[1] | 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[76553] | 7 | * Copyright (C) 2006-2019 Oracle Corporation
|
---|
[1] | 8 | *
|
---|
| 9 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
| 10 | * available from http://www.virtualbox.org. This file is free software;
|
---|
| 11 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
[5999] | 12 | * General Public License (GPL) as published by the Free Software
|
---|
| 13 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
| 14 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
| 15 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
[69498] | 16 | * --------------------------------------------------------------------
|
---|
[1] | 17 | *
|
---|
| 18 | * This code is based on:
|
---|
| 19 | *
|
---|
| 20 | * QEMU VGA Emulator templates
|
---|
| 21 | *
|
---|
| 22 | * Copyright (c) 2003 Fabrice Bellard
|
---|
| 23 | *
|
---|
| 24 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
---|
| 25 | * of this software and associated documentation files (the "Software"), to deal
|
---|
| 26 | * in the Software without restriction, including without limitation the rights
|
---|
| 27 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
---|
| 28 | * copies of the Software, and to permit persons to whom the Software is
|
---|
| 29 | * furnished to do so, subject to the following conditions:
|
---|
| 30 | *
|
---|
| 31 | * The above copyright notice and this permission notice shall be included in
|
---|
| 32 | * all copies or substantial portions of the Software.
|
---|
| 33 | *
|
---|
| 34 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
---|
| 35 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
| 36 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
---|
| 37 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
---|
| 38 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
---|
| 39 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
---|
| 40 | * THE SOFTWARE.
|
---|
| 41 | */
|
---|
| 42 |
|
---|
| 43 | #if DEPTH == 8
|
---|
| 44 | #define BPP 1
|
---|
[11166] | 45 | #define PIXEL_TYPE uint8_t
|
---|
[1] | 46 | #elif DEPTH == 15 || DEPTH == 16
|
---|
| 47 | #define BPP 2
|
---|
[11166] | 48 | #define PIXEL_TYPE uint16_t
|
---|
[1] | 49 | #elif DEPTH == 32
|
---|
| 50 | #define BPP 4
|
---|
[11166] | 51 | #define PIXEL_TYPE uint32_t
|
---|
[1] | 52 | #else
|
---|
| 53 | #error unsupport depth
|
---|
| 54 | #endif
|
---|
| 55 |
|
---|
| 56 | #if DEPTH != 15
|
---|
| 57 |
|
---|
[49887] | 58 | static inline void RT_CONCAT(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
|
---|
| 59 | int font_data,
|
---|
| 60 | uint32_t xorcol,
|
---|
| 61 | uint32_t bgcol,
|
---|
| 62 | int dscan,
|
---|
| 63 | int linesize)
|
---|
[1] | 64 | {
|
---|
| 65 | #if BPP == 1
|
---|
| 66 | ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
|
---|
| 67 | ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
|
---|
[34024] | 68 | if (dscan) {
|
---|
| 69 | uint8_t *c = d + linesize;
|
---|
| 70 | ((uint32_t *)c)[0] = ((uint32_t *)d)[0];
|
---|
| 71 | ((uint32_t *)c)[1] = ((uint32_t *)d)[1];
|
---|
| 72 | }
|
---|
[1] | 73 | #elif BPP == 2
|
---|
| 74 | ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
|
---|
| 75 | ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
|
---|
| 76 | ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
|
---|
| 77 | ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
|
---|
[34024] | 78 | if (dscan)
|
---|
| 79 | memcpy(d + linesize, d, 4 * sizeof(uint32_t));
|
---|
[1] | 80 | #else
|
---|
| 81 | ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
|
---|
| 82 | ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
|
---|
| 83 | ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
|
---|
| 84 | ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
|
---|
| 85 | ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
|
---|
| 86 | ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
|
---|
| 87 | ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
|
---|
| 88 | ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
|
---|
[34024] | 89 | if (dscan)
|
---|
| 90 | memcpy(d + linesize, d, 8 * sizeof(uint32_t));
|
---|
[1] | 91 | #endif
|
---|
| 92 | }
|
---|
| 93 |
|
---|
[49887] | 94 | static void RT_CONCAT(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
|
---|
| 95 | const uint8_t *font_ptr, int h,
|
---|
| 96 | uint32_t fgcol, uint32_t bgcol, int dscan)
|
---|
[1] | 97 | {
|
---|
[33974] | 98 | uint32_t xorcol;
|
---|
| 99 | int font_data;
|
---|
[11166] | 100 |
|
---|
[1] | 101 | xorcol = bgcol ^ fgcol;
|
---|
| 102 | do {
|
---|
| 103 | font_data = font_ptr[0];
|
---|
[49887] | 104 | RT_CONCAT(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol, dscan, linesize);
|
---|
[1] | 105 | font_ptr += 4;
|
---|
[34024] | 106 | d += linesize << dscan;
|
---|
[1] | 107 | } while (--h);
|
---|
| 108 | }
|
---|
| 109 |
|
---|
[49887] | 110 | static void RT_CONCAT(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
|
---|
| 111 | const uint8_t *font_ptr, int h,
|
---|
| 112 | uint32_t fgcol, uint32_t bgcol, int dscan)
|
---|
[1] | 113 | {
|
---|
[33974] | 114 | uint32_t xorcol;
|
---|
| 115 | int font_data;
|
---|
[11166] | 116 |
|
---|
[1] | 117 | xorcol = bgcol ^ fgcol;
|
---|
| 118 | do {
|
---|
| 119 | font_data = font_ptr[0];
|
---|
[49887] | 120 | RT_CONCAT(vga_draw_glyph_line_, DEPTH)(d,
|
---|
| 121 | expand4to8[font_data >> 4],
|
---|
| 122 | xorcol, bgcol, dscan, linesize);
|
---|
| 123 | RT_CONCAT(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP,
|
---|
| 124 | expand4to8[font_data & 0x0f],
|
---|
| 125 | xorcol, bgcol, dscan, linesize);
|
---|
[1] | 126 | font_ptr += 4;
|
---|
[34024] | 127 | d += linesize << dscan;
|
---|
[1] | 128 | } while (--h);
|
---|
| 129 | }
|
---|
| 130 |
|
---|
[49887] | 131 | static void RT_CONCAT(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
|
---|
| 132 | const uint8_t *font_ptr, int h,
|
---|
| 133 | uint32_t fgcol, uint32_t bgcol, int dup9)
|
---|
[1] | 134 | {
|
---|
[33974] | 135 | uint32_t xorcol, v;
|
---|
| 136 | int font_data;
|
---|
[11166] | 137 |
|
---|
[1] | 138 | xorcol = bgcol ^ fgcol;
|
---|
| 139 | do {
|
---|
| 140 | font_data = font_ptr[0];
|
---|
| 141 | #if BPP == 1
|
---|
[49887] | 142 | ((uint32_t *)d)[0] = RT_H2LE_U32((dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
|
---|
[1] | 143 | v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
|
---|
[49887] | 144 | ((uint32_t *)d)[1] = RT_H2LE_U32(v);
|
---|
[1] | 145 | if (dup9)
|
---|
| 146 | ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
|
---|
| 147 | else
|
---|
| 148 | ((uint8_t *)d)[8] = bgcol;
|
---|
[11166] | 149 |
|
---|
[1] | 150 | #elif BPP == 2
|
---|
[49887] | 151 | ((uint32_t *)d)[0] = RT_H2LE_U32((dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
|
---|
| 152 | ((uint32_t *)d)[1] = RT_H2LE_U32((dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
|
---|
| 153 | ((uint32_t *)d)[2] = RT_H2LE_U32((dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
|
---|
[1] | 154 | v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
|
---|
[49887] | 155 | ((uint32_t *)d)[3] = RT_H2LE_U32(v);
|
---|
[1] | 156 | if (dup9)
|
---|
| 157 | ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
|
---|
| 158 | else
|
---|
| 159 | ((uint16_t *)d)[8] = bgcol;
|
---|
| 160 | #else
|
---|
| 161 | ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
|
---|
| 162 | ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
|
---|
| 163 | ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
|
---|
| 164 | ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
|
---|
| 165 | ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
|
---|
| 166 | ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
|
---|
| 167 | ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
|
---|
| 168 | v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
|
---|
| 169 | ((uint32_t *)d)[7] = v;
|
---|
| 170 | if (dup9)
|
---|
| 171 | ((uint32_t *)d)[8] = v;
|
---|
| 172 | else
|
---|
| 173 | ((uint32_t *)d)[8] = bgcol;
|
---|
| 174 | #endif
|
---|
| 175 | font_ptr += 4;
|
---|
| 176 | d += linesize;
|
---|
| 177 | } while (--h);
|
---|
| 178 | }
|
---|
| 179 |
|
---|
[11166] | 180 | /*
|
---|
[1] | 181 | * 4 color mode
|
---|
| 182 | */
|
---|
[82109] | 183 | static void RT_CONCAT(vga_draw_line2_, DEPTH)(VGAState *s1, PVGASTATER3 pThisCC, uint8_t *d,
|
---|
[49887] | 184 | const uint8_t *s, int width)
|
---|
[1] | 185 | {
|
---|
[4682] | 186 | uint32_t plane_mask, *palette, data, v, src_inc, dwb_mode;
|
---|
[1] | 187 | int x;
|
---|
[82109] | 188 | RT_NOREF(pThisCC);
|
---|
[1] | 189 |
|
---|
| 190 | palette = s1->last_palette;
|
---|
| 191 | plane_mask = mask16[s1->ar[0x12] & 0xf];
|
---|
[4682] | 192 | dwb_mode = (s1->cr[0x14] & 0x40) ? 2 : (s1->cr[0x17] & 0x40) ? 0 : 1;
|
---|
| 193 | src_inc = 4 << dwb_mode;
|
---|
[1] | 194 | width >>= 3;
|
---|
| 195 | for(x = 0; x < width; x++) {
|
---|
| 196 | data = ((uint32_t *)s)[0];
|
---|
| 197 | data &= plane_mask;
|
---|
| 198 | v = expand2[GET_PLANE(data, 0)];
|
---|
| 199 | v |= expand2[GET_PLANE(data, 2)] << 2;
|
---|
| 200 | ((PIXEL_TYPE *)d)[0] = palette[v >> 12];
|
---|
| 201 | ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
|
---|
| 202 | ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
|
---|
| 203 | ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
|
---|
| 204 |
|
---|
| 205 | v = expand2[GET_PLANE(data, 1)];
|
---|
| 206 | v |= expand2[GET_PLANE(data, 3)] << 2;
|
---|
| 207 | ((PIXEL_TYPE *)d)[4] = palette[v >> 12];
|
---|
| 208 | ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
|
---|
| 209 | ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
|
---|
| 210 | ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
|
---|
| 211 | d += BPP * 8;
|
---|
[4682] | 212 | s += src_inc;
|
---|
[1] | 213 | }
|
---|
| 214 | }
|
---|
| 215 |
|
---|
| 216 | #if BPP == 1
|
---|
| 217 | #define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v)
|
---|
| 218 | #elif BPP == 2
|
---|
| 219 | #define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v)
|
---|
| 220 | #else
|
---|
| 221 | #define PUT_PIXEL2(d, n, v) \
|
---|
| 222 | ((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
|
---|
| 223 | #endif
|
---|
| 224 |
|
---|
[11166] | 225 | /*
|
---|
[1] | 226 | * 4 color mode, dup2 horizontal
|
---|
| 227 | */
|
---|
[82109] | 228 | static void RT_CONCAT(vga_draw_line2d2_, DEPTH)(VGAState *s1, PVGASTATER3 pThisCC, uint8_t *d,
|
---|
[49887] | 229 | const uint8_t *s, int width)
|
---|
[1] | 230 | {
|
---|
[4682] | 231 | uint32_t plane_mask, *palette, data, v, src_inc, dwb_mode;
|
---|
[1] | 232 | int x;
|
---|
[82109] | 233 | RT_NOREF(pThisCC);
|
---|
[1] | 234 |
|
---|
| 235 | palette = s1->last_palette;
|
---|
| 236 | plane_mask = mask16[s1->ar[0x12] & 0xf];
|
---|
[4682] | 237 | dwb_mode = (s1->cr[0x14] & 0x40) ? 2 : (s1->cr[0x17] & 0x40) ? 0 : 1;
|
---|
| 238 | src_inc = 4 << dwb_mode;
|
---|
[1] | 239 | width >>= 3;
|
---|
| 240 | for(x = 0; x < width; x++) {
|
---|
| 241 | data = ((uint32_t *)s)[0];
|
---|
| 242 | data &= plane_mask;
|
---|
| 243 | v = expand2[GET_PLANE(data, 0)];
|
---|
| 244 | v |= expand2[GET_PLANE(data, 2)] << 2;
|
---|
| 245 | PUT_PIXEL2(d, 0, palette[v >> 12]);
|
---|
| 246 | PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
|
---|
| 247 | PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
|
---|
| 248 | PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
|
---|
| 249 |
|
---|
| 250 | v = expand2[GET_PLANE(data, 1)];
|
---|
| 251 | v |= expand2[GET_PLANE(data, 3)] << 2;
|
---|
| 252 | PUT_PIXEL2(d, 4, palette[v >> 12]);
|
---|
| 253 | PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
|
---|
| 254 | PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
|
---|
| 255 | PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
|
---|
| 256 | d += BPP * 16;
|
---|
[4682] | 257 | s += src_inc;
|
---|
[1] | 258 | }
|
---|
| 259 | }
|
---|
| 260 |
|
---|
[11166] | 261 | /*
|
---|
[1] | 262 | * 16 color mode
|
---|
| 263 | */
|
---|
[82109] | 264 | static void RT_CONCAT(vga_draw_line4_, DEPTH)(VGAState *s1, PVGASTATER3 pThisCC, uint8_t *d,
|
---|
[49887] | 265 | const uint8_t *s, int width)
|
---|
[1] | 266 | {
|
---|
[67766] | 267 | uint32_t plane_mask, data, v, *palette, vram_ofs;
|
---|
[1] | 268 | int x;
|
---|
[82109] | 269 | RT_NOREF(pThisCC);
|
---|
[1] | 270 |
|
---|
[82109] | 271 | vram_ofs = s - pThisCC->pbVRam;
|
---|
[1] | 272 | palette = s1->last_palette;
|
---|
| 273 | plane_mask = mask16[s1->ar[0x12] & 0xf];
|
---|
| 274 | width >>= 3;
|
---|
| 275 | for(x = 0; x < width; x++) {
|
---|
[82109] | 276 | s = pThisCC->pbVRam + (vram_ofs & s1->vga_addr_mask);
|
---|
[1] | 277 | data = ((uint32_t *)s)[0];
|
---|
| 278 | data &= plane_mask;
|
---|
| 279 | v = expand4[GET_PLANE(data, 0)];
|
---|
| 280 | v |= expand4[GET_PLANE(data, 1)] << 1;
|
---|
| 281 | v |= expand4[GET_PLANE(data, 2)] << 2;
|
---|
| 282 | v |= expand4[GET_PLANE(data, 3)] << 3;
|
---|
| 283 | ((PIXEL_TYPE *)d)[0] = palette[v >> 28];
|
---|
| 284 | ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
|
---|
| 285 | ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
|
---|
| 286 | ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
|
---|
| 287 | ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
|
---|
| 288 | ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
|
---|
| 289 | ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
|
---|
| 290 | ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
|
---|
| 291 | d += BPP * 8;
|
---|
[67766] | 292 | vram_ofs += 4;
|
---|
[1] | 293 | }
|
---|
| 294 | }
|
---|
| 295 |
|
---|
[11166] | 296 | /*
|
---|
[1] | 297 | * 16 color mode, dup2 horizontal
|
---|
| 298 | */
|
---|
[82109] | 299 | static void RT_CONCAT(vga_draw_line4d2_, DEPTH)(VGAState *s1, PVGASTATER3 pThisCC, uint8_t *d,
|
---|
[49887] | 300 | const uint8_t *s, int width)
|
---|
[1] | 301 | {
|
---|
| 302 | uint32_t plane_mask, data, v, *palette;
|
---|
| 303 | int x;
|
---|
[82109] | 304 | RT_NOREF(pThisCC);
|
---|
[1] | 305 |
|
---|
| 306 | palette = s1->last_palette;
|
---|
| 307 | plane_mask = mask16[s1->ar[0x12] & 0xf];
|
---|
| 308 | width >>= 3;
|
---|
| 309 | for(x = 0; x < width; x++) {
|
---|
| 310 | data = ((uint32_t *)s)[0];
|
---|
| 311 | data &= plane_mask;
|
---|
| 312 | v = expand4[GET_PLANE(data, 0)];
|
---|
| 313 | v |= expand4[GET_PLANE(data, 1)] << 1;
|
---|
| 314 | v |= expand4[GET_PLANE(data, 2)] << 2;
|
---|
| 315 | v |= expand4[GET_PLANE(data, 3)] << 3;
|
---|
| 316 | PUT_PIXEL2(d, 0, palette[v >> 28]);
|
---|
| 317 | PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
|
---|
| 318 | PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
|
---|
| 319 | PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
|
---|
| 320 | PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
|
---|
| 321 | PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
|
---|
| 322 | PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
|
---|
| 323 | PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
|
---|
| 324 | d += BPP * 16;
|
---|
| 325 | s += 4;
|
---|
| 326 | }
|
---|
| 327 | }
|
---|
| 328 |
|
---|
[11166] | 329 | /*
|
---|
[1] | 330 | * 256 color mode, double pixels
|
---|
| 331 | *
|
---|
| 332 | * XXX: add plane_mask support (never used in standard VGA modes)
|
---|
| 333 | */
|
---|
[82109] | 334 | static void RT_CONCAT(vga_draw_line8d2_, DEPTH)(VGAState *s1, PVGASTATER3 pThisCC, uint8_t *d,
|
---|
[49887] | 335 | const uint8_t *s, int width)
|
---|
[1] | 336 | {
|
---|
| 337 | uint32_t *palette;
|
---|
| 338 | int x;
|
---|
[82109] | 339 | RT_NOREF(pThisCC);
|
---|
[1] | 340 |
|
---|
| 341 | palette = s1->last_palette;
|
---|
| 342 | width >>= 3;
|
---|
| 343 | for(x = 0; x < width; x++) {
|
---|
| 344 | PUT_PIXEL2(d, 0, palette[s[0]]);
|
---|
| 345 | PUT_PIXEL2(d, 1, palette[s[1]]);
|
---|
| 346 | PUT_PIXEL2(d, 2, palette[s[2]]);
|
---|
| 347 | PUT_PIXEL2(d, 3, palette[s[3]]);
|
---|
| 348 | d += BPP * 8;
|
---|
| 349 | s += 4;
|
---|
| 350 | }
|
---|
| 351 | }
|
---|
| 352 |
|
---|
[11166] | 353 | /*
|
---|
[1] | 354 | * standard 256 color mode
|
---|
| 355 | *
|
---|
| 356 | * XXX: add plane_mask support (never used in standard VGA modes)
|
---|
| 357 | */
|
---|
[82109] | 358 | static void RT_CONCAT(vga_draw_line8_, DEPTH)(VGAState *s1, PVGASTATER3 pThisCC, uint8_t *d,
|
---|
[49887] | 359 | const uint8_t *s, int width)
|
---|
[1] | 360 | {
|
---|
| 361 | uint32_t *palette;
|
---|
| 362 | int x;
|
---|
[82109] | 363 | RT_NOREF(pThisCC);
|
---|
[1] | 364 |
|
---|
| 365 | palette = s1->last_palette;
|
---|
| 366 | width >>= 3;
|
---|
| 367 | for(x = 0; x < width; x++) {
|
---|
| 368 | ((PIXEL_TYPE *)d)[0] = palette[s[0]];
|
---|
| 369 | ((PIXEL_TYPE *)d)[1] = palette[s[1]];
|
---|
| 370 | ((PIXEL_TYPE *)d)[2] = palette[s[2]];
|
---|
| 371 | ((PIXEL_TYPE *)d)[3] = palette[s[3]];
|
---|
| 372 | ((PIXEL_TYPE *)d)[4] = palette[s[4]];
|
---|
| 373 | ((PIXEL_TYPE *)d)[5] = palette[s[5]];
|
---|
| 374 | ((PIXEL_TYPE *)d)[6] = palette[s[6]];
|
---|
| 375 | ((PIXEL_TYPE *)d)[7] = palette[s[7]];
|
---|
| 376 | d += BPP * 8;
|
---|
| 377 | s += 8;
|
---|
| 378 | }
|
---|
| 379 | }
|
---|
| 380 |
|
---|
| 381 | #endif /* DEPTH != 15 */
|
---|
| 382 |
|
---|
| 383 |
|
---|
| 384 | /* XXX: optimize */
|
---|
| 385 |
|
---|
[11166] | 386 | /*
|
---|
[1] | 387 | * 15 bit color
|
---|
| 388 | */
|
---|
[82109] | 389 | static void RT_CONCAT(vga_draw_line15_, DEPTH)(VGAState *s1, PVGASTATER3 pThisCC, uint8_t *d,
|
---|
[49887] | 390 | const uint8_t *s, int width)
|
---|
[1] | 391 | {
|
---|
[82109] | 392 | RT_NOREF(s1, pThisCC);
|
---|
[1] | 393 | #if DEPTH == 15 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
|
---|
| 394 | memcpy(d, s, width * 2);
|
---|
| 395 | #else
|
---|
| 396 | int w;
|
---|
| 397 | uint32_t v, r, g, b;
|
---|
| 398 |
|
---|
| 399 | w = width;
|
---|
| 400 | do {
|
---|
[49887] | 401 | v = s[0] | (s[1] << 8);
|
---|
[1] | 402 | r = (v >> 7) & 0xf8;
|
---|
| 403 | g = (v >> 2) & 0xf8;
|
---|
| 404 | b = (v << 3) & 0xf8;
|
---|
[49887] | 405 | ((PIXEL_TYPE *)d)[0] = RT_CONCAT(rgb_to_pixel, DEPTH)(r, g, b);
|
---|
[1] | 406 | s += 2;
|
---|
| 407 | d += BPP;
|
---|
| 408 | } while (--w != 0);
|
---|
[11166] | 409 | #endif
|
---|
[1] | 410 | }
|
---|
| 411 |
|
---|
[11166] | 412 | /*
|
---|
[1] | 413 | * 16 bit color
|
---|
| 414 | */
|
---|
[82109] | 415 | static void RT_CONCAT(vga_draw_line16_, DEPTH)(VGAState *s1, PVGASTATER3 pThisCC, uint8_t *d,
|
---|
[49887] | 416 | const uint8_t *s, int width)
|
---|
[1] | 417 | {
|
---|
[82109] | 418 | RT_NOREF(s1, pThisCC);
|
---|
[1] | 419 | #if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
|
---|
| 420 | memcpy(d, s, width * 2);
|
---|
| 421 | #else
|
---|
| 422 | int w;
|
---|
| 423 | uint32_t v, r, g, b;
|
---|
| 424 |
|
---|
| 425 | w = width;
|
---|
| 426 | do {
|
---|
[49887] | 427 | v = s[0] | (s[1] << 8);
|
---|
[1] | 428 | r = (v >> 8) & 0xf8;
|
---|
| 429 | g = (v >> 3) & 0xfc;
|
---|
| 430 | b = (v << 3) & 0xf8;
|
---|
[49887] | 431 | ((PIXEL_TYPE *)d)[0] = RT_CONCAT(rgb_to_pixel, DEPTH)(r, g, b);
|
---|
[1] | 432 | s += 2;
|
---|
| 433 | d += BPP;
|
---|
| 434 | } while (--w != 0);
|
---|
[11166] | 435 | #endif
|
---|
[1] | 436 | }
|
---|
| 437 |
|
---|
[11166] | 438 | /*
|
---|
[1] | 439 | * 24 bit color
|
---|
| 440 | */
|
---|
[82109] | 441 | static void RT_CONCAT(vga_draw_line24_, DEPTH)(VGAState *s1, PVGASTATER3 pThisCC, uint8_t *d,
|
---|
[49887] | 442 | const uint8_t *s, int width)
|
---|
[1] | 443 | {
|
---|
| 444 | int w;
|
---|
| 445 | uint32_t r, g, b;
|
---|
[82109] | 446 | RT_NOREF(s1, pThisCC);
|
---|
[1] | 447 |
|
---|
| 448 | w = width;
|
---|
| 449 | do {
|
---|
| 450 | #if defined(TARGET_WORDS_BIGENDIAN)
|
---|
| 451 | r = s[0];
|
---|
| 452 | g = s[1];
|
---|
| 453 | b = s[2];
|
---|
| 454 | #else
|
---|
| 455 | b = s[0];
|
---|
| 456 | g = s[1];
|
---|
| 457 | r = s[2];
|
---|
| 458 | #endif
|
---|
[49887] | 459 | ((PIXEL_TYPE *)d)[0] = RT_CONCAT(rgb_to_pixel, DEPTH)(r, g, b);
|
---|
[1] | 460 | s += 3;
|
---|
| 461 | d += BPP;
|
---|
| 462 | } while (--w != 0);
|
---|
| 463 | }
|
---|
| 464 |
|
---|
[11166] | 465 | /*
|
---|
[1] | 466 | * 32 bit color
|
---|
| 467 | */
|
---|
[82109] | 468 | static void RT_CONCAT(vga_draw_line32_, DEPTH)(VGAState *s1, PVGASTATER3 pThisCC, uint8_t *d,
|
---|
[49887] | 469 | const uint8_t *s, int width)
|
---|
[1] | 470 | {
|
---|
[82109] | 471 | RT_NOREF(s1, pThisCC);
|
---|
[1] | 472 | #if DEPTH == 32 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
|
---|
| 473 | memcpy(d, s, width * 4);
|
---|
| 474 | #else
|
---|
| 475 | int w;
|
---|
| 476 | uint32_t r, g, b;
|
---|
| 477 |
|
---|
| 478 | w = width;
|
---|
| 479 | do {
|
---|
| 480 | #if defined(TARGET_WORDS_BIGENDIAN)
|
---|
| 481 | r = s[1];
|
---|
| 482 | g = s[2];
|
---|
| 483 | b = s[3];
|
---|
| 484 | #else
|
---|
| 485 | b = s[0];
|
---|
| 486 | g = s[1];
|
---|
| 487 | r = s[2];
|
---|
| 488 | #endif
|
---|
[49887] | 489 | ((PIXEL_TYPE *)d)[0] = RT_CONCAT(rgb_to_pixel, DEPTH)(r, g, b);
|
---|
[1] | 490 | s += 4;
|
---|
| 491 | d += BPP;
|
---|
| 492 | } while (--w != 0);
|
---|
| 493 | #endif
|
---|
| 494 | }
|
---|
| 495 |
|
---|
| 496 | #if DEPTH != 15
|
---|
| 497 | #ifndef VBOX
|
---|
| 498 | #ifdef VBOX
|
---|
| 499 | static
|
---|
[11166] | 500 | #endif/* VBOX */
|
---|
[49887] | 501 | void RT_CONCAT(vga_draw_cursor_line_, DEPTH)(uint8_t *d1,
|
---|
| 502 | const uint8_t *src1,
|
---|
| 503 | int poffset, int w,
|
---|
| 504 | unsigned int color0,
|
---|
| 505 | unsigned int color1,
|
---|
| 506 | unsigned int color_xor)
|
---|
[1] | 507 | {
|
---|
| 508 | const uint8_t *plane0, *plane1;
|
---|
| 509 | int x, b0, b1;
|
---|
| 510 | uint8_t *d;
|
---|
| 511 |
|
---|
| 512 | d = d1;
|
---|
| 513 | plane0 = src1;
|
---|
| 514 | plane1 = src1 + poffset;
|
---|
| 515 | for(x = 0; x < w; x++) {
|
---|
| 516 | b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
|
---|
| 517 | b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
|
---|
| 518 | #if DEPTH == 8
|
---|
| 519 | switch(b0 | (b1 << 1)) {
|
---|
| 520 | case 0:
|
---|
| 521 | break;
|
---|
| 522 | case 1:
|
---|
| 523 | d[0] ^= color_xor;
|
---|
| 524 | break;
|
---|
| 525 | case 2:
|
---|
| 526 | d[0] = color0;
|
---|
| 527 | break;
|
---|
| 528 | case 3:
|
---|
| 529 | d[0] = color1;
|
---|
| 530 | break;
|
---|
| 531 | }
|
---|
| 532 | #elif DEPTH == 16
|
---|
| 533 | switch(b0 | (b1 << 1)) {
|
---|
| 534 | case 0:
|
---|
| 535 | break;
|
---|
| 536 | case 1:
|
---|
| 537 | ((uint16_t *)d)[0] ^= color_xor;
|
---|
| 538 | break;
|
---|
| 539 | case 2:
|
---|
| 540 | ((uint16_t *)d)[0] = color0;
|
---|
| 541 | break;
|
---|
| 542 | case 3:
|
---|
| 543 | ((uint16_t *)d)[0] = color1;
|
---|
| 544 | break;
|
---|
| 545 | }
|
---|
| 546 | #elif DEPTH == 32
|
---|
| 547 | switch(b0 | (b1 << 1)) {
|
---|
| 548 | case 0:
|
---|
| 549 | break;
|
---|
| 550 | case 1:
|
---|
| 551 | ((uint32_t *)d)[0] ^= color_xor;
|
---|
| 552 | break;
|
---|
| 553 | case 2:
|
---|
| 554 | ((uint32_t *)d)[0] = color0;
|
---|
| 555 | break;
|
---|
| 556 | case 3:
|
---|
| 557 | ((uint32_t *)d)[0] = color1;
|
---|
| 558 | break;
|
---|
| 559 | }
|
---|
| 560 | #else
|
---|
| 561 | #error unsupported depth
|
---|
| 562 | #endif
|
---|
| 563 | d += BPP;
|
---|
| 564 | }
|
---|
| 565 | }
|
---|
| 566 | #endif /* !VBOX */
|
---|
| 567 | #endif
|
---|
| 568 |
|
---|
| 569 | #undef PUT_PIXEL2
|
---|
| 570 | #undef DEPTH
|
---|
| 571 | #undef BPP
|
---|
| 572 | #undef PIXEL_TYPE
|
---|