Programming the Vintage Intel MCS-48 Microcontrollers
I have had a box in my parts collection for a few years that contains a variety of interesting vintage components. The most prominent are the Intel 8035L microcontrollers. These microcontrollers are from the Intel MCS-48 (commonly known as the 8048) line. They have 64 bytes of RAM and access to 4096 bytes of external program memory. Thankfully they are not the one-time-programmable (OTP) variety so I am free to put them up to any task. These processors have a copyright date of 1977 which puts them at roughly twice my age.
There are also a couple of different EPROMS: D27256, with a copyright date of 1984 and D2758 with a copyright date of 1977. Obviously whoever owned these components prior to me was building some interesting embedded systems.
They are in relatively good shape. I would say that these are socket pulls. They have some signs of prior use (adhesive on the quartz windows). These may have also been “development” units.
These components coupled with my new EPROM tools were enough for me to bring this vintage processor online. I managed to get the classic blinking LED working as shown on the top trace of my oscilloscope.
Continue reading to see how I did it!
The first thing I did was make sure that I could load code onto an EPROM using the MEMprog2 that I ordered. Unfortunately the tools do not support the D2758 EPROMs but they do support the D27256. I decided that I could just tie the upper address bits to ground and it would work fine.
Once I knew that I could successfully load code into program memory I had to find a compiler or assembler (read toolchain) of sorts. I decided to become friendly with the hardware and stick with assembly. The asm48 project looked promising. I have used Windows 7 as my development host for this project since the programming tools are running on that platform. I use VirtualBox to keep a few copies of Windows 7 around for IE web development anyway.
My test program (3 bytes) and the output of the assembler.
Once I had the program assembled and ready to load, I had to look at the datasheet for more hardware information. Thankfully a fellow by the name Arnim Läuger has done a fantastic job of compiling numerous MCS-48 family documents into one easy to read PDF. He has made this available under the title Grokking the MCS-48 System. This document served as an instruction set manual and helped me determine how to connect the program memory to the processor.
Early Intel processors combine the address and data bits onto the same lines and use two signals: ALE (Address Latch Enable) and PSEN (Program Store Enable) to signal what state the bus is in. This was done to save costs and keep pin count down. Unfortunately this complicates the connection to an external PROM.
Various Device Pinouts (EPROM Left, Processor Right, Discrete Logic Behind)
This processor has an interesting Instruction Fetch waveform. I studied this waveform for a couple of hours to determine the best way to interface with the external program memory. I devised that I would need some form of external latch to store the address lines after the bus returned to a floating state. I could use the ALE line to signal when the address was stable and retain that value.
I looked through my discrete logic collection and came across a bag of 74LS373 devices. I had labelled these “8-Bit 3-State Transparent Latch” at some point in the past. I looked up the datasheet and decided that this device would be suitable. All of this design work was done mentally. I have drawn it up quickly for your benefit.
If you refer to both the instruction fetch waveform and this crude sketch I can explain the basic theory of operation. The processor will assert the address that it wishes to read from on the bus. When the address is stable on the outputs, the ALE line will go low. I use this signal to latch the address lines into the 74LS373 which is otherwise transparent. The processor then puts the bus into a high impedance (floating) state. When it is ready to read the byte of data from the program memory it will assert PSEN by lowering it. I use this signal to control the output enable of the EPROM. This allows the EPROM to put the value of the data being read onto the bus. The processor will raise PSEN when it is finished putting the bus back into in a floating state. This sort of handshaking action will ensure that there is never contention on the bus.
A keen reader will spot the error in my drawing. CS should be OE.
After I had the circuit assembled it was as simple as putting the EPROM in my burner and loading my sample program. I validated that the processor was working by observing the state of the address lines. Since my program is only 3 bytes long only the first two bits of the address lines should change. My hypothesis was correct. The rest of the address lines were idle in a low state.
I wrote a slightly more complex program to toggle the state of the output lines and managed to observe a blinking LED!
I hope you have enjoyed reading this article. This blog outlines the process that I took to get scaled up on this very simple vintage processor. Next steps would be to experiment with interrupts. I would like to also toy with the timer that this processor has.
Perhaps my favorite discovery throughout this process was the fact that this setup uses 135mA at 5V. These days we are concerned about getting into the uA range for low power devices.
I am interested in building a clock using Nixie tubes. I may end up using this processor as the brains behind the operation.