vgaclgd546x.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. typedef struct Cursor546x Cursor546x;
  14. struct Cursor546x {
  15. ushort x;
  16. ushort y;
  17. ushort preset;
  18. ushort enable;
  19. ushort addr;
  20. };
  21. enum {
  22. PaletteState = 0xB0,
  23. CursorMMIO = 0xE0,
  24. };
  25. static ulong
  26. clgd546xlinear(VGAscr* scr, int* size, int* align)
  27. {
  28. ulong aperture, oaperture;
  29. int oapsize, wasupamem;
  30. Pcidev *p;
  31. oaperture = scr->aperture;
  32. oapsize = scr->apsize;
  33. wasupamem = scr->isupamem;
  34. aperture = 0;
  35. if(p = pcimatch(nil, 0x1013, 0)){
  36. switch(p->did){
  37. case 0xD0:
  38. case 0xD4:
  39. case 0xD6:
  40. aperture = p->mem[0].bar & ~0x0F;
  41. *size = p->mem[0].size;
  42. break;
  43. default:
  44. break;
  45. }
  46. }
  47. if(wasupamem){
  48. if(oaperture == aperture)
  49. return oaperture;
  50. upafree(oaperture, oapsize);
  51. }
  52. scr->isupamem = 0;
  53. aperture = upamalloc(aperture, *size, *align);
  54. if(aperture == 0){
  55. if(wasupamem && upamalloc(oaperture, oapsize, 0)){
  56. aperture = oaperture;
  57. scr->isupamem = 1;
  58. }
  59. else
  60. scr->isupamem = 0;
  61. }
  62. else
  63. scr->isupamem = 1;
  64. return aperture;
  65. }
  66. static void
  67. clgd546xenable(VGAscr* scr)
  68. {
  69. Pcidev *p;
  70. int size, align;
  71. ulong aperture;
  72. /*
  73. * Only once, can't be disabled for now.
  74. * scr->io holds the virtual address of
  75. * the MMIO registers.
  76. */
  77. if(scr->io)
  78. return;
  79. if(p = pcimatch(nil, 0x1013, 0)){
  80. switch(p->did){
  81. case 0xD0:
  82. case 0xD4:
  83. case 0xD6:
  84. break;
  85. default:
  86. return;
  87. }
  88. }
  89. else
  90. return;
  91. scr->io = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
  92. if(scr->io == 0)
  93. return;
  94. addvgaseg("clgd546xmmio", scr->io, p->mem[1].size);
  95. scr->io = (ulong)KADDR(scr->io);
  96. size = p->mem[0].size;
  97. align = 0;
  98. aperture = clgd546xlinear(scr, &size, &align);
  99. if(aperture) {
  100. scr->aperture = aperture;
  101. scr->apsize = size;
  102. addvgaseg("clgd546xscreen", aperture, size);
  103. }
  104. }
  105. static void
  106. clgd546xcurdisable(VGAscr* scr)
  107. {
  108. Cursor546x *cursor546x;
  109. if(scr->io == 0)
  110. return;
  111. cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
  112. cursor546x->enable = 0;
  113. }
  114. static void
  115. clgd546xcurload(VGAscr* scr, Cursor* curs)
  116. {
  117. int c, i, m, y;
  118. uchar *p;
  119. Cursor546x *cursor546x;
  120. if(scr->io == 0)
  121. return;
  122. cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
  123. /*
  124. * Disable the cursor then change only the bits
  125. * that need it.
  126. */
  127. cursor546x->enable = 0;
  128. p = (uchar*)(scr->aperture + scr->storage);
  129. for(y = 0; y < 16; y++){
  130. c = curs->set[2*y];
  131. m = 0;
  132. for(i = 0; i < 8; i++){
  133. if(c & (1<<(7-i)))
  134. m |= 1<<i;
  135. }
  136. *p++ = m;
  137. c = curs->set[2*y + 1];
  138. m = 0;
  139. for(i = 0; i < 8; i++){
  140. if(c & (1<<(7-i)))
  141. m |= 1<<i;
  142. }
  143. *p++ = m;
  144. p += 6;
  145. c = curs->set[2*y]|curs->clr[2*y];
  146. m = 0;
  147. for(i = 0; i < 8; i++){
  148. if(c & (1<<(7-i)))
  149. m |= 1<<i;
  150. }
  151. *p++ = m;
  152. c = curs->set[2*y + 1]|curs->clr[2*y + 1];
  153. m = 0;
  154. for(i = 0; i < 8; i++){
  155. if(c & (1<<(7-i)))
  156. m |= 1<<i;
  157. }
  158. *p++ = m;
  159. p += 6;
  160. }
  161. /*
  162. * Save the cursor hotpoint and enable the cursor.
  163. */
  164. scr->offset = curs->offset;
  165. cursor546x->enable = 1;
  166. }
  167. static int
  168. clgd546xcurmove(VGAscr* scr, Point p)
  169. {
  170. int x, xo, y, yo;
  171. Cursor546x *cursor546x;
  172. if(scr->io == 0)
  173. return 1;
  174. cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
  175. if((x = p.x+scr->offset.x) < 0){
  176. xo = -x;
  177. x = 0;
  178. }
  179. else
  180. xo = 0;
  181. if((y = p.y+scr->offset.y) < 0){
  182. yo = -y;
  183. y = 0;
  184. }
  185. else
  186. yo = 0;
  187. cursor546x->preset = (xo<<8)|yo;
  188. cursor546x->x = x;
  189. cursor546x->y = y;
  190. return 0;
  191. }
  192. static void
  193. clgd546xcurenable(VGAscr* scr)
  194. {
  195. uchar *p;
  196. Cursor546x *cursor546x;
  197. clgd546xenable(scr);
  198. if(scr->io == 0)
  199. return;
  200. cursor546x = (Cursor546x*)(scr->io+CursorMMIO);
  201. /*
  202. * Cursor colours.
  203. * Can't call setcolor here as cursor is already locked.
  204. */
  205. p = (uchar*)(scr->io+PaletteState);
  206. *p |= 0x08;
  207. vgao(PaddrW, 0x00);
  208. vgao(Pdata, Pwhite);
  209. vgao(Pdata, Pwhite);
  210. vgao(Pdata, Pwhite);
  211. vgao(PaddrW, 0x0F);
  212. vgao(Pdata, Pblack);
  213. vgao(Pdata, Pblack);
  214. vgao(Pdata, Pblack);
  215. *p &= ~0x08;
  216. /*
  217. * Find a place for the cursor data in display memory.
  218. * 2 cursor images might be needed, 1KB each so use the last
  219. * 2KB of the framebuffer and initialise them to be
  220. * transparent.
  221. */
  222. scr->storage = ((vgaxi(Seqx, 0x14) & 0x07)+1)*1024*1022;
  223. cursor546x->addr = (scr->storage>>10)<<2;
  224. memset((uchar*)(scr->aperture + scr->storage), 0, 2*64*16);
  225. /*
  226. * Load, locate and enable the 64x64 cursor.
  227. */
  228. clgd546xcurload(scr, &arrow);
  229. clgd546xcurmove(scr, ZP);
  230. cursor546x->enable = 1;
  231. }
  232. VGAdev vgaclgd546xdev = {
  233. "clgd546x",
  234. clgd546xenable,
  235. nil,
  236. nil,
  237. clgd546xlinear,
  238. };
  239. VGAcur vgaclgd546xcur = {
  240. "clgd546xhwgc",
  241. clgd546xcurenable,
  242. clgd546xcurdisable,
  243. clgd546xcurload,
  244. clgd546xcurmove,
  245. };