Added draw menu, vars and additional functions needed for it

Added some functionality to the procdump to show the current console and parent pids of processes for debugging
Added var to clearconsole that enables the internal lock if one wasnt prelocked before hand
Fixed issue where race conditions would stop the title from drawing by drawing it to the buffer too
Fixed issue where the maze function was spamming the conswrite and cons lock by changing it to send an entire line instead of 1 char at a time
This commit is contained in:
iDunnoDev
2022-12-23 00:48:57 +00:00
committed by iDunnoDev
parent 662e3795a7
commit c23d669858
5 changed files with 366 additions and 84 deletions

404
console.c
View File

@ -16,6 +16,13 @@
#include "x86.h"
#define INPUT_BUF 128
// Proc title length + 3 for the console id + 2 for the left and right border + 2 for space between
#define MENUWIDTH 27
// Number of max consoles + 1 for bottom border and another 2 for a space between top and bottom
#define MENUHEIGHT (MAXVCONSOLES + 3);
static int currentmenuitem = 0;
static int menuactive = 0;
struct kbdbuffer
{
@ -54,7 +61,7 @@ struct vconsole* getvalidprocessconsoleptr(void);
void clearconsole(ushort *bufferin);
void loadscreenbuffer(ushort *bufferin);
void savescreenbuffer(ushort *bufferin);
void clearscreen(void);
void clearscreen(int prelocked);
static void consputc(int);
@ -73,6 +80,66 @@ static struct
int locking;
} vcons;
static int getcurrentactiveconsolecount(void)
{
int resultcount = 0;
for (int i = 0; i < MAXVCONSOLES; i++)
{
if (consoles[i].active)
{
resultcount++;
}
}
return resultcount;
}
static int getconsolemenuindex(struct vconsole* consolein)
{
int resultcount = 0;
for (int i = 0; i < MAXVCONSOLES; i++)
{
if (&consoles[i] == consolein && consoles[i].active)
{
break;
}
else
{
resultcount++;
}
}
return resultcount;
}
static int getmenuindexconsole(int menuindex)
{
int resultcount = 0;
int resultconsoleindex = 0;
for (int i = 0; i < MAXVCONSOLES; i++)
{
if (consoles[i].active)
{
if (resultcount == menuindex)
{
resultconsoleindex = consoles[i].consoleindex;
break;
}
else
{
resultcount++;
}
}
}
return resultconsoleindex;
}
int getconsoleindex(struct vconsole* consolein)
{
return consolein->consoleindex;
}
// Split the printint so we can just get the char out in draw title
// itoa is the function in the c standard library (?) so i reused the name
// since it does something similar
@ -248,9 +315,9 @@ void sprintf(char* strbuffer, char *fmt, ...)
{
s = "(null)";
}
for (; *s; s++)
for (int sli = 0; sli < strlen(s); sli++)
{
strbuffer[si] = *s;
strbuffer[si] = s[sli];
si++;
}
break;
@ -328,66 +395,169 @@ struct vconsole* getvalidprocessconsoleptr(void)
return inconsoleptr;
}
void setconsoleproctitle(struct vconsole* consoleptr, char* newtitle)
{
if (!consoleptr->titlelocked)
{
acquire(&consoleptr->lock);
//Clear the current buffer
memset(consoleptr->proctitle, 0, sizeof(consoleptr->proctitle));
//Copy the new title into the console title buffer
safestrcpy(consoleptr->proctitle, newtitle, sizeof(consoleptr->proctitle));
//Redraw the title since its been updated now
drawtitle();
release(&consoleptr->lock);
}
}
#define BACKSPACE 0x100
#define CRTPORT 0x3d4
#define TITLEOFF (SCRWIDTH * 1) // Size of the offset we need for the title bar
static ushort *crt = (ushort *)P2V(0xb8000); // CGA memory
void drawtitle(void)
static void drawmenu(void)
{
struct vconsole* inconsoleptr = getvalidprocessconsoleptr();
if (inconsoleptr->inuse)
{
int pos = 0;
char c = ' ';
char menutext[] = "(M)enu";
char consoletitletext[10]; // + (inconsoleptr->consoleindex + 1);
sprintf(consoletitletext, "Console %d", inconsoleptr->consoleindex + 1);
for (pos = 0; pos < SCRWIDTH; pos++)
int rows = getcurrentactiveconsolecount() + 3;
int pos = TITLEOFF;
uint c = 0;
char menulines[MAXVCONSOLES][24];
for (int i = 0; i < MAXVCONSOLES; i++)
{
if (consoles[i].active)
{
memset(menulines[i], 0, sizeof(menulines[i][0]) * sizeof(menulines[i]));
sprintf(menulines[i], "%d: %s", consoles[i].consoleindex, consoles[i].proctitle);
}
}
for (int y = 0; y < rows; y++)
{
pos = TITLEOFF + (y * SCRWIDTH);
for (int x = 0; x < MENUWIDTH; x++)
{
int offset = 0;
if (pos < 6) {
c = menutext[pos - offset];
}
else if (pos >= 10 && pos < 20)
if (y == 0 || y == (rows - 2))
{
offset = 10;
c = consoletitletext[pos - offset];
}
else if (pos >= 25 && pos < 45)
if (x == 0 || x == (MENUWIDTH - 1))
{
c = 0xB2 | inconsoleptr->titlebgcol;
}
else
{
c = 0x0720;
}
}
else if (y == (rows - 1))
{
offset = 25;
c = inconsoleptr->proctitle[pos - offset];
}
else if (pos >= 50 && pos < 80)
{
offset = 50;
c = inconsoleptr->status[pos - offset];
c = 0xB2 | inconsoleptr->titlebgcol;
}
else
{
c = ' ';
if (x == 0 || x == (MENUWIDTH - 1))
{
c = 0xB2 | inconsoleptr->titlebgcol;
}
else if (x == 1 || x == (MENUWIDTH - 2))
{
c = 0x0720;
}
else
{
c = menulines[y - 1][x - 2];
c = (c & 0xff);
if (currentmenuitem == (y - 1))
{
c = c | 0xCF00;
}
else
{
c = c | 0x0700;
}
}
}
crt[pos] = c;
pos++;
}
}
menuactive = 1;
}
static void navigatemenu(int dir)
{
int pos = 0;
int newindex = currentmenuitem + dir;
int totalactiveconsoles = getcurrentactiveconsolecount();
if (newindex < 0)
{
newindex = 0;
}
else if (newindex >= totalactiveconsoles)
{
newindex = totalactiveconsoles - 1;
}
if (newindex != currentmenuitem)
{
pos = TITLEOFF + ((currentmenuitem + 1) * SCRWIDTH);
for (int x = 2; x < MENUWIDTH - 2; x++)
{
crt[pos + x] = (crt[pos + x] & 0x00FF) | 0x0700;
}
pos = TITLEOFF + ((newindex + 1) * SCRWIDTH);
for (int x = 2; x < MENUWIDTH - 2; x++)
{
crt[pos + x] = crt[pos + x] | 0xCF00;
}
currentmenuitem = newindex;
}
}
static void closemenu(void)
{
loadscreenbuffer(currentconsole->screenbuffer);
int pos = currentconsole->pos;
outb(CRTPORT, 14);
outb(CRTPORT + 1, pos >> 8);
outb(CRTPORT, 15);
outb(CRTPORT + 1, pos);
menuactive = 0;
}
static void drawtitle(void)
{
struct vconsole* inconsoleptr = getvalidprocessconsoleptr();
int pos = 0;
char c = ' ';
char menutext[] = "(M)enu";
char consoletitletext[10]; // + (inconsoleptr->consoleindex + 1);
sprintf(consoletitletext, "Console %d", inconsoleptr->consoleindex);
for (pos = 0; pos < SCRWIDTH; pos++)
{
int offset = 0;
if (pos < 6) {
c = menutext[pos - offset];
}
else if (pos >= 10 && pos < 20)
{
offset = 10;
c = consoletitletext[pos - offset];
}
else if (pos >= 25 && pos < 45)
{
offset = 25;
c = inconsoleptr->proctitle[pos - offset];
}
else if (pos >= 50 && pos < 80)
{
offset = 50;
c = inconsoleptr->status[pos - offset];
}
else
{
c = ' ';
}
if (inconsoleptr->inuse)
{
crt[pos] = (c & 0xff) | inconsoleptr->titlebgcol;
}
inconsoleptr->screenbuffer[pos] = (c & 0xff) | inconsoleptr->titlebgcol;
}
}
@ -445,7 +615,17 @@ static void cgaputc(int c)
memset(currentbuffer + pos, 0, sizeof(crt[0]) * (SCRHEIGHT * SCRWIDTH - pos));
if (inconsoleptr->inuse)
{
memmove(crt + TITLEOFF, crt + (SCRWIDTH + TITLEOFF), sizeof(crt[0]) * (SCRHEIGHT - 1) * SCRWIDTH);
int menuoffset = 0;
if (menuactive)
{
int menuitems = getcurrentactiveconsolecount() + 3;
for (int y = 0; y < menuitems; y++)
{
memmove(crt + menuoffset + TITLEOFF + MENUWIDTH, crt + menuoffset + (SCRWIDTH + TITLEOFF) + MENUWIDTH, sizeof(crt[0]) * (SCRWIDTH - MENUWIDTH));
menuoffset += SCRWIDTH;
}
}
memmove(crt + TITLEOFF + menuoffset, crt + (SCRWIDTH + TITLEOFF) + menuoffset, (sizeof(crt[0]) * (SCRHEIGHT - 1) * SCRWIDTH) - menuoffset);
memset(crt + pos, 0, sizeof(crt[0]) * (SCRHEIGHT * SCRWIDTH - pos));
}
}
@ -510,6 +690,7 @@ void consoleintr(int (*getc)(void))
int c;
int doprocdump = 0;
int doconsoleswitch = 0;
int switchto = -1;
int doconsolehome = 0;
//struct vconsole* inconsoleptr = getvalidprocessconsoleptr();
struct kbdbuffer* consolekbdbuffer = &currentconsole->keybuffer;
@ -518,7 +699,27 @@ void consoleintr(int (*getc)(void))
while ((c = getc()) >= 0)
{
switch (c)
{
{
case 27:
if (menuactive)
{
closemenu();
}
break;
// Up arrow (found in kbd.h)
case 0xE2:
if (menuactive)
{
navigatemenu(-1);
}
break;
// Down arrow (found in kbd.h)
case 0xE3:
if (menuactive)
{
navigatemenu(1);
}
break;
case C('P'): // Process listing.
// procdump() locks cons.lock indirectly; invoke later
doprocdump = 1;
@ -545,16 +746,40 @@ void consoleintr(int (*getc)(void))
case C('K'):
doconsolehome = 1;
break;
default:
if (c != 0 && consolekbdbuffer->e - consolekbdbuffer->r < INPUT_BUF)
case C('M'):
if (!menuactive)
{
c = (c == '\r') ? '\n' : c;
consolekbdbuffer->buf[consolekbdbuffer->e++ % INPUT_BUF] = c;
consputc(c);
if (c == '\n' || c == C('D') || consolekbdbuffer->e == consolekbdbuffer->r + INPUT_BUF)
drawmenu();
}
else
{
closemenu();
}
break;
// If enter is hit and the menu is active then we want to override the normal behaviour
case 10:
if (menuactive)
{
closemenu();
switchto = currentmenuitem;
doconsoleswitch = 1;
// The menu has been sorted we can break from the switch
break;
}
// if the menu was not active we want the enter to be handled in the default case
default:
if (!menuactive)
{
if (c != 0 && consolekbdbuffer->e - consolekbdbuffer->r < INPUT_BUF)
{
consolekbdbuffer->w = consolekbdbuffer->e;
wakeup(&(consolekbdbuffer->r));
c = (c == '\r') ? '\n' : c;
consolekbdbuffer->buf[consolekbdbuffer->e++ % INPUT_BUF] = c;
consputc(c);
if (c == '\n' || c == C('D') || consolekbdbuffer->e == consolekbdbuffer->r + INPUT_BUF)
{
consolekbdbuffer->w = consolekbdbuffer->e;
wakeup(&(consolekbdbuffer->r));
}
}
}
break;
@ -562,7 +787,7 @@ void consoleintr(int (*getc)(void))
}
release(&cons.lock);
if (doprocdump)
if (doprocdump && !menuactive)
{
procdump(); // now call procdump() wo. cons.lock held
}
@ -577,17 +802,24 @@ void consoleintr(int (*getc)(void))
{
struct vconsole* toconsole = 0;
acquire(&cons.lock);
for (int i = (currentconsole->consoleindex + 1); i < MAXVCONSOLES; i++)
{
if (consoles[i].active)
if (switchto == -1)
{
for (int i = (currentconsole->consoleindex + 1); i < MAXVCONSOLES; i++)
{
toconsole = &consoles[i];
break;
if (consoles[i].active)
{
toconsole = &consoles[i];
break;
}
}
if (toconsole == 0)
{
toconsole = getbaseconsoleptr();
}
}
if (toconsole == 0)
else
{
toconsole = getbaseconsoleptr();
toconsole = &consoles[getmenuindexconsole(switchto)];
}
release(&cons.lock);
if (!toconsole->inuse)
@ -664,6 +896,7 @@ int consolewrite(struct inode *ip, char *buf, int n)
return n;
}
// Function to flood a buffer with A-Z characters looping (for testing initially)
void testfillbuffer(ushort *bufferin)
{
ushort firstchar = 65;
@ -706,12 +939,15 @@ void savescreenbuffer(ushort *bufferin)
memmove(bufferin, crt, sizeof(crt[0]) * SCRHEIGHT * SCRWIDTH);
}
void clearscreen(void)
void clearscreen(int prelocked)
{
// Check if a process has actually been created otherwise use the base console
struct vconsole* inconsoleptr = getvalidprocessconsoleptr();
acquire(&cons.lock);
if (!prelocked)
{
acquire(&cons.lock);
}
int pos = TITLEOFF;
clearconsole(inconsoleptr->screenbuffer);
inconsoleptr->pos = pos;
@ -726,7 +962,10 @@ void clearscreen(void)
outb(CRTPORT + 1, pos);
}
drawtitle();
release(&cons.lock);
if (!prelocked)
{
release(&cons.lock);
}
}
void consoleinit(void)
@ -758,7 +997,7 @@ void consoleinit(void)
devsw[CONSOLE].read = consoleread;
cons.locking = 1;
clearscreen();
clearscreen(0);
cprintf("Welcome! you are currently in the base console\n");
ioapicenable(IRQ_KBD, 0);
@ -807,18 +1046,19 @@ int switchtoconsole(struct vconsole* consoleptr)
{
int pos;
acquire(&vcons.lock);
acquire(&vcons.lock);
releaseallconsoles();
currentconsole = consoleptr;
currentconsole->inuse = 1;
//input = &currentconsole->keybuffer;
// ioapicenable(IRQ_KBD, 0);
acquire(&cons.lock);
loadscreenbuffer(currentconsole->screenbuffer);
if (!currentconsole->active)
{
clearscreen();
clearscreen(1);
cprintf("Welcome to Console: %d\n", currentconsole->consoleindex);
currentconsole->active = 1;
}
@ -832,8 +1072,11 @@ int switchtoconsole(struct vconsole* consoleptr)
outb(CRTPORT + 1, pos);
}
drawtitle();
release(&vcons.lock);
//drawtitle();
menuactive = 0;
currentmenuitem = getconsolemenuindex(currentconsole);
release(&cons.lock);
release(&vcons.lock);
return 0;
}
@ -873,4 +1116,21 @@ int getcurrentconsoleindex(void)
}
release(&vcons.lock);
return -1;
}
void setconsoleproctitle(struct vconsole* consoleptr, char* newtitle)
{
if (!consoleptr->titlelocked)
{
acquire(&consoleptr->lock);
//Clear the current buffer
memset(consoleptr->proctitle, 0, sizeof(consoleptr->proctitle[0]) * sizeof(consoleptr->proctitle));
//Copy the new title into the console title buffer
safestrcpy(consoleptr->proctitle, newtitle, sizeof(consoleptr->proctitle));
//Redraw the title since its been updated now
drawtitle();
release(&consoleptr->lock);
}
}

