vgaclgd546x.c 4.6 KB

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