ctr

DeMon48_128k

Intel 8049 (8048, 8748, 8749, 8035, 8039) / MCS-48 Hardware-Debugger & Monitor

Documentation - Chapter 2


2.0.0 MCS-48 Primer

2.1.0 The MCS-48 microcontroller family

The Intel MCS-48 single chip microcomputer family was introduced to the market in 1976 and advertised as the "first complete computer on a chip" (by Intel). It was manufactured using NMOS technology and could be operated with a maximum oscillator frequency of 6MHz, later 11MHz.

When operating at 11MHz, the instruction cycle time is 1.364µs (T[µs] = 15 / fosc[MHz]), in which 1-byte/1-cycle instructions are executed, which account for more than 50% of the instruction set consisting of 96 instructions for the 8035, 8039, 8048, 8049, 8748, 8749, 8040 and 8050 types (see "7.1.0 Instruction set of the 8035,8039,8048,8049,8748,8749,8040,8050µCs").

Later versions were manufactured using Intel's HMOS-II process (high density, short channel MOS) with lower static power consumption, smaller structure sizes (channel length approx. 2µm) and gate delays (approx. 0.5ns). CMOS versions were offered for example by Intersil in 1979.

The µCs of the Intel MCS-48 family are designed for a Harvard architecture, i.e. for the use of logically and physically separate instruction- and data-memories.

2.1.1 Devices and on-chip resources (1979)

DevicePackageROMEPROMRAMI/ONotes
8035DIP40--6415RAM-Standby
8048DIP401k-6427RAM-Standby
8748DIP40-1k6427-
8039DIP40--12815RAM-Standby
8049DIP402k-12827RAM-Standby
8749DIP40-2k12827-
8040DIP40--25615RAM-Standby
8050DIP404k-25627RAM-Standby
8021DIP281k-6421-
8022DIP402k-6426 + 2xAD-

2.1.2 MCS-48 in publications of the 1970s and 1980s

DateTitle (Topic)Publication
1976 / 02"Intel prepares 8-bit processor for low end""Electronics", 05.02.1976
1976 / 11"Single-chip 8- bit microcomputer fills gap between calculator types and powerful multichip processors" (8048 (Mask ROM) / 8748 (EPROM); 1kB ROM, 64bytes RAM; 6MHz max. clock frequency)"Electronics", 25.11.1976
1976 / 11"For the low end of the market we are promised two minimum chip families: the MCS48 and the MCS41.""Electronics Today International (AU)",
11 / 1976
1977 / 03"Intel to double microcomputer chip program memory" (2kB 8049 / 8039)"Electronics", 03.03.1977
1977 / 03"Programmer added for MCS-48 family" (Prompt-48)"Electronics", 31.03.1977
1977 / 06"The [...] control computer features an eight-bit CPU (i.e. the Intel 8048) with BCD arithmetic capabilities 1 k of ROM, 64 words of internal RAM, interrupt, oscillator and clock driver circuits and an internal timer and event counter.[...] US prices are $249 with ROM and $399 with EROM."
(IMSAI 8048)
"Electronics Today International (AU)",
06 / 1977
1978 / 02"Single-chip µC has twice memory of MCS-48s" (2kB 8049 / 8039)"Electronic Design", 15.02.1978
1978 / 04"IBM receives license for MCS-48, UPI-41 architectures and software""Electronics", 27.04.1978
1978 / 05"Intel's 8022 packs a-d converter, plus""Electronics", 11.05.1978
1978 / 05"Intel speeds up 8049 and 8039 by 80% to 11 MHz""Electronics", 11.05.1978
1978 / 05"Microcontroller includes a-d converter for lowest-cost analog interfacing" (8022)"Electronics", 25.05.1978
1979 / 01"A look at Intel's [...] MCS-48 µP family.""Radio Electronics",
01 / 1979
1979 / 05"Intersil's C-MOS drive" (MCS-48 C-MOS devices; 87C48, 87C41, 80C48, 80C41, 80C49, 80C35)"Electronics", 10.05.1979
1979 / 12"Microcomputer with A/D converter - Intel's 8022 is the first low-cost single-IC microcomputer that includes an A/D converter.""Radio Electronics",
12 / 1979
1980 / 02"Valvo, the Hamburg-based component-producing subsidiary of NV Philips Gloeilampenfabrieken, is now gearing up for production of the 8048 microcomputer""Electronics", 28.02.1980
1980 / 02"8048 to be made with Intel's HMOS process""Electronics", 28.02.1980
1980 / 09"National Semiconductor quadruples memory of 8048 microcomputer" (INS8050: 4kB ROM, 256bytes RAM)"Electronics", 25.09.1980
1981 / 03"Intel announced [...] a [...] 'automotive grade' version of its MCS-48 single-chip microcomputer family (able to operate at -40° to +100°C)""Electronics", 24.03.1981

