console.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. #include "serial.h"
  18. static unsigned addr_6845;
  19. static rt_uint16_t *crt_buf;
  20. static rt_int16_t crt_pos;
  21. extern void rt_serial_init(void);
  22. extern char rt_keyboard_getc(void);
  23. static void rt_console_putc(int c);
  24. /**
  25. * @addtogroup QEMU
  26. */
  27. /*@{*/
  28. /**
  29. * This function initializes cga
  30. *
  31. */
  32. void rt_cga_init(void)
  33. {
  34. rt_uint16_t volatile *cp;
  35. rt_uint16_t was;
  36. rt_uint32_t pos;
  37. cp = (rt_uint16_t *) (CGA_BUF);
  38. was = *cp;
  39. *cp = (rt_uint16_t) 0xA55A;
  40. if (*cp != 0xA55A)
  41. {
  42. cp = (rt_uint16_t *) (MONO_BUF);
  43. addr_6845 = MONO_BASE;
  44. }
  45. else
  46. {
  47. *cp = was;
  48. addr_6845 = CGA_BASE;
  49. }
  50. /* Extract cursor location */
  51. outb(addr_6845, 14);
  52. pos = inb(addr_6845+1) << 8;
  53. outb(addr_6845, 15);
  54. pos |= inb(addr_6845+1);
  55. crt_buf = (rt_uint16_t *)cp;
  56. crt_pos = pos;
  57. }
  58. /**
  59. * This function will write a character to cga
  60. *
  61. * @param c the char to write
  62. */
  63. static void rt_cga_putc(int c)
  64. {
  65. /* if no attribute given, then use black on white */
  66. if (!(c & ~0xff)) c |= 0x0700;
  67. switch (c & 0xff)
  68. {
  69. case '\b':
  70. if (crt_pos > 0)
  71. {
  72. crt_pos--;
  73. crt_buf[crt_pos] = (c&~0xff) | ' ';
  74. }
  75. break;
  76. case '\n':
  77. crt_pos += CRT_COLS;
  78. /* cascade */
  79. case '\r':
  80. crt_pos -= (crt_pos % CRT_COLS);
  81. break;
  82. case '\t':
  83. rt_console_putc(' ');
  84. rt_console_putc(' ');
  85. rt_console_putc(' ');
  86. rt_console_putc(' ');
  87. rt_console_putc(' ');
  88. break;
  89. default:
  90. crt_buf[crt_pos++] = c; /* write the character */
  91. break;
  92. }
  93. if (crt_pos >= CRT_SIZE)
  94. {
  95. rt_int32_t i;
  96. rt_memcpy(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) << 1);
  97. for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i++)
  98. crt_buf[i] = 0x0700 | ' ';
  99. crt_pos -= CRT_COLS;
  100. }
  101. outb(addr_6845, 14);
  102. outb(addr_6845+1, crt_pos >> 8);
  103. outb(addr_6845, 15);
  104. outb(addr_6845+1, crt_pos);
  105. }
  106. /**
  107. * This function will write a character to serial an cga
  108. *
  109. * @param c the char to write
  110. */
  111. static void rt_console_putc(int c)
  112. {
  113. rt_cga_putc(c);
  114. rt_serial_putc(c);
  115. }
  116. /**
  117. * This function initializes console
  118. *
  119. */
  120. void rt_console_init(void)
  121. {
  122. rt_cga_init();
  123. rt_serial_init();
  124. }
  125. /**
  126. * This function is used to display a string on console, normally, it's
  127. * invoked by rt_kprintf
  128. *
  129. * @param str the displayed string
  130. *
  131. * Modified:
  132. * caoxl 2009-10-14
  133. * the name is change to rt_hw_console_output in the v0.3.0
  134. *
  135. */
  136. //void rt_console_puts(const char* str)
  137. void rt_hw_console_output(const char* str)
  138. {
  139. while (*str)
  140. {
  141. rt_console_putc (*str++);
  142. }
  143. }
  144. #define BY2CONS 512
  145. static struct
  146. {
  147. rt_uint8_t buf[BY2CONS];
  148. rt_uint32_t rpos;
  149. rt_uint32_t wpos;
  150. }cons;
  151. static void rt_console_intr(char (*proc)(void))
  152. {
  153. int c;
  154. while ((c = (*proc)()) != -1)
  155. {
  156. if (c == 0)
  157. continue;
  158. cons.buf[cons.wpos++] = c;
  159. if (cons.wpos == BY2CONS)
  160. cons.wpos = 0;
  161. }
  162. }
  163. /**
  164. * return the next input character from the console,either from serial,
  165. * or keyboard
  166. *
  167. */
  168. int rt_console_getc(void)
  169. {
  170. int c;
  171. rt_console_intr(rt_serial_getc);
  172. rt_console_intr(rt_keyboard_getc);
  173. if (cons.rpos != cons.wpos)
  174. {
  175. c = cons.buf[cons.rpos++];
  176. if (cons.rpos == BY2CONS)
  177. cons.rpos = 0;
  178. return c;
  179. }
  180. return 0;
  181. }
  182. /*@}*/