Intel MCS-48
Adapted from Wikipedia ยท Discoverer experience
The MCS-48 microcontroller series was Intel's first microcontroller, released in 1976. It included important models like the 8048, 8035, and 8748, with the 8048 being the most well-known. These tiny computers were made using a special kind of technology called NMOS at first, and later they used CMOS technology in the early 1980s. People kept making them until the 1990s to help older machines still work.
The MCS-48 series used a special design called a modified Harvard architecture. It had its own memory for programs, called ROM, and a small amount of memory for temporary information, called RAM. It also had special areas for controlling devices, called I/O, which were separate from where programs and data were kept address space.
Even though newer models like the MCS-51 came along, the MCS-48 stayed popular into the year 2000. This was because it cost very little, was easy to find, and used memory very efficiently. Because of these advantages, it was used in many everyday items like TV remotes, computer keyboards, and toys.
Uses
The MCS-48 series was often used in computer and terminal keyboards. It helped turn key presses into signals that digital circuits could understand. This made it easier to connect keyboards with fewer wires.
The 8048 was used in many devices, like the Magnavox Odysseyยฒ video game console and several music machines. The TRS-80 Model II also used this series in its keyboard. The first IBM PC keyboard used an 8048 as well. Later computers used similar chips to control the keyboard and other functions.
Instruction set
The MCS-48 microcontroller has instructions that are one or two bytes long, with most being just one byte. It can handle 4096 bytes of program memory, 256 bytes of RAM, and 256 bytes of extra memory. It also has eight ports for connecting to other devices. Many math and logic tasks use a special area called the accumulator. Eight special memory spots act like quick-access registers, and two of these can point to other memory locations.
The code can jump to different parts of the program, but to reach all parts it needs a special instruction. It supports interruptions well, allowing it to quickly switch tasks and return to where it left off. Each instruction takes one or two steps to complete, and each step lasts for 15 clock signals.
Example code
Here is some assembler code for a routine called add32 that adds two 32-bit numbers stored in little endian order. One number is pointed to by R0, and the other number and the result are pointed to by R1.
| Opcode | Operand | Mnemonic | Cycles | Description | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | โ | NOP | 1 | No operation |
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | โ | OUTL BUS,A | 2 | Bus latch โ A |
| ALUI | 0 | 0 | 1 | 1 | data | ADD ADDC MOV ORL ANL XRL | 2 | A โ A ALU # | |||
| addhi | 0 | 0 | 1 | 0 | 0 | addlo | JMP add | 2 | PC โ DBF:addhi:addlo | ||
| 0 | 0 | 0 | I | 0 | 1 | 0 | 1 | โ | EN/DIS I | 1 | I โ 0 (EN) or I โ 1 (DIS) |
| 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | โ | DEC A | 1 | A โ A - 1 |
| 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | โ | INS A,BUS | 2 | A โ bus |
| 0 | 0 | 0 | 0 | 1 | 0 | PP | โ | IN A,Pp | 2 | A โ Port(p) (Ports 1-2) | |
| 0 | 0 | 0 | 0 | 1 | PP | โ | MOVD A,Pp | 2 | A0-3 โ 8243 Port(p); A4-7 โ 0 (Ports 4-7) | ||
| ALU | 0 | 0 | 0 | R | โ | INC XCH ORL ANL ADD ADDC MOVaA XRL MOVAa | 1 | dest โ dest ALU @Rr (@R0, @R1 only; no DEC) | |||
| ALU | 1 | RRR | โ | INC XCH ORL ANL ADD ADDC MOVaA DEC XRL MOVAa | 1 | dest โ dest ALU Rr | |||||
| BIT | 1 | 0 | 0 | 1 | 0 | addr | JBb addr | 2 | If A โง (1 0-7 โ addr | ||
| addhi | 1 | 0 | 1 | 0 | 0 | addlo | CALL add | 2 | (SP) โ PSW4-7:PC; SP โ SP + 1; PC โ DBF:addhi:addlo | ||
| 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | addr | JTF addr | 2 | If TF = 1 then PC0-7 โ addr (timer flag set) |
| 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | โ | INC A | 1 | A โ A + 1 |
| 0 | 0 | 1 | T | 0 | 1 | 0 | 1 | โ | EN/DIS TCNTI | 1 | TCNTI โ 0 (EN) or TCNTI โ 1 (DIS) (timer/counter interrupt) |
| 0 | 0 | 1 | F | 0 | 1 | 1 | 0 | addr | JNT0 JT0 addr | 2 | If F = T0 then PC0-7 โ addr (test input 0) |
| 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | โ | CLR A | 1 | A โ 0 |
| 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | โ | CPL A | 1 | A โ ยฌA |
| 0 | 0 | 1 | 1 | 1 | 0 | PP | โ | OUTL Pp,A | 2 | Port(p) โ A (Ports 1-2) | |
| 0 | 0 | 1 | 1 | 1 | PP | โ | MOVD Pp,A | 2 | 8243 Port(p) โ A0-3 (Ports 4-7) | ||
| 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | โ | MOV A,T | 1 | A โ T (Move timer to A) |
| 0 | 1 | 0 | T | 0 | 1 | 0 | 1 | โ | STRT CNT/T | 1 | If T = 0 start count else start timer |
| 0 | 1 | 0 | F | 0 | 1 | 1 | 0 | addr | JNT1 JT1 addr | 2 | If F = T1 then PC0-7 โ addr (test input 1) |
| 0 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | โ | SWAP A | 1 | A0-3 โ A4-7 |
| 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | โ | DA A | 1 | If A0-4 > 9 OR AC = 1 then A โ A + 6; then if A4-7 > 9 OR C = 1 then A โ A + 0x60 |
| 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | โ | MOV T,A | 1 | T โ A (Move A to timer) |
| 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | โ | STOP TCNT | 1 | Stop timer and count |
| 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | โ | RRC A | 1 | C โ A0; A0-6 โ A1-7; A7 โ C |
| 0 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | โ | ENT0 CLK | 1 | Set T0 as a clock output |
| 0 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | addr | JF1 addr | 2 | If F1 = 1 then PC0-7 โ addr |
| 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | โ | RR A | 1 | A0-6 โ A1-7; A7 โ A0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | R | โ | MOVX A,@Rr | 2 | A โ external @Rr (@R0, @R1 only) |
| 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | โ | RET | 2 | SP โ SP - 1; PC โ (SP) |
| 1 | 0 | N | 0 | 0 | 1 | 0 | 1 | โ | CLR Fn | 1 | Fn โ 0 |
| 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | addr | JNI addr | 2 | If I input = 0 then PC0-7 โ addr (test interrupt input low) |
| 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | data | ORL BUS,# | 2 | A โ bus โจ # |
| 1 | 0 | 0 | 0 | 1 | 0 | PP | data | ORL Pp,# | 2 | A โ Port(p) โจ # (Ports 1-2) | |
| 1 | 0 | 0 | 0 | 1 | PP | โ | ORLD Pp,A | 2 | 8243 Port(p) โ 8243 Port(p) โจ A0-3 (Ports 4-7) | ||
| 1 | 0 | 0 | 1 | 0 | 0 | 0 | R | โ | MOVX @Rr,A | 2 | external @Rr โ A (@R0, @R1 only) |
| 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | โ | RETR | 2 | SP โ SP - 1; PC โ (SP); PSW4-7 โ (SP) |
| 1 | 0 | N | 1 | 0 | 1 | 0 | 1 | โ | CPL Fn | 1 | Fn โ ยฌFn |
| 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | โ | CLR C | 1 | C โ 0 |
| 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | data | ANL BUS,# | 2 | A โ bus โง # |
| 1 | 0 | 0 | 1 | 1 | 0 | PP | data | ANL Pp,# | 2 | A โ Port(p) โง # (Ports 1-2) | |
| 1 | 0 | 0 | 1 | 1 | PP | โ | ANLD Pp,A | 2 | 8243 Port(p) โ 8243 Port(p) โง A0-3 (Ports 4-7) | ||
| 1 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | โ | MOVP A,@A | 2 | A โ ROM(PC8-11:A) (read program memory) |
| 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | โ | CPL C | 1 | C โ ยฌC |
| 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | โ | JMPP @A | 2 | PC0-7 โ A (indirect JMP) |
| 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | addr | JF0 addr | 2 | If F0 = 1 then PC0-7 โ addr |
| 1 | 1 | 0 | N | 0 | 1 | 0 | 1 | โ | SEL RBn | 1 | BS โ n (select register bank) |
| 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | addr | JZ addr | 2 | If A = 0 then PC0-7 โ addr |
| 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | โ | MOV A,PSW | 1 | A โ PSW |
| 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | โ | MOV PSW,A | 1 | PSW โ A |
| 1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | โ | MOVP3 A,@A | 2 | A โ ROM(0011:A) (read page 3 program memory) |
| 1 | 1 | 1 | N | 0 | 1 | 0 | 1 | โ | SEL MBn | 1 | DBF โ n (select memory bank: PC11) |
| 1 | 1 | 1 | F | 0 | 1 | 1 | 0 | addr | JNC JC addr | 2 | If F = C then PC0-7 โ addr |
| 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | โ | RL A | 1 | A1-7 โ A0-6; A0 โ A7 |
| 1 | 1 | 1 | 0 | 1 | RRR | addr | DJNZ Rr,addr | 2 | Rr โ Rr - 1; If Rr โ 0 then PC0-7 โ addr | ||
| 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | โ | RLC A | 1 | C โ A7; A1-7 โ A0-6; A0 โ C |
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Operand | Mnemonic | Cycles | Description |
| RRR or R | 3 | 2 | 1 | 0 | ALU | ALUI #immed | |||||
| R0 @R0 | 0 | 0 | 0 | 0 | ADD A,# (A โ A + #) | ||||||
| R1 @R1 | 0 | 0 | 0 | 1 | INC arg (arg โ arg + 1) | ADDC A,# (A โ A + # + C) | |||||
| R2 | 0 | 0 | 1 | 0 | XCH A,arg (A โ arg) | MOV R,# (R โ #) | |||||
| R3 | 0 | 0 | 1 | 1 | |||||||
| R4 | 0 | 1 | 0 | 0 | ORL A,arg (A โ A โจ arg) | ORL A,# (A โ A โจ #) | |||||
| R5 | 0 | 1 | 0 | 1 | ANL A,arg (A โ A โง arg) | ANL A,# (A โ A โง #) | |||||
| R6 | 0 | 1 | 1 | 0 | ADD A,arg (A โ A + arg) | ||||||
| R7 | 0 | 1 | 1 | 1 | ADDC A,arg (A โ A + arg + C) | ||||||
| 1 | 0 | 1 | 0 | MOV arg,A (arg โ A) | |||||||
| 1 | 1 | 0 | 0 | DEC arg (arg โ arg - 1) | |||||||
| 1 | 1 | 0 | 1 | XRL A,arg (A โ A โป arg) | XRL A,# (A โ A โป #) | ||||||
| 1 | 1 | 1 | 1 | MOV A,arg (A โ arg) | |||||||
| RRR or R | 3 | 2 | 1 | 0 | ALU | ALUI #immed | |||||
Variants
The 8049 model had a special type of memory called masked ROM, with space for 2 KB, which could be swapped for a larger 4 KB external ROM. It also included 128 bytes of RAM and 27 I/O ports for connecting to other devices. The chip used an oscillator to manage its timing, turning the clock frequency into different steps for processing.
The UPI-41 series was a version of the MCS-48 made for use with peripheral devices. These chips included a buffered parallel data-bus interface and some changed instructions to help them work with this setup.
| Device | Program memory | Data memory | Remarks |
|---|---|---|---|
| 8020 | 1K ร 8 ROM | 64 ร 8 RAM | subset of 8048, 20 pins, only 13 I/O lines |
| 8021 | 1K ร 8 ROM | 64 ร 8 RAM | subset of 8048, 28 pins, 21 I/O lines |
| 8022 | 2K ร 8 ROM | 64 ร 8 RAM | subset of 8048, A/D-converter |
| 8035 | none | 64 ร 8 RAM | |
| 8038 | none | 64 ร 8 RAM | |
| 8039 | none | 128 ร 8 RAM | |
| 8040 | none | 256 ร 8 RAM | |
| 8048 | 1K ร 8 ROM | 64 ร 8 RAM | 27รย I/O ports |
| 8049 | 2K ร 8 ROM | 128 ร 8 RAM | 27รย I/O ports |
| 8050 | 4K x 8 ROM | 256 ร 8 RAM | |
| 8648 | 1K ร 8 OTP EPROM | 64 ร 8 RAM | Factory OTP EPROM |
| 8748 | 1K ร 8 EPROM | 64 ร 8 RAM | 4K program memory expandable, 2รย 8-bit timers, 27รย I/O ports |
| 8749 | 2K ร 8 EPROM | 128 ร 8 RAM | 2รย 8-bit timers, 27รย I/O ports |
| 87P50 | ext. ROM socket | 256 ร 8 RAM | Has piggy-back socket for 2758/2716/2732 EPROM |
| Device | Program memory | Data memory | Remarks |
|---|---|---|---|
| 8041 | 1K ร 8 ROM | 64 ร 8 RAM | Universal Peripheral Interface (UPI) |
| 8041AH | 1K ร 8 ROM | 128 ร 8 RAM | UPI |
| 8741A | 1K ร 8 EPROM | 64 ร 8 RAM | UPI, EPROM version of 8041 |
| 8741AH | 1K ร 8 OTP EPROM | 128 ร 8 RAM | UPI, OTP EPROM version of 8041AH |
| 8042AH | 2K ร 8 ROM | 256 ร 8 RAM | UPI |
| 8242 | 2K ร 8 ROM | 256 ร 8 RAM | UPI, preprogrammed with keyboard controller firmware |
| 8742 | 2K ร 8 EPROM | 128 ร 8 RAM | UPI, EPROM version |
| 8742AH | 2K ร 8 OTP EPROM | 256 ร 8 RAM | UPI, OTP EPROM version of 8042AH |
Derived microcontrollers
Philips Semiconductors, now known as NXP, had permission to make copies of this series. They created their MAB8400-family using the same design. These were the first microcontrollers to include an IยฒC connection and were used in the first Philips (Magnavox in the US) Compact Disc players, like the CD-100.
Other companies also made versions of this design, including:
-
Intel MCS-48 second sources
-
Mitsubishi Electric M5M80C39P-6
-
Fujitsu MBL8742H
-
Kvazar Kiev KM1816VE48 (Soviet Union โ 8748 clone)
-
National Semiconductor NS87PC48D (piggyback variant)
-
Signetics SCN8048A
-
Philips MAF 8049H
Images
Related articles
This article is a child-friendly adaptation of the Wikipedia article on Intel MCS-48, available under CC BY-SA 4.0.
Images from Wikimedia Commons. Tap any image to view credits and license.
Safekipedia