cga.c 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include "all.h"
  2. #include "mem.h"
  3. enum {
  4. Width = 160,
  5. Height = 25,
  6. Attr = 7, /* white on black */
  7. };
  8. #define CGASCREENBASE ((uchar*)(KZERO|0xB8000))
  9. static int pos;
  10. static int screeninitdone;
  11. static Lock screenlock;
  12. static uchar
  13. cgaregr(int index)
  14. {
  15. outb(0x3D4, index);
  16. return inb(0x3D4+1) & 0xFF;
  17. }
  18. static void
  19. cgaregw(int index, int data)
  20. {
  21. outb(0x3D4, index);
  22. outb(0x3D4+1, data);
  23. }
  24. static void
  25. movecursor(void)
  26. {
  27. cgaregw(0x0E, (pos/2>>8) & 0xFF);
  28. cgaregw(0x0F, pos/2 & 0xFF);
  29. CGASCREENBASE[pos+1] = Attr;
  30. }
  31. static void
  32. cgascreenputc(int c)
  33. {
  34. int i;
  35. if(c == '\r')
  36. return;
  37. if(c == '\n'){
  38. pos = pos/Width;
  39. pos = (pos+1)*Width;
  40. }
  41. else if(c == '\t'){
  42. i = 4 - ((pos/2)&3);
  43. while(i-->0)
  44. cgascreenputc(' ');
  45. }
  46. else if(c == '\b'){
  47. if(pos >= 2)
  48. pos -= 2;
  49. cgascreenputc(' ');
  50. pos -= 2;
  51. }
  52. else{
  53. CGASCREENBASE[pos++] = c;
  54. CGASCREENBASE[pos++] = Attr;
  55. }
  56. if(pos >= Width*Height){
  57. memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
  58. memset(&CGASCREENBASE[Width*(Height-1)], 0, Width);
  59. pos = Width*(Height-1);
  60. }
  61. movecursor();
  62. }
  63. static void
  64. screeninit(void)
  65. {
  66. lock(&screenlock);
  67. if(screeninitdone == 0){
  68. pos = cgaregr(0x0E)<<8;
  69. pos |= cgaregr(0x0F);
  70. pos *= 2;
  71. screeninitdone = 1;
  72. }
  73. unlock(&screenlock);
  74. }
  75. void
  76. cgaputs(char* s, int n)
  77. {
  78. if(screeninitdone == 0)
  79. screeninit();
  80. while(n-- > 0)
  81. cgascreenputc(*s++);
  82. }
  83. void
  84. cgaputc(int c)
  85. {
  86. if(screeninitdone == 0)
  87. screeninit();
  88. cgascreenputc(c);
  89. }