cga.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "u.h"
  10. #include "lib.h"
  11. #include "mem.h"
  12. #include "dat.h"
  13. #include "fns.h"
  14. enum {
  15. Black = 0x00,
  16. Blue = 0x01,
  17. Green = 0x02,
  18. Cyan = 0x03,
  19. Red = 0x04,
  20. Magenta = 0x05,
  21. Brown = 0x06,
  22. Grey = 0x07,
  23. Bright = 0x08,
  24. Blinking = 0x80,
  25. Attr = (Black<<4)|Grey, /* (background<<4)|foreground */
  26. };
  27. enum {
  28. Index = 0x3D4,
  29. Data = Index+1,
  30. Width = 80*2,
  31. Height = 25,
  32. Poststrlen = 0,
  33. Postcodelen = 2,
  34. Postlen = Poststrlen+Postcodelen,
  35. };
  36. #define CGA ((uint8_t*)KADDR(0xB8000))
  37. static Lock cgalock;
  38. static int cgapos;
  39. static int cgainitdone;
  40. static int
  41. cgaregr(int index)
  42. {
  43. outb(Index, index);
  44. return inb(Data) & 0xFF;
  45. }
  46. static void
  47. cgaregw(int index, int data)
  48. {
  49. outb(Index, index);
  50. outb(Data, data);
  51. }
  52. static void
  53. cgacursor(void)
  54. {
  55. uint8_t *cga;
  56. cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
  57. cgaregw(0x0F, cgapos/2 & 0xFF);
  58. cga = CGA;
  59. cga[cgapos+1] = Attr;
  60. }
  61. static void
  62. cgaputc(int c)
  63. {
  64. int i;
  65. uint8_t *cga, *p;
  66. cga = CGA;
  67. if(c == '\n'){
  68. cgapos = cgapos/Width;
  69. cgapos = (cgapos+1)*Width;
  70. }
  71. else if(c == '\t'){
  72. i = 8 - ((cgapos/2)&7);
  73. while(i-- > 0)
  74. cgaputc(' ');
  75. }
  76. else if(c == '\b'){
  77. if(cgapos >= 2)
  78. cgapos -= 2;
  79. cgaputc(' ');
  80. cgapos -= 2;
  81. }
  82. else{
  83. cga[cgapos++] = c;
  84. cga[cgapos++] = Attr;
  85. }
  86. if(cgapos >= (Width*Height)-Postlen*2){
  87. memmove(cga, &cga[Width], Width*(Height-1));
  88. p = &cga[Width*(Height-1)-Postlen*2];
  89. for(i = 0; i < Width/2; i++){
  90. *p++ = ' ';
  91. *p++ = Attr;
  92. }
  93. cgapos -= Width;
  94. }
  95. cgacursor();
  96. }
  97. void
  98. cgaconsputs(char* s, int n)
  99. {
  100. ilock(&cgalock);
  101. while(n-- > 0)
  102. cgaputc(*s++);
  103. iunlock(&cgalock);
  104. }
  105. void
  106. cgapost(int code)
  107. {
  108. uint8_t *cga;
  109. static char hex[] = "0123456789ABCDEF";
  110. cga = CGA;
  111. cga[Width*Height-Postcodelen*2] = hex[(code>>4) & 0x0F];
  112. cga[Width*Height-Postcodelen*2+1] = Attr;
  113. cga[Width*Height-Postcodelen*2+2] = hex[code & 0x0F];
  114. cga[Width*Height-Postcodelen*2+3] = Attr;
  115. }
  116. void
  117. cgainit(void)
  118. {
  119. ilock(&cgalock);
  120. cgapos = cgaregr(0x0E)<<8;
  121. cgapos |= cgaregr(0x0F);
  122. cgapos *= 2;
  123. cgainitdone = 1;
  124. iunlock(&cgalock);
  125. }