vgaclgd542x.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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. static int
  14. clgd542xpageset(VGAscr*, int page)
  15. {
  16. uchar gr09;
  17. int opage;
  18. if(vgaxi(Seqx, 0x07) & 0xF0)
  19. page = 0;
  20. gr09 = vgaxi(Grx, 0x09);
  21. if(vgaxi(Grx, 0x0B) & 0x20){
  22. vgaxo(Grx, 0x09, page<<2);
  23. opage = gr09>>2;
  24. }
  25. else{
  26. vgaxo(Grx, 0x09, page<<4);
  27. opage = gr09>>4;
  28. }
  29. return opage;
  30. }
  31. static void
  32. clgd542xpage(VGAscr* scr, int page)
  33. {
  34. lock(&scr->devlock);
  35. clgd542xpageset(scr, page);
  36. unlock(&scr->devlock);
  37. }
  38. static ulong
  39. clgd542xlinear(VGAscr* scr, int* size, int* align)
  40. {
  41. ulong aperture, oaperture;
  42. int oapsize, wasupamem;
  43. Pcidev *p;
  44. oaperture = scr->aperture;
  45. oapsize = scr->apsize;
  46. wasupamem = scr->isupamem;
  47. if(wasupamem)
  48. upafree(oaperture, oapsize);
  49. scr->isupamem = 0;
  50. if(p = pcimatch(nil, 0x1013, 0)){
  51. aperture = p->mem[0].bar & ~0x0F;
  52. *size = p->mem[0].size;
  53. }
  54. else
  55. aperture = 0;
  56. aperture = upamalloc(aperture, *size, *align);
  57. if(aperture == 0){
  58. if(wasupamem && upamalloc(oaperture, oapsize, 0))
  59. scr->isupamem = 1;
  60. }
  61. else
  62. scr->isupamem = 1;
  63. return aperture;
  64. }
  65. static void
  66. clgd542xdisable(VGAscr*)
  67. {
  68. uchar sr12;
  69. sr12 = vgaxi(Seqx, 0x12);
  70. vgaxo(Seqx, 0x12, sr12 & ~0x01);
  71. }
  72. static void
  73. clgd542xenable(VGAscr* scr)
  74. {
  75. uchar sr12;
  76. int mem, x;
  77. /*
  78. * Disable the cursor.
  79. */
  80. sr12 = vgaxi(Seqx, 0x12);
  81. vgaxo(Seqx, 0x12, sr12 & ~0x01);
  82. /*
  83. * Cursor colours.
  84. * Can't call setcolor here as cursor is already locked.
  85. */
  86. vgaxo(Seqx, 0x12, sr12|0x02);
  87. vgao(PaddrW, 0x00);
  88. vgao(Pdata, Pwhite);
  89. vgao(Pdata, Pwhite);
  90. vgao(Pdata, Pwhite);
  91. vgao(PaddrW, 0x0F);
  92. vgao(Pdata, Pblack);
  93. vgao(Pdata, Pblack);
  94. vgao(Pdata, Pblack);
  95. vgaxo(Seqx, 0x12, sr12);
  96. mem = 0;
  97. switch(vgaxi(Crtx, 0x27) & ~0x03){
  98. case 0x88: /* CL-GD5420 */
  99. case 0x8C: /* CL-GD5422 */
  100. case 0x94: /* CL-GD5424 */
  101. case 0x80: /* CL-GD5425 */
  102. case 0x90: /* CL-GD5426 */
  103. case 0x98: /* CL-GD5427 */
  104. case 0x9C: /* CL-GD5429 */
  105. /*
  106. * The BIOS leaves the memory size in Seq0A, bits 4 and 3.
  107. * See Technical Reference Manual Appendix E1, Section 1.3.2.
  108. *
  109. * The storage area for the 64x64 cursors is the last 16Kb of
  110. * display memory.
  111. */
  112. mem = (vgaxi(Seqx, 0x0A)>>3) & 0x03;
  113. break;
  114. case 0xA0: /* CL-GD5430 */
  115. case 0xA8: /* CL-GD5434 */
  116. case 0xAC: /* CL-GD5436 */
  117. case 0xB8: /* CL-GD5446 */
  118. case 0x30: /* CL-GD7543 */
  119. /*
  120. * Attempt to intuit the memory size from the DRAM control
  121. * register. Minimum is 512KB.
  122. * If DRAM bank switching is on then there's double.
  123. */
  124. x = vgaxi(Seqx, 0x0F);
  125. mem = (x>>3) & 0x03;
  126. if(x & 0x80)
  127. mem++;
  128. break;
  129. default: /* uh, ah dunno */
  130. break;
  131. }
  132. scr->storage = ((256<<mem)-16)*1024;
  133. /*
  134. * Set the current cursor to index 0
  135. * and turn the 64x64 cursor on.
  136. */
  137. vgaxo(Seqx, 0x13, 0);
  138. vgaxo(Seqx, 0x12, sr12|0x05);
  139. }
  140. static void
  141. clgd542xinitcursor(VGAscr* scr, int xo, int yo, int index)
  142. {
  143. uchar *p, seq07;
  144. uint p0, p1;
  145. int opage, x, y;
  146. /*
  147. * Is linear addressing turned on? This will determine
  148. * how we access the cursor storage.
  149. */
  150. seq07 = vgaxi(Seqx, 0x07);
  151. opage = 0;
  152. p = KADDR(scr->aperture);
  153. if(!(seq07 & 0xF0)){
  154. lock(&scr->devlock);
  155. opage = clgd542xpageset(scr, scr->storage>>16);
  156. p += (scr->storage & 0xFFFF);
  157. }
  158. else
  159. p += scr->storage;
  160. p += index*1024;
  161. for(y = yo; y < 16; y++){
  162. p0 = scr->set[2*y];
  163. p1 = scr->set[2*y+1];
  164. if(xo){
  165. p0 = (p0<<xo)|(p1>>(8-xo));
  166. p1 <<= xo;
  167. }
  168. *p++ = p0;
  169. *p++ = p1;
  170. for(x = 16; x < 64; x += 8)
  171. *p++ = 0x00;
  172. p0 = scr->clr[2*y]|scr->set[2*y];
  173. p1 = scr->clr[2*y+1]|scr->set[2*y+1];
  174. if(xo){
  175. p0 = (p0<<xo)|(p1>>(8-xo));
  176. p1 <<= xo;
  177. }
  178. *p++ = p0;
  179. *p++ = p1;
  180. for(x = 16; x < 64; x += 8)
  181. *p++ = 0x00;
  182. }
  183. while(y < 64+yo){
  184. for(x = 0; x < 64; x += 8){
  185. *p++ = 0x00;
  186. *p++ = 0x00;
  187. }
  188. y++;
  189. }
  190. if(!(seq07 & 0xF0)){
  191. clgd542xpageset(scr, opage);
  192. unlock(&scr->devlock);
  193. }
  194. }
  195. static void
  196. clgd542xload(VGAscr* scr, Cursor* curs)
  197. {
  198. uchar sr12;
  199. /*
  200. * Disable the cursor.
  201. */
  202. sr12 = vgaxi(Seqx, 0x12);
  203. vgaxo(Seqx, 0x12, sr12 & ~0x01);
  204. memmove(&scr->Cursor, curs, sizeof(Cursor));
  205. clgd542xinitcursor(scr, 0, 0, 0);
  206. /*
  207. * Enable the cursor.
  208. */
  209. vgaxo(Seqx, 0x13, 0);
  210. vgaxo(Seqx, 0x12, sr12|0x05);
  211. }
  212. static int
  213. clgd542xmove(VGAscr* scr, Point p)
  214. {
  215. int index, x, xo, y, yo;
  216. index = 0;
  217. if((x = p.x+scr->offset.x) < 0){
  218. xo = -x;
  219. x = 0;
  220. }
  221. else
  222. xo = 0;
  223. if((y = p.y+scr->offset.y) < 0){
  224. yo = -y;
  225. y = 0;
  226. }
  227. else
  228. yo = 0;
  229. if(xo || yo){
  230. clgd542xinitcursor(scr, xo, yo, 1);
  231. index = 1;
  232. }
  233. vgaxo(Seqx, 0x13, index<<2);
  234. vgaxo(Seqx, 0x10|((x & 0x07)<<5), (x>>3) & 0xFF);
  235. vgaxo(Seqx, 0x11|((y & 0x07)<<5), (y>>3) & 0xFF);
  236. return 0;
  237. }
  238. VGAdev vgaclgd542xdev = {
  239. "clgd542x",
  240. 0,
  241. 0,
  242. clgd542xpage,
  243. clgd542xlinear,
  244. };
  245. VGAcur vgaclgd542xcur = {
  246. "clgd542xhwgc",
  247. clgd542xenable,
  248. clgd542xdisable,
  249. clgd542xload,
  250. clgd542xmove,
  251. };