Main Page | Alphabetical List | Class List | File List | Class Members | File Members

console.cc

Go to the documentation of this file.
00001 // console.cc 00002 // Routines to simulate a serial port to a console device. 00003 // A console has input (a keyboard) and output (a display). 00004 // These are each simulated by operations on UNIX files. 00005 // The simulated device is asynchronous, 00006 // so we have to invoke the interrupt handler (after a simulated 00007 // delay), to signal that a byte has arrived and/or that a written 00008 // byte has departed. 00009 // 00010 // DO NOT CHANGE -- part of the machine emulation 00011 // 00012 // Copyright (c) 1992-1993 The Regents of the University of California. 00013 // All rights reserved. See copyright.h for copyright notice and limitation 00014 // of liability and disclaimer of warranty provisions. 00015 00016 #include "copyright.h" 00017 #include "console.h" 00018 #include "system.h" 00019 00020 // Dummy functions because C++ is weird about pointers to member functions 00021 static void ConsoleReadPoll(int c) 00022 { Console *console = (Console *)c; console->CheckCharAvail(); } 00023 static void ConsoleWriteDone(int c) 00024 { Console *console = (Console *)c; console->WriteDone(); } 00025 00026 //---------------------------------------------------------------------- 00027 // Console::Console 00028 // Initialize the simulation of a hardware console device. 00029 // 00030 // "readFile" -- UNIX file simulating the keyboard (NULL -> use stdin) 00031 // "writeFile" -- UNIX file simulating the display (NULL -> use stdout) 00032 // "readAvail" is the interrupt handler called when a character arrives 00033 // from the keyboard 00034 // "writeDone" is the interrupt handler called when a character has 00035 // been output, so that it is ok to request the next char be 00036 // output 00037 //---------------------------------------------------------------------- 00038 00039 Console::Console(char *readFile, char *writeFile, VoidFunctionPtr readAvail, 00040 VoidFunctionPtr writeDone, int callArg) 00041 { 00042 if (readFile == NULL) 00043 readFileNo = 0; // keyboard = stdin 00044 else 00045 readFileNo = OpenForReadWrite(readFile, TRUE); // should be read-only 00046 if (writeFile == NULL) 00047 writeFileNo = 1; // display = stdout 00048 else 00049 writeFileNo = OpenForWrite(writeFile); 00050 00051 // set up the stuff to emulate asynchronous interrupts 00052 writeHandler = writeDone; 00053 readHandler = readAvail; 00054 handlerArg = callArg; 00055 putBusy = FALSE; 00056 incoming = EOF; 00057 00058 // start polling for incoming packets 00059 interrupt->Schedule(ConsoleReadPoll, (int)this, ConsoleTime, ConsoleReadInt); 00060 } 00061 00062 //---------------------------------------------------------------------- 00063 // Console::~Console 00064 // Clean up console emulation 00065 //---------------------------------------------------------------------- 00066 00067 Console::~Console() 00068 { 00069 if (readFileNo != 0) 00070 Close(readFileNo); 00071 if (writeFileNo != 1) 00072 Close(writeFileNo); 00073 } 00074 00075 //---------------------------------------------------------------------- 00076 // Console::CheckCharAvail() 00077 // Periodically called to check if a character is available for 00078 // input from the simulated keyboard (eg, has it been typed?). 00079 // 00080 // Only read it in if there is buffer space for it (if the previous 00081 // character has been grabbed out of the buffer by the Nachos kernel). 00082 // Invoke the "read" interrupt handler, once the character has been 00083 // put into the buffer. 00084 //---------------------------------------------------------------------- 00085 00086 void 00087 Console::CheckCharAvail() 00088 { 00089 char c; 00090 00091 // schedule the next time to poll for a packet 00092 interrupt->Schedule(ConsoleReadPoll, (int)this, ConsoleTime, 00093 ConsoleReadInt); 00094 00095 // do nothing if character is already buffered, or none to be read 00096 if ((incoming != EOF) || !PollFile(readFileNo)) 00097 return; 00098 00099 // otherwise, read character and tell user about it 00100 Read(readFileNo, &c, sizeof(char)); 00101 incoming = c ; 00102 stats->numConsoleCharsRead++; 00103 (*readHandler)(handlerArg); 00104 } 00105 00106 //---------------------------------------------------------------------- 00107 // Console::WriteDone() 00108 // Internal routine called when it is time to invoke the interrupt 00109 // handler to tell the Nachos kernel that the output character has 00110 // completed. 00111 //---------------------------------------------------------------------- 00112 00113 void 00114 Console::WriteDone() 00115 { 00116 putBusy = FALSE; 00117 stats->numConsoleCharsWritten++; 00118 (*writeHandler)(handlerArg); 00119 } 00120 00121 //---------------------------------------------------------------------- 00122 // Console::GetChar() 00123 // Read a character from the input buffer, if there is any there. 00124 // Either return the character, or EOF if none buffered. 00125 //---------------------------------------------------------------------- 00126 00127 char 00128 Console::GetChar() 00129 { 00130 char ch = incoming; 00131 00132 incoming = EOF; 00133 return ch; 00134 } 00135 00136 //---------------------------------------------------------------------- 00137 // Console::PutChar() 00138 // Write a character to the simulated display, schedule an interrupt 00139 // to occur in the future, and return. 00140 //---------------------------------------------------------------------- 00141 00142 void 00143 Console::PutChar(char ch) 00144 { 00145 ASSERT(putBusy == FALSE); 00146 WriteFile(writeFileNo, &ch, sizeof(char)); 00147 putBusy = TRUE; 00148 interrupt->Schedule(ConsoleWriteDone, (int)this, ConsoleTime, 00149 ConsoleWriteInt); 00150 }

Generated on Thu Sep 16 12:33:44 2004 for NachOS by doxygen 1.3.8