Add Syscall: Exit, PutChar, GetCar, PutString, GetString

This commit is contained in:
Yorick Barbanneau 2021-10-11 22:41:17 +02:00
parent 6f405265a5
commit 80fc250109
15 changed files with 359 additions and 17 deletions

View file

@ -0,0 +1,66 @@
#ifdef CHANGED
#include "copyright.h"
#include "system.h"
#include "consoledriver.h"
#include "synch.h"
#define STRINGBUFFER 8
static Semaphore *readAvail;
static Semaphore *writeDone;
static void ReadAvailHandler(void *arg) { (void) arg; readAvail->V(); }
static void WriteDoneHandler(void *arg) { (void) arg; writeDone->V(); }
ConsoleDriver::ConsoleDriver(const char *in, const char *out)
{
readAvail = new Semaphore("read avail", 0);
writeDone = new Semaphore("write done", 0);
console = new Console (in, out, ReadAvailHandler, WriteDoneHandler, NULL);
}
ConsoleDriver::~ConsoleDriver()
{
delete console;
delete writeDone;
delete readAvail;
}
void ConsoleDriver::PutChar( int ch)
{
console->TX(ch);
writeDone->P();
}
int ConsoleDriver::GetChar()
{
readAvail->P();
int ch = console->RX();
return ch;
}
void ConsoleDriver::PutString(const char s[MAX_STRING_SIZE])
{
int i;
for (i = 0; i < MAX_STRING_SIZE; i++){
if (*(s+i) =='\0'){
return;
}
PutChar(*(s+i));
}
}
void ConsoleDriver::GetString(char * s, int n)
{
int i;
for ( i = 0; i < n - 1; i++){
char c = GetChar();
if ( c == '\0' || c == '\n' || c == EOF) {
break;
}
*(s+i) = c;
}
*(s+i) = '\0';
}
#endif // CHANGED

View file

@ -0,0 +1,25 @@
#ifdef CHANGED
#ifndef CONSOLEDRIVER_H
#define CONSOLEDRIVER_H
#include "copyright.h"
#include "utility.h"
#include "console.h"
class ConsoleDriver:dontcopythis {
public:
// initialize the hardware console device
ConsoleDriver(const char *readFile, const char *writeFile);
~ConsoleDriver(); // clean up
void PutChar(int ch); // Behaves like putchar(3S)
int GetChar(); // Behaves like getchar(3S)
void PutString(const char *s); // Behaves like fputs(3S)
void GetString(char *s, int n); // Behaves like fgets(3S)
private:
Console *console;
};
#endif // CONSOLEDRIVER_H
#endif // CHANGED

View file

