vga-helpers.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. /*
  2. * QEMU VGA Emulator templates
  3. *
  4. * Copyright (c) 2003 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. static inline void vga_draw_glyph_line(uint8_t *d, uint32_t font_data,
  25. uint32_t xorcol, uint32_t bgcol)
  26. {
  27. ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
  28. ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
  29. ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
  30. ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
  31. ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
  32. ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
  33. ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
  34. ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
  35. }
  36. static void vga_draw_glyph8(uint8_t *d, int linesize,
  37. const uint8_t *font_ptr, int h,
  38. uint32_t fgcol, uint32_t bgcol)
  39. {
  40. uint32_t font_data, xorcol;
  41. xorcol = bgcol ^ fgcol;
  42. do {
  43. font_data = font_ptr[0];
  44. vga_draw_glyph_line(d, font_data, xorcol, bgcol);
  45. font_ptr += 4;
  46. d += linesize;
  47. } while (--h);
  48. }
  49. static void vga_draw_glyph16(uint8_t *d, int linesize,
  50. const uint8_t *font_ptr, int h,
  51. uint32_t fgcol, uint32_t bgcol)
  52. {
  53. uint32_t font_data, xorcol;
  54. xorcol = bgcol ^ fgcol;
  55. do {
  56. font_data = font_ptr[0];
  57. vga_draw_glyph_line(d, expand4to8[font_data >> 4],
  58. xorcol, bgcol);
  59. vga_draw_glyph_line(d + 32, expand4to8[font_data & 0x0f],
  60. xorcol, bgcol);
  61. font_ptr += 4;
  62. d += linesize;
  63. } while (--h);
  64. }
  65. static void vga_draw_glyph9(uint8_t *d, int linesize,
  66. const uint8_t *font_ptr, int h,
  67. uint32_t fgcol, uint32_t bgcol, int dup9)
  68. {
  69. uint32_t font_data, xorcol, v;
  70. xorcol = bgcol ^ fgcol;
  71. do {
  72. font_data = font_ptr[0];
  73. ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
  74. ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
  75. ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
  76. ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
  77. ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
  78. ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
  79. ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
  80. v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
  81. ((uint32_t *)d)[7] = v;
  82. if (dup9)
  83. ((uint32_t *)d)[8] = v;
  84. else
  85. ((uint32_t *)d)[8] = bgcol;
  86. font_ptr += 4;
  87. d += linesize;
  88. } while (--h);
  89. }
  90. /*
  91. * 4 color mode
  92. */
  93. static void vga_draw_line2(VGACommonState *vga, uint8_t *d,
  94. uint32_t addr, int width)
  95. {
  96. uint32_t plane_mask, *palette, data, v;
  97. int x;
  98. palette = vga->last_palette;
  99. plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
  100. width >>= 3;
  101. for(x = 0; x < width; x++) {
  102. data = vga_read_dword_le(vga, addr);
  103. data &= plane_mask;
  104. v = expand2[GET_PLANE(data, 0)];
  105. v |= expand2[GET_PLANE(data, 2)] << 2;
  106. ((uint32_t *)d)[0] = palette[v >> 12];
  107. ((uint32_t *)d)[1] = palette[(v >> 8) & 0xf];
  108. ((uint32_t *)d)[2] = palette[(v >> 4) & 0xf];
  109. ((uint32_t *)d)[3] = palette[(v >> 0) & 0xf];
  110. v = expand2[GET_PLANE(data, 1)];
  111. v |= expand2[GET_PLANE(data, 3)] << 2;
  112. ((uint32_t *)d)[4] = palette[v >> 12];
  113. ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
  114. ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
  115. ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
  116. d += 32;
  117. addr += 4;
  118. }
  119. }
  120. #define PUT_PIXEL2(d, n, v) \
  121. ((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
  122. /*
  123. * 4 color mode, dup2 horizontal
  124. */
  125. static void vga_draw_line2d2(VGACommonState *vga, uint8_t *d,
  126. uint32_t addr, int width)
  127. {
  128. uint32_t plane_mask, *palette, data, v;
  129. int x;
  130. palette = vga->last_palette;
  131. plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
  132. width >>= 3;
  133. for(x = 0; x < width; x++) {
  134. data = vga_read_dword_le(vga, addr);
  135. data &= plane_mask;
  136. v = expand2[GET_PLANE(data, 0)];
  137. v |= expand2[GET_PLANE(data, 2)] << 2;
  138. PUT_PIXEL2(d, 0, palette[v >> 12]);
  139. PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
  140. PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
  141. PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
  142. v = expand2[GET_PLANE(data, 1)];
  143. v |= expand2[GET_PLANE(data, 3)] << 2;
  144. PUT_PIXEL2(d, 4, palette[v >> 12]);
  145. PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
  146. PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
  147. PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
  148. d += 64;
  149. addr += 4;
  150. }
  151. }
  152. /*
  153. * 16 color mode
  154. */
  155. static void vga_draw_line4(VGACommonState *vga, uint8_t *d,
  156. uint32_t addr, int width)
  157. {
  158. uint32_t plane_mask, data, v, *palette;
  159. int x;
  160. palette = vga->last_palette;
  161. plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
  162. width >>= 3;
  163. for(x = 0; x < width; x++) {
  164. data = vga_read_dword_le(vga, addr);
  165. data &= plane_mask;
  166. v = expand4[GET_PLANE(data, 0)];
  167. v |= expand4[GET_PLANE(data, 1)] << 1;
  168. v |= expand4[GET_PLANE(data, 2)] << 2;
  169. v |= expand4[GET_PLANE(data, 3)] << 3;
  170. ((uint32_t *)d)[0] = palette[v >> 28];
  171. ((uint32_t *)d)[1] = palette[(v >> 24) & 0xf];
  172. ((uint32_t *)d)[2] = palette[(v >> 20) & 0xf];
  173. ((uint32_t *)d)[3] = palette[(v >> 16) & 0xf];
  174. ((uint32_t *)d)[4] = palette[(v >> 12) & 0xf];
  175. ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
  176. ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
  177. ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
  178. d += 32;
  179. addr += 4;
  180. }
  181. }
  182. /*
  183. * 16 color mode, dup2 horizontal
  184. */
  185. static void vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
  186. uint32_t addr, int width)
  187. {
  188. uint32_t plane_mask, data, v, *palette;
  189. int x;
  190. palette = vga->last_palette;
  191. plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
  192. width >>= 3;
  193. for(x = 0; x < width; x++) {
  194. data = vga_read_dword_le(vga, addr);
  195. data &= plane_mask;
  196. v = expand4[GET_PLANE(data, 0)];
  197. v |= expand4[GET_PLANE(data, 1)] << 1;
  198. v |= expand4[GET_PLANE(data, 2)] << 2;
  199. v |= expand4[GET_PLANE(data, 3)] << 3;
  200. PUT_PIXEL2(d, 0, palette[v >> 28]);
  201. PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
  202. PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
  203. PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
  204. PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
  205. PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
  206. PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
  207. PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
  208. d += 64;
  209. addr += 4;
  210. }
  211. }
  212. /*
  213. * 256 color mode, double pixels
  214. *
  215. * XXX: add plane_mask support (never used in standard VGA modes)
  216. */
  217. static void vga_draw_line8d2(VGACommonState *vga, uint8_t *d,
  218. uint32_t addr, int width)
  219. {
  220. uint32_t *palette;
  221. int x;
  222. palette = vga->last_palette;
  223. width >>= 3;
  224. for(x = 0; x < width; x++) {
  225. PUT_PIXEL2(d, 0, palette[vga_read_byte(vga, addr + 0)]);
  226. PUT_PIXEL2(d, 1, palette[vga_read_byte(vga, addr + 1)]);
  227. PUT_PIXEL2(d, 2, palette[vga_read_byte(vga, addr + 2)]);
  228. PUT_PIXEL2(d, 3, palette[vga_read_byte(vga, addr + 3)]);
  229. d += 32;
  230. addr += 4;
  231. }
  232. }
  233. /*
  234. * standard 256 color mode
  235. *
  236. * XXX: add plane_mask support (never used in standard VGA modes)
  237. */
  238. static void vga_draw_line8(VGACommonState *vga, uint8_t *d,
  239. uint32_t addr, int width)
  240. {
  241. uint32_t *palette;
  242. int x;
  243. palette = vga->last_palette;
  244. width >>= 3;
  245. for(x = 0; x < width; x++) {
  246. ((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)];
  247. ((uint32_t *)d)[1] = palette[vga_read_byte(vga, addr + 1)];
  248. ((uint32_t *)d)[2] = palette[vga_read_byte(vga, addr + 2)];
  249. ((uint32_t *)d)[3] = palette[vga_read_byte(vga, addr + 3)];
  250. ((uint32_t *)d)[4] = palette[vga_read_byte(vga, addr + 4)];
  251. ((uint32_t *)d)[5] = palette[vga_read_byte(vga, addr + 5)];
  252. ((uint32_t *)d)[6] = palette[vga_read_byte(vga, addr + 6)];
  253. ((uint32_t *)d)[7] = palette[vga_read_byte(vga, addr + 7)];
  254. d += 32;
  255. addr += 8;
  256. }
  257. }
  258. /*
  259. * 15 bit color
  260. */
  261. static void vga_draw_line15_le(VGACommonState *vga, uint8_t *d,
  262. uint32_t addr, int width)
  263. {
  264. int w;
  265. uint32_t v, r, g, b;
  266. w = width;
  267. do {
  268. v = vga_read_word_le(vga, addr);
  269. r = (v >> 7) & 0xf8;
  270. g = (v >> 2) & 0xf8;
  271. b = (v << 3) & 0xf8;
  272. ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
  273. addr += 2;
  274. d += 4;
  275. } while (--w != 0);
  276. }
  277. static void vga_draw_line15_be(VGACommonState *vga, uint8_t *d,
  278. uint32_t addr, int width)
  279. {
  280. int w;
  281. uint32_t v, r, g, b;
  282. w = width;
  283. do {
  284. v = vga_read_word_be(vga, addr);
  285. r = (v >> 7) & 0xf8;
  286. g = (v >> 2) & 0xf8;
  287. b = (v << 3) & 0xf8;
  288. ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
  289. addr += 2;
  290. d += 4;
  291. } while (--w != 0);
  292. }
  293. /*
  294. * 16 bit color
  295. */
  296. static void vga_draw_line16_le(VGACommonState *vga, uint8_t *d,
  297. uint32_t addr, int width)
  298. {
  299. int w;
  300. uint32_t v, r, g, b;
  301. w = width;
  302. do {
  303. v = vga_read_word_le(vga, addr);
  304. r = (v >> 8) & 0xf8;
  305. g = (v >> 3) & 0xfc;
  306. b = (v << 3) & 0xf8;
  307. ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
  308. addr += 2;
  309. d += 4;
  310. } while (--w != 0);
  311. }
  312. static void vga_draw_line16_be(VGACommonState *vga, uint8_t *d,
  313. uint32_t addr, int width)
  314. {
  315. int w;
  316. uint32_t v, r, g, b;
  317. w = width;
  318. do {
  319. v = vga_read_word_be(vga, addr);
  320. r = (v >> 8) & 0xf8;
  321. g = (v >> 3) & 0xfc;
  322. b = (v << 3) & 0xf8;
  323. ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
  324. addr += 2;
  325. d += 4;
  326. } while (--w != 0);
  327. }
  328. /*
  329. * 24 bit color
  330. */
  331. static void vga_draw_line24_le(VGACommonState *vga, uint8_t *d,
  332. uint32_t addr, int width)
  333. {
  334. int w;
  335. uint32_t r, g, b;
  336. w = width;
  337. do {
  338. b = vga_read_byte(vga, addr + 0);
  339. g = vga_read_byte(vga, addr + 1);
  340. r = vga_read_byte(vga, addr + 2);
  341. ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
  342. addr += 3;
  343. d += 4;
  344. } while (--w != 0);
  345. }
  346. static void vga_draw_line24_be(VGACommonState *vga, uint8_t *d,
  347. uint32_t addr, int width)
  348. {
  349. int w;
  350. uint32_t r, g, b;
  351. w = width;
  352. do {
  353. r = vga_read_byte(vga, addr + 0);
  354. g = vga_read_byte(vga, addr + 1);
  355. b = vga_read_byte(vga, addr + 2);
  356. ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
  357. addr += 3;
  358. d += 4;
  359. } while (--w != 0);
  360. }
  361. /*
  362. * 32 bit color
  363. */
  364. static void vga_draw_line32_le(VGACommonState *vga, uint8_t *d,
  365. uint32_t addr, int width)
  366. {
  367. int w;
  368. uint32_t r, g, b;
  369. w = width;
  370. do {
  371. b = vga_read_byte(vga, addr + 0);
  372. g = vga_read_byte(vga, addr + 1);
  373. r = vga_read_byte(vga, addr + 2);
  374. ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
  375. addr += 4;
  376. d += 4;
  377. } while (--w != 0);
  378. }
  379. static void vga_draw_line32_be(VGACommonState *vga, uint8_t *d,
  380. uint32_t addr, int width)
  381. {
  382. int w;
  383. uint32_t r, g, b;
  384. w = width;
  385. do {
  386. r = vga_read_byte(vga, addr + 1);
  387. g = vga_read_byte(vga, addr + 2);
  388. b = vga_read_byte(vga, addr + 3);
  389. ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
  390. addr += 4;
  391. d += 4;
  392. } while (--w != 0);
  393. }