2.2.0 The MCS-48 microcontrollers

The MCS-48 µCs 8035, 8039, 8048, 8049, 8748, 8749, 8040 and 8050 consist of the components of the CPU, the internal program memory (which is available depending on the type and implemented as a mask-programmed ROM or EPROM) and the internal static RAM:

  • one 8-Bit Timer/Counter
  • three 8-Bit ports (BUS, P1, P2)
  • Oscillator hardware
  • Interrupt logic: 2 sources (external interrupt on *INT and Timer/Counter)

They have two "Test" connections (T0 and T1) which, depending on the programming, can be used for conditional jumps, as an input for the 8-bit counter or as an output for the "CLK" signal (fclk = fosc / 3), with whose frequency the internal state machine is clocked to generate the S1 to S5 machine cycles. Using the *SS input, programs can be executed in single-step mode (see "3.5.0 Single-Step Hardware").

Enable T0-Clock-output
Image: Executing the "ENT0 CLK" instruction (opcode 0x75) to output CLK to T0

By applying a logic H to the "EA" (External Access) input, the internal ROM can be switched off and an external memory chip can be used as program memory with the base address 0x000. A µC with internal program memory then behaves like an otherwise identical type without internal program memory (e.g. an 8049 like an 8039).

The signals from BUS and the lower half of P2 (P2.0 to P2.3) are used to access an external program memory. The lower 8 bits of the address and data are multiplexed on BUS, the lower nibble (the least significant 4 bits) of P2 signals the upper 4 bits of the address or, at certain times during a command cycle, which consists of the five states S1 to S5 of the CPU state machine, the I/O information written on P2 (see set of drawings: "MCS-48 Logic Analyzer Traces").

MCS-48 Machine States S1 to S5
Image: S1 to S5 of the CPU state machine

2.2.1 Program memory

The 8048, 8049, 8748, 8749, 8035, 8039, 8040 and 8050 microcontrollers of the Intel MCS-48 family support an address bus width of up to 12 bits (A0 to A11) for the program memory, thus a maximum of 4kByte can be addressed. However, these 4kByte are divided into 2 banks of 2kByte each, and only within these 2kByte memory banks can addressing be done linearly using "JMP" and "CALL" commands.

To switch between these 2kB memory banks, the MCS-48 instruction set contains the instructions "SEL MB0" (select memory bank 0: address range 0x000 to 0x7FF (0 to 2047 decimal)) and "SEL MB1" (select memory bank 1: address range 0x800 to 0xFFF (2048 to 4095 decimal)). If one of these instructions is executed, a flip-flop in the microcontroller, the official name of which is "DBF: Memory Bank Flip-Flop" (Intel 8-Bit Embedded Controllers Handbook 1990; Chapter "MCS(R)-48 Instruction Set, Symbols and Abbreviations Used"; p. 3-7), is set by "SEL MB1" or reset by "SEL MB0". As soon as an unconditional jump is executed using the "JMP" or "CALL" instructions, the lower 11 bits (A0 to A10) of the program counter are loaded with the target address specified in the jump command and the output of the preparation flip-flop (MB-FF) is used as the 12th bit (A11) of the program counter.

Internes MB-FlipFlop (A12)
Image: Schematic representation of the internal logic for generating the 12th address bit, PC.11

After executing the following code, the program counter (PC) has the value 0x800 (Bit11 = 1):

000 F5 SEL MB1 ;MB-FlipFlop = 1
001 04 JMP 000 ;PC = 0x000 + 0x800
002 00

If the following is then executed, the program counter is set to 0x000 (Bit11 = 0):

