vgaark2000pv.c 3.3 KB

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