console.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. * File : console.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://openlab.rt-thread.com/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2006-09-15 QiuYi the first version
  13. */
  14. #include <rtthread.h>
  15. #include <rthw.h>
  16. #include <bsp.h>
  17. static unsigned addr_6845;
  18. static rt_uint16_t *crt_buf;
  19. static rt_int16 crt_pos;
  20. extern void rt_serial_init(void);
  21. extern char rt_keyboard_getc(void);
  22. static void rt_console_putc(int c);
  23. /**
  24. * @addtogroup QEMU
  25. */
  26. /*@{*/
  27. /**
  28. * This function initializes cga
  29. *
  30. */
  31. void rt_cga_init(void)
  32. {
  33. rt_uint16_t volatile *cp;
  34. rt_uint16_t was;
  35. rt_uint32_t pos;
  36. cp = (short *) (CGA_BUF);
  37. was = *cp;
  38. *cp = (rt_uint16_t) 0xA55A;
  39. if (*cp != 0xA55A)
  40. {
  41. cp = (rt_int16 *) (MONO_BUF);
  42. addr_6845 = MONO_BASE;
  43. }
  44. else
  45. {
  46. *cp = was;
  47. addr_6845 = CGA_BASE;
  48. }
  49. /* Extract cursor location */
  50. outb(addr_6845, 14);
  51. pos = inb(addr_6845+1) << 8;
  52. outb(addr_6845, 15);
  53. pos |= inb(addr_6845+1);
  54. crt_buf = (rt_uint16_t *)cp;
  55. crt_pos = pos;
  56. }
  57. /**
  58. * This function will write a character to cga
  59. *
  60. * @param c the char to write
  61. */
  62. static void rt_cga_putc(int c)
  63. {
  64. /* if no attribute given, then use black on white */
  65. if (!(c & ~0xff)) c |= 0x0700;
  66. switch (c & 0xff)
  67. {
  68. case '\b':
  69. if (crt_pos > 0)
  70. {
  71. crt_pos--;
  72. crt_buf[crt_pos] = (c&~0xff) | ' ';
  73. }
  74. break;
  75. case '\n':
  76. crt_pos += CRT_COLS;
  77. /* cascade */
  78. case '\r':
  79. crt_pos -= (crt_pos % CRT_COLS);
  80. break;
  81. case '\t':
  82. rt_console_putc(' ');
  83. rt_console_putc(' ');
  84. rt_console_putc(' ');
  85. rt_console_putc(' ');
  86. rt_console_putc(' ');
  87. break;
  88. default:
  89. crt_buf[crt_pos++] = c; /* write the character */
  90. break;
  91. }
  92. if (crt_pos >= CRT_SIZE)
  93. {
  94. rt_int32 i;
  95. rt_memcpy(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) << 1);
  96. for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i++)
  97. crt_buf[i] = 0x0700 | ' ';
  98. crt_pos -= CRT_COLS;
  99. }
  100. outb(addr_6845, 14);
  101. outb(addr_6845+1, crt_pos >> 8);
  102. outb(addr_6845, 15);
  103. outb(addr_6845+1, crt_pos);
  104. }
  105. /**
  106. * This function will write a character to serial an cga
  107. *
  108. * @param c the char to write
  109. */
  110. static void rt_console_putc(int c)
  111. {
  112. rt_cga_putc(c);
  113. rt_serial_putc(c);
  114. }
  115. /**
  116. * This function initializes console
  117. *
  118. */
  119. void rt_console_init(void)
  120. {
  121. rt_cga_init();
  122. rt_serial_init();
  123. }
  124. /**
  125. * This function is used to display a string on console, normally, it's
  126. * invoked by rt_kprintf
  127. *
  128. * @param str the displayed string
  129. */
  130. void rt_console_puts(const char* str)
  131. {
  132. while (*str)
  133. {
  134. rt_console_putc (*str++);
  135. }
  136. }
  137. #define BY2CONS 512
  138. static struct
  139. {
  140. rt_uint8_t buf[BY2CONS];
  141. rt_uint32_t rpos;
  142. rt_uint32_t wpos;
  143. }cons;
  144. static void rt_console_intr(char (*proc)(void))
  145. {
  146. int c;
  147. while ((c = (*proc)()) != -1)
  148. {
  149. if (c == 0)
  150. continue;
  151. cons.buf[cons.wpos++] = c;
  152. if (cons.wpos == BY2CONS)
  153. cons.wpos = 0;
  154. }
  155. }
  156. /**
  157. * return the next input character from the console,either from serial,
  158. * or keyboard
  159. *
  160. */
  161. int rt_console_getc(void)
  162. {
  163. int c;
  164. rt_console_intr(rt_serial_getc);
  165. rt_console_intr(rt_keyboard_getc);
  166. if (cons.rpos != cons.wpos)
  167. {
  168. c = cons.buf[cons.rpos++];
  169. if (cons.rpos == BY2CONS)
  170. cons.rpos = 0;
  171. return c;
  172. }
  173. return 0;
  174. }
  175. /*@}*/