vgahiqvideo.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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. Xrx = 0x3D6, /* Configuration Extensions Index */
  15. };
  16. static uchar
  17. hiqvideoxi(long port, uchar index)
  18. {
  19. uchar data;
  20. outb(port, index);
  21. data = inb(port+1);
  22. return data;
  23. }
  24. static void
  25. hiqvideoxo(long port, uchar index, uchar data)
  26. {
  27. outb(port, index);
  28. outb(port+1, data);
  29. }
  30. static ulong
  31. hiqvideolinear(VGAscr* scr, int* size, int* align)
  32. {
  33. ulong aperture, oaperture;
  34. int oapsize, wasupamem;
  35. Pcidev *p;
  36. oaperture = scr->aperture;
  37. oapsize = scr->apsize;
  38. wasupamem = scr->isupamem;
  39. aperture = 0;
  40. if(p = pcimatch(nil, 0x102C, 0)){
  41. switch(p->did){
  42. case 0x00C0: /* 69000 HiQVideo */
  43. case 0x00E0: /* 65550 HiQV32 */
  44. case 0x00E4: /* 65554 HiQV32 */
  45. case 0x00E5: /* 65555 HiQV32 */
  46. aperture = p->mem[0].bar & ~0x0F;
  47. *size = p->mem[0].size;
  48. break;
  49. default:
  50. break;
  51. }
  52. }
  53. if(wasupamem){
  54. if(oaperture == aperture)
  55. return oaperture;
  56. upafree(oaperture, oapsize);
  57. }
  58. scr->isupamem = 0;
  59. aperture = upamalloc(aperture, *size, *align);
  60. if(aperture == 0){
  61. if(wasupamem && upamalloc(oaperture, oapsize, 0)){
  62. aperture = oaperture;
  63. scr->isupamem = 1;
  64. }
  65. else
  66. scr->isupamem = 0;
  67. }
  68. else
  69. scr->isupamem = 1;
  70. return aperture;
  71. }
  72. static void
  73. hiqvideoenable(VGAscr* scr)
  74. {
  75. Pcidev *p;
  76. int align, size, vmsize;
  77. ulong aperture;
  78. /*
  79. * Only once, can't be disabled for now.
  80. */
  81. if(scr->io)
  82. return;
  83. if(p = pcimatch(nil, 0x102C, 0)){
  84. switch(p->did){
  85. case 0x00C0: /* 69000 HiQVideo */
  86. vmsize = 2*1024*1024;
  87. break;
  88. case 0x00E0: /* 65550 HiQV32 */
  89. case 0x00E4: /* 65554 HiQV32 */
  90. case 0x00E5: /* 65555 HiQV32 */
  91. switch((hiqvideoxi(Xrx, 0x43)>>1) & 0x03){
  92. default:
  93. case 0:
  94. vmsize = 1*1024*1024;
  95. break;
  96. case 1:
  97. vmsize = 2*1024*1024;
  98. break;
  99. }
  100. break;
  101. default:
  102. return;
  103. }
  104. }
  105. else
  106. return;
  107. size = p->mem[0].size;
  108. align = 0;
  109. aperture = hiqvideolinear(scr, &size, &align);
  110. if(aperture) {
  111. scr->aperture = aperture;
  112. scr->apsize = size;
  113. addvgaseg("hiqvideoscreen", aperture, size);
  114. }
  115. /*
  116. * Find a place for the cursor data in display memory.
  117. * Must be on a 4096-byte boundary.
  118. * scr->io holds the physical address of the cursor
  119. * storage area in the framebuffer region.
  120. */
  121. scr->storage = vmsize-4096;
  122. scr->io = scr->aperture+scr->storage;
  123. }
  124. static void
  125. hiqvideocurdisable(VGAscr*)
  126. {
  127. hiqvideoxo(Xrx, 0xA0, 0x10);
  128. }
  129. static void
  130. hiqvideocurload(VGAscr* scr, Cursor* curs)
  131. {
  132. uchar *p;
  133. int x, y;
  134. /*
  135. * Disable the cursor.
  136. */
  137. hiqvideocurdisable(scr);
  138. if(scr->io == 0)
  139. return;
  140. p = KADDR(scr->io);
  141. for(y = 0; y < 16; y += 2){
  142. *p++ = ~(curs->clr[2*y]|curs->set[2*y]);
  143. *p++ = ~(curs->clr[2*y+1]|curs->set[2*y+1]);
  144. *p++ = 0xFF;
  145. *p++ = 0xFF;
  146. *p++ = ~(curs->clr[2*y+2]|curs->set[2*y+2]);
  147. *p++ = ~(curs->clr[2*y+3]|curs->set[2*y+3]);
  148. *p++ = 0xFF;
  149. *p++ = 0xFF;
  150. *p++ = curs->set[2*y];
  151. *p++ = curs->set[2*y+1];
  152. *p++ = 0x00;
  153. *p++ = 0x00;
  154. *p++ = curs->set[2*y+2];
  155. *p++ = curs->set[2*y+3];
  156. *p++ = 0x00;
  157. *p++ = 0x00;
  158. }
  159. while(y < 32){
  160. for(x = 0; x < 64; x += 8)
  161. *p++ = 0xFF;
  162. for(x = 0; x < 64; x += 8)
  163. *p++ = 0x00;
  164. y += 2;
  165. }
  166. /*
  167. * Save the cursor hotpoint and enable the cursor.
  168. */
  169. scr->offset = curs->offset;
  170. hiqvideoxo(Xrx, 0xA0, 0x11);
  171. }
  172. static int
  173. hiqvideocurmove(VGAscr* scr, Point p)
  174. {
  175. int x, y;
  176. if(scr->io == 0)
  177. return 1;
  178. if((x = p.x+scr->offset.x) < 0)
  179. x = 0x8000|(-x & 0x07FF);
  180. if((y = p.y+scr->offset.y) < 0)
  181. y = 0x8000|(-y & 0x07FF);
  182. hiqvideoxo(Xrx, 0xA4, x & 0xFF);
  183. hiqvideoxo(Xrx, 0xA5, (x>>8) & 0xFF);
  184. hiqvideoxo(Xrx, 0xA6, y & 0xFF);
  185. hiqvideoxo(Xrx, 0xA7, (y>>8) & 0xFF);
  186. return 0;
  187. }
  188. static void
  189. hiqvideocurenable(VGAscr* scr)
  190. {
  191. uchar xr80;
  192. hiqvideoenable(scr);
  193. if(scr->io == 0)
  194. return;
  195. /*
  196. * Disable the cursor.
  197. */
  198. hiqvideocurdisable(scr);
  199. /*
  200. * Cursor colours.
  201. * Can't call setcolor here as cursor is already locked.
  202. * When done make sure the cursor enable in Xr80 is set.
  203. */
  204. xr80 = hiqvideoxi(Xrx, 0x80);
  205. hiqvideoxo(Xrx, 0x80, xr80|0x01);
  206. vgao(PaddrW, 0x04);
  207. vgao(Pdata, Pwhite);
  208. vgao(Pdata, Pwhite);
  209. vgao(Pdata, Pwhite);
  210. vgao(Pdata, Pblack);
  211. vgao(Pdata, Pblack);
  212. vgao(Pdata, Pblack);
  213. hiqvideoxo(Xrx, 0x80, xr80|0x10);
  214. hiqvideoxo(Xrx, 0xA2, (scr->storage>>12)<<4);
  215. hiqvideoxo(Xrx, 0xA3, (scr->storage>>16) & 0x3F);
  216. /*
  217. * Load, locate and enable the 32x32 cursor.
  218. * Cursor enable in Xr80 better be set already.
  219. */
  220. hiqvideocurload(scr, &arrow);
  221. hiqvideocurmove(scr, ZP);
  222. hiqvideoxo(Xrx, 0xA0, 0x11);
  223. }
  224. VGAdev vgahiqvideodev = {
  225. "hiqvideo",
  226. hiqvideoenable, /* enable */
  227. nil, /* disable */
  228. nil, /* page */
  229. hiqvideolinear, /* linear */
  230. };
  231. VGAcur vgahiqvideocur = {
  232. "hiqvideohwgc",
  233. hiqvideocurenable, /* enable */
  234. hiqvideocurdisable, /* disable */
  235. hiqvideocurload, /* load */
  236. hiqvideocurmove, /* move */
  237. };