I started using 8051 family microcontrollers over twenty years ago. I bought an old multi terminal Z80 computer system for £1 from a second hand computer auction. It didn't work for long after I took it home, and when I dismantled it I found inside about 8 (if memory serves) 8031 chips - one in each keyboard and several on the motherboards - a few Z80s and a large number of 6116 RAM chips. This was before I had internet access, and I recall that it took several weeks to get together enough information and software to be able to work out how to use them. Only three ICs were required to get an 8031 up and running. I attached a membrane keypad and some 7 segment LED displays to the ports and was delighted that it worked. I made a several more 8031 circuits over the next few years, some of them still work.
Today the 8051 is still widely used and well supported. I picked up one of my 8031 projects a couple of years ago and decided to do some more work on it.
This schematic shows how the 8031 is booted using a PIC to inject a short bootstrap program (up to 256 bytes) into the RAM. The PIC holds the 8031 in reset and controls the bus. It takes A8-A15 low. To write each byte into RAM it then uses the demultiplexing 373 to set the address to program, puts data onto the bus, and lowers the /WR pin.
Also shown in this schematic is the logic that maps the 128K RAM to the 8031 address spaces. Program memory read accesses using /PSEN always fetch from the lower 64K of the RAM. When P1.1 on the 8031 is low, data memory accesses using the MOVX instructions also use the lower 64K. When P1.1 is high, data memory accesses use the upper 64K.
I've added a link to GitHub from this project - I'll add all of the source code there in due course. At the moment it only contains the 8051 and PIC assembly language programs used for booting. Currently the boot program that the PIC injects into the RAM checks the state of pin P1.0 on the 8031, and depending on whether that pin is high or low (set using a jumper), it either loads a program from the first few sectors in the external serial flash (not shown in the schematic above) into program memory and executes it, or it downloads a program via the UART and executes that.
This system has an OS and language developed from scratch. I have tried to make both as simple as possible, while still being useful. The language (called MC) borrows heavily from C and Forth. It is easier to parse than C. It uses stack based semantics for expression evaluation and function call / return. The compiler does a few simple optimisations. The compiler source code is 2300 lines of C, I'm currently in the process of rewriting the compiler in MC so that I can compile programs on the 8051 system.
The OS has a flat file system and a simple shell that supports passing arguments to programs and input/output redirection. The OS is currently about 1300 lines of assembly language and 1000 lines of MC.
Regardless of any future developments and increases in complexity of the OS and language, I intend to always retain a minimalistic version, always less than 10000 lines of code.