@ -63,6 +63,37 @@ UpdatePC ()
// "which" is the kind of exception. The list of possible exceptions
// are in machine.h.
//----------------------------------------------------------------------
int copyStringFromMachine(int from, char *to, unsigned size)
{
unsigned i = 0;
int res;
// Need to read size-1 to put final /0 if needed
while((i<size-1) && (machine->ReadMem(from+i,1,&res))){
*(to+i) = (char)res;
if ((char)res == '\0'){
return i;
}
i++;
}
*(to+i)='\0';
return size;
}
int copyStringToMachine(int to, char* from, unsigned size)
{
unsigned i;
for (i=0; i < size - 1; i++) {
if (from[i] == '\0') {
break;
}
machine->WriteMem(to+i,1,(int)from[i]);
}
// Write the last /0
machine->WriteMem(to+i,1,'\0');
return i;
}
void
ExceptionHandler (ExceptionType which)
@ -82,6 +113,67 @@ ExceptionHandler (ExceptionType which)
interrupt->Powerdown ();
break;
}
#ifdef CHANGED
case SC_Exit:
{
int ret = machine->ReadRegister(4);
printf("Exit code %d\n", ret);
interrupt->Powerdown();
break;
}
case SC_PutChar:
{
DEBUG ('s', "PutChar.\n");
consoledriver->PutChar((char)machine->ReadRegister(4));
break;
}
case SC_PutString:
{
DEBUG ('s', "PutString.\n");
int readsize;
int addr_start = machine->ReadRegister(4);
do {
char* read = new char[MAX_STRING_SIZE];
readsize = copyStringFromMachine( addr_start, read, MAX_STRING_SIZE);
consoledriver->PutString(read);
// beware, the last element of our buffer was added by
// copyStringFromMachine(), we need to remove one memory case
// or the first char of our next read will be
// forgotten
addr_start += readsize - 1;
delete [] read;
} while(readsize == MAX_STRING_SIZE);
break;
}
case SC_GetChar:
{
DEBUG ('s', "GetChar.\n");
// Get the char input an write it to the register n.2
int c = consoledriver->GetChar();
machine->WriteRegister((2), c);
break;
}
case SC_GetString:
{
DEBUG ('s', "GetString.\n");
int writesize = 0;
int addr = machine->ReadRegister(4);
int size = machine->ReadRegister(5);
DEBUG ('s', "size:%d\n", size);
do {
char* write = new char[MAX_STRING_SIZE];
consoledriver->GetString(write, MAX_STRING_SIZE);
printf("write:%s:\n", write);
writesize = copyStringToMachine(addr, write, MAX_STRING_SIZE);
addr += writesize;
printf("Writed:%d\n", writesize);
delete [] write;
} while( writesize == MAX_STRING_SIZE - 1 );
break;
}
#endif
default:
{
printf("Unimplemented system call %d\n", type);

View file

@ -10,6 +10,7 @@
#include "copyright.h"
#include "system.h"
#include "consoledriver.h"
#include "console.h"
#include "addrspace.h"
#include "synch.h"
@ -84,7 +85,7 @@ void
ConsoleTest (const char *in, const char *out)
{
char ch;
printf("test console\n<");
readAvail = new Semaphore ("read avail", 0);
writeDone = new Semaphore ("write done", 0);
console = new Console (in, out, ReadAvailHandler, WriteDoneHandler, NULL);
@ -93,14 +94,44 @@ ConsoleTest (const char *in, const char *out)
{
readAvail->P (); // wait for character to arrive
ch = console->RX ();
#ifdef CHANGED
// My modifications...
// Check input before display it...
if (ch == 'q' || ch == -1 ) {
printf ("au revoir!\n");
break; // if q, quit
}
console->TX ('<');
writeDone->P ();
console->TX (ch); // echo it!
writeDone->P (); // wait for write to finish
console->TX ('>');
writeDone->P ();
#else
console->TX (ch); // echo it!
writeDone->P (); // wait for write to finish
if (ch == 'q') {
printf ("Nothing more, bye!\n");
break; // if q, quit
}
#endif
}
delete console;
delete readAvail;
delete writeDone;
}
#ifdef CHANGED
void
ConsoleDriverTest (const char *in, const char *out)
{
printf("test consoledriver\n");
char ch;
ConsoleDriver *test_consoledriver = new ConsoleDriver(in, out);
while ((ch = test_consoledriver->GetChar()) != EOF)
test_consoledriver->PutChar(ch);
fprintf(stderr, "EOF detected in ConsoleDriver!\n");
delete test_consoledriver;
}
#endif //CHANGED

View file

@ -14,5 +14,7 @@
extern void StartProcess (char *filename);
extern void ConsoleTest (const char *in, const char *out);
#ifdef CHANGED
extern void ConsoleDriverTest (const char *in, const char *out);
#endif //CHANGED
#endif // PROGTEST_H

View file

@ -20,18 +20,23 @@
/* system call codes -- used by the stubs to tell the kernel which system call
* is being asked for
*/
#define SC_Halt 0
#define SC_Exit 1
#define SC_Exec 2
#define SC_Join 3
#define SC_Create 4
#define SC_Open 5
#define SC_Read 6
#define SC_Write 7
#define SC_Close 8
#define SC_Fork 9
#define SC_Yield 10
#define SC_Halt 0
#define SC_Exit 1
#define SC_Exec 2
#define SC_Join 3
#define SC_Create 4
#define SC_Open 5
#define SC_Read 6
#define SC_Write 7
#define SC_Close 8
#define SC_Fork 9
#define SC_Yield 10
#ifdef CHANGED
#define SC_PutChar 11 // My first SysCall :')
#define SC_PutString 12
#define SC_GetChar 13
#define SC_GetString 14
#endif
#ifdef IN_USER_MODE
// LB: This part is read only on compiling the test/*.c files.
@ -130,6 +135,13 @@ void Fork (void (*func) ());
*/
void Yield ();
#ifdef CHANGED
void PutChar (char c);
void PutString (char * s);
void GetChar(char c);
void GetString(char * s, int n );
#endif // CHANGED
#endif // IN_USER_MODE
#endif /* SYSCALL_H */