vga.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*
  2. *
  3. * Copyright © 2000 Keith Packard
  4. *
  5. * Permission to use, copy, modify, distribute, and sell this software and its
  6. * documentation for any purpose is hereby granted without fee, provided that
  7. * the above copyright notice appear in all copies and that both that
  8. * copyright notice and this permission notice appear in supporting
  9. * documentation, and that the name of Keith Packard not be used in
  10. * advertising or publicity pertaining to distribution of the software without
  11. * specific, written prior permission. Keith Packard makes no
  12. * representations about the suitability of this software for any purpose. It
  13. * is provided "as is" without express or implied warranty.
  14. *
  15. * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  16. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  17. * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  18. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  19. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  20. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  21. * PERFORMANCE OF THIS SOFTWARE.
  22. */
  23. #ifdef HAVE_CONFIG_H
  24. #include <kdrive-config.h>
  25. #endif
  26. #include "vesa.h"
  27. static const VesaModeRec vgaModes[] = {
  28. {
  29. 6, 0,
  30. MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_LINEAR,
  31. 1, 1, MEMORY_PLANAR,
  32. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  33. 640, 200, 80,
  34. },
  35. {
  36. 0xd, 0,
  37. MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
  38. 4, 4, MEMORY_PLANAR,
  39. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  40. 320, 200, 40,
  41. },
  42. {
  43. 0xe, 0,
  44. MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
  45. 4, 4, MEMORY_PLANAR,
  46. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  47. 640, 200, 80,
  48. },
  49. {
  50. 0x10, 0,
  51. MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
  52. 4, 4, MEMORY_PLANAR,
  53. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  54. 640, 350, 80,
  55. },
  56. {
  57. 0x11, 0,
  58. MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_LINEAR,
  59. 1, 1, MEMORY_PLANAR,
  60. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  61. 640, 480, 80,
  62. },
  63. {
  64. 0x12, 0,
  65. MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
  66. 4, 4, MEMORY_PLANAR,
  67. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  68. 640, 480, 80,
  69. },
  70. {
  71. 0x13, 0,
  72. MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR | MODE_LINEAR,
  73. 8, 8, MEMORY_PSEUDO,
  74. 0, 0, 0, 0, 0, 0, 0, 0, 0,
  75. 320, 200, 320,
  76. },
  77. };
  78. #define NUM_VGA_MODE (sizeof vgaModes / sizeof vgaModes[0])
  79. int VgaGetNmode(Vm86InfoPtr vi)
  80. {
  81. return NUM_VGA_MODE;
  82. }
  83. int VgaGetModes(Vm86InfoPtr vi, VesaModePtr mode, int nmode)
  84. {
  85. if (nmode > NUM_VGA_MODE)
  86. nmode = NUM_VGA_MODE;
  87. memcpy(mode, vgaModes, nmode * sizeof(VesaModeRec));
  88. return nmode;
  89. }
  90. int VgaSetMode(Vm86InfoPtr vi, int mode)
  91. {
  92. int code;
  93. vi->vms.regs.eax = mode & 0x7f;
  94. code = Vm86DoInterrupt(vi, 0x10);
  95. if (code < 0)
  96. return -1;
  97. return 0;
  98. }
  99. int VgaGetMode(Vm86InfoPtr vi, int *mode)
  100. {
  101. *mode = Vm86Memory(vi, 0x449);
  102. return 0;
  103. }
  104. void VgaSetWritePlaneMask(Vm86InfoPtr vi, int mask)
  105. {
  106. asm volatile ("outb %b0,%w1"::"a" (2), "d"(0x3c4));
  107. asm volatile ("outb %b0,%w1"::"a" (mask), "d"(0x3c5));
  108. }
  109. int VgaSetPalette(Vm86InfoPtr vi, int first, int number, U8 * entries)
  110. {
  111. U8 *palette_scratch;
  112. int mark;
  113. int palette_base;
  114. int i, j, code;
  115. if (number == 0)
  116. return 0;
  117. if (first < 0 || number < 0 || first + number > 256) {
  118. ErrorF("Cannot set %d, %d palette entries\n", first, number);
  119. return -1;
  120. }
  121. mark = Vm86MarkMemory(vi);
  122. palette_base = Vm86AllocateMemory(vi, 3 * 256);
  123. palette_scratch = &LM(vi, palette_base);
  124. vi->vms.regs.eax = 0x1012;
  125. vi->vms.regs.ebx = first;
  126. vi->vms.regs.ecx = number;
  127. vi->vms.regs.es = POINTER_SEGMENT(palette_base);
  128. vi->vms.regs.edx = POINTER_OFFSET(palette_base);
  129. j = 0;
  130. i = 0;
  131. while (number--) {
  132. palette_scratch[j++] = entries[i++] >> 2;
  133. palette_scratch[j++] = entries[i++] >> 2;
  134. palette_scratch[j++] = entries[i++] >> 2;
  135. i++;
  136. }
  137. code = Vm86DoInterrupt(vi, 0x10);
  138. Vm86ReleaseMemory(vi, mark);
  139. if (code < 0)
  140. return -1;
  141. return 0;
  142. }
  143. int VgaGetPalette(Vm86InfoPtr vi, int first, int number, U8 * entries)
  144. {
  145. U8 *palette_scratch;
  146. int mark;
  147. int palette_base;
  148. int i, j, code;
  149. if (number == 0)
  150. return 0;
  151. if (first < 0 || number < 0 || first + number > 256) {
  152. ErrorF("Cannot get %d, %d palette entries\n", first, number);
  153. return -1;
  154. }
  155. mark = Vm86MarkMemory(vi);
  156. palette_base = Vm86AllocateMemory(vi, 3 * 256);
  157. palette_scratch = &LM(vi, palette_base);
  158. vi->vms.regs.eax = 0x1017;
  159. vi->vms.regs.ebx = first;
  160. vi->vms.regs.ecx = number;
  161. vi->vms.regs.es = POINTER_SEGMENT(palette_base);
  162. vi->vms.regs.edx = POINTER_OFFSET(palette_base);
  163. code = VbeDoInterrupt10(vi);
  164. if (code < 0)
  165. return -1;
  166. j = 0;
  167. i = 0;
  168. while (number--) {
  169. entries[i++] = palette_scratch[j++] << 2;
  170. entries[i++] = palette_scratch[j++] << 2;
  171. entries[i++] = palette_scratch[j++] << 2;
  172. entries[i++] = 0;
  173. }
  174. Vm86ReleaseMemory(vi, mark);
  175. return 0;
  176. }
  177. #define VGA_FB(vm) ((vm) < 8 ? 0xb8000 : 0xa0000)
  178. void *VgaSetWindow(Vm86InfoPtr vi, int vmode, int bytes, int mode, int *size)
  179. {
  180. *size = 0x10000 - bytes;
  181. return &LM(vi, VGA_FB(vmode) + bytes);
  182. }
  183. void *VgaMapFramebuffer(Vm86InfoPtr vi, int vmode, int *size, CARD32 * ret_phys)
  184. {
  185. if (VGA_FB(vmode) == 0xa0000)
  186. *size = 0x10000;
  187. else
  188. *size = 0x4000;
  189. *ret_phys = VGA_FB(vmode);
  190. return &LM(vi, VGA_FB(vmode));
  191. }
  192. void VgaUnmapFramebuffer(Vm86InfoPtr vi)
  193. {
  194. }