Main Page   Compound List   File List   Compound 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 Mon Feb 10 09:54:44 2003 for nachos by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002
The University of Southern California does not screen or control the content on this website and thus does not guarantee the accuracy, integrity, or quality of such content. All content on this website is provided by and is the sole responsibility of the person from which such content originated, and such content does not necessarily reflect the opinions of the University administration or the Board of Trustees