===================================== = LC3-project-1.html ===================================== = LC3 micro-OS Project Requirements ===================================== Description Build an OS for the LC3. A very small OS is also called a "monitor"; "micro" (one-million-th) gives some idea of the relative size of our project as compared to a real, full-scale OS (see below). An OS provides an interface to the HW and services. It is the program that includes booting and then whatever follows as a service interface. We might think of our LC3 OS as suitable for an embedded application where overall system size is very restricted. It is to be written in assembly language and C, linked together. Required Capabilities: --- Initializes the stack, the vector table, all service routines that need initialization, and any OS data structures. --- Issues a prompt to screen. --- Echoes user's keyboard input to the display. --- Reads keyboard input to detect user commands. --- Executes at least three commands: "h": lists available commands "r": runs a user program "q": shuts down the machine A user program should return to the OS when finished and the OS should then continue taking commands. Your user program should be written in C and compiled with our LC3 compiler, lcc. The lcc compiler generates a user program that will execute RET as its last instruction (essentially, RET is the C "return" statement.) Consequently, your OS main loop should jump to user code as if it is making a function call. The user code will return to the instruction immediately following that jump instruction. Any enhancements beyond the bare bones capabilities receives extra credit, of course. Note: An estimate of the size of a real system is around 30 million lines of source code (SLOC), and eight-thousand person-years. We will work on our system about one-fifth of the time for one-fourth of a semester, or about (1/100) person-year, and our code will be about 200 SLOC. If you are interested in the above estimations, see, http://www.dwheeler.com/sloc/redhat71-v1/redhat71sloc.html ===================================== Methods, Languages ===================================== ---- Your OS will be written in C and assembly language. You will compile, assemble, and link these together using our LC3 C compiler, lcc. You will load the object file, os.obj, into PennSim.jar at address x0200. You will also load a user program to address x3000. You will then have PennSim.jar execute your OS. Your OS will display a prompt, get commands, and execute the commands. When your OS executes the run-user-program command, "r", your OS will jump to your user code to execute it. The starting point for your OS code development consists of two files, os.c and asm-utilities.asm. ---- Keyboard input is simulated by having PennSim.jar read a plain text file. Characters from the file are received by the LC3's keyboard controller in order, first to last. Characters are limited to upper and lower case letters A-Z, punctuation, digits, and "Enter" or "Return". The characters are loaded into KBDR by PennSim.jar one at a time. Unfortunately, and unrealistically, as soon as the KBDR is read (ldi, e.g.) a new character arrives in its place, as if the typist were insanely fast. Load the input file with a sequence of characters modelling a user interacting with the OS. Only user input belongs in the file: the program receiving the input does character echoing (displaying what was entered), including newlines. There is a command window in PennSimm (just under the control buttons). The command to read the text file as keyboard input is, input myKeyboardInput.txt where "myKeyboardInput.txt" is any text file you have prepared as input. ===================================== OS Elements ===================================== ---- Your OS initialization should set up the vector table, defining an address for every vector. Since most vectors are undefined, they should get some default address. Just write a loop that fills in the default address for all vectors from x0000 to x01FF (0-255). Next, overwrite the vectors you need to initialize to non-default addresses: x0020 --- TRAP x20, aka "GETC", get one char from keyboard. x0021 --- TRAP x21, aka "OUT" , send one char to display. x0022 --- TRAP x22, aka "PUTS", display a string. x0022 --- TRAP x25, aka "HALT", display a string. x0100 --- EXCEPTION-PRIVILEGE , handle a Privilege Exception. x0101 --- EXCEPTION-OPCODE , handle an Illegal Opcode Exception. ---- Your keyboard interrupt handler should store keyboard data in a buffer (one char is big enough). It should also set a flag variable to indicate to an input service routine that new data is available in the buffer. A keyboard input service routine should return a character from the keyboard buffer and reset the flag. Programs should call this input routine using a trap: typically, this would be the lowest-level input service, "getc", which you should rewrite (the existing getc code does not work as just described). ---- Your testbench should also load a user program to x3000. Your user code should print "Hello World" and exit back the OS monitor. Use a trap routine to return to the OS. Alternately, have your OS initially set the user's stack as if a C routine had called main(). That way, the usual C code to leave a subroutine will work to leave main() and get back to the OS command loop. This also means you can write the user's code entirely in C.