jsos

college code for operating system fundamentals in js

git clone https://9o.is/git/jsos.git

commit 3e1d6ed4bae7c6ac1a0e752a7d5567316696d539
parent 0c771ca4a47984f973244b57d36cfd92408fdb1e
Author: Jul <jul@9o.is>
Date:   Wed, 10 Oct 2012 07:28:26 -0400

second and last all-nighter. completed iProject2 and v.0.2

Diffstat:
Adocs/iProject1.pdf | 0
Adocs/iProject2.pdf | 0
Adocs/iProject3.pdf | 0
Mglobals.js | 23+++++++++++++++++++----
Mindex.html | 62+++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mscripts/host/control.js | 3++-
Mscripts/host/cpu.js | 162+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Mscripts/host/devices.js | 2+-
Ascripts/host/memory.js | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mscripts/os/interrupt.js | 2+-
Mscripts/os/kernel.js | 38++++++++++++++++++++++++++++++--------
Mscripts/os/memoryManager.js | 53+++++++++++++++++++++++++++++++++++++++++++----------
Ascripts/os/pcb.js | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mscripts/os/queue.js | 4++++
Mscripts/os/shell.js | 36++++++++++++++++++++++++++++++++----
Dstyles/ie.css | 44--------------------------------------------
Mstyles/julios.css | 17++++++++++++++++-
17 files changed, 504 insertions(+), 101 deletions(-)

