vgacyber938x.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "io.h"
  7. #include "../port/error.h"
  8. #define Image IMAGE
  9. #include <draw.h>
  10. #include <memdraw.h>
  11. #include <cursor.h>
  12. #include "screen.h"
  13. enum {
  14. CursorON = 0xC8,
  15. CursorOFF = 0x00,
  16. };
  17. static int
  18. cyber938xpageset(VGAscr*, int page)
  19. {
  20. int opage;
  21. opage = inb(0x3D8);
  22. outb(0x3D8, page);
  23. outb(0x3D9, page);
  24. return opage;
  25. }
  26. static void
  27. cyber938xpage(VGAscr* scr, int page)
  28. {
  29. lock(&scr->devlock);
  30. cyber938xpageset(scr, page);
  31. unlock(&scr->devlock);
  32. }
  33. static ulong
  34. cyber938xlinear(VGAscr* scr, int* size, int* align)
  35. {
  36. ulong aperture, oaperture;
  37. int oapsize, wasupamem;
  38. int osize;
  39. Pcidev *p;
  40. osize = *size;
  41. oaperture = scr->aperture;
  42. oapsize = scr->apsize;
  43. wasupamem = scr->isupamem;
  44. if(wasupamem)
  45. upafree(oaperture, oapsize);
  46. scr->isupamem = 0;
  47. scr->mmio = 0;
  48. if(p = pcimatch(nil, 0x1023, 0)){
  49. aperture = p->mem[0].bar & ~0x0F;
  50. *size = p->mem[0].size;
  51. /*
  52. * Heuristic to detect the MMIO space. We're flying blind
  53. * here, with only the XFree86 source to guide us.
  54. */
  55. if(p->mem[1].size == 0x20000)
  56. scr->mmio = (ulong*)(p->mem[1].bar & ~0x0F);
  57. }
  58. else
  59. aperture = 0;
  60. aperture = upamalloc(aperture, *size, *align);
  61. if(aperture == 0){
  62. if(wasupamem && upamalloc(oaperture, oapsize, 0))
  63. scr->isupamem = 1;
  64. }
  65. else
  66. scr->isupamem = 1;
  67. if(aperture)
  68. addvgaseg("cyber938xscreen", aperture, osize);
  69. if(scr->mmio)
  70. addvgaseg("cyber938xmmio", (ulong)scr->mmio, 0x20000);
  71. return aperture;
  72. }
  73. static void
  74. cyber938xcurdisable(VGAscr*)
  75. {
  76. vgaxo(Crtx, 0x50, CursorOFF);
  77. }
  78. static void
  79. cyber938xcurload(VGAscr* scr, Cursor* curs)
  80. {
  81. uchar *p;
  82. int islinear, opage, y;
  83. cyber938xcurdisable(scr);
  84. opage = 0;
  85. p = KADDR(scr->aperture);
  86. islinear = vgaxi(Crtx, 0x21) & 0x20;
  87. if(!islinear){
  88. lock(&scr->devlock);
  89. opage = cyber938xpageset(scr, scr->storage>>16);
  90. p += (scr->storage & 0xFFFF);
  91. }
  92. else
  93. p += scr->storage;
  94. for(y = 0; y < 16; y++){
  95. *p++ = curs->set[2*y]|curs->clr[2*y];
  96. *p++ = curs->set[2*y + 1]|curs->clr[2*y + 1];
  97. *p++ = 0x00;
  98. *p++ = 0x00;
  99. *p++ = curs->set[2*y];
  100. *p++ = curs->set[2*y + 1];
  101. *p++ = 0x00;
  102. *p++ = 0x00;
  103. }
  104. memset(p, 0, (32-y)*8);
  105. if(!islinear){
  106. cyber938xpageset(scr, opage);
  107. unlock(&scr->devlock);
  108. }
  109. /*
  110. * Save the cursor hotpoint and enable the cursor.
  111. */
  112. scr->offset = curs->offset;
  113. vgaxo(Crtx, 0x50, CursorON);
  114. }
  115. static int
  116. cyber938xcurmove(VGAscr* scr, Point p)
  117. {
  118. int x, xo, y, yo;
  119. /*
  120. * Mustn't position the cursor offscreen even partially,
  121. * or it might disappear. Therefore, if x or y is -ve, adjust the
  122. * cursor origins instead.
  123. */
  124. if((x = p.x+scr->offset.x) < 0){
  125. xo = -x;
  126. x = 0;
  127. }
  128. else
  129. xo = 0;
  130. if((y = p.y+scr->offset.y) < 0){
  131. yo = -y;
  132. y = 0;
  133. }
  134. else
  135. yo = 0;
  136. /*
  137. * Load the new values.
  138. */
  139. vgaxo(Crtx, 0x46, xo);
  140. vgaxo(Crtx, 0x47, yo);
  141. vgaxo(Crtx, 0x40, x & 0xFF);
  142. vgaxo(Crtx, 0x41, (x>>8) & 0xFF);
  143. vgaxo(Crtx, 0x42, y & 0xFF);
  144. vgaxo(Crtx, 0x43, (y>>8) & 0xFF);
  145. return 0;
  146. }
  147. static void
  148. cyber938xcurenable(VGAscr* scr)
  149. {
  150. int i;
  151. ulong storage;
  152. cyber938xcurdisable(scr);
  153. /*
  154. * Cursor colours.
  155. */
  156. for(i = 0x48; i < 0x4C; i++)
  157. vgaxo(Crtx, i, 0x00);
  158. for(i = 0x4C; i < 0x50; i++)
  159. vgaxo(Crtx, i, 0xFF);
  160. /*
  161. * Find a place for the cursor data in display memory.
  162. */
  163. storage = ((scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024);
  164. vgaxo(Crtx, 0x44, storage & 0xFF);
  165. vgaxo(Crtx, 0x45, (storage>>8) & 0xFF);
  166. storage *= 1024;
  167. scr->storage = storage;
  168. /*
  169. * Load, locate and enable the 32x32 cursor.
  170. * (64x64 is bit 0, X11 format is bit 6 and cursor
  171. * enable is bit 7). Bit 3 needs to be set on 9382
  172. * chips otherwise even the white bits are black.
  173. */
  174. cyber938xcurload(scr, &arrow);
  175. cyber938xcurmove(scr, ZP);
  176. vgaxo(Crtx, 0x50, CursorON);
  177. }
  178. VGAdev vgacyber938xdev = {
  179. "cyber938x",
  180. nil, /* enable */
  181. nil, /* disable */
  182. cyber938xpage, /* page */
  183. cyber938xlinear, /* linear */
  184. nil, /* drawinit */
  185. };
  186. VGAcur vgacyber938xcur = {
  187. "cyber938xhwgc",
  188. cyber938xcurenable, /* enable */
  189. cyber938xcurdisable, /* disable */
  190. cyber938xcurload, /* load */
  191. cyber938xcurmove, /* move */
  192. };