vgahiqvideo.c 4.8 KB

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