00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <interrupt.h>
00036 #include <console/chardev.h>
00037 #include <arch/drivers/msim.h>
00038 #include <arch/cp0.h>
00039 #include <console/console.h>
00040
00041 static chardev_t console;
00042
00043 static void msim_write(chardev_t *dev, const char ch);
00044 static void msim_enable(chardev_t *dev);
00045 static void msim_disable(chardev_t *dev);
00046 static char msim_do_read(chardev_t *dev);
00047
00048 static chardev_operations_t msim_ops = {
00049 .resume = msim_enable,
00050 .suspend = msim_disable,
00051 .write = msim_write,
00052 .read = msim_do_read,
00053 };
00054
00056 void msim_write(chardev_t *dev, const char ch)
00057 {
00058 *((char *) MSIM_VIDEORAM) = ch;
00059 }
00060
00061
00062 void msim_enable(chardev_t *dev)
00063 {
00064 cp0_unmask_int(MSIM_KBD_IRQ);
00065 }
00066
00067
00068 void msim_disable(chardev_t *dev)
00069 {
00070 cp0_mask_int(MSIM_KBD_IRQ);
00071 }
00072
00073 #include <print.h>
00075 static char msim_do_read(chardev_t *dev)
00076 {
00077 char ch;
00078
00079 while (1) {
00080 ch = *((volatile char *) MSIM_KBD_ADDRESS);
00081 if (ch) {
00082 if (ch == '\r')
00083 return '\n';
00084 if (ch == 0x7f)
00085 return '\b';
00086 return ch;
00087 }
00088 }
00089 }
00090
00092 static void msim_interrupt(int n, istate_t *istate)
00093 {
00094 char ch = 0;
00095
00096 ch = *((char *) MSIM_KBD_ADDRESS);
00097 if (ch =='\r')
00098 ch = '\n';
00099 if (ch == 0x7f)
00100 ch = '\b';
00101 chardev_push_character(&console, ch);
00102 }
00103
00104
00105
00106 void msim_console(void)
00107 {
00108 chardev_initialize("msim_console", &console, &msim_ops);
00109
00110 int_register(MSIM_KBD_IRQ, "msim_kbd", msim_interrupt);
00111
00112 cp0_unmask_int(MSIM_KBD_IRQ);
00113
00114 stdin = &console;
00115 stdout = &console;
00116 }
00117
00118 static iroutine oldvector;
00119 void msim_kbd_grab(void)
00120 {
00121 oldvector = int_register(MSIM_KBD_IRQ, "msim_kbd", msim_interrupt);
00122 }
00123 void msim_kbd_release(void)
00124 {
00125 int_register(MSIM_KBD_IRQ, "user_interrupt", oldvector);
00126 }
00127