vgaclgd542x.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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. default: /* uh, ah dunno */
  108. break;
  109. }
  110. scr->storage = ((256<<mem)-16)*1024;
  111. /*
  112. * Set the current cursor to index 0
  113. * and turn the 64x64 cursor on.
  114. */
  115. vgaxo(Seqx, 0x13, 0);
  116. vgaxo(Seqx, 0x12, sr12|0x05);
  117. }
  118. static void
  119. clgd542xinitcursor(VGAscr* scr, int xo, int yo, int index)
  120. {
  121. uchar *p, seq07;
  122. uint p0, p1;
  123. int opage, x, y;
  124. /*
  125. * Is linear addressing turned on? This will determine
  126. * how we access the cursor storage.
  127. */
  128. seq07 = vgaxi(Seqx, 0x07);
  129. opage = 0;
  130. p = scr->vaddr;
  131. if(!(seq07 & 0xF0)){
  132. lock(&scr->devlock);
  133. opage = clgd542xpageset(scr, scr->storage>>16);
  134. p += (scr->storage & 0xFFFF);
  135. }
  136. else
  137. p += scr->storage;
  138. p += index*1024;
  139. for(y = yo; y < 16; y++){
  140. p0 = scr->set[2*y];
  141. p1 = scr->set[2*y+1];
  142. if(xo){
  143. p0 = (p0<<xo)|(p1>>(8-xo));
  144. p1 <<= xo;
  145. }
  146. *p++ = p0;
  147. *p++ = p1;
  148. for(x = 16; x < 64; x += 8)
  149. *p++ = 0x00;
  150. p0 = scr->clr[2*y]|scr->set[2*y];
  151. p1 = scr->clr[2*y+1]|scr->set[2*y+1];
  152. if(xo){
  153. p0 = (p0<<xo)|(p1>>(8-xo));
  154. p1 <<= xo;
  155. }
  156. *p++ = p0;
  157. *p++ = p1;
  158. for(x = 16; x < 64; x += 8)
  159. *p++ = 0x00;
  160. }
  161. while(y < 64+yo){
  162. for(x = 0; x < 64; x += 8){
  163. *p++ = 0x00;
  164. *p++ = 0x00;
  165. }
  166. y++;
  167. }
  168. if(!(seq07 & 0xF0)){
  169. clgd542xpageset(scr, opage);
  170. unlock(&scr->devlock);
  171. }
  172. }
  173. static void
  174. clgd542xload(VGAscr* scr, Cursor* curs)
  175. {
  176. uchar sr12;
  177. /*
  178. * Disable the cursor.
  179. */
  180. sr12 = vgaxi(Seqx, 0x12);
  181. vgaxo(Seqx, 0x12, sr12 & ~0x01);
  182. memmove(&scr->Cursor, curs, sizeof(Cursor));
  183. clgd542xinitcursor(scr, 0, 0, 0);
  184. /*
  185. * Enable the cursor.
  186. */
  187. vgaxo(Seqx, 0x13, 0);
  188. vgaxo(Seqx, 0x12, sr12|0x05);
  189. }
  190. static int
  191. clgd542xmove(VGAscr* scr, Point p)
  192. {
  193. int index, x, xo, y, yo;
  194. index = 0;
  195. if((x = p.x+scr->offset.x) < 0){
  196. xo = -x;
  197. x = 0;
  198. }
  199. else
  200. xo = 0;
  201. if((y = p.y+scr->offset.y) < 0){
  202. yo = -y;
  203. y = 0;
  204. }
  205. else
  206. yo = 0;
  207. if(xo || yo){
  208. clgd542xinitcursor(scr, xo, yo, 1);
  209. index = 1;
  210. }
  211. vgaxo(Seqx, 0x13, index<<2);
  212. vgaxo(Seqx, 0x10|((x & 0x07)<<5), (x>>3) & 0xFF);
  213. vgaxo(Seqx, 0x11|((y & 0x07)<<5), (y>>3) & 0xFF);
  214. return 0;
  215. }
  216. VGAdev vgaclgd542xdev = {
  217. "clgd542x",
  218. 0,
  219. 0,
  220. clgd542xpage,
  221. clgd542xlinear,
  222. };
  223. VGAcur vgaclgd542xcur = {
  224. "clgd542xhwgc",
  225. clgd542xenable,
  226. clgd542xdisable,
  227. clgd542xload,
  228. clgd542xmove,
  229. };