ark2000pv.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include "pci.h"
  5. #include "vga.h"
  6. /*
  7. * ARK Logic ARK2000PV GUI accelerator.
  8. */
  9. static void
  10. snarf(Vga* vga, Ctlr* ctlr)
  11. {
  12. int i;
  13. /*
  14. * Unlock access to the extended I/O registers.
  15. */
  16. vgaxo(Seqx, 0x1D, 0x01);
  17. for(i = 0x10; i < 0x2E; i++)
  18. vga->sequencer[i] = vgaxi(Seqx, i);
  19. for(i = 0x40; i < 0x47; i++)
  20. vga->crt[i] = vgaxi(Crtx, i);
  21. vga->crt[0x50] = vgaxi(Crtx, 0x50);
  22. /*
  23. * A hidey-hole for the coprocessor status register.
  24. */
  25. vga->crt[0xFF] = inportb(0x3CB);
  26. /*
  27. * Memory size.
  28. */
  29. switch((vga->sequencer[0x10]>>6) & 0x03){
  30. case 0x00:
  31. vga->vma = vga->vmz = 1*1024*1024;
  32. break;
  33. case 0x01:
  34. vga->vma = vga->vmz = 2*1024*1024;
  35. break;
  36. case 0x02:
  37. vga->vma = vga->vmz = 4*1024*1024;
  38. break;
  39. }
  40. ctlr->flag |= Fsnarf;
  41. }
  42. static void
  43. options(Vga*, Ctlr* ctlr)
  44. {
  45. ctlr->flag |= Hlinear|Hpclk2x8|Foptions;
  46. }
  47. static void
  48. init(Vga* vga, Ctlr* ctlr)
  49. {
  50. Mode *mode;
  51. ulong x;
  52. mode = vga->mode;
  53. vga->crt[0x46] = 0x00;
  54. if(ctlr->flag & Upclk2x8){
  55. vga->crt[0x00] = ((mode->ht/2)>>3)-5;
  56. vga->crt[0x01] = ((mode->x/2)>>3)-1;
  57. vga->crt[0x02] = ((mode->shb/2)>>3)-1;
  58. x = (mode->ehb/2)>>3;
  59. vga->crt[0x03] = 0x80|(x & 0x1F);
  60. vga->crt[0x04] = (mode->shs/2)>>3;
  61. vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F;
  62. if(x & 0x20)
  63. vga->crt[0x05] |= 0x80;
  64. vga->crt[0x13] = mode->x/8;
  65. vga->crt[0x46] |= 0x04;
  66. }
  67. /*
  68. * Overflow bits.
  69. */
  70. vga->crt[0x40] = 0x00;
  71. if(vga->crt[0x18] & 0x400)
  72. vga->crt[0x40] |= 0x08;
  73. if(vga->crt[0x10] & 0x400)
  74. vga->crt[0x40] |= 0x10;
  75. if(vga->crt[0x15] & 0x400)
  76. vga->crt[0x40] |= 0x20;
  77. if(vga->crt[0x12] & 0x400)
  78. vga->crt[0x40] |= 0x40;
  79. if(vga->crt[0x06] & 0x400)
  80. vga->crt[0x40] |= 0x80;
  81. vga->crt[0x41] = 0x00;
  82. if(vga->crt[0x13] & 0x100)
  83. vga->crt[0x41] |= 0x08;
  84. if(vga->crt[0x04] & 0x100)
  85. vga->crt[0x41] |= 0x10;
  86. if(vga->crt[0x02] & 0x100)
  87. vga->crt[0x41] |= 0x20;
  88. if(vga->crt[0x01] & 0x100)
  89. vga->crt[0x41] |= 0x40;
  90. if(vga->crt[0x00] & 0x100)
  91. vga->crt[0x41] |= 0x80;
  92. /*
  93. * Interlace.
  94. */
  95. vga->crt[0x42] = 0x00;
  96. vga->crt[0x44] = 0x00;
  97. if(mode->interlace){
  98. vga->crt[0x42] = vga->crt[0]/2;
  99. vga->crt[0x44] |= 0x04;
  100. }
  101. vga->crt[0x45] = 0x00;
  102. /*
  103. * Memory configuration:
  104. * enable linear|coprocessor|VESA modes;
  105. * set aperture to 64Kb, 0xA0000;
  106. * set aperture index 0.
  107. * Bugs: 1024x768x1 doesn't work (aperture not set correctly?);
  108. * hwgc doesn't work in 1-bit modes (hardware?).
  109. */
  110. vga->sequencer[0x10] &= ~0x3F;
  111. vga->sequencer[0x11] &= ~0x0F;
  112. switch(mode->z){
  113. case 1:
  114. vga->sequencer[0x10] |= 0x03;
  115. vga->sequencer[0x11] |= 0x01;
  116. cflag = 1;
  117. break;
  118. case 8:
  119. vga->sequencer[0x10] |= 0x0F;
  120. vga->sequencer[0x11] |= 0x06;
  121. if(vga->linear && (ctlr->flag & Hlinear) && vga->vmz)
  122. ctlr->flag |= Ulinear;
  123. break;
  124. default:
  125. error("depth %d not supported\n", mode->z);
  126. }
  127. vga->sequencer[0x12] &= ~0x03;
  128. vga->sequencer[0x13] = 0x0A;
  129. vga->sequencer[0x14] = 0x00;
  130. vga->sequencer[0x15] = 0x00;
  131. vga->sequencer[0x16] = 0x00;
  132. /*
  133. * Frame Buffer Pitch and FIFO control.
  134. * Set the FIFO to 32 deep and refill trigger when
  135. * 6 slots empty.
  136. */
  137. vga->sequencer[0x17] = 0x00;
  138. vga->sequencer[0x18] = 0x13;
  139. if(mode->x <= 640)
  140. vga->sequencer[0x17] = 0x00;
  141. else if(mode->x <= 800)
  142. vga->sequencer[0x17] |= 0x01;
  143. else if(mode->x <= 1024)
  144. vga->sequencer[0x17] |= 0x02;
  145. else if(mode->x <= 1280)
  146. vga->sequencer[0x17] |= 0x04;
  147. else if(mode->x <= 1600)
  148. vga->sequencer[0x17] |= 0x05;
  149. else if(mode->x <= 2048)
  150. vga->sequencer[0x17] |= 0x06;
  151. /*
  152. * Clock select.
  153. */
  154. vga->misc &= ~0x0C;
  155. vga->misc |= (vga->i[0] & 0x03)<<2;
  156. vga->sequencer[0x11] &= ~0xC0;
  157. vga->sequencer[0x11] |= (vga->i[0] & 0x0C)<<4;
  158. vga->attribute[0x11] = 0x00; /* color map entry for black */
  159. ctlr->flag |= Finit;
  160. }
  161. static void
  162. load(Vga* vga, Ctlr* ctlr)
  163. {
  164. ulong l;
  165. /*
  166. * Ensure there are no glitches when selecting a new
  167. * clock frequency.
  168. * The sequencer toggle seems to matter on the Hercules
  169. * Stingray 64/Video at 1280x1024x8. Without it the screen
  170. * is fuzzy; a second load clears it up and there's no
  171. * difference between the two register sets. A mystery.
  172. */
  173. vgao(MiscW, vga->misc & ~0x0C);
  174. vgaxo(Seqx, 0x11, vga->sequencer[0x11]);
  175. vgao(MiscW, vga->misc);
  176. if(vga->ramdac && strncmp(vga->ramdac->name, "w30c516", 7) == 0){
  177. sequencer(vga, 1);
  178. sleep(500);
  179. sequencer(vga, 0);
  180. }
  181. if(ctlr->flag & Ulinear){
  182. vga->sequencer[0x10] |= 0x10;
  183. if(vga->vmz <= 1024*1024)
  184. vga->sequencer[0x12] |= 0x01;
  185. else if(vga->vmz <= 2*1024*1024)
  186. vga->sequencer[0x12] |= 0x02;
  187. else
  188. vga->sequencer[0x12] |= 0x03;
  189. l = vga->vmb>>16;
  190. vga->sequencer[0x13] = l & 0xFF;
  191. vga->sequencer[0x14] = (l>>8) & 0xFF;
  192. }
  193. vgaxo(Seqx, 0x10, vga->sequencer[0x10]);
  194. vgaxo(Seqx, 0x12, vga->sequencer[0x12]);
  195. vgaxo(Seqx, 0x13, vga->sequencer[0x13]);
  196. vgaxo(Seqx, 0x14, vga->sequencer[0x14]);
  197. vgaxo(Seqx, 0x15, vga->sequencer[0x15]);
  198. vgaxo(Seqx, 0x16, vga->sequencer[0x16]);
  199. vgaxo(Seqx, 0x17, vga->sequencer[0x17]);
  200. vgaxo(Seqx, 0x18, vga->sequencer[0x18]);
  201. vgaxo(Crtx, 0x40, vga->crt[0x40]);
  202. vgaxo(Crtx, 0x41, vga->crt[0x41]);
  203. vgaxo(Crtx, 0x42, vga->crt[0x42]);
  204. vgaxo(Crtx, 0x44, vga->crt[0x44]);
  205. vgaxo(Crtx, 0x45, vga->crt[0x45]);
  206. vgaxo(Crtx, 0x46, vga->crt[0x46]);
  207. ctlr->flag |= Fload;
  208. }
  209. static void
  210. dump(Vga* vga, Ctlr* ctlr)
  211. {
  212. int i;
  213. printitem(ctlr->name, "Seq10");
  214. for(i = 0x10; i < 0x2E; i++)
  215. printreg(vga->sequencer[i]);
  216. printitem(ctlr->name, "Crt40");
  217. for(i = 0x40; i < 0x47; i++)
  218. printreg(vga->crt[i]);
  219. printitem(ctlr->name, "Crt50");
  220. printreg(vga->crt[0x50]);
  221. printitem(ctlr->name, "Cop status");
  222. printreg(vga->crt[0xFF]);
  223. }
  224. Ctlr ark2000pv = {
  225. "ark2000pv", /* name */
  226. snarf, /* snarf */
  227. options, /* options */
  228. init, /* init */
  229. load, /* load */
  230. dump, /* dump */
  231. };
  232. Ctlr ark2000pvhwgc = {
  233. "ark2000pvhwgc", /* name */
  234. 0, /* snarf */
  235. 0, /* options */
  236. 0, /* init */
  237. 0, /* load */
  238. 0, /* dump */
  239. };