vgacyber938x.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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 void
  34. cyber938xlinear(VGAscr* scr, int, int)
  35. {
  36. Pcidev *p;
  37. if(scr->vaddr)
  38. return;
  39. vgalinearpciid(scr, 0x1023, 0);
  40. p = scr->pci;
  41. /*
  42. * Heuristic to detect the MMIO space. We're flying blind
  43. * here, with only the XFree86 source to guide us.
  44. */
  45. if(p->mem[1].size == 0x20000)
  46. scr->mmio = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
  47. if(scr->apsize)
  48. addvgaseg("cyber938xscreen", scr->paddr, scr->apsize);
  49. if(scr->mmio)
  50. addvgaseg("cyber938xmmio", p->mem[1].bar&~0x0F, 0x20000);
  51. }
  52. static void
  53. cyber938xcurdisable(VGAscr*)
  54. {
  55. vgaxo(Crtx, 0x50, CursorOFF);
  56. }
  57. static void
  58. cyber938xcurload(VGAscr* scr, Cursor* curs)
  59. {
  60. uchar *p;
  61. int islinear, opage, y;
  62. cyber938xcurdisable(scr);
  63. opage = 0;
  64. p = scr->vaddr;
  65. islinear = vgaxi(Crtx, 0x21) & 0x20;
  66. if(!islinear){
  67. lock(&scr->devlock);
  68. opage = cyber938xpageset(scr, scr->storage>>16);
  69. p += (scr->storage & 0xFFFF);
  70. }
  71. else
  72. p += scr->storage;
  73. for(y = 0; y < 16; y++){
  74. *p++ = curs->set[2*y]|curs->clr[2*y];
  75. *p++ = curs->set[2*y + 1]|curs->clr[2*y + 1];
  76. *p++ = 0x00;
  77. *p++ = 0x00;
  78. *p++ = curs->set[2*y];
  79. *p++ = curs->set[2*y + 1];
  80. *p++ = 0x00;
  81. *p++ = 0x00;
  82. }
  83. memset(p, 0, (32-y)*8);
  84. if(!islinear){
  85. cyber938xpageset(scr, opage);
  86. unlock(&scr->devlock);
  87. }
  88. /*
  89. * Save the cursor hotpoint and enable the cursor.
  90. */
  91. scr->offset = curs->offset;
  92. vgaxo(Crtx, 0x50, CursorON);
  93. }
  94. static int
  95. cyber938xcurmove(VGAscr* scr, Point p)
  96. {
  97. int x, xo, y, yo;
  98. /*
  99. * Mustn't position the cursor offscreen even partially,
  100. * or it might disappear. Therefore, if x or y is -ve, adjust the
  101. * cursor origins instead.
  102. */
  103. if((x = p.x+scr->offset.x) < 0){
  104. xo = -x;
  105. x = 0;
  106. }
  107. else
  108. xo = 0;
  109. if((y = p.y+scr->offset.y) < 0){
  110. yo = -y;
  111. y = 0;
  112. }
  113. else
  114. yo = 0;
  115. /*
  116. * Load the new values.
  117. */
  118. vgaxo(Crtx, 0x46, xo);
  119. vgaxo(Crtx, 0x47, yo);
  120. vgaxo(Crtx, 0x40, x & 0xFF);
  121. vgaxo(Crtx, 0x41, (x>>8) & 0xFF);
  122. vgaxo(Crtx, 0x42, y & 0xFF);
  123. vgaxo(Crtx, 0x43, (y>>8) & 0xFF);
  124. return 0;
  125. }
  126. static void
  127. cyber938xcurenable(VGAscr* scr)
  128. {
  129. int i;
  130. ulong storage;
  131. cyber938xcurdisable(scr);
  132. /*
  133. * Cursor colours.
  134. */
  135. for(i = 0x48; i < 0x4C; i++)
  136. vgaxo(Crtx, i, 0x00);
  137. for(i = 0x4C; i < 0x50; i++)
  138. vgaxo(Crtx, i, 0xFF);
  139. /*
  140. * Find a place for the cursor data in display memory.
  141. */
  142. storage = ((scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024);
  143. vgaxo(Crtx, 0x44, storage & 0xFF);
  144. vgaxo(Crtx, 0x45, (storage>>8) & 0xFF);
  145. storage *= 1024;
  146. scr->storage = storage;
  147. /*
  148. * Load, locate and enable the 32x32 cursor.
  149. * (64x64 is bit 0, X11 format is bit 6 and cursor
  150. * enable is bit 7). Bit 3 needs to be set on 9382
  151. * chips otherwise even the white bits are black.
  152. */
  153. cyber938xcurload(scr, &arrow);
  154. cyber938xcurmove(scr, ZP);
  155. vgaxo(Crtx, 0x50, CursorON);
  156. }
  157. VGAdev vgacyber938xdev = {
  158. "cyber938x",
  159. nil, /* enable */
  160. nil, /* disable */
  161. cyber938xpage, /* page */
  162. cyber938xlinear, /* linear */
  163. nil, /* drawinit */
  164. };
  165. VGAcur vgacyber938xcur = {
  166. "cyber938xhwgc",
  167. cyber938xcurenable, /* enable */
  168. cyber938xcurdisable, /* disable */
  169. cyber938xcurload, /* load */
  170. cyber938xcurmove, /* move */
  171. };