800 E5 SEL MB0 ;MB-FlipFlop = 0
801 04 JMP 000 ;PC = 0x800 - 0x800
802 00

SEL MB1
Image: Executing the "SEL MB1" instruction (0xF5) and effect on P2.3 after "JMP 000" (0x04,0x00)

After a hardware interrupt has been triggered, all program memory accesses are limited to memory bank 0 (0x000...0x7FF) during its processing, but the state of the MB flip-flop remains unchanged.

If a bank change occurs in connection with a subroutine call, caution is advised. Since all 12 address bits are stored on the stack and restored by the return command "RET", the contents of the program counter (PC) are correct again afterwards, but the MB flip-flop is not affected by "RET". This can lead to unexpected results:

000 F5 SEL MB1
001 14 CALL 000 ;Call to 0x800 (Address 0x000 in Bank 1)
002 00
003 04 JMP 010  ;Jump to 0x010 (or to 0x810 ?)
004 10
800 83 RET      ;Return to address 0x003

In fact, the last jump instruction "JMP 010" will set the program counter to 0x810 because the MB flip-flop is still set!

("[...]Since all twelve bits of the program counter including bit (11) are stored in the stack when a Call is executed, the user may jump to subroutines across the 2K boundary and the proper bank will be restored upon return. However, the bank switch flipflop will not be altered on return." Quelle: "Intel MCS-48 Family of Single Chip Microcomputers User's Manual" (1980); Kap. "3.1.2 Extended Program Memory Addressing (Beyond 2K)" / "Program Memory Bank Switch"; S. 3-2).

A further effect of the actually only 11 bits wide program counter (PC) is that in the event of an overflow of the program counter, address 0x7FF is followed by address 0x000 and, correspondingly, address 0xFFF is followed by address 0x800.

Conditional jump instructions store only an 8-bit address and usually the destination must be within the same 256-byte page. There is a special case: if the jump instruction is in one of the highest addresses of a 256-byte page, then the destination address is in the next 256-byte page due to the program counter being incremented during S2 (1st instruction cycle) or S3 (2nd instruction cycle).

2.2.2 Reset- and Interrupt-Vectors

After a reset the program execution starts at address 0x000, after an interrupt request triggered by a low level at the *INT input, program execution is continued at address 0x003 and after a Timer/Counter interrupt program execution is continued at address 0x007 of the program memory.

2.2.3 PSW (Program Status Word)

The CPU flags and the stack pointer are stored in the PSW.

It can be completely written to and read only by "MOV PSW,A" (opcode 0xD7) and "MOV A,PSW" (opcode 0xC7) commands because it is a hardware register independent of the internal RAM.

BitDefinition / Function
7CYCarry FlagAn overflow has occurred in A
6ACAuxiliary Carry FlagAn overflow from bit3 to bit4 has occurred in A
5F0User Flag 0Is reset with "CLR F0", inverted with "CPL F0" and used for conditional jumps with "JF0"
4BSRegister Bank Select0: Register bank0 active; 1: Register bank1 active
3'1'Is in the result of a read access to the PSW access always 1
2S2Stack Pointer Bit 2Stack pointer bit with decimal value 4
1S1Stack Pointer Bit 1Stack pointer bit with decimal value 2
0S0Stack Pointer Bit 0Stack pointer bit with decimal value 1

2.2.4 Internal RAM

The internal static RAM comprises 64 bytes for the Intel 8035, 8048 and 8748 types, 128 bytes for the 8039, 8049 and 8749 types and 256 bytes for the 8040 and 8050 types.

The separate supply connection Vdd at pin 26 of the 8035, 8039, 8048, 8049, 8040 and 8050 types allows to preserve the memory contents when the main supply, Vcc at pin 40, is switched off.

The internal RAM contains two 8-byte register banks, within which the contents of the corresponding RAM address can be accessed directly using the Rr (R0 ... R7) specification in a suitable instruction (e.g.: "MOV R5,A" to access RAM address 0x05 if BS in PSW = 0, or RAM address 0x1D if BS in PSW = 1). The active register bank is selected using the "BS" flag (Register Bank Select) in the PSW (Program Status Word) or using the "SEL RB0" instruction (Opcode 0xC5) to select register bank 0 and the "SEL RB1" instruction (Opcode 0xD5) to select register bank 1. The RAM addresses of the two register banks can also be accessed indirectly using the index registers R0 and R1.