5
defs.h
View File

@ -32,13 +32,14 @@ int closeconsole(void);
// Function to get the current inuse console index
int getcurrentconsoleindex(void);
// Function to clear the current screen buffer
void clearscreen(void);
void clearscreen(int);
// Function to get the base consoles ptr
struct vconsole* getbaseconsoleptr(void);
// Function to provide cprintf functionality but saved into a char array
void sprintf(char*, char*, ...);
void setconsoleproctitle(struct vconsole* consoleptr, char* newtitle);
void drawtitle();
//void drawtitle();
int getconsoleindex(struct vconsole* consolein);
// exec.c
int exec(char*, char**);

23
maze.c
View File

@ -45,13 +45,22 @@ int main(int argc, char *argv[]) {
seed = atoi(argv[i + 1]);
}
}
cls();
greeting();
printf(1, "Start Maze\n");
char mazeline[80];
for (int y = 0; y < lines; y++)
{
for (int x = 0; x < 80; x++)
for (int x = 0; x < 79; x++)
{
if (x == 0)
{
mazeline[x] = ' ';
continue;
}
int rndnum = rngrange(188, 197, seed);
switch (rndnum)
{
@ -65,10 +74,12 @@ int main(int argc, char *argv[]) {
rndnum = 180;
break;
}
printf(1, "%c", rndnum);
}
//printf(1, "\n");
// This is causing huge lock ups due to having to lock the console for each character
// is what im guessing so instead write it to a per line buffer then print
//printf(1, "%c", rndnum);
mazeline[x] = rndnum;
}
printf(1, "%s\n", mazeline);
sleep(10);
}
printf(1, "Maze Ended\n");