diff --git a/docs/iProject1.pdf b/docs/iProject1.pdf Binary files differ. diff --git a/docs/iProject2.pdf b/docs/iProject2.pdf Binary files differ. diff --git a/docs/iProject3.pdf b/docs/iProject3.pdf Binary files differ. diff --git a/globals.js b/globals.js @@ -12,13 +12,15 @@ // Global Constants // var APP_NAME = "JuliOS"; // 'cause I was at a loss for a better name. -var APP_VERSION = "0.1"; +var APP_VERSION = "0.2"; var CPU_CLOCK_INTERVAL = 100; // in ms, or milliseconds, so 1000 = 1 second. var TIMER_IRQ = 0; // Pages 23 (timer), 9 (interrupts), and 561 (interrupt priority). // NOTE: The timer is different from hardware clock pulses. Don't confuse these. -var KEYBOARD_IRQ = 1; +var KEYBOARD_IRQ = 1; + +var SYSCALL_IRQ = 2; // @@ -28,6 +30,8 @@ var _CPU = null; var _OSclock = 0; // Page 23. +var _Memory = null; + var _Mode = 0; // 0 = Kernel Mode, 1 = User Mode. See page 21. // TODO: Fix the naming convention for these next five global vars. @@ -52,6 +56,7 @@ var _KernelInterruptQueue = null; var _KernelBuffers = null; var _KernelInputQueue = null; var _KernelMemoryManager = null; +var _KernelReadyQueue = null; // Standard input and output var _StdIn = null; @@ -70,5 +75,15 @@ var _SarcasticMode = false; var krnKeyboardDriver = null; // memory size -var TOTAL_MEMORY = 128; //bytes -var MAX_MEMORY_PROGRAM = 32; //bytes +var TOTAL_PAGES = 4; +var MAX_MEMORY_PROGRAM = 64; //bytes +var TOTAL_MEMORY = TOTAL_PAGES * MAX_MEMORY_PROGRAM; //bytes + +// pcb states +var PCB_STATE_RESIDENT = "resident"; +var PCB_STATE_READY = "ready"; +var PCB_STATE_RUNNING = "running"; +var PCB_STATE_TERMINATED = "terminated"; + +// error codes +var ERROR_INVALID_OPERATOR = 1; diff --git a/index.html b/index.html @@ -5,12 +5,12 @@ <meta name="author" content="Alan G. Labouseur and Julio Cabrera" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <link rel="stylesheet" href="styles/1140.css" type="text/css" media="screen" /> - <link rel="stylesheet" href="styles/julios.css" type="text/css" media="screen" /> + <link rel="stylesheet" href="styles/1140.css" type="text/css" media="screen" /> + <link rel="stylesheet" href="styles/julios.css" type="text/css" media="screen" /> <link rel="stylesheet" href="styles/julios-buttons.css" type="text/css" media="screen" /> <title> - JuliOS 0.1 - a Browser-based virtual Operating System + JuliOS 0.2 - a Browser-based virtual Operating System </title> <!-- Globals CONSTANTS and _Variables. Must included be first. --> @@ -20,6 +20,7 @@ <script type="text/javascript" src="scripts/host/control.js"></script> <script type="text/javascript" src="scripts/host/devices.js"></script> <script type="text/javascript" src="scripts/host/cpu.js"></script> + <script type="text/javascript" src="scripts/host/memory.js"></script> <!-- Virtual OS Routines: Make sure Kernel code is last, since it needs those above it. --> <script type="text/javascript" src="scripts/os/interrupt.js"></script> @@ -28,9 +29,10 @@ <script type="text/javascript" src="scripts/os/deviceDriver.js"></script> <script type="text/javascript" src="scripts/os/deviceDriverKeyboard.js"></script> <script type="text/javascript" src="scripts/os/queue.js"></script> - <script type="text/javascript" src="scripts/os/stack.js"></script> + <!--<script type="text/javascript" src="scripts/os/stack.js"></script>--> <script type="text/javascript" src="scripts/os/shell.js"></script> <script type="text/javascript" src="scripts/os/kernel.js"></script> + <script type="text/javascript" src="scripts/os/pcb.js"></script> <script type="text/javascript" src="scripts/os/memoryManager.js"></script> <!-- Other Routines --> @@ -59,7 +61,47 @@ onclick="simBtnReset_click(this)"> <i class="icon28-reset"></i></button> </div> - <div class="fivecol"></div> + <div class="fourcol" id="processes"> + <h4>Processes</h4> + <table cellspacing="10" id="processesTable"> + <tr> + <th>pid</th> + <th>state</th> + <th>base</th> + <th>limit</th> + <th>PC</th> + <th>ACC</th> + <th>X</th> + <th>Y</th> + <th>Z</th> + </tr> + </table> + </div> + <div class="onecol"> + <h4>Registers</h4> + <table> + <tr> + <th align="right">PC:</th> + <td id="pc_register"></td> + </tr> + <tr> + <th align="right">ACC:</th> + <td id="acc_register"></td> + </tr> + <tr> + <th align="right">X:</th> + <td id="x_register"></td> + </tr> + <tr> + <th align="right">Y:</th> + <td id="y_register"></td> + </tr> + <tr> + <th align="right">Z:</th> + <td id="z_register"></td> + </tr> + </table> + </div> <div class="fourcol last"> <textarea id="taProgramInput" placeholder="Input Program hex here"></textarea> @@ -71,15 +113,21 @@ <canvas id="display" tabindex="0" width="1138" - height="500"></canvas> + height="450"></canvas> </div> </div> <div class="row"> - <div class="twelvecol last"> + <div class="eightcol"> <textarea id="taLog" placeholder="No Log Output"></textarea> </div> + + <div class="fourcol last" id="memoryDump"> + <table cellspacing="10" id="memoryDumpTable"> + <tr><th>Empty Memory Dump</th></tr> + </table> + </div> </div> <div class="row"> diff --git a/scripts/host/control.js b/scripts/host/control.js @@ -44,7 +44,6 @@ function simLog(msg, source) { taLog.value = str + taLog.value; } - /* * Starts the OS by intiating a cpu and starting the kernel. * @@ -61,7 +60,9 @@ function simBtnStartOS_click(btn) { document.getElementById(CANVAS_ID).focus(); _CPU = new cpu(); + _Memory = new memory(TOTAL_MEMORY); _CPU.init(); + _Memory.init(); hardwareClockID = setInterval(simClockPulse, CPU_CLOCK_INTERVAL); krnBootstrap(); } diff --git a/scripts/host/cpu.js b/scripts/host/cpu.js @@ -15,33 +15,155 @@ /* * The cpu that contains the program counter (PC), - * accumulator (Acc), X register (Xreg), - * Y register (Yreg), Z-ero flag (Zflag). + * accumulator (ACC), X register (X), + * Y register (Y), Z-ero flag (Z). */ function cpu() { - this.PC = 0; - this.Acc = 0; - this.Xreg = 0; - this.Yreg = 0; - this.Zflag = 0; + this.PC = '0'; + this.ACC = '0'; + this.X = '0'; + this.Y = '0'; + this.Z = 0; this.isExecuting = false; + this.running = null; // process currently running this.init = function() { - this.PC = 0 - this.Acc = 0; - this.Xreg = 0; - this.Yreg = 0; - this.Zflag = 0; - this.isExecuting = false; - } - - // TODO: Do we need this? Probably not. - this.pulse = function(){} + this.output(); + } - // TODO: Accumulate CPU usage and profiling - // statistics here. Do real work here. Set - // this.isExecuting appropriately. + // Executes a CPU cycle + // if process is not running, CPU checks in the ready queue + // if ready queue is empty, it sets isExecuting false. this.cycle = function() { krnTrace("CPU cycle"); + if(this.running == null && _KernelReadyQueue.isEmpty()) + this.isExecuting = false; + else if(this.running == null && _KernelReadyQueue.isNonEmpty()) { + this.running = _KernelReadyQueue.dequeue(); + this.running.setState(PCB_STATE_RUNNING); + this.PC = this.running.PC; + this.execute(); + } else this.execute(); + + this.output(); + this.running.updateRegisters( + this.PC, this.ACC, this.X, this.Y, this.Z); + } + + // executes the byte in location PC + // assumes it's a operator. + this.execute = function() { + this.isExecuting = true; + var operator = _Memory.getByte(parseInt(this.PC, 16)); + this.incrementPC(1); + + if(operator == undefined) return; + switch(operator.toUpperCase()) { + case 'A9': // LDA: Load the accumulator with a constant + var operand = this.immediateOperand(); + this.ACC = operand; + this.incrementPC(1); + break; + case 'AD': // LDA: Load the accumulator from memory + var operand = this.directOperand(); + this.ACC = (parseInt(this.ACC,16) + parseInt(operand,16)).toString(16); + this.incrementPC(2); + break; + case '8D': // STA: Store the accumulator in memory + _Memory.setByte(this.ACC, this.PC); + this.incrementPC(2); + break; + case '6D': // ADC: Add with carry + var operand = this.directOperand(); + addToACC(operand); + this.incrementPC(2); + break; + case 'A2': // LDX: Load the X register with a constant + var operand = this.immediateOperand(); + this.X = operand; + this.incrementPC(1); + break; + case 'AE': // LDX: Load the X register from memory + var operand = this.directOperand(); + this.X = operand; + this.incrementPC(2); + break; + case 'A0': // LDY: Load the Y register with a constant + var operand = this.immediateOperand(); + this.Y = operand; + this.incrementPC(1); + break; + case 'AC': // LDY: Load the Y register from memory + var operand = this.directOperand(); + this.Y = operand; + this.incrementPC(2); + break; + case 'EA': // NOP: No operation + break; + case '00': // BRK: Break (which is really a system call) + krnInterrupt(SYSCALL_IRQ, new Array('00')); + break; + case 'EC': // CPX: Compare a byte in memory to the X reg Sets the Z (zero) flag if equal + var operand = this.directOperand(); + if(operand == this.X) this.Z = 1; + else this.Z = 0; + this.incrementPC(2); + break; + case 'D0': // BNE: Branch X bytes if Z flag = 0 + if(this.Z != 0) this.incrementPC(1); + else { + var operand = this.immediateOperand(); + this.PC = operand; + } + break; + case 'EE': // INC: Increment the value of a byte + var operand = this.directOperand(); + operand = (parseInt(operand,16) + 1).toString(16); + var location = _Memory.getByte(parseInt(this.PC, 16)); + _Memory.setByte(operand, location); + this.incrementPC(2); + break; + case 'FF': // SYS: System Call + krnInterrupt(SYSCALL_IRQ); + break; + default: // unknown operator + krnInterrupt(SYSCALL_IRQ, new Array('FF', ERROR_INVALID_OPERATOR)); + break; + } + } + + // Gets operand from memory in location PC + this.directOperand = function() { + var location = _Memory.getByte(parseInt(this.PC, 16)); + var value = _Memory.getByte(parseInt(location, 16)); + return value; + } + + // Gets operand as a constant in location PC + this.immediateOperand = function() { + var value = _Memory.getByte(parseInt(this.PC, 16)); + return value; + } + + // Given decimal value, it adds that value to the PC which + // is a hexadecimal. + this.incrementPC = function(value) { + this.PC = (parseInt(this.PC, 16) + value).toString(16); + } + + // adds operand to accumulator + // Note: operand and accumulator are hexadecimal values + this.addToACC = function(operand) { + var value = parseInt(this.ACC,16) + parseInt(operand,16); + this.ACC = (value).toString(16); + } + + // displays register values in interface + this.output = function() { + document.getElementById("pc_register").innerHTML = _CPU.PC; + document.getElementById("acc_register").innerHTML = _CPU.ACC; + document.getElementById("x_register").innerHTML = _CPU.X; + document.getElementById("y_register").innerHTML = _CPU.Y; + document.getElementById("z_register").innerHTML = _CPU.Z; } } diff --git a/scripts/host/devices.js b/scripts/host/devices.js @@ -55,6 +55,6 @@ function simOnKeypress(event) { if (event.target.id == CANVAS_ID) { event.preventDefault(); var params = new Array(event.which, event.shiftKey); - _KernelInterruptQueue.enqueue( new Interrput(KEYBOARD_IRQ, params) ); + _KernelInterruptQueue.enqueue( new Interrupt(KEYBOARD_IRQ, params) ); } } diff --git a/scripts/host/memory.js b/scripts/host/memory.js @@ -0,0 +1,104 @@ +/* ------------ + CPU.js + + Requires global.js. + + Core Memory implementation. + In this manner, it's A LITTLE BIT like a hypervisor, + in that the Document envorinment inside a browser is the "bare metal" (so to speak) for which we write code + that hosts our client OS. But that analogy only goes so far, and the lines are blurred, because we are using + JavaScript in both the host and client environments. + + This code references page numbers in the text book: + Operating System Concepts 8th editiion by Silberschatz, Galvin, and Gagne. ISBN 978-0-470-12872-5 + ------------ */ + +/* + * The core memory has an array to save bytes of data + */ + +function memory(maxBytes) { + this.memory = new Array(); + + // initialize the memory with zeros + this.init = function() { + for(var i=0; i<maxBytes; i++) { + this.memory[i] = "00"; + } + this.output(); + } + + // allocate a byte in a location in memory + // and limit the memory to its size + this.allocateByte = function(byte, location) { + if(maxBytes < location) + krnTrapError("Stack overflow."); + this.memory[location] = byte; + } + + this.deallocateByte = function() { + this.memory.pop(); + } + + // allocates an array of bytes starting from base + this.allocateBytes = function(bytes, base) { + for(var i=0; i<bytes.length; i++) { + this.allocateByte(bytes[i], base+i); + } + this.output(); + } + + // gets byte in a location + this.getByte = function(location) { + if(maxBytes < location) + krnTrapError("Stack overflow."); + return this.memory[location]; + } + + // sets byte in a location + this.setByte = function(byte, location) { + if(maxBytes < location) + krnTrapError("Stack out of bounds."); + this.memory[location] = byte; + } + + // memory dump + this.dumpMemory = function() { + return this.memory; + } + + // outputs memory dump to interface + this.output = function() { + + // padding for location hex ie. a8 to 00a8 + function pad(hex) { + while(hex.length < 4) hex = '0'+hex; + return hex; + } + + // extracts every byte and returns html table rows of + // 8 columns + function extract(dump) { + var i=0; + var html = ""; + for(var j=0; j < dump.length; j++) { + if(i == 8) { + i=0; + html += '</tr>'; + if(j < dump.length) + html += '<tr><th align="right">'+pad(j.toString(16))+'</th>'; + } + i++; + html += '<td>'+dump[j]+'</td>'; + } + return html; + } + + var dump = this.dumpMemory(); + var html = '<tr><th>location</th></tr><tr>'; + html += '<th align="right">0000</th>'; + html += extract(dump); + html += '</tr>'; + document.getElementById("memoryDumpTable").innerHTML = html; + } +} diff --git a/scripts/os/interrupt.js b/scripts/os/interrupt.js @@ -2,7 +2,7 @@ Interrupt.js ------------ */ -function Interrput(_irq, _params) { +function Interrupt(_irq, _params) { // Properties this.irq = _irq; this.params = _params; diff --git a/scripts/os/kernel.js b/scripts/os/kernel.js @@ -17,15 +17,16 @@ function krnBootstrap() // Page 8. { simLog("bootstrap", "host"); // Use simLog because we ALWAYS want this, even if _Trace is off. + // Initialize the Console. + _Console = new Console(); // The console output device. + _Console.init(); + // Initialize our global queues. _KernelInterruptQueue = new Queue(); // A (currently) non-priority queue for interrupt requests (IRQs). _KernelBuffers = new Array(); // Buffers... for the kernel. _KernelInputQueue = new Queue(); // Where device input lands before being processed out somewhere. _KernelMemoryManager = new MemoryManager(); - _Console = new Console(); // The console output device. - - // Initialize the Console. - _Console.init(); + _KernelReadyQueue = new Queue(); // the ready queue for waiting processes to execute. // Initialize standard input and output to the _Console. _StdIn = _Console; @@ -81,7 +82,8 @@ function krnOnCPUClockPulse() var interrput = _KernelInterruptQueue.dequeue(); krnInterruptHandler(interrput.irq, interrput.params); } - else if (_CPU.isExecuting) // If there are no interrupts then run a CPU cycle if there is anything being processed. + // If there are no interrupts then run a CPU cycle if there is anything being processed. + else if (_KernelReadyQueue.getSize() > 0 || _CPU.isExecuting) { _CPU.cycle(); } @@ -109,6 +111,11 @@ function krnDisableInterrupts() // Put more here. } +// Queue an interrupt +function krnInterrupt(irq, params) { + _KernelInterruptQueue.enqueue(new Interrupt(irq, params)); +} + function krnInterruptHandler(irq, params) // This is the Interrupt Handler Routine. Page 8. { // Trace our entrance here so we can compute Interrupt Latency by analyzing the log file later on. Page 766. @@ -129,6 +136,9 @@ function krnInterruptHandler(irq, params) // This is the Interrupt Handler Ro krnKeyboardDriver.isr(params); // Kernel mode device driver _StdIn.handleInput(); break; + case SYSCALL_IRQ: // System Call interrupt + krnSystemCall(params); + break; default: krnTrapError("Invalid Interrupt Request. irq=" + irq + " params=[" + params + "]"); } @@ -141,8 +151,6 @@ function krnTimerISR() // The built-in TIMER (not clock) Interrupt Service Rout // Check multiprogramming parameters and enfore quanta here. Call the scheduler / context switch here if necessary. } - - // // System Calls... that generate software interrupts via tha Application Programming Interface library routines. // @@ -157,7 +165,21 @@ function krnTimerISR() // The built-in TIMER (not clock) Interrupt Service Rout // - ReadFile // - WriteFile // - CloseFile - +function krnSystemCall(params) { + switch(params[0]) { + case '00': // a process has been terminated + krnTrace("Process "+_CPU.running.pid+" terminated successfully."); + _CPU.running.setState(PCB_STATE_TERMINATED); + _CPU.running = null; + case 'FF': // something bad happened. Terminate process and print error code + krnTrace("Error: "+params[1]+" - Process "+_CPU.running.pid+" terminated unsuccessfully."); + _CPU.running.setState(PCB_STATE_TERMINATED); + _CPU.running = null; + break; + default: + krnTrapError("Invalid system call in X register: "+_CPU.x); + } +} // // OS Utility Routines diff --git a/scripts/os/memoryManager.js b/scripts/os/memoryManager.js @@ -1,16 +1,49 @@ /* * Manages the OS memory. */ - function MemoryManager() { - this.memory = new MemoryStack(TOTAL_MEMORY); - this.load = memoryManagerLoad; -} + this.processes = new Array(); // array of pcb's + + /* + * Loads a program (hex or bytes) into memory. + * @param hex an array of bytes + */ + this.load = function(bytes) { + var pid = this.processes.length; + var base = pid * MAX_MEMORY_PROGRAM; + var limit = (pid+1) * MAX_MEMORY_PROGRAM - 1; + var process = new pcb(pid, PCB_STATE_RESIDENT, base, limit, base); + this.processes.push(process); + _Memory.allocateBytes(bytes, base); -/* - * Loads a program (hex or bytes) into the memory stack. - * @param hex an array of bytes - */ -function memoryManagerLoad(bytes) { - this.memory.allocateBytes(bytes); + console.log("Loaded pid:"+pid+" base="+base+" limit="+limit); + this.output(); + + return pid; + }; + + // outputs pcb attributes of each process in control of this + // OS's memory manager to the interface + this.output = function() { + var div = document.getElementById("processesTable"); + var html = + '<tr><th>pid</th><th>state</th><th>base</th>' + + '<th>limit</th><th>PC</th><th>ACC</th><th>X</th>' + + '<th>Y</th><th>Z</th></tr>'; + for(var i=0; i<this.processes.length; i++) { + var p = this.processes[i]; + html += '<tr>'; + html += '<td>'+p.PID+'</td>'; + html += '<td>'+p.state+'</td>'; + html += '<td>'+p.base.toString(16)+'</td>'; + html += '<td>'+p.limit.toString(16)+'</td>'; + html += '<td>'+p.PC.toString(16)+'</td>'; + html += '<td>'+p.ACC+'</td>'; + html += '<td>'+p.X+'</td>'; + html += '<td>'+p.Y+'</td>'; + html += '<td>'+p.Z+'</td>'; + html += '</tr>'; + } + div.innerHTML = html; + } } diff --git a/scripts/os/pcb.js b/scripts/os/pcb.js @@ -0,0 +1,55 @@ +/* + * Process Control Block + */ +function pcb(pid, state, base, limit, pc) { + this.PID = pid; + this.state = state; + this.base = base; + this.limit = limit; + this.PC = pc; + this.ACC = 0; + this.X = 0; + this.Y = 0; + this.Z = 0; + + /* + * Updates process control block values. + */ + this.update = function(state, base, limit, pc, acc, x, y, z) { + this.state = state; + this.base = base; + this.limit = limit; + this.PC = pc; + this.ACC = acc; + this.X = x; + this.Y = y; + this.Z = z; + _KernelMemoryManager.output(); + } + + /* + * Updates the PCB with a new state. + */ + this.setState = function(newState) { + this.update( + newState, + this.base, + this.limit, + this.PC, + this.ACC, + this.X, + this.Y, + this.Z); + } + + /* + * Updates the registers and Zflag. + */ + this.updateRegisters = function(pc, acc, x, y, z) { + this.update( + this.state, + this.base, + this.limit, + pc, acc, x, y, z); + } +} diff --git a/scripts/os/queue.js b/scripts/os/queue.js @@ -18,6 +18,10 @@ function Queue() { return (this.q.length == 0); } + this.isNonEmpty = function() { + return (this.q.length > 0); + } + this.enqueue = function(element) { this.q.push(element); } diff --git a/scripts/os/shell.js b/scripts/os/shell.js @@ -117,6 +117,13 @@ function shellInit() sc.function = shellLoad; this.commandList[this.commandList.length] = sc; + // run + sc = new ShellCommand(); + sc.command = "run"; + sc.description = "- Runs a process."; + sc.function = shellRun; + this.commandList[this.commandList.length] = sc; + // processes - list the running processes and their IDs // kill <id> - kills the specified process id. @@ -425,7 +432,7 @@ function shellWhereami(args) { return false; } -// TODO: Override all data in filesystem in under 10 seconds +// TODO: Override all data in filesystem less than 2 seconds // (when the filesystem is implemented). function shellQuickerase(args) { @@ -449,6 +456,9 @@ function shellStatus(args) } } +/* + * Loads a program into a memory so it becomes a process. + */ function shellLoad(args) { var hex = trim(document.getElementById(TA_PROGRAM_INPUT).value.replace(/\n/g, " ")); if(isValidHex(hex)) { // in utils.js @@ -456,13 +466,31 @@ function shellLoad(args) { if(bytes.length > 1) { if (bytes.length <= MAX_MEMORY_PROGRAM) { // pass the hex to kernel's memory manager - _KernelMemoryManager.load(bytes); - _StdOut.putText("Your program has been successfully loaded."); + var pid = _KernelMemoryManager.load(bytes); + _StdOut.putText("Your program has been successfully loaded with PID: " + pid); } else { - _StdOut.putText("Program is too large. Must be less than "+MAX_MEMORY_PROGRAM); + _StdOut.putText("Program is too large. Must be less than "+MAX_MEMORY_PROGRAM+" bytes."); } } else _StdOut.putText("Input Program textarea is empty."); } else { _StdOut.putText("Invalid program. Make sure it's properly formatted hex."); } } + +/* + * Executes a loaded process given a PID. + */ +function shellRun(args) { + var pid = args[0]; + if(pid == undefined) { + _StdIn.putText('Usage: run <pid>'); + } else { + var process = _KernelMemoryManager.processes[pid]; + if(process == undefined) { + _StdOut.putText("No such process."); + } else { + _KernelReadyQueue.enqueue(process); + process.state = PCB_STATE_READY; + } + } +} diff --git a/styles/ie.css b/styles/ie.css @@ -1,43 +0,0 @@ -.onecol { -width: 4.7%; -} - -.twocol { -width: 13.2%; -} - -.threecol { -width: 22.05%; -} - -.fourcol { -width: 30.6%; -} - -.fivecol { -width: 39%; -} - -.sixcol { -width: 48%; -} - -.sevencol { -width: 56.75%; -} - -.eightcol { -width: 61.6%; -} - -.ninecol { -width: 74.05%; -} - -.tencol { -width: 82%; -} - -.elevencol { -width: 91.35%; -} -\ No newline at end of file diff --git a/styles/julios.css b/styles/julios.css @@ -15,11 +15,26 @@ body { font-size: 10pt; } -#taLog, #taProgramInput { +#taProgramInput { height: 100px; width: 99%; } +#taLog { + height: 150px; + width: 100%; +} + +#memoryDump { + overflow-y:auto; + height:150px; +} + +#processes { + overflow-y:auto; + height:100px; +} + #buttons { text-align: center; margin-top: 20px;