Because two independent register banks are available, effective interrupt service routines can be created, for example by using register bank 0 in the main program and register bank 1 in the interrupt routine.

All other addresses of the internal RAM can only be accessed indirectly via the index registers R0 and R1 of the selected register bank. For example, a "MOV @R0,A" instruction copies the contents of the accumulator to RAM address 0x20 if R0 = 0x20.

Additionally, it contains the 8-level stack area.

Address (hex)FunctionNotes
20...3F
20...7F
20...FF
RAM8035, 8048, 8748 = 32 Byte
8039, 8049, 8749 = 96 Byte
8040, 8050 = 224 Byte
1FR7'Register bank1 (PSW.4 = 1)
1ER6'Register bank1 (PSW.4 = 1)
1DR5'Register bank1 (PSW.4 = 1)
1CR4'Register bank1 (PSW.4 = 1)
1BR3'Register bank1 (PSW.4 = 1)
1AR2'Register bank1 (PSW.4 = 1)
19R1'Register bank1 (PSW.4 = 1)
18R0'Register bank1 (PSW.4 = 1)
17Stack Level 7 MSB (*) / RAMSP (PSW.0...PSW.2) = 7
16Stack Level 7 LSB (*) / RAMSP (PSW.0...PSW.2) = 7
15Stack Level 6 MSB (*) / RAMSP (PSW.0...PSW.2) = 6
14Stack Level 6 LSB (*) / RAMSP (PSW.0...PSW.2) = 6
13Stack Level 5 MSB (*) / RAMSP (PSW.0...PSW.2) = 5
12Stack Level 5 LSB (*) / RAMSP (PSW.0...PSW.2) = 5
11Stack Level 4 MSB (*) / RAMSP (PSW.0...PSW.2) = 4
10Stack Level 4 LSB (*) / RAMSP (PSW.0...PSW.2) = 4
0FStack Level 3 MSB (*) / RAMSP (PSW.0...PSW.2) = 3
0EStack Level 3 LSB (*) / RAMSP (PSW.0...PSW.2) = 3
0DStack Level 2 MSB (*) / RAMSP (PSW.0...PSW.2) = 2
0CStack Level 2 LSB (*) / RAMSP (PSW.0...PSW.2) = 2
0BStack Level 1 MSB (*) / RAMSP (PSW.0...PSW.2) = 1
0AStack Level 1 LSB (*) / RAMSP (PSW.0...PSW.2) = 1
09Stack Level 0 MSB (*) / RAMSP (PSW.0...PSW.2) = 0
08Stack Level 0 LSB (*) / RAMSP (PSW.0...PSW.2) = 0
07R7Register bank0 (PSW.4 = 0)
06R6Register bank0 (PSW.4 = 0)
05R5Register bank0 (PSW.4 = 0)
04R4Register bank0 (PSW.4 = 0)
03R3Register bank0 (PSW.4 = 0)
02R2Register bank0 (PSW.4 = 0)
01R1Register bank0 (PSW.4 = 0)
00R0Register bank0 (PSW.4 = 0)
(*) Stack LSB = PC.0 ... PC.7; Stack MSB = PC.8 ... PC.11 (Bit0 ... 3), PSW.4 ... PSW.7 (Bit4 ... 7)

2.2.5 Stack in internal RAM

The internal RAM contains a stack area of up to 16 bytes from address 0x08 to 0x17 for storing return addresses and PSW flags by the CPU.

The "CY", "AC", "F0" and "BS" flags (PSW.7 ... PSW.4) are stored in the RAM in the byte pair of the stack area addressed by the stack pointer (PSW.0 ... PSW.2) when a subroutine is called using a "CALL" command or an interrupt request, together with the current contents of the program counter (PC.0 ... PC.11).

The stack pointer in PSW.0 to PSW.2 is automatically incremented after executing a "CALL" instruction or an interrupt request, and decremented when executing a "RET" or "RETR" instruction. If the stack pointer overflows, it changes from the value 0x07 to the value 0x00 and, if it underflows, from the value 0x00 to the value 0x07.

