User Mode Programs
I made a little progress this week on separating what I hope will eventually become the operating system software from everything else. Up until now, all the test programs I’ve written have essentially been the operating system, or part of it: their executable code exists in ROM, they execute in memory bank 0, and they make direct subroutine calls to library routines for handling the keyboard and LCD. I finally cleaned this up a little, and got my first working example of a user program, separate from the OS. It just prints the letter “A” endlessly and doesn’t make for an exciting demo, but it’s a start.
Since there’s no disk or other storage media yet, the user program was actually embedded in the OS boot code, as a piece of data. At boot-up, the OS copies the user program into memory bank 1, which is RAM instead of ROM, and then jumps to it to begin execution. The program then executes inside of bank 1, and has no visibility or access to other banks. In order to access hardware like the keyboard or LCD, it uses a new instruction I added named JSP, or “jump to system procedure”. This instruction takes a two byte immediate argument, which indicates the subsystem (LCD, keyboard, clock, etc) and procedure to be invoked. The microcode for this instruction switches to bank 0, and then uses the arguments to lookup into a jump table to find the address of a system procedure handler routine to invoke. The handler does the requested work, and a RSP instruction (return from system procedure) returns control to the original program in its original bank.
The idea is that JSP should allow user programs to access hardware resources in a controlled way, without doing a jump directly to some bank 0 handler address, since handlers might change location between versions of the OS. Jumping to the wrong bank 0 address might also cause the OS to write invalid data or crash in the worst case. Of course the trade-off for this extra layer of protection is that access to hardware resources is more cumbersome and slow.
This is all still executing as a single process for now: The OS program starts, sets up the user program, and jumps to it. Once that happens, there is no more OS program running. However, the next logical step is to add an interrupt handler to swap between several user programs. In theory this shouldn’t be difficult: just store a table of saved registers for each process somewhere in bank 0. Whenever a timer interrupt occurs, the handler would copy the current register contents into an entry in the table, fill the registers using another entry in the table, and then return. I think the harder part is actually thinking of two programs that would make sense to run at the same time on BMOW. Multiprocessing makes a lot more sense on a graphical display with windows than on a text screen. With only one LCD, output from two programs would be jumbled together. Maybe I could make one program that uses the keyboard and LCD for I/O, while another runs simultaneously using the USB interface. Or maybe someone here can suggest a more impressive multiprocessing demo?
Read 2 comments and join the conversation2 Comments so far
Leave a reply. For customer support issues, please use the Customer Support link instead of writing comments.
Hi,
I know this is rather late.. but what about a sort of “virtual terminal” concept? (Borrow from Unix.)
A key combination would switch between the output of each task? (On the LCD)
Yes, that’s a good idea, and wouldn’t be difficult to implement I think. As a demo it still wouldn’t have the obvious wow-factor of seeing multiple programs running and drawing and printing all at once, but from a practical standpoint it’s closer to what you’d want anyway.
Now that I’m starting work on video output, I could probably do a more interesting multitasking demo by dividing the screen into windows in some way. Anyone remember Geos for the Commodore 64? It always seemed like more of a proof of concept than an actual product to me.