vgaark2000pv.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "../port/error.h"
  7. #define Image IMAGE
  8. #include <draw.h>
  9. #include <memdraw.h>
  10. #include <cursor.h>
  11. #include "screen.h"
  12. static int
  13. ark2000pvpageset(VGAscr*, int page)
  14. {
  15. uchar seq15;
  16. seq15 = vgaxi(Seqx, 0x15);
  17. vgaxo(Seqx, 0x15, page);
  18. vgaxo(Seqx, 0x16, page);
  19. return seq15;
  20. }
  21. static void
  22. ark2000pvpage(VGAscr* scr, int page)
  23. {
  24. lock(&scr->devlock);
  25. ark2000pvpageset(scr, page);
  26. unlock(&scr->devlock);
  27. }
  28. static void
  29. ark2000pvdisable(VGAscr*)
  30. {
  31. uchar seq20;
  32. seq20 = vgaxi(Seqx, 0x20) & ~0x08;
  33. vgaxo(Seqx, 0x20, seq20);
  34. }
  35. static void
  36. ark2000pvenable(VGAscr* scr)
  37. {
  38. uchar seq20;
  39. ulong storage;
  40. /*
  41. * Disable the cursor then configure for X-Windows style,
  42. * 32x32 and 4/8-bit colour depth.
  43. * Set cursor colours for 4/8-bit.
  44. */
  45. seq20 = vgaxi(Seqx, 0x20) & ~0x1F;
  46. vgaxo(Seqx, 0x20, seq20);
  47. seq20 |= 0x18;
  48. vgaxo(Seqx, 0x26, 0x00);
  49. vgaxo(Seqx, 0x27, 0x00);
  50. vgaxo(Seqx, 0x28, 0x00);
  51. vgaxo(Seqx, 0x29, 0xFF);
  52. vgaxo(Seqx, 0x2A, 0xFF);
  53. vgaxo(Seqx, 0x2B, 0xFF);
  54. /*
  55. * Cursor storage is a 256 byte or 1Kb block located in the last
  56. * 16Kb of video memory. Crt25 is the index of which block.
  57. */
  58. storage = (vgaxi(Seqx, 0x10)>>6) & 0x03;
  59. storage = (1024*1024)<<storage;
  60. storage -= 256;
  61. scr->storage = storage;
  62. vgaxo(Seqx, 0x25, 0x3F);
  63. /*
  64. * Enable the cursor.
  65. */
  66. vgaxo(Seqx, 0x20, seq20);
  67. }
  68. static void
  69. ark2000pvload(VGAscr* scr, Cursor* curs)
  70. {
  71. uchar *p, seq10;
  72. int opage, x, y;
  73. /*
  74. * Is linear addressing turned on? This will determine
  75. * how we access the cursor storage.
  76. */
  77. seq10 = vgaxi(Seqx, 0x10);
  78. opage = 0;
  79. p = KADDR(scr->aperture);
  80. if(!(seq10 & 0x10)){
  81. lock(&scr->devlock);
  82. opage = ark2000pvpageset(scr, scr->storage>>16);
  83. p += (scr->storage & 0xFFFF);
  84. }
  85. else
  86. p += scr->storage;
  87. /*
  88. * The cursor is set in X11 mode which gives the following
  89. * truth table:
  90. * and xor colour
  91. * 0 0 underlying pixel colour
  92. * 0 1 underlying pixel colour
  93. * 1 0 background colour
  94. * 1 1 foreground colour
  95. * Put the cursor into the top-left of the 32x32 array.
  96. * The manual doesn't say what the data layout in memory is -
  97. * this worked out by trial and error.
  98. */
  99. for(y = 0; y < 32; y++){
  100. for(x = 0; x < 32/8; x++){
  101. if(x < 16/8 && y < 16){
  102. *p++ = curs->clr[2*y + x]|curs->set[2*y + x];
  103. *p++ = curs->set[2*y + x];
  104. }
  105. else {
  106. *p++ = 0x00;
  107. *p++ = 0x00;
  108. }
  109. }
  110. }
  111. if(!(seq10 & 0x10)){
  112. ark2000pvpageset(scr, opage);
  113. unlock(&scr->devlock);
  114. }
  115. /*
  116. * Save the cursor hotpoint.
  117. */
  118. scr->offset = curs->offset;
  119. }
  120. static int
  121. ark2000pvmove(VGAscr* scr, Point p)
  122. {
  123. int x, xo, y, yo;
  124. /*
  125. * Mustn't position the cursor offscreen even partially,
  126. * or it might disappear. Therefore, if x or y is -ve, adjust the
  127. * cursor origins instead.
  128. */
  129. if((x = p.x+scr->offset.x) < 0){
  130. xo = -x;
  131. x = 0;
  132. }
  133. else
  134. xo = 0;
  135. if((y = p.y+scr->offset.y) < 0){
  136. yo = -y;
  137. y = 0;
  138. }
  139. else
  140. yo = 0;
  141. /*
  142. * Load the new values.
  143. */
  144. vgaxo(Seqx, 0x2C, xo);
  145. vgaxo(Seqx, 0x2D, yo);
  146. vgaxo(Seqx, 0x21, (x>>8) & 0x0F);
  147. vgaxo(Seqx, 0x22, x & 0xFF);
  148. vgaxo(Seqx, 0x23, (y>>8) & 0x0F);
  149. vgaxo(Seqx, 0x24, y & 0xFF);
  150. return 0;
  151. }
  152. VGAdev vgaark2000pvdev = {
  153. "ark2000pv",
  154. 0,
  155. 0,
  156. ark2000pvpage,
  157. 0,
  158. };
  159. VGAcur vgaark2000pvcur = {
  160. "ark2000pvhwgc",
  161. ark2000pvenable,
  162. ark2000pvdisable,
  163. ark2000pvload,
  164. ark2000pvmove,
  165. };