When a "RETR" instruction is executed, the upper 4 bits of the PSW (PSW.4 ... PSW.7) saved on the stack are restored in addition to the program counter, which does not happen when a "RET" instruction is executed.

With the aid of the up to 16 bytes stack area, subroutines can be nested up to 8 times without causing a stack overflow and destroying the stack contents.

Unused stack locations are available for use as general RAM.

Contents of a stack byte pair:

BitStackOffset+0 (*)StackOffset+1 (*)
7PC.7PSW.7
6PC.6PSW.6
5PC.5PSW.5
4PC.4PSW.4
3PC.3PC.11
2PC.2PC.10
1PC.1PC.9
0PC.0PC.8
(*) StackOffset = StackPointer * 2 + 8

Example 1 :

PSW.2 = PSW.1 = PSW.0 = 0

StackOffset = 0 * 2 + 8 = RAM address 0x08

Example 2 :

PSW.2 = 0

PSW.1 = PSW.0 = 1

StackOffset = 3 * 2 + 8 = RAM address 0x0E

2.2.6 Timer/Counter

The "STRT CNT" instruction (opcode 0x45) starts the counter mode and the "STRT T" instruction (opcode 0x55) starts the timer mode. Both modes are stopped using the "STOP TCNT" instruction (opcode 0x65).

When the timer mode is started, the prescaler, which divides the frequency of the "ALE" signal by 32 (fprescaler = fosc / 480), is reset and its output is connected to the input of the timer/counter. Using the timer mode, times from t = 1 / fprescaler to t = 256 / fprescaler can be achieved by loading a suitable start value into the timer/counter register "T" using the "MOV T,A" instruction (opcode 0x62). Longer times are achieved by counting the overflows of the timer/counter register.

When the counter mode is started, the input of the timer/counter is connected to the T1 connection at pin 39 of the µC and high-to-low transitions occurring at T1 are counted by the timer/counter. T1 must assume a low level for at least the duration of one command cycle (t = 15 / fosc) and receive a high level after each low-to-high transition for at least the duration of one machine cycle (t = 3 / fosc). The maximum frequency of the signal at T1 is fcnt = fosc / 45. The counter contents can be preset with the "MOV T,A" instruction (opcode 0x62) and read with the "MOV A,T" instruction (opcode 0x42).

Each event in timer or counter mode (32 instruction cycles in timer mode or a high-to-low transition at T1 in counter mode) increments the RAM-independent hardware register "T". When "T" overflows from 0xFF to 0x00 the timer flag, which cannot be accessed except via the "JTF addr" instruction (opcode 0x16 addr), is set.

If the timer/counter interrupt was previously enabled by the "EN TCNTI" instruction (opcode 0x25) when the "T" register overflows, program execution continues at address 0x007 of the program memory. The timer/counter interrupt is disabled by the "DIS TCNTI" instruction (opcode 0x35). If an external interrupt request via *INT and a timer/counter interrupt occur at the same time, the external interrupt request is processed first and afterwards that of the timer/counter interrupt.

In addition to using the timer/counter interrupt to evaluate an overflow of the T register, the timer flag can also be polled cyclically in the user program using the conditional jump command "JTF addr" (opcode 0x16 addr). The timer flag is reset by executing the "JTF addr" instruction.

2.3.0 Minimal system with external program memory

8049 Minimalsystem mit externem EPROM
Image: This circuit allows execution of the MCS-48 program in the external EPROM 2732

ComponentFunction
8049Microcontroller
74LS373Latch for address lines A0...A7
273232 Kbit EPROM as program memory

2.4.0 DIP40 pin assignment, control signals, ports, timing

