diff --git a/Makefile b/Makefile index 1e3387a..8df2736 100644 --- a/Makefile +++ b/Makefile @@ -223,8 +223,8 @@ QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \ then echo "-gdb tcp::$(GDBPORT)"; \ else echo "-s -p $(GDBPORT)"; fi) ifndef CPUS -#CPUS := 2 -CPUS := 1 +CPUS := 2 +#CPUS := 1 endif QEMUOPTS = -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp $(CPUS) -m 512 $(QEMUEXTRA) diff --git a/console.c b/console.c index 5e908bc..18b4476 100644 --- a/console.c +++ b/console.c @@ -29,6 +29,8 @@ struct kbdbuffer inputBuffer; struct kbdbuffer * input = 0; struct vconsole { + struct spinlock lock; + struct proc* processowner; ushort screenbuffer[SCRWIDTH * SCRHEIGHT]; struct kbdbuffer keybuffer; int pos; @@ -36,6 +38,7 @@ struct vconsole { }; struct vconsole consoles[MAXVCONSOLES]; +struct vconsole* currentconsole = 0; static uint currentconsoleindex = 0; #define C(x) ((x) - '@') // Control-x @@ -171,46 +174,66 @@ static void cgaputc(int c) { // Check if a process has actually been created otherwise use the base console if (myproc() != 0x0) { - consoleindex = currentconsoleindex; //myproc()->consoleIndex; + consoleindex = myproc()->consoleIndex; } - //ushort* currentbuffer = consoles[consoleindex].screenbuffer; - - // Cursor position: col + 80*row. - outb(CRTPORT, 14); - pos = inb(CRTPORT + 1) << 8; - outb(CRTPORT, 15); - pos |= inb(CRTPORT + 1); - + ushort* currentbuffer = consoles[consoleindex].screenbuffer; + + if (consoleindex == currentconsoleindex) + { + // Cursor position: col + 80*row. + outb(CRTPORT, 14); + pos = inb(CRTPORT + 1) << 8; + outb(CRTPORT, 15); + pos |= inb(CRTPORT + 1); + } + else + { + pos = consoles[consoleindex].pos; + } + if (c == '\n') { pos += SCRWIDTH - pos % SCRWIDTH; } else if (c == BACKSPACE) { if (pos > (TITLEOFF)) { - //currentbuffer[pos] = 0; // Clear the character from the buffer + currentbuffer[pos] = 0; // Clear the character from the buffer --pos; } } - else { - //currentbuffer[pos++] = (c & 0xff) | 0x0700; // black on white - crt[pos++] = (c & 0xff) | 0x0700; // black on white - + else { + //int posp = pos; + if (consoleindex == currentconsoleindex) + { + crt[pos] = (c & 0xff) | 0x0700; // black on white + } + currentbuffer[pos] = (c & 0xff) | 0x0700; // black on white + pos++; + } if (pos < TITLEOFF || pos > SCRHEIGHT * SCRWIDTH) { panic("pos under/overflow"); } if ((pos / 80) >= 24) { // Scroll up. - memmove(crt + TITLEOFF, crt + (SCRWIDTH + TITLEOFF), sizeof(crt[0]) * (SCRHEIGHT - 1) * SCRWIDTH); + memmove(currentbuffer + TITLEOFF, currentbuffer + (SCRWIDTH + TITLEOFF), sizeof(crt[0]) * (SCRHEIGHT - 1) * SCRWIDTH); pos -= 80; - memset(crt + pos, 0, sizeof(crt[0]) * (SCRHEIGHT * SCRWIDTH - pos)); + memset(currentbuffer + pos, 0, sizeof(crt[0]) * (SCRHEIGHT * SCRWIDTH - pos)); + if (consoleindex == currentconsoleindex) + { + memmove(crt + TITLEOFF, crt + (SCRWIDTH + TITLEOFF), sizeof(crt[0]) * (SCRHEIGHT - 1) * SCRWIDTH); + memset(crt + pos, 0, sizeof(crt[0]) * (SCRHEIGHT * SCRWIDTH - pos)); + } + } + consoles[consoleindex].pos = pos; + + if (consoleindex == currentconsoleindex) + { + outb(CRTPORT, 14); + outb(CRTPORT + 1, pos >> 8); + outb(CRTPORT, 15); + outb(CRTPORT + 1, pos); + crt[pos] = ' ' | 0x0700; } - consoles[consoleindex].pos = pos; - - outb(CRTPORT, 14); - outb(CRTPORT + 1, pos >> 8); - outb(CRTPORT, 15); - outb(CRTPORT + 1, pos); - crt[pos] = ' ' | 0x0700; } void consputc(int c) { @@ -250,8 +273,8 @@ int consoleget(void) { void consoleintr(int (*getc)(void)) { int c, doprocdump = 0, doconsoleswitch = 0, doconsolehome = 0; - - acquire(&cons.lock); + + acquire(&cons.lock); while ((c = getc()) >= 0) { switch (c) { case C('P'): // Process listing. @@ -260,7 +283,7 @@ void consoleintr(int (*getc)(void)) { break; case C('U'): // Kill line. while (input->e != input->w && - input->buf[(input->e - 1) % INPUT_BUF] != '\n') { + input->buf[(input->e - 1) % INPUT_BUF] != '\n') { input->e--; consputc(BACKSPACE); } @@ -292,6 +315,7 @@ void consoleintr(int (*getc)(void)) { } } release(&cons.lock); + if (doprocdump) { procdump(); // now call procdump() wo. cons.lock held } @@ -324,7 +348,7 @@ int consoleread(struct inode *ip, char *dst, int n) { int c; iunlock(ip); - target = n; + target = n; acquire(&cons.lock); while (n > 0) { while (input->r == input->w) { @@ -392,7 +416,7 @@ void testfillbuffer(ushort *bufferin) void clearconsole(ushort *bufferin) { // Flood the screen buffer with blank spaces - memset(bufferin, 0x0700, sizeof(bufferin[0]) * SCRHEIGHT * SCRWIDTH); + memset(bufferin, 0, sizeof(bufferin[0]) * SCRHEIGHT * SCRWIDTH); } void loadscreenbuffer(ushort *bufferin) @@ -411,32 +435,46 @@ void clearscreen(void) { //cprintf("process id: %d", myproc()->consoleIndex); //return; - //cprintf("size of buffer item: %d\n", sizeof(consoles[currentconsoleindex].screenbuffer[0]) * (SCRHEIGHT * SCRWIDTH)); //cprintf("size of crt item: %d\n", sizeof(crt[0]) * (SCRHEIGHT * SCRWIDTH)); - //return; - int pos = TITLEOFF; - - //testfillbuffer(consoles[currentconsoleindex].screenbuffer); - clearconsole(consoles[currentconsoleindex].screenbuffer); - //loadscreenbuffer(consoles[currentconsoleindex].screenbuffer); + int consoleindex = 0; + // Check if a process has actually been created otherwise use the base console + if (myproc() != 0x0) + { + consoleindex = myproc()->consoleIndex; + } + if (consoleindex == currentconsoleindex) + { + acquire(&cons.lock); + int pos = TITLEOFF; + + //testfillbuffer(consoles[currentconsoleindex].screenbuffer); + clearconsole(crt); + //loadscreenbuffer(consoles[currentconsoleindex].screenbuffer); + release(&cons.lock); - consoles[currentconsoleindex].pos = pos; + currentconsole->pos = pos; - outb(CRTPORT, 14); - outb(CRTPORT + 1, pos >> 8); - outb(CRTPORT, 15); - outb(CRTPORT + 1, pos); + outb(CRTPORT, 14); + outb(CRTPORT + 1, pos >> 8); + outb(CRTPORT, 15); + outb(CRTPORT + 1, pos); + } + else + { + + } } void consoleinit(void) { - initlock(&cons.lock, "console"); + initlock(&cons.lock, "console"); - consoles[currentconsoleindex].active = 1; - - // Initialise pointer to point to our console input buffer - input = &consoles[currentconsoleindex].keybuffer; + // Initialise pointer to point to our console input buffer + currentconsole = &consoles[currentconsoleindex]; + currentconsole->active = 1; + initlock(¤tconsole->lock, "vconsole0"); + input = ¤tconsole->keybuffer; devsw[CONSOLE].write = consolewrite; devsw[CONSOLE].read = consoleread; @@ -468,32 +506,35 @@ int switchtoconsole(int consoleindex) { int pos; - outb(CRTPORT, 14); + /*outb(CRTPORT, 14); pos = inb(CRTPORT + 1) << 8; outb(CRTPORT, 15); - pos |= inb(CRTPORT + 1); + pos |= inb(CRTPORT + 1);*/ - consoles[currentconsoleindex].pos = pos; + //consoles[currentconsoleindex].pos = pos; - savescreenbuffer(consoles[currentconsoleindex].screenbuffer); + //savescreenbuffer(consoles[currentconsoleindex].screenbuffer); - //acquire(&cons.lock); + //acquire(¤tconsole->lock); + //sleep(&(currentconsole), ¤tconsole->lock); + acquire(&cons.lock); currentconsoleindex = consoleindex; - input = &consoles[currentconsoleindex].keybuffer; + currentconsole = &consoles[currentconsoleindex]; + input = ¤tconsole->keybuffer; //ioapicenable(IRQ_KBD, 0); - //release(&cons.lock); + + loadscreenbuffer(currentconsole->screenbuffer); + release(&cons.lock); - loadscreenbuffer(consoles[consoleindex].screenbuffer); - - if (!consoles[currentconsoleindex].active) + if (!currentconsole->active) { clearscreen(); cprintf("Welcome to Console: %d\n", currentconsoleindex); - consoles[currentconsoleindex].active = 1; + currentconsole->active = 1; } else { - pos = consoles[consoleindex].pos; + pos = currentconsole->pos; outb(CRTPORT, 14); outb(CRTPORT + 1, pos >> 8); @@ -501,13 +542,14 @@ int switchtoconsole(int consoleindex) outb(CRTPORT + 1, pos); } + //wakeup(myproc()->chan); return 0; } int closeconsole(int consoleindex) { - clearconsole(consoles[currentconsoleindex].screenbuffer); - consoles[currentconsoleindex].active = 0; + clearconsole(currentconsole->screenbuffer); + currentconsole->active = 0; switchtoconsole(0); return 0; } diff --git a/param.h b/param.h index d2a9fb0..f28374a 100644 --- a/param.h +++ b/param.h @@ -11,6 +11,7 @@ #define LOGSIZE (MAXOPBLOCKS*3) // max data blocks in on-disk log #define NBUF (MAXOPBLOCKS*3) // size of disk block cache #define FSSIZE 1000 // size of file system in blocks + #define MAXVCONSOLES 10 // Max number of consoles that can be open #define SCRWIDTH 80 // Numbers of characters across the screen #define SCRHEIGHT 25 // Number of lines down the screen diff --git a/sysproc.c b/sysproc.c index a78fc53..4cb5937 100644 --- a/sysproc.c +++ b/sysproc.c @@ -131,10 +131,9 @@ int sys_screen(void) int result = 0; int consoleindex = -1; if ((consoleindex = newconsole()) != 0) - { - curproc->consoleIndex = consoleindex; - switchtoconsole(consoleindex); - wakeup(myproc()->chan); + { + curproc->consoleIndex = consoleindex; + switchtoconsole(consoleindex); result = 1; } return result;