vgaclgd542x.c 4.7 KB

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