PinSignalFunction
1T0"Test0" input / "CLK" output
2XTAL1Oscillator connection 1
3XTAL2Oscillator connection 2
4*RESETInitialization input
5*SSSingle-Step input
6*INTExternal interrupt request
7EAEnable external access
8*RDRead access to data / IO
9*PSENRead access to program
10*WRWrite access to data / IO
11ALEActivate address latch
12D0"BUS" Address-/data bus, Bit0
13D1"BUS" Address-/data bus, Bit1
14D2"BUS" Address-/data bus, Bit2
15D3"BUS" Address-/data bus, Bit3
16D4"BUS" Address-/data bus, Bit4
17D5"BUS" Address-/data bus, Bit5
18D6"BUS" Address-/data bus, Bit6
19D7"BUS" Address-/data bus, Bit7
20VssGround connection, GND
PinSignalFunction
40Vcc+5V main supply
39T1"Test1"-/Counter-input
38P2.7Port2, Bit7
37P2.6Port2, Bit6
36P2.5Port2, Bit5
35P2.4Port2, Bit4
34P1.7Port1, Bit7
33P1.6Port1, Bit6
32P1.5Port1, Bit5
31P1.4Port1, Bit4
30P1.3Port1, Bit3
29P1.2Port1, Bit2
28P1.1Port1, Bit1
27P1.0Port1, Bit0
26Vdd+5V for RAM-Standby (*)
25PROGConnection to Portexpander (*)
24P2.3Port2, Bit3
23P2.2Port2, Bit2
22P2.1Port2, Bit1
21P2.0Port2, Bit0
(*) 8748, 8749: no RAM standby, pins 25, 26 are used for programming the EPROM

MCS-48 DIP40 Pinbelegung
Image: DIP40 package of the MCS-48 8035, 8039, 8048, 8049, 8748, 8749, 8040 and 8050 types

2.4.1 EA

If a logic high (+5V) is applied to the EA input (External Access) on pin 7 of the µC, all program memory accesses are executed with external memory units via ALE, *PSEN, BUS, P2.0, P2.1, P2.2 and P2.3, the internal program memory is deactivated.

2.4.2 *RESET

*RESET is a low-level active initialization input with Schmitt-Trigger properties and an in the µC integrated pull-up FET with approx. 80kOhm impedance on pin 4 of the µC. Must be activated at least 10ms after Vcc, Vdd and Vss are stable. Must be activated at least 5 command cycles (t = 75 / fosc) if the oscillator of the µC has already stabilized.

Activating the reset input creates the following state:

  1. PC = 0 (Program Counter)
  2. SP = 0 (Stack Pointer, S0, S1, S2)
  3. RB = 0 (Register Bank Flag)
  4. MB = 0 (Memory Bank Flip-Flop)
  5. P1 = P2 = Input Mode (Port1, Port2)
  6. Interrupts are deactivated (Timer/Counter and *INT)
  7. Timer/Counter is stopped
  8. Timer Flag = 0
  9. F0 = F1 = 0 (User Flag0, User Flag1)
  10. 10. Stops output of CLK (fosc/3) to T0 (Test0)

Due to the input's integrated pull-up FET, connecting it to an external 1µF capacitor is sufficient to realize a power-on reset in the minimum case.

2.4.3 *INT

*INT is a low-level active input for external interrupt requests on pin 6 of the µC. Must be activated for at least 3 instruction cycles (t = 45 / fosc) to ensure reliable detection of the interrupt request. After the µC has detected an interrupt request, PC and PSW are saved on the stack and PC is loaded with address 0x003 - even if the upper 2kB block 0x800 to 0xFFF is currently selected or prepared by a "SEL MB1" instruction. The "RETR" instruction must be used to return from the ISR.

After a reset, external interrupt requests are disabled and can be enabled by the "EN I" instruction (opcode 0x05). Even if external interrupt requests are disabled, the level at the *INT pin can be evaluated for conditional jumps using the "JNI" instruction. The detection of external interrupt requests can be disabled in software by executing the "DIS I" instruction (opcode 0x15).

If an external interrupt request via *INT and a timer/counter interrupt occur at the same time, the external interrupt request is processed first and afterwards that of the timer/counter interrupt.

2.4.4 ALE

The falling edge of the ALE output (Address Latch Enable) on pin 11 of the µC indicates that valid address information is present on BUS and can be used to store the address in a flip-flop. At the time of the rising edge of the ALE signal, the most recently written I/O information is always available at P2.0 to P2.3 and can be as well stored in a corresponding flip-flop.

Timing MCS-48 Instruction Fetch

2.4.5 *PSEN

The low-active *PSEN output (Program Store Enable) on pin 9 of the µC is used to read from an external program memory. When *PSEN=L the external program memory places the information on BUS, from where it is then transferred into the µC before the rising edge of *PSEN.

2.4.6 *RD

