vgaclgd546x.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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 void
  26. clgd546xlinear(VGAscr* scr, int, int)
  27. {
  28. vgalinearpci(scr);
  29. }
  30. static void
  31. clgd546xenable(VGAscr* scr)
  32. {
  33. Pcidev *p;
  34. if(scr->mmio)
  35. return;
  36. if((p = pcimatch(nil, 0x1013, 0)) == nil)
  37. return;
  38. switch(p->did){
  39. case 0xD0:
  40. case 0xD4:
  41. case 0xD6:
  42. break;
  43. default:
  44. return;
  45. }
  46. scr->pci = p;
  47. scr->mmio = vmap(p->mem[1].bar&~0x0F, p->mem[1].size);
  48. if(scr->mmio == 0)
  49. return;
  50. addvgaseg("clgd546xmmio", p->mem[1].bar&~0x0F, p->mem[1].size);
  51. }
  52. static void
  53. clgd546xcurdisable(VGAscr* scr)
  54. {
  55. Cursor546x *cursor546x;
  56. if(scr->mmio == 0)
  57. return;
  58. cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
  59. cursor546x->enable = 0;
  60. }
  61. static void
  62. clgd546xcurload(VGAscr* scr, Cursor* curs)
  63. {
  64. int c, i, m, y;
  65. uchar *p;
  66. Cursor546x *cursor546x;
  67. if(scr->mmio == 0)
  68. return;
  69. cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
  70. /*
  71. * Disable the cursor then change only the bits
  72. * that need it.
  73. */
  74. cursor546x->enable = 0;
  75. p = (uchar*)scr->vaddr + scr->storage;
  76. for(y = 0; y < 16; y++){
  77. c = curs->set[2*y];
  78. m = 0;
  79. for(i = 0; i < 8; i++){
  80. if(c & (1<<(7-i)))
  81. m |= 1<<i;
  82. }
  83. *p++ = m;
  84. c = curs->set[2*y + 1];
  85. m = 0;
  86. for(i = 0; i < 8; i++){
  87. if(c & (1<<(7-i)))
  88. m |= 1<<i;
  89. }
  90. *p++ = m;
  91. p += 6;
  92. c = curs->set[2*y]|curs->clr[2*y];
  93. m = 0;
  94. for(i = 0; i < 8; i++){
  95. if(c & (1<<(7-i)))
  96. m |= 1<<i;
  97. }
  98. *p++ = m;
  99. c = curs->set[2*y + 1]|curs->clr[2*y + 1];
  100. m = 0;
  101. for(i = 0; i < 8; i++){
  102. if(c & (1<<(7-i)))
  103. m |= 1<<i;
  104. }
  105. *p++ = m;
  106. p += 6;
  107. }
  108. /*
  109. * Save the cursor hotpoint and enable the cursor.
  110. */
  111. scr->offset = curs->offset;
  112. cursor546x->enable = 1;
  113. }
  114. static int
  115. clgd546xcurmove(VGAscr* scr, Point p)
  116. {
  117. int x, xo, y, yo;
  118. Cursor546x *cursor546x;
  119. if(scr->mmio == 0)
  120. return 1;
  121. cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
  122. if((x = p.x+scr->offset.x) < 0){
  123. xo = -x;
  124. x = 0;
  125. }
  126. else
  127. xo = 0;
  128. if((y = p.y+scr->offset.y) < 0){
  129. yo = -y;
  130. y = 0;
  131. }
  132. else
  133. yo = 0;
  134. cursor546x->preset = (xo<<8)|yo;
  135. cursor546x->x = x;
  136. cursor546x->y = y;
  137. return 0;
  138. }
  139. static void
  140. clgd546xcurenable(VGAscr* scr)
  141. {
  142. uchar *p;
  143. Cursor546x *cursor546x;
  144. clgd546xenable(scr);
  145. if(scr->mmio == 0)
  146. return;
  147. cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
  148. /*
  149. * Cursor colours.
  150. * Can't call setcolor here as cursor is already locked.
  151. */
  152. p = (uchar*)scr->mmio+PaletteState;
  153. *p |= 0x08;
  154. vgao(PaddrW, 0x00);
  155. vgao(Pdata, Pwhite);
  156. vgao(Pdata, Pwhite);
  157. vgao(Pdata, Pwhite);
  158. vgao(PaddrW, 0x0F);
  159. vgao(Pdata, Pblack);
  160. vgao(Pdata, Pblack);
  161. vgao(Pdata, Pblack);
  162. *p &= ~0x08;
  163. /*
  164. * Find a place for the cursor data in display memory.
  165. * 2 cursor images might be needed, 1KB each so use the last
  166. * 2KB of the framebuffer and initialise them to be
  167. * transparent.
  168. */
  169. scr->storage = ((vgaxi(Seqx, 0x14) & 0x07)+1)*1024*1022;
  170. cursor546x->addr = (scr->storage>>10)<<2;
  171. memset((uchar*)scr->vaddr + scr->storage, 0, 2*64*16);
  172. /*
  173. * Load, locate and enable the 64x64 cursor.
  174. */
  175. clgd546xcurload(scr, &arrow);
  176. clgd546xcurmove(scr, ZP);
  177. cursor546x->enable = 1;
  178. }
  179. VGAdev vgaclgd546xdev = {
  180. "clgd546x",
  181. clgd546xenable,
  182. nil,
  183. nil,
  184. clgd546xlinear,
  185. };
  186. VGAcur vgaclgd546xcur = {
  187. "clgd546xhwgc",
  188. clgd546xcurenable,
  189. clgd546xcurdisable,
  190. clgd546xcurload,
  191. clgd546xcurmove,
  192. };