14
proc.c
View File

@ -522,6 +522,8 @@ void procdump(void) {
char *state;
uint pc[10];
cprintf("Listing Processes\nPid(Parent) State Name(console)\n");
cprintf("-------------------------------\n");
for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) {
if (p->state == UNUSED) {
continue;
@ -532,10 +534,18 @@ void procdump(void) {
else {
state = "???";
}
cprintf("%d %s %s", p->pid, state, p->name);
int parentpid = 0;
if (p->parent != 0x0)
{
parentpid = p->parent->pid;
}
cprintf("%d(%d) %s %s(%d)", p->pid, parentpid, state, p->name, getconsoleindex(p->consoleptr));
if (p->state == SLEEPING) {
getcallerpcs((uint*)p->context->ebp + 2, pc);
for (i = 0; i < 10 && pc[i] != 0; i++) {
// was 10
for (i = 0; i < 5 && pc[i] != 0; i++) {
cprintf(" %p", pc[i]);
}
}

View File

@ -98,7 +98,7 @@ int sys_greeting(void)
cprintf("Using Console: %d\n", getcurrentconsoleindex());
cprintf("Current PID: %d\n", myproc()->pid);
cprintf("Current Parent PID: %d\n", myproc()->parent->pid);
//cprintf("Process Console: %d\n", myproc()->consoleptr->consoleindex);
cprintf("Process Console: %d\n", getconsoleindex(myproc()->consoleptr));
return 0;
}
@ -154,6 +154,6 @@ int sys_screen(void)
int sys_cls(void)
{
clearscreen();
clearscreen(0);
return 0;
}