The low-active *RD output (Read) on pin 8 of the µC is used to read from an external unit (RAM / IO etc.). When *RD goes low, the external unit places the information on BUS, from where it is then transferred into the µC before the rising edge of the *RD signal. When EA=High, only the "MOVX A,@Ri" commands (1 byte, 2 cycles) can be used to generate the *RD signal.

Timing MCS-48 Data Read

2.4.7 *WR

The low-active *WR output (Write) on pin 10 of the µC is used to transfer information to an external unit (RAM / IO etc.). When *WR is low, the µC places the information to be transferred on BUS, where it is then stable at the rising edge of the *WR signal and stored by the external unit. When EA=High, only the "MOVX @Ri,A" commands (1 byte, 2 cycles) can be used to generate the *WR signal.

Timing MCS-48 Data Write

2.4.8 PROG

The falling edge of the PROG output on pin 25 of the µC indicates that a command code and a port address are being output at P2.0 to P2.3. The associated data is transferred into an external unit on the rising edge of the PROG signal or it is transferred into the µC before the rising edge of the PROG signal.

The command code is determined by the MCS-48 instruction The port address is determined by the port specified in this MCS-48 instruction
InstructionP2.3P2.2
MOVD A,Pp00
MOVD Pp,A01
ORLD Pp,A10
ANLD Pp,A11
pP2.1P2.0
400
501
610
711

During write accesses, the data corresponds to the lower nibble (bit0...bit3) of the accumulator or is transferred into the lower nibble of the accumulator during read accesses.

Timing MCS-48 Portexpander Read

Timing MCS-48 Portexpander Write

2.4.9 P1, P2

P1 and P2 are quasi-bidirectional, static input/output ports with 8 lines each. The quasi-bidirectionality is achieved by connecting a constantly active pull-up FET with approx. 8kOhm impedance to each port line and at the same time two FETs with low impedance that can set the port line to "0"- or "1"-level.

The FET for applying the "1"-level is active for approximately half a machine cycle (t = 1.5 / fosc) for each write-access with "1" in order to increase the edge steepness of a "0" to "1" transition, after which the "1"-level is maintained by the pull-up FET.

The FET for applying the "0"-level remains constantly active after a write access to a port line with "0" until a write access with "1".

In order to use a port line as an input, the corresponding output register must contain a "1" so that only the high-impedance pull-up FET is active and the port line can be pulled down to "0" by an external signal. It can be individually determined for each port line whether it should serve as an input or an output.

Timing MCS-48 P1, P2 Write

2.4.10 BUS

BUS is a bidirectional, static input/output port with 8 lines D0 to D7. When a write access is made with an "OUTL BUS,A" or "MOVX @Ri,A" instruction, the *WR line is activated (low), and its rising edge signals that valid data is on D0 to D7 and can be stored by an external unit.

During a read access by an "INS A,BUS" or "MOVX A,@Ri" instruction, the *RD line is activated (low) and before its rising edge the µC reads the information placed on D0 to D7 by an external unit.

Without additional hardware it is not permitted to execute "OUTL BUS,A" or "INS A,BUS" instructions when using an external program memory.

2.4.11 Timing

MCS-48 Timing

2.5.0 Logic-Analyzer Traces

MCS-48 Program-Memory access
Image: Access to external program memory

MCS-48 external RAM access
Image: Access to external RAM

MCS-48 PROG access
Image: Write access via "PROG" signal

MCS-48 Port Write
Image: Write access to Port1 and Port2

MCS-48 JMP / CALL address instructions
Image: Unconditional jump with "JMP" or "CALL"

MCS-48 RET instruction
Image: Executing a "RET" instruction

It is noteworthy that when a "RET" (Return from subroutine) instruction is executed, *PSEN (Program Store Enable) is activated (Low) for the second instruction cycle, even though it is a 1-byte instruction (meaning that nothing is read from the program memory in the second instruction cycle).

MCS-48 JMPP @A instruction
Image: Indirect jump on a 256byte page with "JMPP @A"

MCS-48 MOVP A,@A / MOVP3 A,@A instructions
Image: Reading constants from program memory with "MOVP A,@A" and "MOVP3 A,@A"

More extensive graphics with better quality can be found in the project's set of drawings.
(The download version of the documentation, available as a PDF, also offers better image quality.)