210911 001_i APX86_88_186_188_Programmers_Reference_1983 001 I APX86 88 186 188 Programmers Reference 1983

User Manual: 210911-001_iAPX86_88_186_188_Programmers_Reference_1983

Open the PDF directly: View PDF PDF.
Page Count: 550

Download210911-001_i APX86_88_186_188_Programmers_Reference_1983 210911-001 I APX86 88 186 188 Programmers Reference 1983
Open PDF In BrowserView PDF
iAPX 86, 88, 186 and 188 User's Manual

Programmer's Reference

May 1983

Intel Corporation makes no warranty for the use of its products and assumes no responsibility for any errors which may
appear in this document nor does it make a commitment to update the information contained herein.
Intel retains the right to make changes to these specifications at any time, without notice.
Contact your local sales office to obtain the latest specifications before placing your order.
The following are trademarks of Intel Corporation and may only be used to identify Intel Products:
BXP, CREDIT, i, ICE, 12 1CE, ICS, iDBp, iOIS, iLBX, i m , iMMX,
Insite, INTEL, intel, Intelevision, Intellec, inteligent Identifier'·,
intelBOS, inteligent Programming'·, Intellink, iOSP, iPDS,
iRMS, iSBC, iSBX, iSDM, iSXM, Library Manager, MCS,
Megachassis, Micromainframe, MULTI BUS, Multichannel'"
Plug-A-Bubble, MULTI MODULE, PROMPT, Ripplemode,
RMX/80, RUPI, System 2000, and UPI, and the combination of
ICE, iCS, iRMX, iSBC, MCS, or UPI and a numerical suffix.
MDS is an ordering code only and is not used as a product name or trademark. MDS® is a registered trademark of
Mohawk Data Sciences Corporation .
• MULTIBUS is a patented Intel bus.
Additional copies of this manual or other Intel literature may be obtained from:
Intel Corporation
Literatu re Department
3065 Bowers Avenue
Santa Clara, CA 95051

© INTEL CORPORATION.

1983

PREFACE
This manual describes the iAPX 86,88, and iAPX 186,188 family of microprocessor systems. It is divided into
two volumes.
Volume 1 is a general introduction and contains an overview of the CPUs along with some design information.
In addition, Volume 1 includes a general description of the 8087 numeric processor extension (NPX), the 8089
I/O processor (lOP), and the 80130 operating system firmware (OSF).
Volume 2 is a reference source, containing detailed hardware information on the major components making up
the systems, the various configurations available and implementation data. Volume 2 also includes the Device
Specifications and several Application Notes.
Volume 1 is divided as follows:
Chapter 1 introduces microcomputer concepts and associated terminology.
Chapter 2 is an-overview of the iAPX 86,88 and the iAPX 186,188 CPU family with its key features. It covers
the CPU Architecture, Memory, Interrupts, the 80186,188 extensions, and a short overview of the 8087, 8089,
and 80130 processors.
Chapter 3 provides a detailed discussion of the programmer's architecture including the EU and BIU, Register
Structure, Memory structure, I/O Port Organization, Addressing Modes, the Instruction Set and Programming
Examples.
Chapter 4 contains general information, on the block diagram level, needed by the hardware designer to incorporate the basic 8086 and 8088 microprocessors into microcomputer systems. Included is a discussion of the
Bus Structures, Multiprocessing and Processor Control.
Chapter 5 contains general information needed by the hardware designer to incorporate the 80186 and 80188
microprocessors into microcomputer systems. Included is a discussion of 8086,88 and 80186,188 Bus
Differences, Multiprocessing, Processor Control and the integrated peripherals of the 80186 and 80188
processors, such as Clock Generator, Chip Select/Ready Logic, DMA Channels, Timers and the Interrupt
Controller.
Chapter 6 describes the 8087 Numeric Processor Extension (NPX). Included is an overview of the processor,
the Architecture, Computational Fundamentals, the Instruction Set, and Programming Examples.
Chapter 7 describes the 8089 Input/Output Processor (lOP). It covers the Processor Overview, Architecture,
I/O, the Instruction Set, Addressing Modes, and Programming Examples.
Chapter 8 describes the 80130 Operating System Firmware (OSF) component. The chapter covers the
Architecture, Multitasking, Multiprogramming, Intertask Coordination, Dynamic Memory Relocation,
Extendability, the Primitives, and Programming Examples.
RELATED DOCUMENTATION

•

The iAPX 88 Book
Describes the Intel iAPX 88 (8088) microprocessor in detail.

•

The Peripheral Design Handbook
Contains data sheets and application notes featuring Intel peripheral devices.

•

The Intel Component Data Catalog
Contains data sheets for all Intel semiconductor components, including memories and peripherals.

•

ASM86 Language Reference Manual
Describes the assembly language for the 8086/8088 and the 8087.

I
l

PREFACE

•

ASM86 Language Reference Manual
Describes the assembly language for the 8086, 88/80186, 188 and the 8087.

•

iOSP 86 Support Package Reference Manual

These books, and other documentation, are available from
Literature Department
Intel Corporation
3065 Bowers A venue
Santa Clara, California 95051

THE INTEL MICROSYSTEM 80 NOMENCLATURE
AsInte]'sproduiCtline.h.JlseYoh'ed,.itscom.ponent~seQ-produtt-ffilffiBefiftg system has become inappropriate
for- all the-Possible VLSI computer solutions offered. While the components retain their names, Intel has
moved to a new system-based naming scheme to accommodate these new VLSI systems.

The following prefixes have been adopted for Intel's product lines, all of them under the general heading of Microsystem 80:
iAPX
iRMX
iSBC
iSBX

-

Processor Series
Operating Systems
Single Board Computers
MULTIMODULE Boards

In the iAPX Series, the following processor lines are currently defined:
iAPX
iAPX
iAPX
iAPX
iAPX

86
88
186
188
286

-

8086 CPU -based system
8088 CPU -based system
80186 CPU -based system
80188 CPU-based system
80286 CPU-based system

Configuration options within each iAPX system are identified by adding a numerical suffix, for example:
iAPX
iAPX
iAPX
iAPX

186110
186/11
186120
186121

iAPX 186/30
iAPX 186/40

-

CPU alone (80186)
CPU + lOP (80186 + 8089)
CPU with Math Extension (80186 + 8087)
CPU with Math Extension + lOP
(80186,8087 + 8089)
- CPU with Operating System Processor
(80186 + 80130)
- CPU with Math Extension + OSP
(80186,8087 + 80130)

This improved numbering system provides a more meaningful view of the capabilities of Intel's evolving Microsystem 80.

ii

:1

it

Table of Contents
CHAPTER 1
INTRODUCTION TO MICROCOMPUTERS
1.1 What is a Microcomputer? .................................... .
1.2 The CPU ................................................... .
1.3 Memory ................................. , .................. .
1.4 Input/Output or I/O Devices ................................... .
1.5 Data, Address and Control Busses ............................. ,
1.6 Bus Cycles ................................................. .
1.7 Interrupts ................................................... .
1.8 Direct Memory Access ....................................... .
1.9 Addressing Modes ........................................... .
1.10 Intel Microcomputer Components ............................ .

1 -1
1 -1
1 -1
1 -2
1 -2
1 -2
1 -3
1-3
1 -3
1 -3

CHAPTER 2
THE iAPX 86,88,186,188 FAMILY OVERVIEW
2.1 Introduction ................................................. 2-1
2.2 The CPU Architecture ......................................... 2-2
2.3 Memory Addressing .......................................... 2-7
2.4 Interrupts .................................................... 2-8
2.5 Minimum and Maximum Modes (8086,88 ONLY) ................. 2-10
2.6 The 80186,188 Extensions ................................... 2-10
2.7 The 8087 ................................................... 2-12
2.8 The 8089 I/O Processor (lOP) . , ............................... 2-13
2.9 The 80130 Operating System Firmware (OSF). . . . . . . . . . . . . . . . . .. 2-13

CHAPTER 3
THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS
3.1 Introduction ................................................. 3-1
3.2 CPU Architecture ................................ , ............ 3-1
3.3 Register Structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 3-3
3.4 Memory Structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 3-6
3.5 I/O Port Organ ization ....... "................................ 3-14
3.6 Addressing Modes ........................................... 3-15
3.7 The I nstruction Set ..... , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 3-19
3.8 8086,88 Programming Examples ............................. 3-171
3.9 80186,188 Programming Examples ........................... 3-191

CHAPTER 4
iAPX 86,88 HARDWARE DESIGN OVERVIEW
4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 4-1
4.2 Multiprocessing Features ..................................... 4-1
4.3 Interrupt Structure ..................... , , , , , , , .. , , , . , . , , . , . , ". 4-6

:1
: "!J
;r!

j

f
'~,

,;

,I
I ~,'~

I

,

TABLE OF CONTENTS

CHAPTER 5
iAPX 186,188 HARDWARE DESIGN OVERVIEW
5.1 Introduction ................................................. 5-1
5.2 80186 and 80188 CPU Enhancements .......................... 5-1
5.3 Bus Structure ................................................ 5-3
5.4 Interrupts .................................................... 5-5
5.5 Clock Generator. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 5-6
5.6 Internal Peripheral Interface ................................... 5-7
5.7 Chip Select Unit. ............................................. 5-8
5.8 DMA Controller. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 5-12

-

-

-~9

Hmer Unit -:-.:-:-. . -:-:- . ;-:-. .--:-.

.~

::-:-.-:-:-:

.~.
. .--:-:.

.-:-. . ~ . -:-:. . -:-: . -~ . -5-16

5.10 Interrup. ,ontroller ......................................... 5-18

CHAPTER 6
THE 8087 NUMERIC PROCESSOR EXTENSION
6.1 Introduction ................................................. 6-1
6.2 Processor Overview '" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 6-1
6.3 Processor Architecture ........................................ 6-7
6.4 Computation Fundamentals ................................... 6-12
6.5 Instruction Set .............................................. 6-20
6.6 Programming Facilities ....................................... 6-48
6.7 Special Topics .............................................. 6-57
6.8 Programming Examples ...................................... 6-69

CHAPTER 7
THE 8089 INPUT/OUTPUT PROCESSOR
7.1
7.2
7.3
7.4
7.5
7.6
7.7
7.8

Introduction ................................................. 7-1
Processor Overview ..................................... : .... 7-1
ProcessorArchitecture ....................................... 7-12
I nputlOutput. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 7-20
Instruction Set .............................................. 7-28
Addressing Modes ..............................•............ 7-35
Programming Facilities ..................................... " 7-46
Programming Considerations ................................. 7-58

CHAPTER 8
THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT
8.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 8-1
8.2 80130 OSF Overview ................................... , . . . .. 8-2
8.3 Architecture ................................................ , 8-2

TABLE OF CONTENTS

8.4 Multitasking ................................................. 8-3
8.5 Multiprogramming ............................................ 8-8
8.6 Intertask Coordination ........................................ 8-9
8.7 Dynamic Memory Allocation .................................. 8-13
8.8 Management of Objects ...................................... 8-15
8.9 Extendability ................................................ 8-22
8.10 OSP Primitives ............................................. 8-23
8.11 Adding iRMX 86 Features to the OSP ......................... 8-109

\

Introduction to
Microcomputers

1

CHAPTER 1
INTRODUCTION TO MICROCOMPUTERS
1.1 WHAT IS A MICROCOMPUTER?

CPU operations are controlled by a set of
instructions, called a program. Programs are stored in
the memory. Data is also kept in the memory and
processed according to programmed instructions.
The CPU reads in data and control signals
(instructions) through the input ports, executes one
instruction at a time, and sends data and control signals to the outside world through the output ports.

A microcomputer is a system of one or more integrated circuit devices, using semiconductor
technology and digital logic to implement large
computer functions on a smaller scale.
The Intel iAPX 86,88 and iAPX 186,188 family of
microprocessors, along with other closely related
Intel processors described in this manual, are essential functional blocks of such microcomputers.

A typical CPU consists of the following three functional units: the registers, the arithmetic/logic unit
(ALU), and the control circuitry. Each is briefly described below.

There are three main elements in a microcomputer.
These elements and their functions parallel those
found in all computers. Each has a special role to
play in the overall operation of the computer system.
The block diagram in Figure 1-1 shows these three
elements. They are the central processing unit (CPU),
the memory, and the input/output (I/O) devices or
ports.

Registers provide temporary storage within the CPU
for memory addresses, status codes, and other information useful during program execution. Different
microprocessors have different numbers and sizes
of registers. The Intel iAPX 86,88 and the iAPX
186,188 family of microprocessors have 16-bit
registers.

All CPUs contain an arithmetic/logic unit or ALU. The
ALU contains an adder to perform binary arithmetic
operations on the data obtained from memory, the
registers or other inputs. Some ALUs perform more
complex operations such as multiplication and
division. ALUs provide other functions as well,
including Boolean logic and data shifting.

1.2 THE CPU
The heart of the microcomputer system is the CPU.
It performs the numerical processing (additions,
subtractions, etc.), logical operations, and timing
functions.

CPU
MODULE

CONTROL BUS

Figure 1-1 Microcomputer Block Diagram

1-1

210911

INTRODUCTION TO MICROCOMPUTERS

The ALU also contains flag bits that signal the results
of arithmetic and logical manipulations such as sign,
zero, carry, and parity information.
The control circuitry coordinates all microprocessor
activity. Using clock inputs, the control circuitry
maintains the proper sequence of events required
for any processing task. The control circuitry
decodes the instruction bits and issues control signals
to units both internal and external to the CPU to perform the proper processing action.

The CPU uses the address bus to select the desired
memory or 110 device by providing a unique address
that corresponds to one of the memory or I/O elements of the system.
The control bus carries control signals to the memory
and I/O devices, specifying whether data is to go into
or out of the CPU, and exactly when the data is
being transferred.

1.6 BUS CYCLES
1.3 MEMORY

As the microcomputer program executes, data is
transferred to and from memory and 1/0 devices.
Each instance of data transfer from one part of the
system to another is called a bus cycle (or machine
eye/e). The timing of these cycles is done by the CPU
clock signal. Operations like instruction fetch,
memory read, memory write, read from an input
port, or write to an output port are operations taking
place in one or more bus cycles.

Microcomputers generally use semiconductor
devices to store programs and data. Two examples
of these are the RAM - Random Access Memory,
and the ROM - Read Only Memory. To expand
memory space, microcomputer systems often use
some kind of mass storage device such as floppydisks or magnetic tape.

1.4 INPUT/OUTPUT OR I/O DEVICES
I/O devices, also called peripherals, are the means by
which the the CPU communicates with the outside
world. In a typical microcomputer system with a
CRT terminal, the input ports (or channels) are connected to the keyboard, while the output ports are
connected to hardware that generates the characters
displayed on the screen.

The length of bus cycles is determined relative to the
frequency of a clock signal. Typical clock rates at
which microcomputers operate are 5, 8 and 10 MHz.
The 8 MHz versions of the Intel iAPX 86 and 186
have clock cycles of 125 nanoseconds (or .125
microseconds) .
At the beginning of a bus cycle, the CPU issues a
code to the address bus to identify the memory lOCation or I/O device to be accessed. Next, the CPU
issues an activity command on the control bus.
Third, the CPU either receives or transmits data
over the data bus.

The Intel 8089 Input/Output Processor (lOP) is a
special I/O device. This device handles the burden of
I/O processing, thus permitting greater CPU efficiency. Allowing the CPU to perform its tasks in parallel
with the I/O processor is a concept typical of large
mainframes that is here applied to microcomputers.

The CPU then performs the logical, arithmetic, or
I/O operations as required by the instructions.
The CPU keeps track of the instruction sequence
with the program counter register, which contains the
address of the next instruction in memory. In more
recent Intel CPUs, the term 'program counter' has
been is replaced by the term 'instruction pointer'.

1.5 DATA, ADDRESS AND CONTROL
BUSSES

Normally, the instruction pointer is incremented
after a given instruction is executed. The CPU automatically fetches .instructions from memory,
decodes them, and executes them in sequence until
the program ends, or until special instructions tell it
to execute instructions in other parts of program
memory.

The CPU is connected to memory and I/O by a set
of parallel wires or lines called a bus. As seen in
Figure I-I, there are three different busses that interface the CPU to other system components: the
data bus, the address bus and the control bus.
Data travels between the CPU, memory, and I/O
over the data bus. This data can either be instructions
for the CPU, or information the CPU is passing to or
from I/O ports. In the case of the 8088 and 188, the
data bus is 8-bits wide; in the 8086 and 186, the data
bus is 16-bits wide.

Certain situations can interrupt the normal sequential flow of instruction execution. For example, a
wait state may be imposed in a given bus cycle to provide more time for memory or an I/O device to com'
municate with the CPU. Wait states are needed
1-2

210911

INTRODUCTION TO MICROCOMPUTERS

Some peripheral devices transfer information to and
from memory faster than the CPU can accomplish
the transfer under program control. By using DMA,
the CPU allows the peripheral device to hold and
control the bus, transferring the data directly to and
from memory without involving the CPU itself.
When the DMA transfer is done, the peripheral
releases the hold request signal. The CPU then
resumes processing instructions where it left off.

when the rate of data transfer from memory is
slower than the rate at which the CPU requests it. In
such cases, the memory must request a wait state
when it receives the CPU signal that a memory read
or write operation has commenced. After the
memory responds, it signals the CPU to leave the
wait state and continue processing.

1.7 INTERRUPTS
1.9 ADDRESSING MODES

Another situation that alters sequential instruction
execution is an interrupt. For example, consider a
computer which is processing a large volume of
data, portions of which are to be output to a printer.
The CPU can send to the printer a given amount of
data in a single bus cycle, but the printer may take
several bus cycles to print the characters specified by
that data. Thus, the CPU must remain idle until the
printer can accept the next data. The interrupt capability permits the CPU to output to the printer and
then return to other data processing.

The address that the CPU provides on the address
bus selects one specific memory or 1/0 device from
all those available. This address can be generated in
different ways depending on the operation being
performed. The ways of generating these addresses
are called addressing modes.
In the simplest addressing mode, the desired data
item is contained within the instruction being
executed. In a more complex addressing mode, the
instruction contains the memory address of the data.
Or, the instruction may reference a CPU register
that contains the memory address of the data.

When the printer is ready to accept the next data
byte, it signals the CPU via a special interrupt control
line. When the CPU receives the interrupt signal, it
suspends the main program execution and automatically switches to the instructions that output to the
printer, after which the CPU continues with the
main program execution where processing was
suspended.

Finally, within some microprocessors, the instruction may tell the control circuitry to generate a complex address that is the sum of several address
components, such as multiple registers plus data contained in the instruction itself.

Often several interrupting devices share the same
CPU. In order to service all of them, interrupts can
be prioritized. When two or more interrupts occur
sim ultaneously, the one with the higher priority will
be serviced first.

Generally, the most powerful microprocessors are
the ones with the widest variety of addressing modes
available.

1.10 INTEL MICROCOMPUTER
COMPONENTS
1.8 DIRECT MEMORY ACCESS
Intel manufactures a complete line of microcomputer
components. These components constitute building
blocks, which can be tailored to fit the performance
needs of a particular application precisely. This
manual describes the following components: the
iAPX 86 (8086) CPU, the iAPX 88 (8088) CPU, the
iAPX 186 (80186) CPU, the iAPX 188 (80188)
CPU, the 8087 Numeric Processor Extension
(NPX), the 8089 1/0 Processor (lOP), and the
80130 Operating System Firmware (OSF).

Another feature that improves microprocessor efficiency is direct memory access, also called DMA.
In ordinary input/output operations, the CPU supervises the entire data transfer as it executes I/O instructions to transfer data from the input device to
the CPU, and then from the CPU to a specified
memory location. Similarly, data going from
memory to an output device goes by way of the CPU.

1-3

210911

The iAPX 86,88,186,188
Family Overview

2

I

i

I,

1.1

'1
l

I

!
"

CHAPTER 2
THE iAPX 86,88, 186,188 FAMILY OVERVIEW
2.1 INTRODUCTION

performance is realized by combining a 16-bit internal data path with a pipe lined architecture that
allows instructions to be prefetched during spare bus
cycles. A compact instruction format that enables
more instructions to be fetched in a given amount of
time also contributes to the performance.

The iAPX 86,88 and iAPX 186,188 family consists
of advanced, high-performance microprocessors.
The family includes general data processors (8086,
8088, 80186 and 80188), specialized coprocessors
such as the 8087 numeric processor extension
(NPX) and the 8089 I/O processor (lOP), as well as
the 80130 operating system firmware (OSF).

Software need not be written in assembly language.
These CPUs are designed to provide direct hardware
support for programs written in high-level languages
such as Pascal-86 and Intel's, PLlM-86. However,
routines with critical performance requirements that
cannot be met with a high-level language may be
written in ASM-86 (the 8086/80186 assembly
language) and linked with Pascal-86 or PLlM-86
code.

Four key architectural concepts shaped the microprocessor designs. All four reflect the family's role
as vehicles for modular, high-level language programming (in addition to assembly language
programming) .
The concepts are:
•
•
•
•

While these CPUs are totally new designs, they
make the most of the user's existing investments in
systems designed around the 8080/8085 microprocessors. Many of the standard Intel memory,
peripheral control, and communication chips are
compatible with the 8086,88 and the 80186,188.

Memory segmentation,
Operand addressing structure,
Operation register set, and
Instruction encoding scheme.

The iAPX 86,881186,188 memory segmentation
scheme is optimized for the reference needs of
computer programs, and is separate from the operand addressing structure.

Other important features of the family are, in the
case of the 8086 and 8088 CPUs, dual operating
modes (minimum and maximum) and built-in multiprocessing capability. The 80186 and 80188 CPUs,
on the other hand, integrate many key functions
including a programmable interrupt controller, chip
select logic, two high speed DMA channels, timers,
and a clock generator.

The structure for addressing operands within segments directly supports the various data types found
in high level programming languages.
An operation register set is provided to support
general computation requirements. It also provides
for optimized operation register sets to do specialized
data processing functions with its inherent multi'
and coprocessor support.

These characteristics, as well as others to be described in following chapters, make the iAPX 86,88,
186,188 family suitable for a wide spectrum of microcomputer applications. Systems can range from the
uniprocessor, minimal-memory designs implemented with a handful of chips (Figure 2-0 to multiprocessor systems with up to a megabyte of memory
(Figure 2-2).

The family uses optimized instruction encoding for
high performance and memory efficiency.
High-level languages using modular programming
have become the norm on large software development projects in the last decade. The iAPX
86,881186,188 microprocessor family with its
memory segmentation scheme is designed for modular programs. It supports the static and dynamic
memory requirements of program modules, as well
as their communication needs, The register scheme
employs specialized registers and implicit register
usage.

2.2 THE CPU ARCHITECTURE
The following sections of this chapter describe the
mainstays of the microprocessor family: the central
processing units. The internal operation of the CPU
and the interaction of the processors with other
devices are discussed in functional terms. Electrical
characteristics, timing, and other hardware related
information may be found in Volume 2 of this set.

These CPUs are substantially more powerful than
microprocessors previously offered by Intel. High
2-1

210911

"

THE iAPX 86,88,186,188 FAMILY OVERVIEW

"'''-

I"PORTA

•

•

•

8155
RAM

"0

TIMER

•

--'"

PORTS

.•

PORTe

.....- }CLOCK
---.... TIMER

ADDRESS

•
PORT A

•

4AODRESS/DATA

8088
CPU

••

CONTROL

8755A
EPROM

•
•

"0

4

PORTS

'---

•
•

r----->.

r-L-

4

8284
CLOCK
GEN

'"--

•
•

...

,j,.

8185
11< X 8

RAM

Figure 2-1 Small8088-Based System

I

I

110 DEVICES

t

4.

I

110 MAPPED
ROM. RAM

1

1/0 BUS

I

.J

8284
CLOCK GENERATOR

......

I

8089
'OP

Lt

I

I

8288
BUS CONTROLLER

...
I

II

......
8289

BUS ARBITER

•

I lJ

I
.j,.

I

'"

j,.

MUl TlBU.,! CONTROLS

II

t

TRANSCEIVERS
AND LATCHES

]J

I

MUL TlBUS'" SYSTEM BUS

-~

SYSTEM ROM, RAM

,a..

]J

I

T
8288
BUSCONTROLLER

.

I

"86
OR

'"

,
j,.

L

.J I

8284
CLOCK GENERATOR

TRANSCEIVERS
AND LATCHES

TRANSCEIVERS
AND LATCHES

t

LOCAL BUS

I'

......

LOCAL
RESOURCES

TRANSCEIVERS
AND LATCHES

t

]JI

.,88
CPU

.......
8Z89
BUS ARBITER

..J.

.....

J

Il

8288
8US CONTROLLER

J

~
~

MUL lIBU) CONTAOLS

Figure 2-2 8086/8088/8089 Multiprocessing System
2-2

210911

THE iAPX 86,88,186,188 FAMILY OVERVIEW

The BIU and EU
- Pipelined Architecture

Functional Units
Standard microprocessors execute a program by
repeatedly cycling through the steps shown in Figure
2-3. First, the microprocessor must fetch the instruction to be performed, then it executes the
instruction. Only after the execution is complete is
the CPU ready to fetch the next instruction, execute
that instruction, etc.

The CPUs have a separate bus interface unit (BIU),
whose only job is to fetch instructions from memory
and pass data to and from the execution hardware
and the outside world. Since the execution unit and
the bus interface unit are independent, the bus interface unit fetches additional instructions while the execution unit (sometimes called the EU) executes a
previously fetched instruction. This is made possible
by the instruction pipeline (or queue) between the
bus interface unit and the execution unit. The BIU
fills this pipeline with instructions awaiting
execution. Thus, whenever the execution unit
finishes executing a given instruction, the next instruction is usually ready for immediate execution
without delays caused by instruction fetching. Figure
2-5 shows parallel fetching and executing in these
CPUs.

The CPU hardware that executes instructions must
obviously wait until the instruction is fetched and
decoded before execution begins. Therefore, in standard microprocessors, the execution hardware
(primarily the control circuitry and the arithmetic
and logic unit) spends a lot of time waiting for instructions to be fetched. The 8086,88 and 80186,188
microprocessors eliminate this wasted time by dividing the internal CPU into two independent functional
units (see Figure 2-4).

FETCH
TIME

EXECUTE

FETCH

EXECUTE

FETCH· ••

-

Figure 2-3 Program Execution in Standard Microprocessor

EXECUTION
UNIT

~STRUCTION
PIPELINE

BUS
INTERFACE
UNIT

V
SYSTEM BUS
PIPELINED ARCHITECTURE PROVIDES PERFORMANCE WITH REDUCED BUS "DEAD TIME"

Figure 2-4 Pipelined Internal Architecture
2-3

210911

I

THE iAPX 86,88,186,188 FAMILY OVERVIEW

BIU

EU

WAIT

EXECUTE

EXECUTE

EXECUTE

Figure 2-5 Parallel Operation In CPU

Register Resources

Because the BIU is usually busy fetching instructions
for the pipeline, the bus is more fully utilized.
Another benefit of this parallel operation is that
since the execution unit seldom needs to wait for the
BIU to fetch the next instruction, there is less need
for the BIU to fetch data quickly. Maximum performance and processing power is thus achieved without high speed memory devices in the system.

Figure 2-7 gives an overview of the registers available in the 8086,88 and 80186,188 CPUs. These
CPUs have fourteen 16-bit registers. The registers
are grouped into general, control and segment
registers.
General registers are analogous to the accumulators
of first and second generation microprocessors.
They are, in turn, grouped into data, index and
pointer registers. The function of all registers is described in more detail in the following paragraphs.

This parallel operation of the BIU and EU is transparent to the user, except when program execution
transfers to a new, non-sequential address. When
this happens, the bus interface unit is given the new
address by the execution unit; it then begins fetching
instructions sequentially from the new address. The
execution unit must wait for the next instruction to
be fetched the way most CPUs wait for every instruction to be fetched. After the first instruction is
fetched from the new location, the bus interface unit
continues to fill the pipeline with instructions, and
fetch-time becomes transparent.

Data Registers
The data registers are unique in that their upper and
lower halves are separately addressable. This means
that each data register can be used interchangeably
as a 16-bit register, or as two 8-bit registers. In their
16-bit form, the data registers are the AX, BX, CX
and DX registers (Figure 2-8). For 8-bit operations,
they are divided into high byte and low byte. AH is
the high byte of the AX register, AL is the low byte
of the AX register, and so on. As mentioned, these
registers have general usage for arithmetic and logical operations.

Bus Structure
A summary of the iAPX 86,88 and iAPX 186,188
bus structure is shown in Figure 2-6. There are two
types of buses: system and local. Both buses may be
shared by multiple processors, i.e., both are multimaster buses. Microprocessors are always connected to a local bus, and memory and I/O components
usually reside on a system bus. The 8086,88 and
80186,188 bus interface components link a local bus
to a system bus.

Some registers have additional special functions,
which are performed in the execution of certain
instructions. For example, the CX register is frequently used to contain a count value during repetitive instructions, and the BX register is used as a
base register in some of the more powerful addressing modes. This implicit use of registers allows a
very compact instruction encoding.
2-4

210911

THE iAPX 86,88,186,188 FAMILY OVERVIEW

1-------------.
I
I

----.-------------------------------------------.
I

I

!

I...... , . .

PR'VATE
MEMORY

I

I

r-------j

:

:

I

PR'VATE

:

'/0

'"

~"';,_

11:1-

O-~

I

l..6.....
"11

...

:
:
:. ______ J

I

MODULE

:

PUBLIC
MEMORY

I

.. ~;

I
I
I

I
I

~

! I :--------

1--------0

PROCESSING

I
I
I
I
1I ______ - ______ 1I

I
I
I
I
I
I
I

.--------;
I
I
II
I

..J
I.,.

BUS

BUS
INTERFACE
GROUP

PROCESSOR

INTERFACE
GROUP

I

L__• ___ !

T

1

...
..
LOCAL BUS

:---.Y---1
I

I

:
PROCESSING
MOOULE

:

:
PROCESSOR

I
I
I

L _______

i------------"i

I
I

I
I

I

:

I

I
I
!I

• .,.

I

I
I
I

I

I

________________________________________________ JI

I
I

~

I
I

PROCESS'NG
MODULE

I
:

I
I
I

:-------------~

Figure 2-6 Generalized iAPX 86/186 Bus Structure

GENERAL
REGISTERS

~
f POINTER j
REGISTERS
f CONTROL j} CONTROL

f

~

INDEX

SEGMENT

1}

AH

AL

AX

BH

BL

BX

.~

i1
'I

~

SEGMENT
REGISTERS

Figure 2-7 CPU Register Set

CH

CL

CX

DH

DL

OX

iJ
.~

Figure 2-8 Data Group Registers
2-5

210911

THE iAPX 86,88,186,188 FAMILY OVERVIEW

The two index registers are the SI (source index)
register and the DI (destination index) register
(Figure 2-9). These are both 16-bits wide and are
used by string manipulation instructions and in
building some of the ·more powerful 8086,88 and
80186,188 data structures and addressing modes.
Both the S.I and the DI registers have autoincrementing and auto-decrementing capabilities.

Pointer and Index Registers
Figure 2-9 shows the pointer and index registers.
The BP and SP registers both point to the stack, a
linear array in the memory used for subroutine
parameters, subroutine return addresses, or other
data temporarily saved during execution of a
program.
Most microprocessors have a single stack pointer
register called the SP. The 8086,88 and 80186,188
have an additional pointer into the stack called the
BP (base pointer) register. While the SP is used
similarly to the stack pointer in other machines (for
pointing to subroutine and interrupt return
addresses), the BP register can contain an old stack
pointer value, or it can mark a place in the subroutine stack independent of the SP register. Using the
BP register to mark the stack saves the juggling of a
single stack pointer to reference subroutine parameters and addresses.

BP & SP FOR
STACK PARAMETER
PASSING

SI & 01 FOR
STRING MANIP. &
DATA STRUCTURES

All base and index registers have general arithmetic
and logical capabilities in addition to their special
functions.

Control Registers
The control registers consist of two special purpose
registers, the IP or instruction pointer and the Status
Word or Flags register (see Figure 2-10). The IP is
similar to a Program Counter used in some
microprocessors, except that the IP points to the
next instruction to be fetched (by the BIU), whereas
the traditional program counter points to the next instruction to be executed. For 8086/186 instructions
that manipulate the IP, however, its contents are adjusted to point to the next instruction to be executed.

~
~
~
~

The Status Word or Flags register contains the flags
or condition codes that reflect the results of arithmetic or logical operations as they are performed by
the execution unit. (On the 8086,88 this register is
referred to as the Flags register; on the 186,88 it is
referred to as the Status Word register. The contents
of the register is the same in both cases.) The condition codes are described in detail in Chapter 3 of this
volume.

THESE CAN ALSO BE USED AS GENERAL
REGISTERS

Figure 2-9 Base and Index Registers

INSTRUCTION
POINTER

STATUS WORD
OR FLAGS

IP

I

I
Figure 2-10 Control Registers

2-6

210911

THE iAPX 86,88,186,188 FAMILY OVERVIEW

Every 20-bit memory address points either to program code, data, or stack area in memory (Figure
2-12). Each of the four different memory spaces is
pointed to by one of segment base registers (Figure
2-13). The code segment register points to the base
of the program currently executing, the stack segment register points to the base of the stack, the data
segment register points to the base of one data area,
and the extra segment register points to the base of
another area where data may be stored.

Segment Registers
Four 16-bit special purpose registers, called segment
registers, are provided in a segment register file.
They are the code segment (CS), stack segment
(SS), data segment (DS) and extra segment (ES).
Segment registers are used by the 8086,88 and
80186,188 in the formulation of memory addresses.
Their usage is described in the following section on
memory addressing.

2.3 MEMORY ADDRESSING
Memory is organized in sets of segments. Each segment consists of a linear sequence of up to 64K
bytes. These bytes are stored sequentially from byte
00000 to byte FFFFF hex. The memory is addressed
using a two-compomint address (a pointer) that consists of a 16-bit segment base (specifying the beginning address of the segment in memory) and a
16-bit offset (specifying the address relative to the
beginning of the segment). The base values are contained in one of the four internal segment registers
(CS, DS, SS, ES). A 20-bit physical memory address
is calculated by shifting the base value in the appropriate segment register left by four bits and
adding the 16-bit offset value to it (Figure 2-11).
This form of addressing allows access to one million
bytes of memory.
15

I

0
LOGICAL ADDRESS

l~bb~i1s
CONTENTS OF SEGMENT REGISTERS
POINT TO THE BASE ADDRESS OF THE
CORRESPONDING AREAS IN MEMORY.
Figure 2·12 Segment Registers

15
EGMENT REGISTER

SEGMENT

j-..l-_ _...JADDRESS

IMPLICIT
SELECTION
CODE
STACK
DATA

I

~""S-E-G-M-EN-T""'I

+

EXTRA

o

19

SEGMENT
REGISTERS

20-BIT
PHYSICAL MEMORY ADDRESS

Figure 2·11 Memory Addressing

20 BIT
PHYSICAL
ADDRESS

Figure 2·13 How an Address Is Built

2-7

210911

THE iAPX 86,88,186,188 FAMILY OVERVIEW

Figure 2-14 shows how an entire process, consisting
of code, stack and data areas, can be reloc~ted.
Likewise, in a reentrant program, a single program
uses multiple data areas. Before the reentrant code is
entered the second time, the data segment register
value is changed so that a different data area is made
available to the program.

Generating Addresses
Each time the CPU needs to generate a memory
address, one of the s'egment registers is automatically chosen and its contents added to a logical address.
For an instruction fetch, the code segment register is
automatically added to the logical address (in this
case, the contents of the instruction pointer) to compute the value of the instruction address.

Addressing Modes

For an instruction referencing the stack, the stack
segment register is automatically added to the logical
address (the SP or BP register contents) to compute
the value of the stack address.

The 8086,88 and 80186,188 provide 24 different
addressing modes. Various logical address combinations are shown in Figure 2-15, from the simplest immediate data mode to the register addressing mode,
where a selected register contains the data being
used by the instruction. In the direct addressing
mode, the instruction itself contains the address of
the data. In the register indirect mode., the instruction points to a register containing the memory address of 'the desired data. There are both indexed
and based addressing modes where the contents of
an index or base register is added to an immediate
data value contained in the instruction to form the
memory address.

For a data reference operation, where either the data
or extra segment register are chosen as the base, the
logical address can be made up of many different
types of values: it can be simply the immediate data
value contained in the instruction, or it can be the
sum of an immediate data value, plus a base
register, plus an index register. Generally, the selection of the DS or ES register is made automatically,
though provisions do exist to override this selection.

Since logical addresses are 16-bits wide, up to 64K
(65,536) bytes in a given segment may be addressed
without changing the value of the segment base
register. In systems that use 64K or fewer bytes of
memory for each memory area (code, stack, data
and extra), the segment registers can be initialized
to zero at the beginning of the program and then
ignored, since zero plus a 16-bit offset yields a 16-bit
address. In a system where the total amount of
memory is 64K bytes or less, it is possible to set all
segment registers equal and have fully overlapping
segments.

Exactly how the 8086,88 and 80186,188 select an addressing mode for a given instruction is encoded
within the bits of the instruction code. This is' described in more detail in Chapter 3.

2.4 INTERRUPTS
The interrupt system of the 8086,88 and 80186,188
is simple but versatile. Interrupts may be triggered
by devices external to the CPU or by software interrupt instructions or, under certain conditions, by the
CPU itself.

Segment registers are also very useful for large programming tasks, which require isolation of program
code from the data area, or isolation of module data
from the stack information, etc.

Segmentation makes it easy to build relocatable and
reentrant programs. In many cases, the task of
relocating a program (relocation means having the
ability to run lne same program in several different
areas of memory without changing addresses in the
program itselO simply requires moving the program
code and then adjusting the code segment register to
point to the base of the new code area. Since programs can be written for the 8086,88 or 80186,188 in
which all branches and jumps are relative to the instruction pointer, it does not matter what value is
kept in the code segment register.

2-8

Every interrupt is assigned a type code that identifies
it to the CPU. The type code is used by the CPU to
point to a location in the memory based interrupt
vector table containing the address of the interrupt
routine. This interrupt vector table can contain up to
256 vectors for different interrupt types.
Interrupts 0-31 are reserved by Intel
The following sections provide a general introduction to interrupt processing for the 8086,88 and
80186,188 CPUs. For more detailed information,
see Chapter 4, Section 4.3 (8086,88) and Chapter 5,
Section 5.4 (80186,188).
210911

THE iAPX 86,88,186,188 FAMILY OVERVIEW

CODE

CODE

STACK

STACK

DATA

DATA

EXTRA

EXTRA

TO RELOCATE AN ENTIRE PROCESS MOVE THE CODE,
STACK, AND DATA, AND UPDATE THE SEGMENT REGISTER
CONTENTS TO POINT TO THE NEW AREAS.

Figure 2-14 Process Relocation

MODE

LOCATION OF OATA

IMMEDIATE

WITHIN INSTRUCTION

REGISTER

IN REGISTER

DIRECT

AT MEMORY LOCATION POINTED TO BY ADDRESS CONTAINED IN
INSTRUCTION.

REGISTER INDIRECT

AT MEMORY LOCATION POINTED TO BY ADDRESS CONTAINED IN
REGISTER.

INDEXED OR BASED

AT MEMORY LOCATION POINTED TO BY SUM OF INDEX REGISTER
OR BASE REGISTER CONTENTS AND IMMEDIATE DATA CONTAINED
IN INSTRUCTION.

BASED AND INDEXED
WITH DISPLACEMENT

MEMORY ADDRESS IS SUM OF BASE REGISTER CONTENTS AND
INDEX REGISTER CONTENTS AND IMMEDIA TE DATA

THE LOCATION OF OAT A IS REALLY THE LOGICAL ADDRESS. WHICH IS ADDED TO THE SEGMENT
REGISTER VALUE TO FORM THE PHYSICAL MEMORY ADDRESS.
.

Figure 2-15 iAPX 88 Addressing Modes

2-9

210911

THE iAPX 86,88,186, 188 FAMILY OVERVIEW

External Interrupts
The 8086,88 have two inputs that may be used by external devices to signal interrupts, the INTR
(Interrupt Request) line, and the NMI (NonMaskable Interrupt) line. The INTR line is usually
driven by a PIC, such as Intel's 8259A Programmable Interrupt. Controller, which in turn is connected
to the devices that need interrupt service.
The 80186,188 have five inputs for use by external
devices to signal interrupt requests: the four INT
lines (INTO-INT3) and the NMI line. Two of the
INT lines may function as dedicated interrupt acknowledge outputs. This capability is included to
allow external expansion of the PIC using multiple
8259As (see Chapter 5, Section 5.10, for a detailed
discussion of this facility).
On both the 8086,88 and 80186,188 CPUs, the NMI
input line is generally used to signal the CPU of a
"catastrophic" event, such as imminent loss of
power, memory error, or bus parity error. Interrupt
requests arriving on the NMI caimot be disabled.
They are latched by the CPU, and have higher priority than an interrupt request on INTR or INTO-3.

Internal Interrupts

this mode, the CPU itself generates all bus control
signals and the command output signal. It also provides a mechanism for requesting bus access that is
compatible with bus master type controllers.
In the maximum mode (typically used for multiple
board systems), an Intel 8288 Bus Controller is
added to provide a sophisticated bus control function
and compatibility with the Multibus architecture. In
this mode, the bus controller, rather than the CPU,
provides all bus control and command outputs, and
allows pins previously delegated to these functions
to be redefined to support multiprocessing
functions. This mode is also required to support processor extensions, i.e., the 8087 Numerical Processor
Extension, the 8089 Input/Output Processor, and
the 80130 Operating System Firmware.

2.6 THE 80186,188 EXTENSIONS
The 80186 and 80188 CPUs integrate, in addition to
the features of the 8086 and 8088 CPU s, a chip-select
logic unit, two independent high-speed DMA
channels, three programmable timers, a programmable interrupt controller and a clock generator (see
Figure 2-16). These extensions are discussed in
Chapter 5.

Internal interrupts are generated by two instructions
(INT and INTO), by conditions resulting from the
execution of two instructions (DIV, IDIV), and by
most instructions when the Single Step flag in the
Flags or Status Word register is set. In addition to all
these, the 80186,188 provide interrupts generated
by the integrated peripherals (see Section 2.6), by
two instructions (ESC and BOUND) and by the occurrence of undefined opcodes.

The register set of the 80186,188 is identical to that
of the 8086,88 with the minor exception that the
8086,88 Flags register is referred to as the Status
Word register in the 80186,188; the contents of the
two registers is the same. The 80186,188 is object
code compatible with the 8086,88 and adds ten additional instruction types to the existing 8086,88 instruction set.

A detailed discussion of interrupts is included in
Chapters 4 and 5, which deal with the 8086,88 and
the 80186,188 respectively, as well as in Volume 2 of
this set, which covers the hardware details of interrupts for both CPUs.

Integrated Peripherals

2.5 MINIMUM AND MAXIMUM MODES
(8086,88 ONLY)
A unique feature of the 8086,88 CPUs is the ability
of a user to define a subset of the CPU's control
signal outputs to tailor it to its intended system
environment.
In the minimum mode, the CPU supports small,
single-processor systems (usually single board) that
consist of a few devices, and that use a local bus
rather than support the M ultibus architecture. In

All the 80186,188 CPU integrated peripherals are
controlled by 16-bit registers contained in a 256-byte
control block, which may be mapped into either the
memory or I/O space. A 16-bit relocation register
within this control block contains the base
addresses. The integrated peripherals operate semiautonomously from the CPU.

The 80186,188 Chip-Select LogiC
The chip-select logic provides programmable chipselect generation for both memories and peripherals.
Six memory chip-select outputs are provided for 3
address areas: upper memory, lower memory, and
midrange memory. The range of each chip-select is
2-10

210911

THE iAPX 86,88,186,188 FAMILY OVERVIEW

CLOCK

ENHANCED
8086-2 or
8088-2
CPU

INTERRUPTS

TIMERS

INTERNAL BUS

DMA
CHANNELS

Figure 2-16 iAPX 186,188 Block Diagram

user programmable. The 80186,188 can also generate chip-selects for up to seven peripheral devices.

Timers
The 80186,188 include three internal 16-bit programmable timers. Two of these are highly flexible
and are connected to external pins. They can be used
to count external events, time external events,
generate nonrepetitive waveforms, etc. The third
timer is not connected to external pins, and is useful
for real-time coding and time delays.

In addition, the chip-select logic can be programmed
to provide READY (or WAIT state) generation.

DMA Channels
The 80186,188 DMA controller provides two independent high-speed DMA channels. This controller
can transfer data between memory and I/O, between
memory and memory, or between I/O and I/O. Data
can be transferred in bytes or in words (bytes only in
the case of the 188) and may be transferred to or
from even or odd addresses. The channels maintain
both a 20-bit source and destination pointer which
can be optionally incremented or decremented after
each data transfer.
Each DMA channel has six registers in the control
block defining the channels specific operation. The
channels may be programmed to always give priority
to one channel over the other, or they may be programmed to alternate cycles when both have DMA
requests pending.

The timers are controlled by eleven 16-bit registers
in the internal peripheral control block. A timer
mode/control register within this block allows the
user to program the specific mode of operation or
check the current programmed status for any of the
timers.
Each timer has a 16-bit count register, the current
contents of which may be read or written to by the
CPU at any time.

Interrupt Controller
The 80186,188 can receive interrupts from a
number of sources, both internal and external. The
2-11

210911

THE iAPX 86,88,186,188 FAMILY OVERVIEW

internal interrupt controller serves to merge these
requests on a priority basis, for individual service by
the CPU.
The interrupt controller has its own control
registers,used to set the mode of operation for the
controller. Internal interrupt sources can be disabled
by their own control registers or by mask bits from
the interrupt controller.
The interrupt controller resolves priority among
simultaneously pending requests. Nesting is
permitted, i.e., interrupt service routines may be interrupted by those of equal or higher priority.
If interrupts are undesirable, the controller may be
used in a polled mode. When polling, the processor
disables interrupts and then simply polls the interrupt controller (rather than the individual interrupt
sources) whenever it is convenient.

2.7 THE 8087
The 8087 Numeric Processor Extension (NPX) performs arithmetic and comparison operations (using
80-bit internal registers) on a variety of numeric
data types. It also executes numerous built-in transcendental functions such as log, tangent, etc. In conjunction with the maximum mode 8086,88 CPUs, or
the 80186,188 CPUs, the NPX effectively extends
the register and instruction sets of the host CPU and
adds several new data types as well. The 8087 block
diagram is shown in Figure 2-17.

The 8087 uses the standard iAPX 86/186 family instruction set plus over fifty numeric instructions.
Programs can be written in ASM-86 assembly
language, or in the Intel high-level languages
PLlM-86, Fortran-86 and Pascal-86. From the standpoint of the programmer the NPX is not perceived
as a separate device; instead, the computational abilities of the CPU appear greatly expanded.

Clock Generator
The 8087 adds extensive high-speed numeric processing capabilities to the CPU. It conforms to the
IEEE format for single- and double-precisiOri floating
point numbers. Even for programmers who are not
expert in the problems of numerical analysis (for
instance, the accumulation of rounding errors which
may result from a long chain of floating point
calculations), the 8087 will provide correct results,
and is straightforward and easy to program. Chapter
6 of this volume describes the software aspects of
the 8087; Chapter 3 of Volume 2 covers the
hardware.

The on-chip clock generator provides both internal
and external clock generation. It includes a crystal
oscillator, a divide-by-two counter, synchronous
and asynchronous ready inputs, and reset circuitry.
The oscillator circuit is designed to operate with a
parallel resonant fundamental mode crystal. The
crystal frequency is double the CPU clock frequency.
An external oscillator may be used instead of the
crystal, which may be connected directly to the XI
input in lieu of a crystal, with X2 left open.

HOST CPU (8086
ExeCUTION
UNIT

I
I
I
I

I

or 8088)

NUMERIC DATA PROCESSOR (8087)
flOATING POINT EXECUTION UNIT

I

j

INSTRUCTIONS
DATA

I

I

DATA
BLOCK

I

~

I

v

I

I
I
I

I

BUS INTER FACE UNIT

BUS
INTERFACE
UNIT

ADOR ESS/ST ATUS

ADDRESSING

I
I

AND
BUS TRACKING

-v

OPERAND
QUEUE

I
I
I

k=::>

CONTROL
UNIT

I

J

ALU

I
I

I

I

I

Figure 2-17 Numeric Data Processor Block Diagram

2-12

210911

THE iAPX 86,88,186,188 FAMILY OVERVIEW

2.8 THE 8089 1/0 PROCESSOR (lOP)

2.9 THE 80130 OPERATING SYSTEM
FIRMWARE (OSF)

The 8089 Input/Output Processor is a highperformance, general purpose I/O system on a chip
(see Figure 2-18). It is an independent microprocessor that optimizes input/output operations. It is designed to remove all I/O details from applications
software. Responding to the CPU direction, but execu ting its own instruction stream in parallel with
other processors, it can transfer 16-bit data at rates
up to 1.25 megabytes per second.
In conjunction with the 8086,88, the 8089 combines
the attributes of both a CPU and a DMA controller
to provide a powerful I/O subsystem. I/O subsystem
changes or upgrades can be made without impact to
application software.
The CPU communicates with the lOP in two modes:
initialization and command. The lOP has two independent channels, each with its own register set,
channel attention, interrupt request and DMA control signals.
Programs are written in ASM-89, the 8089 assembly
language. About 50 basic instructions are available,
including general purpose instructions similar to
those found in CPU s as well as instructions specifically tailored for I/O operations.
In the case of the 80186,188 and 8089 combination,
the 8089 is used in the remote mode only. This is described in Chapter 7 of this manual; hardware considerations are in Volume 2, Chapter 4.

The 80130 firmware (software in silicon) is, in conjunction with the 8086,88 or 80186,188 CPUs, the
nucleus of a real-time, high-performance multitasking operating system. The 80130 adds task
management, interrupt management, message
passing, synchronization and memory allocation
capabilities to the CPU. A block diagram of the OSF
is shown in Figure 2-19.
The 80130 OSF has five operating system data types:
jobs, tasks, segments, mailboxes and regions. To
create, manipulate and delete these data types, the
80130 uses 35 operating-system instructions or
primitives. Programs using the 80130 primitives may
be written in ASM-86, PLlM-86, Fortran-86 or
Pascal-86.
The OSF contains a 16-bit operating-system, a programmable interrupt controller, delay timers, and a
variable baud-rate generator, thus replacing about
10 LSI ICs in a system. It is connected directly to the
multiplexed address/data bus of the 8086,88 or
80186,188 CPUs.
Scheduling of tasks is based on priority. Each task is
given a priority and interrupt level relative to other
tasks when created, but priorities may be altered
dynamically. The design approach used in the 80130
OSF is one common to mini and mainframe
computers.
The 80130 OSF is described in detail in Chapter 8;
hardware considerations are found in Chapter 5,
Volume 2.

HOST CPU (8086 or 8088)
EXECUTION

UNIT

I
I

BASE
INTERFACE
UNIT

PERIPHERALS
1/0 PROCESSOR (8089)

CRT'S
PRINTERS

DISKETTES

PRIVATE MEMORY
PUBLIC MEMORY

CHANNEL 1 PROGRAM

PROGRAM

CHANNEL 2 PROGRAM
DATA

Figure 2-18 1/0 Processor Block Diagram
2-13

210911

THE iAPX 86,88,186,188 FAMILY OVERVIEW

HOST CPU (8086,88,186,188)

EXECUTION UNIT

BUS
INTERFACE UNIT

r-l

CONTROL
UNIT

A

.

LOGIC

I

...A

A

.

INTERRUPT

ADDR/DATA BUS

I--

"
...A
STATUS/CONTROL BUS

H

SYSTEM
TIMER

H

DELAY
TIMER

H

BAUD RATE
GENERATOR

L

SYSTEM

L

DELAY

I

BAUD RATE

I

V

I

KERNAL CONTROL STORE

J

J

J

Figure 2-19 80130 (OSP) Block Diagram

2-14

210911

The iAPX 86,88 and
iAPX 186,188
Architecture and
Instructions

3

:/1

i
:~

;1
..

,I····.·

'i
:1~
I

;']

CHAPTER 3
TH E iAPX 86,88 and iAPX 1 86,1 88
ARCHITECTURE AND INSTRUCTIONS
3.1 INTRODUCTION

3.2 CPU ARCHITECTURE

This chapter describes the programmer's architecture of the iAPX 86,88 and iAPX 186,188 CPUs. It
is divided into the following sections:

The two independently operating functional units of
the CPU, the BIU and EU, are able, under most
circumstances, to extensively overlap instruction
fetch with execution. The result is that, in most
cases, the time normally required to fetch instructions "disappears" because the EU executes instructions that have already been fetched by the BIU.
Figure 3-1 illustrates this overlap and compares it
with traditional microprocessor operation. In the
example, overlapping reduces the elapsed time required to execute three instructions, and allows two
additional instructions to be pre fetched as well.

•
•
•
•
•
•
•

CPU Architecture
Register Structure
Memory Structure
I/O Port Organization
Addressing Modes
Instructio n Set
Programming Examples

f--~~~~~~~~~-ELASPEDTIME~~~~-------__
..

SECOND{ CPU
GENERATION
MICROPROCESSOR
BUS:

BOBS/BOBB
MICROPROCESSOR

BIU:

[~~)1~J~J

(FE~QH J I: FETCH 1

BUS:~

Wc'tff»J

[*~Tt~

,,\,IHTE
~

t~XECUTE 1 I FETCH I ~

hEICH)

~

I

EXECUTE

I

ltlli:]

~ ~ ~ ~ ~
INSTRUCTION STREAM

~
I 1i.J

1st INSTRUCTION (ALREADY FETCHED):
EXECUTE AND WRITE RESULT

2nd INSTRUCTION:
EXECUTE ONLY

c:i]

3rd INSTRUCTION:
READ OPERAND AND EXECUTE

iii

4th INSTRUCTION:
(UNDEFINED)

Ia

5th INSTRUCTION:
(UNDEFINED)

Figure 3-1 Overlapped Instruction Fetch and Execution
3-1

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

Execution Unit

Bus Interface Unit

In the execution unit, a 16-bit ALD maintains the
CPD status and control flags, and manipulates the
general registers and instruction operands. All registers and data paths within the ED are 16 bits wide
(Figure 3-2).

The BIDs of the 8088/80188 and the 8086/80186 are
functionally identical, but are implemented differently to match the data path size of their buses, which
are 8 bits and 16 bits respectively.
The BID performs all bus operations for the ED.
Data is transferred between the CPD and memory
or I/O devices upon demand from the ED.
In addition, during periods when the ED is busy executing instructions, the BID "looks ahead" and
fetches more instructions from memory. The instructions are stored in an internal RAM array called
the instruction stream queue. The 8088/80188 instruction queue holds up to four bytes of the instruction stream, while the 8086/80186 queue can store
up to six instruction bytes. These queue sizes keep
the ED supplied with prefetched instructions under
most conditions without monopolizing the system
bus.

The ED has no connection to the system bus, the
"outside world." It obtains instructions from a
queue maintained by the BID. Likewise, when an instruction requires access to memory or to a peripheral device, the ED requests the BID to fetch or store
the data. All addresses manipulated by the ED are
16 bits wide. However, the address relocation facility
provided by the BID provides the ED with access to
a full megabyte of memory space.

A

,...

EXECUTION UNIT (EU)

BUS INTERFACE UNIT (BIU)

GENERAL
REGISTERS

SEGMENT
REGISTERS

It It

I

OPERANDS

t t

Dt

ALU

I

INSTRUCTION
POINTER

t
ADDRESS
GENERATION
AND BUS
CONTROL

I

I
I
I

I
I

MULTIPLEXED BUS

.... ,...
INSTRUCTION
QUEUE

I

FLAGS

Figure 3-2 Execution and Bus Interface Units (EU and BIU)
3-2

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

The data registers can be used in most arithmetic
and logic operations. Some instructions (e.g. string
instructions), however, require certain general registers for specific uses (see Table 3-1). This implicit
register use allows a more compact instruction
encoding.

The 8088/80188 BIU fetches another instruction
byte whenever there is one empty byte in its queue,
and there is no active request for bus access from
the EU. The 8086/80186 BIU operates similarly
except that it does not normally initiate a fetch until
there are two empty bytes in its queue.
The 8086/80186 BIU will generally obtain two instruction bytes per fetch; if a program transfer forces
fetching from an odd address, the BIU automatically
reads one byte from the odd address and then
resumes fetching two-byte words from the subsequent even address.

Table 3-1 Implicit Use of General Register

REGISTER

Under most circumstances, the queue contains at
least one byte of the instruction stream, and the EU
does not have to wait for instructions to be fetched.
The instructions in the queue are those stored in the
memory locations immediately adjacent to and
higher than the instruction currently being
executed. That is, they are the next logical instructions so long as execution proceeds serially. If the
EU executes an instruction that transfers control to
another location, the BIU fetches the instruction
from the new address, passes it immediately to the
EU, and then begins refilling the queue from the
new location (no flushing of the previous contents is
necessary). In addition, the BIU suspends instruction
fetching whenever the EU requests a memory or I/O
read or write (except that a fetch already in progress
is completed before executing the EU's bus request).

AX
AL

AH
BP
BX
CX
CL
DX
SP
SI
DI

OPERATIONS
Word Multiply, Word Divide,
Word I/O
Byte Multiply, Byte Divide,
Byte I/O, Translate, Decimal
Arithmetic
Byte Multiply, Byte Divide
Enter, Leave (186, 188 only)
Translate
String Operations
Variable Shift and Rotate
Word Multiply, Word Divide,
Indirect I/O
Stack Operations
String Operations
String Operations

3_3 REGISTER STRUCTURE
The 8086,88 and 80186,188 contain the same basic
set of fourteen registers as shown in Figure 3-3.
These registers are grouped into the following
categories: general registers, segment registers, and
status and control registers.

The pointer and index registers consist of the 16-bit
registers SP, BP, SI, and DI as shown in Figure 3-3.
They can also be used in most arithmetic and logic
operations. These registers usually contain offset addresses for addressing within a segment. They
reduce program size by eliminating the need for
each instruction to specify frequently used
addresses. These registers serve another function;
they provide for dynamic logical address computation as described in the section on operand
addressing. The pointer and index registers are also
used implicitly in some instructions (Table 3-1).

General Registers
The CPUs have eight 16-bit general registers. They
are divided into two files of four registers each: the
data register file and the pointer and index register
file.
The upper and lower halves of the data registers are
separately addressable. This means that each data
register can be used interchangeably as a 16-bit
register, or as two 8-bit registers.

As shown in Figure 3-3, this register file is divided
into the pointer subfile (SP and BP) and the index
subfile (SI and DO. The pointer registers provide
convenient access to the current stack segment (as
opposed to the data segment). Unless otherwise
specified in the instruction, pointer registers refer to
the current stack segment while index registers refer
to the current data segment. In certain instances,
specific uses of these four registers are indicated by
the mnemonic phrases "stack pointer," "base
pointer," "source index," and "destination index."

The 16-bit data registers are named AX, BX, CX,
and DX; the 8-bit registers are named AL, AH, BL,
BH, CL, CH, DL, and DH (the H or L suffix designates high-order or low-order byte of the 16-bit
register). The other registers are always accessed as
16-bit units only.

3-3

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

DATA REGISTERS

o

07

7
AX

AH

AL

BX

BH

BL

CX

CH

CL

OX

DH

DL

POINTER AND INDEX REGISTERS
15

0
STACK POINTER

SP
BP

BASE POINTER

SI

SOURCE INDEX

01

I

I

DESTINATION INDEX

SEGMENT REGISTERS
0

15
CS

CODE

OS

DATA

SS

STACK

ES

I

I

EXTRA

INSTRUCTION POINTER AND FLAGS
0

15
IP
STATUS WORD
OR FLAGS

I

15

10lDIIITI51 Z 1

IA I

I

pi

IC

11 10 9 8 7 6 5 4 3 2 1 0

I

INSTRUCTION
POINTER

Figure 3-3 Register Structure
.3-4

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

Segment Registers
The segment registers are also 16-bit registers.
These registers specify the four currently addressable
memory segments: CS (code segment), DS (data
segment), SS (stack segment), and ES (extra
segment). All instructions are fetched from the current code segment, offset by the instruction pointer
OP) register. Operand fetches are usually made from
the current data segment (DS) or the current stack
segment (SS), depending on whether the offset address was calculated from the contents of a pointer
register. For the exceptional cases where operand
references are required outside the default segment,
a segment override prefix may be added to the instruction to designate the required segment.

Status and Control Registers
The status and control registers consist of the instruction pointer and the status word or flags.

The status word or flags is a 16-bit register consisting
of three control flags and six status flags (see Figure
3-4). The status flags record specific characteristics
of the result of logical and arithmetic instructions
(bits 8,9, and 10); the six status flags control the operation of the CPU within a given operating mode
(bits 0, 2, 4, 6, 7, and 11).
The status flags provide status information that the
EU posts to reflect certain properties of the result of
an arithmetic or logic operation. A group of instructions is available that allows a program to alter its execution depending on the contents of the status
flags, that is, on the result of a prior operation. Table
3-2 summarizes the status word or flag bit functions.
Different instructions affect the status flags
differently; in general, however, the flags reflect the
following conditions:
1) If AF (the auxiliary flag) is set, there has been a
carry out of the low nibble (the low order 4-bits of a
byte) into the high nibble or a borrow from the high
nibble into the low nibble of an 8-bit quantity
(low-order byte of a 16-bit quantity). This flag is
used by decimal arithmetic instructions.

The 16-bit instruction pointer OP) is analogous to
the program counter (PC) in earlier CPU sand
points to the next instruction. The instruction pointer is updated by the BIU so that it contains the offset
(distance in bytes) of the next instruction from the
beginning of the current code segment. During
normal execution, the IP contains the offset of the
next instruction to be fetched by the BIU. However,
for all instructions that manipulate the IP, the contents of IP are adjusted to point to the next instruction to be executed, for example, when the IP is
pushed on the stack or is used to calculate the address of a relative jump.

2) If CF (carry flag) is set, there has been a carry
out of, or a borrow into, the high-order bit of the
result (8- or 16-bit). The flag is used by instructions
that add and subtract multibyte numbers. Rotate instructions can also isolate a bit in memory or a register by placing it in the carry flag.

STATUS FLAGS
CARRY

-----------------------,

PARITY - - - - - - - - - - - - - - - - - - - - ,
AUXILIARY CARAY - - - - - - - - - - - - - ' - - - - - ,

L -_ _ _ _ _ _ _ _ _

~

DIRECTION FLAG

INTEL RESERVED

Figure 3-4 Status Word or Flags Format

3-5

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

flag controls the direction of the string manIpulations, the interrupt flag enables or disables external
interrupts, and the trap flag puts the processor into a
single-step mode for debugging.

Table 3-2 Status Word or Flags
Bit Functions
Bit
Position

Name

Function

0

CF

Carry Flag-Set on high-order bit
carry or borrow; cleared otherwise

2

PF

Parity Flag-Set if low-order 8 bits
of result contain an even number bf
1-bits; cleared otherwise

4

AF

Set on carry from or borrow to the
low order four bits of AL; cleared
otherwise

6

ZF

Zero Flag-Set if result is zero;
cleared otherwise

7

SF

Sign Flag-Set equal to high-order
bitofresult(Oifpositive, 1 if negative)

8

TF

Single Step Flag-Once set, a single step interrupt occurs after the
next instruction executes. TF is
cleared by the single step interrupt.

9

IF

Interrupt-enable Flag-When set,
maskable interrupts will cause the
CPU to transfer control to an interrupt vector specified location.

10

DF

Di rection Flag-Causes string
instructions to auto decrement
the appropriate index register
when set. Clearing DF causes
auto increment.

11

OF

Overflow Flag-Set if the signed
result cannot be expressed
within the number of bits in the
destination operand; cleared
otherwise

3) If OF (the overflow flag) is set, an arithmetic

overflow has occurred; that is, a significant digit has
been lost because the size of the computation exceeded the capacity of its destination location. An optional Interrupt On Overflow instruction is available
that generates an interrupt in this situation.
4) If SF (the sign flag) is set, the high-order bit of
th~ result is a 1. Since negative binary numbers are
represented by standard two's complement
notation, SF indicates the sign of the result
(O=positive, I = negative).

The control flags are set and cleared as follows:
]) Setting DF (the direction flag) causes string instructions to auto-decrement, that is, to process
strings from high addresses to low addresses, or
from right to left. Clearing DF causes string instructions to auto-increment, or to process strings from
left to right.
2) Setting IF (the interrupt-enable flag) allows the
CPU to recognize maskable, external interrupt
requests (including interrupts from 80186,188 integrated peripherals). Clearing IF disables these interrupts. IF has no effect on either nonmaskable
external or internally generated interrupts.
3) Setting TF (the trap flag) puts the processor into
single-step mode for debugging. In this mode, the
CPU automatically generates an internal interrupt
after each instruction, allowing a program to be inspected as it executes, instruction by instruction.

3.4 MEMORY STRUCTURE
The memory and input/output space of the 8086,88
and 80186,188 are treated in parallel and are collectively referred to as the memory structure. Code
and data reside in the memory space, while
(non-memory-mapped) peripheral devices reside in
the I/O space. This section describes how memory is
functionally organized and used.

Memory Space
The memory in an 8086,88 and 80186,188 system is
a sequence of up to one million (I,048,576) bytes. A
word is any two consecutive bytes in memory (word
alignment is not required). Words are stored in
memory with the most significant byte at the higher
memory address.
The memory can be conceived of as an arbitrary
number of segments, each containing a maximum
of 64K bytes. The starting address of each segment
is evenly divisible by 16 (the four least significant address bits are 0). At any moment, the program can
immediately access the contents of four such
segments:

5) If PF (the parity flag) is set, the result has even

parity. This flag can be used to check for data transmission errors. (Only the low-order 8 bits are
tested.)
6) If ZF (zero flag) is set, the result of the operation

is O.
1)

2)
3)
4)

The three control flags are used by programs to alter
processor operations in specified ways. The direction
3-6

the current code segment
the current data segment
the current stack segment
the current extra segment
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

Each of these segments can be identified by placing
the 16 most significant bits of the segment's starting
address into one of the four 16-bit segment
registers. Instructions can refer to bytes or words
within a segment by using a 16-bit offset address.
The processor constructs the 20-bit byte or word address automatically by adding the 16-bit offset address (also called the logical address) to the contents
of a 16-bit segment register, with four low-order
zeros appended (see Figure 3-5).

HIGH MEMORY

lOW MEMORY
OOOOOH

00001H

00002H

5

yFFFFEH FFFFFH

I! ! ! I ! I ! II ! I II ! II ! II I 115 51) IIII1 ! ! ! III!
7

I..

07

07

07

1 MEGABYTE

I

0
..

I

Figure 3-6 Storage Organization

o

15

I

LOGICAL ADDRESS

IOFFSET
ADDRESS

15
EGMENT REGISTER

~~

SEGMENT
____~ADDRESS

Figure 3- 7 Instruction and Variable Storage

Word data is always stored with the most-significant
byte in the higher memory location (Figure 3-8).
Most of the time this storage convention is transparent to the programmer, except when monitoring the
system bus or reading memory dumps.

o

19
20-BIT
PHYSICAL MEMORY ADDRESS

VALUE OF WORD STORED AT 724H: 5502H

Figure 3-5 How to Address One Million Bytes
Figure 3-8 Storage of Word Variables

Storage Organization

Pointers addressing data and code that are outside
the currently-addressable segments are stored as
doublewords. The lower-addressed word of a pointer
contains an offset value; the higher-addressed word
contains a segment base address. By convention,
each word is stored with the higher-addressed byte
holding the most-significant eight bits of the word
(Figure 3-9).

From the storage point point of view, memory
spaces are organized as arrays of 8-bit bytes (Figure
3-6). Instructions, byte data and word data may be
freely stored at any byte address without regard for
alignment, thereby saving memory space by allowing
code to b~ densely packed in memory (Figure 3-7).
3-7

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

VALUE OF POINTER STORED.AT 4H:
SEGMENT BASE ADDRESS: 3B4CH
OFFSET: 65H

Figure 3-9 Storage of Pointer Variables

Segmentation

Physical Address Generation

Programs view memory space as a group of segments
defined by the application. A segment is a logical
unit of memory that may be up to 64K bytes long.
Each segment is made up of contiguous memory locations and is an independent, separately addressable
unit. Every segment is assigned (by software) a base
address, which is its starting location in the memory
space. All segments start on 16-byte memory
boundaries. There are no other restrictions on segment locations. Segments may be adjacent, disjoint,
partially overlapped, or fully overlapped (Figure
.3-10). A physical memory location may be mapped
into (contained in) one or more logical segments.

It is useful to think of every memory location as

having two kinds of addresses - physical and
logical. A physical address is the 20-bit value that
uniquely identifies each byte location in the memory
space. Physical addresses may range from OH
through FFFFFH. All exchanges between the CPU
and memory components use this physical address.
Programs, however, deal with logical rather than
physical addresses. The use of logical addresses
allows code to be developed without prior knowledge
of where the code is to be located in memory, and
facilitates dynamic management of memory
resources.

The segment registers point to (contain the base address values of) the four immediately addressable
segments (Figure 3-11). Programs obtain access to
code and data in other segments by changing the segment registers to point to the desired segments.

A logical address consists of a segment base value
and an offset value. For any given memory location,
the segment base value locates the first byte of the
containing segment aod the offset value is the
distance, in bytes, of the target location from the
beginning of the segment. Segment base and offset
values are unsigned 16-bit quantities; the lowestaddressed by~ in a segment has an offset of O. Many
different logical addresses can map to the same
physical location as shown in Figure 3-12.

Every application will define and use segments
differently. The currently addressable segments provide a generous work space: 64K bytes for code, a
64K byte stack and 128K bytes of data storage. Many
applications can be written to simply initialize the
segment registers and then forget them. Larger applications should be designed with careful consideration given to segment definition. This segmented
structure of the memory space supports modular
software design by discouraging very large, monolithic programs. Segments can also be used to advantage in many programming situations. An example
is the case of an editor for several on-line terminals.
A 64K byte text buffer (say, an extra segment)
could be assigned to each terminal. A single program
could maintain all the buffers by simply changing
register ES to point to the buffer of the terminal
requiring service.

Whenever the BIU accesses memory-to fetch an instruction or to obtain or store a variable-it generates a physical address from a logical address. This is
done by shifting the segment base value four bit positions and adding the offset as illustrated in Figure
3-13. This addition process provides for modulo 64K
addressing (addresses wrap around from the end of
a segment to the beginning of the same segment).
The BIU obtains the logical address of a memory location from different sources depending on the type
of reference that is being made (see Table 3-3).
3-8

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

FULLY

OVEI1LAP~1
PARTLY

SEGMENT D

!

~DISJOINT

OVERLAP~I

CONTIGUOUS~

I
I

SEGMENT A

I
I

LOGICAL
SEGMENTS

I

SEGMENT E

I

I

t

OH

I

I

SEGMENT B

I

t

I

SEGMENT C

t

t

10000H

1("

I

20000H

}PHYSICAL
MEMORY

30000H

Figure 3-10 Segment Locations in Physical Memory

FFFFFH

DATA:

DS:

CODE:

CS:

STACK: SS:

EXTRA:

ES:

B

1--~-I

H

_BG
D

1-,1

h

\

1\
I I
I I
IL
I
L_

-:

EJ

OH

Figure 3-11 Currently Addressable Segments

3-9

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

r
2 C4H

PHYSICAL
ADDRESS

t

r

2 C3H

~

2 C2H

OFFSET
(3H)

2 C1H

~I

SEGMENT
BASE

2 COH

2 BFH
2 BEH

2 BDH
2 BCH
2 BBH
LOGICAL
ADDRESSES

2 BAH

OFFSET
(13H)

....

2 B9H
2 BSH
2 B7H
2 B6H
2 B5H
2 B4H
2 B3H
2 B2H
2 B1H

'- SEGMENT
BASE

2 BOH
~

~

Figure 3-12 Logical and Physical Addresses

r----.. . . .:,. . . I.
I

rIFTLEFT4 BITS

";~91_ _ _...,..._4"""",:-°.. 101

+

I

1

2

°

15

2

I
U~~~ENT}
~1':"5--------:!O
I °°22
1

2

3 4

LOGICAL
ADDRESS

IOFFSET

15
t------.
..

11 ....

°

°
6

2

I

PHYSICAL ADDRESS

~19~---+r---...I10
TOMEMORY

Figure 3-13 Physical Address Generation
3-10

210911

I

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

Table 3-3 Logical Address Sources

TYPE OF MEMORY REFERENCE

Instruction Fetch
Stack Operation
Variable (exectp following)
String Souce
String Destination
BP Used AS Base Register
BX Used As Base Register

DEFAULT
SEGMENT
BASE

ALTERNATE
SEGMENT
BASE

CS
SS
OS
OS
ES
SS
OS

NONE
NONE
CS, ES, SS
CS, ES,SS
NONE
CS, OS, ES
CS, ES, SS

Instructions are always fetched from the current
code segment. The instruction pointer OP) contains
the offset of the target instruction from the beginning of the segment.

OFFSET

IP
SP
Effective Address
SI
01
Effective Address
Effective Address

based on the most frequent typical usage. It is
possible, however, to explicitly direct the BIU to
access a variable in any of the currently addressable
segments (the only exception is the destination operand of a string instruction which must pe in the extra
segment). This is done by preceding an instruction
with a segment override prefix. This one-byte
machine instruction tells the BIU which segment
register to use to access a variable referenced in the
following instruction.

Stack instructions always operate on the current
stack segment. The stack pointer (SP) contains the
offset of the top of the stack. Most variables
(memory operands) are assumed to reside in the
current data segment, although a program can instruct the BIU to access a variable in one of the other
currently addressable segments. The offset of a
memory variable is calculated by the EU. This calculation is based on the addressing mode specified in
the instruction; the result of the calculation is called
the operand's effective address (EA). Section 3.6
covers addressing modes and effective address calculation in detail.

Dynamically Relocatable Code
The segmented memory structure of the 8086,88
and 80186,188 makes it possible to write programs
that are position-independent, or dynamically
relocatable. Dynamic relocation allows a multiprogramming or multitasking system to make particularly effective use of the available memory. Inactive
programs can be written to disk, and the space they
occupied allocated to other programs. If a diskresident program is needed lat<:r, it can be read back
into any available memory location and restarted.
Similarly, if a program needs a large contiguous
block of storage, and the total amount is available
only in nonadjacent fragments, other program segments can be compacted to free up a continuous
space. This process is shown graphically in Figure
3-14.

Strings are addressed differently from other
variables. The source operand of a string instruction
is assumed to lie in the current data segment, but
another currently addressable segment may be
specified. Its offset is taken from register SI, the
source index register. The destination operand of a
string instruction always resides in the current extra
segment (ES). Its offset is taken from the DI, the
destination index register. The string instructions automatically adjust SI and DI as they process the
strings one byte or word at a time.
When register BP, the base pointer register, is
designated as a base register in an instruction, the
variable is assumed to reside in the current stack
segment. Register BP thus provides a convenient
way to address data on the stack. BP can be used,
however, to access data in any of the other currently
addressable segments.

In order to be dynamically relocatable, a program
must not load or alter its segment registers and must
not transfer directly to a location ou tside the current
code segment. In other words, all offsets in the program must be relative to fixed values contained in
the segment registers. This allows the program to be
moved anywhere in memory as long as the segment
registers are updated to point to the new base
addresses.

In most cases, the BIU's segment assumptions are a
convenience to the programmer, since they are
3-11

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

BEFORE RELOCATION

AFTER RELOCATION

CODE
SEGMENT

I
STACK
SEGMENT

I

r-

CS

CS

SS

SS

OS

OS

f--

ES

ES

f-

DATA
SEGMENT

CODE
SEGMENT

EXTRA
SEGEMENT

STACK
SEGMENT
DATA
SEGMENT
EXTRA
SEGMENT

c::J

FREE SPACE

Figure 3-14 Dynamic Code Relocation

Stack Implementation
Stacks are located in memory and are accessed by
the stack segment register (SS) and the stack pointer
register (SP). A system may have an unlimited
number of stacks, and a stack may be up to 64K
bytes long, the maximum length of a segment. (An
attempt to expand a stack beyond 64K bytes overwrites the beginning of the stack.) One stack is
directly addressable at a time, the current stack,
generally referred to simply as the stack. SS contains
the base address of this stack and SP points to the
top of the stack (TOS). In other words, SP contains
the offset of the top of the stack from the stack segment's base address. The stack's base address
(contained in SS), however, is not the bottom of the
stack.
Stacks are 16-bits wide; thus, instructions that operate on stacks add and remove stack items one word
at a time. A word is pushed onto the stack by decrementing SP by 2 and writing the item at the new TOS
(see Figure 3-15). A word is popped off the stack by
copying it from TOS and then incrementing SP by 2.

In other words, the stack grows down in memory towards its base address. Stack operations never move
items on the stack, nor do they erase them. The top
of the stack changes only as a result of updating the
stack pointer.

Dedicated and Reserved Memory
Locations
.
Two areas in extreme low and high memory are
dedicated to specific processor functions or are reo
served by Intel Corporation for use by Intel hardware and software products. As shown in Figure
3-16, the locations are: OH through 7FH (128 bytes)
and FFFFOH through FFFFFH (16 bytes). These
areas are used for interrupt and system reset
processing. Application systems should not use
these areas for any other purpose. Doing so may
make these systems incompatible with future Intel
products.
As Figure 3-16 indicates, the 8086,88 and the
80186,188 processors differ in the proportion of
dedicated to reserved locations.
3-12

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

POP AX
pOP BX

AX~-l

PUSH AX

AX~l

EXISTING
STACK

r

r

1062

00

11

1060

22

33

105E

44

55

105B

66

77

105A

88

99

~'058

AA

BB

i'"

08

SP

1052

89

AB

105E

44

55

105B

66

77

105A

88

99

1058

AA

BB

~'056

34

12

1054

45

67

89

AB

CD

EF

'"
0><.,0
....

00

67

33

........

50

23

45

11

22

::;;u

10

01

1054

00

1060

0«

r

1056

1062

!zu
~;:!:

w'"
a:UJ

a.J:

zO
~b~
SS

1052

r---

'05O

Bxl!!El-l :

I
I
I
I

00

11

1060

22

33

105E

44

55

105C

66

77

88

99

105B AA

BB

J

1056

34

12

-

1054

45

67

1052

89

AB

~'05A

_J

I
I
I

1062

I
I
I

--.J

r'050~

I I Iss
10

50

00

061 SP

~SS
00

STACK OPERATION FOR CODE

OA

I SP

SE~UENCE

PUSH AX
POPAX
POP BX

Figure 3-15 Stack Operation

FFFFFH
RESERVED
FFFFCH
FFFFBH
DEDICATED

FFfFOH

FFFEFH

"r

OPEN

"

FFFFFH

cq-

RESERVED
FFFFCH
FFFFBH
DEDICATED

r

OPEN

14H
13H
DEDICATED

RESERVED

.

OPEN

~
~

r
100H
FFH
F8H
F7H

OPEN
OH

OPEN

80H
7FH
RESERVED
50H
4FH
DEDICATED

RESERVED

OH

1/0

MEMORY

iAPX86,88

1 DOH
FFH
F8H
F7H

OPEN
OH

OH

1/0

MEMORY

DEDICATED
FFFEH

80H
7FH
RESERVED

FFFFH

FFFFDH
FFFEFH

RESERVED

iAPX 186,188

Figure 3-16 Reserved and Dedicated Memory and I/O Locations
3-13

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

Integrated Peripheral Control Block
The 80186,188 integrated peripherals are controlled
by an array of l6-bit registers located in an internal
256-byte control block. Control and status registers
are provided for the chip select unit, the DMA
controller, the timers, and the interrupt controller.
The control block may be mapped into memory or
I/O space. The control block base address is programmed by the 16-bit relocation register, which is
contained in the control block itself. Each of the control and status registers are located at a fixed offset
from the base address.

3.5 I/O PORT ORGANIZATION
The 8086,88 and 80186,188 have a versatile set of
input/output facilities. The processors provide a
large I/O space that is separate from the memory
space. I/O devices may also be placed in the memory
space to bring the power of the full instruction set
and addressing modes to input/output processing.
For high speed transfers, the 8086,88 may be used
with traditional direct memory access controllers or
the 8089 I/O Processor. The 80186,188 has an integrated DMA controller with two high-speed DMA
channels.

I/O Space
8086/80186 and 8088/801 88
Memory Access Differences
The 8086 and 80186 can access either 8 or 16 bits of
memory at a time. If an instruction refers to a word
variable, and that variable is located at an evennumbered address, the 8086/80186 accesses the
complete word in one bus cycle. If the word is located
at an odd-numbered address, it is accessed one byte
at a time in two consecutive bus cycles.

Thus, to maXImIze throughput in 8086- and
80186-based systems, 16-bit data should be stored at
even addresses (i.e., it should be word aligned). This
is parttcularly true of stacks. Unaligned stacks can
slow a system's response to interrupts. Nevertheless, except for the performance penalty, word alignment is totally transparent to software, allowing
maximum data packing where memory space is
constrained.

The 8086/80186 always fetch the instruction stream
in words from even addresses, except that the first
fetch after a program transfer to an odd address 0 btains a byte. The instruction stream is disassembled
inside the processor, and instruction alignment will
not materially affect the performance of most
systems.

The 8088 and 80188 always access memory in bytes.
Word operands are accessed in two bus cycles
regardless of their alignment. Instructions are also
fetched one byte at a time. Although alignment of
word operands does not affect the performance of
the 8088/188, locating 16-bit data on even addresses
will insure maximum throughput if the system is
ever transferred to an 8086 or 80186.

The I/O space can accommodate up to 64K 8-bit
ports or up to 32K 16-bit ports. Ports are addressed
the same way as memory except that there are no
port segment registers. All ports are considered to
be in one segment.
A 16-bit device should be located at an even address
so that words will be transferred in a single bus cycle.
An 8-bit device may be located at either an even or
odd address. Thus, internal registers in a given 8-bit
device will have all even or all odd addresses.
To access a port, the BIU places the port address
(O-FFFFH) on the lower 16 lines of the address bus.
Different forms of the I/O instructions allow the address to be specified as a fixed value in the instruction or as a variable taken from register DX. The IN
and OUT (input and output) instructions transfer
data between the accumulator (AL for byte
transfers, AX for word transfers) and ports located
in the I/O space.
The first 256 ports are directly addressable (address
in the instruction) by some input/output instructions; other instructions let the programmer address
the total of 64K ports indirectly (address in a
register) .

Restricted I/O Locations
As shown in Figure 3-16, on both the 8086,88 and
80186,188 processors, locations F8H throughFFH
(eight of the 64K locations) in the I/O space are reserved by Intel Corporation for use by future Intel
hardware and software products. Using these locations for any other purpose may inhibit compatibility
with future Intel products. Locations FFFE and
FFFF are dedicated, on the 80186,188 processors, to
the relocation register's reset location. On the
8086,88 these locations are reserved.
3-14

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

Memory-Mapped 1/0
I/O devices may also be placed in the memory space.
This memory-mapped I/O provides additional programming flexibility. Any instruction that references
memory may be used to access an 110 port located in
the memory space. A group of terminals, for
example, could be treated as an array in memory,
with an index register selecting one of the terminals
in the array.

operand, it must pass an offset value to the BIU. The
BIU adds the offset to the (shifted) contents of a segment register, producing a 20-bit physical address,
and then executes the bus cycle(s) needed to access
the operand.

The Effective Address

Memory reference instructions take longer to
execute, however, and are less compact than the
simpler IN and OUT instructions.

3.6 ADDRESSING MODES
The 8086,88 and 80186,188 provide many different
ways of addressing operands. Operands may be contained in registers, within the instruction itself, in
memory or in I/O ports. In addition, the addresses
of memory and 110 port operands can be calculated
in several different ways. These addressing modes
greatly extend the flexibility and convenience of the
instruction set.

Register and Immediate Operands
Instructions that specify only register operands are
generally the most compact and fastest executing.
This is because the register addresses are encoded in
instructions in just a few bits, and because these operations are performed entirely within the CPU (no
bus cycles are run). Registers may serve as source
operands, destination operands, or both.
Immediate operands are constant data contained in
an instruction. The data may be either 8 or 16 bits
long. Immediate operands can be accessed quickly
because they are available directly from the instruction queue; (as in the case of register operands, no
bus cycles need to be run to obtain an immediate
operand). The limitations of immediate operands
are that they may only serve as source operands and
that they are constant values.

The offset that the EU calculates for a memory operand is called the operand's effective address or EA.
It is an unsigned 16-bit number that expresses the
operand's distance in bytes from the beginning of
the segment in which it resides. The EU can calculate
the effective address in several different ways. Information encoded in the second byte of the instruction
tells the EU how to calculate the effective address of
each memory operand. A compiler or assembler
derives this information from the statement or instruction written by the programmer. Assembly language programmers have access to all addressing
modes.

As shown in Figure 3-17, the EU calculates the EA
by summing a displacement, the contents of a base
register, and the contents of an index register. The
fact that any combination of these three components
may be present in a given instruction results in the
great variety of memory addressing modes provided
by the 8086,88 and 80186,188.
The displacement element is an 8- or 16-bit number
that is contained in the instruction. The displacement
generally is derived from the position of the operand
name (a variable or label) in the program. The programmer can also modify this value or specify the
displacement explicitly.

Memory Addressing Modes

A programmer may specify that either BX or BP is to
serve as a base register whose contents are to be
used in the EA computation. Similarly, either SI or
DI may be specified as an index register. Whereas
the displacement value is a constant, the contents of
the base and index registers may change during the
execution. This makes it possible for one instruction
to access different memory locations as determined
by the current value in the base and/or ind·ex
registers.

Unlike register and immediate operands, which are
directly accessible to the EU, memory operands
must be transferred to and from the CPU over the
bus. When the EU needs to read or write a memory

Effective address calculations with the BP are made,
by default, using the SS register, though either the
DS or the ES registers may be specified instead.

3-15

210911

THE iAPX B6,BB AND iAPX 1 B6,1 BB ARCHITECTURE AND INSTRUCTIONS

DOUBLE INDEX

SINGLE INDEX

~
X.

jdbS
OR I

OR

BP·

ENCODED
INTHE
INSTRUCTION

r- -

{
EXPLICIT
INTHE
INSTRUCTION

+

~I:':LA:CEMENT

01

i

l---- +

/

EU

EFFECTIVE
ADDRESS

l

ASSUMED
UNLESS
OVERRIDDEN
BY PREFIX

BIU

Figure 3-17 Memory Address Computation

L

OPCODE

J

MOD RIM

l

DISPLA

CEM~N~

J

Direct Addressing
EA

Direct addressing (see Figure 3-18) is the simplest
memory addressing mode. No registers are
involved; the EA is taken directly from the displacement field of the instruction. Direct addressing typically is used to access simple variables (scalars).

Figure 3-18 Direct Addressing
3-16

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

Register Indirect Addressing
The EA of a memory operand may be taken directly
from the BP, BX, SI or DI register (see Figure 3-19).
One instruction can operate on many different
memory locations if the value in the pointer or index
register is updated appropriately. The load effective
address (LEA) and arithmetic instructions might be
used to change the register value.
Note that with the JMP and CALL instructions, any
16-bit general register may be used for register indirect addressing.

When BX is used as the base register, the operand
by default resides in the current Data Segment, and
the DS register is used to compute the operand's EA.
Base addressing provides a straightforward way to
address structures which may be located at different
places in memory (see Figure 3-20. A base register
can be set to point to the base of the structure, and
elements of the structure can then be addressed by
their displacement from the base. Different copies of
the same structure can be accessed by simply changing the base register.

HIGH ADDRESS
DISPLACEMENT

OPCOOE

t

MOD RIM

L

r -I
BX
OR
BP
OR

SI

DISPLACEMENT

AGE

r-

ISTATUS

RATE
VAC

DEPT

BASE REGISTER

r

I
I

SICK

DIV

EMPLOYEE

t
I
I
EA
L _____ -.J

EA

ISTATUS

AGE

OR

01

RATE
VAC
DEPT

r
I

SICK
DIV

EMPLOYEE

Figure 3-19 Register Indirect Addressing

~

I

BASE REGISTER

F

~

:

I
I

~-----~

LOW ADDRESS

Figure 3- 21 Accessing a Structure
with Based Addressing

Base Addressing
In base addressing (Figure 3-20), the effective address is the sum of a displacement value and the contents of register BX or register BP. Specifying BP as a
base register directs the BIU to obtain the operand
from the current stack segment (unless a segment
override prefix is present). This makes base addressing with BP a very convenient way to access stack
data.

Figure 3-20 Based Addressing

Indexed AddreSSing
In indexed addressing, the EA is calculated from the
sum of a displacement and the contents of an index
register, SI or DI, as shown in Figure 3-22. Indexed
addressing is often used to access elements in an
array (Figure 3-23). The displacement locates the
beginning of the array, and the value of the index
register selects one element (the first element is
selected if the index register contains 0). Since all
array elements are the same length, simple arithmetic on the index register will select any element.

Figure 3-22 Indexed Addressing
3-17

210911

THE iAPX 86,88 AND iAPX 186, 188 ARCHITECTURE AND INSTRUCTIONS

HIGH ADDRESS
HIGH ADDRESS

:-T

r
I
I
I
I
I

r-

DISPLACEMENT

INDEX

I

~GISTER
"i

EA

L ----

ARRAY (7)

ARRAY (6)

I

I

ARRAY (3)

--

I-

ARRAY (21

ARRAY (1)
ARRAY (0)

~

t
EA

I I

I

I

1

II

I
I

_-- _____ J

I

1

I

1-1WORD~

"J""'f
•
"

BX

OLD

AX

I

ARRAY (6)

I

1

(BP)

ARRAY (3)

I
I
I

----i

ARRAY (2)

EA

1

I
I

ARRAY {11

ARRAY (0)

•

COUNT

'--T ------1
______ 1_

Figure 3-23 Accessing an Array
with Indexed Addressing

BP

OLD

ARRAY (4)

..-

1 1

OLD

ARRAY (5)

I

EA

1
1

LOW ADDRESS

IP

BASE REGISTERI(BP)

1

,

PARM

+

I

ARRAY (4)

DISPLACEMENT

PARM 2

6

~;":;;;:'=.:.Jl.

ARRAY (5)

I

T-'

DISPLACEMENT

ARRAY (8)

TEMP

L

STATUS

I

I---------r'
.. 1------....J

-.-1 WORD......
LOWER ADDRESS

Based Indexed Addressing
Figure 3-25 AcceSSing a Stack Array
with Based Indexed Addressing

Based indexed addressing generates an effective address that is the sum of a base register (BX or BP),
an index register (SI or DI) and a displacement
(Figure 3-24). Based indexed addressing is a very
flexible mode because two address components can
be varied at execution time.

Arrays contained in structures and matrices
(two-dimensional arrays) can also be accessed with
based indexed addressing.

String Addressing

E!;:::f-j
E~7:::f-r
I

EA

String instructions do not use the normal memory
addressing modes to access their operands. Instead,
the index registers are used implicitly as shown in
Figure 3-26. When a string instruction is executed,
SI is assumed to point to the first byte or word of the
source string, and DI is assumed to point to the first
byte or word of the destination string. Tn a repeated
string operation, the CPU automatically adjusts SI
and DI to obtain subsequent bytes or words.

Figure 3-24 Based Indexed Addressing
IOPCODEI

Based indexed addressing provides a convenient
way for a procedure to address an array allocated on
a stack (Figure 3-25). Register BP can contain the
offset of a reference point on the stack, typically the
top of the stack after the procedure has saved registers and allocated local storage. The offset of the
beginning of the array from the reference point can
be expressed by a displacement value, and an index
register can be used to access individual array
elements.

SI

DI

J----..I
J----..I

SOURCE EA

DESTINATION EA

I

Figure 3-26 String Operand Addressing
3-18

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

I/O Port Addressing
If an I/O port is memory mapped, any of the
memory operand addressing modes may be used to
access the port (for example, a group of terminals
can be accessed as an array). String instructions can
also be used to transfer data to memory-mapped
ports with an appropriate hardware interface.
To access ports located in the I/O space, the two different addressing modes illustrated in Figure 3-27
can be used. In direct port addressing, the port
number is an 8-bit immediate operand. This allows
fixed access to ports numbered 0 to 255. Indirect
port addressing is similar to register indirect addressing of memory operands. The port number is taken
from register DX and can range from 0 to 65,535
(providing access to any port in the I/O space). A
group of adjacent ports can be accessed using a
simple software loop that adjusts the value in DX.

DIRECT PORT ADDRESSING

I..__D_X_ _...J----..I PORT ADDRESS I
INDIRECT PORT ADDRESSING

Figure 3-27 1/0 Port Addressing

3.7 THE INSTRUCTION SET
The 8086,88 and 80186,188 instructions include
equivalents to the instructions typically found in
such CPUs as the 8080 and 8085. Significant new instructions added by the 8086 are:
•

multiplication and division of signed and unsigned binary numbers as well as unpacked
decimal numbers,

•

move, scan and compare operations for
strings up to 64K bytes in length,

•

non-destructive bit testing,

•

byte translation from one code to another,

•

additional software-generated interrupts, and

•

a group of instructions that can help coordinate the activities of multiprocessor systems.

In addition to these instructions, the 80186,188 provides ten new instruction types that serve to streamline existing code or produce optimum iAPX 186
code.
All instructions treat different types of operands
uniformly. Nearly every instruction can operate on
either byte or word data. Register, memory and immediate operands may be specified interchangeably
in most instructions. The exception is that immediate values may only serve as source and not destination operands. In particular, memory variables can
be added to, subtracted from, shifted, compared,
and so on, in place, without moving them in and out
of registers. This saves instructions, registers, and
execution time in assembly language programs. In
high-level languages, where most variables are
memory-based, compilers, such as PLlM-86, can
produce faster and shorter object programs.
The instruction set can be viewed as existing at two
levels: the assembly level and the machine level. To
the assembly language programmer the 8086 and
80186 appear to have about 100 instructions. One
MOY (move) instruction, for example, transfers a
byte or a word from a register or a memory location
or an immediate value to either a register or a
memory location. The CPUs, however, recognize 28
different MOY machine instructions (move byte
register to memory, move word immediate to
register, etc.). The ASM-86 assembler translates the
assembly-level instructions written by a programmer
into the machine-level instructions that are actually
executed by the CPU. Compilers such as the
PL/M-86 translate high-level language statements
directly into machine-level instructions.
The two levels of the instruction set address two different requirements: efficiency and simplicity. The
numerous-about 300 in all-forms of machinelevel instructions allow these instructions to make
very efficient use of storage. For example, the machine instruction that increments a memory operand
is three or four bytes long because the address of the
operand must be encoded in the instruction. To
3-19

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

Table 3-4 Data Transfer Instructions,

increment a register, however, does not require as
much information, so the instruction can be shorter.
In fact, the 8086,88 and 80186,188 have eight different machine-level instructions that increment a
different 16-bit register; these instructions are only
one byte long.

GENERAL PURPOSE
MOV
PUSH
POP
PUSHA
paPA
XCHG
XLAT

This section presents the instruction set from two
perspectives. First, the assembly-level instructions
are described in functional terms. They are then presented in a reference table format that specifies all
permissible operand combinations, provides execution times and machine instruction length, and
shows the effect that the instruction has on the CPU
flags.

INPUT/OUTPUT
IN
OUT

The details of the syntax of the instruction set are described fully in Intel's "ASM86 Language Reference
Manual," # 121703. A shorter treatment of the assembly language can be found in Intel's "An Introduction to ASM 86" manual, # 121689.

Input byte or word
Output byte or word
ADDRESS OBJECT

LEA
LOS
LES

Instruction Set Organization
The instructions are divided into the' following functional groups:

•
•
•
•
•
•
•

Move byte or word
Push word onto stack
Pop word off stack
Push all registers on stack
Pop all registers from stack
Exchange byte or word
Translate byte

Load effective address
Load pointer using OS
Load pointer using ES
FLAG TRANSFER

LAHF
SAHF
PUSHF
POPF

Data transfer
Arithmetic

Load AH register from flags
Store AH register in flags
Push flags onto stack
Pop flags off stack

Bit manipulation
String manipulation
Control transfer
High-level (186,188 only)
Processor control

GENERAL PURPOSE DATA TRANSFERS:
MOV destination, source

Data Transfer Instructions
The data transfer instructions (Table 3-4) move
single bytes, words, and doublewords between
memory and registers, as well as between register
AL or AX and I/O ports. The stack manipulation instructions are included in this group, as are instructions for transferring flag contents and for loading
segment registers.
Sub-groups of the data transfer instructions are the
general purpose data transfer, 110, address object,
and flag transfer instructions.

MOV transfers a byte or a word from the source
operand to the destination operand.

PUSH source

PUSH decrements SP (the stack pointer) by two and
then transfers a word from the source operand to
the top of the stack now pointed to by SP. PUSH is
often used to place parameters on the stack before
calling a procedure; more generally, it is the basic
means of storing temporary data on the stack.
3-20

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

first byte in the table has an offset of O. For example,
if AL contains 5H, and the sixth element of the
translation table contains 33H, then AL will contain
33H following the instruction. XLAT is useful for
translating characters from one code to another,
such as ASCII to EBCDIC or the reverse.

PUSH immediate (186,188 only)

The PUSH (push immediate) instruction allows immediate data to be pushed onto the stack. The data
can be either immediate byte or immediate word.
Byte data will be sign extended to word size before it
is pushed onto the stack (since all stack operations
are done on word data).

POP destination

INPUT/OUTPUT:

POP transfers the word at the current top of stack
(pointed to by SP) to the destination operand, and
then increments SP by two to point to the new top of
the stack. POP can be used to move temporary variables from the stack to registers or memory.

IN accumulator, port

PUSHAIPOPA (186,188 only)

These instructions (push all, pop all) allow all CPU
general purpose registers to be stored and restored.
The PUSHA instruction pushes all CPU registers
onto the stack, and the POPA instruction pops all
CPU registers from the stack. The order in which
the registers are saved is: AX, CX, DX, BX, SP, BP,
SI and DI. The SP value pushed is the SP value
before the first register (AX) is pushed. When the
POPA instruction is executed, the SP value is
popped, but the value is discarded.
Note that this instruction does not save any of the
segment registers (CS, DS, SS, ES), the instruction
pointer (IP), the flag register, or any of the integrated peripheral registers.

IN transfers a byte or a word from an input port to
the AL register or the AX register respectively. The
port number may be specified either with an immediate byte constant, allowing access to ports numbered
o through 255, or with a number previously placed
in the DX register, allowing variable access (by
changing the value in DX) to ports numbered from
o through 65,535.
OUT port, accumulator

OUT transfers a byte or a word from the AL register
or the AX register, respectively, to an output port.
The port number may be specified either with an immediate byte constant, allowing access to ports numbered 0 through 255, or with a number previously
placed in register DX, allowing variable access (by
changing the value in DX) to ports numbered from
othrough 65,535.

ADDRESS OBJECT TRANSFERS:
XCHG destination, source

XCHG (exchange) switches the contents of the
source and destination (byte or word) operands.
When used in conjunction with the LOCK prefix,
XCHG can test and set a semaphore that controls
access to a resource shared by multiple processors.

XLAT translate-table
XLAT (translate) replaces a byte in the AL register
with a byte from a 256-byte, user-coded translation
table. Register BX is assumed to point to the beginning of the table. The byte in AL is used as an index
into the table and is replaced by the byte at the offset
in the table corresponding to AL's binary value. The
3-21

These instructions manipulate the addresses of variables rather than the contents or values of variables.
They are most useful for list processing, based
variables, and string operations.

LEA destination, source
LEA (load effective address) transfers the offset of
the source operand (rather than its value) to the
destination operand. The source operand must be a
memory operand, and the destination operand must
be a 16-bit general register. LEA does not affect any
flags. The XLAT and string instructions assume that
certain registers point to operands. LEA can be used
to load these registers (e.g., loading BX with the address of the translate table used by the XLAT
instruction) .
210911

THEiAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

LOS destination. source

LDS (load pointer using DS) transfers a 32-bjt pointer variable from the source operand, which must be
a memory operand, to the destination operand and
register DS. The offset word of the pointer is transferred to the destination operand, which may be any
16-bit general register. The segment word of the
pointer is transferred to register DS. Specifying SI as
the destination operand is a convenient way to prepare to process a source string that is not in the current data segment (string instructions assume. that
the source string is located in the current data segment an~ that SI contains the offset of the string).

LAHF,
SAHF

IS,Z,U,A,U,P,u,cl

17

6

5

4

32

1

01

1_8080/8085 FLAGS_I
I
I

I

~g~~F'1 U

U , U I U , 0 10 I I , T, S
15 14 13 12 11 10 9 8 7
I

I

I

Z
6

I

U
5

I

A
4

I

U
3

I

P, U I C
2 1 0

I

U = UNDEFINED; VALUE IS INDETERMINATE

o = OVERFLOW FLAG

D = PIRECTION FLAG
I = I.NTERRUPT ENABLE FLAG
T "TRAP FLAG
s= SIGN FLAG
ZERO FlAG
A = AUXILIARY CARRY FLAG
P = PARITY FLAG
,.c; = CARRY FLAG

z=

LES destination. source

LES (load pointer using ES) transfers a 32-bit pointer variable from the source operand, which must be
a memory operand, to the destination operand and
register ES. The offset word of the pointer is transferred to the destination operand, which may be any
16-bit register. The segment word of the pointer is
transferred to register ES. Specifying DI as the destination operand is a convenient way to prepare to process a destination string that is not in the current
extra segment. (The destination string must be locat- .
ed in the extra segment, and DI must contain the
offset of the string.)
FLAG TRANSFERS:

LAFH
LAHF (load register AH froni flags) copies SF, ZF,
AF, PF and CF (the 8080/8085 flags) into bits 7, 6,
4, 2 and 0 respectively, of register AH (see Figure
3-28). The contents of bits 5, 3 and 1 is undefined;
the flags themselves are not affected. LAHF is
provided primarily for converting 8080/8085 assembly language programs to run on 8086 and 80186
CPUs.

Figure 3-28 Flag Storage Formats

POPF
POPF transfers specific bits from the word at the current top of stack (pointed to by register SP) into
flags, replacing whatever values the flags previously
contained (see Figure 3-28). SP is then incremented
by two to point to the new top of stack. PUSHF and
POPF allow a procedure to save and restore a calling
program's flags.

Arithmetic Instructions
Arithmetic operations (Table 3-5) may be performed
on four types of numbers: unsigned binary, signed
binary (integers), unsigned packed decimal and unsigned unpacked decimal (see Table 3-6). Binary
numbers may be 8 or 16 bits long. Decimal numbers
are stored in bytes, two digits per byte for packed
decimal and one digit per byte for unpacked decimal.
The processor always assumes that the operands
specified in arithmetic instructions contain data that
represents valid numbers for the type of instruction
being performed. Invalid data may produce unpredictable results.

SAHF
SAHF (stOle register AH into flags) transfers bits 7,
6,4,2 and 0 from register AH into SF, ZF, AF, PF
and CF respectively, replacing whatever values
these flags previously had. OF, DF, IF and TF are
not affected. This instruction is provided for
8080/8085 compatibility.

PUSHF
PUSHF decrements SP (the stack pointer) by two
and then transfers all flags to the word at the top of
stack pointed to by SP (see Figure 3-28). The flags
themselves are not affected.
3-22

Unsigned binary numbers may be either 8 or 16 bits
long; all bits are considered in determining a number's magnitude. The value range of an 8-bit unsigned binary number is 0-255. Values from 0 to
65,535 can be. represented by 16 bits. Addition,
subtraction, multiplication and division operations
are available for unsigned binary numbers.
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

positive sign. Multiplication and division operations
are provided for signed binary numbers. Addition
and subtraction are performed with the unsigned
binary instructions. Conditional jump instructions,
as well as .an "interr\lpt on overflow" instruction,
can be used following an unsigned operation on an
integer to detect overflow into the sign bit.

Table 3·5 Arithmetic Instructions

ADD
ADC
INC
AAA
DAA
SUB
SBB
DEC
NEG
CMP
AAS
DAS
MUL
IMUL
AAM
DIV
IDIV
AAD
CBW
CWD

ADDITION
Add byte or word
Add byte or word with carry
Increment byte or word by 1
ASCII adjust for addition
Decimal adjust for addition

Packed decimal numbers are stored as unsigned
byte quantities. The byte is treated as having one
decimal digit in each half-byte (nibble); the digit in
the high-order half-byte is the most significant.
Hexadecimal values 0-9 are valid in each half-byte,
and the range of a packed decimal number is 0-99.
Addition and subtraction are performed in two
steps. First an unsigned binary instruction is used to
produce an intermediate result in register AL. Then
an adjustment operation is performed which
changes the intermediate value in AL to a final correct packed decimal result. Multiplication and division adjustment are not available for packed decimal
numbers.

SUBTRACTION
Subtract byte or word
Subtract byte or word with
borrow
Decrement byte or word by 1
Negate byte or word
Compare byte or word
ASCII adjust for subtraction
Decimal adjust for subtraction
MULTIPLICATION
Multiply byte or word unsigned
Integer multiply byte or word
ASCII adjust for multiply
DIVISION
Divide byte or word unsigned
Integer divide byte or word
ASCII adjust for division
Convert byte to word
Convert word to doubleword

1
Unpacked decimal numbers are stored as unsigned
byte quantities. The magnitude of the number is
determined from the low-order half-byte. Hexadecimal values 0-9 are valid and are interpreted as decimal numbers. The high-order half-byte must be
zero for multiplication and division; it may contain
any value for addition and subtraction. Arithmetic
operations on unpacked decimal numbers are performed in two steps. The unsigned binary addition,
subtraction and multiplication operations are used to
produce an intermediate result in register AL. An
adjustment instruction then changes the value in AL
to a final correct unpacked decimal number. Division
is performed similarly, except that the adjustment is
carried out on the numerator operand in register AL
first, and then a following unsigned binary division
instruction produces a correct result.

Signed binary numbers (integers) may be 8 or 16
bits long. The high-order (leftmost) bit is interpreted
as the number's sign: 0 = positive and 1 = negative.
Negative numbers are represented in standard two's
complement notation. Since the high-order bit is
used as a sign, the range of an 8-bit integer is -128
through + 127; 16-bit integers may range from
- 32,768 through +32,767. The value of zero has a

Table 3·6 Arithmetic Interpretation of a·Bit Numbers

HEX

BIT PATTERN

,

I

UNSIGNED
BINARY

SIGNED
BINARY

UNPACKED
DECIMAL

PACKED
DECIMAL

+7

7

7

07

o0 0 0 0 1 1 1

7

89

10001001

137

-119

Invalid

89

C5

11000101

197

-59

Invalid

Invalid

3-23

210911

THE iAPX 86,88.AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

binary numbers, the sign flag will be 0 for
positive results and 1 for negative results (so
long as overflow does not occur). A conditional jump instruction can be used following
addition or subtraction to alter the flow of the
program depending on the sign of the result.
Programs performing unsigned operations
typically ignore SF since the high-order bit of
the result is interpreted as a digit rather than a
sign.

Unpacked decimal numbers are similar to the ASCII
character representations of the digits 0-9. Note,
however, that the high-order half-byte of an ASCII
numeral is always 3H. Unpacked decimal arithmetic
may be performed on ASCII numeric characters
under the following conditions:
•

the high-order half-byte of an ASCII numeral
must be set to OH prior to multiplication or
division.

•

unpacked decimal arithmetic leaves the highorder half-byte set to OH; it must be set to 3H
to produce a valid ASCII numeral.

•

or logical operation is zero, then ZF is set;
otherwise ZF is cleared. A conditional jump
instruction can be used to alter the flow of the
program if the result is or is not zero.
•

Arithmetic instructions post certain characteristics
of the result of the operation to six flags. Most of
these flags can be tested by following the arithmetic
instruc~ion with a conditional jump instruction, and
the INTO (interrupt on overflow) instruction may
also be used. The various instructions affect the flags
differently, as explained in the instruction
descriptions. However, they follow these general
rules:

•

AF (auxiliary carry flag): If an addition re-

sults in a carry out of the low-order half-byte
of the result, then AF is set; otherwise AF is
cleared. If a subtraction results in a borrow
into the low-order half-byte of the result,
then AF is set; otherwise AF is cleared. The
auxiliary carry flag is provided for the decimal
adjust instructions and ordinarily is not used
for any other purpose.
•

•

SF (sign flag): Arithmetic and logical in-

structions set the sign flag equal to the highorder bit (bit 7 or 15) of the result. For signed

OF (overflow flag): If the result of an opera-

tion is too large a positiye number, or too
small a negative number (0 fit in the destination operand (excluding the sign bit), then
OF is set; otherwise OF is cleared. OF thus indicates signed arithmetic overflow. It can be
tested with a conditional jump or the INTO
(interrupt on overflow) instruction. OF may
be ignored when performing unsigned
arithmetic. OF is set if the operation results in
a carry into the high-order bit of the result
but not a carry out of the high-order bit, or
vice versa; otherwise OF is cleared.

CF (carry flag): If an addition results in a

carry out of the high-order bit of the result,
then CF is set; otherwise CF is cleared. If a
subtraction results in a borrow into the highorder bit of the result, then CF is set; otherwise CF is cleared. Note that a signed carry is
indicated by CF = OF (overflow flag). CF
can be used to detect an unsigned overflow.
Two instructions, ADC (add with carry) and
SBB (subtract with borrow), incorporate the
carry flag in their operations and can be used
to perform multibyte (e.g., 32-bit, 64-bit) addition and subtraction.

PF (parity flag): If the low-order eight bits

of an arithmetic or logical result contain an
even number of 1- bits, then the parity flag is
set; otherwise it is cleared. PF is provided for
8080/8085 compatibility. It can also be used
to check ASCII characters for correct parity.

ARITHMETIC INSTRUCTIONS AND FLAGS

•

ZF (zero flag): If the result of an arithmetic

ADDITION

ADD destination, source
The sum of two operands, which may be bytes or
words, replaces the destination operand. Both operands may be signed or unsigned binary numbers
(see AAA and DAA). ADD updates AF, CF, OF,
PF, SF and ZF.

ADC destination, source
ADC (add with carry) sums the operands, which
may be bytes or words, adds one if CF is set and replaces the destination operand with the result. Both
operands may be signed or unsigned binary numbers
(see AAA and DAA). ADC updates AF, CF, OF,
PF, SF and ZF. Since ADC incorporates a carry
from a previous operation, it can be used to write
routines to add numbers longer than 16 bits.
3-24

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

INC destination

NEG destination

INC (increment) adds one to the destination
operand. The operand may be a byte or a word and
is treated as an unsigned binary number (see AAA
and DAA). INC updates AF, OF, PF, SF and ZF; it
does not effect CF.

NEG (negate) subtracts the destination operand,
which may be a byte or a word, from 0 and returns
the result to the destination. This forms the two's
complement of the number, effectively reversing
the sign of an integer. If the operand is zero, its sign
is not changed. Attempting to negate a byte containing -128 or a word containing - 32,768 causes no
change to the operand and sets OF. NEG updates
AF, CF, OF, PF, SF and ZF. CF is always set except
when the operand is zero, in which case it is cleared.

AAA
AAA (ASCII adjust for addition) changes the contents of register AL to a valid unpacked decimal
number; the high-order half-byte is zeroed. AAA
updates AF and CF; the contents of OF, PF, SF and
ZF is undefined following execution of AAA.

CMP destination, source

CMP (compare) subtracts the source from the
destination, which may be bytes or words, but does
not return the result. The operands are unchanged,
but the flags are updated and can be tested by a subsequent conditional jump instruction. CMP updates
AF, CF, OF, PF, SF and ZF. The comparison reflected in the flags is that of the destination to the
source. If a CMP instruction is followed by a JG
(jump if greater) instruction, for example, the jump
is taken if the destination operand is greater than the
source operand.

DAA
DAA (decimal adjust for addition) corrects the
result of previously adding two valid packed decimal
operands (the destination operand must have been
register AL). DAA changes the contents of AL to a
pair of valid packed decimal digits. It updates AF,
CF, PF, SF and ZF; the contents of OF is undefined
following execution ofDAA.

AAS
AAS (ASCII adjust for subtraction) corrects the
result of a previous subtraction of two valid unpacked decimal operands (the destination operand
must have been specified as register AL). AAS
changes the contents of AL to a valid unpacked decimal number; the high-order half-byte is zeroed.
AAS updates AF and CF; the contents of OF, PF,
SF and ZF is undefined following execution of AAS.

SUBTRACTION
SUB destination, source

The source operand is subtracted from the destination operand, and the result replaces the destination
operand. The operands may be signed or unsigned
binary numbers (see AAS and DAS). SUB updates
AF, CF, OF, PF, SF and ZF.

DAS
DAS (decimal adjust for subtraction) corrects the results of a previous subtraction of two valid packed
decimal operands (the destination operand must
have been specified as register AL). DAS changes
the contents of AL to a pair of valid packed decimal
digits. DAS updates AF, CF, PF, SF and ZF; the
contents of OF is undefined following execution of
DAS.

SBB destination, source

SBB (subtract with borrow) subtracts the source
from the destination, subtracts one if CF is set, and
returns the result to the destination operand. Both
operands may be bytes or words. Both operands may
be signed or unsigned binary numbers (see AAS
and DAS). SBB updates AF, CF, OF, PF, SF and
ZF. Since it incorporates a borrow from a previous
operation, SBB may be used to write routines that
subtract numbers longer than 16 bits.

MULTIPLICATION
DEC destination

MUL source

DEC (decrement) subtracts one from the
destination, which may be a byte or a word. DEC updates AF, OF, PF, SF and ZF; it does not affect CF.

MUL (multiply) performs an unsigned multiplication of the source operand and the accumulator. If
the source is a byte, then it is multiplied by register
3-25

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

AL, and the double-length result is returned in AH
and AL. If the source operand is a word, then it is
multiplied by register AX, and the double-length
result is returned in registers DX and AX. The operands are treated as unsigned binary numbers (see
AAM). If the upper half of the results (AH for byte
source, DX for word source) is nonzero, CF and OF
are set; otherwise they are cleared. When CF and
OF are set, they indicate that AH or DX contains significant digits of the result. The contents of AF, PF,
SF and ZF is undefined following execution ofMUL.
IMUL source

IMUL (integer multiply) performs a signed multiplication of the source operand and the accumulator. If
the source is a byte, then it is multiplied by register
AL, and the double-length result is returned in register AH and AL. If the source is a word, then it is
multiplied by register AX, and the double-length
result is returned in registers DX and AX. If the
upper half of the result (AH for byte source, DX for
word source) is not the sign extension of the lower
half of the result, CF and OF are set; otherwise they
are cleared. When CF and OF are set, they indicate
that AH or DX contains significant digits of the
result. The content of AF, PF, SF and ZF is undefined following execution ofiMUL.
IMUL destination-register, source, immediate
(186,188 only)

The IMUL (integer immediate multiply, signed) instruction allows a value to be multiplied by an immediate value. This value may be a byte or word; if
iUs a byte, it will be sign extended to 16 bits. When
this instruction is used, only the lower 16 bits of the
result will be saved. The result must always be
placed in one of the general purpose registers. The
two operands are the immediate value, and the data
at an effective address (which may be the same register in which the result will be placed, another
register, or a memory location). This instruction requires three arguments: the immediate value, the
effective address of the second operand, and the
register in which the result is to be placed.

AAM

AAM (ASCII adjust for multiply) corrects the result
of a previous multiplication of two valid unpacked
decimal operands. A valid 2-digit unpacked decimal
number is derived from the content of AH and AL
and is returned to AH and AL. The high-order halfbytes of the multiplied operands must have been OH
for AAM to produce a correct result. AAM updates
PF, SF and ZF; the content of AF, CF and OF is undefined following execution of AAM.

DIVISION

DIVsource

DIV (divide) performs an unsigned division of the
accumulator (and its extension) by the source
operand. If the source operand is a byte, it is divided
into the double-length dividend assumed to be in
register AH and AL. The single-length quotient is returned in AL, and the single-length remainder in
AH. If the source operand is a word, it is divided
into the double-length dividend in registers DX and
AX. The single-length quotient is returned in AX,
and the single-length remainder is returned in DX.
If the quotient exceeds the capacity of its destination
register (FFH for byte source, OFFFFH for word
source), as when division by zero is attempted, a
type 0 interrupt is generated, and the quotient and
the remainder are undefined. Nonintegral quotients
are truncated to integers. The content of AF, CF,
OF, PF, SF and ZF is undefined following execution
ofDIV.
IDIV source

IDIV (integer divide) performs a signed division of
the accumulator (and its extension) by the source
operand. If the source operand is a byte, it is divided
into the double-length dividend assumed to be in
registers AH and AL. The single-length quotient is
returned in AL, and the single-length remainder is
returned in AH. For byte integer division,the maximum positive quotient is + 127 (7FH) and the minimum negative quotient is -127 (81 H). If the source
operand is a word, it is divided into the doublelength dividend in registers DX and AX (the highorder 16 bits are in DX and the low-order 16 bits in
AX). The single-length quotient is returned in AX,
and the the single-length remainder is returned in
DX. For word integer division, the maximum positive quotient is + 32,767 (7FFFH) and the minimum
negative quotient is -32,767 (8001H). If the quotient is positive and exceeds the maximum, or is
negative and is less then the minimum, the quotient
and the remainder are undefined, and a type 0 interrupt is generated. In particular, this occurs if division
by 0 is attempted. N onintegral quotients are truncated (toward 0) to integers, and the remainder has the
same sign as the dividend. The content of AF, CF,
OF, PF, SF and ZF is undefined following execution
ofIDIV.

AAD

AAD (ASCII adjust for division) modifies the
numerator in AL before dividing two valid unpacked
decimal operands so that the quotient produced by
the division will be a valid unpacked decimal
number. AH must be zero for the subsequent DIV
3-26

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

to produce the correct result. The quotient is returned in AL, and the remainder is returned in AH;
both high-order half-bytes are zeroed. AAD updates
PF, SF and ZF; the content of AF, CF and OF is undefined following execution of AAD.

LOGICAL

The logical instructions include the boolean operators "not," "and," "inclusive Of," and "exclusive
or," plus a TEST instruction that sets the flags, but
does not alter either of its operands.

CBW

CBW (convert byte to word) extends the sign of the
byte in register AL throughout register AH. CBW
does not affect any flags. CBW can be used to produce a double-length (word) dividend from a byte
prior to performing byte division.
CWD

CWD (convert word to doubleword) extends the
sign of the word in register AX throughout register
DX. CWD does not affect any flags. CWD can be
used to produce a double-length (doubleword) dividend from a word prior to performing word division.

Bit Manipulation Instructions
Three groups of instructions (Table 3-7) are available for manipulating bits within both bytes and
words: logical, shift and rotates.

AND, OR, XOR and TEST affect the flags as
follows:
The overflow (OF) and carry (CF) flags are always
cleared by logical instructions, and the contents of
the auxiliary carry (AF) flag is always undefined following execution of a logical instruction.
The sign (SF), zero (ZF) and parity (PF) flags are
always posted to reflect the result of the operation
and can be tested by conditional jump instructions.
The interpretation of these flags is the same as for
arithmetic instructions. SF is set if the result is negative (high-order bit is 1), and is cleared if the result
is positive (high-order bit is 0). ZF is set if the result
is zero, cleared otherwise. PF is set if the lower
8-bits of the result contains an even number of
I-bits (has even parity) and is cleared if the number
ofl-bits is odd (the result has odd parity).
Note that NOT has no effect on the flags.

NOT destination
NOT inverts the bits (forms the one's complement)
of the byte or word operand.

Table 3- 7 Bit Manipulation Instructions

LOGICALS

NOT
AND
OR
XOR
TEST

"Not" byte or word
"And" byte or word
"Inclusive or" byte or word
"Exclusive or" byte or word
"Test" byte or word
SHIFTS

SHLISAL
SHR
SAR

Shift logical I arithmetic left
byte or word
Shift logical right byta or word
Shift arithmetic right byte or
word
ROTATES

ROL
ROR
RCL
RCR

Rotate left byte or word
Rotate right byte or word
Rotate through carry left byte
or word
Rotate through carry right byte
or word

AND destination, source
AND performs the logical "and" of the two operands (byte or word) and returns the result to the
destination operand. A bit in the result is set if both
corresponding bits of the original operands are set;
otherwise the bit is cleared.

OR destination, source
OR performs the logical "inclusive or" of the two
operands (byte or word) and returns the result to
the destination operand. A bit in the result is set if
either or both corresponding bits in the original operands are set; otherwise the result bit is cleared.
XOR destination, source
XOR (exclusive or) performs the logical "exclusive
or" of the two operands and returns the result to the
destination operand. A bit in the result is set if the
corresponding bits of the original operands contain
opposite values (one is set, the other is cleared);
otherwise the result bit is cleared.
3-27

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

TEST destination, source

SAR destination, count

TEST performs the logical "and" of the two operands (byte or word), updates the flags, but does not
return the result, i.e., neither operand is changed. If
a TEST instruction is followed by a JNZ (jump if not
zero) instruction, the jump will be taken if there are
any corresponding I-bits in both operands.

SAR (shift arithmetic right) shifts the bits in the
destination operand (byte or word) to the right by
the number of bits specified in the count operand.
Bits equal to the original high-order (sign) bit are
shifted in on the left, preserving the sign of the original value. Note that SAR does not produce the same
result as the dividend of an "equivalent" IDIV instruction if the destination operand is negative and
I-bits are shifted out. For example, shifting - 5 right
by one bit yields - 3, while integer division of - 5 by
2 yields - 2. The difference in the instructions is that
IDIV truncates all numbers toward zero, while SAR
truncates positive numbers toward zero and negative
num bers toward negative infinity.

SHIFTS

The bits in bytes and words may be shifted arithmetically or logically. On the 8086,88 up to 255 shifts
may be performed, according to the value of the
count operand coded in the instruction. The count
may be specified as the constant 1, or as register CL,
allowing the shift count to be a variable supplied at
execution time. In addition, the 80186,188 allow the
number of shifts to be specified as an immediate
value in the instruction. This eliminates the need for
a MOV immediate to the CL register if the number
of shifts required is known at assembly time. Before
the 80186,188 perform a shift (or rotate) they AND
the value to be shifted with IFH, thus limiting the
number of shifts occurring to 32 bits.
Arithmetic shifts may be used to multiply and divide
binary numbers by powers of two (see note in description of SAR). Logical shifts can be used to isolate bits in bytes or words.
Shift instructions affect the flags as follows:
AF is always undefined following a shift operation.
PF, SF and ZF are updated normally, as in the logical
instructions. CF always contains the value of the last
bit shifted out of the destination operand. The contents of OF is always undefined following a multibit
shift. In a single-bit shift,OF is set if the value of the
high-order (sign) bit was changed by the operation;
if the sign bit retains its original value, OF is cleared.
SHLISAL destination, count

SHL and SAL. (shift logical left and shift arithmetic
left) perform the same operation and are physically
the same instruction. The destination byte or word is
shifted left by the number of bits specified in the
count operand. Zeroes are shifted in on the right. If
the sign bit retains its original value, then OF is
cleared.

ROTATES

Bits in bytes and words may also be rotated. Bits
rotated out of an operand are not lost as in a shift,
but are "circled" back into the other "end" of the
operand. As in the shift instructions, the number of
bits to be rotated is taken from the count operand,
which may specify either a constant 1, or the CL
register. The carry flag may act as an extension of
the operand in two of the rotate instructions, allowing a bit to be isolated in CF and then tested by a JC
(jump if carry) or JNC (jump if not carry)
instruction.
Rotates affect only the carry and overflow flags. CF
always contains the value of the last bit rotated out.
On multibit rotates, the value of OF is Always
undefined. In single-bit rotates, OF is set if the operation changes the high-order (sign) bit of the destination operand. If the sign bit retains its original
value, OF is cleared.
. ROL destination, count

ROL (rotate left) rotates the destination byte or
word by the number of bits specified in the count
operand.

ROR destination, count
ROR (rotate right) operates similar to ROL except
that the bits.in the destination byte or word are rotated right instead ofleft.

SHR destination, source

SHR (shift logical right) shifts the bits in the destination operand (byte or word) to the right by. the
number of bits specified in the count operand. Zeros
are shifted in on the left. If the sign bit retains its
original value, then OF is cleared.

RCL destination, count
RCL (rotate through carry left) rotates the bits in
the byte or word destination operand to the left by
the number of bits specified in the count operand.
3-28

210911

I

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

.'1

The carry flag (CF) is treated as "part of' the destination operand; that is, its value is rotated into the
low-order bit of the destination, and itself is replaced
by the high-order bit of the destination.

RCR destination, count
RCR (rotate through carry right) operates exactly
like RCL except that the bits are rotated right instead
of left.

,I

Table 3-8 String Instructions

-;;

\

REP

Repeat

REPE/REPZ

Repeat while equal/zero

REPNE/REPNZ

Repeat while not
equal/not zero

MOVS

Move byte or word string

MOVSB/MOVSW

Move byte or word string

CMPS

SCAS

Compare byte or word
string
Move byte or word
string from I/O port
Move byte or word
string to I/O port
Scan byte or word string

LODS

Load byte or word string

STOS

Store byte or word string

Immediate Shifts/Rotates
All the shift/rotate instructions of the 80186,188
allow the number of bits shifted to be specified by an
immediate value. These instructions require two
operands: the operand to be shifted (which may be a
register or a memory location specified by any of the
addressing modes) and the number of bits to be
shifted.

String Instructions
The basic string instructions, also called primitives,
operate on strings of bytes or words, one element
(byte or word) at a time. Strings of up to 128K bytes
may be manipulated with these instructions. Instructions are available to move, compare and scan for a
value, as well as for moving string elements to and
from the accumulator, and, in the case of the
80186,188, to and from I/O ports (see Table 3-8).
These basic operations may be preceded by a special
one-byte prefix that causes the instruction to be
repeated by the hardware, processing long strings
much faster than would be possible with a software
loop. The repetitions can be terminated by a variety
of conditions, and a repeated operation may be interrupted and resumed.

INS
OUTS

SI (source index) is used as an offset to address the
current element of the source string, and the contents of register D I (destination index) is taken as
the offset of the current destination string element.
These registers must be initialized to point to the
source/destination strings before executing the
string instruction; the LDS, LES and LEA instructions are useful in this regard.
Tl;lble 3-9 String Instruction
Register and Flag Use

The string instructions operate similarly in many
respects; the common characteristics are covered
here and in Table 3-9 and in Figure 3-29, rather than
in the descriptions of the individual instructions. A
string instruction may have a source operand, a
destination operand, or both. The hardware assumes
that a source string resides in the current data
segment; a segment prefix byte may. be used to override this assumption. A destination string must be in
the current extra segment. The assembler checks
the attributes of the operands to determine if the elements of the strings are bytes or words. The assembler does not, however, use the operand names to
address the strings. Rather, the contents of register
3-29

SI

Index (offset) for source string

DI

Index (offset) for destination
string

DX

Port Address

CX

Repetition counter

ALiAX

Scan value
Destination for LODS
Source for STOS

DF

0= auto-increment SI, DI
1 = auto-decrement SI, DI

ZF

Scan/compare terminator

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

SI/DI,CX
{ AND DFWOULD
TYPICALLY BE
INITIALIZED HERE

!

/

STRING

OF

DELTA

.' BYTE
BYTE
WORD
WORD

0
1
0
1

1
-1
2
-2

PREFIX

Z

REPE
REPZ
REPNE
REPNZ

1
1
0
0

PRESENT

r-----l
I INST~~~TTION I
L _____ J
Figure 3-29 String Operation Flow

3-30

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

The string instructions automatically update SI
and/or DI in anticipation of processing the next
string element. The setting of DF (direction flag)
determines whether the index registers are autoincremented (DF = 0) or auto-decremented
(DF = 1). If byte strings are being processed, SI
and/or DI is adjusted by 1. The adjustment is 2 for
word strings.

instruction; after returning from the interrupt, processing resumes at this point, but any additional prefixes specified are not in effect. On the 80186,188,
however, interrupt string instructions resume executing from the first prefix of the repeated
instruction; thus, interrupted string move instructions with multiple prefixes will resume execution
properly.

If a repeat prefix has been coded, then register CX
(count register) is decremented by I after each repetition of the string instruction. CX must be initialized
to the n urn ber of repetitions desired before the
string instruction is executed. If CX is 0, the string
instruction is not executed, and control goes to the
following instruction.

If more than one prefix must be used with a string instruction executing on the 8086,88, interrupts may
be disabled for the duration of the repeated
execution. However, this will not prevent a nonmaskable interrupt from being recognized. Also, the
time that the system is unable to respond to interrupts may be unacceptable if long strings are being
processed.

Section 3.8 contains examples illustrating the use of
string instructions.

REP/REPE/REPZ/REPNE/REPNZ
Repeat, Repeat While Equal, Repeat While Zero,
Repeat While Not Equal, and Repeat While Not
Zero are five mnemonics for three forms of the
prefix byte that controls repetition of a subsequent
string instruction. The different mnemonics are
provided to improve program clarity. The repeat prefixes do not affect the flags.
REP is used in conjunction with the MOVS (move
string), the STOS (store string), the INS (in string)
and OUTS (out string) instructions and is interpreted as "repeat while not end-of-string" (CX not 0).
REPE and REPZ operate identically and are physically the same prefix byte as REP. These instructions
are used with the CMPS (compare string) and SCAS
(scan string) instructions and require ZF (posted by
these instructions) to be set before initiating the
next repetition. REPNE and REPNZ are two
mnemonics for the same prefix byte. These instructions function the same as REPE and REPZ except
that the zero flag must be cleared or the repetition is
terminated. Note that ZF does not need to be initialized before executing the repeated string instruction.
Repeated string sequences are interruptable; the processor recognizes the interrupt before processing the
next string element. System interrupt processing is
not affected in any way. Upon return from the
interrupt, the repeated operation is resumed from
the point of interruption. Note, however, that on the
8086,88 execution does not resume properly if a
second or third prefix (i.e., segment override or
LOCK) has been specified in addition to any of the
repeat prefixes. The processor "remembers" only
one prefix in effect at the time of the interrupt, i.e.,
the prefix that immediately precedes the string

Repeated string instructions (MOVS, INS, OUTS)
operate at full bus bandwidth on the 80186,188, allowing very high speed memory-to-memory and
memory-to-I/O transfers by the CPU.

MOVS destination-string, source-string

MOVS (move string) transfers a byte or a word
from the source string (addressed by SI) to the destination string (addressed by DI) and updates SI and
DI to point to the next string element. When used in
conjunction with REP, MOVS performs a memoryto-memory block transfer.
MOVSB/MOVSW

These are alternate mnemonics for the move string
instruction. These mnemonics are coded without
operands. They tell the assembler explicitly that a
byte string (MOVSB) or a word string MOVWS) is
to be moved (when MOVS is coded, the assembler
determines the string type from the attribute of the
operands). These mnemonics are useful when the
assembler cannot determine the attributes of a
string, e.g., when a section of code is being moved.

CMPS destination-string,

source-string

CMPS (compare string) subtracts the destination
byte or word (addressed by DO from the source
byte or word (addressed by SO. CMPS affects the
flags but does not alter either operand, updates SI
and DI to point to the next string element and updates AF, CF, OF, PF, SF and ZF to reflect the relationship of the destination element to the source
element. For example, if a JG (jump if greater) instruction fonows CMPS, the jump is taken if the
destination element is greater than the source
3-31

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

element. If the CMPS is prefixed with REPE or
REPZ, the operation is interpreted as "compare
while not end-of-string (CX not zero) and strings
are equal (ZF = 1)." If CMPS is preceded by REPNE
or REPNZ, the operation is interpreted as "compare
while not end-of-string (CX not zero) and strings
are not equal (ZF=O)." Thus, CMPS can be used to
find matching or differing string elements.

seAS destination-string
SCAS (scan string) subtracts the destination string
element (byte or word) addressed by DI from the
contents of AL (byte string) or AX (word string)
and updates the flags, but does not alter the destination string or the accumulator. SCAS also updates
DI to point to the next string element and AF, CF,
OF, PF, SF and ZF to reflect the relationship of the
scan value in ALI AX to the string element. If SCAS
is prefixed with REPE or REPZ, the operation is interpreted as "scan while not end-of string (CX not
0) and string-element = scan-value (ZF=1)." This
form may be used to scan for departure from a given
value. If SCAS is prefixed with REPNE or REPNZ,
the operation is interpreted as "scan while not endof-string (CX not 0) and string-element is not equal
to scan-value (ZF=O)." This may be used to locate
a value in a string.
LODS source-string

LODS (load string) transfers the byte or word string
element addressed by SI to register AL or AX, and
updates SI to point to the next element in the string.
This instruction is not ordinarily repeated since the
accumulator would be overwritten by each
repetition, and only the last element would be
retained. However, LaDS is very useful in software
loops as part of a more complex string function built
up from string primitives and other instructions.
STOS destination-string

STOS (store string) transfers a byte or word from
register AL or AX to the string element addressed
by DI and updates DI to point to the next location in
the string. As a repeated operation, STOS provides a
convenient way to initialize a string to a constant
value (e.g., to blank out a print line).
INS source-string, port (186,88 only)
OUTS port, destination-string

INS and OUTS (in string, out string) instructions
perform block input/output. Their operation is similar to the string move instructions. In both the INS

and OUTS instructions, the port address is placed in
the DX register. For INS, the memory address is
placed in the DI register; for OUTS, the memory address is placed in the SI register. In the case of INS,
the segment register used is the ES register, and this
may not be overridden. In the case of OUTS, the
segment register used is the DS register; this may be
overridden with a segment override instruction. In
both cases, after the transfer has taken place (in two
subsequent bus cycles), the pointer register is incremented or decremented (depending on the state of
the DF flag) by an appropriate amount (1 for byte, 2
for word transfers).

Control Transfer Instructions
The sequence of instructions executing in an
8086,88 or 80186,188 program is determined by the
contents of the code segment register (CS) and the
instruction pointer OP). The CS register contains
the base address of the current code segment, the
64K portion of memory from which instructions are
presently being fetched. The IP is used as an offset
from the beginning of the code segment; the combination of CS and IP points to the memory location
from which the next instruction is to be fetched.
(Under most operating conditions, the next instruction to be executed has already been fetched from
memory and is waiting in the CPU instruction
queue.) The program transfer instructions operate
on the instruction pointer and on the CS register;
changing the contents of these causes normal
sequential execution to be altered. When a program
transfer occurs, the queue no longer contains the
correct instruction, and the BIU obtains the next instruction from memory using the new IP and CS
values, passes the instruction directly to the EU, and
then begins refilling the queue from the new
location.
Four groups of program transfers are available (see
Table 3-10): unconditional transfers, conditional
transfers, iteration control instructions and
interrupt-related instructions. Only the interruptrelated instructions affect any CPU flags. However,
the execution of many of the program transfer instructions is affected by the states of the flags.
UNCONDITIONAL TRANSFERS

The unconditional transfer instructions may transfer
control to a target instruction within the current
code segment (intrasegment transfer) or to a different code segment (intersegment transfer). (The
ASM-86 assembler terms an intr;lsegment target
NEAR and an intersegment target FAR.) The transfer is made unconditionally any time the instruction
is executed.
3-32

210911

I

THE iAPX 86,88 ANDiAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

Table 3-1 0 Program Transfer Instructions

UNCONDITIONAL TRANSFERS
CALL
RET
JMP

Call procedure
Return from procedure
Jump
CONDITIONAL TRANSFERS

JA/JNBE
JAE/JNB
JB/JNAE
JBE/JNA
JC
JE/JZ
JG/JNLE
JGE/JNL
JLlJNGE
JLE/JNG
JNC
JNE/JNZ
JNO
JNP/JPO
JNS
JO
JP/JPE
JS

Jump if above/not below
nor equal
Jump if above or
equal/not below
Jump if below / not above
nor equal
Jump if below or
equal/not above
Jump if carry
Jump if equal/zero
Jump if greater/ not less
nor equal
Jump if greater or
equal/not less
Jump if less/ not greater
nor equal
Jump if less or equal/ not
greater
Jump if not carry
Jump if not equal/not
zero
Jump if not overflow
Jump if not parity / parity
odd
Jump if not sign
Jump if overflow
Jump if parity /parity
even
Jump if sign
ITERATION CONTROLS

LOOP
Loop
LOOPE/LOOPZ
Loop if equal/zero
LOOPNE/ LOOPNZ Loop if not equal/not
zero
JCXZ
Jump if register CX = 0
INTERRUPTS
INT
INTO
IRET

Interrupt
Interrupt if overflow
Interrupt return

CALL procedure-name
CALL activates an out-of-line procedure, saving information on the stack to permit a RET (return) instruction in the procedure to transfer control back to
the instruction following the CALL. The assembler
generates a different type of CALL instruction
depending on whether the programmer has defined
the procedure name as NEAR or FAR. For control
to return properly, the type of CALL instruction
must match the type of RET instruction that exits
from the procedure. (The potential for mismatch
exists if the procedure and the CALL are contained
in separately assembled programs.) Different forms
of the CALL instruction allow the address of the
target procedure to be obtained from the instruction
itself (direct CALL) or from a memory location or
register referenced by the instruction (indirect
CALL).
In the following descriptions, bear in mind that the
processor automatically adjusts IP to point to the
next instruction to be executed before saving it on
the stack.
For an intrasegment direct CALL, SP is decremented
by two and IP is pushed onto the stack. The relative
displacement (up to plus or minus 32K) of the target
procedure from the CALL instruction is then added
to the instruction pointer. This form of the CALL instruction is "self-relative" and is appropriate for
position-independent (dynamically relocatable) routines in which the CALL and its target are in the
same segment and are moved together.
An intrasegment indirect CALL may be made
through memory or through a register. SP is decremented by two and IP is pushed onto the stack. The
offset of the target procedure is obtained from the
memory word or 16-bit general register referenced
in the instruction and replaces IP.
For an inter segment direct CALL, SP is decremented
by two, and CS is pushed onto the stack. CS is replaced by the segment word contained in the
instruction. SP again is decremented by two. IP is
pushed onto the stack and is replaced by the offset
word contained in the instruction.
,

For an inter segment indirect CALL (which may only
be made through memory), SP is decremented by
two, and CS is pushed onto the stack. CS is then replaced by the contents of the second word of the
doubleword memory pointer referenced by the
instruction. SP again is decremented by two, and IP
is pushed onto the stack and is replaced by the contents of the first word of the doubleword pointer
referenced by the instruction.
3-33

210911

I

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

RET optional-pop-value

CONDITIONAL TRANSFERS

RET (return) transfers control from a procedure
back to the instruction following the CALL that activated the procedure. The assembler generates an
intrasegment RET if the programmer has defined
the procedure NEAR, or an inter segment RET if the
procedure has been defined as FAR. RET pops the
word at the top of the stack (pointed to by register
SP) into the instruction pointer and increments SP
by two. If RET is inter segment, the word at the new
top of stack is popped into the CS register, and SP is
again incremented by two. If an optional pop value
has been specified, RET adds that value to SP. This
feature may be used to discard parameters pushed
onto the stack before the execution of the CALL
instruction.

The conditional transfer instructions are jumps that
mayor may not transfer control depending on the
state of the CPU flags at the time the instruction is
executed. These instructions (see Table 3-11) each
test a different combination of flags for a condition.
If the condition is "true," then control is transferred
to the target specified in the instruction. If the condition is "false," then control passes to the instruction
that follows the conditional jump. All conditional
jumps are SHORT, that is, the target must be in the
current code segment and within -128 to + 127
bytes of the first byte of the next instruction (JMP
OOH jumps to the first byte of the next instruction).
Since the jump is made by adding the relative displacement of the target to the instruction pointer, all
conditional jumps are self-relative and are appropriate for position-independent routines.

JMP target

ITERATION CONTROL

JMP unconditionally transfers control to the target
location. Unlike a CALL instruction, JMP does not
save any information on the stack, and no return to
the instruction following the JMP is expected. Like
CALL, the address of the target operand may be obtained from the instruction itself (direct JMP) or
from memory or a register referenced by the instruction (indirect JMP).

The iteration control instructions can be used to
regulate the repetition of software loops. These instructions use the CX register as a counter. Like the
conditional transfers, the iteration control instructions are self-relative and may only transfer to targets that are within -128 to + 127 bytes of
themselves, i.e., they are SHORT transfers.

An intrasegment direct JMP changes the instruction
pointer by adding the relative displacement of the
target from the JMP instruction. If the assembler
can determine that the target is within 127 bytes of
the JMP, it automatically generates a two-byte form
of this instruction called a SHORT JMP; otherwise,
it generates a NEAR JMP that can address a target
within plus or minus 32K. Intrasegment direct
JUMPs are self-relative and are appropriate in
position-independent (dynamically relocatable) routines in which the JMP and its target are in the same
segment and are moved together.

LOOP short-label

An intrasegment indirect JMP may be made either
through memory or through a 16-bit general
register. In the first case, the contents of the word
referenced by the instruction replaces the instruction
pointer. In the second case, the new IP value is
taken from the register named in the instruction.
An intersegment direct JMP replaces IP and CS with
values contained in the instruction.
An inter segment indirect JMP may be made only
through memory. The first word of the doubleword
pointer referenced by the instruction replaces IP,
and the second word replaces CS.

LOOP decrements CX by 1 and transfers control to
the target operand if CX is not 0; otherwise the instruction following LOOP is executed.

LOOP/LOOPNZ short-label

LOOPE and LOOPZ (loop while equal and loop
while zero) are different mnemonics for the same instruction (similar to the REPE and REPZ repeat
prefixes). CX is decremented by 1, and control is
transferred to the target operand if CX is not 0 and if
ZF is set; otherwise the instruction following
LOOPE/LOOPZ is executed.

LOOPNE/LOOPNZ short-/abel

LOOPNE/LOOPNZ (loop while not equal and loop
while not zero) are also synonyms for the same
instruction. CX is decremented by 1, and control is
transferred to the target operand if CX is not 0 and if
ZF is clear; otherwise the next sequential instruction
is executed.
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

Table 3-11 Interpretation of Conditional Transfers

MNEMONIC

CONDITION TESTED

"JUMP IF ,,' "

JA/JNBE
JAE/JNB
JB/JNAE
JBE/JNA
JC
JE/JZ
JG/JNLE
JGE/JNL
JLlJNGE
JLE/JNG
JNC
JNE/JNZ
JNO
JNP/JPO
JNS
JO
JP/JPE
JS

(CF OR ZF)=O
CF=O
CF=1
(CF OR ZF)=1
CF=1
ZF=1
((SF XOR OF) OR ZF)=O
(SF XOR OF)=O
(SF XOR OF)=1
((SF XOR OF) OR ZF)=1
CF=O
ZF=O
OF=O
PF=O
SF=O
OF=1
PF=1
SF=1

above I not below nor equal
above or equall not below
below I not above nor equal
below or equal I not above
carry
equal/zero
greater/not less nor equal
greater or equal/not less
lessl not.greater nor equal
lessor equal I not greater
not carry
not equal I not zero
not overflow
not parity I parity odd
not sign
overflow
parity I parity equal
sign

Note: "above" and "below" refer to the relationship of two unsigned values;
"greater" and "less" refer to the relationship of two signed values.
JCXZ short-label

Jexz (jump if ex zero) transfers control to the
target operand if ex is O. This instruction is usefuI"at
the beginning of a loop to bypass the loop if ex has a
zero value, i.e., to execute the loop zero times.

pushed onto the stack. The address of the interrupt
pointer is calculated by multiplying interrupt-type by
four; the second word of the interrupt pointer replaces es. SP again is decremented by two, and IP is
pushed onto the stack and is replaced by the first
word of the interrupt pointer. If interrupt-type = 3,
the assembler generates a short (J byte) form of the
instruction, known as the breakpoint interrupt.

INTERRUPT INSTRUCTIONS

The interrupt instructions allow interrupt service
routines to be activated by programs as well as by external hardware devices. The effect of software interrupts is similar to hardware-initiated interrupts.
However, the processor does not execute an inter.
rupt acknowledge bus cycle if the interrupt originates
in software or with an NMI (non-maskable
interrupt) .The effect of the interrupt instructions on
the flags is covered in the description of each
instruction.
INT interrupt-type

INT (interrupt) activates the interrupt procedure
specified by the interrupt-type operand. INT decrements the stack pointer by two, pushes the flags
onto the stack, and clears the trap (TF) and
interrupt-enable (IF) flags to disable single-step and
maskable interrupts. The flags are stored in the
same format used by the PUSHF instruction. SP is
decremented again by two, and the es register is

Software interrupts can be used as "supervisor
calls," i.e., requests for service that the operating
system could supply for an application program. A
different interrupt-type can be used for each type of
service that the operating system could supply for an
application program. Software interrupts also may be
used to check out interrupt service procedures written for hardware-initiated interrupts.
INTO

INTO (interrupt on overflow) generates a software
interrupt if the overflow flag (OF) is set; otherwise
control proceeds to the following instruction without
activating an interrupt procedure. INTO addresses
the target interrupt procedure (its type is 4) through
the interrupt pointer at location lOH; it dears the TF
and IF flags and otherwise operates like INT. INTO
may be written following an arithmetic or logical operation to activate an interrupt procedure if overflow
occurs.
3-35

210911

THE iAPX 86,88 AND iAPX186, 188 ARCHITECTURE AND INSTRUCTIONS

IRET

IRET (interrupt return) transfers control back to the
point of interruption by popping IP, CS and the flags
from the stack. IRET thus affects all flags by restoring them to previously saved values. IRET is used to
exit .any interrupt procedure, whether activated by
hardware or software.

BP
OLDBP

•

OLD FRAME

High-level Instructions
PTRS.

ENTER

The ENTER (enter procedure) instruction executes
the calling sequence for a high-level language. It pro.
vides for saving the current stack frame pointer
(which is in the BP register), copying down stack
frame pointers from procedures below the current
call (to allow access to local variables in these
procedures), and allocating space on the stack for
the local variables of the. current procedure
invocation. This instruction reqJlires two arguments:
the size of the local variables (the displacement),
and the level of the procedure (which may be as
great as 255).

CURRENT FRAME
PTR

/

LOCAL
VARIABLE
AREA
SP

The algorithm for this instruction is:

*'

PUSHBP
1* save the previous frame pointer
iflevel = 0 then
BP:= SP;
else
templ:= SP; 1* savecurrentframepointer*'
temp2 : = level - 1;
!* copy down previous level
do while temp2 > 0
fraine
BP ·=·BP - 2'
!* pointers
puim [BPI; ,
BP:,:" tempI;
PUSHBP;
!* put current level frame pointer "'
!* in the save area
SP:= SP - disp;
'"create space on the stack for
local variables

*'

*'

'*

*'
*'

*'

Figure 3-30 shows the layout of the stack after this
operation.

LEAVE

The LEAVE (leave procedure) instruction is the
opposite of the ENTER instruction. This in~truction
"cleans up" the procedure's stack .to prepare for returning from the procedure. It deallocates all local or
automatic variables, and. returns the stack registers
(SP and BP) to. the same values they were immediately after the procedure invo.cation. As cal). be seen
from the layout of the stack. left by the ENTER instruction (see Figure 3-~0), this involves moving
the contents of theBP nigisier to'the SP register,
and popping the old BP value off of the stack.

Figure 3-30 Stack Layout
After ENTER Instruction

Note that neither the ENTER nor the LEAVE instructions save any of the 80186,188 general purpose
registers. If they must be saved, this must be done in
addition to the ENTER and LEAVE. Also, the
LEAVE instruction does not perform a return from
subroutine. If this is desired, the LEAVE instruction
must be explicitly followed by the RET instruction;
BOUND

The BOUND (detect value out of range) instruction
allows for array bounds checking in hardware. The
calculated. array index is placed in one of the general
purpose registers, and the upper and lower bounds
of the array are placed in two consecutive memory
locations. The instruction compare.s. the contents of
the specified register against the memory location
values, and if the register value is less. than the first
memory location or greater than. the second
memory location, a trap tYPe 5 is generated. The
comparisons performed are signed comparisons. A
register value equal. to either the UPPer or lower
bound will not cause a trap'. Following a trap, the IP
(which has been pushed on the stack) will point to
the instruction following the BOUND instruction.
3-36

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

The instruction requires two arguments: the register
in which the calculated array index is placed, and the
effective address of the memory location containing
the lower bound of the array (which can be specified
by any of the 80186,188 memory addressing
modes). The memory location containing the upper
bound of the array must follow immediately the
memory location containing the lower bound of the
array, i.e., the address of the memory location containing the upper bound of the array is the address of
the lower bound location plus 2.

CMC
CMC (complement carry flag) "toggles" CF to its
opposite state and affects no other flags.

STC
STC (set carry flag) sets CF to I and affects no other
flags.

CLO

Processor Control Instructions
These instructions (see Table 3-12) allow programs
to control various CPU functions. One group of instructions updates flags, and another group is used
primarily for synchronizing the processor with external events. A final instruction causes the CPU to do
nothing. Except for the flag operations, none of the
processor instructions affect the flags.
Table 3·12 Processor Control Instructions

CLO (clear direction flag) zeroes OF causing the
string instructions to auto-increment the SI and lor
01 index registers. CLO does not affect any other
flags.

STO
STO (set direction flag) sets OF to I causing the
string instructions to auto-decrement the SI andlor
01 index registers. STO does not affect any other
flags.

FLAG OPERATIONS

STC
CLC
CMC
STO
CLO

Set carry flag
Clear carry flag
Complement carry flag
Set direction flag
Clear direction flag
Set interrupt enable flag
Clear interrupt enable flag

STI
CLI

EXTERNAL SYNCHRONIZATION

HLT
WAIT
ESC
LOCK

Halt until interruptor reset
Wait for TEST pin active
Escape to external processor
Lock bus during next
instruction
NO OPERATION

Nap

No operation

CLI
CLI (clear interrupt-enable flag) zeroes IF. When
the interrupt-enable flag is cleared, the processor
does not recognize an external interrupt request that
appears on the INTR line; in other words maskable
interrupts are disabled. A non-maskable interrupt
appearing on the NMI line; however, is honored, as
is a software interrupt. CLI does not affect any other
flags.

STI
STI (set interrupt-enable flag) sets IF to 1, enabling
processor recognition of maskable interrupt requests
appearing on the INTR line. Note, however, that a
pending interrupt will not actually be recognized
until the instruction following STI has executed. STI
does not affect any other flags.

FLAG OPERATIONS

EXTERNAL SYNCHRONIZATION

CLC

HLT

CLC (clear carry flag) zeroes the carry flag (CF) and
affects no other flags. It (and CMC and STC) is
useful in conjunction with the RCL and RCR
instructions.

HLT (halt) causes the processor to enter the halt
state. The processor leaves the halt state upon activation of the RESET line, upon receipt of a nonmaskable interrupt request on NMI, or, if interrupts
3-37

210911

THE'iAPX 86,88 AND iAPX 186,188 ARCHnECTURE·AND·INSTRUCTloNS

are enabled, upon receipt of a maskable interrupt request on INTR. HLT does not affect any flags. It
may be used as an alternative to an endless software
loop in situations where a prograrn must wait for an
interrupt.
WAIT

UI\jDEFINED OPCODES

When the opcodes 63H, 64H, 65H, 66H,67H, FlH,
FEH XXUIXXXB and FFH XX111XXXB are
executed, the 80186,188 .will execute an illegal instruction exception (interrupt type 6). The 8086,88
wit! ignore theseopco.des.
OFH OPCODE

WAIT causes the CPU to enter the wait state while
its TEST line is not active. WAIT does not affect any
flags.

When the opcode OFH is encountered, the 8086;88
will execute a POP CS; the 86186,188 will execute an
illegal instruction exception.

ESC external-opcode. source
WORD WRITE AT OFFSET FFFFH

ESC (escape) provides a means for an external processor to obtain an opcode and possibly a memory
operand from the 8086 or 80186. The external
opcode is a 6-bit immediate constant that the assembler encodes in the machine instruction it builds. An
external processor may monitor the system bus and
capture this opcode when the ESC is fetched. Then,
using the second byte of the opcode, the CPU performs an operand access. If the source operand is a
register, the processor does nothing. If the source
operand is a memory variable, the processor obtains
the operand from memory and discards it. An external processor may capture the memory operand and
the memory operand's 20-bit address when the processor reads it from memory.
LOCK

LOCK isa one-byte prefix that causes the processors
to assert their bus LOCK signals while the following
instructions execute. LOCK does not affect any flags.
NO OPERATION

Nap

Nap (no operation) causes the CPU to do nothing.
Nap does not affect any flags,

When a word write is. performed at offset FFFFH in
a segment, the 8086,88 will write one byte at offset
FFFFH, and the other at offset 0; the 80186,188 will
write one byte at offset FF'FFH,' and the other at
offset 10000H (one byte byyond the enq of the
segment). One byte segment underflow will also
occur on the 80186,188 if a stack PUSH is executed
and the Stack Poihter containstht:'Value 1.
SHIFT/ROTATE BY VALUE GREATER THAN 31

Before the 80186,188 performs a shift or rotate by a
value (either in theCL registe~, or by an immediate
value) it ANDs. the value with IFH, limiting the
number of bits rotated to less than 32.·The 8086,88
does not do this.
. LOCK PREFIX

The 8086,88 activates its' LOCK sighal immediately
after executing the LOCK jJrefix. The 80186,188
does not activate the LOCK signal until the processor is ready to begin the data cycles associated with
the LOCKed instruction.

INTERRUPTED STRING MOVE
INSTRUCTIONS

If an 8086,88 is interrupted during the execution of a
repeated string move' instruction, the return value
pushed on the stack will point to the last prefix instruction before the string move instructipn. If the
instruction had more than one prefix (e.g., a segment override prefix in addition to the repeat
prefix), the prefix will not be re-executed upon returning from the interrupt. The 80186,188, on the
other hand, pushes the value of the first prefix to the
repeated instruction: Thus, so long as prefixes are
not themselves repeated, string instructions will
properly resume execution.

Instruction Operation Differences,
8086,88 - 801 86,1 88
There are a few instruction operation differences between the 8086,88 and 80186,188, most of which
have been previously discussed in this' chapter and
in Chapter 2. The following is a summary of these
differences:
3-38

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

CONDITIONS CAUSING DIVIDE ERROR
WITH AN INTEGER DIVIDE

The 8086,88 will cause a divide error whenever the
absolute value of the quotient is greater then 7FFFH
(for word operations) or if the absolute value of the
quotient is greater than 7FH (for byte operations).
The 80186,188 has expanded the range of negative
numbers allowed as a quotient by 1 to include 8000H
and 80H. These numbers represent the most negative numbers representable using two's complement
arithmetic (equal to - 32768 and -128 in decimal,
respectively) .

ESC OPCODE

The 80186,188 may be programmed to cause an interrupt type 7 whenever an ESCape instruction
(used for co-processors like the the 8087) is
executed. The 8086,88 has no such provision.

Instruction Set Reference
The instruction set summary which follows provides
detailed operational information for the iAPX
861186 (8086, 8088, 80186, and 80186) instruction
set. The information is presented from the point of
view of utility to the assembly language programmer.
Instruction timings are represented as the number
of clock periods required to execute a particular
form (register-to-register, immediate-to-memory,
etc.) of instruction. At 5MHz clock, the clock period
is 200 ns; at 8MHz, the clock period is 125 ns. For
8086,88 instruction timings which use memory
operands, "+ EA" denotes the number of additional
clock periods needed to calculate the operand's effective address. (On the 80186,188 this computation is
performed in hardware.)
For control transfer instructions, the timings given
include any additional clocks required to reinitialize
the instruction queue as well as the time required to
fetch the target instruction. For the 8086, four clocks
should be added for each instruction reference to a
word operand located at an odd memory address t.o
reflect any additional operand bus cycles required.
The required number of data references is listed in
the instruction set summary for each instruction to
aid in this calculation.

All of the instruction times given are of the form
"n(m) ," where n is the number of clocks required
for the 8086 to execute the given instruction, and m
is the time required by the 80186 for the same
instruction. The number of clocks required for the
8088 will be n for 8-hit operations and n + (4 •
transfers) for 16-bit operations. For the 80188, the
number of clocks will be m for 8-bit operations and
m + (4' transfers) for 16-bit operations.
For instructions which repeat a specified number of
times, the values m and n each consist of two parts
in the relation "x + y/rep," where x is the initial
number of clocks required to start the instruction,
and y is the number of clocks corresponding to the
number of iterations specified. For 16-bit repeated
instructions on the 8088 and 80188, when the expression" (4 * transfers)" has to be added to m or n,
it should be added to the y part of the expression
before it is multiplied by the number of repetitions.
Several additional factors can increase actual execution time over the figures shown in Table 3-13. The
time provided assumes that the instruction has already been prefetched and that it is waiting in the instruction queue, an assumption that is valid under
most, but not all, operating conditions. A series of
fast executing (fewer than two clocks per opcode
byte) instructions can drain the queue and increase
execution time. Execution time also is slightly impacted by interaction of the EU and BIU when
memory operands must be read or written. If the EU
needs access to memory, it may have to wait for up
to one clock if the BIU has already started an instruction fetch bus cycle. (The EU can detect the need for
a memory operand and post a bus request far
enough in advance of its need for this operand to
avoid waiting a full 4-clock bus cycle.) Of course the
EU does not have to wait when the queue is full, because the BIU is idle. (This assumes that the BIU
can bbtain the bus on demand, i.e., no other processors are competing for the bus.)
With typical instruction mixes, the time actually required to execute a sequence of instructions will typically be within 5-10% of the sum of the individual
timings given in the instruction set summary. Cases
can be constructed, however, in which execution
time may be much higher than the sum of the figures
provided in the table. The execution time for a given
sequence of instructions, however, is always
repeatable, assuming comparable external conditions
(interrupts, coprocessor activity, etc.). If the execution time for a given series of instructions must be
determined exactly, the instructions should be run
on an execution vehicle such as the iSBC 88!25™ or
the 86/30 board.
3-39

210911

THEiAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

REF

REFERENCES
FOR INSTRUCTION SET

REF

Key to following Instruction Set Reference Pages
IDENTIFIER

..

USEDIN

EXPLANATION

destination

data transfer,
bit manipulation

A register or memory location that may contain data
operated on by the instruction, and which receives (is
replaced by) the result of the operation.

source

data transfer,
arithmetic,
bit manipulation

A register, memory location or immediate value that is
used in the operation, but is not altered by the
instruction.

source-table

XLAT

Name of memory translation table addressed by
register BX.

target

JMP, CALL

A label to which control is to be transferred directly, or
a register or memory location whose content is the
address of the location to which control is to be
transferred indirectly.

short-label

condo transfer,
iteration control

A label to which control is to be conditionally
transferred; must lie within -128 to +127 bytes of the
first byte of the next instruction.

accumuiator

IN,OUT

Register AX for word transfers, AL for bytes.

port

IN,OUT

An I/O port number; specified as an immediate value of
0-255, or register DX (which contains port number in
range 0-64k).

source-string

string ops.

Name of a string in memory that is addressed by
register SI; used only to identify string as byte or word
and specify segment override, if any. This string is
used in the operation, but is not altered.

dest-string

string ops.

Name of string in memory that is addressed by register
DI; used only to identify string as byte or word. This
string receives (is replaced by) the result of the
operation.

count

shifts, rotates

Specifies number of bits to shift or rotate; written as
immediate value 1 or register CL (which contains the
count in the range 0-255).

interru pt-type

INT

Immediate value of 0-255 identifying interrupt pointer
number.

optional-pop-val ue

RET

Number of bytes (0-64k, ordinarily an even number) to
discard from stack.

external-opcode

ESC

Immediate value (0-63) that is encoded in the instruction
for use by an external processor.

above-below

conditional jumps

Above and below refer to the relationship of two unsigned
values.

greater-less

conditional jumps

Greater and less refer to the relationship of two signed
values.

3-40

210911

I

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

,

',,!'~

REF

REF

REFERENCES
FOR INSTRUCTION SET

Key to Operand Types
IDENTIFIER

EXPLANATION

(no operands)

No operands are written
An 8- or 16-bit general register
An 16-bit general register
A segment register
Register AX or AL
A constant in the range

register
reg 16
seg-reg
accumulator
immediate
immed8
memory
mem8
mem16
source-table
source-string
dest-string
DX
short-label
near-label
far-label
near-proc
far-proc
memptr16

memptr32

regptr16

repeat

1514111211

to

981654

OF OF IF TF SF ZF

I

321

AF

PF

0
CF

L_L=

AIJXILIARYCARRY

ZERO
SIGN

INTERRUPT

O-FFFFH
A constant in the range O-FFH
An 8- or 16-bit memory
10cation"1
An 8-bit memory 10cation"1
A 16-bit memory 10cation '1i
Name of 256-byte translate
table
Name of string addressed by
register SI
Name of string, addressed by
register DI
Register DX
A label within -128 to +127
bytes of the end of the
instruction
A label in current code
segment
A label in another code
segment
A procedure in current code
segment
A procedure in another code
segment
A word containing the offset of
the location in the current code
segment to which control is to
be transferred '1i
A doubleword containing the
offset and the segment base
address of the location in
another code segment to
which control is to be transferred '1'
A 16-bit general register
containing the offset of the
location In the current code
segment to which control is to
be transferred
A string instruction repeat
prefix

CARRY

DIRECTION
OVERFLOW

Effective Address Calculation Time (8086,88 ONLY)

EA COMPONENTS

CLOCKS'

Displacement Only

6

Base or Index Only (BX,BP,SI,OI)

5

Displacement
+
Base or Index

9
(BX,BP,SI,OI)

Base
+
Index

BP+ 01, BX+SI

7

BP+SI, BX+DI

8

Displacement
+
Base
+
Index

BP+ DI+ OISP
BX+SI+DISP

11

BP+SI+OISP
BX+OI+OISP

12

• Add 2 clocks for segment override
Notation Key
+
Addition
Subtraction
Multiplication
Division
%
Modulo
Concatenation
&
And
9 or (AF) = 1 then
(AL) +- (AL) + 6
(AH) +- (AH) + 1
(AF) +- 1
(CF) +- (AF)
(AL) ~ (AL) & OFH

AF, CF.
OF, PF, XF, ZF undefined

Description:
AAA (ASCII Adjust for Addition) changes
the contents of register ALto a valid unpacked
decimal number; the high-order half-byte is
zeroed. AAA updates AF and CF; the content
of OF, PF, SF and ZF is undefined following
execution of AAA.

Encoding:
1001101111
AAA Operands .

(no operands)

Clocks

8(8)

Transfers Bytes

-

3-43

1

AAA Coding Example

AAA

210911

'THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

AAD

AAD

ASCII ADJUST
FOR DIVISION

Operation:

Flags Affeeted:

(AL) +- (AH) • OAH + (AL)
(AH)- 0

PF, SF, ZF.
AF, CF, OF undefined

Description:
AAD (ASCII Adjust for Division) modifies
the numerator in AL before dividing two valid
unpacked decimal operands so that the quotient produced by the division will be a valid
unpacked decimal number. AH must be zero

for the subsequent DIY to produce the correct
result. The quotient is returned in AL, and the
remainder is returned in AH; both high-order
half-bytes are zeroed. AAD updates PF, SF
and ZF; the content of AF, CF and OF is
undefined following execution of AAD.

Encoding:
1101010100001010
AAD Operands

(no operands)

Clocks

60(15)

Transfers Bytes

-

3-44

2

AAD Coding Example

AAD

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

AAM
Operation:
(AH)
(AL)

~
~

AAM

ASCII ADJUST
FOR MULTIPLY
Flags Affected:

(AL) / OAH
(AL) % OAH

PF, SF, ZF.
AF, CF, OF undefined

Description:
AAM (ASCII Adjust for Multiply) corrects
the result of a previous multiplication of two
valid unpacked decimal operands. A valid 2digit unpacked decimal number is derived
from the content of AH and AL and is

returned to AH and AL. The high-order halfbytes of the multiplied operands must have
been OH for AAM to produce a correct result.
AAM updates PF, SF and ZF; the content of
AF, CF and OF is undefined following execution of AAM.

Encoding:
1101010000001010
AAM Operands
(no operands)

Clocks

Transfers Bytes

-

83(19)

3-45

2

AAM Coding Example

AAM
210911

THE iAPX. 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

A'AS'

ASCII ADJUST
FOR SUBTRACTION
Flags Affected:

Operation:
if «AL) & OFH) >9 or (AF) = 1 then
(AL) +- (AL)- 6
(AH) +- (AH) -1
(AF) +- 1

(CF)
(AL)

+-

~

AAS

AF, CF.
OF, PF, SF, ZF undefined

(AF)
(AL) & OFH

Description:
register AL). AAS changes the content of AL
to a valid unpacked decimal number; the highorder half-byte is zeroed. AAS updates AF
and CF; the content of OF, PF, SF and ZF is
undefined following execution of AAS,

AAS (ASCII Adjust for Subtraction) corrects
the result of a previous subtraction' of two
valid unpacked decimal operands (the destination operand must have been specified as

Encoding:
001 1 1 111
AAS Operands

(no operands)

Clocks
8(7)

Transfers Bytes

3-46

1

AAS Coding Example
AAS

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

ADC

ADD WITH CARRY

Operation:

ADC

Flags Affecoted:

if (CF) = 1 then (DEST) +- (LSRC)
+ (RSRC) + 1
else (DEST) +- (LSRC) + (RSRC)

AF, CF, OF, PF, SF, ZF

Description:
ADC destination, source

ADC (Add with Carry) sums the operands,
which may be bytes or words, adds one if CF is
set and replaces the destination operand with
the result. Both operands may be signed or
unsigned binary numbers (see AAA and
DAA). ADC updates AF, CF, OF, PF, SF and
ZF. Since ADC incorporates a carry from a
previous operation, it can be used to write
routines to add numbers longer than 16 bits.

3-47

210911

THE iAPX 86,88 ANDiAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

ADD WITH CARRY

ADC

ADC

Encoding:
Memory or Register Operand with Register Operand:
10001 00 d w

I mod reg rIm 1

if d = 1 then LSRC = REG, RSRC = EA, DEST = REG
else LSRC = EA, RSRC = REG, DEST ,= EA

Immediate Operand to Memory or Register Operand:
1100000 sw 1mod 0 1 0 rIm 1

data

Idata if s:w=011

LSRC = EA, RSRC = data, DEST = EA

Immediate Operand to Accumulator:
1 0001 01 0 w 1

data

1 data if w=1

1

if w = 0 then LSRC = AL, RSRC = data, DEST = AL
else LSRC = AX, RSRC = data, DEST = AX

ADC Operands

register, register
register, memory
memory, register
register, immediate
memory, immediate
accumulator,
immediate

Clocks

Transfers Bytes

-

3(3)
9(10)+EA
16(10) +EA
4(4)
17(16) +EA

1
2

4(3-4)

ADC Coding Example

2

2
2-4
2-4
3-4
3-6

ADCAX,SI
ADD DX, BETA [SI]
ADC ALPHA [BX][Sll,DI
ADC BX, 256
ADC GAMMA, 30H

-

2-3

ADC AL, 5

-

3-48

210911

THE iAPX 86,88.AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

ADD

ADDITION

Operation:
(DEST)

+-

ADD

Flags Affected:

(LSRC) + (RSRC)

AF, CF, OF, PF, SF, ZF

Description:
ADD destination,source
The sum of the two operands, which may be
bytes or words, replaces the destination
operand. Both operands may be signed or
unsigned binary numbers (see AAA and
DAA). ADD updates AF, CF, OF, PF, SF and

ZF.

3-49

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

ADD

ADD

ADDITION

Encoding:
Memory or Register Operand with Register Operand:
\ 000 0 0 0 d w \ mod reg rIm \
if d = 1 then LSRC = REG, RSRC = EA, DEST
else LSRC = EA, RSRC = REG, DEST = EA

= REG

Immediate Operand to Memory or Register Operand:
data

\1 00000 s w \ mod 000 rIm \
LSRC

= EA,

RSRC

= data, DEST =

\data if s:w=01\

EA

Immediate Operand to Accumulator:
\ 000001 0 w \

data

\ data if w=1

\

if w = 0 then LSRC = AL, RSRC = dpta, DEST = AL
else LSRC = AX, RSRC = data, DE'ST = AX
ADD Operands

Clocks

register, register
register, memory
memory, register
register, immediate
memory, immediate
accumulator,
immediate

3(3)
9(10) +EA
16(10)+EA
4(4)
17(16)+EA

1
2

4(3-4)

Transfers Bytes

-

ADD Coding Example

2

2
2-4
2-4
3-4
3-6

AOOCX, OX
ADD 01, [BX).ALPHA
AOOTEMP,CL
AOOCL,2
ADD ALPHA, 2

-

2-3

ADD AX, 200

-

3-50

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

AND

AND LOGICAL

Operation:

AND

Flags Affected:

(DEST) +- (LSRC) & (RSRC)
(CF) +- 0
(OF) +- 0

I:;

CF, OF, PF, SF, ZF.
AF undefined

Description:
AND destination,source
AND performs the logical "and" of the two
operands (byte or word) and returns the result
to the destination operand. A bit in the result
is set if both corresponding bits of the original
operands are set; otherwise the bit is cleared.

3-51

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

AND

AND LOGICAL

AND

Encoding:
Memory or Register Operand with Register Operand:

I001 000 d w Imod reg rim 1
if d = 1 then LSRC = REG, RSRC = EA, DEST = REG
else LSRC = EA, RSRC = REG, DEST = EA

Immediate Operand to Memory or Register Operand:
11 00 0 0 0 0 w 1mod 1 00 rim 1

data if w::::'1

data

LSRC = EA, RSRC = data, DEST = EA

Immediate Operand to Accumulator:
1 001 00 1 0 w

I

data

I data if w=1

1

if w = 0 then LSRC = AL, RSRC = data, DEST = AL
else LSRC = AX, RSRC = data, DEST = AX
AND Operands

Clocks

Transfers Bytes

register, register
register, memory
memory, register
register, immediate
memory, immediate
accumulator,
immediate

3(3)
9(10)+EA
16(10) +EA
4(4)
17(16)+EA

1
2

4(3-4)

-

AND Coding Example

2

2
2-4
2-4
3-4
3-6

AND.AL; BL
AND CX, FLAG WORD
AND ASCII [DU:-AL
ANDCX,OFOH
AND BETA, 01 H

-

2-3

AND AX, 0101 OOOOB

-

3-52

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

BOUND

DETECT VALUE
OUT OF RANGE

Operation:

BOUND

Flags Affected:
None

If ((LSRC) < (RSRC) OR (LSRC)
(SP) -- (SP) - 2
((SP) + 1 : (SP» --FLAGS
(IF) -- 0
(TF) --0
(SP) -- (SP) - 2
((SP) + 1: (SP» -- (CS)
(CS) -- (1 EH)
(SP) -- (SP) - 2
((SP) + 1 : (SP)) -- (I P)
UP) -- (1CH)

>

((RSRC)

+ 2) then

Description:
BOUND destination, source
BOUND provides array bounds checking in hardware. The
calculated array index is placed in one of the general purpose
registers, and the upper and lower bounds of the array are
placed in two consecutive memory locations. The contents of
the register are compared with the memory location values,
and if the register value is less than the first location or greater than the second memory location, a trap type 5 is
generated.

3-53

210911

THE iAPX 86,88 AN"DiAPX 186,188 ARCHITECTURE AN[J'INSTR'OCTIONS

,BOUND

·E>ETECTVALUE
OUTOFRANGE

BOUND

Encoding:
01100010

BOUND Operands
register, memory

mod req

Clocks
(35)

rim

Transfers Bytes

2

3-54

2

BOUND Coding Example
BOUND AX, ALPHA

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS
.\

CALL

CALL PROCEDURE

Operation:

CALL

Flags Affected:

if Inter-Segment then
(SP) ~ (SP) - 2
((SP) + 1 :(SP)) ~ (CS)
(CS) ~ SEG
(SP) ~ (SP) - 2
((SP) + 1 :(SP)) ~ (lP)
(IP) ~ DEST

None

Description:
CALL procedure-name

CALL activates an out-of-line procedure, saving information on the stack to permit a RET
(return) instruction in the procedure to
transfer control back to the instruction following the CALL. The assembler generates a different type of CALL instruction depending on
whether the programmer has defined the procedure name as NEAR or FAR. For control to
return properly, the type of CALL instruction
must match the type of RET instruction that
exits from the procedure. (The potential for a
mismatch exists if the procedure and the
CALL are contained in separately assembled
programs.) Different forms of the CALL
instruction allow the address of the target procedure to be obtained from the instruction
itself (direct CALL) or from a memory location or register referenced by the instruction
(indirect CALL). In the following descriptions, bear in mind that the processor automatically adjusts IP to point to the next
instruction to be executed before saving it on
the stack.
For an intrasegment direct CALL, SP (the
stack pointer) is decremented by two and IP is
pushed onto the stack. The target procedure's
relative displacement (up to ±32k) from
the CALL instruction is then added to the
instruction pointer. This CALL instruction

form is "self-relative" and appropriate for
position-independent (dynamically relocatable) routines in which the CALL and its
target are moved together in the same segment.
An intrasegment indirect CALL may be made
through memory or a register. SP is decremented by two; IP is pushed onto the stack.
The target procedure offset is obtained from
the memory word or 16-bit general register
referenced in the instruction and replaces IP.
For an intersegment direct CALL, SP is decremented by two, and CS is pushed onto the
stack. CS is replaced by the segment word contained in the instruction. SP again is
decremented by two. IP is pushed onto the
stack and replaced by the offset word in the
instruction.
For an inter segment indirect CALL (which
only may be made through memory), SP is
decremented by two, and CS is pushed onto
the stack. CS is then replaced by the content of
the second word of the doubleword memory
pointer referenced by the instruction. SP again
is decremented by two, and IP is pushed onto
the stack and replaced by the content of the
first word of the doubleword pointer referenced by the instruction.

3-55

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

CALL PROCEDURE

CALL

CALL

Encoding:
I ntra-segment direct:
disp-Iow

111101000

disp-high

DEST,- (EA)

Intra-Segment Indirect:
11111111
DEST = (IP)

mod010rim

+ disp

Inter-Segment Direct:
11 0011 010 1 offset-low

I

offset-high

seg-Iow

seg-high

DEST = offset, SEG = seg

Inter-Segment Indirect:
111 11 1111 1mod 0 11 rIm 1
DEST = (EA), SEG

CALL Operands
near-proc
far-proc
memptr16
regptr16
memptr32

= (EA +

2)

Clocks
19(14)
28(23)
21(19)+EA
16(13)
37(38) +EA

Transfers Bytes
1
2
2
1
4

3-56

3

5
2-4
2
2-4

CALL Coding Examples
CALL NEAR PROC
CALL FAR PROC
CALL PROC_TABLE [SI]
CALLAX
CALL [BX].TASK [SI]

210911

THE iAPX 86,88 AND iAPX186, 188 ARCHITECTURE AND INSTRUCTIONS

CONVERT BYTE
TOWORD

CBW
Operation:
if (AL) < SOH then (AH)

CBW

Flags Affected:
~

0 else (AH)

~

None

FFH

Description:
CBW (Convert Byte to Word) extends the sign
of the byte in register AL throughout register
AH. CBW does not affect any flags. CBW can
be used to produce a double-length (word)
dividend from a byte prior to performing byte
division.

Encoding:
10011000
CBW Operands

(no operands)

Clocks
2(2)

Transfers Bytes

-

3-57

1

CBW Coding Example

CBW

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

CLC

ClC

CLEAR CARRY

Operation:

Flags Affected:
CF

(CF)'-' 0

Description:
CLC (Clear Carry flag) zeroes the carry flag
(CF) and affects no other flags. It (and CMC
and STC) is useful in conjunction with the
RCL and RCR instructions.

Encoding:
11111000

CLC Operands

(no operands)

Clocks

2(2)

Transfers Bytes

3-58

1

CLC Coding Example
CLC

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

CLD

CLEAR DIRECTION
FLAG

CLD

Flags Affected:

Operation:

DF

(DF)- 0

Description:
CLD (Clear Direction flag) zeroes DF causing
the string instructions to auto-increment the SI
and! or DI index registers. CLD does not
affect any other flags.

Encoding:
11111100

CLDOperands

(no operands)

Clocks

2(2)

Transfers Bytes

3-59

1

CLD Coding Example

CLD

210911

THEiAPX86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

ell

CLEA.RINTERRUPTENABLE FLAG

Operation:

ell

Flags Affected:

(IF)- 0

IF

Description:
CLI (Clear Interrupt-enable flag) zeroes IF.
When the interrupt-enable flag is cleared, the
8086 and 8088 do not recognize an external
interrupt request that appears on the INTR
line; in other words maskable interrupts are
disabled. A non-maskable interrupt appearing
on the NMI line, however, is honored, as is a
software interrupt. CLI does not affect any
other flags.

Encoding:
11111010

CLiOperands

(no operands)

Clocks
2(2)

Transfers Bytes

.3-60

1

CLI Coding Example

eLi
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

CMC

COMPLEMENT
CARRY FLAG

Operation:

CMC

Flags Affected:
I.

if (CF) = 0 then (CF) -1 else (CF) - 0

~

CF

I

Description:
CMC (Complement Carry flag) "toggles" CF
to its opposite state and affects no other flags.

Encoding:
1111101011

CMC Operands

(no operands)

Clocks
2(2)

Transfers Bytes

3-61

1

CMC Coding Example

CMC
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

CMP

COMPARE

Operation:

GMP

Flags Affeeted:

(LSRC) - (RSRC)

AF, CF, OF, PF, SF, ZF

Description:
CMP destination, source
CMP (Compare) subtracts the source from the
destination, which may be bytes or words, but
does not return the result. The operands are
unchanged, but the flags are updated and can
be tested by a subsequent conditional jump
instruction. CMP updates AF, CF, OF, PF,

3-62

SF and ZF. The comparison reflected in the
flags is that of the destination to the source. If
a CMP instruction is followed by a JG (jump
if greater) instruction, for example, the jump
is taken if the destination operand is greater
than the source operand.

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

CMP

COMPARE

CMP

Encoding:
Memory or Register Operand with Register Operand:
10 0 1 1 1 0 d w 1 mod reg r / m I
if d = 1 then LSRC = REG, RSRC = EA
else LSRC = EA, RSRC = REG

Immediate Operand with Memory or Register Operand:
data

11 OOOOOsw Imod111 rIm I

Idata if s:w=o11

LSRC = EA, RSRC = data

Immediate Operand with Accumulator:
1 0 a1 1 1 1 0 w

I

data

I data if w=1

if w = 0 then LSRC = AL, RSRC
else LSRC = AX, RSRC = data
CMP Operands

register, register
register, memory
memory, register
register, immediate
memory, immediate
accumulator,
immediate

= data

Clocks

Transfers Bytes

-

3(3)
9(10)+EA
9(10)+EA
4(3)
10(10)+EA

1
1

4(3-4)

CMP Coding Examples

1

2
2-4
2-4
3-4
3-6

CMP BX,CX
CMP DH, ALPHA
CMP [BP+21,SI
CMP BL,02H
CMP [BX].RADAR
[DI),3420H

-

2-3

CMP AL, 0001 OOOOB

-

3-63

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

CMPS

COMPARE STRING
(BYTE OR WORD)

Operation:

CMPS

Flags Affected:

(LSRC) - (RSRC)
if (OF) = 0 then
(SI) - (SI) + OEL TA
(01) - (01) + OEL TA
else
(SI) - (SI) - OEL TA
(01) - (01) - OEL TA

AF, CF, OF, PF, SF, ZF

Description:
CMPS destination-string, source-string

CMPS (Compare String) subtracts the destination byte or word (addressed by 01) from the
source byte or word (addressed by SI). CMPS
affects the flags but does not alter either
operand, updates Sl and 01 to point to the
next string element and updates, AF, CF, OF,
PF, SF and ZF to reflect the relationship of the
destination element to the source element. For
example, if a JG (J1J.mp if Greater) instruction
follows CMPS, the jump is taken if the des-

tination element is greater than the source
element. If CMPS is prefixed with REPE or
REPZ, the operation is interrupted as "compare while not end-of-string (CX not zero) and
strings are equal (ZF = \)." If CMPS is
preceded by REPNE or REPNZ, the operation
is interrupted as "compare while not end-ofstring (CX not zero) and strings are not equal
(ZF = 0)." Thus, CMPS can be used to find
matching or differing string elements.

Encoding:
11010011wl
if w = 0 then LSRC = (SI), RSRC = (01), OEL TA = 1
else LSRC = (SI) + 1 :(SI), RSRC = (01) + 1 :(01), OELTA
CMPS Operands

Clocks

dest-string,
source-string
(repeat)dest-string,
source-string

22(22)
9+22
(5+22/rep)

Transfers Bytes

=2

CMPS Coding Examples

2

1

CMPS BUFF1, BUFF2

2/rep

1

REP COMPSID, KEY

3-64

210911

THE iAPX 86,88 AND iAPX186,188 ARCHITECTURE AND INSTRUCTIONS

cwo

CONVERT WORD
TO DOUBLEWORD

cwo

Flags Affected:

Operation:
if (AX) < 8000H then (DX)
else (DX) +- FFFFH

+-

None

0

Description:
CWD (Convert Word to Doubleword) extends
the sign of the word in register AX throughout
register DX. CWD does not affect any flags.
CWD can be used to produce a double-length
(doubleword) dividend from a word prior to
performing word division.

Encoding:
10011001

CWO Operands

(no operands)

Clocks

5(4)

Transfers Bytes

3-65

1

CWO Coding t:xample

CWD

210911

THE iAPX 86,88~AND iAPX 186,+88 ARCHITECTURE AND INSTRUCTIONS

DAA

DECIMAL ADJUST
FOR ADDITION
Flags Affected:

Operation:
if ((AL) & OFH) > 9 or (AF) = 1 then
(AL) - (AL) + 6
(AF) -1
if (AL) > 9FH or (CF) = 1 then
(AL) - (AL) + 60H
-(CF) -1

AF, CF, PF,SF, ZF
OF undefined

Description:
DAA (Decimal Adjust for Addition) corrects
the result of previously adding two valid
packed decimal operands (the destination
operand must have been register AL). DAA
changes the content of AL to a pair of valid
packed decimal digits. It updates AF, CF, PF,
SF and ZF; the content of OF is undefined
following execution of DAA.

Encoding:
1001001111

.

DAA Operands
(no operands)

Clocks

4(4)

Transfers Bytes

3-66

1

DAA Coding Example

DAA
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

DAS

DECIMAL ADJUST
FOR SUBTRACTION

DAS

Flags Affected:

Operation:
if «AL) & OFH) >9 or (AF) = 1 then
(AL) - (AL) - 6
(AF) -1
if (AL) > 9FH or (CF) = 1 then
(AL) - (AL) - 60H
(CF) -1

AF, CF, PF, SF, ZF.
OF undefined

Description:
DAS (Decimal Adjust for Subtraction) corrects the result of a previous subtraction of
two valid packed decimal operands (the destination operand must have been specified as
register AL). DAS changes the content of AL
to a pair of valid packed decimal digits. DAS
updates AF, CF, PF, SF and ZF; the content
of OF is undefined following execution of
DAS.

Encoding:
00101111

DAS Operands

(no operands)

Clocks

4(4)

Transfers Bytes

3-67

1

DAS Coding Example
DAS
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

DEC

DECREMENT

Operation:

DEC

Flags Affected:
AF, OF, PF, SF, ZF

(DEST) - (DEST) -1

Description:
DEC (Decrement) subtracts one from the
destination operand. The operand may be a
byte or a word and is treated as an unsigned
binary number (see AAA and DAA). DEC
updates AF, OF, PF, SF and ZF; it does not
affect CF.

Encoding:
Memory or Register Operand:
11111111 w Imod001

r/ml

DEST= EA

16-Bit Register Operand:
1

01 001 reg

DEST= REG
DEC Operands
reg16
reg8
memory

Clocks

3(3)
3(3)
15(15)+EA

Transfers Bytes

-

-

2

3-68

1
2
2-4

DEC Coding Example
DECAX
DECAL
DEC ARRAY [SI]

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

DIV

DIVIDE

Operation:

DIV

Flags Affected:
AF, CF, OF, PF, SF, ZF undefined

(temp) - (NUMR)
if (temp) I (DIVR) > MAX then the
following, in sequence
(QUO), (REM) undefined
(SP) - (SP) - 2
((SP) + 1 :(SP)) - FLAGS
(IF) +- 0
(TF) +- 0
(SP) +- (SP) - 2
((SP) + 1 :(SP)) +- (CS)
(CS) +- (2) Le., the contents of
memory locations 2 and 3
(SP) +- (SP) - 2
((SP) + 1 :(SP)) +- (IP)
(IP) +- (0) Le., the contents of
locations 0 and 1
else
(QUO) +- (temp) I (DIVR), where
I is unsigned division
(REM) +- (temp) % (DIVR) where
% is unsigned modulo

Description:
DIV source

DIV (divide) performs an unsigned division of
the accumulator (and its extension) by the
source operand. If the source operand is a
byte, it is divided into the two-byte dividend
assumed to be in registers AL and AH. The
byte quotient is returned in AL, and the byte
remainder is returned in AH. If the source
operand is a word, it is divided into the twoword dividend in registers AX and DX. The
word quotient is returned in AX, and the word

3-69

remainder is returned in DX. If the quotient
exceeds the capacity of its destination register
(FFH for byte source, FFFFH for word
source), as when division by zero is attempted,
a type 0 interrupt is generated, and the
quotient and remainder are undefined. Nonintegral quotients are truncated to integers. The
content of AF, CF, OF, PF, SF and ZF is undefined following execution of DIY.

210911

THE iAPX 86,88ANDiAPX186, 188 ARCHltECTUREANDINSTAU'CTIONS

DIVI[)E

DIV

Encoding:

I

11111 011 w mod 11 0 r / m

I

if w == 0 then NUMR == AX, DIVR == EA, QUO == AL, REM == AH,MAX == FFH
else,NUMR == DX:AX, DIVR == EA,QUO == AX, REM::: DX, MAX == FFFFH
DIV Operands

CI()cks

Transfers Bytes

DIV Coding Example
<

reg8
reg16
mem8
mem16

80-,90(29)
144-162(38)
86-96' '
+EA(35)
154-172
+EA(44)

t"

-

2
2

1

2-4

DIV ALPHA

1

2-4

DIV TABLE [SI]

3-70

.,,:

lu

' DIVCL
DIVBX

210911

,..·1.

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

ENTER

PROCEDURE ENTRY

Operation:

ENTER

Flags Affected:
None

(SP) +- (SP) - 2
((SP+1: (SP» +- (BP)
(FP) +- (SP)
IF LEVEL> 0 then
Repeat (Level - 1) times
(BP) +- (BP) - 2
(SP) +- (SP) - 2
((SP) + 1 : (SP» +- ((BP»
End Repeat
(SP) +- (SP) - 2
((SP) + 1 : (SP» +- (FP)
End if
(BP) +- (FP)
(SP) +- (SP) - (LSRC)

Description:
ENTER executes the calling sequence for a high-level
language. It saves the current frame pointer (in BP), copies
frame pointers from procedures below the current call (to
allow access to local variables in these procedures) and allo,"
cates space on the stack for the local variables of the current
procedure invocation.

3-71

210911

·
.
THE iAPX86,88 AND,iApx 186,188 ARCHITECTURE AND INSTRUCTIONS

ENTER

PROCEDURE ENTRY

ENTER

Encoding:
11 1 0 0 1 0 ~ 0 1 data low 1data high 1

ENTER Operands

Locals, level

Clocks

L=O(15)
L= 1 (25)
L>1(22+16)

Transfers Bytes

-

4

ENTER Cooing Example

ENTER 28,3

(n-1) )
3-72

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

ESCAPE

ESC

ESC

Flags Affected:

Operation:
if mod f 11 then data bus

+-

(EA)

None

Description:
The ESC (Escape) instruction provides a
mechanism by which other processors
(coprocessors) may receive their instructions
from the 8086 or 8088 instruction stream and
make use of the 8086 or 8088 addressing
modes. The CPU (8086 or 8088) does a no
operation (NOP) for the ESC instruction other
than to access a memory operand and place it
on the bus. On the 80186,188, if bit 15 in the
relocation register is set, a trap type 7 will be
generated; if this bit is set to 0, the 80186,188
will respond to the ESC opcode in the same
way as the 8086,88.

Encoding:
11011x

modxr/m

ESC Operands

Clocks

immediate, memory
immediate, register

8(6) +EA
2(2)

Transfers Bytes

1

-

3-73

2-4
2

ESC Coding Example

ESC 6, ARRAY [SI]
ESC 20, AL··

210911

THE iAPX 86,88 AN.D iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

HLT

HLT
Operation:

Flags Affected:
None

None

Description:
HLT (HaIt) causes the CPU to enter the halt
state. The processor leaves the halt state upon
activation of the RESET line, upon receipt of a
non-maskable interrupt request on NMI, or, if
interrupts are enabled, upon receipt of a mask-

able interrupt request on INTR. HLT does not
affect any flags. It may be used as an alternative to an endless software loop in situations
where a program must wait for an interrupt.

Encoding:
11110100
HLT Operands

(no operands)

Clocks

2(2)

Transfers Bytes

-

3-74

1

HLT Coding Example

HLT

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

IDIV

INTEGER DIVIDE

Operation:

IDIV

Flags Affected:

(temp) +- (NUMR)
if (temp) I (DIVR) > 0 and (temp)
I (DIVR) > MAX
or (temp) I (DIVR) < 0 and (temp)
I (DIVR) < 0 - MAX -1 then
(QUO), (REM) undefined
(SP) +- (SP) - 2
((SP) + 1 :(SP)) +- FLAGS

AF, CF, OF, PF, SF, ZF undefined

(IF) +- 0
(TF) +- 0

(SP) +- (SP) - 2
((SP) + 1:(SP)) +- (CS)
(CS) +- (2)
(SP) +- (SP) - 2
((SP) + 1 :(SP)) +- (lP)
(I P)

+-

(0)

else
(QUO) +- (temp) I (DIVR), where
I is signed division
(REM) +- (temp) % (DIVR) where
% is signed modulo

Description:
IDIV source
j

IDlY (Integer Divide) performs a signed division of the accumulator (and its extension) by
the source operand. If the source operand is a
byte, it is divided into the double-length dividend assumed to be in registers AL and AH;
the single-length quotient is returned in AL,
and the single-length remainder is returned in
AH. For byte integer division, the maximum
positive quotient is +127 (7FH) and the
minimum negative quotient is -127 (81 H). If
the source operand is a word, it is divided into
the double-length dividend in registers AX and
DX;~ the single-length quotient is returned in

AX, and the single-length rentainder is
returned in OX. For word integer division, the
maximum positive quotient is +32,767
(7FFFH) and the minimum negative quotient
is -32,767 (8001H). If the quotient is positive
and exceeds the maximum, or is negative and
is less than the minimum, the quotient and
remainder are undefined, and a type 0 interrupt is generated. In particular, this occurs if
division by 0 is attempted. Nonintegral quotients are truncated (toward 0) to integers, and
the remainder has the same sign as the dividend. The content of AF, CF, OF, PF, SF and
ZF is undefined following IDlY.

3-75

210911

"

"~

1

. THEiAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

IDIV

IDIV

INTEGER DIVIDE

Encoding:
11111 011 w 1mod 111 rIm 1
if w = 0 then NUMR = AX, DIVR = EA, QUO = AL, REM = AH, MAX = 7FH
else NUMR = DX:AX, DIVR = EA, QUO = AX, REM = DX, MAX = 7FFFH
IDlY Operands

reg8
reg16
mem8
mem16

Clocks

101-112
(44-52)
165-184
(53-61 )
107-118
+EA(50-58)
171-190
+EA(59-67)

Transfers Bytes

IDlY Coding Example

-

2

IDIVBL

-

2

IDIVCX

1

2-4

IDIV DIVISOR..'-BYTE[SI]

1

2-4

IDIV [BX].DIVISOR_WORD

3-76

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

IMUL

INTEGER MULTIPLY

IMUL

Flags Affected:

Operation:
(DEST) +- (LSRC) * (RSRC) where
* is signed multiply
if (ext) = sign-extension of (LOW)
then (CF) +- 0
else (CF) +-1;
(OF) +- (CF)

CF,OF
AF, PF, SF, ZF undefined

Description:
IMULsource

IMUL (Integer Multiply) performs a signed
multiplication of the source operand and the
accumulator. If the source is a byte, then it is
multiplied by register AL, and the doublelength result is returned in AH and AL. If the
source is a word, then it is multiplied by
register AX, and the double-length result is
returned in registers DX and AX. If the upper

half of the result (AH for byte source, DX for
word source) is not the sign extension of the
lower half of the result, CF and OF are set;
otherwise they are cleared. When CF and OF
are set, they indicate that AH or DX contains
significant digits of the result. The content of
AF, PF, SF and ZF is undefined following execution of IMUL.

Encoding:
;

'I\

11111 011 w 1mod 1 01 rim 1
if w = 0 then LSRC = AL, RSRC = EA, DEST = AH, EXT = AH, LOW = AL
else LSRC = AX, RSRC = EA, DEST = DX:AX, EXT = DX, LOW = AX
IMUL Operands
immed8
immed16
reg8
reg16
mem8
mem16

Clocks
(22-25)
(29-32)
80-98(25-28)
128-154
(34-37)
86-104
+EA(31-34)
134-160
+EA(40-43)

Transfers Bytes

i

:I

,:1'
,';

IMUL Coding Example

I

-

3
4
2

IMUL6
IMUL20
IMULCL

-

2

IMUL BX

1

2-4

IMUL RATE_BYTE

1

2-4

IMUL RATE_WORD [BP][DI1

3-77

210911

.. THE iAPX 86,88 AND iAPX 186,1;88 ARCHITECTURE AND INSTRUCTIONS

INPUT·BYT:E ORWORD

IN
Operation:
(DEST)

+-

:',

,~.

·IN

Flags Affected:

.

(SRC)

None

Description:
IN accumulator, port

IN transfers a byte or a word from an input
port to the AL register or the AX register,
respectively. The port number may be specified either with an immediate byte constant,
allowing access to ports numbered 0 through

255, or with a number previously placed in the
DX register, allowing variable access ,(by
changing the value in DX) to ports numbered
from 0 through 65,535.

Encoding:
Fixed Port:
111 1 00 1 Ow 1

port

if w = 0 then SRC = port, DEST = A\L
else SRC = port + 1 :port, DEST = AX

Variable Port:
11110t10wl

if w = 0 then SRC= (DX), DEST = AL
else SRC = (DX) + 1 :(DX), DEST = AX
IN Operands

Clocks

accumulator,
·immed8· .
accumulator,DX

10(10)
8(8) .

Transfers Bytes

IN Coding Example

...

1
1

3-78

2 .. IN AL, OEAH
1
IN AX, DX

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

INC
Operation:
(DEST) - (DEST)

INC

INCREMENT
Flags Affected:
+

1

AF, OF, PF, SF, ZF

Description:
INC destination

INC (Increment) adds one to the destination
operand. The operand may be a byte or a word
and is treated as an unsigned binary number
(see AAA and DAA). INC updates AF, OF,
PF, SF and ZF; it does not affect CF.

Encoding:
Memory or Register Operand:
11 1 1 1 1 1 1 w 1mcd 0 0 0 rim 1
DEST= EA

16-Bit Register Operand:
1 01000 reg
DEST= REG
INC Operands
reg16
reg8
memory

Clocks

3(3)
3(3)
15(15)+EA

Transfers Bytes

-

1

2

2
2-4

-

3-79

INC Coding Example
INCCX
INCBL
INC ALPHA [DI][BX]

210911

THE,i~PX

86,88 ANI) jAPX 186,188 ARCHITECTURE. AND INSTRUCTIONS

INPUT STRING

INS

INS

Operation:

Flags Affected:

(OEST) -

None

(SRC)

Description:
INS source-string, port
INS (Input String) transfers a byte or a word from an I/O
port (addressed by DX) to a memory address (pointed to by
DI) and updates DX to point to the next string element.
When used in conjunction with REP, INS performs block
transfers at full bus bandwidth.

Encoding:
I0110110wl

INS Operands

Clocks

dest-string,port
(repeaUdest-string,
port

(14)

2

1

INS BUFF1 , USART 0

(8+8/rep)

2/rep

1

REP INS BUFF1 , USART 0

Transfers Bytes

INS Coding Example

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

INT

INTERRUPT

Operation:

INT

Flags Affected:
"';

(SP) +- (SP) - 2
((SP) + 1 :(SP)) +- FLAGS
(IF)+-O
(TF) +- 0
(SP) +- (SP) - 2
((SP) + 1 :(SP)) +- (CS)
(CS) +- (TYPE * 4 + 2)
(SP) +- (SP) - 2
((SP) + 1 :(SP)) +- (IP)
(lP) +- (TYPE * 4)

I,

IF, TF

Description:
INT interrupt-type
INT (Interrupt) activates the interrupt procedure specified by the interupt-type operand.
INT decrements the stack pointer by two,
pushes the flags onto the stack, and clears the
trap (TF) and interrupt-enable (IF) flags to
disable single-step and maskable interrupts.
The flags are stored in the format used by the
PUSHF instruction. SP is decremented again
by two, and the CS register is pushed onto the
stack. The address of the interrupt pointer is
calculated by multiplying interrupt-type by
four; the second word of the interrupt pointer
replaces CS. SP again is decremented by two,
and IP is pushed onto the stack and is replaced

by the first word of the interrupt pointer. If
interrupt-type = 3, the assembler generates a
short (l byte) form of the instruction, known
as the breakpoint interrupt.
Software interrupts can be used as "supervisor
calls," i.e., requests for service from an
operating system. A different interrupt-type
can be used for each type of service that the
operating system could supply for an application program. Software interrupts also may be
used to check out interrupt service procedures
written for hardware-initiated interrupts.

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

INT

INT

INTERRUPT

Encoding:

I 11 0011 0 v I type if v= 1
if v = 0 then TYPE = 3
else TYPE = type
INT Operands

Clocks

immed8(type=3)

52(45)
51 (47)

immed8(type~3)

Transfers Bytes
5
5

3-82

1
2

INT Coding Example
INT3
INT67

210911

IIi

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

INTO

INTERRUPT ON
OVERFLOW

Operation:

INTO

,

Flags Affected:

if (OF) = 1 then

None

(SP) - (SP) - 2
((SP) + 1 :(SP)) - FLAGS
(IF) - 0
(TF) - 0
(SP) - (SP) - 2
((SP) + 1 :(SP)) -- (CS)
(CS) - (12H)
(SP) -- (SP) - 2
((SP) + 1 :(SP)) - (lP)
(lP) - (10H)

.;
"

Description:
INTO (Interrupt on Overflow) generates a
software interrupt if the overflow flag (OF) is
set; otherwise control proceeds to the following instruction without activating an interrupt
procedure. INTO addresses the target interrupt procedure (its type is 4) through the inter-

rupt pointer at location lOH; it clears the TF
and IF flags and otherwise operates like INT.
INTO may be written following an arithmetic
or logical operation to activate an interrupt
procedure if overflow occurs.

Encoding:
1110011101
INTO Operands

(no operands)

i·,

:1·.···

Clocks

530r4
(48 or 4)

Transfers Bytes

5

3-83

1

INTO Coding Example

INTO

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

IRET

INTERRUPT RETURN

Operation:

IRET

Flags Affected:

(IP) - ((SP) + 1 :(SP))
(SP) - (SP) + 2
(CS) +- ((SP) + 1 :(SP))
(SP) +- (SP) + 2
FLAGS +- ((SP) + 1 :(SP))
(SP) +- (SP) + 2

All

Description:
IRET (Interrupt Return) transfers control
back to the point of interruption by popping
IP, CS and the flags from the stack. IRET thus
affects all flags by restoring them to previously
saved values. IRET is used .to exit any interrupt procedure, whether activated by hardware or software.

Encoding:
1110011111
IRET Operands
(no operands)

Clocks
32(28)

Transfers Bytes
3

3-84

1

IRET Coding Example
IRET

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JA

JNBE

JA

JUMP ON ABOVE
JUMPONNOTBELOW
OR EQUAL

Operation:

JNBE

Flags Affected:

if (CF) & (ZF) = 0 then
(IP) - (lP) + disp (sign-extended
to 16-bits)

None

Description:
Jump on Above (JA)/ Jump on Not Below or
Equal (JNBE) transfers control to the target

operand (IP + displacement) if CF and ZF = O.

Encoding:

I 0111 0111
JAI JNBE Operands
short-label

disp

Clocks

16or4(130r4)

Transfers Bytes

-

2

JA Coding Example

JAABOVE
JNBE Coding Example

JNBEABOVE
3-85

210911

I

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND 'INSTRUCTIONS

JUMP ON ABOVE
OR EQUAL

JAE

JUMP ON,NOT BELOW

JNB

JAE
Operation:

Flags Affected:

if (CF) = 0 then
(IP) .- (lP) + disp (sign-extended
to 16-bits)

None

Description:
JAE (Jump on Above or Equal)! JNB (Jump
on Not Below) transfers control to the target
operand (IP + displacement) if CF = '0.

Encoding:

I 0111 0011
JAE/JNB Operands
short-label

disp
Clocks
16or4(130r4)

Transfers Bytes

-

2

JAE Coding Example
JAE ABOVE_EQUAL

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JB

JUMPON BELOW

JB

JNAE

JUMP ON NOT
ABOVE OR EQUAL

JNAE

Operation:

Flags Affected:

if (CF) = 1 then
(lP) +- (IP) + disp (sign-extended
to 16-bits)

None

Description:
JB (Jump on Below)/ JNAE (Jump on Not
Above or Equal) transfers control to the target
operand (IP + displacement) if CF = I,

I

Encoding:
101110010 1

i~

I.'

disp

~
~

JB/JNAE Operands

short-label

Clocks

16or4
(130r4)

Transfers Bytes

JB Coding Example

I.j.#.'

!.

-

2

JB BELOW

!I
3-87

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JBE

JUMP ON··BELOW
OR EQUAL

JBE

JNA

JUMP ON
NOT ABOVE

JNA

Operation:

Flags Affected:

IF (CF) or (ZF) = 1 then
(IP) ~ (lP) + disp (sign-extended
to 16-bits)

None

Description:
JBE (Jump on Below or Equal)/ JNA (Jump
on Not Above) transfers control to the target
operand (IP + displacement) if CF or ZF = 1.

Encoding:

I 0111 011 0 I
JBE/JNA Operands

short-label

disp
Clocks

16 or4
(130r4)

Transfers Bytes

-

3-88

2

JNA Coding Example

JNA NOT_ABOVE

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JC

JUMP ON CARRY

Operation:

JC

Flags Affected:

if (CF) = 1 then
(IP) ~ (IP) + disp (sign-extended
to 16-bits)

None

Description:
JC (Jump on Carry) transfers control to the
target operand (lP + displacement) on the condition CF = 1.

Encoding:

I 0111 001 0 I
JCOperands
short-label

disp
Clocks
16 or 4
(130r4)

Transfers Bytes

3-89

2

JC Coding Example
JCCARRY SET
210911

THE iAPX 86,88AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JCXZ

JUMP IF ex
REGISTER ZERO

JCXZ

Flags Affected:

Operation:
if (ex) = 0 then
(lP) .- (IP) + disp (sign-extended

None

to 16-bits)

Description:
JCXZ short-label
JeXZ (Jump if ex Zero) transfers control to
the target operand if ex is O. This instruction
is useful at the beginning of a loop to bypass
the loop if ex has a zero value, i.e., to execute
the loop zero times.

Encoding:
11100011

JCXZ Operands

short-label

disp

Clocks

18or6
(16or5)

Transfers Bytes

3-90

2

JCXZ Coding Example

JCXZ COUNT DONE
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JE

JUMP ON EQUAL

JE

JZ

JUMP ONZERO

JZ

Operation:

Flags Affected:

if (ZF) = 1 then
(lP) ~ (IP) + disp (sign-extended
to 16-bits)

None

Description:
JE (Jump on Equal)/ JZ (Jump on Zero)
transfers control to the target operand (lP +
displacement) if ZF = 1.

Encoding:

I 0111 01 00 I
JElJZ Operands
short-label

disp

Clocks
16or4(130r4)

Cc

Transfers Bytes

3-91

2

JZ Coding Example

JZZERO
210911

· THE iAPX 86,88 AND iAPX 186,,188 ARCHITECTURE AND INSTRUCTIONS

JG
JNLE

JUMP ON GREATER
JUMPON NOT
LESS OR EQUAL

Operation:

JG
JNLE

Flags Affected:

if ({SF) = (OF)) or (ZF) = 0 then
(IP) +- (lP) + disp (sign-extended
to 16-bits)

None

Description:
JG (Jump on Greater Than)/ JNLE (Jump on
Not Less Than or Equal) transfers control to
the target operand (IP + displacement) if the
conditions «SF XOR OF) or ZF = 0) are
greater than/not less than or equal to the
tested value.

Encoding:
101111111

JG/JNLE Operands
short-label

disp

Clocks
16or4(130r4)

Transfers Bytes

3-92

2

JG Coding Example
JG GREATER

210911

,

'iI

,j

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

A

JGE

JUMP ON GREATER
OR EQUAL

JGE

JNL

JUMP ON NOT LESS

JNL

Flags Affected:

Operation:
if (SF) = (OF) then
(IP)..- (lP) + disp (sign-extended
to 16-bits)

None

Description:
JGE (Jump on Greater Than or Equal)! JNL
(Jump on Not Less Than) transfers control to
the target operand (lP + displacement) if the
condition (SF XOR OF = 0) is greater than or
equal/not less than the tested value.

Encoding:

I 011111 01
JGEI JNL Operands
short-label

disp
Clocks

16or4
(130r4)

Transfers Bytes

3-93

2

JGE Coding Example

JGE GREATER_EQUAL

210911

I.;..

I

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JUMP ON LESS

JL

JUMP ON NOT
GREATER OR EQUAL
Operation:

JNGE

Flags Affected:

if (SF) i= (OF) then
(lP) ~ (IP) + disp (sign-extended
to 16-bits)

None

Description:
JL (Jump on Less Than)/ JNGE (Jump on Not
Greater Than or Equal), transfers control to
the target operand if the condition (SF XOR
OF = \) is less than/not greater than or equal
to the tested value.

Encoding:

I 011111 00 I
JLlJNGE Operands

short-label

disp
Clocks

16or4
(130r4)

Transfers Bytes

3-94

2

JL Coding Example

JL LESS

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JLE

JUMPON LESS
OR EQUAL

JNG

JUMP ON NOT GREATER

Operation:

JLE

JNG

Flags Affected:

if «SF) :#= (OF)) or «ZF) = 1) then
(lP) +- (lP) + disp (sign-extended
to 16-bits)

None

Description:
JLE (Jump on Less Than or Equal to)IJNG
(Jump on Not Greater Than) transfers control
to the target operand (lP + displacement) if
the conditions tested «SF XOR OF) or ZF = I)
are less than or equal to/not greater than the
tested value.

Encoding:

I 0111111 0 I
JLE/JNG Operands

short-label

disp
Clocks

160r 4
(130r4)

Transfers Bytes

3-95

2

JNG Coding Example

JNG NOT_GREATER

210911

THE iAPX86;88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JMP

JUMPUNCONDITIONALLY

Operation:

JMP

Flag's Affected:
None

if Inter-Segment then (CS) - SEG
(IP) - DEST

Description:
JMP target
JMP unconditionally transfers control to the
target location. Unlike a CALL instruction,
JMP does not save any information on the
stack; no return to the instruction following
the JMP is expected. Like CALL, the address
of the target operand may be obtained from
the instruction itself (direct JMP), or from
memory or a register referenced by the instruction (indirect JMP).
An intrasegment direct JMP changes the
instruction pointer by adding the relative
displacement of the target from the JMP
instruction. If the assembler can determine
that the target is within 127 bytes of the JMP,
it automatically generates a two-byte instruction form called a SHORT JMP; otherwise, it
generates a NEAR JMP that can address a
target within ±32k. Intrasegment direct JMPS
are self-relative and appropriate in position-

independent (dynamically relocatable)
routines in which the JMP and its target are
moved together in the same segment.
An intrasegment indirect JMP may be made
either through memory or a 16-bit general
register. In the first case, the word content
referenced by the instruction replaces the
instruction pointer. In the second case, the
new IP value is taken from the register named
in the instruction.
An intersegment direct JMP replaces IP and
CS with values contained in the instruction.
An intersegment indirect JMP may be made
only through memory. The first word of the
doubleword pointer referenced by the instruction replaces IP and the second word replaces
CS.

3-96

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JMP

JUMPUNCONDITIONALLY

JMP

Encoding:
Intra-Segment Direct:
1111 01 001 1 disp-Iow
DEST = (lP)

disp-high

+ disp

Intra-Segment Direct Short:
1111 01 011 1
DEST = (lP)

disp

+ disp sign extended to 16-bits

Intra-Segment Indirect:
1111111111mod100r/ml
DEST = (EA)

Inter-Segment Direct:
111101 01 0 1 offset-low

offset-high

seg-Iow

seg-high

DEST = offset, SEG = seg

Inter-Segment Indirect:
1111111111mod101r/ml
DEST = (EA), SEG = (EA + 2)

JMP Operands

short-label
near-label
far-label
memptr16
regptr16
memptr32

Clocks

15(13)
15(13)
15(13)
18(17)+EA
11(11 )
24(26)+EA

Transfers Bytes

3-97

2
3
5
2-4
2
2-4

JMP Coding Example

JMPSHORT
JMP WITHIN SEGMENT
JMP FAR LABEL
JMP[BX]:tARGET
JMPCX
JMP OTHER.SEG[SI]

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JUMP ON NOT CARRY

JNC
Operation:

JNC

Flags Affected:

if (CF) = 0 THEN
(lP) +- (IP) disp (sign-extended
to 16-bits)

None

+

Description:
JNC (Jump on Not Carry) transfers control to
the target operand (lP + displacement) on the
condition CF = o.

Encoding:
101110011

JNC Operands

short-label

disp

Clocks

16or4
(130r4)

Transfers Bytes

3-98

2

JNC Coding Example

JNC NO_CARRY
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JNE
JNZ

JUMP ON NOT EQUAL
JUMP ON NOT ZERO

JNE
JNZ

Flags Affected:

Operation:
if (ZF) = 0 then
(IP) +- (lP) + disp (sign-extended
to 16-bits)

None

Description:
JNE (Jump on Not Equal toll JNZ (Jump on
Not Zero) transfers control to th'e target
operand (IP + displacement) if the condition
tested (ZF = 0) is true.

Encoding:

I 0111 01 01
JNE/JNZ Operands

short-label

disp
Clocks

16 or4
(130r4)

Transfers Bytes

3-99

2

JNE Coding Example

JNE NOT_EQUAL

210911

I
,

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JNO

JNO

JUMP ON NOT
OVERFLOW

Operation:

Flags Affected:

if (OF) = 0 then
(lP) - (lP) + disp (sign-extended
to 16-bits)

None

Description:
JNO (Jump on Not Overflow} transfers control to the target operand (lP + displacement)
if the condition tested (OF = 0) is true.

Encoding:
101110001
JNO Operands

short-label

disp
Clocks

16or4
(130r 4)

Transfers Bytes

3-100

2

JNO Coding Example

JNO NO OVERFLOW
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JNS

JUMP ON NOT SIGN

JNS

Flags Affected:

Operation:

J

if (SF) = 0 then
(lP) ~ (lP) + disp (sign-extended
to 16-bits)

i

None

j:

Description:
JNS (Jump on Not Sign) transfers control to
the target operand (lP + displacement) when
the tested condition (SF = 0) is true.

Encoding:

I 01111 001
JNS Operands
short-label

disp
Clocks
16or4
(130r4)

Transfers Bytes

3-101

2

JNS Coding Example
JNS POSITIVE
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JNP
JPO

JUMP ON NOT PARITY
JUMP ON PARITY ODD

Operation:

JNP
JPO

Flags Affected:

if (PF) = 0 then
(IP) ..- (IP) + disp (sign-extended
to 16-bits)

None

Description:
JNP (Jump on Not Parity)/ JPO (Jump on
Parity Odd) transfers control to the target
operand if the condition tested (PF = 0) is true.

Encoding:
101111011

JNP/JPO Operands

short-label

disp

Clocks

16or4
(130r4)

Transfers Bytes

3-102

2

JPO Coding Example
JPO ODD _PARITY

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JO

JUMP ON OVERFLOW

JO

Flags Affected:

Operation:
if (OF) = 1 then
(IP) +- (lP) + disp (sign-extended
to 16-bits)

None

Description:
JO (Jump on Overflow) transfers control to
the target operand (lP + displacement) if the
tested condition (OF = 1) is true.

Encoding:

I 0111 0000 I
JOOperands

short-label

disp
Clocks

16 or 4
(130r4)

Transfers Bytes

3-103

2

JO Coding Example

JO SIGNED_OVERFLOW
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JP
JPE

JUMPON PARITY
JUMP ON PARITY EQUAL

Operation:

JP
JPE

Flags Affected:

if (PF) = 1 then
(IP) +- (lP) + disp (sign-extended
to 16-bits)

None

Description:
JP (Jump on Parity)/ JPE (Jump on Parity
Equal) transfers control to the target operand
(lP + displacement) if the condition tested (PF
= 1) is true.

Encoding:

I 01111 01 0 I
JP/JPE Operands

short-label

disp
Clocks

16 or4
(130r4)

Transfers Bytes

3-104

2

JPE Coding Example

JPE EVEN PARITY

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JS

JS

JUMP ON SIGN

Operation:

Flags Affected:

if (SF) = 1 then
(IP) ~ (lP) + disp (sign-extended
to 16-bits)

None

Description:
JS (Jump on Sign) transfers control to the
target operand OP + displacement) if the
tested condition (SF = 1) is true.

Encoding:

I 01111 000 I
JSOperands

short-label

disp
Clocks

16 or 4
(130r4)

Transfers Bytes

3-105

2

JS Coding Example
JS NEGATIVE
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

LAHF

LOAD REGISTER AH
FROM FLAGS

Operation:
(AH)

~

LAHF

Flags Affected:

(SF):(ZF):X:(AF):X:(PF):X:(CF)

None

Description:
LAHF (load register AH from flags) copies
SF, ZF, AF, PF and CF (the 8080/8085 flags)
into bits 7, 6, 4, 2 and 0, respectively, of
register AH. The content of bits 5, 3 and 1 is
undefined; the flags themselves are not
affected. LAHF is provided primarily for converting 8080/8085 assembly language programs to run on an 8086 or 8088.

Encoding:
1100111111
LAHF Operands
(no operands)

Clocks
4(2)

Transfers Bytes

3-106

1

LAHF Coding Example
LAHF

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

LOS

LOAD POINTER USING OS

Operation:

LOS

Flags Affected:

(REG) +- (EA)
(OS) +- (EA + 2)

None

Description:
LDS destination, source
pointer is transferred to register OS. Specifying Sl as the destination operand is a convenient way to prepare to process a source string
that is not in the current data segment (string
instructions assume that the source string is
located in the current data segment and that Sl
contains the offset of the string).

LOS (load pointer using OS) transfers a 32-bit
pointer variable from the source operand,
which must be a memory operand, to the destination operand and register OS. The offset
word of the pointer is transferred to the destination operand, which may be any 16-bit
general register. The segment word of the

Encoding:
111 0001 01 1mod reg rIm

I

if mod = 11 then undefined operation

LOS Operands
reg16, mem32

Clocks

16(18)+EA

Transfers Bytes

2

3-107

2-4

LOS Coding Example
LOS SI, OATA.SEG[OI]

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

LEA
Operation:
(REG)

+--

LEA

LOAD EFFECTIVE
ADDRESS
Flags Affected:

EA

None

Description:
LEA destination, source
LEA (load effective address) transfers the offset of the source operand (rather than its
value) to the destination operand. The source
operand must be a memory operand, and the
destination operand must be a 16-bit general

register. LEA does not affect any flags. The
XLA T and string instructions assume that certain registers point to operands; LEA can be
used to load these registers (e.g., loading BX
with the address of the translate table used by
the XLAT instruction).

Encoding:
10001101
if mod

=

mod req rim

11 then undefined operation

LEA Operands
reg16, mem16

Clocks
2(6)+EA

Transfers Bytes

3-108

2-4

LEA Coding Example
LEA BX,[BP)[DI]
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

LEAVE

RESTORE STACK
FOR PROCEDURE EXIT

LEAVE

Flags Affected:

Operation:

,

:f:

:1,
I

None
(SP) -- (BP)
(BP) -- ((SP) + 1 : (SP))
(SP) -- (SP) + 2

Description:
LEAVE executes a procedure return for a high level
language. It deallocates all local variables and restores the SP
and BP registers to their values immediately after the procedure's invocation.

Encoding:
111001001

LEAVE Operands

(no operands)

Clocks

8

Transfers Bytes

1
3-109

1

LEAVE Coding Example

LEAVE
210911

~

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

LOAD POINTER USING ES

LES

LES

Flags Affected:

Operation:

None

(REG) +- (EA)
(ES) +- (EA + 2)

Description:
LES destination, source
pointer is transferred to register ES. Specifying
OI as the destination operand is a convenient
way to prepare to process a destination string
that is not in the current extra: segment. (The
destination string must be located in the extra
segment, and OI must contain the offset of the
string. )

LES (load pointer using ES) transfers a 32-bit
pointer variable from the source operand,
which must be a memory operand, to the destination operand and register ES. The offset
word of the pointer is transferred to the destination operand, which may be any 16-bit
general register. The segment word of the

Encoding:
111000100

I mod reg rIm I

if mod = 11 then undefined operation
LES Operands

Clocks

Transfers Bytes

~

reg16, mem32

16(18)+EA

2

2-4

LES Coding Example
...
LES OI,[BXl.Tf£XT _BUFF

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

LOCK

LOCK

LOCK THE BUS
Flags Affected:

Operation:

None

None

Description:
LOCK is a one-byte prefix that causes the 8088
(configured in maximum mode) to assert its
bus LOCK signal while the following instruction executes. LOCK does not affect any flags.

Check:
LOCK

JNZ

AL,1
Sema,AL
AL,AL
Check

;set AL to 1 (implies locked)
;test and set lock
;set flags based on AL
;retry if lock already set

MOV

Sema,O

;clear the lock when done

MOV
XCHG

TEST

The instruction most useful in this context is
an exchange register with memory. A simple
software lock may be implemented with the
following code sequence:

The LOCK prefix may be combined with the
segment override and/ or REP prefixes.

Encoding:
11110000

LOCK Operands
(no operands)

Clocks

2(2)

Transfers Bytes

3-111

1

LOCK Coding Example

LOCK XCHG FLAG, AL
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

LODS

LOAD STRING
(BYTE OR WORD)

Operation:

LODS

Flags Affected:

(DEST) +- (SRC)
if (OF) = 0 then (81) +- (81) + DELTA
else (SI) +- (SI) - DELTA

None

Description:
LODS source-string
LODS (Load String) transfers the byte or word
string element addressed by SI to register AL
or AX, and updates SI to point to the next element in the string. This instruction is not ordinarily repeated since the accumulator would be

overwritten by each repetition, and only the
last element would be retained. However,
LODS is very useful in software loops as part
of a more complex string function built up
from string primitives and other instructions.

Encoding:
11010110wl
if w = 0 then SRC = (SI), DEST = AL, DELTA = 1
else SRC = (SI) + 1 :(SI), DEST = AX, DELTA = 2
LODS Operands
sou rce-stri ng
(repeat)
sou rce-stri ng

Clocks

12(10)
9+13
(6+ 11 Irep)

Transfers Bytes

LODS Coding Example

1

1

LaDS CUSTOMER_NAME

1/rep

1

REP LaDS NAME

3-112

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

LOOP

LOOP
Operation:

LOOP

Flags Affected:

(ex) ~ (ex) -1
if (ex) -j 0 then

None

(IP) ~ (lP) + disp (sign-extended
to 16-bits)

Description:
LOOP short-label
LOOP decrements ex by 1 and transfers control to the target operand if ex is not 0;
otherwise the instruction following LOOP is
executed.

Encoding:
11100010
LOOP Operands

short-label

disp
Clocks

17 or S
(1SorS)

Transfers Bytes

3-113

2

LOOP Coding Example

LOOP AGAIN
210911

THE iAPX 86,88.AND iAPX 186,188 ARCHITECTURE .AND INSTRUCTIONS

LOOPE

LOOPWHILE
EQUAL

LOOPE

LOOPZ

LOOPWHILE
ZERO

LOOPZ

Operation:

Flags Affected:
None

(ex) - (ex) -1

if (ZF) = 1 and (eX) =1= 0 then
(IP) - (lP) + disp (sign-extended
to 16-bits)

Description:
LOOPE/LOOPZ short-label
LOOPE and LOOPZ (Loop While Equal and
Loop While Zero) are different mnemonics for
the same instruction (similar to the REPE and
REPZ repeat prefixes). ex is decremented by
I, and control is transferred to the target
operand if ex is not a and if ZF is set;
otherwise the instruction following LOOPEI
LOOPZ is executed.

Encoding:
1111 00001

LOOPEILOOPZ
Operands

short-label

disp

Clocks

18or6
(16 or 6)

Transfers Bytes

3-114

2

LOOPE Coding Example

LOOPEAGAIN
210911

I

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

LOOPNZ

LOOP WHILE
NOT ZERO

LOOPNZ

LOOP WHILE
NOTEQUAL

LOOPNE

LOOPNE
Operation:

Ill,",

I'
"

~'

Flags Affected:

(ex) ..- (ex) -1
if (ZF) = 0 and (eX) 0 then
(lP) ..- (IP) + disp (sign-extended
to 16-bits)

None

*

Description:
LOOPNE/LOOPNZ short-label
LOOPNE and LOOPNZ (Loop While Not
Equal and Loop While Not Zero) are also
synonyms for the same instruction, ex is
decremented by 1, and control is transferred to
the target operand if ex is not 0 and if ZF is
clear; otherwise the next sequential instruction
is executed.

'f

I

,-'I,
I

I.:
J,

Encoding:
111100000 1
LOOPNEILOOPNZ
Operands

short-label

disp

Clocks

19 or5
(16or5)

Transfers Bytes

3-115

2

LOOPNE Coding Example

LOOPNE AGAIN
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

MOV

MOVE (BYTE OR WORD)MOV

Operation:
(DEST)

+-

Flags Affected:

(SRC)

None

Description:
MOV destina'tion, source

MOVE transfers a byte or a word from the
source operand to the destination operand.

Encoding:
Memory or Register Operand to/from Register Operand:

I

11 0001 0 d w mod reg rIm

I

if d = 1 then SRC = EA, DEST = REG
else SRC = REG, DEST = EA

Immediate Operand to Memory or Register Operand:

I

111 00011 w mod 000 rIm
SRC

I

data

data if w=l

= data, DEST = EA

Immediate Operand to Register:
110 11w reg
SRC

I

data

data if w=l
!

= data,, DEST = REG
3-116

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

M OV

MOVE (BYTE OR WORD)

MOV

Encoding:
Memory Operand to Accumulator:
1101 0000 w 1 addr-Iow

1 addr-high

if w = 0 then SRC = addr, DEST = AL
else SRC = addr+ 1:addr, DEST = AX

Accumulator to Memory Operand:
1101 0001 w 1 addr-Iow

1 addr-high
if w = 0 then SRC = AL, DEST = addr
else SRC = AX, DEST = addr+ 1:addr

Memory or Register Operand to Segment Register:
11 000111 0 Imod 0 reg r I ml
if reg "* 01 then SRC = EA, DEST = REG
else undefined operation

Segment Register to Memory or Register Operand:
11 00 0 1 1 0 0 Imod 0 reg r I ml
SRC = REG,DEST = EA

MOV Operands

Clocks

memory, accumulator
accu m u lator, memory
register, register
register, memory
memory, register
register, immediate
memory, immediate

10(9)
10(8)
2(2)
8(12)+EA
9(9)+EA
4(3-4)
10(12-13)
+ EA
2(2)
8(9)+EA
2(2)
9(11)+EA

seg-reg, reg16
seg-reg, mem16
reg16, seg-reg
memory, seg-reg

.

Transfers Bytes

1
1

-

1
1

-

1

-

1

-

1

3-117

MOV Coding Example

3
3
2
2-4
2-4
2-3

MOV ARRAY AL
MOV AX,TEMP _RESULT
MOVAX,CX
MOV BP, STACK TOP
MOV COUNT [DIf.CX
MOVCL,2

3-6
2
2-4
2
2-4

MOV MASK[BX][SI],2CH
MOVES, CX
MOV DS,SEGMENT _BASE
MOVBP, SS
MOV[BX],SEG_SAVE,CS

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

MOVE STRING

MOVS
Operation:

MOVS

Flags Affected:

)

(DEST)

+--

(SRC)

None

Description:
MOVS destination-string, source-string
MOVS (Move String) transfers a byte or a
word from the source string (addressed by SI)
to the destination string (addressed by DI) and
updates SI and DI to point to the next string
element. When used in conjunction with REP,
MOVS performs a memory-to-memory block
transfer.

Encoding:
11010010wl
if w = 0 then SRC = (SI), DEST = AL, DELTA = 1
else SRC = (SI) + 1:(SI), DESr= AX, DELTA =2
MOVS Operands

Clocks

dest-string,
source-string
(repeat) dest-string,
source-string

18(9)
9+ 17/rep
(8+8/rep)

Transfers Bytes

MOVS Coding Example

2

1

MOVS LINE EDIT DATA

2/rep

1

REP MOVS SCREEN,
BUFFER

(

3-118

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

MUL

MUL

MULTIPLY
Flags Affected:

Operation:
(DES) +- (LSRC) * (RSRC), where *
is unsigned multiply
if (EXT) = 0 then (CF) +- 0
else (CF) +-1;
(OF) +- (CF)

CF,OF.
AF, PF, SF, ZF undefined

Description:
MUL source
ands are treated as unsigned binary numbers
(see AAM). If the upper half of the result (AH
for byte ~ource, OX for word source) is nonzero, CF and OF are set; otherwise they are
cleared. When CF and OF are set, they indicate that AH or OX contains significant digits
of the result. The content of AF, PF, SF and
ZF is undefined following execution of MUL.

MUL (Multiply) performs an unsigned multiplication of the source operand and the accumulator. If the source is a byte, then it is
multiplied by register AL, and the doublelength result is returned in AH and AL. If the
source operand is a word, then it is multiplied
by register AX, and the double-length result is
returned in registers OX and AX. The oper-

Encoding:
11111 011 w 1mod 1 00 rIm 1
if w = 0 then LSRC = AL, RSRC = EA, DEST = AX, EXT = AH
else LSRC = AX, RSRC = EA, DEST = DX:AX, EXT = DX
MUL Operands
regS
reg16
memS
mem16

Clocks

Transfers Bytes

.:3:

70-77
(26-2S)(,. D
11S-1n
(35-37)
76-S3 +
EA(32-34)
124-139
+EA(41-43)

MUL Coding Example
,I

-

2

MUL BL

-

2

MULCX

1

2-4
2-4

II

:1
:1

II

MUL MONTH [sl)
MUL BAUD RATE

1

'1

iI.l
3-119

210911

11

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

NEG

NEG

NEGATE

Operation:

Flags Affected:
AF, CF, OF, PF, SF, ZF

(EA) - SRC - (EA)
(EA) - (EA) + 1 (affecting flags)

Description:
NEG destination
NEG (Negate) subtracts the destination
operand, which may be a byte or a word, from
o and returns the result to the destination. This
forms the two's complement of the number,
effectively reversing the sign of an integer. If
the operand is zero, its sign is not changed.

Attempting to negate a byte containing -128
or a word containing -32,768 causes no
change to the operand and sets OF. NEG
updates AF, CF, OF, PF, SF and ZF. CF is
always set except when the operand is zero, in
which case it is cleared.

Encoding:
11111 011 w 1mod 0 11 r / m 1
if w = 0 then SRC = FFH
else SRC = FFFFH

NEG Operands

register
memory

Clocks

3(3)
16(3) +EA

Transfers Bytes

-

2

3 c 120

2
2-4

NEG Coding Example

NEGAL
NEG MULTIPLIER

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

NOP

NOP

NO OPERATION
Flags Affected:

Operation:

None

None

Description:
NOP
NOP (No Operation) causes the CPU to do
nothing. NOP does not affect any flags.

II
,!

Encoding:
1100100001

NOP Operands
(no operands)

Clocks

3(3)

Transfers Bytes

3-121

1

NOP Coding Example
NOP

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

NOT
Operation:
(EA)

+-

NOT

LOGICAL NOT
Flags Affected:

SRC - (EA)

None

Description:
NOT destination
NOT inverts the bits (forms the one's complement) of the byte or word operand.

Encoding:
11111 011 w 1mod 01 0 r / m 1
if w = 0 then SRC = FFH
else SRC = FFFFH
NOT Operands

register
memory

Clocks

3(3)
16(3) +EA

Transfers Bytes

2

-

NOT Coding Example

NOTAX
NOT CHARACTER

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

OR

LOGICAL OR

Operation:

OR

Flags Affected:

(DEST) +- (LSRC) OR (RSRC)
(CF) +- 0
(OF) +- 0

CF, OF, PF, SF, ZF.
AF undefined

Description:
OR destination,source
OR performs the logical "inclusive or" of the
two operands (byte or word) and returns the
result to the destination operand. A bit in the
result is set if either or both corresponding bits
in the original operands are set; otherwise the
result bit is cleared.

I

3-123

210911

':~

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

OR

OR

LOGICAL OR

Encoding:
Memory or Register Operand with Register Operand:
100001 0 d w 1mod reg rIm 1

if d = 1 then LSRC = REG, RSRC = EA, DEST = REG
else LSRC = EA, RSRe = REG, DEST = EA

Immediate Operand to Memory or Register Operand:
11000000 w

Imod 001 rim I

LSRC = EA, RSRC

=

data if w=1

data

data, DEST = EA

Immediate Operand to Accumulator:

I 000011 0 w I

data

I

data if w=1

I

if w = 0 then LSHC = AL, RSRC = data, DEST = AL
else LSRC = AX, RSRC = data, DEST = AX

OR Operands

Clocks

reg ister, reg ister
register, memory
memorY,register
accumulator,
immediate
register, immediate
memory, immediate

3(3)
9(10)+EA
16(10)+EA
4(3-4)
4(4)
17(16)+EA

Transfers Bytes

OR Coding Example

-

2
2-4
2-4

ORAL, BL
OR OX,PORT 10[01]
OR FLAG_BYTE, CL

-

2-3
3-4
3-6

OR AL, 011011 OOB
ORCX,01H
OR[BX] .CMO_WORO,OCFH

1
2

-

2

3-124

210911

OUTPUT

OUT
Operation:

OUT

Flags Affected:
None

(DEST) - (SRC)

Description:
OUT port,accumulator

255, or with a number previously placed in
register DX, allowing variable access (by
changing the value in DX) to ports numbered
from 0 through 65,535.

OUT transfers a byte or a word from the AL
register or the AX register, respectively, to an
output port. The port number may be specified either with an immediate byte constant,
allowing access to ports numbered 0 through

Encoding:
Fixed Port:
111 1 00 11 w 1

port

if w = 0 then SRC = AL, DEST = port
else SRC = AX, DEST = port + 1 :port

Variable Port:
11110111wl
if w = 0 then SRC = AL, DEST = (DX)
else SRC = AX, DEST = (DX) + 1 :(DX)

OUT Operands

Clocks·

im med8,accu m u lator
OX, accumulator

10(9)

8(7)

Transfers Bytes
1
1

3-125

2
1

OUT Coding Example

OUT 44, AX
OUTOX,AL

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

OUTS

OUTPUT STRING

OUTS

Flags Affected:

Operation:

None
(DST) -- (SRC)

Description:
OUTS port, destination string
OUTS transfers a byte or word from a destination
string (addressed by SO to an output port
(addressed by DX). After the transfer, SI is
updated to point to the next string element.
When used with REP, the block transfer takes
place at full bus bandwidth.

Encoding:
I0110111Wl

OUTS Operands

port,source-string
(repeat) port,
sou rce-stri ng

Clocks

Transfers Bytes

OUTS Coding Example

(14)

2

1

OUTS PORT2, BUFF2

(8+8/rep)

2/rep

1

REP OUTS PORT4, BUFF2

3-126

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

POP

POP

Operation:

POP

Flags Affected:

(DEST) +- ((SP) + 1 :(SP))
(SP) +- (SP) + 2

None

Description:
POP destination
POP transfers the word at the current top of
stack (pointed to by SP) to the destination
operand, and then increments SP by two to
point to the new top of stack. POP can be used
to move temporary variables from the stack to
registers or memory.

3-127

210911

THEiAPX 86,88 AND iAPX .186, 188 ARCHITECTURE AND INSTRUCTIONS

POP

POP

POP

Encoding:
Memory or Register Operand:
110001111 1mod 000 rim

I

DEST = EA

Register Operand:
1 01 011 reg
DEST= REG

Segment Register:

I0 0 0 reg 1 1 1 I
if reg =f. 01 then DEST = REG
else undefined operation

POP Operands

register
seg-reg(CS illegal)
memory

Clocks

8(10)
8(8)
17(20) +EA

Transfers Bytes

1
1
2

3-128

1
1
2-4

POP Coding Example

POPDX
POPDS
POP PARAMETER

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

POPA

POP ALL REGISTERS

POPA

Flags Affected:

Operation:

None

(DI) +- «SP) + 1 : (SP))
(SP) +- (SP) + 2
(SI) +(SP) +- (SP) + 2
(BP) +- «SP) + 1 : (SP»
(SP) +- (SP) + 2
(BX) +- «SP) + 1: (SP»
(SP) +- (SP) + 2
(DX) +- «SP) + 1: (SP»
(SP) +- (SP) + 2
(eX) +- «SP) + 1 : (SP»
(SP) +- (SP) + 2
(AX) +-,«SP + 1 : (SP»
(SP) +- (SP) + 2

3-129

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

POPA

POP ALL REGISTERS

POPA

Description:
POPA pops all data, pointer and index registers
off of the stack. The SP value popped is discarded.

Encoding:
101100001

POPA Operands

(no operands)

Clocks

(51 )

Transfers Bytes

8
3-130

1

POPA Coding Example

POPA

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

POPF

POPF

POP FLAGS

Operation:

Flags Affected:

Flags .- ((SP) + 1:(SP))
(SP) .- (SP) + 2

I'

All

I

I

IIi1.
~

Description:
POPF
POPF transfers specific bits from the word at
the current top of stack (pointed to by register
SP) into the 8086/8088 flags, replacing
whatever values the flags previously contained
(see figure 2-32). SP is then incremented by
two to point to the new top of stack. PUSHF

and POPF allow a procedure to save and
restore a calling program's flags. They also
allow a program to change the setting of TF
(there is no instruction for updating this flag
directly). The change is accomplished by
pushing the flags, altering bit 8 of the memoryimage and then popping the flags.

III,
I!
I,
i.~

H

Encoding:
1100111011

POPF Operands
(no operands)

Clocks

8(8)

Transfers Bytes
1
3-131

1

POPF Coding Example
POPF

210911

THE iAPX86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

PUSH

PUSH

Operation:

PUSH

Flags Affected:

(SP) +- (SP) - 2
((SP) + 1 :(SP)) +- (SRC)

None

Description:
PUSH source

PUSH decrements SP (the stack pointer) by
two and then tranfers a word from the source
operand to the top of stack now pointed to by
SP. PUSH often is used to place parameters
on the stack before calling a procedure; more
generally, it is the basic means of storing temporary data on the stack.

3-132

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

PUSH

PUSH

PUSH

II

Encoding:
Memory or Register Operand:
111111111 1mod 11 0 rIm 1
SRC= EA

Register Operand:
1 01 01 0 reg
SRC= REG

Segment Register:
10 0 0 reg 1 1 0 1
SRC= REG

PUSH Operands
register
seg-reg(CS legal)
memory

Clocks
11(10)
10(9)
16(16)+EA

Transfers Bytes
1
1
2
3-133

1
1
2-4

PUSH Coding Example
PUSH SI
PUSH ES
PUSH RETURN_CODE[SI]
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

PUSHA

PUSH ALL REGISTERS

PUSHA

Flags Affected:

Operation:

None
temp +-- (SP)
(SP) +-- (SP) - 2
((SP) + 1 : (SP))
(SP) +-- (SP) - 2
((SP) + 1 : (SP))
(SP) +-- (SP) - 2
((SP) + 1 : (SP))
(SP) +-- (SP) - 2
((SP) + 1 : (SP))
(SP) +-- (SP) - 2
((SP) + 1 : (SP))
(SP) +-- (SP) - 2
((SP) + 1 : (SP))
(SP) +-- (SP) - 2
((SP) + 1 : (SP))
(SP) +- (SP) - 2
((SP) + 1 : (SP))
(SP) +-- (SP) - 2
((SP) + 1 : (SP))

+--

(AX)

+--

(eX)

+--

(DX)

+--

(BX)

+--

(SP)

+--

(SP)

+--

(BP)

+--

(SI)

+--

(DI)

3-134

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

PUSHA

PUSH ALL REGISTERS

PUSHA

Description:
PUSHA pushes all data, pointer and index registers
onto the stack. The order in which the registers are
saved is: AX, ex, DX, BX, SP, BP, SI and DI. The SP
value pushed is the SP value before the first register
(AX) is pushed.

Encoding:
1011000001

PUSHA Operands
(no operands)

Clocks
(36)

Transfers Bytes

8
3-135

1

PUSHA Coding Example

PUSHA
210911

THE iAPX Q6,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

PUSHF

PUSH FLAGS

PUSHF

Flags Affected:

Operation:
(SP)- (SP) - 2
((SP) + 1:(SP)) - Flags

None

Description:
PUSHF
PUSHF decrements SP (the stack pointer) by
two and then transfers all flags to the word at
the top of stack pointed to by SP. The flags
themselves are not affected.

Encoding:
11 001 1 1 001

PUSHF Operands

(no operands)

Clocks
10(9)

Transfers Bytes
1

1

PUSHF Coding Example

PUSHF
210911

Ij

II

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

RCL

ROTATE THROUGH
CARRY LEFT

Operation:

.~

RCL

Flags Affected:
CF,OF

(temp) - COUNT
do while (temp) i= 0
(tmpcf) - (CF)
(CF) - high-order bit of (EA)
(EA) - (EA) * 2 + (tmpcf)
(temp) - (temp)-1
if COUNT = 1 then
if high-order bit of (EA) i= (CF)
then (OF) -1
else (OF) - 0
else (OF) undefined

Description:
RCL destination, count

RCL (Rotate through Carry Left) rotates the
bits in the byte or word destination operand to
the left by the number of bits specified in the
count operand. The carry flag (CF) is treated
as "part of" the destination operand; that is,
its value is rotated into the low-order bit of the
destination, and itself is replaced by the highorder bit of the destination.

3-137

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

RCL

ROTATE THROUGH
CARRY LEFT

RCL

Encoding:
1110100vw Imod010r/mi

if v = 0 then COUNT = 1
else COUNT = (CL)

RCL Operands

register, n
memory, n
register 1,
register, CL
memory, 1
memory, CL

Clocks

(5+ 1fbit)
(17+ 1fbit)
2(2)
8+4fbit
(5+ 1fbit)
15(15)+EA
20 + 4fbit
(17+1/bID+EA

Transfers Bytes

-

RCL Coding Example

3
3-5
2

RCLCX,5
RCLALPHA,5
RCL CX, 1

2

2
2-4

RCLAL, CL
RCLALPHA,1

2

2-4

RCLlBP].PARAM, CL

2

-

-

3-138

210911

I
.~

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

RCR

ROTATE THROUGH
CARRY RIGHT

Operation:

RCR

Flags Affected:

(temp) - COUNT
do while (temp) "* 0
(tmpcf) - (CF)
(CF) - low-order bit of (EA)
(EA) - (EA) I 2
high-order bit of (EA) - (tmpcf)
(temp) - (temp)-1
if COU NT = 1 then
if high-order bit of (EA)"* nextto-high-order bit of (EA)
then (OF) -1
else (OF) - 0
else (OF) undefined

CF,OF

Description:
RCR destination, count
RCR (Rotate through Carry Right) operates
exactly like RCLexcept that the bits are
rotated right instead of left.

Encoding:
111 01 00 v w 1mod 011 rIm 1
if v = 0 then COUNT = 1
else COU NT = (CL)
RCR Operands

register, n
memory, n
register, 1
register, CL
memory, 1
memory, CL

Clocks

(5+ 1 fbit)
(17+1fbit)
2(2)
8+4fbit
(5+ 1 fbit)
15(15)+EA
2O+4fbit
(17+1fbit)+EA

Transfers Bytes

-

RCR Coding Example

3
3-5
2

RCR BX, 5
RCR [BXl.STATUS, 5
RCR BX, 1

2

2
2-4

RCR BL, CL
RCR [BXl.STATUS, 1

2

2-4

RCR ARRAY[OI], CL

2

-

-

3-139

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

REPEAT
REP
REP
REPE/REPZ
REPE/REPZ
REPEAT WHILE EQUAL/
REPEAT WHILE ZERO

REPNE/REPNZREPNE/REPNZ
REPEAT WHILE NOT EQUAL/
REPEAT WHILE NOT ZERO

Operation:

Flags Affected:

do while (CX) =1= 0
service pending interrupt (if
any) execute primitive string
operation in succeeding byte
(CX) - (CX) -1
if primitive operation is CMPB,
CMPW, SCAB, or SCAW and
(ZF) =1= z then exit from
while loop

None

3-140

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

REPEAT
REP
REP
REPE/REPZ
REPE/REPZ
REPEAT WHILE EQUAL/
REPEAT WHILE ZERO

REPNE/REPNZREPNE/REPNZ
REPEAT WHILE NOT EQUAL/
REPEAT WHILE NOT ZERO

Description:
REP/REPE/REPZ/REPNE/REPNZ
Repeat, Repeat While Equal, Repeat While
Zero, Repeat While Not Equal and Repeat
While Not Zero are mnemonics for two forms
of the prefix byte that controls subsequent
string instruction repetition. The different
mnemonics are provided to improve program
clarity. The repeat prefixes do not affect the
flags,
REP is used in conjunction with the MOVS
(Move String) and STOS (Store String)
instructions and is interpreted as "repeat while
not end-of-string" (CX not 0). REPE and
REPZ operate identically and are physically
the same prefix byte as REP. These instructions are used with the CMPS (Compare
String) and SCAS (Scan String) instructions
and require ZF (posted by these instructions)
to be set before initiating the next repetition.
REPNE and REPNZ are mnemonics for the
same prefix byte. These instructions function
the same as REPE and REPZ except that the
zero flag must be cleared or the repetition is
terminated. ZF does not need to be initialized before executing the repeated string
instruction.

Repeated string sequences are interruptable;
the processor will recognize the interrupt
before processing the next string element.
System interrupt processing is not affected in
any way. Upon return from the interrupt, the
repeated operation is resumed from the point
of interruption. However, execution does not
resume properly if a second or third prefix
(i.e., segment override or LOCK) has been
specified in addition to any of the repeat
prefixes, At interrupt time, the processor
"remembers" only the prefix that immediately
precedes the string instruction. After returning
from the interrupt, processing resumes, but
any additional prefixes specified are not in
effect. If more than one prefix must be used
with a string instruction, interrupts may be
disabled for the duration of the repeated execution. However, this will not prevent a nonmask able interrupt from being recognized.
Also, the time that the system is unable to
respond to interrupts may be unacceptable if
long strings are being processed.

3-141

210911

I
l~.·
I'

,

THE iAPX 86,88 AND iAPX186, 188 ARCHITECTURE AND INSTRUCTIONS

REPEAT
REP
REP
REPE/REPZ
REPE/REPZ
REPEAT WHILE EaUALl
REPEAT WHILE ZERO

REPN E/REPNZREPN E/REPNZ
REPEAT WHILE NOr EaUALl
REPEAT WHILE NOT ZERO

Encoding:
11111001z1
REP Operands
(no operands)
REPE/REPZ Operands
(no operands)

Clocks Transfers Bytes REP Coding Example .

2(2)

-

1

REP MOVS DEST, SRCE

Clocks Transfers Bytes REPE Coding Example

2(2)

-

1

REPE CMPS DATA, KEY

REPNE/REPNZ Operands Clocks Transfers Bytes REPNE Coding Example
(no operands)

2(2)

3-142

1

REPNE SCAS INPUT_LINE

/

210911

I
,~

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

'~
l

RET

RETURN

RET

Flags Affected:

Operation:

None

(lP) - ((SP)=1 :(SP))
(SP) - (SP) + 2
if Inter-Segment then
(CS) - ((SP) + 1 :(SP))
(SP) - (SP) + 2
if Add Immediate to Stack Pointer
then (SP) - (SP) + data

Description:
RET optional-pop-value

RET (Return transfers control from a procedure back to the instruction following the
CALL that activated the procedure. The
assembler generates an intrasegment RET if
the programmer has defined the procedure
NEAR, or an intersegment RET if the procedure has been defined as FAR. RET pops
the word at the top of the stack (pointed to by
register SP) into the instruction pointer and

increments SP by two. If RET is intersegment,
the word at the new top of stack is popped into
the CS register, and SP is again incremented
by two. If an optional pop value has been
specified, RET adds that value to SP. This
feature may be used to discard parameters
pushed onto the stack before the execution of
the CALL instruction.

3-143

210911

I

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

RETURN

RET

RET

Encoding:
Intra-Segment:
1110000111

Intra-Segment and Add Immediate to Stack Pointer:
111 00001 0 1 data-low

data-high

Inter-Segment:
1110010111

Inter-Segment and Add Immediate to Stack Pointer:
111 001 010 1 data-low
RET Operands
(intra-segment,
no pop)
(intra-segment, pop)
(inter-segment,
no pop)
(inter-segment, pop)

Clocks

data-high
Transfers Bytes

16(16)
20(18)

1
1

3

26(22)
25(25)

2
2

3

3-144

1
1

RET Coding Example
RET
RET4
RET
RET2
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

ROL

ROTATE LEFT

Operation:

ROL

Flags Affected:
CF, OF

(temp) - COUNT
do while (temp);/= 0
(CF) - high-order bit of (EA)
(EA) - (EA) * 2 + (CF)
(temp) - (temp)-1
if COUNT = 1 then
if high-order bit of (EA);/= (CF)
then (OF)-1
else (OF) - 0
else (OF) undefined

Description:
ROl destination, count
ROL (Rotate Left) rotates the destination byte
or word left by the number of bits specified in
the count operand.

Encoding:
11101 OOvw Imod 000

r/ml

if v = 0 then COUNT = 1
else COUNT = (CL)

ROL Operands
register, n
memory, n
register, 1
register, CL
memory, 1
memory, CL

Clocks
(5+ 1 fbit)
(17 + 1 fbit)
2(2)
8+4fbit
(5+ 1 fbit)
15(15) +EA
20+4fbit
(17-f-1fbit)+EA

Transfers Bytes

-

ROL Coding Example

3
3-5
2

ROL BX,5
ROL FLAG_BYTE[011,5
ROL BX, 1

2

2
2-4

ROL 01, CL
ROL FLAG_BYTE[Oll, 1

2

2-4

ROL ALPHA, CL

2

-

3-145

210911

THE iAPX86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

ROR

ROTATE RIGHT

Operation:

ROR

Flags Affected:
CF, OF

(temp) - COUNT
do while (temp) =1= 0
(CF) - low-order bit of (EA)
(EA) - (EA) I 2
high-order bit of (EA) - (CF)
(temp) - (temp)-1
if COUNT = 1 then
if high-order bit of (EA) =1= nextto-high-order bit of (EA)
then (OF)-1
else (OF) - 0
else (OF) undefined

Description:
ROR destination, count
ROR (Rotate Right) operates similar to ROL
except that the bits in the destination byte or
word are rotated right instead of left.

Encoding:
11101 OOvw Imod001 rlml
if v = 0 then COUNT = 1
else COUNT = (CL)

ROR Operands
register, n
memory, n
register, 1
register, CL
memory, 1
memory, CL

Clocks
(5+ 1/bit)
(17 + 1/bit)
2(2)
8+4/bit
(5+ 1/bit)
15(15) +EA
2O+4/bit
(17+1/bit}+EA

Transfers Bytes

-

ROR Coding Example

3
3-5
2

RORAL,5
ROR PORT_STATUS, 5
ROR AL, 1

2

-

2
2-4

ROR BX, CL
ROR PORT _STATUS, 1

2

2-4

ROR CMD_WORD, CL

2

-

3-146

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

SAHF

STORE REGISTER AH
INTO FLAGS

SAHF

Flags Affected:

Operation:
(SF):(ZF):X:(AF):X:(PF):X:(CF) +- (AH)

,~

AF, CF, PF, SF, ZF

Description:
SAHF
SAHF (store register AH into flags) transfers
bits 7, 6, 4, 2 and 0 from register AH into SF,
ZF, AF, PF and CF, respectively, replacing
whatever values these flags previously had.
OF, OF, IF and TF are not affected. This
instruction is provided for 8080/8085
compatibility.

Encoding:
10011110

SAHF Operands

(no operands)

Clocks
4(3)

Transfers Bytes

3-147

1

SAHF Coding Example

SAHF

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

SAL
SH L

SHIFT ARITHMETIC LEFT
SHIFT LOGICAL LEFT

Operation:

SAL
SHL

Flags Affected:
CF, OF, PF, SF, ZF.
AF undefined

(temp) - COUNT
do while (temp) i= 0
(CF) +- high-order bit of (EA)
(EA) - (EA) * 2
(temp) - (temp)-1
if COU NT = 1 then
if high-order bit of (EA) i= (CE)
then (OF) -1
else (OF) +- 0
else (OF) undefined

Description:
SHL/SAL destination, count
SHL and SAL (Shift Logical Left and Shift
Arithmetic Left) perform the same operation
and are physically the same instruction. The
destination byte or word is shifted left by the
number of bits specified in the count operand.
Zeros are shifted in on the right. If the sign bit
retains its original value, then OF is cleared.

3-148

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

SAL
SHL

SHIFT ARITHMETIC LEFT
SHIFT LOGICAL LEFT

SAL
SHL

Encoding:
11101 OOvw Imcd1

OOr/m]

if v = 0 then COU NT = 1
else COUNT = (CL)

SALISHL
Operands

register, n
memory, n
register, 1
register, CL
memory, 1
memory, CL

SAL/SHL
Clocks

(5+ 1Ibit)
(17 + 1Ibit)
2(2)
8+4/bit
(5+ 1Ibit)
15(15) +EA
20 + 4/bit
(17+ 1Ibit} +EA

Transfers Bytes

-

Coding Example

3
3-5
2

SALAH,5
SAL[BX].OVERDRAW,5
SAL AH, 1

2

2
2-4

SHLDI, CL
SHL[BX].OVERDRAW,1

2

2-4

SAL STORE_COUNT, CL

2

-

3-149

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

SAR

SHIFT'ARITHMETIC
RIGHT

Operation:

SAR

Flags Affected:
CF, OF, PF, SF, ZF.
AF undefined

(temp) - COUNT
do while (temp) i= 0
(CF) - low-order bit of (EA)
(EA) - (EA) I 2, where I is
equivalent to signed division,
rounding down
(temp) - (temp)-1
if COUNT = 1 then
if high-order bit of (EA) i= nextto-high-order bit of (EA)
then (OF)-1
else (OF) - 0
else (OF) - 0

Description:
SAR destination, count
SAR (Shift Arithmetic Right) shifts the bits in
the destination operand (byte or word) to the
right by the number of bits specified in the
count operand. Bits equal to the original highorder (sign) bit are shifted in on the left,
preserving the sign of the original value. Note
that SAR does not produce the same result as
the dividend of an "equivalent" IDlY instruc-

tion if the destination operand is negative and
I-bits are shifted out. For example, shifting -5
right by one bit yields -3, while integer division -5 by 2 yields -2. The difference in the
instructions is that IDlY truncates all numbers
toward zero, while SAR truncates positive
numbers toward zero and negative numbers
toward negative infinity.

3-150

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

SAR

SHIFT ARITHMETIC
RIGHT

SAR

'Ii,,

Encoding:
111 01 00 v w 1mod 111 r / m
if v = 0 then COU NT
else COUNT = (CL)

SAR Operands

register, n
memory, n
register, 1
register, CL
memory, 1
memory, CL

I

=1

Clocks

(5+ 1 fbit)
(17 + 1 fbi!)
2(2)
8+4fbit
(5+ 1 fbit)
15(15)+EA
20 + 4fbit
(17+1fbit)+EA

Transfers Bytes

-

SAR Coding Example

3
3-5
2

SAR OX, 5
SAR N_BLOCKS, 5
SAR OX, 1

2

2
2-4

SAR 01, CL
SAR N_BLOCKS, 1

2

2-4

SAR N_BLOCKS, CL

2

-

3-151

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

SBB

SUBTRACT WITH
BORROW

Operation:

SBB

Flags Affected:

if (CF) = 1 then (DEST) = (LSRC)(RSRC) -1
else (DEST) - (LSRC) - (RSRC)

AF, CF, OF, PF, SF, ZF

Description:
SBB destination, source
SBB (Subtract with Borrow) subtracts the
source from the destination, subtracts one if
CF is set, and returns the result to the destination operand. Both operands may be bytes or
words. Both operands may be signed or

unsigned binary numbers (see AAS and DAS).
SBB updates AF, CF, OF, PF, SF, and ZF.
Since it incorporates a borrow from a
previous operation, SBB may be used to write
routines that subtract numbers longer than 16
bits.

3-152

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

SBB

seB

SUBTRACT WITH
BORROW

Encoding:
Memory or Register Operand and Register Operand:
I 00011 0 d w 1mod reg r / m 1
if d = 1 then LSRC = REG, RSRC = EA, DEST = REG
else LSRC = EA, RSRC = REG, DEST = EA

Immediate Operand from Memory or Register Operand:
11 00000 s w I mod 0 11 r / m I
LSRC = EA, RSRC = data, DEST

data

Idata if s:w=o11

= EA

Immediate Operand from Accumulator:
I 0001110w 1

data

I data if w=1

I

if w = 0 then LSRC = AL, RSRC = data, DEST = AL
else LSRC = AX, RSRC = data, DEST = AX
SBB Operands

Clocks

register, register
register, memory
memory, register
accumulator,
immediate
register, immediate
memory, immediate

3(3)
9(10)+EA
16(10)+EA
4(3-4)
4(4)
17(16)+EA

Transfers Bytes

1
2

2

3-153

SBB Coding Example

2
2-4
2-4

SBB BX, CX
SBB DI,[BXl.PAYMENT
SBB BALANCE, AX

2-3
3-4
3-6

SBB AX, 2
SBB Cl, 1
SBB COUNT [Sll, 10 .

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

SCAS

SCAN (BYTE OR
WORD) STRING

SCAS

Flags Affected:

Operation:
(LSRC) - RSRC)
if (OF) = 0 then (01) -- (01)
else (01) -- (01) - OELTA

+

AF, CF, OF, PF, SF, ZF
OELTA

Description:
seAS destination-string
SCAS (Scan String) subtracts the destination
string element (byte or word) addressed by 01
from the content of AL (byte string) or AX
(word string) and updates the flags, but does
not alter the destination string or the accumulator. SCAS also updates 01 to point to the
next string element and AF, CF, OF, PF, SF
and ZF to reflect the relationship of the scan
value in ALI AX to the string element. If

SCAS is prefixed with REPE or REPZ, the
operatio!1 is interpreted as "scan while not
end-of-string (CX not 0) and string-element =
scan-value (ZF = 1)." This form may be used
to scan for departure from a given value. If
SCAS is prefixed with REPNE or REPNZ, the
operation is interpreted as "scan while not
end-of-string (CX not 0) and string-element is
not equal to scan-value (ZF = 0)." This form
may be used to locate a value in a string.

Encoding:
1

1 0 1 0111W]

if w = 0 then LSRC = AL, RSRC = (01), OEL TA
else LSRC = AX, RSRC = (01) + 1 :(01), OEL TA

SCAS Operands

dest-string
(repeat)dest-string

Clocks

=1
=2

Transfers Bytes

SCAS Coding Example

15(15)
9+15

1

1

SCAS INPUT_LINE

(5+ 15/rep)

1/rep

1

REPNE SCAS BUFFER

3-154

210911

THE iAPX S6,SS AND iAPX 1 S6,1 SS ARCHITECTURE AND INSTRUCTIONS

SHR

SHIFT LOGICAL RIGHT

Operation:

SHR

Flags Affected:
CF, OF, PF, SF, ZF.
AF undefined

(temp) - COUNT
do while (temp) "* 0
CF) - low-order bit of (EA
(EA) - (EA) / 2, where I is
equivalent to unsigned
division
(temp) - (temp)-1
if COUNT = 1 then
if high-order bit of (EA) "* nextto-high-order bit of (EA)
then (OF) -1
else (OF) - 0
else (OF) undefined

Description:
SHR destination, source
SHR (Shift Logical Right) shifts the bits in the
destination operand (byte or word) to the right
by the number of bits specified in the count
operand. Zeros are shifted in on the left. If the
sign bit retains its original value, then OF is
cleared.

3-155

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

SHIFT LOGICAL RIGHT

SHR

SHR

Encoding:
111 01 00 v w 1mod 1 01 rIm

I

if v = 0 then COU NT = 1
else COUNT = (CL)

SHR Operands

register, n
memory, n
register, 1
register, CL
memory, 1
memory, CL

i

Clocks

(5+ 1 fbit)
(17+1fbit)
2(2)
8+4fbit
, (5+ 1 fbit)
15(15) +EA
2O+4fbit
(17+1fbit)+EA

Transfers Bytes

-

SHR Coding Example

3
3-5
2

SHRSI,5
SHR ID_BYTE[SI][BXl, 5
SHR SI, 1

2

2
2-4

SHR SI, CL
SHR ID_BYTE[SIJ[BXl, 1

2

2-4

SHR INPUT_WORD, CL

2

-

3-156

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

STC

SET CARRY

Operation:

STC

Flags Affected:

(CF) -1

CF

Description:
STC
STC (Set Carry flag) sets CF to 1 and affects
no other flags.

Encoding:
1111110011

STC Operands
(no operands)

Clocks

2(2)

Transfers Bytes

3-157

1

STC Coding Example
STC

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

STD

SET DIRECTION FLAG

STD

Flags Affected:

Operation:
(DF) +-1

DF

Description:
STD
/

STD (Set Direction flag) sets OF to I causing
the string instructions to auto-decrement the
SI and/or DI index registers. STD does not
affect any other flags.

Encoding:
111111101

Timing: 2 clocks

STD Operands

(no operands)

Clocks

2(2)

Transfers Bytes

3-158

1

STD Coding Example

sro
\

\.

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

STI

STI

SET INTERRUPT·
ENABLE FLAG

Operation:

Flags Affected:

(IF) -1

IF

Description:
STI (Set Interrupt-enable flag) sets IF to I,
enabling processor recognition of mask able
interrupt requests appearing on the INTR line.
Note however, that a pending interrupt will
not actually be recognized until the instruction
following STi has executed. STI does not
a ffect any other flags.

Encoding:
11111011

STI Operands

(no operands)

Clocks

2(2)

Transfers Bytes

3-159

1

STI Coding Example

STI

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

STOS

STORE (BYTE/ORI
WORD) STRING

STOS

Flags Affect~d:

Operation:
(OEST) ~ (SRC)
if (OF) = 0 then (01) ~ (01) + DELTA
else (01) ~ (01) - OEL TA

None

Description:
STOS destination-string
STOS (Store String) transfers a byte or word
from register AL or AX to the string element
addressed by DI and updates DI to point to the
next location in the string. As a repeated
operation, STOS provides a convenient way
to initialize a string to a constant value (e.g., to
blank out a print line).

Encoding:
11010101wl
if w = 0 then SRC = AL, OEST = (01), OELTA = 1
else SRC = AX, OEST = (01) + 1 :(01), OELTA = 2
STOS Operands

dest-string
(repeat)dest-stri ng

Clocks

11(10)
9+10/rep
(6+9/rep)

Transfers Bytes

STOS Coding Example

1

1

STOP PRINT LINE

1/rep

1

REP STOS DISPLAY

3-160

210911

I

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

.~

SUB

SUBTRACT

Operation:
(DEST)

+-

SUB

Flags Affected:

(LSRC) - (RSRC)

AF, CF, OF, PF, SF, ZF

Description:
SU B destination, source
The source operand is subtracted from the
destination operand, and the result replaces
the destination operand. The operands may be
bytes or words. Both operands may be signed
or unsigned binary numbers (see AAS and
DAS). SUB updates AF, CF, OF, PF, SF and
ZF.

3-161

210911

,

.1

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

SUBTRACT

SUB

SUB

Encoding:
Memory or Register Operand and Register Operand:
1a a 1 a 1 ad w 1mod reg rIm 1
if d = 1 then LSRC = REG, RSRC = EA, DEST = REG
else LSRC = EA, RSRC = REG, DEST = EA

Immediate Operand from Memory or Register Operand:
1100 a a a s w 1mod 10 1 rIm I
LSRC = EA, RSRC

= data,

data

Idata if s:w=01!

DEST = EA

Immediate Operand from Accumulator:
1a a 1 a 11 ow!

data

I data if w=1 !

if w = a then LSRC = AL, RSRC = data, DEST = AL
else LSRC = AX, RSRC = data, DEST = AX
SUB Operands

Clocks

register, register
register, memory
memory, register
accu mu lator,
immediate
register, immediate
memory, immediate

3(3)
9(10) +EA
16(10)+EA
4(3-4)
4(4)
17(16)+EA

Transfers Bytes

1
2

-

-

2

3-162

SUB Coding Example

2
2-4
2-4

SUBCX, BX
SUB DX,MATH TOTAL[SI]
SUB[BP + 21, CL

2-3
3-4
3-6

SUBAL,10
SUB SI, 5280
SUB[BP].BALANCE, 1000

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

TEST

TEST

Operation:

TEST

Flags Affected:

(LSRC) & (RSRC)
(CF) - 0
(OF) - 0

CF, OF, PF, SF, ZF.
AF undefined

Description:
TEST destination, source

TEST performs the logical "and" of the two
operands (byte or word), updates the flags, but
does not return the result, i.e., neither operand
is changed. If a TEST instruction is followed
by a JNZ (jump if not zero) instruction, the
jump will be taken if there are any corresponding I-bits in both operands.

3-163

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

TEST

TEST

TEST

Encoding:
Memory or Register Operand with Register Operand:
11 00001 0 w 1mod reg rIm 1
LSRC

= REG, RSRC = EA

Immediate Operand with Memory or Register Operand:
11111 011 w 1mod 000 rIm 1

data

data if w=1

LSRC = EA, RSRC = data

Immediate Operand with Accumulator:
11 0 1 0 1 0 0 w 1

data

1 data if w=1

if w = 0 then LSRC = AL, RSRC = data
else LSRC = AX, RSRC = data

TEST Operands

Clocks

Transfers Bytes

register, register
register, memory
accumulator,
immediate
register, immediate
memory, immediate

3(3)
9(10)+EA

1

2
2-4

TEST SI, 01
TEST SI, END_COUNT

4(3-4)
5(4)
11(10)+EA

-

2-3
3-4
3-6

TEST AL, 001 OOOOOB
TEST BX, OCC4H
TEST RETURN_CODE,01 H

-

3-164

TEST Coding Example

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

WAIT

WAIT
Operation:

WAIT

Flags Affected:

None

None

Description:
WAIT causes the CPU to enter the wait state
while its TEST line is not active. WAIT does
not affect any flags.

Encoding:
10011011

WAIT Operands

(no operands)

Clocks

4+5n(6)

Transfers Bytes

3-165

1

WAIT Coding Example
WAIT

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

XCHG

EXCHANGE

Operation:

XCHG

Flags Affected:

(temp) +- (DEST)
(DEST) +- (SRC)
(SRC) +- (temp)

None

Description:
XCHG destination, source
XCHG (exchange) switches the contents of the
source and destination (byte or word)
operands. When used in conjunction with the
LOCK prefix, XCHG can test and set a semaphore that controls access to a resource shared
by multiple processors (see section 2.5).

3-166

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

EXCHANGE

XCHG

XCHG

Encoding:
Memory or Register Operand with Register Operand:
11 000011 w 1mod reg rIm 1
SRC = EA, DEST = REG

Register Operand with Accumulator:
1 1 001 0 reg 1
SRC

= REG, DEST = AX

XCHG Operands

accumulator,reg16
memory, register
register, register

Clocks

Transfers Bytes

3(3)

-

17(17)+EA
4(4)

2

-

3-167

1
2-4
2

XCHG Coding Example

XCHG AX, BX
XCHG SEMAPHORE, AX
XCHG AL, BL

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

XLAT

TRANSLATE

XLAT

Flags Affected:

Operation:
AL +- ((BX) + (AL))

None

Description:
XLAT translate-table
XLAT (translate) replaces a byte in the AL
register with a byte from a 256-byte, usercoded translation table. Register BX is
assumed to point to the beginning of the table.
The byte in AL is used as an index into the
table and is replaced by the byte at the offset in
the table corresponding to AL's binary value.

The first byte in the table has an offset of O.
For example, if AL contains 5H, and the sixth
element of the translation table contains 33H,
then AL will contain 33H following the
instruction. XLAT is useful for translating
characters from one code to another, the
classic example being ASCII to EBCDIC or
the reverse.

Encoding:
11010111

XLAT Operands
source-table

Clocks
11(11 )

Transfers Bytes
1

3-168

1

XLAT Coding Example

XLAT ASCII_TAB

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

XOR

EXCLUSIVE OR

Operation:

XOR

Flags Affected:

(DEST) +- (LSRC) XOR (RSRC)
(CF) +- 0
(OF) +- 0

CF, OF, PF, SF, ZF.
AF undefined

Description:
XOR destination, source
XOR (Exclusive Or) performs the logical
"exclusive or" of the two operands and
returns the result to the destination operand. A
bit in the result is set if the corresponding bits
of the original operands contain opposite
values (one is set, the other is cleared); otherwise the result bit is cleared.

3-169

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

XOR

XOR

EXCLUSIVE OR

Encoding:
Memory or Register Operand with Register Operand:
10011 00 d w 1mod reg rim

I

if d = 1 then LSRC = REG, RSRC = EA, DEST = REG
else LSRC = EA, RSRC = REG, DEST = EA

Immediate Operand to Memory or Register Operand:

I

11000000 w mod 110 rim
LSRC

= EA,

I

data if w=1

data

RSRC = data, DEST = EA

Immediate Operand to Accumulator:
10011 01 0 w 1

data

I data if w=1 I

if w = 0 then LSRC = AL, RSRC = data, DEST = AL
else LSRC = AX, RSRC = data, DEST = AX
XOR Operands

Clocks

register, register
register, memory
memory, register
accumulator,
immediate
register, immediate
memory, immediate

3(3)
9(10)+EA
16(10)+EA
4(3-4)
4(4)
17(16)+EA

Transfers Bytes

XOR Coding Example

-

2
2-4
2-4

XOR CX, BX
XOR Cl, MASK BYTE
XOR AlPHA[SIf,DX

-

2-3
3-4
3-6

XOR Al, 0100001 OB
XOR SI, 00C2H
XOR RETURN_CODE,OD2H

1
2

2

3-170

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

The examples are intended to show one way to use
the instruction set and addressing modes. They do
not demonstrate the "best" way to solve a particular
problem. The flexibility of the 8086 and 80186 application differences plus variations in programming
style usually add up to a number of ways to implement a programming solution.

3.8 8086,88 PROGRAMMING EXAMPLES
In this section and the section following, specific programming examples are provided which illustrate
how the instruction set and addressing modes may
be used in various, commonly encountered programming situations.
The programs are primarily written in ASM-86.
ASM-86 is the 8086/80186 assembly language. It
provides the programmer who is familiar with the
CPU architecture, access to all processor features.
For critical code segments within programs that
make sophisticated use of the· hardware, have extremely demanding performance or memory
constraints, ASM-86 is the best choice. For detailed
information about Intel's 8086/80186 assembly language see: ASM86 Language Reference Manual,
121703.
Programs can also be written in high-level languages
such as PLlM-86. PLlM-86 is a high-level language
suitable for most microprocessor applications. It is
easy to use, even by programmers who have little experience with microprocessors. Because it reduces
software development time, PLlM-86 is ideal for
most of the programming in any application, especially applications that must get to market quickly.
The languages are completely compatible, and ajudicious combination of the two often makes good
sense. Prototype software can be developed rapidly
with a high-level language. When the system is.
operating correctly, it can then be analyzed to see
which sections can best profit from being written in
ASM-86. Since the logic of these sections has already
been debugged, selective rewriting can be done
quickly and with low risk.

The programming examples in this section address
the following topics:
•

Procedures

•

JMP and CALL (jump, call)

•
•
•

Bit manipulation
Dynamic code relocation

•

Breakpoints

•

Interrupt handling

•

String operations

Memory mapped I/O

Procedures (parameters, reentrancy)
The code in Figure 3-31 illustrates several techniques
that are typically used in writing ASM-86 procedures. In this example a calling program invokes a
procedure (called EXAMPLE) twice, passing it a different byte array each time. Two parameters are
passed on the stack; the first contains the number of
elements in the array, and the second contains the
address (offset in D ATA2SEG) of the first array
element. This same technique can be used to pass a
variable-length parameter list to a procedure (the
"array" could be any series of parameters or parameter addresses). Thus, although the procedure always
receives two parameters, these can be used to indirectly access any number of variables in memory.
Any results returned by a procedure should be
placed in registers or in memory, but not on the
stack. AX or AL is often used to hold a single word
or byte result. Alternatively, the calling program can
pass the address (or addresses) of a result area to the
procedure as a parameter. It is good practice for
ASM-86 programs to follow the calling conventions
used by PLlM-86.
EXAMPLE is defined as a FAR procedure, meaning
it is in a different segment than the calling program.
The calling program must use an intersegment
CALL to activate the procedure. Note that this type
of CALL saves CS and IP on the stack. If EXAMPLE
were defined as NEAR (in the same segment as the
caller) then an intrasegment CALL would be used,
and only IP would be saved on the stack. It is the responsibility of the calling program to know how the
procedure is defined and to issue the correct type of
CALL.

Figure 3-32 shows the stack before the caller pushes
the parameters onto it. Figure 3-33 shows the stack
as the procedure receives it after the CALL has been
executed.
3-171

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

EXAMPLE is divided into four sections. The
"prolog" sets up register BP so it can be used to address data on the stack (specifying BP as a base register in an instruction automatically refers to the stack
segment unless a segment override prefix is coded).
The next step in the prolog is to save the "state of
the machine" as it existed when the procedure was
activated. This is done by pushing any registers used
by the procedure (only ex and BP in this case) onto

STACK~SEG

STACK~TOP

SEGMENT
DW

the stack. If the procedure changes the flags, and the
caller expects the flags to be unchanged following execution of the procedure, they also may be saved on
the stack. The last instruction in the prolog allocates
three words on the stack for the procedure to use as
local temporary storage'. Figure 3-34 shows the stack
at the end of the prolog. Note that PLIM procedures
assume that all registers except SP and BP can be
used without saving and restoring.

20 DUP (?)

; ALLOCATE 20-WORD ST ACK

WORD

; LABEL INITIAL TOS

STACK~SEG

LABEL
ENDS

DATA~SEG
ARRAY~1

SEGMENT
10 DUP (?)
DB

ARRAY~2

DB

DATA~SEG

ENDS

5 DUP (?)

; 10-ELEMENT BYTE ARRAY
; 5-ELEMENT BYTE ARRAY

PROC~SEG
SEGMENT
ASSU ME CS:PROC~SEG ,DS:DATA~SEG ,SS:STACK~SEG,ES:NOTHING

EXAMPLE

PROC

FAR

; MUST BE ACTIVATED BY
INTERSEGMENT CALL

; PROCEDURE PROLOG
PUSH
BP
; SAVE BP
MOV
BP, SP
; ESTABLISH BASE POINTER
PUSH
CX
; SAVE CALLER'S
PUSH
BX
REGISTERS
,
AND FLAGS
PUSHF
SP,6
SUB
; ALLOCATE3WORDS LOCAL STORAGE
; END OF PROLOG
; PROCEDURE BODY
CX, [BP + 8]
; GET ELEMENT COUNT
MOV
BX, [BP+6]
; GET OFFSET OF 1ST ELEMENT
MOV
; PROCEDURE CODE GOES HERE
; FIRST PARAMETER CAN BE ADDRESSED:
[BX]
; LOCAL STORAGE CAN BE ADDRESSED:
[BP-8], [BP-10], [BP-12]
; END OF PROCEDURE BODY

Figure 3-31 Procedure Example 1

3-172

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

; PROCEDURE EPILOG
ADD
SP,6
POPF
POP
BX
POP
CX
POP
BP
; END OF EPILOG
; PROCEDURE RETURN
RET
4
EXAMPLE

; DE-ALLOCATE LOCAL STORAGE
; RESTORE CALLER'S
REGISTERS
AND
FLAGS

; DISCARD 2 PARAMETERS
; END OF PROCEDURE "EXAMPLE"

ENDP

PROC_SEG
ENDS
CALLER_SEG
SEGMENT
; GIVE ASSEMBLER SEGMENT/REGISTER CORRESPONDENCE
ASSUME
CS:CALLER_SEG,
&
DS:DATA_SEG,
&
SS:STACK_SEG,
&
ES:NOTHING
; NO EXTRA SEGMENT IN THIS PROGRAM
; INITIALIZE SEGMENT REGISTERS
START:
MOV
AX,DATA_SEG
MOV
DS,AX
MOV
AX,ST ACK_SEG
MOV
SS,AX
MOV
SP,OFFSETSTACK_TOP ; POINTSPTOTOS
; ASSUME ARRAY_1IS INITIALIZED

,
; CALL "EXAMPLE", PASSING ARRAY_1, THAT IS, THE NUMBER OF ELEMENTS
IN THE ARRAY, AND THE LOCATION OFTHE FIRST ELEMENT.
MOV
AX,SIZE ARRAY _1
PUSH
AX
MOV
AX,OFFSET ARRAY_1
PUSH
AX
CALL
EXAMPLE
; ASSUME ARRAY_2IS INITIALIZED

,
; CALL "EXAMPLE" AGAIN WITH DIFFERENT SIZE ARRAY.
MOV
AX,SIZE ARRAY _2
PUSH
AX
MOV
AX,OFFSET ARRAY_2
PUSH
AX
CALL
EXAMPLE
ENDS
END

START

Figure 3-31 Procedure Example 1 (continued)
3-173

210911

THE iAPX86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

HIGH ADDRESSES

I---------i

_SP(TOS)
PARAMETER 1
PARAMETER 2
OLDCS
OLD IP

~SP(TOS)

LOW ADDRESSES

Figure 3-32 Stack Before Pushing Parameters

Figure 3-33 Stack at Procedure Entry

The procedure "body" does the actual processing
(none in the example). The parameters on the stack
are addressed relative to BP. Note that if EXAMPLE
were a NEAR procedure, CS would not be on the
stack and the parameters would be two bytes
"closer" to BP. BP also is used to address the local
variables on the stack. Local constants are best
stored in a data or extra segment.

HIGH ADDRESSES

BP+S .....

PARAMETER 1

BP+6 .....

PARAMETER 2
OLD CS
OLD IP
OLD BP

_BP

OLDCX
OLD BX

The procedure "epilog" reverses the activities of the
prolog, leaving the stack as it was when the procedure was entered (see Figure 3-35).

OLD FLAGS

The procedure "return" restores CS and IP from the
stack and discards the parameters. As Figure 3-36
shows, when the calling program is resumed, the
stack is in the same state as it was before any parameters were pushed onto it.

BP-S .....

LOCAL 1

BP-10 .....

LOCAL2

BP-12 .....

LOCAL3

_SP(TOS)

LOW ADDRESSES

Figure 3-34 Stack Following Procedure Prolog

3-174

210911

THE iAPX 86,88 AND iAPX 1 86,188 ARCHITECTURE AND INSTRUCTIONS

r

HIGHER ADDRESSES

HIGH ADDRESSES

1-----------1- SP (TOS)
PARAMETER 1
PARAMETER 2
RETURN ADDRESS
OLD BP

h

___ BP & SP (TOS)

h
LOWER ADDRESSES

Figure 3-35 Stack Following Procedure Epilog

Figure 3-37 shows a simple procedure that uses an
ASM -86 structure to address the stack. Register BP
points to the base of the structure, which is the top
of the stack since the stack grows toward lower addresses (see Figure 3-38). Any structure element
can then be addressed by specifying BP as a base
register:

LOW ADDRESSES

[BP].structure_element
Figure 3-39 shows a different approach to using as
ASM-86 structure to define the stack layout. As
shown in Figure 3-40, register BP is pointed at the
middle of the structure (at OLD...BP) rather than at
the base of the structure. Parameters and the return
address are thus located at positive displacements
(high addresses) from BP, while local variables are
at negative displacements (lower addresses) from
BP. This means that the local variables will be
"closer" to the beginning of the stack segment and
increase the likelihood that the assembler will be
able to produce shorter instructions to access these
variables, i.e., their offset from SS may be 255 bytes
or less and can be expressed as a I-byte value rather
than a 2-byte value. Exit from the subroutine also is
slightly faster because a MOV instruction can be
used to deallocate the local storage instead of an
ADD (compare Figure 3-31).
It is possible for a procedure to be activated a second

time before it has returned from its first activation.
For example, procedure A may caB procedure B,
and an interrupt may occur while procedure B is
executing. If the interrupt service procedure calls B,
then procedure B is reentered and must be written
to handle this situation correctly, i.e., the procedure
must be made reentrant.

Figure 3-36 Stack Following Procedure Return

In PLlM-86 this can be done by simply writing:
B:PROCEDURE(PARM 1, PARM2) REENTRANT;

An ASM-86 procedure will be reentrant if it uses the
stack for storing aBlocal variables. When the procedure is reentered, a new "generation" of variables
will be located on the stack. The stack will grow, but
the sets of variables (and the parameters and return
addresses as well) will automatically be kept straight.
The stack must be large enough to accommodate the
maximum "depth" of procedure activation that can
occur under actual running conditions. In addition,
any procedure called by a reentrant procedure must
itself be reentrant.
A related situation that also requires reentrant procedures is recursion:

3-175

• A calls A (direct recursion),
• A caBs B, B caBs A (indirect recursion),
• A caBs B, B calls C, C caBs A (indirect recursion).
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

CODE

SEGMENT
ASSUME CS:CODE
MAX
PROC
; THIS PROCEDURE IS CALLED BY THE FOLLOWING
SEQUENCE:
PUSH PARM1
PUSH PARM2
CALL MAX
,
; IT RETURNS THE MAXIMUM OF THE TWO WORD
PARAMETERS IN AX.

; DEFINE THE STACK LAYOUT
STACK_LAYOUTSTRUC
OLD_BP
DW?
RETURN_ADDR DW?
PARM_2
DW?
PARM_1
DW?
STACK_LAYOUT ENDS

AS A STRUCTURE.
; SAVED BP VALUE-BASE OF STRUCTURE
; RETURN ADDRESS
; SECOND PARAMETER
; FIRST PARAMETER

; PROLOG
PUSH
MOV

BP
BP,SP

; SAVE IN OLD_BP
; POINT TO OLD_BP

MOV
CMP
JG
MOV

AX, [BPJ.PARM_1
AX, [BPJ.PARM_2
FIRST _IS_MAX
AX, [BPJ.PARM_2

; IF FIRST
; >SECOND
; THEN RETURN FIRST
;ELSERETURNSECOND

BP

; RESTORE BP (& SP)

4

; DISCARD PARAMETERS

; BODY

; EPILOG
FIRST_IS_MAX: POP
; RETURN
RET
MAX
ENDP
CODE

ENDS
END
Figure 3-37 Procedure Example 2 The Stack as a Structure

HIGHER ADDRESSES

'r'

,
Jumps and Calls
The instruction set contains many different types of
JMP and CALL instructions (e.g., direct, indirect,
through register, indirect through memory, etc.).
These varying types of transfer provide efficient use
of space and execution time in different programming situations. Figure 3-41 illustrates typical use of
the different forms of these instructions. Note that
the ASM-86 assembler uses the terms "NEAR" and
"FAR" to denote intrasegment and inter segment
transfers, respectively.

PARAMETER 1
PARAMETER 2
RETURN ADDRESS
OLDBP

h
LOWER ADDRESSES

.......- BP & SP (TOS)

"

Figure 3-38 Procedure Example 2 Stack Layout
3-176

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

EXTRA
SEGMENT
; CONTAINS STRUCTURE TEMPLATE THAT "NEARPROC"
;
USES TO ADDRESS AN ARRAY PASSED BY ADDRESS.
DUMMY
STRUC
PARM_ARRAY
DB
256 DUP?
DUMMY
ENDS
EXTRA
ENDS
CODE

SEGMENT
ASSUME CS:CODE,ES:EXTRA
NEARPROC
PROC
; LAY OUT THE STACK (THE DYNAMIC STORAGE AREA OR DSA).
DSASTRUC
STRUC
; LOCAL VARIABLES FIRST
I
OW
?
10 DUP (?)
LOC_ARRA Y
OW
OLD_BP
OW
?
; ORIGINAL BP VALUE
?
; RETURN ADDRESS
RETADDR
OW
?
DO
; 2ND PARM-POINTER TO "PARM_ARRAY".
POINTER
?
; 1ST PARM-A BYTE OCCUPIES
COUNT
DB
?
A WORD ON THE STACK
DB
ENDS
DSASTRUC

; USE AN EQU TO DEFINE THE BASE ADDRESS OF THE
DSA. CANNOT SIMPLY USE BP BECAUSE IT WILL
BE POINTING TO "OLD_BP" IN THE MIDDLE OF
;
THE DSA.
DSA
EQU
[BP - OFFSET OLD_BP]
; PROCEDURE ENTRY
PUSH
MOV
SUB

BP
; SAVE BP
BP, SP
; POINT BP AT OLD __ BP
SP, OFFSET OLD_BP ; ALLOCATE LOC_ARRA Y & I

; PROCEDURE BODY
; ACCESS LOCAL VARIABLE I
MOV
AX,DSA.I
; ACCESS LOCAL ARRAY (3) I.E., 4TH ELEMENT
MOV
SI,6
; WORD ARRAY-INDEX IS 3*2
MOV
AX,DSA.LOC_ARRAY [SI]
; LOAD POINTER TO ARRAY PASSED BY ADDRESS
LES
BX,DSA.POINTER
; ES:BX NOW POINTS TO PARM __ ARRAY (0)
; ACCESS SI'TH ELEMENT OF PARM __ ARRAY
MOV
AL,ES:[BX].PARM_ARRAY [SI]
; ACCESSTHEBYTEPARAMETER
MOV
AL,DSA.COUNT

Figure 3-39 Procedure Example 3

3-177

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

; PROCEDURE EXIT
MOV
SP,BP
; DE-ALLOCATE LOCALS
BP
; RESTORE BP
POP
; STACK NOW AS RECEIVED FROM CA~LER
RET
6
; DISCARD PARAMETERS
ENDP
ENDS
END

NEARPROC
CODE

Figure 3-39 Procedure Example 3 (continued)

,

HIGHER ADDRESSES

I

•

aI)! indirect CALL through memory to a
procedure located in another segment,

•

a direct JMP to a label in another segment,

•

an indirect JMP through memory to a label in
the same segment,

•

an indirect JMP through a register to a label
in the same segment,

•

a direct CALL to a procedure in another
segment,

•

a direct CALL to a procedure in the same
segment,

•

direct JMPs to labels in the same segment,
within -128 to + 127 bytes ("SHORT") and
farther than -128 to + 127 bytes ("NEAR").

r

COUNT

-POINTER
RETADDR
OLD_BP

-BP

LOC_ARRAY (9)
LOC_ARRAY (8)
LOC_ARRAY

(n

LOC_ARRAY (8)
LaC_ARRAY (5)
LOC_ARRAY (4)
LOC_ARRAY (3)
LOC

ARRAY (2)

LOC_ARRAY(I)
LOC __ ARRAY (0)
I

"-

LOWER ADDRESSES

_SP

Bit Manipulation w/RECORD

"

Figure 3-42 shows the ASM-86 RECORD facility
may be used to manipulate bit data. The example
shows how to:

Figure 3-40 Procedure Example 3
Stack Layout

The procedure in Figure 3-41 illustrates how a
PLlM-86 DO CASE construction may be implemented in ASM-86. It also shows:
3-178

•

right-justify a bit field,

•

test for a value,

•

assign a constant known at assembly time,

•

assign a variable,

•

set or clear a bit field.
210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

DATA
SEGMENT
; DEFINE THE CASE TABLE (JUMP TABLE) USED BY PROCEDURE
"DO_CASE." THE OFFSET OF EACH LABEL WILL
;
BE PLACED IN THE TABLE BY THE ASSEMBLER.
CASE_TABLE
OW
ACTIONO, ACTION1, ACTION2,
&
ACTION3, ACTION4, ACTIONS
DATA
ENDS
; DEFINE TWO EXTERNAL (NOT PRESENT IN THIS
ASSEMBLY BUT SUPPLIED BY R & L FACILITY)
PROCEDURES. ONE IS IN THIS CODE SEGMENT
(NEAR) AND ONE IS IN ANOTHER SEGMENT (FAR).
NEAR_PROC: NEAR, FAR_PROC: FAR
EXTRN
; DEFINE AN EXTERNAL LABEL (JUMP TARGET) THAT
IS IN ANOTHER SEGMENT.
EXTRN
ERR_EXIT: FAR
CODE

SEGMENT
ASSUME
CS: CODE, OS: DATA
;ASSUMEDSHASBEENSETUP
BY CALLER TO POINT TO "DATA" SEGMENT.
DO_CASE
PROC
NEAR
; THIS EXAMPLE PROCEDURE RECEIVES TWO
PARAMETERS ON THE STACK. THE FIRST
PARAMETER IS THE "CASE N.UMBER" OF
A ROUTINE TO BE EXECUTED (0-5). THE SECOND
PARAMETER IS A POINTER TO AN ERROR
PROCEDURE THAT IS EXECUTED IF AN INVALID
CASE NUMBER (>5) IS RECEIVED.

; LAYOUTTHESTACK.
ST ACK_LA YOUT STRUC
OLD_BP
OW?
RETADDR
OW?
ERR_PROC_ADDR DO
CASE_NO
DB?
DB
?
STACK_LAYOUT ENDS

?

; SET UP PARAMETER ADDRESSING
BP
PUSH
MOV
BP, SP
; CODE TO SAVE CALLER'S REGISTERS COULD GO HERE.
; CHECK THE CASE NUMBER
MOV
MOV
CMP
JLE

BH,O
BL, [BPj.CASE_NO
BX, LENGTH CASE_TABLE
OK
; ALL CONDITIONAL JUMPS
; ARE SHORT DIRECT

Figure 3·41 JMP and Call Examples

3·179

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

; CALL THE ERR.OR ROUTINE WITH A FAR
INDIRECT CALL. A FAR INDIRECT CALL
IS INDICATED SINCE THE OPERAND HAS
TYPE "DOUBLEWORD."
CALL
[BP).ERR_PROC_ADDR
....

; JUMP DIRECTLY TO A LABEL IN ANOTHER SEGMENT.
AFAR DIRECT JUMP IS INDICATED SINCE
THE OPERAND HAS TYPE "FAR."
JMP
ERR_EXIT
OK:
; MULTIPLY CASE NUMBER BY 2 TO GET OFFSET
INTO CASE_TABLE (EACH ENTRY IS 2 BYTES).
SHL
BX,l
; NEAR INDIRECT JUMP THROUGH SELECTED
ELEMENT OF CASE_TABLE. A NEAR
INDIRECT JUMP IS INDICATED SINCE THE
OPE RAN D HAS TYPE "WORD."
JMP
CASE_TABLE [BX)
ACTIONO:
; EXECUTED IF CASE_NO = 0
\' ; CODE TO PROCESS THE ZERO CASE GOES HERE.
; FOR ILLUSTRATION PURPOSES, USE A
NEAR INDIRECT JUMP THROUGH A
REGISTER TO BRANCH TO THE POINT
WHERE ALL CASES CONVERGE.
A DIRECT JUMP (JMP ENDCASE) IS
ACTUALLY MORE APPROPRIATE HERE.
MOV
AX, OFFSET ENDCASE
JMP
AX
ACTION1:
; EXECUTED IF CASE_NO = 1
;CALLAFAREXTERNALPROCEDURE.AFAR
DIRECT CALL IS INDICATED SINCE OPERAND
HAS TYPE "FAR."
CALL
FAR_PROC
; CALL A NEAR EXTERNAL PROCEDURE.
CALL
NEAR_PROC
; BRANCH TO CONVERGENCE POINT USING NEAR
DIRECT JUMP. NOTE THAT "ENDCASE"
IS MORE THAN 127 BYTES AWAY
SO A NEAR DIRECT JUMP WILL BE USED.
JMP
ENDCASE
ACTION2:
; EXECUTED IF CASE_NO =< 2
; CODE GOES HERE
JMP
ENDCASE; NEAR DIRECT JUMP

Figure 3-41JMP and CALL Examples (continued)
3-180

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

ACTION3:
; EXECUTED IF CASE_NO = 3
; CODE GOES HERE
JMP
ENDCASE; NEAR DIRECT JMP
; ARTIFICIALLY FORCE "ENDCASE" FURTHER AWAY
SOTHAT ABOVE JUMPS CANNOT BE "SHORT."
ORG
500
ACTION4:
; EXECUTED IF CASE_NO = 4
; CODE GOES HERE
JMP
ENDCASE; NEAR DIRECT JUMP
ACTION5:
; EXECUTED IF CASE_NO = 5
; CODE GOES HERE.
; BRANCH TO CONVERGENCE POINT USING
SHORT DIRECT JUMP SINCE TARGET IS
WITHIN 127 BYTES. MACHINE INSTRUCTION
HAS 1-BYTE DISPLACEMENT RATHER THAN
2-BYTE DISPLACEMENT REQUIRED FOR
NEAR DIRECT JUMPS. "SHORT" IS
WRITTEN BECAUSE "ENDCASE" IS A FORWARD
REFERENCE, WHICH ASSEMBLER ASSUMES IS
"NEAR." IF "ENDCASE" APPEARED PRIOR
TO THE JUMP, THE ASSEMBLER WOULD
AUTOMATICALLY DETERMINE IF IT WERE REACHABLE
WITH A SHORT JUMP.
JMP
SHORTENDCASE
ENDCASE:

; ALL CASES CONVERGE HERE.

; POP CALLER'S REGISTERS HERE.
; RESTORE BP & SP, DISCARD PARAMETERS
AND RETURN TO CALLER.
MOV
SP, BP
POP
BP
RET
6
ENDP
ENDS
END

; OF ASSEMBLY

. Figured 3-41 JMP and CALL Examples (continued)

3-181

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

DATA
SEGMENT
; DEFINE A WORD ARRAY
XREF
DW 3000 DUP (?)
; EACH ELEMENT OF XREF CONSISTS OF 3.FIELDS:
A 2-BIT TYPE CODE,
A 1-BIT FLAG,
;
A 13-BIT NUMBER.
; DEFINE A RECORD TO LAY OUT THIS ORGANIZATION.
LINE REC
RECORD
LINE_TYPE: 2,
&
VISIBLE: 1,
&
LlNE_NUM: 13
DATA
ENDS
CODE

SEGMENT
ASSUME CS: CODE, DS: DATA
; ASSUME SEGMENT REGISTERS ARE SET UP PROPERLY
AND THAT SIINDEXES AN ELEMENT OF XREF.
; A RECORD FIELD-NAME USED BY ITSELF RETURNS
THE SHIFT COUNT REQUIRED TO RIGHT-JUSTIFY
; THE FIELD. ISOLATE "LINE_TYPE" IN THIS
; MANNER.
MOV
AL, XREF [SI)
CL, LINE_TYPE
MOV
SHR
AX, CL
; THE "MASK" OPERATOR APPLIED TO A RECORD
FIELD-NAME RETURNS THE BIT MASK
REQUIRED TO ISOLATE THE FIELD WITHIN
THE RECORD. CLEAR ALL BITS EXCEPT
"LlNE_NUM."
MOV
DX, XREF[SI)
AND
DX, MASK LlNE_NUM
; DETERMINE THE VALUE OF THE "VISIBLE" FIELD
TEST
XREF[SIJ, MASK VISIBLE
JZ
NOT_VISIBLE
; NO JUMP IF VISIBLE = 1
NOT_VISIBLE:
; JUMP HERE IF VISIBLE = 0
; ASSIGN A CONSTANT KNOWN AT ASSEMBLY-TIME
TO A FIELD, BY FIRST CLEARING THE BITS
AND THEN OR'ING IN THE VALUE. IN
THIS CASE "LINE_TYPE" IS SET TO 2 (10B).
AND
XREF[SIJ, NOT MASK LINE_TYPE
OR
XREF[SIJ,2 SHL LINE_TYPE
; THE ASSEMBLER DOES THE MASKING AND SHIFTING.
; THE RESULT IS THE SAME AS:
AND
XREF[SIJ, 3FFFH
OR
XREF[SIJ, 8000H
BUT IS MORE READABLE AND LESS SUBJECT
TO CLERICAL ERROR.
Figure 3-42 RECORD Example

3-182

210911

THE iAPX 86,88 AND iAPX 1 86,188 ARCHITECTURE AND INSTRUCTIONS

; ASSIGN A VARIABLE (THE CONTENT OF AX)
TO LINE_TYPE.
MOV
CL, LINE_TYPE ; SHIFTCOUNT
SHL
AX, CL ; SHIFTTO "LINE UP" BITS
AND
XREF[SI], NOT MASK LINE_TYPE ; CLEAR BITS
OR
XREF[SI], AX ; OR IN NEWVALUE
; NO SHIFT IS REQUIRED TO ASSIGN TO THE
RIGHT-MOST FIELD. ASSUMING AX CONTAINS
A VALID NUMBER (HIGH 3 BITS ARE 0),
ASSIGN AX TO "LlNE_NUM."
AND
XREF[SI], NOT MASK LlNE_NUM
OR
XREF[SI], AX
; A FIELD MAY BE SET OR CLEARED WITH
ONE INSTRUCTION. CLEAR THE "VISIBLE"
FLAG AND THEN SET IT.
AND
XREF[SI], NOT MASK VISIBLE
OR
XREF[SI], MASK VISIBLE
CODE

ENDS
END

; OF ASSEMBLY

Figure 3-42 RECORD Example (continued)

code also effectively makes the code offset-dependent, and therefore is not
recommended.

Position-I ndependent Code
The following considerations apply to positionindependent code sequences:
•

A label that is referenced by a direct FAR (intersegment) transfer is not moveable.

•

A label that is referenced by an indirect transfer (either NEAR or FAR) is moveable so
long as the register or memory pointer to the
label contains the label's current address.

•

•

A label that is referenced by a SHORT (e.g.,
conditional jump) or a direct NEAR (intrasegment) transfer is moveable so long as the
referencing instruction is moved with the
label as a unit. These transfers are selfrelative; that is, they require only that the
label maintain the same distance from the
referencing instruction, and actual addresses
are immaterial.
Data is segment-independent, but not offsetindependent. That is, a data item may be
moved to a different segment, but it must
maintain the same offset from the beginning
of the segment. Placing constants in a unit of

•

A procedure should not be moved while it is
active or while any procedure it has called is
active.

•

A section of code that has been interrupted
should not be moved.

The segment that is receiving a section of code must
have "room" for the code. If the MOVS (or
MOVSB or MOVSW) instruction attempts to autoincrement 01 past 64K, it wraps around to 0 and
causes the beginning of the segment to be
overwritten. If a segment override is needed for the
source operand, code similar to the following can be
used to properly resume the instruction if it is
interrupted:
RESUME: REP MOVS
DESTINATION.ES:SOURCE
;IF CX NOT~O THEN INTERRUPT HAS OCCURRED
AND CX,CX
;CX~O?
lNZ RESUME
;NO,FINISH EXECUTION
;CONTROL COMES HERE WHEN STRING HAS BEEN MOVED.

On the 8086,88, if the MOVS is interrupted, the
CPU "remembers" the segment override but

3-183

210911

THEiAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

"forgets" the presence of the REP prefix when execution resumes. Testing ex indicates whether the instruction is completed or not. Jumping back to the
instruction resumes it where it left off. Note that a
segment override cannot be specified with MOVSB
or MOVSW.

program (which is not moved) keeps a pointer variable that contains the current location (offset and segment base) of a position-independent procedure.
The supervisor always calls the procedure through
this pointer. The supervisor also has access to the
procedure's length in bytes. The procedure is moved
with the MOVSB instruction. After the procedure is
moved, its pointer is updated with the new location.
The ASM-86 WORD PTR operator is written to
inform the assembler that one word of the doubleword pointer is being updated at a time.

DynamiC Code Relocation
Figure 3-43 illustrates one approach to moving programs in memory at execution time. A "supervisor"

MAIN_DATA
SEGMENT
; SET UP POINTERS TO POSITION-INDEPENDENT PROCEDURE
AND FREE SPACE.
PIP_PTA
DD
EXAMPLE
FREE_PTA
DD
TARGET_SEG
; SET UP SIZE OF PROCEDURE IN BYTES
PIP_SIZE
DW
EXAMPLE_LEN
MAIN_DATA
ENDS
STACK

STACK_TOP
STACK

SEGMENT
DW
LABEL
ENDS

20 DUP(?)

; 20 WORDS FOR STACK

WORD

; TOS BEGINS HERE

SOURCE_SEG
SEGMENT
; THE POSITION-INDEPENDENT PROCEDURE IS INITIALLY IN THIS SEGMENT.
; OTHER CODE MAY PRECEDE IT, I.E., ITS OFFSET NEED NOT BE ZERO.
CS:SOURCE_SEG
ASSUME
EXAMPLE
PROC
FAR
; THIS PROCEDURE READS AN 8-BIT PORT UNTIL
; BIT 3 OF THE VALUE READ IS FOUND SET. IT
; THEN READS ANOTHER PORT. IF THE VALUE READ
; IS GREATER THAN 10H IT WRITES THE VALUE TO
; A THIRD PORT AND RETURNS; OTHERWISE IT STARTS
; OVER.
STATUS_PORT EQU
ODOH
PORT_READY
EQU
008H
INPUT_PORT
EQU
OD2H
010H
THRESHOLD
EQU
OUTPUT_PORT EQU
OD4H

Figure 3-43 Dynamic Code Relocation Example

3-184

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

CHECK_AGAIN: IN
TEST
JNE
IN
CMP
JLE
OUT

AL,STATUS_PORT
AL, PORT_READY
CHECK_AGAIN
AL,INPUT_PORT
AL,THRESHOLD
CHECK_AGAIN
OUTPUT_PORT,AL

RET
; GET PROCEDURE LENGTH
EXAMPLE_LEN EQU
ENDP
SOURCE_SEG
ENDS

; RETURN TO CALLER

; GET STATUS
; DATA READY?
; NO, TRY AGAIN
; YES, GET DATA
; > 10H?
; NO, TRY AGAIN
; YES, WRITE IT

(OFFSET THIS BYTE)-(OFFSET CHECK_AGAIN)
EXAMPLE ENDP

TARGET_SEG
SEGMENT
; THE POSITION-INDEPENDENT PROCEDURE
IS MOVED TO THIS SEGMENT, WHICH IS
;
INITIALLY "EMPTY."
; IN TYPICAL SYSTEMS, A "FREE SPACE MANAGER" WOU LD
; MAINTAIN A POOL OF AVAILABLE MEMORY SPACE
; FOR ILLUSTRATION PURPOSES, ALLOCATE ENOUGH
SPACE TO HOLD IT
DB
EXAMPLE_LEN DUP (?)
TARGET_SEG

ENDS

MAIN_CODE
SEGMENT
; THIS ROUTINE CALLS THE EXAMPLE PROCEDURE
; AT ITS INITIAL LOCATION, MOVES IT, AND
; CALLS IT AGAIN AT THE NEW LOCATION.
ASSUME
&

CS:MAIN_CODE,SS:STACK,
DS:MAIN_DATA,ES:NOTHING

; INITIALIZE SEGMENT REGISTERS & ST ACK POINTER.
START:
MOV
AX,MAIN_DATA
MOV
DS,AX
AX,STACK
MOV
MOV
SS,AX
MOV
SP ,OFFSET ST ACK __ TOP
; CALL EXAMPLE AT INITIAL LOCATION.
CALL
PIP PTR
; SET UP CX WITH COUNT OF BYTES TO MOV
MOV
CX,PIP _SIZE

Figure 3-43 Dynamic Code Relocation Example (continued)

3-185

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

; SAVE OS, SET UP DS/SI AND ES/DI TO
POINT TO THE SOURCE AND DESTINATION
ADDRESSES.
PUSH
OS
DI,FREE_PTR
LES
SI,PIP_PTR
LOS
; MOVETHEPROCEDURE.
CLD
REP MOVSB

; AUTO INCREMENT

; RESTORE OLD ADDRESSABILITY.
; HOLD TEMPORARILY
MOV
AX,DS
POP
OS
; UPDATE POINTER TO POSITION-INDEPENDENT PROCEDURE
MOV
WORD PTR PIP _PTR+2,ES
SUB
DI,PIP _SIZE
; PRODUCES OFFSET
MOV
WORD PTR PIP _PTR,DI
; UPDATE POINTER TO FREE SPACE
MOV
WORD PTR FREE_PTR+2,AX
SUB
SI,PIP _SIZE
; PRODUCES OFFSET
MOV
WORD PTR FREE_PTR,SI
; CALL POSITION-INDEPENDENT PROCEDURE AT
NEW LOCATION AND STOP
CALL
PIP _PT~
MAIN_CODE
ENDS
END
START

Figure 3-43 Dynamic Code Relocation Example (continued)

Memory Mapped 1/0

Breakpoints

Figure 3-44 shows how memory-mapped I/O can be
used to address a group of communication lines as
an "array." In the example, indexed addressing is
used to poll the array of status ports, one port at a
time. Any of the other memory addressing modes
may be used in conjunction with memory-mapped
I/O devices as well.

Figure 3-46 illustrates how a program may set a
breakpoint. In the example, the breakpoint routine
puts the processor into single-step mode, but the
same general approach could be used for other purposes as well. A program passes the address where
the break is to occur to a procedure that saves the
byte located at that address and replaces it with an
INT 3 (breakpoint) instruction. When the CPU encounters the breakpoint instruction, it calls the type
3 interrupt procedure. In the example, this procedure
places the processor into single-step mode starting
with the instruction where the breakpoint was
placed.

In Figure 3-45 a MOYS instruction is used to perform a high-speed transfer to a memory-mapped
line printer. Using this technique requires the hardware to be set up as follows. Since the MOYS instruction transfers characters to successive memory
addresses, the decoding logic must select the line
printer if any of these locations is written. One way
of accomplishing this is to have the chip select logic
decode only the upper 12 lines of the address bus
(AI9-A8), ignoring the contents of the lower eight
lines (A7-AO). When data is written to any address
in this 256-byte block, the upper 12 lines will not
change, so the printer will be selected.

Interrupt Handling
Figure 3-47 is a block diagram of a hypothetical
8086,88 system that is used to illustrate three different examples of interrupt handling: an external
(maskable) interrupt, an external non-maskable interrupt and a software interrupt.

3-186

210911

il

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

COM_LINES
SEGMENT AT 800H
; THE FOLLOWING IS A MEMORY MAPPED "ARRAY"
OF EIGHT 8-BIT COMMUNICATIONS CONTROLLERS
(E.G.,8251 USARTS). PORTS HAVE ALL-ODD
OR ALL-EVEN ADDRESSES (EVERY OTHER BYTE
IS SKIPPED) FOR 8086-COMPATIBILITY.
COM_DATA
COM

STATUS

COM_LINES

DB
DB
DB
DB
DB
ENDS

?
?
?
?
28

I
I~

; SKIP THIS ADDRESS
; SKIP THIS ADDRESS
; REST OF "ARRAY"

DUP (?)

CODE
SEGMENT
; ASSUME STACK IS SET UP, AS ARE SEGMENT
REGISTERS (DS POINTING TO COM_LINES).
FOLLOWING CODE POLLS THE LINES.
CHAR_RDY
ST ART __ POLL:

READ_CHAR:
; ETC.
CODE

EQU
MOV
SUB

00000010B
CX,8
SI, SI

TEST
JE
ADD
LOOP
JMP

COM_STATUS [SI), CHAR_RDY
READ_CHAR; READ IF PRESENT
SI,4
; ELSE BUMP TO NEXT LINE
POLL_NEXT; CONTINUE POLLING UNTIL
,
ALL 8 HAVE BEEN CHECKED
START_POLL; START OVER

MOV

AL,COM_DATA [SI]

; CHARACTER PRESENT
; POLL 8 LINES ZERO
; ARRAY INDEX

;GETTHE DATA

ENDS
END

Figure 3-44 Memory Mapped 1/0 "Array"

In this hypothetical system, an 8253 Programmable
Interval Timer is used to generate a time base. One
of the three timers on the 8253 is programmed to
repeatedly generate interrupt requests at 50 millisecond intervals. The output from this timer is tied to
one of the eight interrupt request lines of an 8259A
Programmable Interrupt Controller. The 8259A, in
turn, is connected to the INTR line of an 8086.

A power-down circuit is used in the system to illustrate one application of the NMI (non-maskable
interrupt) line. If the ac line voltage drops below a
certain threshold, the power supply activates ACLO.

The power-down circuit then sends a power-fail interrupt (PFI) pulse to the CPU's NMI input. After 5
milliseconds, the power-down circuit activates
MPRO (memory protect) to disable reading from
and writing to the system's battery-powered RAM.
This protects the RAM from fluctuations that may
occur when power is actually lost 7.5 milliseconds
after the power failure is detected. The system software must save all vital information in the batterypowered RAM segment within 5 milliseconds of the
activation ofNMI.
When power returns, the power-down circuit activates the system RESET line. Pressing the "cold
start" switch also produces a system RESET. The

3-187

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

PRINTER
SEGMENT
; THIS SEGMENT CONTAINS A "STRING" THAT
IS ACTUALLY A MEMORY-MAPPED LINE PRINTER.
THE SEGMENT (PRINTER) MUST BE ASSIGNED (LOCATED)
TO A BLOCK OF THE ADDRESS SPACE SUCH
THAT WRITING TO ANY ADDRESS IN THE
BLOCK SELECTS THE PRINTER.
PRINT

SELECT

PRINTER

DB 133
DB 123
ENDS

DATA
SEGMENT
PRINT_BUF
DB 133
PRINT_COUNT DB 1
; OTHER PROGRAM DATA
DATA
ENDS

DUP (?)
DUP(?)

; "STRING" REPRESENTING PRINTER
; REST OF 256-BYTE BLOCK

DUP(?)

; LINE TO BE PRINTED
; LINE LENGTH

?

CODE
SEGMENT
; ASSUME STACK AND SEGMENT REGISTERS HAVE
BEEN SET UP (OS POINTS TO DATA SEGMENT).
FOLLOWING CODE TRANSFERS A LINE TO
THE PRINTER.

REP

ASSUME
MOV
MOV
SUB
SUB
MOV
CLD
MOVS

ES: PRINTER
; PREVENT SEGMENT OVERRIDE
AX, PRINTER
ES,AX
; CLEAR SOURCE AND
01,01
DESTINATION POINTERS
SI,SI
CX, PRINT_COUNT
; AUTO-INCREMENT
PRINT_SELECT, PRINT _BU F

; ETC.
CODE

ENDS
END

Figure 3-45 Memory Mapped Block Transfer Example

PFS (power fail status) line, which is connected to
the low-order bit of port EO, identifies the source of
the RESET. If the bit is set, the software executes a
"warm start" to restore the information saved by
the power-fail routine. If the PFS bit is cleared, the
software executes a "cold start" from the beginning
of the program. In either case, the software writes a
"one" to the low-order bit of port E2. This line is
connected to the power-down circuit's PFSR (power
failure status reset) signal and is used to enable the
battery-powered RAM segment.
A software interrupt is used to update a simple realtime clock. This procedure is written in PLlM-86,
while the rest of the system is written in ASM-86 to

demonstrate the interrupt handling capability of
both languages. The system's main program simply
initializes the system following receipt of a RESET
and then waits for an interrupt. An example of this
interrupt procedure is given in Figure 3-48.
In the case of the 80186,188, the equivalent function
of the two blocks designated as the 8259A Interrupt
Controller and the 8253 Counter Timer chip are integrated on the chip. Thus, the example in Figure
3-48 remains essentially the same except for the initialization code (INIT) which will need to be
changed to reflect the presence of the integrated Interrupt Controller and Counter Timer.

3-188

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

INT_PTR_TAB SEGMENT
; INTERRUPT POINTER TABLE-LOCATE AT OH
TYPE_O
DD
?
TYPE_1
DD
SINGLE_STEP
TYPE_2
DD
?
TYPE_3
DD
BREAKPOINT
INT_PTR_TAB ENDS
SAVE_SEG
SAVE_INSTR

SEGMENT
DB 1

SAVE_SEG

ENDS

DUP (?)

; NOT DEFINED IN EXAMPLE
; NOT DEFINED IN EXAMPLE

; INSTRUCTION REPLACED
; BY BREAKPOINT

MAIN_CODE
. SEGMENT
; ASSUME STACK AND SEGMENT REGISTERS ARE SET UP.
; ENABLE SINGLE-STEPPING WITH INSTRUCTION AT
LABEL "NEXT" BY PASSING SEGMENT AND
OFFSET OF "NEXT" TO "SET_BREAK" PROCEDURE
PUSH
CS
LEA
AX,CS:NEXT
PUSH
AX
CALL
FAR SET_BREAK
; ETC.
NEXT:

IN
; ETC.

MAIN_CODE

ENDS

AL,OFFFH

; BREAKPOINT SET HERE

BREAK
SEGMENT
SET_BREAK
PROC
FAR
; THIS PROCEDURE SAVES AN INSTRUCTION BYTE (WHOSE
ADDRESS IS PASSED BY THE CALLER) AND WRITES
AN INT 3 (BREAKPOINT) MACHINE INSTRUCTION
AT THE TARGET ADDRESS.
TARGET

EQU

DWORD PTR [BP + 6]

; SET UP BP FOR PARM ADDRESSING & SAVE REGISTERS
PUSH
BP
MOV
BP, SP
PUSH
DS
PUSH
ES
PUSH
AX
PUSH
BX
; POINT DSI BX TO THE TARGET INSTRUCTION
BX,TARGET
LDS

Figure 3-46 Breakpoint Example
3-189

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECtURE AND INSTRUCTIONS

; POINT ES TO THE SAVE AREA
MOV
AX, SAVE_SEG
MOV
ES, AX
; SWAP THE TARGET INSTRUCTION FOR INT 3 (OCCH)
MOV
AL,OCCH
XCHG
AL, DS: [SXJ
; SAVE THE TARGET INSTRUCTION
MOV
ES: SAVE_INSTR, AL
; RESTORE AND RETURN
POP
SX
POP
AX
POP
ES
POP
DS
POP
BP
RET
4
SET_BREAK
EN DP
BREAKPOINT
PROC
FAR
; THE CPU WILL ACTIVATE THIS PROCEDURE WHEN IT
EXECUTES THE INT 3 INSTRUCTION SET BY THE
SET_BREAK PROCEDURE. THIS PROCEDURE
RESTORES THE SAVED INSTRUCTION BYTE TO ITS
ORIGINAL LOCATION AND BACKS UP THE
INSTRUCTION POINTER IMAGE ON THE STACK
SO THAT EXECUTION WILL RESUME WITH
THE RESTORED INSTRUCTION. IT THEN SETS
TF (tHE TRAP FLAG) IN THE FLAG-IMAGE
ON THE STACK. THIS PUTS THE PROCESSOR
IN SINGLE-STEP MODE WHEN EXECUTION
RESUMES.
FLAG_IMAGE
EQU
WORD PTR lBP+6J
IP _.. IMAGE
EQU
WORD PTR [BP + 2J
NEXT INSTR
EQU
DWORD PTR IBP+21
; SET UP BP TO ADDRESS STACK AND SAVE REGISTERS
PUSH
SP
MOV
BP, SP
DS
PUSH
PUSH
ES
PUSH
AX
PUSH
BX
; POINT ES AT THE SAVE AREA
MOV
AX, SAVE SEG
MOV
ES, AX
; GET THE SAVED BYTE
MOV
Al, ES: SAVE INSTR
; GET THE ADDRESS OF THE TARGET + 1
(INSTRUCTION FOLLOWING THE BREAKPOINT)
LDS
BX, NEXT_INSTR

Figure 3-46 Breakpoint Example (continued)

3-190

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

; BACK UP IP-IMAGE (IN BX) AND REPLACE ON STACK
DEC
BX
MOV
IP _IMAGE, BX

I

; RESTORE THE SAVED INSTRUCTION
MOV
DS: [BX], AL
; SET TF ON STACK
AND
FLAG_IMAGE,0100H
; RESTORE EVERYTHING AND EXIT
POP
BX
POP
AX
POP
ES
POP
DS
POP
BP
IRET
BREAKPOINT
ENDP

t.\
'!

SINGLE STEP
PROC
FAR
; ONCE SINGLE-STEP MODE HAS BEEN ENTERED,
THE CPU "TRAPS" TO THIS PROCEDURE
AFTER EVERY INSTRUCTION THAT IS NOT IN
AN INTERRUPT PROCEDURE. IN THE CASE
OF THIS EXAMPLE, THIS PROCEDURE WILL
BE EXECUTED IMMEDIATELY FOLLOWING THE
"IN AL, OFFFH" INSTRUCTION (WHERE THE
BREAKPOINT WAS SET) AND AFTER EVERY
SUBSEQUENT INSTRUCTION. THE PROCEDURE
COULD "TURN ITSELF OFF" BY CLEARING
TF ON THE STACK.
; SINGLE-STEP CODE GOES HERE.
; SINGLE_STEP ENDP
BREAK

ENDS
END

Figure 3-46 Breakpoint Example (continued)

String Operations
Figure 3-49 illustrates typical use of string instructions and repeat prefixes. The XLAT instruction
also is demonstrated. The first example simply
moves 80 words of a string, as might be done in a
sort. Next a string is scanned from right to left (the
index register is auto-decremented) to find the last
period (" .") in the string. Finally a byte string of
EBCDIC characters is translated to ASCII. The
translation is stopped at the end of the string or

when a carriage return character is encountered,
whichever occurs first. This is an example of using
the string primitives in combination with other instructions to build up more complex string processing operations.

3.9 80186,188 Programming Examples
Figures 3-50 through 3-53 provide code examples
for DMA, timer, interrupt controller and system
initialization.

3-191

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

~

COLD START-1

r

cl

+5V
BATTERY

O

I

Ar

~

1

J----

POWER DOWN
CIRCUITS
MPRO

RESET

BATTERY
POWERED
RAM

IE1
L
DECODER

PF1

t
(PULSE)

PFSR

PFS

t

1

NMI

EO

I~

CTR1
8253

8086/8085

8259A

I I I

I I I

I I I

I

I

ADORES S BUS

I

OAT A BUS
CONTRO L BUS

I

IR3

I

-

I

I

I

I

I

tII

CS

DECODER

EPROM

I

I

I

I
DECODER

-

CS

E2

PORTS

I I I

I

I

I

I

I

I

tII
RAM

I

I

I

I

5

I

I

Figure 3-47 Interrupt Example Block Diagram

INT~POINTERS
SEGMENT
; INTERRUPT POINTER TABLE, LOCATE ATOH, ROM-BASED
TYPE~O
DD
?
; DIVIDE-ERROR NOT SUPPLIED IN EXAMPLE.
TYPE~1
DD
?
; SINGLE-STEP NOT SUPPLIED IN EXAMPLE.
TYPE~2
DD
POWER~FAIL
; NON-MASKABLE INTERRUPT
TYPE~3
DD
; BREAKPOINT NOT SUPPLIED IN EXAMPLE.
TYPE~4
DD
; OVERFLOW NOT SUPPLIED IN EXAMPLE.
; SKIP RESERVED PART OF EXAMPLE
ORG
32'4
TYPE~32
DD
?
; 8259A IRO - AVAILABLE
TYPE~33
DD
?
; 8259A IR1 - AVAILABLE
TYPE~34
DD
?
; 8259A IR2 - AVAILABLE
TYPE._35
DD
TIMER __ PULSE
; 8259A IR3
TYPE~36
DD
?
; 8259A IR4 - AVAILABLE
TYPE~37
DD
?
; 8259A IR5 - AVAILABLE
TYPE~38
DD
?
; 8259A IR6 - AVAILABLE
TYPE~39
DD
?
; 8259A IR7 - AVAILABLE
; POINTER FOR TYPE 40 SUPPLIED BY PUM-86 COMPILER
INT ~POINTERS

ENDS

Figure 3-48 8086,88 Interrupt Procedures Example
3-192

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

BATTERY
SEGMENT
; THIS RAM SEGMENT IS BATTERY-POWERED. IT CONTAINS VITAL DATA
;
THAT MUST BE MAINTAINED DURING POWER OUTAGES.
STACK_PTR
DW?
; SP SAVE AREA
STACK_SEG
DW?
; SS SAVE AREA
; SPACE FOR OTHER VARIABLES COULD BE DEFINED HERE.
ENDS
BATTERY
DATA
SEGMENT
; RAM SEGMENT THAT IS NOT BACKED UP BY BATTERY
N_PULSES
DB
1 DUP (0)
; ETC.
DATA

; # TIMER PULSES

ENDS

STACK
SEGMENT
; LOCATED IN BATTERY-POWERED RAM
DW
100DUP(?)
STACK_TOP
STACK

LABEL

WORD
ENDS

; THIS IS AN ARBITRARY STACKSIZE
; LABEL THE INITIAL TOS

INTERRUPT_HANDLERS
SEGMENT
; INTERRUPT PROCEDURES EXCEPT TYPE 40 (PLfM-86)
ASSUME:

CS:INTERRUPT _HANDLERS,DS:DA T A,SS:ST ACK ,ES: BATTERY

POWER_FAIL
PROC
; TYPE 2 INTERRUPT
; POWER FAIL DETECT CIRCUIT ACTIVATES NMI LINE ON CPU IF POWER IS
ABOUT TO BE LOST. THIS PROCEDURE SAVES THE PROCESSOR STATE IN
RAM (ASSUMED TO BE POWERED BY AN AUXILIARY SOURCE) SOTHAT IT
CAN BE RESTORED BY A WARM START ROUTINE IF POWER RETURNS
; IP, CS, AND FLAGS ARE ALREADY
SAVE THE OTHER REGISTERS.
PUSH
PUSH
PUSH
PUSH
PUSH
PUSH
PUSH
PUSH
PUSH

ON THE STACK.
AX
BX
CX
DX
SI
DI
BP
DS
ES

; CRITICAL MEMORY VARIABLES COULD ALSO BE SAVED ON THE STACK.ATTHIS
POINT. ALTERNATIVELY, THEY COULD BE DEFINED IN THE "BATTERY"
SEGMENT, WHERE THEY WILL AUTOMATICALLY BE PROTECTED IF MAIN POWER
IS LOST.
; SAVE SP AND SS IN FIXED LOCATIONS THAT ARE KNOWN BY WARM START ROUTINE.
AX,BATTERY
MOV
MOV
ES,AX
ES:STACK_PTR,SP
MOV
MOV
ES:STACK_SEG,SS
; STOP GRACEFULLY
HLT
ENDP

Figure 3-48 8086,88 Interrupt Procedures Example (continued)

3-193

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

TIMER_PULSE
PROC
; TYPE 35 INTERRUPT
; THIS PROCEDURE HANDLES THE 50MS INTERRUPTS GENERATED BY THE 8253.
IT COUNTS THE INTERRUPTS AND ACTIVATES THE TYPE 40 INTERRUPT
PROCEDURE ONCE PER SECOND.
; DS IS ASSUMED TO BE POINTING TO THE DATA SEGMENT

,
; THE 8253 IS RUNNING FREE, AND AUTOMATICALLY LOWERS ITS INTERRUPT
REQUEST. IF A DEVICE REQUIRED ACKNOWLEDGEMENT, THE CODE MIGHT GO HERE.
; NOW PERFORM PROCESSING THAT MUST NOT BE INTERRUPTED (EXCEPT FOR NMI).
N_PULSES
INC
; ENABLE HIGHER-PRIORITY INTERRUPTS AND DO LESS CRITICAL PROCESSING
STI
N_PULSES,200; 1 SECOND PASSED?
CMP
JBE
DONE
; NO, GO ON.
MOV
N_PULSES,O
; YES, RESET COUNT.
INT
40
; UPDATE CLOCK
; SEND NON-SPECIFIC END-OF-INTERRUPT COMMAND TO 8259A, ENABLING EQUAL
;
OR LOWER PRIORITY INTERRUPTS.
; EOI COMMAND
DONE:
MOV
AL,020H
OUT
OCOH,AL
; 8259A PORT
IRET
TIMER_PULSE
ENDP
INTERRUPT_HANDLERS

ENDS

CODE
SEGMENT
; THIS SEGMENT WOULD NORMALLY RESIDE IN ROM.
ASSUME

CS:CODE,DS:DATA,SS:STACK,ES:NOTHING

INIT
PROC
NEAR
; THIS PROCEDURE IS CALLED FOR BOTH WARM AND COLD STARTS TO INITIALIZE
THE 8253 AND THE 8259A. THIS ROUTIN E DOES NOT USE STACK, DATA, OR
EXTRA SEGMENTS, AS THEY ARE NOT SET PREDICTABLY DURING A WARM START.
INTERRUPTS ARE DISABLED BY VIRTUE OF THE SYSTEM RESET.
; INITIALIZE 8253 COUNTER 1 - OTHER COUNTERS NOT USED.
; CLK INPUT TO COUNTER IS ASSUMED TO BE 1.23 MHZ.
L050MS
HI50MS
CONTROL
COUNT_1
MODE2

EQU
EQU
EQU
EQU
EQU

OOOH
OFOH
OD6H
OD2H
01110100B

; COUNT VALUE IS
;
61440 DECIMAL.
; CONTROL PORT ADDRESS
; COUNTER 1 ADDRESS
; MODE 2, BINARY

; LOAD CONTROL BYTE
MOV
DX,CONTROL
MOV
AL,MODE2
OUT
DX,AL
MOV
DX,COUNT_1
; LOAD 50MS DOWNCOUNT
MOV
AL,L050MS
OUT
DX,AL
MOV
AL,HI50MS
DX,AL
OUT
; COUNTER NOW RUNNING, INTERRUPTS STILL DISABLED.

Figure 3-48 8086,88 Interrupt Procedures Example (continued)

3.194

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

INITIALIZE 8259A TO: SINGLE INTERRUPT CONTROLLER, EDGE-TRIGGERED,
INTERRUPT TYPES 32-40 (DECIMAL) TO BE SENT TO CPU FOR INTERRUPT
REQUESTS 0-7 RESPECTIVELY, 8086 MODE, NON-AUTOMATIC END-OF-INTERRUPT.
MASK OFF UNUSED INTERRUPT REQUEST LINES.
ICWl
ICW2
ICW4
OCWl
PORT_A
PORT_B

EQU
EQU
EQU
EQU
EQU
EQU

; EDGE-TRIGGERED, SINGLE 8259A, ICW4 REQUIRED
; TYPE 20H, 32 - 40D
; 8086 MODE, NORMAL EOI
; MASK ALL BUT IR3
; ICWl WRITTEN HERE
; OTHER ICW'S WRITTEN HERE

00010011 B
00100000B
00000001 B
11110111B
OCOH
OC2H

MOV
DX,PORT_A
; WRITE 1ST ICW
MOV
AL,ICWl
OUT
DX,AL
MOV
DX,PORT _B
; WRITE 2ND ICW
MOV
AL,ICW2
OUT
DX,AL
MOV
AL,ICW4
; WRITE 4TH ICW
OUT
DX,AL
MOV
AL,OCWl
; MASK UNUSED IR'S
DX,AL
OUT
; INITIALIZATION COMPLETE, INTERRUPTS STILL DISABLED
RET
INIT
ENDP
USER_PGM:
; "REAL" CODE WOULD GO HERE. THE EXAMPLE EXECUTES AN ENDLESS LOOP
UNTIL AN INTERRUPT OCCURS.
JMP
USER_PGM
; EXECUTION STARTS HERE WHEN CPU IS RESET.
POWER_FAlL_STATUS
EQU
OEOH
ENABLE_RAM
EQU
OE2H

; PORT ADDRESS
; PORT ADDRESS

; ENABLE BATTERY-POWERED RAM SEGMENT
AL,OOl H
START:
MOV
OUT
ENABLE_RAM,AL
; DETERMINE WARM OR COLD START
IN
AL,POWER_FAIL~STATUS
RCR
AL,l
; ISOLATE LOW BIT
JC
WARM START
COLD __ START:
; INITIALIZE SEGMENT REGISTERS AND STACK POINTER.
ASSUME CS:CODE,DS:DATA,SS:STACK,ES:NOTHING
; RESET TAKES CARE OF CS AND IP.
MOV
AX,DATA
MOV
DS,AX
MOV
AX,STACK
MOV
SS,AX
MOV
SP,OFFSET STACK_TOP
; INITIALIZE 8253 AND 8259A.
CALL

INIT

; ENABLE INTERRUPTS
STI

Figure 3-488086,88 Interrupt Procedures Example (continued)

3-195

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

; START MAIN PROCESSING
JMP
WARM_START:
; INITIALIZE 8253 AND 8259A.
CALL

INIT

; RESTORE SYSTEM TO STATE ATTHE TIME POWER FAILED
; MAKE BATTERY SEGMENT ADDRESSABLE
MOV
AX, BATTERY
MOV
DX,AX
; VARIABLES SAVED IN THE "BATTERY" SEGMENT WOULD BE MOVED
BACK TO UNPROTECTED RAM NOW. SEGMENT REGISTERS AND
"ASSUME" DIRECTIVES WOULD HAVE TO BE WRITTEN TO GAIN
ADDRESSABILITY.
; RESTORE THE OLD STACK
SS,DS:STACK_SEG
MOV
MOV
SP,DS:STACK_PTR

CODE

; RESTORE THE OTHER REGISTERS
ES
POP
POP
DS
POP
BP
POP
DI
POP
SI
POP
DX
POP
CX
POP
BX
POP
AX
; RESUME THE ROUTINE THAT WAS EXECUTING WHEN NMI WAS ACTIVATED.
I.E., POP CS, IP, & FLAGS, EFFECTIVELY "RETURNING" FROM THE
NMI PROCEDURE.
IRET
ENDS
; TERMINATE ASSEMBLY AND MARK BEGINNING OFTHE PROGRAM.
END
START
TYPE$40: DO;
DECLARE (HOUR, MIN, SEC) BYTE PUBLIC;
UPDATE$TOD: PROCEDURE INTERRUPT 40;
"THE PROCESSOR ACTIVATES THIS PROCEDURE
'TO HANDLE THE SOFTWARE INTERRUPT
'GENERATED EVERY SECOND BY THE TYPE 35
'EXTERNAL INTERRUPT PROCEDURE. THIS
'PROCEDURE UPDATES A REAL-TIME CLOCK.
'IT DOES NOT PRETEND TO BE "REALISTIC"
'AS THERE IS NO WAY TO SET THE CLOCK."
SEC= SEC + 1;
IF SEC = 60 THEN DO;
SEC =0;
MIN=MIN+1;
IF MIN = 60 THEN DO;
MIN =0;
HOUR = HOUR + 1;
IF HOUR = 24 THEN DO;
HOUR = 0;
END;
END;
END;
END UPDATE$TOD;
END;

Figure 3-48 8086,88 Interrupt Procedures Example (continued)
3-196

210911

I

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

ALPHA
SEGMENT
; THIS IS THE DATA THE STRING INSTRUCTIONS WILL USE
OUTPUT
DW 100
DUP (?)
INPUT
DW 100
DUP (?)
NAME_1
DB 'JONES, JONA'
NAME_2
DB 'JONES, JOHN'
SENTENCE
DB 80
DUP (?)
EBCDIC_CHARS DB 80
DUP (?)
ASCII_CHARS
DB 80
DUP (?)
CONV_TAB
DB64
DUP(OH)
;EBCDICTOASCII
; ASCII NULLS ARE SUBSTITUTED FOR "UNPRINTABLE" CHARS
DB 1
20H
DB 9
DUP (OH)
PB?
'¢',',','<','(','+',OH,'&'
DB 9
DUP (OH)
DBB
'!','$','*',')',';',' ','-','/'
DB 8
DUP (OH)
DB6
't ',', '%', '_', '>', '?'
DB 9
DUP (OH)
0817
' ',':', '#', '@','II', '=','" 't
OH, 'a', 'bt, Ie', 'd', Ie', If', 'g', 'h', Ii'
DUP (OH)
DB7
Ij', 'k't 'I', 'm', In', '0', 'p', 'q', 'r'
DB9
DUP (OH)
DB7
'~', '5', It', "u', 'v', 'w', 'x', 'y', 'z'
DB9
DUP (OH)
DB 22
DB 10
, 't 'A', 'B', 'C', '0', 'E', 'F', 'G', 'H', 'I'
DB6
DUP (OH)
DB 10
, ','J', 'K't 'L', 'M', 'N', '0', 'P', 'Q', 'R'
DB6
DUP (OH)
, ',OH, IS', 'T', lU', 'V', 'W', 'X', IV', 'Z'
DB10
DUP (OH)
DB6
DB 10
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
DB6
DUP (OH)
I

ALPHA

ENDS

STACK

SEGMENT
DW 100

; THIS IS AN ARBITRARY STACK SIZE
; FOR ILLUSTRATION ONLY.
; INITIAL TOS

DUP (?)

STACK_BASE
STACK

LABEL
ENDS

WORD

CODE
BEGIN:

SEGMENT
; SET UP SEGMENT REGISTERS. NOTICE THAT
; ES & DS POINT TO THE SAME SEGMENT, MEANING
; THAT THE CURRENT EXTRA & DATA
; SEGMENTS FULLY OVERLAP. THIS ALLOWS
; ANY STRING IN "ALPHA" TO BE USED
; AS A SOURCE OR A DESTINATION.

Figure 3-49 String Examples

3-197

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

ASSUME CS: CODE, SS: STACK,
OS: ALPHA, ES:ALPHA
MOV
AX, STACK
MOV
SS, AX
MOV
SP, OFFSET STACK_BASE; INITIAL TOS
AX, ALPHA
MOV
OS, AX
MOV
MOV
ES, AX
; MOVE THE FIRST 80 WORDS OF "INPUT" TO
THE LAST 80 WORDS OF "OUTPUT".
LEA
SI, INPUT
; INITIALIZE
LEA
01, OUTPUT + 20
; INDEX REGISTERS
MOV
CX,80
; REPETITION COUN I
CLD
; AUTO-INCREMENT
OUTPUT, INPUT
REP
MOVS
&

; FIND THE ALPHABETICALLY
MOV
MOV
MOV
CLD
REPE CMPS
JB
NAME 1 LOW:
NAME_2_LOW:

LOWER OF 2 NAMES.
SI, OFFSET NAME_1 ; ALTERNATIVE
01, OFFSET NAME __ 2 ; TO LEA
CX, SIZE NAME_2
; CHAR. COUNT
; AUTO-INCREMENT
NAME_2, NAME_1
"WHILE EQUAL"
NAME_2_LOW
; NOT IN THIS EXAMPLE
; CONTROL COMES HERE IN THIS EXAMPLE.
; 01 POINTS TO BYTE ('H') THAT
; COMPARED UNEQUAL.

; FIND THE LAST PERIOD (' .') IN A TEXT STRING.
01, OFFSET SENTENCE +
MOV
&
LENGTH SENTENCE ; START AT END
MOV
CX, SIZE SENTENCE
STD
; AUTO-DECREMENT
MOV
AL, '.'
; SEARCH ARGUMENT
REPNE
SCAS
SENTENCE
; "WHILE NOT ="
JCXZ
NO_PERIOD
; IFCX=O, NO PERIOD FOUND
; IF CONTROL COMES HERE THEN
PERIOD:
; 01 POINTS TO LAST PERIOD IN SENTENCE.
NO_PERIOD:
; ETC.
; TRANSLATE A STRING OF EBCDIC CHARACTERS
TO ASCII, STOPPING IF A CARRIAGE RETURN
(ODH ASCII) IS ENCOUNTERED.
MOV
BX, OFFSET CONV __ TAB ; POINT TO TRANSLATE TABLE
MOV
SI, OFFSET EBCDIC_CHARS ; INITIALIZE
MOV
01, OFFSET ASCILCHARS
INDEX REGISTERS
CX, SIZE ASCILCHARS
;
AND COUNTER
MOV
CLD
; AUTO-INCREMENT
NEXT:
LODS
EBCDIC_CHARS
; NEXT EBCDIC CHAR IN AL
XLAT
CONV_ TAB
; TRANSLATE TO ASCII
ASCII_CHARS
; STORE FROM AL
STOS
TEST
AL,ODH
; IS ITCARRIAGE RETURN?
LOOPNE
NEXT
; NO, CONTINUE WHILE CX NOT 0
Figure 3-49 String Exarnples (continued)

3-198

210911

I

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

JE
CR_FOUND
; YES, JUMP
; CONTROL COMES HERE IF ALL CHARACTERS
HAVE BEEN TRANSLATED BUT NO
,
CARRIAGE RETURN IS PRESENT.
; ETC.

; DI-1 POINTS TO THE CARRIAGE RETURN
IN ASCII_CHARS.
CODE

ENDS
END

Figure 3-49 String Examples (continued)

$mod186
name

assembly_example_80186_DMA_support

This file contains an example procedure which initializes the 80186 DMA controller to perform the DMA
transfers between the 80186 system and the 8272 Floppy Disk Controller (FDC). It assumes that
the 80186 peripheral control block has not been moved from its reset location.
;

argl
arg2
arg3
DMA FROM LOWER
DMA-FROM-UPPER
DMA -TO LO-WER
DMA- TO-UPPER
DMA-COUNT
DMA-CONTROL
DMA=TO _DISK_CONTROL

equ
equ
equ
equ
equ
equ
equ
equ
equ
equ

word ptr [BP
word ptr [BP
word ptr [BP
OFFCOh
OFFC2h
OFFC4h
OFFC6h
OFFC8h
OFFCAh
01486h

+ 4]
+ 6]
+ 8]

OA046h

FDC DMA
FDC-DATA
FDC=STATUS

equ
equ
equ

cgroup
code

group code
segment
public set_dma_
assume cs:cgroup

6B8h
688h
680h

DMA register locations

;
;
;
;
;
;
;
;

destination synchronization
source to memory, incremented
destination to I/O
no terminal count
byte transfers
source synchronization
source to I/O
destination to memory, incr
no terminal count
byte transfers
FDC DMA address
FDC data register
FDC status register

public 'code'

Figure 3-50 80186 DMA Initialization Example

3-199

210911

THE iAPX B6,BBANO iAPX 186,1BB,ARCHITECTURE AND INSTRUCTIONS

set_dma (offset, to) programs the DMA channel to pOint one side to the disk DMA address, and the other
to memory pOinted to by ds:offset. If 'to' = 0 then will be a transfer from disk to memory; if 'to' = 1
then will be a transfer from memory to disk. The parameters to the routine are passed on the stack.
proc
enter

near
0,0

push
push
push

AX
BX
DX

save registers used

test

arg2,1

check to see direction of
transfer

jz

from_disk

set stack addressability

performing a transfer from memory to the disk controller
mov
rol

AX,DS
AX,4

mov
mov
out
and

BX,AX
DX,DMA JROM _UPPER
DX,AX
AX,OFFFOh

add
mov
out
jnc
inc
mov
mov
out

AX,argl
DX,DMAJROM_LOWER
DX,AX
no_carry_from
BX
AX,BX
DX,DMAJROM_UPPER
DX,AX

mcv
mov
out
xor
mov
out
mov
mov
out
pop
pop
pop
leave
ret

AX,FDC DMA
; prgm the lower 16 bits of the DMA
DX,DMA- TO LOWER
; destination register
DX,AX ; zero the upper 4 bits of the DMA
AX,AX
DX,DMA TO UPPER
destination register
DX,AX prgm the DMA ctl reg
AX,DMA TO DISK CONTROL
DX,DMA=CONTROL.
note: DMA may begin immediately
DX,AX
after this word is output
DX
BX
AX

; get the segment value
; gen the upper 4 bits of the
physical address in the lower 4
bits of the register
save the result ...
prgm the upper.4 bits of the
DMA source register
; form the lower 1 6 bits of the
; physical address
; add the offset
prgm the lower 16 bits of the
DMA source register
check for carry out of addition
if carry out, then need to adj
the upper 4 bits of the pOinter

performing a transfer from the disk to memory
mov
rol
mov
out
mov
and
add
mov

AX,DS
AX,4
DX,DMA TO UPPER
DX,AX BX,AX
AX,OFFFOh
AX,argl
DX,DMA_TO_LOWER

Figure 3-50 80186 DMA Initialization Example (continued)

3-200

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

out
jnc
inc
mov
mov
out

DX,AX
no_carrLto
BX
AX,BX
DX,DMA TO UPPER
DX,AX -

mov
mov
out
xor
mov
out
mov
mov
out
pop
pop
pop
leave
ret
endp

AX,FDC DMA
DX,DMA- FROM LOWER
DX,AX AX,AX
DX,DMAfROM_UPPER
DX,AX
AX,DMA FROM DISK CONTROL
DX,DMA=CONTROL DX,AX
DX
BX
AX

ends
end

code

Figure 3-50 80186 DMA Initialization Example (continued)

$modl86
name
This file contains example 80186 timer routines. The first routine sets up the timer and interrupt
controller to cause the timer to generate an interrupt every 10 milliseconds, and to service the
interrupt to implement a real time clock. Timer 2 is used in this example because no input or
output signals are required. The code example assumes that the peripheral control block has not
been moved from its reset location (FFOO-FFFF in 1/0 space).

+ 4]
+ 6]
+ 8]

argl
arg2
arg3
timer2_int
ti mer 2_control
timer 2_max_ctl
timeUnt_ctl
eoi_register
interrupt_stat

equ
equ
equ
equ
equ
equ
equ
equ
equ

data

segment
public hour ,minute ,second ,msec
db
? -

msec_
hour_
minute_
second
data cgroup
dgroup

db
db
db
ends
group
group

word ptr [BP
word ptr [BP
word ptr [BP
19
OFF66h
OFF62h
OFF32h
OFF22h
OFF30h

timer 2 has vector type 19

interrupt controller regs

public 'data'

?
?

?
code
data

Figure 3-51 80186 Timer Interface Code Example
3-201

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

segment
public seUime_
assume cs:code,ds:dgroup

code

public 'code'

seUime (hour, minute, second) sets the time variables, initializes the 80186 timer2" to provide interrupts
every 10 milliseconds, and programs the interrupt vector for timer2
proc

seUime-

push
push
push
push

near
0,0
AX
OX
SI
OS

xor

AX,AX

mov
mov
mov
inc
inc
mov
pop
mov
mov
mov
mov
mov
mov
mov

OS,AX
SI,4 • timer2 int
OS: [Sll,offset timer2_interruptJoutine
SI
SI
OS:[SI1,CS
OS
set the time values
AX,argl
hour_,AL
AX,arg2
minute_,AL
AX,arg3
second_,AL
msec_,O

mov
mov

OX,timer2_max cll
AX,20000

out
mov
mov

OX,AX
OX,timer2_control
AX,1110000000000001b

out

OX,AX

mov

OX,timer_int_ctl

set up the interrupt

mov

AX,OOOOb

unmask interrupts
highest priority interrupt

out
sti

OX,AX

pop
pop
pop
leave
ret
endp

SI
OX
AX

~,enter

set stack addressability
save registers used

set the i nterru pt vector
the timers have unique
interrupt
vectors even though they share
the same control register

set the max count value
10 ms / 500 ns (timer 2 counts
at '/4 the CPU clock rate)
set the control word
enable counting
generate interrupts on TC
continuous counting

controller

set_timelimer2_interruptJoutine

push
push

enable processor interrupts

far

proc
AX
OX

Figure 3-51 Timer Interface Code Example (continued)
3-202

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

timer2 interrupt routine
code -

cmp
jae
inc
jmp

msec_,99
bump_second
msec
reseUnt_ctl

see if one second has passed
if above or equal. ..

mov
cmp
jae
inc
jmp

msec_,O
second ,59
bump_minute
second
reseUnt_ctl

reset millisecond
see if one minute has passed

mov
cmp

second_,O
minute_,59

proc
push
push

near
AX
OX

mov
mov
out
mov
mov

OX,timer1 max_cnt
AX,13
OX,AX
OX,timer1_control
AX,1100000000000001b

jae
inc
jmp

bump_hour
minute
reseUnt_ctl

mov
cmp
jae
inc
jmp

minute_,O
hour_,12
reset_hour
hour
reseUnt_ctl

mov

hour_,1

mov
mov
out

OX,eoi register
AX,8000h
OX,AX

pop
pop
iret

OX
AX

see if one hour has passed
single max count register
save registers used

set the max count value
500ns • 13 = 6.5 usec
set the control word
enable counting
no interrupt on TC
continuous counting

see if 12 hours have passed

non-specific end of interrupt

endp
ends
end

$mod186
name
This file contains example 80186 timer routines. The second routine sets up the timer as a baud rate
generator. In this mode, Timer 1 is used to continually output pulses with a period of 6.5 usec for
use with a serial controller at 9600 baud programmed in divide by 16 mode (the actual period
required for 9600 baud is 6.51 usec). This assumes that the 80186 is running at 8MHz. The code
example also assumes that the peripheral control block has not been moved from its reset location
(FFOO-FFFF in 1/0 space).
timer1_control
timer1_max_cnt

equ
equ

code

segment
assume cs:code

OFF5Eh
OFF5Ah
public 'code'

Figure 3-51 80186 Timer Interface Code Example (continued)
3-203

210911

..

~

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

set_baud () initializes the 80186 timer1 as a baud rate generator for a serial port running at 9600 baud.
out

OX,AX

pop
pop
ret
endp
ends
end

OX
AX

$mod186
name
This file contains example 80186 timer routines. The third routine sets up the timer as an external event
counter. In this mode, Timer1 is used to count transitions on its input pin. After the timer has been
set up by the routine, the number of events counted can be directly read from the timer count
register at location FF58H in 1/0 space. The timer will count a maximum of 65535 timer events
before wrapping around to zero. This code example also assumes that the peripheral control block
has not been moved from its reset location (FFOO-FFFF in 1/0 space).
timer1_control
timer1_max_cnt
timer1_cntJeg

equ
equ
equ

OFF5Eh
OFF5Ah
OFF58H

code

segment
assume cs:code

public 'code'

set_count () initializes the 80186 timer1 as an event counter
set_count-

proc
push
push

near
AX
OX

mov
mov

OX,timer1 max_cnt
AX,O

out
mov
mov

OX,AX
OX,timer1_control
AX, 1100000000000101 b

out

OX,AX

xor
mov

AX,AX
OX,timer1_cnt_reg

zero AX
and zero the count in the

out

OX,AX

count register

pop
pop
ret

OX
AX

save registers used

set the max count value
allows the ti mer to cou nt
all the way to FFFFH
set the control word
enable counting
no interrupt on Te
continuous counting
single max count register
external clocking

timer

endp
ends
end

Figure 3-51 Timer Interface Code Example (continued)

3-204

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

$mod186
name
This routine configures the 80186 interrupt controller to provide two cascaded interrupt inputs (through an
external 8259A interrupt controller on pins INTO/INT2) and two direct interrupt inputs (on pins INT1
and INT3). The default priority levels are used. 8ecause of this, the priority level programmed into the
control register is set the 111, the level all interrupts are programmed to at reset.
intO_control
int_mask

equ
equ

code

segment
assume CS:code
near
proc
push
OX
AX
push

seUnt_
code

OFF38H
OFF28H
public 'code'

mov

AX,01 001118

mov
out

OX,intO_control
OX,AX

mov

AX,01 0011 01 8

mov
out
pop
pop
ret
endp
ends
end

OX,int mask
OX,AXAX
OX

cascade mode
interrupt unmasked

now unmask the other external
interrupts

$mod186
name
This routine configures the 80186 interrupt controller into iRMX 86 mode. This code does not initialize
any of the 80186 integrated peripheral control registers, nor does it initialize the external 8259A
or 80130 interrupt controller.
relocation_reg

equ

code

segment
assumeCS:code
proc
near
push
OX
AX
push

set rmx
code -

OFFFEH
public 'code'

mov
in
or

OX,relocation reg
AX,OX
AX,01000000000000008

pop
pop
ret
endp
ends
end

AX
OX

read old contents of register
set the RMX mode bit

Figure 3-52 80186 Interrupt Controller Interface Code Example
3-205

210911

THE iAPX 86,88 AND iAPX 186,188 ARCHITECTURE AND INSTRUCTIONS

name
This file contains a system initialization routine for the 8086 or the 80186. The code determines whether
it is running on an 80186 or an 8086, and if it is running on an 80186, it initializes the integrated
chip select registers.
restart

segment

atOFFFFh

This is the processor reset address at OFFFFOH

restart

org
jmp
ends

0
far ptr initialize

extrn
monitor:far
segment
assume CS:init_hw

atOFFFOh

This segment initializes the chip selects. It must be located in the top 1 K to insure that the ROM remains
selected in the 80186 system until the proper size of the select area can be programmed.
UMCSJeg
LMCSJeg
PACS_reg
MPCSJeg
UMCS_value
LMCS value
PACS -value
MPCS_value

equ
equ
equ
equ
equ
equ
equ
equ

OFFAOH
OFFA2H
OFFA4H
OFFA8H
OF800H
07F8H
72H
OBAH

; chip select register locations

initialize

proc
mov
mov
shr
test
jz

far
AX,2
CL,33
AX,CL
AX,1
not_80186

mov
moY
out

OX,UMCSJell
AX,UMCS_value
OX,AX

; program the UMCS register

mov
mov
out
mov

OX,LMCSJeg
AX,LMCS_value
OX,AX
OX,PACSJeg

program the LMCS register

mov
out

AX,PACS_value
OX,AX

mov
mov
out

OX,MPCSJeg
AX,MPCS_value
OX,AX

64K, no wait states
32K, no wait states
peripheral base at 400H, 2 ws
PCS5 and 6 supplies,
peripherals in 1/0 space
determine if this is an
8086 or an 80186 (checks
to see if the multiple bit
shift value was ANOed)

set up the peripheral chip
selects (note the mid-range
memory chip selects are not
needed in this system, and
; are thus not initialized

Now that the chip selects are all set up, the main program of the computer may be executed.

initialize
init_hw

jmp
endp
ends
end

far ptr monitor

Figure 3-53 80186/8086 SystemlnitializationCode Example

3-206

210911

iAPX 86,88 Hardware
Design Overview

4

THE iAPX 86,88 HARDWARE DESIGN OVERVIEW

CHAPTER 4
iAPX 86,88 HARDWARE DESIGN OVERVIEW
Multiprocessing has become increasingly attractive
as microprocessor prices have declined. Performance
can be substantially improved by distributing system
tasks among separate, concurrently executing
processors. In addition, multiprocessing encourages
a modular approach to design, usually resulting in
systems that are more easily maintained and
enhanced.

4.1 INTRODUCTION
This chapter is a discussion of the hardware design
of the iAPX 86,88 (8086, 8088) on the functional
level. Electrical characteristics and other hardware
references are discussed in Volume 2 of this set. Application Notes AP-67, "8086 System Design," and
AP-51, "Designing 8086, 8088, 8089 Multiprocessing Systems with the 8289 Bus Arbiter," also in
Volume 2, contain additional design information.

The example in Figure 4-1 shows a multiprocessor
system in which I/O activities have been delegated
to an 8089 lOP. (The 8089 lOP is described in Chapter 7 of this volume.) Should an I/O device in the
system be changed (e.g., a hard disk substituted for
a floppy), the impact of the modification is confined
to the I/O subsystem and is transparent to the CPU
and to the application software.

This chapter includes the following topics:
•

Multiprocessing Features

•

Bus Organization

•

Processor Control

•

Interfacing with Processor Extensions

In general, using multiple processors offers several
significant advantages over the centralized approach
that relies on a single CPU and extremely fast
memory:

4.2 MULTIPROCESSING FEATURES
The 8086 and 8088 are designed for the multiprocessing environment. Multiprocessing means using
two or more coordinated processors in a system.
These CPUs have built-in features that help solve
the coordination problems that have made the development of multiprocessing systems difficult in the
past.

1-- - I

2) Very high levels of performance can be attained
when processors can execute simultaneously
(parallel/ distributed processing);

-1- - - - A::6~:1~Ot:
~~W:-;

DATA,

,

I

1) System tasks may be allocated to special-purpose
processors whose designs are optimized to perform
specific (or classes of) tasks simply and efficiently;

8C~p:U8~
,',8086

SYSTEM BUS

I .~g8:~

,

,

I,

,

~A~SYSTE~

__

-

~
,

I/O BUFFERS

I

... ,... 17g~t~

'
I

... ~.,

:

l

.J

I/O
DEVICES

~

-

I/O PROGRAMS

l ''8 1

,
L __

~OM~Y-

___

~O SUBSYSTEM

l

I/O ,
DEVICES

I

___

I!
..J

Figure 4-1 Multiprocessing System

4-1

210911

THE iAPX 86,88 HARDWARE DESIGN OVERVIEW

LOCAL OR RESIDENT BUS

3) Partitioning of the system promotes parallel development of subsystems, breaks the application
into smaller, more manageable tasks, and helps isolate the effects of system modifications.

The local bus is optimized for use by the 8086,88
CPUs. Since standard memory and 110 components
are not attached to the local bus, information can be
multiplexed and encoded to make efficient use of
processor pins. This allows several pins to be dedicated to coordinating the activity of multiple processors
sharing the local bus. Both independent processors
and processor extensions may share a local bus; onchip arbitration logic determines which processor
drives the. bus. Because the processors on the local
bus share the same bus· interface components, the
local configuration of multiple processors provides a
compact and inexpensive multiprocessing system.

The 8086,88 architecture supports two types of
processors: independent processors and processor
extensions. An independent processor executes its
own instruction stream. The 8086, the 8088 and the
8089 lOP are examples of independent processors.
The 8086,88 typically execute a program in response
to an interrupt. The lOP starts its channels in response to an interrupt-like signal called a channel
attention; this signal is usually issued by a CPU.
The CPUs also support a second type of processor,
called a processor extension, such as the 8087 NPX.
(The 8087 NPX is described in Chapter 6 of this
volume.) Processor extension "hooks" have been
designed into the 8086,88 to allow this type of
processor to be accommodated. The processor
extension adds additional register, data type, and instruction resources directly to the system. A processor extension, in effect, extends the instruction set
(and architecture) of its host processor.

SYSTEM BUS

A system bus carries several signals designed to
meet the needs of memory and 110 devices:

This solves two classic multiprocessing coordination
problems: bus arbitration and mutual exclusion. Bus
arbitration may be performed by the bus
request/grant logic contained in each of the processors (local bus arbitration), by 8289 bus arbiters
(system bus arbitration), or by a combination of the
two when processors have access to multiple shared
buses. In all cases, the arbitration mechanism operates invisibly to software.

•

Address bus

•

Data bus

•

Control lines

•

Interrupt lines

•

Arbitration lines

The system bus design is modular and subsets may
be implemented according to the needs of the
application. For example, the arbitration lines are
not needed in single-processor systems or in
multiple-processor systems that perform arbitration
at the local-bus level.

For mutual exclusion, each processor has a LOCK
signal (bus lock) which a program may activate to
prevent other processors from obtaining a shared
system bus. The lOP may lock the bus during a
DMA transfer to ensure both that the transfer completes in the shortest possible time and that another
processor does not access the target of the transfer
(e.g., a buffer) while it is being updated. Each of the
processors has an instruction that examines and updates a memory byte with the bus locked. This instruction can be used to implement a semaphore
mechanism for controlling the access of multiple processors to shared reso urces.

A group of bus interface components transforms the
signals of a local bus into a system bus. The number
of bus interface components required to generate a
system bus depends on the size and complexity of
the system. Three main variables determine the configuration of a bus interface group: address space
size, data bus width and arbitration needs.
The 8086,88 system bus can easily be made compatible with the Multibus™ system. Multibus is a
general-purpose multiprocessing bus designed by
Intel. The Multibus has been proposed for adoption
by IEEE as the IEEE 796 standard bus. It is the standard design used in Intel's iSBCTM single-board microcomputer products. This compatibility gives
system designers access to a wide variety of
computer, memory, communication and other
modules that may be incorporated into products.
Many other manufacturers offer products that are
compatible with the Multibus architecture as well.
The Multibusis described in more detail later in this
chapter.

Bus Organization
The 8086,88 bus structure can be divided into a local
or Resident Bus, and a system bus. The major distinction between the two is that the local or Resident
Bus has one master, while the system bus can have
several masters (multi-master system bUs). The
8289 bus arbiter (described later in this chapter), interfaces the processors to the Resident Bus and the
multi-master system bus.
4-2

210911

THE iAPX 86,88 HARDWARE DESIGN OVERVIEW

Bus Lock

LOCK is active. If the system uses 8289 Bus Arbiters
to control access to the shared bus, the 8289s accept
LOCK as an input and do not relinquish the bus
while this signal is active.

When configured in maximum mode, the 8086 and
8088 provide the LOCK (bus lock) signal. The BIU
activates LOCK when the EU executes the one-byte
LOCK prefix instruction. The LOCK signal remains
active throughout execution of the instruction that
follows the LOCK prefix. Interrupts are not affected
by the LOCK prefix. If another processor requests
use of the bus (via the request/grant lines, which are
discussed later in this chapter), the CPU records the
request, but does not honor it until execution of the
locked instruction has been completed.

LOCK may be used in multiprocessing systems to
coordinate access to a common resource, such as a
buffer or a pointer. If access to the resources is not
controlled, one processor can read an erroneous
value from the resource when another processor is
updating it (see Figure 4-2).

8US CYCLE

Note that the LOCK signal remains active for the duration of a single instruction. If two consecutive instructions are each preceded by a LOCK prefix,
there will still be an unlocked period between these
instructions. In the case of a locked repeated string
instruction, LOCK does remain active for the duration of the block operation.

IC2, 5914C,

0

0

IC2159131 , 051

Access can be controlled (see Figure 4-3) by using
the LOCK prefix in conjunction with the XCHG
(exchange register with memory) instruction. The
basis for controlling access to a given resource is a
semaphore, a software-settable flag or switch that indicates whether the resource is "available"
(semaphore=O) or "busy" (semaphore = 0. Procesors that share the bus agree by convention not to

SHARED POINTER
IN MEMORY

1

I

I
I
I

I
I

05 12214C 11 B

C2 I

9

591 4C 11 B

IC2 1 59
IC2 159

0

"A" COMPLETES UPDATE

Figure 4-2 Uncontrolled Access
to Shared Resource

C2 I 5914C 11 B

0

"A" UPDATES 1 WORD

I

05 I 2214C I 1B

4

181

C2, 5914C ,18 1 "8" READS PARTIALLY
•
•
_ UPDATED VALUE
_ .

The LOCK signal provides information only. It is
the responsibility of the other processors on the
shared bus not to attempt to obtain the bus while

SEMAPHORE

PROCESSOR ACTIVITIES

I05 I 2214C I 18 1

When the 8086 or 8088 is configured in minimum
mode, the LOCK signal is not available. The LOCK
prefix can be used, however, to delay the generation
of an HOLDA response to a HOLD request until execution of the locked instruction is completed.

8US CYCLE

SHARED POINTER
IN MEMORY

I

PROCESSOR ACTIVITIES

"A" 08TAINS EXCLUSIVE
USE
"A" UPDATES 1 WORD
"B" TESTS SEMAPHORE
AND WAITS

31 105

"A" COMPLETES UPDATE

31 105

"B" TESTS SEMAPHORE
AND WAITS

31 105

"A" RELEASES RESOURCE

IC2 I 59

31 105

"8" OBTAINS
EXCLUSIVE USE

I

C2 1 59

31 105

"B" READS
UPDATED VALUE

IC2 , 59

31 105

"B" RELEASES RESOURCE

C2 1 59

Figure 4-3 Controlled Access to Shared Resource

4-3

210911

'jl
"

'.

THE iAPX 86,88 HARDWARE DESIGN OVERVIEW

use the resource unless the semaphore indicates that
it is available. They likewise agree to set the semaphore when they are using the resource and to clear
it when they are finished.

WAIT and TEST
The 8086 and 8088 (in either maximum or minimum
mode) can be synchronized to an external event
with the WAIT (wait for TEST) instruction and the
TEST input signal. When the EU executes a WAIT
instruction, the result depends on the state of the
TEST input line. If TEST is inactive, the processor
enters an idle state and repeatedly retests the TEST
line at five-clock intervals. If TEST is active, execution continues with the instruction following the
WAIT.

The XCHG instruction can obtain the current value
of the semaphore and set it to "busy" in a single
instruction. The instruction, however, requires two
bus cycles to swap 8-bit values. It is possible for
another processor to obtain the bus between these
two cycles and to gain access to the partially-updated
semaphore. This can be prevented by preceding the
XCHG instruction with a LOCK prefix, as illustrated
in Figure 4-4. The bus lock establishes control over
access to the semaphore and thus to the shared
resource.

Escape
The ESC (escape) instruction provides a way for
another processor to obtain an instruction and/or a
memory operand from an 8086,88 program. When
used in conjunction with WAIT and TEST, ESC can
initiate a "subroutine" that executes concurrently in
another processor (see Figure 4-5). An example of
the use of the WAIT, TEST and ESC instructions is
the application of an 8087 NPX processor extension.

MOV
GET SEMA·
PHORE &
SET "BUSY"

AL,1

Six bits in the ESC instruction may be specified by
the programmer when the instruction is written. By
monitoring the bus and control lines, another processor (e.g., an 8087 NPX) can capture the ESC instruction when it is fetched by the BIU. The six bits
may then direct the external processor to perform
some predefined activity.

WAIT: LOCK XCHG AL,
SEMAPHORE

BUSY(1)

If an 8086 or 8088 is configured in maximum mode,
the external processor, having determined that an
ESC has been fetched, can monitor QSO and QSl
(the queue status lines) and determine when the
ESC instruction is executed. If the instruction references memory the external processor can then monitor the bus and capture the operand's physical
address and/or operand itself.

AL,AL
WAIT

MOV

EXIT

Note that fetching an ESC instruction is not tantamount to executing it. The ESC may be preceded by
a jump that causes the queue to be reinitialized. This
event also can be determined from the queue status
lines.

SEMAPHORE,O

)

Request/Grant Lines
When the 8086 or 8088 is configured in maximum
mode, the HOLD and HLDA lines evolve into two
more sophisticated signals called RQV)GTO and
RQ(f)GTl. These are bidirectional lines that can be
used to share a local bus between an 8086 or 8088
and two other processors via a handshake sequence.

Figure 4·4 Using XCHG and LOCK
4-4

210911

THE iAPX 86,88 HARDWARE DESIGN OVERVIEW

honored until the processor on RQ(!)GTI releases
the bus.

The request/grant sequence is a three-phase cycle:
request, grant and release. First, the processor desiring the bus pulses a request/grant line. The CPU returns a pulse on the same line indicating that it is
entering the "hold acknowledge" state and is relinquishing the bus. The BIU is logically disconnected
from the bus during this period. The EU, however,
will continue to execute instructions until an instruction requires bus access or the queue is emptied,
whichever occurs first. When the other processor
has finished with the bus, it sends a final pulse to the
8086,88 indicating that the request has ended and
that the CPU may reclaim the bus.

Multibus Architecture
When the 8086 or 8088 is configured in maximum
mode, the 8288 Bus Controller outputs signals that
are electrically compatible with the Multibus
protocol. Designers of multiprocessing systems may
want to consider using the Multibus architecture in
the design of their products to reduce development
cost and time, and to obtain compatibility with the
wide variety of boards available in the iSBC product
line.

RQ(!)GTO has higher priority than RQ(!)GTI. If requests arrive simultaneously on both lines, the grant
goes to the processor on RQ(!)GTO and RQ(!)GTl
is acknowledged after the bus has been returned to
the CPU. If, however, a request arrives on
RQ(!)GTO while the CPU is processing a prior request on RQU)GTl, the second request is not

Multibus architecture provides a versatile communications channel that can be used to coordinate a
wide variety of computing modules (see Figure 4-6).
Modules in a Multibus system are designated as masters or slaves. Masters may obtain use of the bus and
initiate data transfers on it. Slaves are the objects of
data transfers only.

PROCESSOR

"6"

PROCESSOR

"A"

Figure 4-5 Using ESC with WAIT and TEST

MASTER
WITH
BUS·ACCESSIBlE
MEMORy

MASTER

I

A

w

'~"
0

i:i

,..

"'"'"

MEMORY SLAVE

][ iit][
*
o



r>
t-

TYPE 33 POINTER:
(AVAILABLE)

-

~

TYPE 32 POINTER:
(AVAILABLE)

-

~

TYPE 31 POINTER:
(RESERVED)

-

084H

080H
07FH

RESERVED
INTERRUPT
POINTERS
(27)

"

I

Ir'

\r'
~

TYPE 5 POINTER:
(RESERVED)

~

TYPE 4 POINTER:
OVERFLOW

014H

010H

DEDICATED
INTERRUPT
POINTERS
(5)

OOCH

-

TYPE 3 POINTER:
r;.BYTE INT INSTRUCTION
~

TYPE 2 POINTER:
NON·MASKABLE

t-

TYPE 1 POINTER:
SINGLE·STEP

~

TYPE 0 POINTER:
DIVIDE ERROR

008H

004H

OOOH

-

CS BASE ADDRESS
~----.--IP OFFSET

1·..

--168ITs---.1

Figure 4-9 Interrupt Pointer Table

4-10

210911

THE iAPX 86,88 HARDWARE DESIGN OVERVIEW

~

~
DIVIDE
INSTRUCTION

.

INTR

DIVIDE ERROR RECOGNIZED

l
PUSH FLAGS
PUSH CS & lP
CLEAR IF & TF

EXECUTE NEXT
INSTRUCTION

l

SINGLE STEP RECOGNIZED

~

~

PUSH FLAGS
PUSH CS & IP
CLEAR IF & TF

DIVIDE ERROR
PROCEDURE

I

J
SINGLE STEP
PROCEDURE·

POP CS & IP
POP FLAGS

TF:=1.IF:=1

I

I

POP CS & IP
POP FLAGS

INTR RECOGNIZED

t

TF:::Q,IF=O

J

PUSH FLAGS
PUSH CS & IP
CLEAR IF & TF
EXECUTE NEXT
INSTRUCTION

I

,
I
I
I
I
I
I
I
I
I

SINGLE STEP RECOGNIZED

t
t

PUSH FLAGS
PUSH CS & IP
CLEAR IF & TF

INTR

PROCEDURE

I

I
SINGLE STEP
PROCEDURE"

PQPCS&IP
POP FLAGS

TF=1,IF=1

I

• TF CAN BE SET IN THE

I
POP CS & IP
POP FLAGS

~NGLESTEPPROCEDURE

IF SINGLE STEPPING OF
THE DIVIDE ERROR OR INTR

PROCEDURE IS DESIRED.

TF=O,IF=O

J

Figure 4-10 Processing Simultaneous Interrupts

4-11

210911

THE iAPX 86,88 HARDWARE DESIGN OVERVIEW

Since the interrupt pointer table is at a fixed storage
location, procedures may "call" each other through
the table by issuing software interrupt instructions.
This provides a stable communication "exchange"
that is independent of procedure addresses. The interrupt procedures may themselves be moved so
long as the interrupt pointer table always is updated
to provide the linkage from the "caIling" program
via the interrupt type code.

Interrupt Procedures
When an interrupt service procedure is entered, the
flags, CS and IP are pushed onto the stack and TF
and IF cleared. The procedure may reenable external
interrupts with the STI (set interrupt-enable flag)
instruction, thus allowing itself to be interrupted by
a request on INTR. (Note, however, that interrupts
are not actually enabled until the instruction/aI/owing
STI has executed.) An interrupt procedure may
always be interrupted by a request arriving on NMI.
Software- or procedure-initiated interrupts occurring
within the procedure also will interrupt the
procedure. Care must be taken in interrupt procedures that the type of interrupt being serviced by the
procedure does not itself inadvertently occur within
the procedure. For example, an attempt to divide by
o in the divide error (type 0) interrupt procedure
may result in the procedure being reentered
endlessly. Enough stack space must be available to
accommodate the maximum depth of interrupt nesting that can occur in the system.

Single-Step (Trap) Interrupt
When TF (the trap flag) is set, the 8086,88 are said
to be in single-step mode. In this mode, the processor automatically generates a type I interrupt after
most instructions. Interrupts will not be generated
after prefix instructions (e.g., REP), instructions
which modify segment registers (e.g., POP OS), or
the WAIT instructions.
Recall that as part of its interrupt processing, the
CPU automatically pushes the flags onto the stack
and then clears TF and IF. Thus the processor is not
in single-step mode when the single-step interrupt
procedure is entered; it runs normally. When the
single-step procedure terminates, the old flag image
is restored from the stack, placing the CPU back into
single-step mode.

Like all procedures, interrupt procedures should
save any registers they use before updating them,
and restore them before terminating. It is good practice for an interrupt procedure to enable external interrupts for all but "critical sections" of code (those
sections that cannot be interrupted without risking
.erroneous results). If external interrupts are disabled
for too long in a procedure, interrupt requests on
INTR can potentially be lost.
All interrupt procedures should be terminated with
an IRET (interrupt return) instruction. The IRET instruction assumes that the stack is in the same condition as it was when the procedure was entered. It
pops the top three stack words into IP, CS and the
flags, thus returning to the instruction that was
about to be executed when the interrupt procedure
was activated. The actual processing done by the
procedure is dependent upon the application. If the
procedure is servicing an external device, it should
output a command to the device instructing it to
remove its interrupt request. It might then read
status information from the device, determine the
cause of the interrupt and then take action
accordingly. See Chapter 3, Section 3.8 for examples
of interrupt procedures.
Software-initiated interrupt procedures may be used
as service routines ("supervisor calls") for other
programs in the system. In this case. the interrupt
procedure is activated when a program, rather than
an external device, needs attention. (The "attention" might be to search a file for a record, send a
message to another program, request an allocation
of free memory, etc.) Software interrupt procedures
can be advantageous in systems that dynamically
relocate programs during execution.
4-12

Single-stepping is a valuable debugging tool. It
allows the single-step procedure to act as a
"window" into the system through which operation
can be observed instruction-by-instruction. A singlestep interrupt procedure, for example, can print or
display register contents, the value of the instruction
pointer (it is on the stack), key memory variables,
etc., as they change after each instruction. In this
way the exact flow of a program can be traced in
detail, and the point at which discrepancies occur can
be determined. Other possible services that could be
provided by a single-step routine include:
•

Writing a message when a specified memory
location or 110 port changes value (or equals
a specified value).

•

Providing diagnostics selectively (only for certain instruction addresses for instance).

•

Letting a routine execute a number of times
before providing diagnostics.

The 8086,88 CPUs do not have instructions for setting or clearing the TF directly. Rather, TF can be
changed by modifying the flag-image on the stack.
(TF can be set by ORing the flag-image with OlOOH
and cleared by ANDing it with FEFFH). After TF is
set in this manner, the first single-step interrupt
occurs after the first instruction following the IRET
from the single-step procedure.
210911

THE iAPX 86,88 HARDWARE DESIGN OVERVIEW

If the processor is single-stepping, it processes an interrupt (either internal or external) as follows. Control is passed normally (flags, CS an IP are pushed)
to the procedure designated to handle the type of interrupt that has occurred. However, before the first
instruction of that procedure is executed, the singlestep interrupt is "recognized" and control is passed
normally (flags, CS and IP are pushed) to the type 1
interrupt procedure. When single-step procedure
terminates, control returns to the previous interrupt
procedure. Figure 4-10 illustrates this process in a
case where two interrupts occur when the processor
is in single-step mode.

RESET, it terminates all activities until the signal
goes low, at which time it initializes the system as
shown in Table 4-2.

Table 4-2 CPU State Following RESET

Breakpoint Interrupt
A type 3 interrupt is dedicated to the breakpoint
interrupt. A breakpoint is generally any place in a
program where normal execution is arrested so that
some sort of special processing may be performed.
Breakpoints typically are inserted into programs
during debugging as a way of displaying registers,
memory locations, etc., at crucial points in the
program.
The INT 3 (breakpoint) instruction is one byte long.
This makes it easy to "plant" a breakpoint anywhere
in a program. Chapter 3, Section 3.8, contains an
example that shows how a breakpoint may be set,
and how a breakpoint procedure may be used to
place the processor into single-step mode.
The breakpoint instruction also may be used to
"patch" a program (insert new instructions) without
recompiling or reassembling it. This may be done by
saving an instruction byte, and replacing it with an
INT 3 (CCH) machine instruction. The breakpoint
procedure would contain the new machine
instructions, plus code to restore the saved instruction byte and decrement IP on the stack before
returning, so that the displaced instruction would be
executed after the patch instructions. The breakpoint
example in Chapter 3, Section 3.8 illustrates these
principles.
Note that patching a program requires machineinstruction programming and should be undertaken
with considerable caution; it is easy to add new bugs
to a program in an attempt to correct existing ones.
Note also that a patch is only a temporary measure
to be used in exceptional conditions. The affected
code should be updated and retranslated as soon as
possible.

System Reset
The 8086,88 RESET lines provide an orderly way to
start or restart an executing system. When the processor detects the positive-going edge of a pulse on
4-13

CPU COMPONENT

CONTENT

Flags
Instruction Pointer
CS Register
OS Register
SS Register
ES Register
Queue

Clear
OOOOH
FFFFH
OOOOH
OOOOH
OOOOH
Empty

Since the code segment register contains FFFFH
and the instruction pointer contains OH, the processor executes its first instruction following system
reset from absolute memory location FFFFOH. This
location normally contains an intersegment direct
JMP instruction from information in the program
that identifies its first instruction. As external
(maskable) interrupts are disabled by system reset,
the system software should reenable interrupts as
soon as the system is initialized to the point where
they can be processed.

Instruction Queue Status
When configured in maximum mode, the 8086,88
provide information about instruction queue operations on QSO and QS 1. Table 4-3 interprets the four
states that these lines can represent.

Table 4-3 Queue Status Signals
(Maximum Mode Only)
QS o QS1

QUEUE OPERATION IN LAST
CLK CYCLE

0

0

No operation; default value

0

1

First byte of an instruction was
taken from the queue

1

0

Queue was reinitialized

1

1

Subsequent byte of an instruction
was taken from the queue

210911

THE iAPX 86,88 HARDWARE DESIGN OVERVIEW

The queue status lines are provided for external processors that receive instructions and/or operands via
the ESC (escape) instruction (see Section 4.2). Such
a processor may monitor the bus to see when an
ESC instruction is fetched and then track the instruction through the queue to determine when (and if)
the instruction is executed.

by the 8288 Bus Controller. S3 and S4 indicate which
segment register was used to construct the physical
address used in this bus cycle (see Table 4-5). Line
S5 reflects the state of the interrupt-enable flag. S6 is
always O. S7 is a spare line whose content is
undefined.

Processor Halt
When the HALT (halt) instruction is executed, the
processor enters the halt state. This condition may
be interpreted as "stop all operations until an external interrupt occurs or the system is reset." No signals are floated during the halt state, and the content
of the address and data buses is undefined. A bus
hold request arriving on the HOLD line (minimum
mode, or either request/grant line (maximum
mode) is acknowledged normally while the processor
is halted.

Table 4-4 Bus Cycle Status Signals

52 51 SO

The halt state can be used when an event prevents
the system from functioning correctly. An example
might be a power-fail interrupt. After recognizing
that loss of power is imminent, the CPU could use
the remaining time to move registers, flags and vital
variables to (for example) a battery-powered CMOS
RAM area - or EEPROM area and then halt until the
return of power was signaled by an interrupt or
system reset.

0
0
0
0

0
0

1

0

1
1

1

1
1
1
1

0
0

0

1
1

0

0

1
1

TYPES OF BUS CYCLE

Interrupt Acknowledge
Read I/O
Write I/O
HALT
Instruction Fetch
Read Memory
Write Memory
Passive; no bus cycle

Table 4-5 Segment Register Status Lines

Status Lines
When configured in maximum mode, the 8086,88
CPUs emit eight status signals that can be used by
external devices. Lines SO, SJand S2identify the
type of bus cycle that the CPU is starting to execute
(Table 4-4). These lines are typically decoded by the

4-14

S4

S3

SEGMENT REGISTER

0
0

0
1

1
1

1

ES
SS
CS or none (I/O or Interrupt Vector)
OS

0

210911

CHAPTER 5
iAPX 186,188 HARDWARE DESIGN OVERVIEW
5.1 INTRODUCTION

•

DMA Controller

This chapter is a discussion of the hardware design
of the iAPX 186 (80186) and the iAPX 188 (80188)
on a functional level. Electrical characteristics and
other hardware references are found in Volume 2 of
this set. Volume 2 also contains the Device Specifications for both processors.

•

Timers

•

Interrupt Controller

5.2 80186 and 80188 CPU
ENHANCEMENTS

This chapter will include the following topics:
•

Enhancements to the 8086 CPU

•

Bus Organization

•

Interrupt Structure

•

Clock Generator

•

Internal Peripheral Interface

•

Chip-Select/Ready Generation Logic

The iAPX 186 and iAPX 188 are highly ,integrated
microprocessors, effectively combining 15 to 20 of
the most common iAPX 86 system components on a
single chip. Block diagrams for both processors are
shown in Figures 5-1 and 5-2. The iAPX 186,188 are
designed to provide both higher performance and
more highly integrated solutions to the total system
problem of the microprocessor user. Higher performance results from enhancements to both general
and specific areas of CPU operation, including faster
effective address calculation, improvement in the

INT3/INTAl

.

rD~LKOUT

TT

I I
X,

INT2/INTAO

I
I
I
I
I
I
I

l6-BIT
AW
CLOCK

GENERATOR
l6-BIT
GENERAL

PURPOSE
REGISTERS

0

(l

T

l

U

:=~

UNIT

-I-

::1-

'-

lIB

1

I

-1~N

LOCK

MAX COUNT
REGISTER A

I

l6·BIT
COUNT REGISTER

it

{

r-r+
PROGRAMMABLE

U

DT/II

16-BIT

SEGMENT
REGISTERS
..BYTE
PREFETCH

PROGRAMMABLE

QUEUE

REGISTERS

CONTROL

AD

ilHEJS7

ADOAD15

Al61S3A191S6

LCS

ORDO
OR01

DMAUNIT
0
1
20-811
SOURCE POINTERS

I

I

~

1

r±t 1

IIIH
lJ.At.,

2

CONTROL REGISTERS

UNIT
BUS INTERFACE

fESf -I-

RESET

TIMERS

CHIP-SELECT

AHOY

1

MAX COUNT ~
REGISTERB ~

CONTROLLER

INTERNAL BUS

r

t
PROGRAMMABLE

INTERRUPT

CONTROL;
REGISTERS

TMRIN

t

PROGRAMMABLE

SRDY

HOLD
HLDA

]

0

-1

J

TMRIN

IN,TO

~

'EXecUTIONuNrTJ

X,

1

TMROUT1 TMROUTO

INn
Ni'

2O-81T
OeSTINATION
POINTERS
16·BIT

TRANSFER COUNT
CQNTROL
REGISTERS

k~A2

PCS5JA1

Figure 5-1 iAPX 186 Block Diagram

5-1

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

CLKOUT Vee GND

~l!l

lJ

1
o

PROGRAMMABLE

'----,r:--....L

50;..S2

CONTROLLER

I
I

CONTROL
REGISTERS

..J

J

INTERNAL BUS

;=

,

2

!.-",'

REGISTER B :...' "" '"
MAX COUNT
REGISTER A

INTERRUPT

I

R~~~:S

+
I

TIMERS

MAXCQUNT

I

16-BIT
GENERAL

~

,

PROGRAMMABLE

I
I
I

l6-BIT
AW

TMR IN

t

'ExEcUTIoNu.."iT1

n

t

TMR OUT 1 TMR OUT 0

TMR IN

CONTROL REGISTERS

I
I

16-BIT
COUNT REGISTER

{

u

j

,-----j-DROO

~t-DRQ'

F""PRQ=G:::R"'A=M""MA'"'B"'
LEo-1
DMAUNIT

o

CHIP·SELECT
UNIT

SRDY-C.
ARDY-_

BUS INTERFACE
UNIT

fHf-fOo
HOLD-_

H:;::_

'6-BIT

SEGMENT

REGISTERS
PROGRAMMABLE

4·BYTE
PREFETCH
QUEUE

RESET_

I

-lJN
LOCK

OT/R

R~~~~RLS

111 IU L

1J.A1e
RO

IHes7

.~

~ OEs~:~kN
POINTERS

IIl

16-811
TRANSFER COUNT

Lll
u f - - - - - - 1 I~ 1
L ~~A2

ADO-

AS -

"015

At5

LCS

,

2O-BIT
SOURCE POINTERS

CONTROL
REGISTERS

PCSSlA1

Figure 5-2 iAPX 188 Block Diagram

execution speed of many instructions, and the inclusion of new instructions which are designed to im. prove the existing code, or to produce optimum
80186,188 code. Increased integration simplifies
system construction, which results in lower system
part count and thus a substanti!ll reduction in system
cost for the user. In this section, the 80186,188 CPU
enhancements will be discussed; increased integration will be considered in subsequent sections.

Execution speed is gained by performing the effective address calculations (base + displacement +
index) with a dedicated hardware adder in the
80186,188 bus-interface unit, rather than with a microcode routine (used by the 8086,88). This results
in an execution speed which is three to six times
faster than the 8MIiz 8086,88.

As described in Chapter 3, the 80186 and 80188
CPUs have the same basic register set, memory
organization, and addressing modes as the 8086,88.
The differences between the 80186 and 80188 are
the same as the differences between the 8086 and
8088: the 80186 has a 16-bit architecture and 16-bit
bus interface; the 80~88 has a 16-bit internal
architecture, but a 8-bit data bus interface. The instruction execution times of the two processors
differ accordingly: for each non-immediate 16-bit
data read/write instruction, 4 additional clock cycles
are required by the 80188.

In addition, the execution speed of specific instructions has been enhanced: all multiple-bit shift and
rotate instructions execute 1.5 to 2.5 times faster
than on the 8MHz 8086,88; multiply and divide instructions execute 3 times faster than on the 8MHz
8086,88; and string move instructions run at bus
bandwidth (i.e., data is transferred onto the bus in
each consecutive CPU clock cycle), allowing transfers in 2 Megabytes per second (80186), and 1
Megabyte per second (80188), which is about twice
the speed of the 8MHz 8086 or 8088 respectively.

CPU Execution Speed
Overall, the 80186,188 CPUs are 30% faster than the
8MHz 8086,88 CPUs and 50% faster than the 5MHz
8086,88 CPUs. The details of timing for individual
instructions is contained in the Instruction Set summary in Chapter 3.

Because of 80186,80188 hardware enhancements in
both the bus interface unit and the execution unit,
most instructions require fewer clock cycles to execute than on the 8086,88.
5-2

210911

t
I;

iAPX 186,188 HARDWARE DESIGN OVERVIEW

New Instructions

LEAVE (Leave Procedure)

Ten new instructions have been added to the basic
8086,88 instruction set. These instructions are designed to simplify assembly language programming,
enhance the performance of high-level language
implementations, and the reduce the size of object
code for the 80186,88. The new instructions are summarized below; for more detailed information, refer
to the Instruction Set summary in Chapter 3.

This instruction is also specifically designed for highlevel languages. It deallocates the memory space of
the the stack frame on procedure exit.
Additional Traps

The 80186,188 include two additional traps:

INS/OUTS (Block I/O)

Unused Opcode. A trap type 6 is generated when
opcodes OFH, 63H-67H, FIH and FFFFH are
executed. This trap is useful in detecting program
errors (e.g., the execution of data), and provides a
set of opcodes which the user may define for specific
purposes, emulating the action of the instruction in
software.

The INS (Input String), and OUTS (Output String)
instructions move a string of bytes or words at bus
bandwidth speed between memory and an I/O port.
This is essentially a DMA transfer in one in-line
instruction.

Escape Opcode. The 80186,188 CPUs may be programmed to cause a trap type 7 when an escape
opcode (D8H-DFH) is encountered. This provides a
straightforward method of giving instructions to coprocessors, e.g., the 8087. The programming is done
by a bit in the relocation register. It is programmed
not to cause a trap on reset.

PUSHI (Push Immediate)

This instruction pushes an immediate 16-bit value or
a sign extended 8-bit value onto the stack.

IMUL (Integer Immediate Multiply, signed)

This instruction performs a signed integer immediate
multiplication with a 16-bit result.

5.3 BUS STRUCTURE

The 80186,188 bus structure is similar to that of the
8086,88. The 80186 has a multiplexed address/data
bus, with 16-bit data and 20-bit address capability, as
does the 8086. The 80188 differs by transferring
8-bits of data per bus cycle (taking two bus cycles to
transfer a word).

PUSHA/POPA (Push All/Pop All)

These instructions push or pop all 8 general purpose
registers onto or off the stack.

For both processors, each bus cycle requires a minimum of 4 CPU clock cycles, in addition to any
number of wait states which may be required to accommodate the speed access limitations of particular
external memory or peripheral devices. The bus
cycles initiated by the 80186,188 CPU are identical
to those which are initiated by the 80186,188 integrated DMA controller.

SHIFT/ROTATE IMMEDIATE

These logic instructions shift or rotate by an immediate value.
BOUND (Array Bounds)

This instruction detects a value out of range by
checking an array index (contained in a register)
against the array bounds in memory.

The 80186,188 multiplexed address/data bus supports simultaneously the 8086,88 minimum mode
local bus and the maximum mode system bus. It provides both local bus controller outputs (RD, WR,
ALE, DEN and DT/R'), as well as system status outputs (SO. IT, S2) for use with the 8288 bus
controller. This differs from the 8086,88, where the
local bus controller outputs (generated only in minimum mode) are unavailable if status outputs
(generated only in maximum mode) are required.

ENTER (Enter Procedure)

This instruction facilitates high-level language procedure calls. It copies the stack frame pointer from a
calling procedure to the current stack frame.
5-3

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

Because the 80186,188 can simultaneously provide
local bus control signals and status outputs, many
systems supporting both a system bus (e.g., a
M ultibus) and a local bus will not require two separate external bus controllers. The bus control signals
may be used to control the local bus, while the status
signals are concurrently connected to the 8288 bus
controller to drive the control signals of the system
bus. To interface with the Multibus, the 80186,188
CPUs require an 8288 and 8289.

Transceiver Control
The 80186,188 generates two control signals (DT/R
and DEN) to be connected to 8286/8287 transceiver
chips. This allows the. addition of transceivers for
extra buffering without adding external logic. These
control lines are generated to control the flow of
data through the transceivers. The operation of
these signals is shown in Table 5-1.
Table 5-1 Transceiver Control
Signals Description

Local Bus Controller

Pin Name

DEN

Function

Enables the output drivers of
the transceivers. It is active
LOW during memory, 1/0, or
INTA cycles.
DTfR (Data Transmit! Determines the direction of
travel through the transceivers.
Receive)
A HIGH level directs data away
from the processor during write
operations, while a LOW level
directs data toward the processor during a read operation.

The local bus signals are generated by the iAPX
186,88 integrated local bus controller. Control lines
are also available that can be used to enable external
buffers and to direct the flow of data on and off the
local bus. These address/data, enable, and control
signals eliminate the need for an external local bus
controller in most systems.

Local Bus Arbitration
The 80186,188 employ a HOLDIHLDA system of
local bus exchange (instead of a REQUEST/GRANT protocol) in order to provide an
asynchronous bus exchange mechanism. The
HOLD/HOLDA protocol allows multiple local bus
masters, operating at separate clock frequencies, to
gain control of the local bus. This protocol also
allows compatibility with Intel's new generation of
highly integrated bus master peripheral devices, for
example, the 82586 Ethernet controller and the
82730 CRT controller/text co-processor.

(Data Enable)

8086,88 and 801 86,1 88 Bus
Differences
The 80186,188 bus was designed to be upward compatible with the 8086,88 bus. As a result, the
8086,88 bus interface components (the 8288 bus
controller and the 8289 bus arbiter) may be used
directly with the 80186,188. However, there are a
few significant differences which should be
considered.

In the HOLD/HLDA protocol, a device requiring
bus control (for example, an external DMA device)
raises the HOLD line. In response to this HOLD
request, the 80186,188 raises its HLDA line after it
has finished its current bus activity. When the external device is finished with the bus, it drops its bus
HOLD request; the 80186 responds by dropping its
HLDA line and resuming bus operation.

In the case of the 186,188:

When there is more than one alternate local bus
master, external circuitry is required to arbitrate
which bus master will gain control of the bus.

•

RESET OUT is synchronized with the processor clock, and indicates that the processor is
being reset.

•

The lines QSO and QSl come out one phase
earlier (with QSMD option) than in the
8086,88.

•

ALE comes active one phase earlier than in
the 8086,88 but remains active throughout
the 8288 ALE (the 80186,188 generate a
longer pulse).

•

On RESET the RD/QSMD pin is sampled. If
it is low, queue status mode is entered, and
ALE and WR becomes QS lines. If this mode
is used, an 8288 is required (Ri), WR, ALE
pins are redefined) .

•

HOLD/HOLDA lines take the place of
RQ/GT.

Memory/Peripheral Control
Bus control signals are used to strobe data from
memory to the CPU, or from the CPU to memory.
The local bus controller does not. provide a
memory/l/O signal. If a memory/I/O signal is
needed, the designer must use the S2signal (which
requires external latching), make the memory and
I/O space nonoveriapping, or use only the integrated
chip-select circuitry.
5-4

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

•

NOTES: (continued)

S3-S6 are defined differently: S3-S6 are
always low, except during DMA, when S6 is
high.

•

There are no advanced write commands.

•

There are no separate I/O-Memory RD/WR
lines.

sources. However. they "ave a defined priority ordering
amongst themselves. (Priority 2A is higher priority than
28.) Each Timer interrupt has a separate vector type
number.
4. Default priorities for the interrupt sources are used only if
the user does not program each source Into a unique
priority level.
'··5. An escape opcode will cause a trap only If the proper bit is
set In the peripheral control block relocation register.

For more detail on the hardware aspects of the
80186,188 bus see Chapter 2, Volume 2, and the
iAPX 186 and iAPX 188 Device Specifications, Appendix B, Volume 2.

5.4 INTERRUPTS

Software-generated Interrupts

The 80186,188 can service interrupts generated by
software or hardware. Software interrupts are
generated by specific instructions or the results of
conditions specified by instructions. Hardware interrupts occur when any of the external interrupt lines
(INTO-INTI) are activated. The vector types for all
interrupts are given in Table 5-2.

The 80186,188 software generated interrupts include
those found on the 8086,88, namely:

Table 5- 2 801 86,188 Interrupt Vectors
Interrupt Name
Divide Error
Exception
Single Step
Interrupt
NMI
Breakpoint
Interrupt
INTO Detected
Overflow
Exception
Array Bounds
Exception
Unused-Opcode
Exception
ESC Opcode
Exception
Timer 0 Interrupt
Timer 1 Interrupt
Timer 2 Interrupt
Reserved
DMA 0 Interrupt
DMA 1 Interrupt
INTO Interrupt
INT1 Interrupt
INT2 Interrupt
INT3 Interrupt

Vector Default
Type Priority
'1

1

12"2

All

2
3

1
'1

All
INT

4

'1

INTO

5

'1

BOUND

6

'1

7

'1"·

Undefined
Opcodes
ESC Opcodes

8
18
19
9
10
11
12
13
14
15

2A····
2B····
2C····
3
4
5
6
7
8
9

Divide error exception (type 0)

•

Single-step interrupt (type 1)

•

Breakpoint interrupt (type 3)

•

INTO Detected overflow exception (type 4)

The divide error interrupt is generated by the CPU
following execution of a DIV or IDIV instruction if
the calculated quotient is larger than the specified
destination.

Related
Instructions

0

•

DIV.IDIV

The single-step interrupt is controlled by the trap
flag (IF). If TF is set, the CPU generates a type 1 interrupt after every instruction.
The breakpoint interrupt is generated if the overflow
flag (OF) is set.
The new interrupts available on the 80186,188 are:

NOTES:
·1. These are generated as the result of an instruction
execution.
·'2. This is handled as in the 8086.
.. ··3. All three timers constitute one source of request to the
interrupt controller. The Timer interrupts all have the same
default priority level with respect to all other interrupt

5-5

•

Array bounds exception (type 5)

•

Unused opcode exception (type 6)

•

Escape opcode exception (type 7)

The array bounds interrupt occurs during a BOUND
instruction if the array index is outside the array
bounds. The array bounds are located in memory at
a location indicated by one of the instruction
operands. The other operand indicates the value of
the index to be checked. (Refer to the BOUND instruction in the Instruction Set Summary, Chapter 3
of this volume, for more details.)
The unused opcode interrupt is generated by the
CPU if it is directed to execute any of the following
unused opcodes: OFH, 63H-67H, FIH and FFFFH.
210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

An ESCape opcode interrupt is generated by the attempted execution of opcodes D8H-DFH. This interrupt is programmed by setting the ET bit in the
relocation register. The return address of this interrupt will point to the ESC instruction causing the
exception. If a segment override prefix preceded the
ESC instruction, the return address will point to the
segment override prefix.

X1~-----------~--L-

$ 1 6 MHz CRYSTAL
80186

~~------------~

Hardware-generated Interrupts
Hardware-generated interrupts are of two types:
maskable and non-maskable types. For external
maskable interrupts, the 80186,188 provide the
INTO-INT3 interrupt request pins. Maskable interrupts may also be generated by the 80186,188 integrated DMA controller and the integrated timer
unit. Software enables these inputs by setting the interrupt flag bit (IF) in the Status Word.

Figure 5-3 Recommended iAPX 186
Crystal Configuration

If an external oscillator is used, it can be connected
directly to input pin Xl in lieu of a crystal (X2
should be left open). This oscillator input is used to
drive an internal divide-by-two counter (see below)
to generate the CPU clock signal; thus the external
frequency input can be practically any duty cycle, so
long as the minimum high and low times for the
signal (as specified in the Device Specification) are
met. The output of the oscillator is not directly
available outside the iAPX 186,188.

A non-maskable interrupt (NMI) is also provided.
This interrupt is serviced regardless of the state of
the IF bit, and is typically used to activate a power
failure routine. The activation of this inp).lt causes an
interrupt with an internally supplied vector value of
2. No external interrupt acknowledge sequence is
performed. The IF bit is cleared at the beginning of
an NMI interrupt to prevent maskable interrupts
from being serviced.

Divide-by-two Counter
The clock generator provides the 50% duty cycle processor clock for the CPU. This is done by dividing
the oscillator output by two, forming the symmetrical clock. If an external oscillator is used, the state of
the clock generator will change on the falling edge of
the oscillator signal. The CLKOUT pin provides the
processor clock signal for use outside the 80186,188.
This signal may be used to drive other system
components. All timings are referenced to the
output clock.

5.5 CLOCK GENERATOR
The 80186,188 provides an integrated clock generator which generates the main clock signal for all
80186,188 integrated components, as well as all CPU
synchronous devices in the system. The clock generator consists of a crystal-controlled oscillator, a
divide-by-two counter, synchronous and asynchronous ready inputs, and reset circuitry.

READY Synchronization
The Oscillator

The clock generator also provides both synchronous
and asynchronous ready inputs. Asynchronous
ready synchronization is generated by circuitry
which samples ARDY in the middle ofT2 and again
in the middle of each Tw until ARDY is sampled
HIGH. One-half CLKOUT cycle of resolution time
is used.

The oscillator circuit is designed to be used with a
parallel resonant fundamental mode crystal at 2X
the desired CPU clock speed (i.e., 16 MHz for an 8
MHz 80186,188), or with an external oscillator also
at 2X the CPU clock. The crystal determines the
CPU clock speed and is used for all instruction time
calculations described in Chapter 3. The use of an
LC or RC circuit with this oscillator is not advised.
The recommended crystal configuration is shown in
Figure 5-3.

A second ready input (SRDY) is provided to interface with externally synchronized ready signals. This
input is sampled at the end of T 2 and again at the end
of each T w until it is sampled HIGH.
5-6

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

RESET Logic

OFFSET

The 80186,188 have both a RES input pin and a
synchronized RESET pin for use with other system
components. The RES input pin is provided with
hysteresis in order to facilitate power-on Reset generation via an RC network. RESET is guaranteed to
remain active for at least five clock cycles given a
RES input of at least six clock cycles. RESET may be
delayed up to two and one-half clock cycles behind
RES.

Relocation Register

FEH

DAH
OMA Descriptors Channel 1

DOH

CAH
DMA Descriptors Channel 0

COH

Multiple 80186,188 processors may be synchronized
through the RES input pin, since this input resets
both the processor and the divide-by-two internal
counter in the clock generator. To insure that the
divide-by-two counters all begin counting at the
same time, the active going edge of RES must satisfy
a 25 ns setup time before the falling edge of the
80186,188 clock input. In addition, in order to insure
that all CPUs begin executing in the same clock
cycle, the reset must satisfy a 25 ns setup time
before the rising edge of the CLKOUT signal of all
the processors.

ASH
Chl~Select

Control Registers

AOH

88H
Timer 2 Control Registers

SOH
5EH
Timer 1 Control Registers
5SH

56H
Timer 0 Control Registers

SOH

3EH

5.6 INTERNAL PERIPHERAL INTERFACE

Interrupt Controller Registers

20H

The iAPX 186 and iAPX 188 include six integrated
peripheral devices along with the BIU and EU.
These six are the chip select unit, the DMA
controller, the timer unit, the interrupt controller,
the local bus controller and the clock generator. The
first four of these are programmable, and will be discussed in the remaining sections of this chapter. The
clock generator and local bus controller, which have
been discussed in previous sections, operate transparently to the programmer.

Figure 5-4 Internal Register Map

The integrated peripherals operate semi-autonomously from the CPU. Access to them is for the
most part through read and write instructions to the
control and data locations in the control block. Because the integrated peripherals are accessed exactly
as if they were external devices, no new instruction
types are required to access and control them.

Peripheral Control Block

Relocation Register

The four 80186,188 programmable integrated
peripherals are controlled by 16-bit registers located
in an internal 256-byte control block (see Figure
5-4). Control and status registers are provided for
each of the programmable peripherals. The function
of these registers will be discussed in subsequent sections under the appropriate peripheral device.

The control block base address is programmed via a
16-bit relocation register contained within the control block at offset FEH from the base address (see
Figure 5-5). The relocation register provides the
upper 12 bits of the base address of the control
block. In addition, bit 12 of this register determines
whether the control block will be mapped into I/O or
memory space. If this bit is 1, the control block will
be located in memory space; if the bit is 0, the control block will be located in I/O space. When the control register block is mapped into I/O space, the
upper 4 bits of the base address must be programmed as 0, since I/O addresses are only 16 bits
wide. The offset map of the 256-byte control register
block is shown in Figure 5-4.

The control block may be mapped into memory or
I/O space. Each of the integrated peripherals' control
and status registers are located at a fixed location
above the programmed base location of the peripheral control block. The base address must be on an
even 256-byte boundary (i.e, the lower 8 bits of the
base address are all zeros).
5-7

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

OF~ET: FEHL--L~~-L~L-________
Re_lo_c_at_~_n_A~
__
~_._._BI_ts_R_'~
__
R8__________~

ET
~ ESC Trap I No ESC Trap (110)
MIlO ~ Register block located In Memory 11/0 Space (110)
RMX = Normal Interrupt Controller mode I iRMX compatlbte
Interrupt Controller mode (011)

Figure 5-5 Relocation Register

In addition to the peripheral control block relocation
information, the relocation register contains two
additional bits. One is used to set the interrupt controller into iRMX_86 compatibility mode (see Section 5.10). The other is used to force the processor
to trap whenever an ESCape (to a coprocessor) instruction is encountered.

The chip select unit is programmable such that it can
be used to fulfill the chip select requirements (in
terms of memory device or bank size and speed) of
most small and medium sized 80186,188 systems.

Because the relocation register is contained within
the control block, upon reset it is automatically programmed with the value 20FFH. This means that
the peripheral control block will be located at the
very top (FFOOH to FFFFH) of 110 space. Thus,
after reset the relocation register will be located at
word location FFFEH in 110 space.

The memory chip select lines are divided into 3
groups which separately address the major areas of
memory in a typical 8086/80186 system: upper
memory for reset ROM, lower memory for interrupt
vectors, and mid-range memory for program
memory. One output each is provided for upper and
lower memory; four outputs are provide for midrange memory.

Memory Chip Selects

If the user wished to locate the peripheral control
block starting at memory location 10000H, he would
program the peripheral control register with the
value 1l00H. In doing so, all registers within the integrated peripheral control block would be moved to
memory locations 10000H to 100FFH. Note that
since the relocation register is contained within the
peripheral control block, it would also be moved to
word location 100FEH in memory space.

The size of each memory area is user programmable
and can be set to 2K, 4K, 8K, 16K, 32K, 64K, 128K,
plus lK and 256K for upper and lower chip selects.
In addition, the beginning or base address of the
midrange memory chip select may be programmed
to be active for any memory location at a time. Note
that all chip select sizes are bytes, whereas the 80186
memory is arranged in words. This means that if, for
example, 16 64K x 1 memories are used, the
memory block size will be 128K bytes, not 64K
bytes.

5.7 CHIP SELECT UNIT

The starting location and ending location of both
upper and lower memory areas are fixed at OOOOOH
and FFFFH respectively; the starting location of the
mid-range memory is uSer programmable.

The iAPX 186,188 include an integrated chip select
unit which provides programmable chip-select generation for both memory banks and peripherals. In
addition, it can be programmed to provide READY
(or WAIT state) generation, and can also provide
latched address bits Al and A2.

The memory chip selects are controlled by four registers located in the peripheral control block (see
Figure 5-6). These include one register each for
upper and lower memory, the values of which determine the size of the two memory blocks; the other
two registers are used to set the size and base address
of the mid-range block. These registers, and the
areas of memory they select, are discussed in the following sections.

Six output lines are used for memory addressing and
seven output lines are used for peripheral
addressing. The chip-select lines are active for all
memory and 110 cycles (in their programmed areas)
generated by both the CPU and by the integrated
DMA unit.

5-8

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

15

14

AOHI 1
A19

OFFSET:

13

12

11

10

7

4

I 1 I u I u Iu Iu I u Iu Iu Iu I 1 I1 I
All

MPCS Register

OFFSET:

A2H

I

15

14

13

12

11

0
A19

0

u

Iu

u

10

9

Iu Iu Iu Iu Iu I I I
1

1

1

R2

1

0

Rl

RO

I I I

All

MMCS Register

15
OFFSET:

A8H I 1

I

14

13

M61 M5

12

11

10

9

8

7

6

M4

M3

M2

Ml

MO

EX

MS

2

1

0

R2

Rl

RO

I I I I I I I I I I I I I I
1

1

1

UMCS Register
15
OFFSET:

A6HI U
A19

0

Iu Iu Iu Iu Iu Iu I

R2

1

I I I
Rl

RO

A13

LMCS Register
Figure 5-6 Memory Chip Select Registers

UPPER MEMORY

The UCS chip select line is used for the top of
memory. This area is usually used as the system
memory, because after reset the 80186,188 begin executing at memory location FFFFOH.
The upper limit of memory defined by this chip
select is always FFFFFH; the lower limit (and thus
the size of the memory block) is defined in the
UMCS register. The UMCS register is located at
offset AOH in the internal control block. The legal
values for bits 6-13 and the resulting starting address
and memory block sizes are given in Table 5-3. Any
combination of bits 6-13 not shown in Table 5-3 will
result in undefined operation. After reset, the
UMCS register is programmed for a lK area. It must
be reprogrammed if a larger upper memory area is
desired.

to be activated. UMCS bits R2-RO are used to specify
READY mode for the area of memory defined by
the register (see below).

Table 5-3 UMCS Programming Values

Any internally generated 20-bit address whose upper
16 bits are greater than or equal to the UMCS register (with register bits 0-5 equal to 0) will cause UCS
5-9

Starting
Address
(Base
Address)

Memory
Block
Size

FFCOO
FF800
FFOOO
FEOOO
FCOOO
F8000
FOOOO
EOOOO
COOOO

1K
2K
4K
8K
16K
32K
64K
128K
256K

UMCS Value
(Assuming
RO=R1 =R2=O)

FFF8H
FFB8H
FF38H
FE38H
FC38H
F838H
F038H
E038H
C038H
210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

Table 5-5 MPCS Programming Values

LOWER MEMORY

The LCS line selects lower memory. The bottom of
memory contains the interrupt vector table, beginning at location OOOOOH. The lower limit of memory
defined by this chip select is always OH; the upper
limit (and thus the size of the memory block) is
defined in the LMCS register. The LMCS register is
located at offset A2H in the internal control block.
The legal vlllues for bits 6-15 and the resulting upper
address and memory block sizes are given in Table
5-4. Any combination of bits 6-15 not shown in
Table 5-4 will result in undefined operation. After
reset, the LMCS register value is undefined.
However, the LCS chip select line will not become
active until the LMCS register is accessed.
Any internally generated 20-bit address whose upper
16 bits are less than or equal to LMCS (with register
bits 0-5 equal to 1) will cause LCS to be active.
LMCS register bits R2-RO are used to specify the
READY mode for the area of memory defined by
the register.

003FFH
007FFH
OOFFFH
01FFFH
03FFFH
07FFFH
OFFFFH
lFFFFH
3FFFFH

Memory
Block
Size

lK
2K
4K
8K
16K
32K
64K
128K
256K

Individual
Select Size

MMCS Bits

8K
16K
32K
64K
128K
256K
512K

2K
4K
8K
16K
32K
64K
128K

00000016
00000106
00001006
00010006
00100006
01000006
10000006

14-8

Each of the four MCS chip-select lines is active for
one of the four equal contiguous divisions of the
mid-range memory block. Thus, if the total block
size is 32K, each chip select is active for 8K of
memory, with MCSO being active for the first range
and MCS3 being active for the last range.
The base address of the mid-range memory block is
defined by bits 15-9 of the MMCS register, located
at offset A6H in the internal control block. Bits 15-9
correspond to bits A19-A13 of the 20-bit memory
address. (Bits Al2-AO of the base address are always
0.) The base address may be set to any integer multiple of the size of the total memory block selected.
For example, if the mid-range block size is 32K (or
the size of the block for which each MCS line is
active is 8K), the block could be located at 10000H
or 18000H, but not at 14000H, since the first few
integer multiples of a 32K memory block are OH,
8000H, 10000H, 18000H, etc.

Table 5-4 LMCS Programming Values
Upper
Address

Total Block
Size

LMCS Value
(Assuming
RO=R1 =R2=O)

0038H
0078H
00F8H
01 F8H
03F8H
07F8H
OFF8H
lFF8H
3FF8H

MID-RANGE MEMORY

The four MCS lines select locations within a userlocatable memory block, which can be located anywhere within the 1M byte memory address space
exclusive of the areas defined by UCS and LCS.
Both the base address and size of this memory block
are programmable.

The S12K block size for the mid-range memory chip
selects is a special case. When using 512K, the base
address would have to be either OOOOH or 80000H; if
it were to be programmed at OOOOOH when the LCS
line was programmed, there would be an internal
conflict between the LCS ready generation logic and
the MCS ready generation logic. Since the LCS chipselect line does not become active until
programmed, while the UCS line is active at reset,
the memory base can be set only at OOOOOH. If this
base address is selected, however, the LCS range
must not be programmed.

The size of the memory block defined by the midrange .select lines, as shown in Table 5-5, is determined. by bits 8-14 of the MPCS register. This
register is located at offset A8H in the internal control block. Note that one, and only one, of bits 8-14
must be set at a time; unpredictable operation of the
MCS lines will otherwise occur. The EX and MS bits
in the ,MPCS register relate to peripheral
functionality, and are described in Section 5.7.
5-10

MMCS bits R2-RO specify the READY mode of operation for all mid-range chip selects. All devices in
mid-range memory must use the same number of
WAIT states.
After reset, the contents of the MPCS and MMCS
registers are undefined. However, none of the MCS
lines will be active until both registers are accessed.
210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

12-15 must be programmed zero, since the I/O address is only 16 bits wide. This address must be a
multiple of lK bytes, i.e., the least significant 10 bits
of the starting address are always O. Table 5-6 shows
the address range of each peripheral chip select with
respect to the PBA contained in the PACS register.
PACS bits 0-2 are used to specify READY mode for
PCSO-PCS3.

Peripheral Chip Select
The iAPX 186,188 can generate chip selects for up to
seven peripheral devices. The chip select lines PCSO"6 are active for seven contiguous blocks of 128
bytes. The base address of the memory block is userprogrammable, and may be located in either I/O or
memory space. Thus, peripheral devices may be
1/0- or memory-mapped.

The mode of operation of the peripheral chip selects
is defined by the MPCS register. Bit 7 (EX) of this
register is used to select the function of PCS5 and
PCS6; bit 6 (MS) is used to select whether the
peripheral chip selects are mapped into memory or
I/O space. The programming of these bits is described in Table 5-7. MPCS bits 0-2 are used to specify READY mode for PCS4-PCS6.

PCS5 and PCS6 can also be programmed to provide
latched address bits AI, A2. (When so
programmed, these lines cannot be used as peripheral selects.) The outputs can be connected directly to
the AO, Al pins used for selecting internal registers
or 8-bit peripherals. This scheme simplifies the hardware interface because the 8-bit registers of peripherals are simply treated as 16-bit registers located on
even boundaries in I/O space or memory space
(only the lower 8-bits of the register are significant;
the upper 8-bits are "don't cares").

Table 5-6 PCS Address Ranges

The peripheral chip selects are controlled by the
PACS and MPCS registers located in the internal
peripheral control block (see Figure 5-7). These
registers allow the base address of the peripherals to
be set, and specify whether the peripherals are
mapped into memory or I/O space. (The MPCS
register is also used to set the size of the mid-range
memory chip-select block, as described below.)
Both registers must be accessed before any of the
peripheral chip selects will become active.

A4H

I

15

Iu I

u

ululu

U

Active between Locations

PCSO
PCS1
PCS2
PCS3
PCS4
PCS5
PCS6

PBA
-PBA+127
PBA+128 -PBA+255
PBA+256 - PBA+383
PBA+384 - PBA+511
PBA+512 - PBA+639
PBA+640 -PBA+ 767
PBA+768 -PBA+895

Table 5- 7 MS, EX Programming Values

The starting address of the peripheral chip-$elect
block is defined by the PACS register, located at
offset A4H in the internal control block. Bits 15-6 of
this register correspond to bits 9-10 of the 20-bit programmable base address (PBA) of the peripheral
chip-select block. Bits 9-0 of the PBA are all zeros. If
the chip-select block is located in I/O space, bits

OFFSET:

pes Line

Bit

Description
1
0
0
1

MS

EX

=
=
=
=

Peripherals mapped into memory space.
Peripherals mapped into I/O space.
5 PCS lines. A1, A2 provided.
7 PCS lines. A1, A2 are not provided.

ululuJull
Al0

A19

PACS Register
15

OFFSET:

ASH

14

13

12

11

10

9

8

7

6

2

1

0

I 1 I M61 M5 I M41 M3 I M21 Ml I MO I EX I MS I 1 I 1 I 1 I R2 I Rl I RO I
MPCS Register
Figure 5- 7 Peripheral Chip Select Registers
5-11

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

R2-RO of each control word specifies the READY
mode for the corresponding block, with the exception of the peripheral chip selects: R2-RO of PACS
set the PCSO-]> READY mode; R2-RO of MPCS set
the PCS4-6 READY mo.de.

READY/WAIT Generation Logic
The 80186,188 can generate an internal READY
signal for each of the memory or peripheral CS lines;
In addition, 0-3 wait states may be inserted for all accesses to the area for which the chip select is active.
Finally, each chip-select range may' be individually
programmed to either ignore external READY or to
factor external READY with the integrated ready
generator.

Chip Select/Ready Logic and Reset
Upon reset, the Chip-Select/Ready Logic will perform the following actions:

READY control consists of 3 bits for each CSline or
group oflines generated by the 80186,188. The interpretation of the ready bits is shown in Table 5-8.
This allows independent ready generation for each
of upper memory, lower memory, mid-range
memory, peripheral devices 0-3 and peripheral
devices 4-6. The ready bits control an integrated wait
state generator which allows a programmable
number of wait states to be automatically inserted
whenever an access is made to the area of memory
associated with the chip select area. Each set of ready
bits includes a bit which determines. whether the external ready signals (ARDY and SRDY) will be
used, or whether they will be ignored (i.e., the bus
cycle will terminate even though a ready has not
been returned on the external pins) .
If the external READY is used (R2=0), the internal
ready generator operates in parallel with it, rather
than in series. For example, if the internal generator
is set to insert two wait states, but activity on the
external READY lines inserts four wait states, the
processor will insert four wait stales, not six. This is
because the two wait states generated by the internal
generator overlapped the first two wait states
generated by the external ready signal. Note that the
external ARDY and SRDY lines are always ignored
during cycles accessing internal peripherals.

R1

0
0

0
0

0

1

0

1

1
1

0
0

1

1

1

1

Upon leaving RESET, the UCS line will be
programmed to provide chip selects to a lK
block. The accompanying READY control
bits will be set at 011 to allow the maximum
number of internal wait states in conjunction
with external Ready consideration (i.e.,
UMCS resets to FFFBH).

•

No other chip select or READY control registers have any predefined values after RESET.
They will not become active until the CPU accesses their control registers. Both the PACS
and MPCS registers must be accessed before
the PCS lines will become active.

Data can be transferred over these channels at the
rate of 2 MBytes/sec. The transfers can occur between memory and 110, 110 and 110, or memory
and memory. Data may be transferred either in
bytes or words, to or from even or odd addresses.
Figure 5-8 shows the block diagram representation
of the DMA unit.

o wait states, external ROY also used.

1 wait state inserted, external ROY also
used.
0 2 wait states inserted, external ROYaiso
used.
1 3 wait states inserted, external ROYaiso
used.
0 o wait states, external ROY ignored.
1 1 wait state inserted, external ROY
ignored.
0 2 wait states inserted, external ROY
ignored.
1 3 wait states inserted, external RO'!
ignored.
1

•

The iAPX 186,188 include two independent, highspeed DMA channels which operate independently
of the CPU and drive all integrated bus interface
components (bus controller, chip selects, etc.).

RO Number of WAIT States Generated
0

All chip-select outputs will be driven HIGH

5.8 DMA CONTROLLER

Table 5-8 READY Bits Programming
R2

•

Every DMA cycle requires two to four bus cycles one or two to fetch the data to an internal register,
and one or two to deposit the data. This allows word
data to be iocated on odd boundaries, or byte data to
be moved from odd locations to even locations.
(This is normally difficult, since odd data bytes are
transferred on the upper 8 data bits of the 16-bit data
bus, while even data bytes are transferred on the
lower 8 data bits of the data bus.)
Each channel has four registers in the peripheral control block which define its specific operation. These
registers include a 20-bit source pointer (2 words), a
20-bit destination pointer (2 words), a 16-bit transfer
counter, and a 16-bit control word. All registers may
be modified or altered by the CPU during any DMA

5-12

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

TIMER REOUEST

DMA
CONTROL
LOGIC

Figure 5·8 DMA Unit Black Diagram

activity. Changes made to these registers will be reflected immediately in DMA operation. Table 5-9
shows the format of these registers; the specific function of each register is discussed in the following
sections.
Table 5·9 DMA Control Block Format
Register Address
Register Name
Control Word
Transfer Count
Destination Pointer (upper 4
bits)
Destination Pointer
Source Pointer (upper 4 bits
Source Pointer

Ch.O

Ch.1

CAH
C8H
C6H

DAH
D8H
D6H

C4H
C2H
COH

D4H
D2H
DOH

5-13

Channel Control Word Register

The DMA control word register (see Figure 5-9)
contains bits which determine the precise mode of
operation for each channel, including for both data
source and destination whether the pointer points to
memory or I/O space, and whether the pointer will
be incremented, decremented or left alone after
each DMA transfer. It also contains the (B7W) bit
which selects between byte or word transfers. Two
synchronization bits are used to determine the
source of the DMA requests: the TC bit determines
whether DMA activity will cease after a programmed
number of DMA transfers, and the INT bit is used
to enable interrupts to the processor when this has
occurred.
210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

15

MI

14

13

10

DESTINATION
DEC
INC

x~

DON'T CARE.

IDw

Byte/Word (0/1) Transfers.

SYN:

ST/STOP:

Start/stop (1/0) Channel.

(2 bits)

CHG/NOCHG:

ChangelDo not change (1/0)
ST/STOP bit. If this bit is set when
writing to the control word, the
ST/STOP bit will be programmed by
the write to the control word. If th is
bit is cleared when writing the control word, the ST/STOP bit will not
be altered. This bit is not stored; it
will always be a a on read.

00 No synchronization.
NOTE: the ST bit will be cleared automatically when the contents of
the TC register reach zero regardless of the state of the TC bit.

01 Source synchronization.
10 Source synchronization.
11 Unused.
SOURCE:INC

INT:

Enable interrupts to CPU on Transfer Count termination.

TC:

If set. DMA will terminate when the
contents of the Transfer Count
register reach zero. The ST/STOP
bit will also be reset at this point if
TC is set. If this bit is cleared, the
DMA unit will decrement the transfer cou nt register for each DMA
cycle, but the DMA transfer will not
stop when the contents of the TC
register reach zero.

Increment source painter by 1 or 2
(depends on IDW) after each transfer.

Mira Source pointer by 1 or 2 (depends on
IDW) after each transfer.

DEC Decrement source pointer by 1 or 2
(depends on IDW) after each transfer.
DEST:

INC

Increment destination pointer by 1 or 2
(IDW) after each transfer.

MIlO Destination pointer is in MilO space
(1/0).

P

Channel priority - relative to other
channel.

a low priority.
1 high priority.
Channels will alternate cycles if both
set at same priority level.
TDRQ

0: Disable DMA requests from timer 2.
1: Enable DMA requests from timer 2.

Bit3

Bit 3 is not used.

If both INC and DEC are specified for the same pointer.
the painter will remain constant after each cycle.

Figure 5-9 DMA Control Word Register and Bit Descriptions

5-14

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

DMA control word register. If the TC bit in the
DMA control word is set, however, DMA activity
will terminate when the transfer count register
reaches zero. A transfer count of zero allows 216
transfers to be made.

The control word register also contains a start/stop
bit which is used to enable DMA transfers. When
this bit is set, a DMA transfer will occur whenever a
DMA request is made to the channel; if this bit is
cleared, no DMA transfers will be performed by the
channel. A companion bit, the CHG/NOCHG bit,
allows the contents of the DMA control register to
be changed without modifying the state of the
start/stop bit. The P bit is used to assign a priority to
each channel. See Figure 5-9 for more information
on each bit in the control word.

DMA Requests

DMA Destination and Source
Pointer Registers
Each DMA channel has a 20-bit source and a 20-bit
destination pointer (see Figure 5-10). These pointers
are used to access the I/O or memory location from
which data will be fetched or to which data will be
written. Each occupies two 16-bit registers in the
peripheral control block, with the lower four bits of
the upper register specifying the four high-order bits
of the 20-bit physical address. Thus, these registers
allow access to the entire 1 Mbyte address space of
the 80186,188.
The source and destination pointers may be individually incremented or decremented after each
transfer. If word transfers are performed, the pointer
is incremented or decremented by two.
Since the DMA channels can perform transfers to or
from odd addresses, there is no restriction on values
for the pointer registers. However, higher transfer
rates can be obtained if all word transfers are performed to even addresses, since this allows data to
be accessed in a single memory access.

DMA transfers may be initiated by internally or externally generated requests. Internally generated requests are issued by timer 2 or by the DMA channel
itself. Externally generated transfers are those
requested by an external device. Each DMA channel
has a single DMA request line by which an external
device may request a DMA transfer. The synchronization bits in the DMA control register determine
whether this line is interpreted to be connected to
the source of the DMA data or the destination of the
DMA data.
For internal interrupt requests, the DMA channel
can be programmed such that whenever timer 2
reaches it maximum count, a DMA request is
generated. This is accomplished by setting the
TDRQ bit in the DMA channel control word
register. The DMA channel can also be programmed
to provide its own DMA requests. DMA transfer
cycles will then run continuously at the maximum
bus bandwidth until the programmed number of
DMA transfers (specified in the transfer count
register) have occurred. This is accomplished by programming the synchronization bits in the DMA control register for unsynchronized transfers. During
unsynchronized transfers, the DMA controller
monopolizes the bus, i.e., no cycle stealing by the
CPU will occur.

DMA Transfer Count Register

Synchronized transfers are DMA transfers requested
by an external device and are of two types: source
synchronized or destination synchronized, that is, either

The transfer count register specifies the number of
DMA transfers to be performed, up to a maximum
of 64K bytes or words. This register is decremented
after every DMA cycle (for both ,byte and word
transfers), regardless of the state of the TC bit in the

the source of the data or the destination of the data
may request the transfer. The only difference between the two is the time at which the DMA request
pin is sampled to determifle if another DMA transfer
is required immediately after the currently executing
transfer.

HIGHER
REGISTER
ADDRESS
LOWER
REGISTER
ADDRESS

xxx

xxx

xxx

Al9-A16

Al5-A12

All-AS

A7-A4

A3-AO

15

xxx

~

DON'" CARE

Figure 5-1 0 DMA Memory Pointer Register Format
5-15

210911

iAPX 186.188 HARDWARE DESIGN OVERVIEW

When source synchronized (or unscynchronized)
transfers are performed, the'DMA channel may
begin another transfer immediately after the' end of
a previous transfer. This allows a complete transfer
to take place every two bus cycles or eight clock
cycles, assuming there are no wait states (see Table
5-10).
When destination synchronization transfers are
requested, the DMA controller relinquishes control
of the bus after every transfer: If no other bus activity is initiated, another DMA cycle will begin after
two processor clock cycles. This is done to allow the
destination device time to remove its request if
another transfer is not desired. Since the DMA controller relinquishes the bus, the CPU can initiate a
bus cycle. As a result, a complete bus cycle will often
be inserted between destination synchronized
transfers. This results in the maximum DMA transfer rates shown in Table 5-10. Note that no DMA
prefetching occurs when destination synchronization
is performed. Data is noffetched fron'! the source address until' the destination device signals that it is
ready to receive it.
Table 5~1 0 Maximum DMA Transfer Rates
Type of
Synchronization
Selected

CPU, RLinnlng

CPU Hatted

Unsynchronized
Source Synch
Destination Synch

2M Byteslsec
2MBytes/sec
1.3MByteslsec

2MByteslsec
2MByteslsec
1.5MByteslsec

cycle. Because an interrupt request cannot suspend a
DMA operation and the' CPU cannot access
memory during a DMA cycle, interrupt latency time
will suffer during sequences of continuous DMA
cycles. An NMI reque~t, however, will cause all internal DMA activity to halt. This allows the CPU to
quickly respond to the NMI request.

DMAProgramming
DMA cycles start whenever the ST/STOP bit of the
Control Register is set. If synchronized transfers are
programmed, a DRQ must also b,e generated ..
Therefore, the source and destination transfer
pointers, and the transfer count register (if used) ,
must be programmed before t~is bit is set.
Each PM;\. channel control register may be changed
while the cha11Ilel is op~rating. If the CHGINOCHG
bit is cleared, when the "control word register is
written, the ST/STOP bit will not be modified by the
write. If ml,iltiple channel registers aTe modified, it is
recommended that a LOCKED string transfer be
used to prevent a DMA transfer from 'occurring between updates to the channel registers.

DMA Channels and Reset
Upon RESET, the DMA channels will perform the
following actions:
•

The ST/STOP bit for each channel will be
reset to STOP:

•

Any transfer in progress will be aborted.

DMA Acknowledge
The 80186,188 generates no explicit DMA acknowledge signal. Instead, the 80186,188 perform a read
or write directly, to the ,'DMA requesting device.
However, if required, a DMA signal can begenerah
edby a decode of an address. Also, since the chipselect lines can be programmed, to be active for a
given block of memory or I/O space, and the DMA
pointers can be programmed to point to the same
given block, a chip-select line could be used to indi"
cafe a DMA acknowledge.

TIMER UNIT
The 80186,188 include an'integrated timer unit
which provides three i6'-bit timer/counters (see
Figure 5-10. These tfIners operate independently of
the CPU: Two of the timers have input and output
pins allowing counting of external events and generationof arbitrary waveforms. The third timer is ·not
connected to any external pins and is useful for realtime coding and time delay applications. In addition,
it can be used asa)prescaler for the other two, or as a
DMA request source.

DMA Priority
The channels may be programmed such that one
channel is always given priority' over the other, or
they may be programmed to, aiternate. cycles when
both channels have DMA requests pending. DMA
cycles always have priority over internal CPU cycles
'except between locked memory accesses or word accessesto'odd memory locations. An external bus
hold, however, takes priority' over an internal DMA

the timers are controlled by eleven 16-bit registers
located in the internal peripheral control block.
Timers 0 and 1 are controlled by four registers each;
timer 3 makes use of three registers. The configura" tion ofthese registers in the peripheral control block
,is shown in Table 5-11.

5-16

210911

I

iAPX 186,188 HARDWARE DESIGN OVERVIEW

OMA
REO.

T2
INT.
REO.

TIMER 0
TIMER 2

t-::~='=:'!':":":-::f

CLOCK

MAX COUNT YAWE

B

MAX COUNT YAWE

MODE/CONTROL
WORD

INTERNAL ADDRESS/DATA BUS
ALL 18 BIT REGISTERS

Figure 5-11 Timer Block Diagram

Table 5-11 Timer Control Block Format
ReglBter Offset
Register Name
Mode/Control Word
Max Count B
Max Count A
Count Register

Tmr.O Tmr.1
56H
54H
52H
50H

5EH
5CH
5AH
58H

Tmr.2
66H
not present,
62H
60H

The count register contains the current value of the
timer and can be read or written whether the timer
is running or not. The value of this register will be incremented for each timer event. The MAX COUNT
register defines the maximum count the timer will
reach. Timers 0 and 1 are equipped with a second
MAX COUNT register, which enables them to alternate their count between two different MAX
COUNT values programmed by the user. The
mode/control register is used for programming the
timer's specific mode of operation: These registers
are discussed in detail in the following three sections.

Count Registers
Each of the three timers has a 16-bit count register.
The current contents of this register may be read or
written by the processor at any time. If the register is

written into while the timer is counting, the new
value will take effect in the current count cycle.
Because the count register is 16 bits wide, up to 216
timer events can be counted by a single
timer/counter. Every fourth CPU clock transition
can act as a timer event. In addition, transitions on
the external lines of timers 0 and 1 can act as timer
events for these timers, and timer 2 can be set to
produce interrupts that serve as timer events for
timers 0 and 1.

Max Count Registers
Timers 0 and 1 have two MAX COUNT registers,
while timer 2 has a single MAX COUNT register.
These contain the number of events the timer will
count.
After reaching the MAX COUNT register value, the
timer count value will reset to zero during the same
clock cycle, i.e., the maximum count value is never
stored in' ~he count register itself. Each timer ,can
generate an interrupt whenever the timer count
value reaches a maximum count value, that is, an interrupt can be generated whenever the value in
maximum count register A is reached, and whenever the value in maximum count register B is
5-17

210911

/

iAPX 186,188 HARDWARE DESIGN OVERVIEW

associated timer to run continuously. The EXT bit
selects between internal and external clocking for
the timer. The P bit is used to let timer 2 serve as a
clock for another timer. The RTG bit determines
the control function provided by an external input
pin. The EN bit provides control over the
RUN/HALT status. The INH bit allows for selective
updating of the EN bit. The INT bit enables interrupts from the timer. The MC bit is set whenever
the timer reaches its final maximum count value.
The RIU bit indicates which MAX COUNT bit is
currently being used. Not all mode bits are provided
for timer 2; the following bits are hardwired: ALT,
EXT, P, RTG and IRU are all set to O.

reached. If a timer generates a second interrupt request before the first interrupt request has been
serviced, the first interrupt request to the CPU will
be lost.
In timers 0 and 1, the MAX COUNT register used
can alternate between the two max count values
whenever the current maximum count is reached.
The timer is reset when the current count value
equals the max count being used. This means that if
the count is changed to be above the max count
value, or if the max count value is changed to be
below the current value, the timer will not reset to
zero, but rather will count to its maximum value,
"wrap around'" to zero, then count until the max
count is reached.

5.10 INTERRUPT CONTROLLER
The iAPX 186,188 integrated interrupt controllers
perform tasks of the interrupt controller in a typical
system. These include synchronization of interrupt
requests, prioritization of interrupt requests, and request type vectoring in response to a CPU interrupt
acknowledge. Nesting is provided so interrupt service routines for lower priority interrupts may themselves be interrupt by higher priority interrupts. The
integrated interrupt controller block diagram is
shown in Figure 5-13.

Timer Mode/Control Register
The mode/control register allows the user to program the specific mode of operation or check the
current programmed status of any of the three integrated timers. Figure 5-12 shows the bits in this
register and describes the function of each bit.
The ALT bit selects one of the two MAX COUNT
registers for comparisons. The CONT bit causes the

15

14

EN IINH

13

12

INT I RIU I

11

5

0

I··· ·1 MC I RTG I

ALT: .
The ALT bit determines which of two MAX COUNT registers is used for count comparison. If ALT = 0, register A
for that timer is always used, while if ALT = 1, the comparison will alternate between register A and register B
when each maximum count is reached. This alternation
allows the user to change one MAX COUNT register
l.i(hile the other is being used, and thus provides a
method of generating non-repetitive waveforms. Square

2
P

1

0

I EXT I ALT ICONTI

waves and pulse outputs of any duty cycle are a subset
of available signals obtained by not changing the final
count registers. The ALT bit also determines the function of the timer output pin. If ALT is zero, the output pin
will go LOW for one clock, the clock after the maximum
count is reached. If ALT is one, the output pin will reflect
the current MAX COUNT register being used (Oil for
B/A).

Figure 5-12 Timer Mode/Control Register
5-18

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

CONT:
Setting the CONT bit causes the associated timer to run
continuously, while resetting it causes the timer to halt
upon maximum count. If CONT = 0 and ALT = I, the
timer will count to the MAX COUNT register A value,
reset, count to the register B value, reset, and halt.
EXT:
The external bit selects between internal and external
clocking for the timer. The external signal may be
asynchronous with respect to the 80186 clock. If this
bit is set the timer will count LOW-to-HIGH transitions
for the input pin. If cleared, it will count an internal clock
while using the input pin for control. In this mode, the
function of the external pin is defined by the RTF bit.
The maximum input to output transition latency time
may be as much as 6 clocks. However, clock inputs may
be pipelined as closely together as every 4 clocks without losing clock pulses.

P:
The prescaler bit is ignored unless internal clocking
has been selected (EXT = 0). If the P bit is a zero, the
timer will count at one-fourth the internal CPU clock
rate. If the P bit is a one, the output of timer 2 will be
used as a clock for the timer. Note that the user must initialize and start timer 2 to obtain the prescaled clock.
RTG:
Retrigger bit is only active for internal clocking (EXT =
0). In this case it determines the control function provided by the input pin.
If RTG = 0, the input level gates the internal clock on
and off. If the input pin is HIGH, the timer will count; if
the input pin is LOW, the timer will hold its value. As indicated previously, the input signal may be asynchronous with respect to the 80186 clock.

INT:
When set, the INT bit enables interrupts from the timer,
which will be generated on every terminal count. If the
timer is configured in dual MAX COUNT register mode,
an interrupt will be generated each time the value in
MAX COUNT register A is reached', and each time the
value in MAX COUNT register B is reached. If this
enable bit is cleared after the interrupt request has
been generated, but before a pending interrupt is
serviced, the interrupt request will still be in force. (The
request is latched in the interrupt Controller.)
MC:
The Maximum Count is set whenever the timer reaches
its final maximum count value. If the timer is configured
in dual MAX COUNT register mode, this bit will be set
each time the value in MAX COUNT register A is
reached, and each time the value in MAX COUNT register B is reached. This bit is set regardless of the timer's
interrupt-enable bit. The MC bit gives the user the ability
to monitor timer status through software instead of
through interrupts. Programmer intervention is required
to clear th is bit.
RIU:
The Register in Use bit indicates which MAX COUNT
register is currently being used for comparison to the
timer count value. A zero value indicates register A. The
RIU bit cannot be written, i.e., its value is not affected
when the control register is written. It is always cleared
when the ALT bit is zero.
Not all model bits are provided for timer 2. Certain bits
are hardwired as indicated below:
ALT

= 0, EXT = 0, P = 0, RTG = 0, RIU = 0

When RTG = I, the input pin detects LOW-to-HIGH
transitions. The first such transition starts the timer
running, clearing the timer value to zero on the first
clock and then incrementing thereafter. Further transitions on the input pin will again reset the timer to zero,
from which it will start counting up again. If CO NT = 0
when the timer has reached maximum count, the EN bit
will be cleared, inhibiting further timer activity.
EN:
The enable bit provides programmer control over the
timer's RUN/HALT status. When set, the timer is
enabled to increment subject to the input pin constraints in the internal clock mode (discussed
previously). When cleared, the timer will be inhibited
from counting. All input pin transitions during the time
EN is zero will be ignored. If CO NT as zero, the EN bit is
automatically cleared upon maximum count.
INH:
The inhibit bit allows for selective updating of the
enable (EN) bit. If INH is a one during the write to the
mode/control word, then the state of the EN bit will be
modified by the write. If INHis a zero diring the write, the
EN bit will be unaffected by the operation. This bit is not
stored; it will always be a 0 on a read.

Figure 5-12 Timer Mode/Control Register (continued)

5-19

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

TIMER TIMER TIMER

o

1

2

DMAO
CONTROL REG.
DMA1
CONTROL REG.
EXT. INPUT 0
CONTROL REG.
EXT. INPUT 1
CONTROL REG.

DMA
1

INTO

INT1

INT2

INT3

NMI

INTERRUPT
REQUEST REG.
INTERRUPT
MASK REG.

INTERRUPT
PRIORITY
RESOLVER

IN-8ERVICE
REG.
PRIOR. LEY.
MASK REG.
INTERRUPT
STATUS REG.

Figure 5-13 Interrupt Controller Block Diagram

The 80186,188 can receive interrupts from a
number of sources, both internal and external. Internal interrupt sources (timers and DMA channels)
can be disabled by their own control registers or by
mask bits within the interrupt controller. The
80186,188 interrupt controller has its own control
registers that set the mode of operation for the
controller.
The interrupt controller operates in two major
modes: non-iRMX 86 mode (also called master
mode) and iRMX 86 mode. In master mode, the
integrated controller acts as the master interrupt controller for the system; in iRMX 86 mode, the controller operates as a slave to an external interrupt
controller which functions as the master interrupt
controller for the system. Some of the interrupt controller registers and interrupt controller pins change
definition between these two modes, but the basic
function of the interrupt controller remains fundamentally the same.

Non-iRMX Mode
In non-iRMX (master) mode, the interrupt controller presents its interrupt input directly to the
80186,188 CPU. Five pins are provided for external
interrupt sources. One of these pins is dedicated to
NMI. The other four (INTO-INT3) may be configured in three ways: as four interrupt input lines
with internally generated interrupt vectors; as an interrupt line and an interrupt acknowledge line
(called the "cascade mode") along with two other
input lines with internally generated interrupt
5-20

vectors; or as two interrupt input lines and two
dedicated interrupt acknowledge output lines. These
four interrupt inputs can be programmed in either
edge- or level-trigger mode, as specified by the LTM
bit in the source's control register.
The interrupt controller will generate interrupt vectors for the integrated DMA channels and the integrated timers. In addition, interrupt vectors for the
external interrupt lines will be generated if they are
not configured in cascade or special fully nested
mode (see below).

Each interrupt source has a pre-assigned vector type
(see Table 5-2). Vector types point to address information for interrupt service routines. The vectors
generated are fixed and cannot be changed.
The user can program the interrupt sources into any
of eight different priority levels. Programming is
done by placing a 3-bit priority level (0-7) in the control register of each interrupt source. (A source with
a priority level of 4 has higher priority over all priority levels from 5 to 7. Priority registers containing
values lower than 4 have greater priority.) All interrupt sources have preprogrammed default priority
levels.
If two requests with the same programmed priority
level are pending at once, the priority ordering
scheme shown in Table 5-2 is used. If the serviced interrupt routine reenables interrupts, it allows other
requests to be serviced.
210911

IAPX 186,188 HARDWARE DESIGN OVERVIEW

The interrupt controller has three basic modes of operation when it is configured in the non-iRMX
mode: fully nested mode, cascade mode and special
fully nested mode. The response to internal interrupts is identical in all three modes; the function of
the four external interrupt pins differs in each mode.
The interrupt controller is set into one of these
modes by programming the correct bits in the INTO
and INTI control registers (see below).
FULLY NESTED MODE

In the fully nested mode, INTO-INT3 are used as
direct interrupt requests. The vectors for these four
inputs are generated internally. An in-service (IS)
bit is provided for every interrupt source. Setting
this bit prevents the interrupt controller from
generating interrupt requests from lower-priority
devices, as well as from the interrupt source currently being serviced. This allows interrupt service
routines to operate with interrupts enabled (thus
insuring that higher-priority interrupts will be
serviced) without being interrupted by lower-priority
interrupts.
When a service routine has completed, the proper IS
bit must be reset by writing the proper pattern to the
EOI register. This is required to allow subsequent interrupts from this interrupt source, and to allow servicing of lower-priority interrupts. An EOI command

is issued at the end of the service routine just before
the execution of the return from interrupt
instruction. If the fully nested structure has been
upheld, the next highest-priority source with its IS
bit set is then serviced.
CASCADE MODE

In the cascade mode, INTO-INT3 are configured
into interrupt input-dedicated acknowledge signal
pairs. The interconnection is shown in Figure 5-14.
INTO is an interrupt input interfaced to an 8259A;
INT2IINTAO serves as the dedicated interrupt acknowledge signal to that peripheral. The same is true
for INTI and INT3/INTAl. Each pair can selectively
be placed in the cascade or non-cascade mode by programming the proper value in the INTO and INTI
control registers. The use of the dedicated acknowledge signal eliminates the need for external logic to
generate INT A and device select signals.
The primary cascade mode allows the capability to
serve up to 128 external interrupt sources through
the use of external master and slave 8259As. Three
levels of priority are created, requiring priority resolution in the 80186,188 interrupt controller, the
master 8259A, and the slave 8259As. If an external
interrupt is serviced, one IS bit is set at each of these
levels. When the interrupt service routine is
completed, up to three end-of-interrupt commands
must be issued by the programmer.

80188

IRTiI

INT
8259A
PIC

IRTA

IRTA1I

Figure 5-14 Cascade Mode Interrupt Connection
5-21

210911

I

iAPX 186,188 HARDWARE DESIGN OVERVIEW

SPECIAL FULLY NESTED MODE

The special fully nested mode is entered by setting
the SFNM bit in the INTO or INTl control register.
This mode enables complete nestability with external
8259A masters. Normally, an interrupt request from
an interrupt source will not be recognized unless the
in-service bit for that source is reset. If more than
one interrupt source is connected to an external interruptcontroller, all of the interrupts will be channelled through the same 80186,188 interrupt request
pin. As a result, if the external interrupt controller
receives a higher-priority interrupt, its interrupt will
not be recognized by the 80186,188 controller until
the 80186,188 in-service bit is reset. In special fully
nested mode, the 80186,188 interrupt controller will
allow interrupts from an external pin regardless of
the state of the in-service bit for an interrupt source
in order to allow multiple interrupts from a single
pin. An in-service bit will continue to be set,
however, to inhibit interrupts from other lowerpriority 80186,188 interrupt sources.

interrupt service routine is completed. The EOI command is issued by writing the proper pattern to the
EO! register. There are two types of EO! commands:
specific and nonspecific. The nonspecific command
does not specify which IS bit is reset. When issued,
the interrupt controller automatically resets the IS
bit of the highest priority source with an active service routine. A specific EOI command requires that
the programmer send the interrupt vector type to
the interrupt controller indicating which source's IS
bit is to be reset. This command is used when the
fully nested structure has been disturbed or the highest priority IS bit that was set does not belong to the
service routine in progress.

Special procedures should be followed when resetting IS bits at the end of interrupt service routines.
Software polling of the external master's IS register
is required to determine if there is more than one bit
set. If so, the IS bit in the 80186,188 remains active
and the next interrupt service routine is entered.

OPERATION IN A POLLED ENVIRONMENT

All three modes may be used in a polled
environment. When polling, the processor disables
interrupts and then polls the interrupt controller
whenever it is convenient. Polling the interrupt controller is accomplished by reading the poll register
(see Figure 5-16). Bit 15 in the poll register indicates
to the processor that an interrupt of higher priority is
requesting service. Bits 0-4 indicate the type vector
of the highest-priority source to be set.
It is often useful to be able to read the poll register

information without guaranteeing service of any
pending interrupts, i.e., without setting the indicated
in-service bit. The poll status word is provided for
this purpose. Poll register information is duplicated
in the poll status word, but reading the poll status
word does not set the associated in-service bit.
These words are located in two adjacent memory locations in the interrupt controller register file.
END-OF-INTERRUPT COMMAND

The end-of-interrupt (EO!) command is used by the
programmer to reset the In-Service (IS) bit when an
5-22.

iRMX 86 Compatability Mode
The iAPX 186,88 integrated interrupt controllers
have a special iRMX 86 compatability mode that
allows the use of the 80186,188 within the iRMX 86
operating system interrupt structure. The controller
is set in this mode by setting bit 14 in the peripheral
Gontrol block relocation· register and providing speciid initialization software.
.
When iRMX mode is used, the internal 80186,188
interrupt controller will be used as a slave controller
to an external master interrupt controller. The internal 80186,188 resources will be monitored through
the internal interrupt controller, while the external
controller functions· as the system master interrupt
controller.
Because of pin limitations caused by the need to interface to an external 8259A master, the internal interrupt controller will no longer accept external
inputs. There are, however, enough 80186,188 interrupt controller inputs (internally) to dedicate one to
each timer. In this mode, each timer interrupt
source has its own mask bit, IS bit, and control word.
The iRMX 86 operating system requires peripherals
to be assigned fixed priority levels. This is incompatible with the normal operation of the 80186,188 interrupt controller. Thus, the initialization software
must program the proper priority levels for each
source. The required priority levels for the internal
interrupt sources in iRMX mode are shown in Table
5-12. These priority level assignments must remain
fixed in the iRMX mode of operation.

Table 5-12 Internal Source Priority Level
Priority Level
0
1
2
3
4
5

j

Interrupt Source
Timer 0
(reserved)
DMAO
DMA 1
Timer 1
Timer 2

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

SPECIFIC END-OF-INTERRUPT

The iRMX 86 mode of operation allows nesting of
interrupt requests. When an interrupt is acknowledged, the priority logic masks off all priority levels
except those with equal or higher priority.

In iRMX 86 mode, the specific EOI command operates to reset an in-service bit of a specific priority.
The user supplies a 3-bit priority level value that
points to an in-service bit to be reset. The command
is executed by writing the correct value in the specific
EO! register at offset 22H.

The configuration of the 80186,188 with respect to
an external 8259A master is shown in Figure 5-15.
The INTO input is used as the 80186 CPU interrupt
input. INT3 functions as an output to send the 80186
slave-interrupt-requests to one of the 8 masterPIC-inputs.

Interrupt Controller Registers

For information on external interfacing in iRMX 86
mode, see Volume 2.

VECTOR GENERATION IN THE iRMX 86 MODE

The interrupt controller has a number of registers
which are .used to control its operation. These registers have been referred to in the preceding discussion of the interrupt controller's various operations;
in the following sections they are individually
discussed.

Vector generation in iRMX 86 mode is exactly like
that of an 8259A slave: the interrupt controller
generates an 8-bit vector which the CPU multiplies
by four and uses as an address into a vector table.
The five most significant bits of the vector are programmed by writing to the Interrupt Vector register
at offset 20H. The lower-order three bits are generated by the priority logic and represent the encoding of
the priority level requesting service.

The interrupt controller register model is shown in
Figure 5-16. It contains 15 registers, all of which can
be read or written unless otherwise specified. Some
of these registers have a different function depending
on the processor's operating mode (master or iRMX
86). The interrupt controller registers for both
modes will be discussed together; differences in
function and implementation in the two modes will
be indicated where appropriate.

8259A
MASTER
INTA

80186 INT. IN

<==

REOUESTSFROM

IRO

INT

OTHER SLAVES

1

-

IR7
CA60-2

80186

~

INTO
SLAV!! !li!Li!CT

lim
INT2
INT3

-

I
I

")

CASCADE
ADDRESS DECODER

80186 SLAVE INTERRUPT OUTPUT

Figure 5-15 iRMX 86 Interrupt Controller Interconnection
5-23

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

OFFSET
INT3 CONTROL REGISTER

3EH

INn CONTROL REGISTER

3CH

INTl CONTROL REGISTER

3AH

INTO CONTROL REGISTER

38H

DMA 1 CONTROL REGISTER

OFFSET
LEVEL 5 CONTROL REGISTER
(TIMER 2)

3AH

LEVEL 4 CONTROL REGISTER
(TIMER 1)

38H

LEVEL 3 CONTROL REGISTER
(OMA 1)

38H

38H

LEVEL 2 CONTROL REGISTER
(OMAO)

34H

OMA 0 CONTROL REGISTER

34H

LEVEL 0 CONTROL REGISTER
(TIMER 0)

32H

TIMER CONTROL REGISTER

32H

INTERRUPT·REQUEST REGISTER

2EH

INTERRUPT CONTROLLER STATUS REGISTER

30H

IN-SERVICE REGISTER

2CH

INTERRUPT REOUEST REGISTER

2EH

PRIORITY·LEVEL MASK REGISTER

2AH

IN-SERVICE REGISTER

2CH

MASK REGISTER

28H

PRIORITY MASK REGISTER

2AH
SPECIFIC EOI REGISTER

22H

MASK REGISTER

28H
INTERRUPT VECTOR REGISTER

20H

POLL STATUS REGISTER

28H

POLL REGISTER

24H

EOI REGISTER

22H

Non-iRMX 86 Mode

iRMX 86 Mode
Figure 5-16 Interrupt Controller Registers

CONTROL REGISTERS

The interrupt controller includes seven control
registers, one for each interrupt source (see Figure
5-17). In master mode, four of these (INTO-INTJ)
serve the external interrupt inputs, one is provided
for each of the two D MA channels, and one register
is used for the collective timer interrupts. In noniRMX 86 mode, the control registers for INT2 and
INT3 are not used, registers INTO and INTI are
used for timer 1 and timer 2 respectively, and the
DMA 0 and DMA 1 registers are used for internal
interrupt sources.

These registers contain three bits (PRO, PRI and
PR2), which select one of eight different priority
'levels for the interrupt device (0 is highest priority, 7
is lowest p'riority), and a mask (MSK) bit to enable

the interrupt. When the mask bit is zero, the interrupt is enabled; when it is set, the interrupt is
masked. The MSK bits in the individual control
registers are exactly the same bits as those in the
mask register, so that modifying these bits in the individual control register will also modify them in the
mask register, and vice versa.

INTERRUPT REQUEST REGISTER

The interrupt request register contains bits which
are automatically set when internal or external
(master mode only) interrupt requests are pending.
The format of this register is shown in Figure 5-18.
Whenever an interrupt request is made by the inter·
rupt source associated with a specific control
register, the bit in the interrupt request register is
set, whether or not the interrupt is enabled or is of
sufficient priority to cause an interrupt.
5-24

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

"

"

a'/

!

15

14

o

0

4

3

2

1

0

2

1

0

I

Timer/DMA Control Registers (Non-iRMX Mode)

15

14

o

0

6

o

ISFNMI

4

c

3

I LTM I MSK I PR2 I PRl I PRO I
"

INTO/INT1 Control Registers (Non-iRMX Mode)

15

14

o

0

4

o

3

2

I LTM I MSKI

0

1

PR21 PRll PRO

I

INT2/INT3 Control Registers (Non-iRMX Mode)

15

14

13

3

2

1

0

Control Word (iRMX 86 Mode)

PRO-2:

Priority programming information. Highest
Priority = 000, Lowest Priority = 111

LTM:

Level-trigger mode bit. 1 = level triggered;
o = edge-triggered. Interrupt input levels
are active high. In level-triggered mode, an
interrupt is generated whenever the external
line is high. In edge-triggered mode, an interrupt will be generated only when this
level is preceded by an inactive-to-active
transition on the line. In both cases, the
level must remain active until the interrupt
is acknowledged.

= mask; 0 = non mask.

MSK:

Mask bit, 1

C:

Cascade mode bit, 1 = cascade; 0

SFNM:

Special fully nested mode bit, 1 = SFNM

=

direct

Figure 5-17 Control Register Format

5-25

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

15
0

14

I

I

0

10

9

0

0

0

I

13

0

11

12

DO

01

10

I I I
0

TMR

Non-iRMX 86 Mode
15

14

I I I
0

8

13

0

0

I

0

7

6

0

0

I I I

5

4

TMR21 TMR1

I

0

2
01

DO

0

!T~

iRMX 86 Mode

Figure 5-18 In-Service, Interrupt Request and Mask Register Format

DO and D I are the interrupt request bits for the
DMA channels; the TMR bit is the logical OR of all
timer interrupt requests. These bits can be both read
and written, while the bits associated with the external interrupt pins (master mode only) can be read
but not written (since values written to them are not
stored).
The external interrupt request bits show exactly
when an interrupt request is given to the interrupt
controller, so that if edge-triggered mode is selected,
the bit in the register will be HIGH only after an
inactive-to-active transition. For internal interrupt
sources, the register bits are set when a request arrives and are reset when the processor acknowledges
the requests.
MASK REGISTER

The mask register contains a mask bit for each interrupt source. When the bit in this register corresponding to a particular interrupt source is set, all
interrupts from that' source will be masked. These
mask bits are exactly the same bits which are used in
the individual control registers; thus, changing the
state of a mask bit in this register will also change the
state of the mask bit in the individual interrupt control register corresponding to the bit, and vice versa.
The format for this register is shown in Figure 5-18.
PRIORITY MASK REGISTER

This register allows masking of all interrupts below a
particular interrupt priority level. The format of this
register is shown in Figure 5-19. The code in the
lower three bits indicate the priority of the current
interrupt being serviced. Wheh an interrupt is

acknowledged, either by the processor running the
interrupt acknowledge or by the processor reading
the interrupt poll register (see beloW), these bits are
automatically set to the priority of the device whose
interrupt is being acknowledged. This prevents any
interrupts of lower priority (as set by the priority bits
in the interrupt control registers for interrupt
sources) from interrupting the processor. Thus, the
contents of this register indicates the lowest prioritylevel interrupt which will be serviced. For example,
100 written into this register masks interrupts of
level five (101), six (110), and seven (I I 1). The
register is reset to seven (I I 1) upon RESET, i.e., interrupts of all priority levels are enabled .
IN-SERVICE REGISTER

This register contain's In-Service (IS) bits for each interrupt source, indicating that its service routine is in
progress (see Figure 5-18). When an IS bit is set, no
interrupts will be generated from devices with a
lower priority level.
In iRMX 86 mode, bit positions 0, 4, and 5 correspond to the integral timers. In master mode, a
single TMR bit is the IS bit for all three timers, and
1O-I3 are the IS bits for the external interrupt pins.
DO and DI are the IS bits for the two DMA channels
in both modes.
The IS bit is set when the processor acknowledges an
interrupt request (either by an interrupt acknowledge or by reading the poll register). The IS bit is
reset at the end of the interrupt service routine by an
EIO command issued by the CPU. This register may
be both read and written, i.e., the CPU may set inservice bits without an interrupt ever occurring, or
may reset them without using the EOI function of
the interrupt controller.
5-26

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

"acknowledge" the interrupt (i.e., the in-service bit
and priority level mask register bits will be set).

POLL AND POLL STATUS REGISTERS
(MASTER MODE ONLY)

The interrupt controller contains a poll register and a
poll status register, both of which contain the same
polling information. The format of this register is
shown in Figure 5-20.

EOI REGISTER

The end of interrupt register is used by the programmer to issue an End Of Interrupt command to the
controller. After receiving this command, the interrupt controller automatically resets the in-service bit
for the interrupt (indicating its service routine has
completed) and the oriority mask register bits. Only
the specific form of the EOI command is supported
in iRMX 86 mode.

The INTREQ bit indicates an interrupt is pending
and is set when an interrupt of sufficient priority has
been received. It is automatically cleared when the
interrupt is acknowledged. When an interrupt is
pending, bits SO-S4 indicates the vector type of the
highest priority interrupt pending.
Reading the poll register will acknowledge the pending interrupt to the interrupt controller, just as if the
processor had acknowledged the interrupt through
interrupt acknowledge cycles. The processor will not
actually run any interrupt acknowledge cycles, and
will not vector through a location in the interrupt
vector table. Only the interrupt request, in-service
and priority mask registers in the interrupt controller
will be set appropriately.

This register is write only; data written is not stored
and cannot be read back. The format of this register
is shown in Figure 5-21.
INTERRUPT STATUS REGISTER

This register contains general interrupt controller
status information. All the significant bits in this
register are read/write. The format of this register is
shown in Figure 5-22.

Reading the poll status register, on the other hand,
will merely transmit the status of the polling bits
without modifying any of the other interrupt controller registers. Both registers are read only; data written to them is not stored.

Three bits (JRTO-IRT2) are used to differentiate
among the three timer interrupts. This is required in
master mode because the timers share a single interrupt control register. The bit associated with a timer
is automatically cleared after the interrupt request
for the timer is acknowledged. More than one of
these bits may be set at a lime.

Though these registers are not supported in iRMX
86 mode, accessing the poll register location when in
iRMX 86 mode will cause the interrupt controller to

15
i

I

0

14

i

I

0

13

I

i

I

I

0

I

0

I

7
0

I

I

It,
0

\

0

\

0

10m2

ml

mO

Non-iRMX Mode
14

15
0

!

0

2

1

0

!PRM2! PRMll PRMO I

!
iRMX 86 Mode

Figure 5-19 Priority Level Mask Register Format

15

14

13

Figure 5-20 Poll Register Format

5-27

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

Non-iRMX Mode
15

14

13

8

5

I I I I I
0

0

0

.0

o

0

I

L2

Ll

LO

iRMX 86 Mode

Figure 5-21 EOI Register Format

I

I

0

0

o

I

2
0

1

0

IIRT2 I IRn I IRTO

I

Figure 5-22 Interrupt Status Register Format

Interrupt Controller and Reset

The DHLT (DMA Halt Transfer) bit insures
prompt servicing of non-maskable interrupts by halting all DMA transfers. It is automatically set whenever a non-maskable interrupt occurs, and is reset
when an IRET instruction is executed. This bit may
also be set explicitly by the programmer. It is never
automatically cleared (except by RESET), so that if
DMA activity is desired, the programmer must clear
this bit after each NMI is received.

Upon RESET, the interrupt controller will perform
the following actions:
•

All SFNM bits reset to 0, implying fully
nested mode.

•

All PR bits in the various control registers set
to 1. This places all sources at lowest priority
(Jevelll 1) .

•

All LTM bits reset to 0, resulting in edge-sense
mode.

•

All Interrupt Service bits reset to O.

•

All Interrupt Request bits reset to 0:

•

All MSK (Interrupt Mask) bits set to 1 (mask).

•

AllC (Cascade) bits reset toO (non-cascade).

•

All PRM (Priority Mask) bits set to 1, implying
no levels masked.

•

Initialized to non-iRMX 86 mode.

INTERRUPT VECTOR REGISTER
(iRMX 86 MODE ONLY)

The interrupt vector register is is used to specify the
5 most significant bits of the interrupt type vector
placed on the CPU bus in response to an interrupt
acknowledgement. The interrupt controller itself
provides the lower three bits of the interrupt vector
as determined by the priority level of the interrupt
request. The lower 3 significant bits of the interrupt
type are determined by the priority level of the
device causing the interrupt. The format of this register is shown in Figure 5-23.
Figures 5-24 and 5-25 summarize the methods of interaction among the various interrupt controller
registers.

I

15

14

13

0

0

0

I

8

I I
0

14

Figure 5-23 InterruptVector Register Format
5-28

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

PRESENT
INTERRUPT
REQUEST TO
EXTERNAL
CONTROLLER

Figure 5-24 80186 Interrupt Request Sequencing

5-29

210911

iAPX 186,188 HARDWARE DESIGN OVERVIEW

INTERRUPT
ACKNOWLEDGE

WAIT FOR NEXT
INTERRUPT
ACKNOWLEDGE

.----P-L-A-C-E----.8)
GENERATE
INTERRUPT TYPE
GENERATE INTA
CYCLES
FOR EXTERNAL
INTERRUPT
CONTROLLER

@YES

INTERRUPT TYPE
ON BUS DURING
SECOND INTA
CYCLE

NO

SET IN-SERVICE
& PRIORITY
MASK REGISTER
BITS

SET IN-SERVICE
& PRIORITY
MASK REGISTER
BITS
PROVIDE
HIGHEST
PRIORITY
INTERRUPT
VECTOR ON
INTERNAL BUS

SET IN-SERVICE
& PRIORITY
MASK REGISTER
BITS

CD Before actual interrupt acknowledge is run by CPU.
@Two interrupt acknowledge cycles will be run; the interrupt type is read by the CPU on the second cycle.

® Interrupt acknowledge cycles will not be run. The interrupt vector address is placed on an internal bus
and is not available outside the processor.
8)

Interrupt type is not driven on bus iRMX86 mode.

Figure 5-25 80186 Interrupt Acknowledge Sequencing
5-30

210911

I
61

~1!@tMIMm:

The 8087 NumeriC?
Processor Extension

1
I

CHAPTER 6
THE 8087 NUMERIC PROCESSOR EXTENSION
The 8087 adds extensive high-speed numeric processing capabilities to an 8086,88- or 80186,188-based
system. It is specifically designed to deliver stable,
correct results when used in a straightforward fashion by programmers who are not expert in numerical
analysis. Its applicability to accounting and financial
environments, in addition to scientific and engineering settings, further distinguishes the 8087 from the
"floating point accelerators" employed in many
computer systems, including minicomputers and
mainframes. The NPX is housed in a standard
40-pin dual in-line package (Figure 6-1) and requires
a single + 5V power source.

6.1 INTRODUCTION
This chapter describes the 8087 Numeric Processor
Extension (NPX). It is divided into the following
sections:
•

Processor Overview

•

Processor Architecture

•

Computation Fundamentals

•

Instruction Set

•

Programming Facilities

•

Spe.cial Features

•

Programming Examples
Vss

The processor overview section covers both hardware and .software topics at a general level. Special
Features describes those features of the NPX that
will be of interest to specialized groups of users; it is
not necessary to understand this section to successfully use the 8087 in most applications. Hardware
coverage in this chapter is limited to discussing processor facilities in functionaiterms. Timing, electrical
characteristics, and other physical interface data may
be found in Volume 2 of this set.
Note that throughout this chapter the term "CPU"
refers to either an 8086,88 configured in maximum
mode, or an 80186,188. To make best use of the
material in this chapter readers should have a good
understanding of the operation of the 8086,88 and
80186,188 CPUs.

vee

A14!014

A15/015

A1J/D13

A16/S3

A12/012

A17/S4

A11/Dl1

A18/55

A1O/01O

A19/S6

A9/D9

IfHE/S7

AS/OS

RQ/GTl

AlID7

INT

AS/OS

ROtGTO

AS/DS

Ne

A4/D4

Ne

A3(D3

S:i

A2I02

51

A11D1

So

M/oa

aso

NC

051

Ne

BUSY

eLK

READY

V55

RESET

NC '" NO CONNECT

6.2 PROCESSOR OVERVIEW
The 8087 Numeric Processor Extension (NPX) performs arithmetic and comparison operations on a
variety of numeric data types; it also executes
numerous built-in transcendental functions (e.g.,
tangent and log functions). As a processor extension
to a maximum mode 8086,88, or an 80186,188, the
NPX effectively extends the register and instruction
sets of the host CPU and adds several new data types
as well. The programmer generally does not perceive
the 8087 as a separate device; instead, the computational capabilities of the CPU appear greatly
expanded.

Figure 6-1 8087 Numeric Data
Processor Pin Diagram

The description of the 8087 in this section deliberately omits some operating details in order to provide a
coherent overall view of the processor's capabilities.
Subsequent sections of the chapter will describe
these capabilities, and others, in more detail.
6-1

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

this standard format. FPAL is a set of subroutines
for the 8080/S0S5 microprocessors. These routines
perform arithmetic and limited standard functions
on single precision (32-bit) real numbers; an FPAL
multiply executes in about loS ms (l.6MHz. 80S0A
CPU). The next product, the iSBC™ 310 High
Speed Math Unit, essentially implements FPAL in a
single iSBC card, reducing a single-precision multiply
to about 100/Ls. The Intel S232 is a single-chip arithmetic processor for the SOSO/S085 family. The 8232
accepts double precision (64-bit) qperands as well as
single precision numbers. It performs a single precision multiply in about 100/Ls and multiplies double
precision numbers in about S75/Ls (2 MHz version).

Evolution
The performance of first- and second-generation
microprocessor-based systems was limited in three
principal areas: storage capacity, input/output speed,
and numeric computation. The 8086,88 CPU broke
the 64K memory barrier, allowing larger and more
time-critical applications to be undertaken. The 8089
Input/Output Processor eliminated many of the I/O
bottlenecks and permitted microprocessors to be
employed effectively in I/O-intensive designs. The
8087 Numeric Processor Extension clears the third
roadblock by enabling applications with significant
computational requirements to be implemented
with microprocessor technology.
Figure 6-2 illustrates the progression of Intel numeric products and events that have led to the development of the 8087. In the mid-1970's, Intel made
the commitment to expand the computational capabilities of microprocessors from addition and
subtraction of integers to an array of widely useful
operations on real numbers. (Real numbers encompass integers, fractions, and irrational numbers such
as 11" and ID In 1977, the corporation adopted a
standard for representing real numbers in a
"floating point" format. Intel's Floating Point Arithmetic Library (FPAL) was the first product to utilize

In 1979, a working committee of the Institute· for
Electrical and Electronic Engineers (IEEE) proposed
an industry standard for minicomputer and microcomputer floating point arithmetic (J. Coonen, W.
Kahan, J. Palmer, T. Pittman, D. Stevenson, "A
Proposed Standard for Binary Floating Point
Arithmetic," ACM SIGNUM Newsletter, October
1979). The intent of the standard is to promote
portability of numeric programs between computers
and to provide a uniform programming environment
that encourages the development of accurate, reliable software. The proposed startdardspecifies reqUirements and options for number formats as well
as the results of computations on these numbers.
The floating point number formats are identical to
those previously adopted by Intel and used in the
products described in this section.
The SOS7 Numeric Processor Extension is the most
advanced development in Intel's continuing effort
to provide improved tools for numerically-oriented
microprocessor applications. It is a single-chip hardware implementation of the proposed IEEE
standard, including all its options for single and
double precision numbers. As such, it is compatible
with previous Intel numerics products; programs
written for the S087 will be transportable to future
products that conform to the proposed IEEE
standard. The NPX also provides many additional
functions that are extensions to the proposed
standard.

100

w

..
U
Z

:E
0:

o...
0:
W

<>.

w
>
;::

..
..J

10

W
0:

Performance
19.77

1978

1979

1980

As Figure 6-2irtdicates, the S087 provides about 10
times the instruction speed of the 8232 and a
100-fold improvement over FPAL. The 8087 multiples 32-bit and 64-bit real numbers in about 19/Ls
and 27/Ls respectively. Of course, the actual performance of the NPX in a given system depends on
numerous application-specific factors.

YEAR INTRODUCED

Figure 6.-2 8087 Evolution and
Relative Performance

6-2

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

Usability

Table 6-1 compares the execution times of several
8087 instructions with the equivalent operations executed in software on a 5 MHz 8086. The software
equivalents are highly optimized assembly language
procedures from the 8087 emulator, an NPX development tool discussed later in this section.

Viewed strictly from the standpoint of raw speed,
the 8087 enables serious computation-intensive
tasks to be performed by microprocessors for the
first time. The 8087 offers more than just high
performance, however. By synthesizing advances
made by numerical analysts in the past several years,
the NPX provides a level of usability that surpasses
existing minicomputer and mainframe arithmetic
units. In fact, the charter of the 8087 design team
was first to achieve exceptional functionality and
then to obtain high performance.

The performance figures quoted in this section are
for operations on real (floating point) numbers. The
8087 also has instructions that enable it to utilize
fixed point binary and decimal integers of up to 64
bits and 18 digits, respectively. Using an 8087, rather
than multiple precision software algorithms for integer operations, can provide speed improvements of
10-100 times.
The 8087's unique processor extension interface to
the CPU can yield an additional performance increment beyond that of simple instruction speed. No
overhead is incurred in setting up the device for a
computation; the 8087 decodes its own instructions
automatically in parallel with the CPU. Moreover,
built-in coordination facilities allow the CPU to proceed with other instructions while the 8087 is
simultaneously executing its numeric instruction.
Programs can exploit this processor parallelism to increase total system throughput.

The 8087 is explicitly designed to deliver stable,
accurate results when programmed using straightforward "pencil and paper" algorithms. While this statement may seem trivial, experienced users of
"floating point processors" will recognize its fundamental importance. For example, most computers
can overflow when two single precision floating
point numbers are multiplied together and then

Table 6-1 8087 Emulator Speed Comparison

Approximate Execution Time (I-Is)
(5 MHz Clock)
Instruction

8087

8086
Emulation

Multiply (single precision)

19

1,600

Multiply (double precision)

27

2,100

Add

17

1,600

Divide (single precision)

39

3,200

Compare

9

1,300

Load (single precision)

9

1,700

Store (single precision)

18

1,200

Square root

36

19,600

Tangent

90

13,000

100

17,100

Exponentiation

6-3

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

divided by a third, even if the final result is a perfectly valid 32-bit number. The 8087 delivers the correctly rounded result. Other typical examples of
undesirable machine behavior in straightforward calculations occur when solving for roots of a quadratic
equation:
- b±

.J b2 -

4ac

•

Performance requirements exceed the capacity of traditional microprocessors;

•

Consistently safe, reliable results must be
delivered using a programming staff that is
not expert in numerical techniques.

Note also that the 8087 can reduce software development costs and improve the performance of systems
that do not utilize real numbers but operate on
multi-precision binary or decimal integer values.

2a

or computing financial rate of return, which involves
the expression: (1 +nn. Straightforward algorithms
will not deliver consistently correct results (and will
not indicate when they are incorrect) on most
machines. To obtain correct results on traditional
machines under all conditions usually requires sophisticated numerical techniques that are foreign to
most programmers. General application programmers using straightforward algorithms will produce
much more reliable programs on the 8087. This
simple fact greatly reduces the software investment
required to develop safe, accurate computationbased products.

A few examples, which show how the 8087 might be
utilized in specific numerics applications, are described below. In many cases, these types of systems
have been implemented in the past with
minicomputers. The advent of the 8087 brings the
size and cost savings of microprocessor technology
to these applications for the first time.

Beyond traditional numerics support for "scientific"
applications, the 8087 has built-in facilities for
"commercial" computing. It can process decimal
numbers of up to 18 digits without rounding off
errors, and it performs exact arithmetic on integers as
large as 264 Exact arithmetic is vital in accounting applications where rounding errors may introduce
money losses that cannot be reconciled.
The NPX contains a number of facilities that can optionally be invoked by sophisticated users. Examples
of these advanced features include two models of
infinity, directed rounding, gradual underflow, and
traps to user-written exception handling software.

•

Business data processing - The NPX's ability
to accept decimal operands and produce exact
decimal results of up to 18 digits greatly simplifies accounting programming. Financial calculations which use power functions can take
advantage of the 8087's exponentiation and
logarithmic instructions.

•

Process control - The 8087 solves dynamic
range problems automatically, and its extended precision allows control functions to be
fine-tuned for more accurate and efficient
performance. Control algorithms implemented with the NPX also contribute to improved
reliability and safety, while the 8087's speed
can be exploited in real-time operations.

•

Numerical control - The 8087 can move and
position machine tool heads with extreme
accuracy. Axis positioning also benefits from
the hardware trigonometric support provided
by the 8087.

•

Robotics - Coupling small size and modest
power requirements with powerful computational abilities, the NPX is ideal for on-board
six -axis positioning.

•

Navigation - Very small, light weight, and
accurate inertial guidance systems can be implemented with the 8087. Its built-in trigonometric functions canspeed and simplify the
calculation of position from bearing data.

•

Graphics terminals - The 8087 can be used
in graphics terminals to locally perform many
functions which normally demand the attention of a main computer; these include
rotation, scaling, and interpolation. By also

Applications
The NPX's versatility and performance make it appropriate for a broad array of numerically-oriented
applications. In general, applications that exhibit any
of the following characteristics can benefit by implementing numeric processing on the 8087:
•

Numeric data vary over a wide range of
values, or include non-integral values;

•

Algorithms produce very large or very small
intermediate results;

•

Computations must be very precise, i.e., a
large number of significant digits must be
maintained;
6-4

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

Table 6-2 lists the seven 8087 data types. Internally,
the 8087 holds all numbers in the temporary real
format; the extended range and precision of this
format are key contributors to the NPX's ability to
consistently deliver stable, expected results. The
8087's load and store instructions convert operands
between the other formats and temporary real. The
fact that these conversions are made, and that calculations may be performed on converted numbers, is
transparent to the programmer. Integer operands,
whether binary or decimal, yield correct integer
results, just as real operands yield correct real
results. Moreover, a rounding error does not occur
when a number in an external format is converted to
temporary real.

including an 8089 InputlOutput Processor to
perform high speed data transfers, very
powerful and highly self-sufficient terminals
can be built from a relatively small number of
8086,88 family parts.
•

Data acquisition - The 8087 can be used to
scan, scale, and reduce large quantities of
data as it is collected, thereby lowering storage
requirements as well as the time required to
process the data for analysis.

The preceding examples are oriented toward
"traditional" numerics applications. There are, in
addition, many other types of systems that do not
appear to the end user as "computational", but can
employ the 8087 to advantage. Indeed, the 8087 presents the imaginative system designer with an opportunity similar to that created by the introduction of
the microprocessor itself. Many applications can be
viewed as numerically-based if sufficient computational power is available to support this view. This is
analogous to the thousands of successful products
that have been built around "buried" microprocessors, even though the products themselves bear
little resemblance to computers.

Computations in the 8087 center on the processor's
register stack. These eight 80-bit registers provide
the equivalent capacity of 40 of the 16-bit registers
found in typical CPUs. This generous register space
allows more constants and intermediate results to be
held in registers during calculations, reducing
memory access and consequently improving execution speed as well as bus availability. The 8087 register set is unique in that it can be accessed both as a
stack, with instructions operating implicitly on the
top one or two stack elements, and as a fixed register
set, with instructions operating on explicitly
designated registers.

Programming Interface
The combination of an 8086,88 or 80186,188 CPU
and an 8087 generally appears to the programmer as
a single machine. The 8087, in effect, adds new data
types, registers, and instructions to the CPU. The
programming languages and the coprocessor architecture take care of most interprocessor coordination
automatically.

Table 6-3 lists the 8087's major instructions by class.
Assembly language programs are written in
ASM-86, the 8086,88/80186,188/8087 common assembly language. ASM-86 provides directives for
defining all 8087 data types and mnemonics for all

Table 6-2 Data Types
Data Type

Bits

Significant
Digits (Decimal)

Approximate Range (Decimal)
~

X ~ + 32,767

16

4

-32,768

Short integer

32

9

-2x10 9 ~ X ~ + 2x10 9

Long integer

64

18

-9x10 18 ~ X ~ +9x10 18

Packed decimal

80

18

-99 ... 99

8.43x10- 37 ~

Word integer

Short real*

32

6-7

Long real*

64

15-16

Temporary real

80

19

~

X ~ + 99 ... 99 (18 digits)

Ixi ~ 3.37x10 38
4.19x1 0- 307 ~ Ix I ~ 1.67x1 0308
3.4x10-4932 ~ Ixl ~ 1.2x10 4932

*The short and long real data types correspond to the single and double precision data types
defined in other Intel numerics products.
6-5

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

Table 6-3 Principal Instructions
Class

Instructions

Data Transfer

Load (all data types), Store (all data types), Exchange

Arithmetic

Add, Subtract, Multiply, Divide, Subtract Reversed,
Divide Reversed, Square Root, Scale, Remainder,
Integer Part, Change Sign, Absolute Value, Extract

Comparison
Transcendental

Compare, Examine, Test
Tangent, Arctangent, 2X -1, YeLog 2(X + 1), YeLog 2(X)

Constants

0, 1,n, Lpg102, Log e2, Log 210, Log 2e

Processor Control

Load Control Word, Store Control Word, Store Status
Word, Load Environment, Store Environment, Save,
Restore, Enable Interrupts, Disable Interrupts, Clear
Exceptions, Initialize

instructions. The fact that some instructions in a program are executed by the 8087 and others by the
CPU is usually of no concern to the programmer. All
8086,88 addressing modes may be used to access
memory-based 8087 operands, enabling convenient
processing of numeric arrays, structures, based
variables, etc.

8087 routines to be developed and checked out on
an 8086,88 or 80186,188 execution vehicle before
prototype 8087 hardware is operational.
At the source code level, there is no difference between a routine that will ultimately run on an 8087
or on a CPU emulation of an 8087. At link time, the
decision is made whether to use the NPX or the software emulator; no recompilation or re-assembly is
necessary. Source programs are independent of the
numeric execution vehicle: except for timing, the operation of the emulated NPX is the same as for "real
hardware". The emulator also makes it simple for a
product to offer the NPX as a "plug-in" performance
option without the necessity of maintaining two sets
of source code. The 80186,188 provides a trap when
an escape (to the 8087) opcode is encountered.

NPX routines may also be written in PL/M-86,
Intel's high-level language for the 8086,88 and
80186,188 CPUs. PLlM-86 provides the programmer with access to many 8087 facilities while reducing the programmer's need to understand the
architecture of the chip.
Two features of the 8087 hardware further simplify
numeric application programming. First, the 8087 is
invoked directly by the programmer's instructions.
There is no need to write instructions that "address"
the NPX as an "I/O device", or to incur the overhead of setting up a DMA operation to perform data
transfers. Second, the NPX automatically detects exception conditions that can potentially damage a calculation at run-time. On-chip exception handlers are
automatically invoked by default to field these
exceptions, so that a reasonable result is produced
and execution may proceed without program
intervention. Alternatively, the 8087 can interrupt
the CPU and thus trap to a user procedure when an
exception is detected.

Hardware Interface
As a processor extension to an 8086,88 or
80186,188, the 8087 is wired directly to the CPU as
shown in Figure 6-3. The CPU's queue status lines
(QSO and QS 1) enable the NPX to obtain and
decode instructions in synchronization with the
CPU. The NPX's BUSY signal informs the CPU that
the NPX is executing; the CPU WAIT instruction
tests this signal to ensure that the NPX is ready to
execute a subsequent instruction. The NPX can interrupt the CPU when it detects an exception. The
NPX's interrupt request line is typically routed to
the CPU through an 8259A Programmable Interrupt
Controller or the 80186,18888 integrated controller.

Besides the assembler and compiler, Intel provides a
software emulator for the 8087. The 8087 emulator
(E8087) is a software package that provides the functional equivalent of an 8087; it executes entirely on
an 8086,88 or 80186,188 CPU. The emulator allows
6-6

210911

THE 8087 NUMERIC PROCESSOR EXTENSION
I'

,
'· .·•1·"·
.

I:,,'

. - - .,

I
I

L

INT

t------I~

INTR

8259A
PIC

.,.!In _

J

8086
FAMILY
BUS
INTERFACE
COMPONENTS

MULTIMASTER
SYSTEM
BUS

8284
CLOCK
GENERATOR
CLK

1-+----_'----1 CLK

8087
NDP

~---~---~INT

~

-,CLK

8089
lOP

...
Figure 6-3 NDP Interconnect

The NPX uses one of its host CPU's request/grant
lines to obtain control of the local bus for data transfers (loads and stores). The other CPU request/grant line is available for general system use, for
example, by a local 8089 Input/Output Processor. A
local 8089 may also be connected to the 8087's
RQ/GTl line. In this configuration, the 8087 passes
the request/grant handshake signals between the
CPU and the lOP when the 8087 is not in control of
the bus, the 8087 relinquishes the bus (at the end of
the current bus cycle) upon a request from the connected IOP, giving the IOP higher priority than
itself. In this way, two local 8089's can be configured
in a module that also includes a CPU and an 8087.

8087 is required to add powerful computational capabilities to 8086, 88- based systems. For 80186,
188-based systems, some additional hardware is required to interface to the 8087. Refer to Volume 2
for more information.

6.3 PROCESSOR ARCHITECTURE
As shown in Figure 6-4, the NPX is internally divided into two processing elements, the control unit
(CU) and the numeric execution unit (NEU). In
essence, the NEU executes all numeric instructions,
while the CU fetches instructions, reads and writes
memory operands, and executes the processor control class of instructions. The two elements are able
to operate independently of one another, allowing
the CU to maintain synchronization with the CPU
while the NEU executes numeric instructions,

The .8086, 8088 and 8087 all utilize the same clock
generator and system bus interface components
(bus controller, latches, transceivers, and bus
arbiter). Thus, no additional hardware beyond the
6-7

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

,.

DATA

I
I
I
I
I
I
I

(61
(51
(41

REG(STER STACK

(31
STATUS

(21

ADDRESS

-

-

-

-

-

-

-

"-

SO BITS

-

--

I

(11
(01

-

-

-

-

~

Figure 6-4 8087 Block Diagram

an instruction containing the escape code, it either
executes the instruction itself, or passes it to the
NEU, depending on the type of instruction.

Control Unit
The CU keeps the 8087 operating in synchronization
with its host CPU. 8087 instructions are intermixed
with CPU instructions in a single instruction stream
fetched by the CPU. By monitoring the status signals
emitted by the CPU, the NPX control unit can determine when an instruction is being fetched. When the
instruction byte or word becomes available on the
local bus, the CU taps the bus in parallel with the
CPU and obtains that portion of the instruction.

The CPU distinguishes between ESC instructions
that reference memory and those that do not. If the
instruction refers to a memory operand, the CPU
calculates the operand's address and then performs
a "dummy read" of the word at that location. This is
a normal read cycle, except that the CPU ignores the
data it receives. If the ESC instruction does not contain a memory reference, the CPU simply proceeds
to the next instruction.

The CU maintains an instruction queue that is identical to the queue in the host CPU. By monitoring the
CPU's queue status lines, the CU is able to obtain
and decode instructions from the queue in synchronization with the CPU. In effect, both processors fetch and decode the instruction stream in
parallel.

A given 8087 instruction (an ESC to the CPU) will
either require loading an operand from memory into
the 8087, or will require storing an operand from the
8087 into memory, or will not reference memory at
all. In the first two cases, the CU makes use of the
"dummy read" cycle initiated by the CPU. The CU
captures and saves the operand address that the
CPU places on the bus early in the "dummy read".
If the instruction is an 8087 load, the CU additionally
captures the first (and possibly only) word of the
operand when it becomes available on the bus. If the
operand to be loaded is longer than one word, the
CU immediately obtains the bus from the CPU and

The two processors execute the instruction stream
differently, however. The first fiVe bits of all 8087
machine instructions are identical; these bits designate the coprocessor escape (ESC) class of
instructions. The control unit ignores all instructions
that do not match these bits, since these instructions
are directed to the CPU only. When the CU decodes

6-8

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

refers to the ith register from ST in the stack (0 i 7).
For example, if ST contains 011 B (register 3 is the
top of the stack), the following instruction would
add registers 3 and 5:

reads the rest of the operand in consecutive bus
cycles. In a store operation, the CU captures and
saves the operand address as in a load, and ignores
the data word that follows in the "dummy read"
cycle. When the 8087 is ready to perform the store,
the CU obtains the bus from the CPU and writes the
operand at the saved address using as many consecutive bus cycles as are necessary to store the operand.

FADD ST,ST(2)

In typical use, the programmer may conceptually
"divide" the registers into a fixed group and an adjustable group. The fixed registers are used like the
conventional registers in a CPU, to hold constants,
accumulations, etc. The adjustable group is used like
a stack, with operands pushed on and results popped
off. After loading, the registers in the fixed group
are addressed explicitly, while those in the adjustable
group are addressed implicitly. Of course, all registers may be addressed using either mode, and the
"definition" of the fixed versus the adjustable areas
may be altered at any time. Section 6.8 contains a
programming example that illustrates typical register
stack use.

Numeric Execution Unit
The NEU executes all instructions that involve the
register stack; these include arithmetic, comparison,
transcendental, constant, and data transfer instructions. The data path in the NEU is 68 bits wide and
allows internal operand transfers to be performed at
very high speeds.

Register Stack
Each of the eight registers in the 8087's register
stack is 80 bits wide, and each is divided into the
"fields" shown in Figure 6-5. This format corresponds to the NPX's temporary real data type that is
used for all calculations. Section 6.6 describes in
detail how numbers are represented in the temporary real format.
79

o

84 83

'eXPONENT

I

The stack organization and top-relative addressing
of the registers simplify subroutine programming.
Passing subroutine parameters on the register stack
eliminates the need for the subroutine to "know"
which registers actually contain the parameters and
allows different routines to call the same subroutine
without having to observe a convention for passing
parameters in dedicated registers. So long as the
stack is not full, each routine simply loads the
parameters on the stack and calls the subroutine.
The subroutine addresses the parameters as ST,
ST(J), etc., ·even though ST may, for example, refer
to register 3 in one invocation and register 5 in
another.

SIGNIFICANO

SIGN

Figure 6-5 Register Structure

At a given point in time, the ST field in the status
word (described shortly) identifies the current topof-stack register. A load ("push") operation decrements ST by 1 and loads a value into the new top
register. A store-and-pop operation stores the value
from the current top register and then increments
ST by 1. Thus, like 8086/80186 stacks in memory,
the 8087 register stack grows "down" toward loweraddressed registers.

Status Word
The status word reflects the overall condition of the
8087; it may be examined by storing it into memory
with an NPX instruction and then inspecting it with
CPU code. The status word is divided into the fields
shown in Figure 6-6. The busy field (bit 15) indicates
whether the NPX is executing an instruction (B= 1)
or is idle (B=O).

Instructions may address registers either implicitly
or explicitly. Many instructions operate on the register at the top of the stack. These instructions implicitly address the register pointed to by ST. For
example, the ASM-86 instruction FSQRT replaces
the number at the top of the stack with its square
root; this instruction takes no operands because the
top-of-stack register is implied as the operand. Other
instructions allow the programmer to explicitly specify the register that is to be used. Explicit register
addressing is "top-relative" where the ASM-86 expression ST denotes the current stack top and STU)

Several 8087 instructions (for example, the comparison instructions) post their results to the condition
code (bits 14 and 10-8 of the status word). The
principal use of the condition code is for conditional
branching. This may be accomplished by executing
an instruction that sets the condition code, storing
the status word in memory and then examining the
condition code with CPU instructions.

6-9

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

15

I

~

EXCEPTION FLAGS (1 ; EXCEPTION HAS OCCURRED)
INVALID OPERATION
DENORMALIZED OPERAND
ZERO DIVIDE
OVERFLOW
UNDERFLOW
PRECISION
(RESERVED)
INTERRUPT REQUEST
CONDITION CODE("
STACK TOP POINTER(2)
BUSY

(1) See desc'riptions of compare, test, examine and remainder instructions in section S.7 for
condition code interpretation.
(2) ST values:
000 ; register 0 is stack top
001 ; register 1 Is stack top

.
.

111 ; register 7

'S stack top

Figure 6-6 Status Word Format

Bits 13-11 of the status word point to the 8087 register that is the current stack top (ST). Note that if
ST=OOOB, a "push" operation, which decrements
ST, produces ST= IIIB; similarly, popping the stack
with ST = III B yields ST = OOOB.
Bit 7 is the interrupt request field. The NPX sets this
field to record a pending interrupt to the CPU.
Bits 5-0 are set to indicate that the NEU has detected
an exception while executing an instruction. Section
6.4 explains these exceptions.

Control Word
To satisfy a broad range of application requirements,
the NPX provides several processing options which
are selected by loading a word from memory into
the control word. Figure 6-7 shows the format and
encoding of the fields in the control word; it is
provided here for reference. Section 6.4 explains the
use of each of these 8087 facilities except the
interrupt-enable control field, which is covered in
Volume 2 of this set.
6-10

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

Tag Word

tag word is to optimize the NPX'S performance
under certa' circumstances, and programmers ordinarily need not be concerned with it.

The tag word marks the content of each register as
shown in Figure 6-8. The principal function of the

15
I

I

IIC I

RC

I
I
-.--.--

l§

EXCEPTION MASKS (1 = EXCEPTION IS MASKED)
INVALID OPERATION
DENORMALIZED OPERAND
ZERODIVIDE
OVERFLOW
UNDERFLOW
PRECISION
(RESERVED)
INTERRUPT·ENABLE MASK(1)
PRECISION CONTROL<2)
ROUNDING CONTROL<3)
INFINITY CONTROL<4)
(RESERVED)

Interrupt.Enable Mask:
o Interrupts Enabled
1 = Interrupts Disabled (Masked)
(2) Precision Control:
00 = 24 bits
01 = (reserved)
10 = 53 bits
11 64 bits
(1)

=

=

(3)

Rounding Control:
00 = Round to Nearest or Even
01 = Round Down (toward -00)
10 = Round Up (toward +00)

11 = Chop (Truncate Toward Zero)
(4) Infinity Control:

~ ~ :;n~~tive

Figure 6- 7 Control Word Format

I

1S
TAG(7)

I

TAG(6)

I

TAG(S)

I

TAG(4)

I

7
TAG(3)

I

TAG(2)

I

TAG(l)

I

0
TAG(O)

I

Ta8ov:I't~~id (Normal or Un normal)
01 = Zero (True)
10 = Special (Not·A·Number,
11 = Empty

00,

or Denormal)

Figure 6-8 Tag Word Format
6-11

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

Exception Pointers

Ideally, it would be desirable for a computer to be
able to operate on the entire real number system. In
practice this is not possible. Computers, no matter
how large, ultimately have fixed size registers and
memories that limit the system of numbers that can
be accommodated. These limitations proscribe both
the range and the precision of numbers. The result is
a set of numbers that is finite and discrete, rather
than infinite and continuous. This sequence is a
subset of the real numbers, which is designed to
form a useful approximation of the real number
system.
.

The exception pointers (see Figure 6-9) are provided
for user-written exception handlers. Whenever the
8087 executes an instruction, the CU saves the instruction address and the instruction opcode in the
exception pointers. In addition, if the instruction
references a memory operand, the address of the
operand is retained also. An exception handler can
store these pointers in memory and thus obtain information concerning the instruction that caused the
exception.

I
I

Figure 6-10 superimposes the basic 8087 real
number system on a real number line (decimal numbers are shown for clarity, although the 8087 actually
represents numbers in binary). The dots indicate the
subset of real numbers the 8087 can represent as the
data and final results of calculations. The 8087's
range is approximately ± 4.19x 10- 307 to
± 1.67xl0308 . Applications that are required to deal
with data and final results outside this range are rare.
By comparison, the range of the IBM 370 is about
±0.54xlO- 78 to ±0.72xI076 .

OPERAND ADDRESS(1)

I

INSTRUCTION OPCODEI2)

INSTRUCTION ADDRESS(1)

10

o

(1) 20-bit physical address
(2) 11 least significant bits of opcode; 5 most significant bits are always 8087 hook (11011 B)

Figure 6·9 Exception Pointers Format

6.4 COMPUTATION FUNDAMENTALS
This section covers 8087 programming concepts that
are common to all applications. It describes the
8087's internal number system and the various types
of numbers that can be employed in NPX programs.
The most commonly used options for rounding, precision and infinity (selected by fields in the control
word) are described, with exhaustive coverage of
less frequently used facilities deferred to the Section
6.7, Special Topics. Exception conditions which may
arise during execution of NPX instructions are also
described, along with the options that are available
for responding to these exceptions.

Number System
The system of real numbers that people use for
pencil and paper calculations is conceptually infinite
and continuous. There is no upper or lower limit to
the magnitude of the numbers one can employ in a
calculation, or to the precision (number of significant
digits) that the numbers can represent. When consid"
ering any real number, there are always aQ infinity
of numbers both larger and smaller. There is also an
infinity of numbers between (i.e., with more significant digits than) any two real numbers. For
example, between 2.5 and 2.6 are 2.51, 2.5897,
2.500001, etc.
6-12

The finite spacing in Figure 6-10 illustrates that the
NPX can represent a great many, but not all, of the
real numbers in its range. There is always a "gap" between two "adjacent" 8087 numbers, and it is possible for the result of a calculation to fall in this space.
When this occurs, the NPX rounds the true result to
a number that it can represent. Thus, a real number
that requires more digits than the 8087 can accommodate (e.g., a 20 digit number) is represented with
some loss of accuracy. Notice also that the 8087's
representable numbers are not distributed evenly
along the real number line. There are, in fact, an
equal number of representable numbers between
successive powers of 2 (i.e., there are as many representable numbers between 2 and 4 as between
65,536 and 131,072). Therefore, the "gaps" between
representable numbers are "larger" as the numbers
increase in magnitude. All integers in the range
± 264 , however, are exactly representable.

In its internal operations, the 8087 actually employs
a number system that is a substantial superset of
that shown in Figure 6-10. The internal format
(called temporary real) extends the 8087's range to
about ± 3.4xl0- 4932 to ± 1.2xl04932 , and its precision to about 19 (equivalent decimal) digits. This
format is designed to provide extra range and precision for constants and intermediate results, and is
not normally intended for data or final results.
210911

I

THE 8087 NUMERIC PROCESSOR EXTENSION

From a practical standpoint, the 8087's set of real
numbers is sufficiently "large" and "dense" so as
not to lim it the vast majority of microprocessor
applications. Compared to most computers, including mainframes, the NPX provides a very good
approximation of the real number system. It is important to remember, however, that it is not an
exact representation, and that arithmetic on real
numbers is inherently approximate.
Conversely, and equally important, the 8087 does
perform exact arithmetic on its integer subset of the
reals. That is, an operation on two integers returns
an exact integral result, provided that the true result
is an integer and is in range. For example, 4+ 2

NEGATIVE RANGE
(NORMALIZED)

••

••

I

yields an exact integer, 1+3 does not, and 240 x 230
+ I does not, because the result requires greater
than 64 bits of precision.

Data Types and Formats
The 8087 recognizes seven numeric data types,
divided into three classes: binary integers, packed
decimal integers, and binary reals. Figure 6-11 summarizes the format of each data type. In the figure,
the most significant digits of all numbers (and fields
within numbers) are the leftmost digits. Table 6-2
provides the range and number of significant
(decimal) digits that each format can accommodate.

'

.

.'

POSITIVE RANGE
INORMALIZED,

,

~~
__~'__-+__.'~'~1~'~'~'~14'4'4'+1~··"·~·~t·"·~·~·I~I~·~·~·I···"
::1-1
1.67x10308

j

L

4.19x10· 307

•

.

.
J

2.00000000000000000
(NOT REPRESENTABLE)
L-_ _ _ _ 1.99999999999999999
PRECISION:

1-18DIGITS-.t

Figure 6-10 8087 Number System

6-13

210911

I
,

THE 8087 NUMERIC PROCESSOR EXTENSION

WORD INTEGER

SHORT INTEGER

INCREASING SIGNIFICANCE

lSi MAGNITUDE

I

15

0

(TWO'S
COMPLEMENT)

lSi
MAGNITUDE
I(TWO'S
.......'--_ _ _ _ _ _ _ _ _ _ _... COMPLEMENT)
31

LONG INTEGER

II
S

I

(TWO'S
COMPLEMENT)

MAGNITUDE

"6~3--------------------------------------------~

PACKED DECIMAL

d17

79

d '6 d ,S

d" d '3

d 12 d l1

MAGNITUDE
dlO d g
dB
d,

d6

dS

d,

d3

d,

d,

dO

72

SHORT REAL

o
LONG REAL

TEMPORARY REAL

~1_S~I E_:_~_AO_SJ_f_N_T_~I

63

__

'-I'

LIS~I~ E_X_~_I~_~_i_~_T
__

79

_ _ _ _ _ _ _S_IG_N_I_F_IC_A_N_D
_______

52~

___

~fij_I~

64 63

~

0

____________S_I_G_N_IF_IC_A_N_D
________________

1

~
0

NOTES:
S = Sign bit (0= positive, 1 = negative)
dn = Decimal digit (two per byte)
X = Bits have no significance; 8087 ignores when loading, zeros when storing.
, = Position of implicit binary pOint
I = Integer bit of significand; stored in temporary real. implicit in short and long real
Exponent Bias (normalized values):
Short Real: 127 (7FH)
Long Real: 1023 (3FFH)
Temporary Real: 16383 (3FFFH)

Figure 6-1.1 Data Formats
6-14

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

negative. (The exponent and significand are analogous to the terms "characteristic" and "mantissa"
used to describe floating point numbers on some
computers.) Negative numbers differ from positive
numbers only in their sign bits.

BINARY INTEGERS

The three binary integer formats are identical except
for length, which governs the range that can be accommodated in each format. The leftmost bit is interpreted as the number's sign: 0= positive and
1 = negative. Negative numbers are represented in
standard two's complement notation (the binary
integers are the only 8087 format to use two's
complement). The quantity zero is represented with
a positive sign (all bits are 0). The 8087 word integer
format is identical to the 16-bit signed integer data
type of the 8086,88 and 80186,188.

Table 6-4 shows how the real number 178.125
(decimal) is stored in the 8087 short real format.
The table lists a progression of equivalent notations
that express the same value to show how a number
can be converted from one form to another. The
ASM-86 and PLlM-86 language translators perform
a similar process when they encounter programmerdefined real number constants. Note that not every
decimal fraction has an exact binary equivalent. The
decimal number 1110, for example, cannot be expressed exactly in binary (just as the number 1/3
cannot be expressed in decimal). When a translator
encounters such a value, it produces a rounded
binary approximation of the decimal value.

DECIMAL INTEGERS

Decimal integers are stored in packed decimal
notation, with two decimal digits "packed" into each
byte, except the leftmost byte, which carries the sign
bit (0 = positive, 1 = negative). Negative numbers
are not stored in two's complement form and are distinguished from positive numbers only by the sign
bit. The most significant digit of the number is the
leftmost digit. All digits must be in the range OH-9H.

The NPX usually carries the digits of the significand
in normalized form. This means that, except for the
value zero, the significand is an integer and a fraction
as follows:
1D. fff... ff

REAL NUMBERS

where /':,. indicates an assumed binary point. The
number of fraction bits varies according to the real
format: 23 for short, 52 for long and 63 for temporary real. By normalizing real numbers so that their
integer bit is always ai, the 8087 eliminates leading
zeros in small values (I x I < 1). This technique
maximizes the number of significant digits that can
be accommodated in a significand of a given width.

The 8087 stores real numbers in a three-field binary
format that resembles scientific, or exponential,
notation. The number's significant digits are held in
the significand field, the exponent field locates the
binary point within the significant digits (and therefore determines the number's magnitude), and the
sign field indicates whether the number is positive or

Table 6-4 Real Number Notation
Notation

Value

Ordinary Decimal

178.125

Scientific Decimal

1,.,78125E2

Scientific Binary

1,., 0110010001 E111

Scientifi.c Binary
(Biased Exponent)

1,., 0110010001 E1 000011 0

8087 Short Real
(Normalized)

Sign

Biased
Exponent

0

10000110

6-15

Significand

01100100010000000000000
1,., (implicit)

L

210911

.1

I

THE 8087 NUMERIC PROCESSOR EXTENSION

Note that in the short and ,long real formats the
integer bit is implicit and is not actually stored; the
integer bit is physically present in the temporary real
format only.

When the temporary real format is used to hold data
or to deliver final results, the safety features built
into the 8087 are compromised. Furthermore, the
range and precision of the long real form are adequate for most microcomputer applications.

If one were to examine only the significand with its
assumed binary point, all normalized, real numbers
would have values between I and 2. The exponent
field locates the actual. binary point in the significant
digits. Just as in decimal scientific notation, a positive
exponent has the effect of moving the binary point
to .the right, and a negative exponent effectively
moves the binary point to the. left, inserting leading
zeros as necessary. An unbiased exponent of zero indicates that the position of the assumed binary point
is also the position of the actual binary. point. The
exponent field, then, determines a real number's
magnitude.

SPECIAL VALUES

Besides being able to represent positive and negative
numbers, the 8087 data formats may be used (0 describe other entities. These special values provide
extra flexibility but most users do not need to understand them in detail to use the 8087 successfully.
Accordingly, they are discussed here only briefly; expanded coverage, including the bit encoding of each
value, is provided in the Special Topics section.

In order to simplify comparing real numbers (e.g.,
for sorting), the 8087 stores exponents in a biased
form. This means that a constant is added to the true
exponent described above. The value of this bias is
different for each real format (see Figure' 6-11). It
has been chosen so as to force the biasedexponent to
be a positive value. This allows two real numbers (of
the same format and sign) to be compared as if they
are unsigned binary integers. that is, when comparing them bitwise from left to right (beginning with
the left-most exponent bit), the first bit position that
differs orders the numbers; there is no need to proceed further with the. comparison. A number's true
exponent can be determined simply by subtracting
the bias value of its format.
The short and long real formats exist in memory
only. If a number in one of these formats is loaded
into a register, it is automatically converted to
temporary real, the format used for all internal
operations. Likewise, data in registers can be converted to short or long real for storage in memory.
The temporary real format may be used in memory
also, typically to store intermediate results that
cannot be held in registers.
Most applications should use the long real form to
store real number data and results; it provides sufficient range and precision to return correct results
with a minimum of programmer attention. The
short real format is appropriate for applications that
are' constrained by memory, but it should be recognized that this format provides a smaller margin of
safety. It is also useful for debugging algorithms because roundoff problems will manifest themselves
more quickly in this format. The temporary real
format should normally be reserved for holding intermediate results, loop accumulations, and
constants. Its extra length is designed to shield final
results from the effects of rounding and overflow /underflow in intermediate calculations. When the

The value zero may be signed positive or negative in
the real and decimal integer formats; the sign of a
binary integer zero is always positive. The fact that
zero may be signed, however, is transparent to the
programmer.
The real number formats allow for the representa,
tion of the special values' + 00 and - 00. The 8087
may generate these values as its built-in response to
exceptions such as division by zero, or the ljttempt
to store a result that exceeds the upper range limit of
the destination format. Infinities may participate in
arithmetic and comparison operations, and in fact
the processor provides two differ.ent conceptual
models for handling these special values.
If a programmer attempts an operation for which the
8087 cannot deliver a reasonable result, it will, at the
programmer's discretion, either request an interrupt, or return the special value indefinite. Taking the
square root of a negative number is an example of
this type of invalid operation. The recommended
action in this situation is to stop the computation by
trapping to a user-written exception handler. If,
however, the programmer elects to continue the
computation, the specially coded indefinite value will
propagate through the calculation and thus flag the
erroneous computation when it is eventually delivered as the result. Each format has an encoding that
represents the special value indefinite.
In the real formats, a whole range of special values,
both positive and negative, is designated to represent
a class of values called NAN (Not-A-Numbed. The
special value indefinite is a reserved NAN encoding,
but all other encodings are made available to be
defined in any way by application software. Using a
NAN as an operand raises the invalid operation
exception, and can trap to a user-written routine to
process the NAN. Alternatively, the 8087's built-in
exception handler will simply return the NAN itself

6-16

210911

I

THE 8087 NUMERIC PROCESSOR EXTENSION

as the result of the operation; in this way NANs,
including indefinite, may be propagated through a calculation and delivered as a final, special-valued,
result. One use for NANs is to detect uninitialized
variables.
As mentioned earlier, the 8087 stores non-zero real
numbers in "normalized floating point" form. It
also provides for storing and operating on reals that
are not normalized, i.e., whose significands contain
one or more leading zeros. Nonnormals arise when
the result of a calculation yields a value that is too
small to be represented in normal form. The leading
zeros of nonnormals permit smaller numbers to be
represented, at the cost of some lost precision (the
number of significant digits is reduced by the leading
zeros). In typical algorithms, extremely small values
are most likely to be generated as intermediate,
rather than final results. By using the NPX's temporary real format for holding intermediates, values as
small as ±3.4xI0- 4932 can be represented; this
makes the occurrence of nonnormal numbers a rare
phenomenon in 8087 applications. Nevertheless, the
NPX can load, store and operate on nonnormalized
real numbers.

Rounding Control
Internally, the 8087 employs three extra bits (guard,
round and sticky bits) which enable it to represent
the infinitely precise true result of a computation;
these bits are not accessible to programmers. Whenever the destination can represent the infinitely precise true result, the 8087 delivers it. Rounding
occurs in arithmetic and store operations when the
format of the destination cannot exactly represent
the infinitely precise true result. For example, a real

,

number may be rounded if it is stored in a shorter
real format, or in an integer format. Or, the infinitely
precise true result may be rounded whim it is returned to a register.
The NPX has four rounding modes, selectable by
the RC field in the control word (see Figure 6-7).
Given a true result b that cannot be represented by
the target data type, the 8087 determines the two
representable numbers a and c that most closely
bracket b in value (a < b < c). The processor then
rounds (changes b to a or to c according to the mode
selected by the RC field as shown in Table 6-5.
Rounding introduces an error in a result that is less
than one unit in the last place to which the result is
rounded.
"Round to nearest or even" is the default mode and
is suitable for most applications; it provides the most
accurate and statistically unbiased estimate of the
true result. The "chop" mode is provided for integer
arithmetic applications.
"Round up" and "round down" are termed directed
rounding and can be used to implement interval
arithmetic. Interval arithmetic generates a certifiable
result independent of the occurrence of rounding
and other errors. The upper and lower bounds of an
interval may be computed by executing an algorithm
twice, rounding up in one pass and down in the
other.

Precision Control
The 8087 allows results to be calculated with 64, 53,
or 24 bits of precision as selected by the PC field of
the control word. The default setting, and the one

Table 6-5 Rounding Modes

RC Field

Rounding Mode

Rounding Action.

00

Round to nearest

Closer to b of a or e; if
equally close, select even
number (the one whose
least significant bit is zero).

01

Round down (toward -00)

a

10

Round up (toward + 00)

e

11

Chop (toward 0)

Smaller il1 magnitude of
a ore

6-17

210911

I

THE 8087 NUMERIC PROCESSOR EXTENSION

that is best-suited for most applications, is.the full 64
bits. The other settings are required by the proposed
IEEE standard, and are provided to obtain compatibility with the specifications of certain existing
programming languages. Specifying less precision
nullifies the advantages of the temporary real format's extended fraction length, and does not improve execution speed. When reduced precision is
specified, the rounding of the fractiqn zeros the
unused bits on the right.

Exceptions
During the execution of most instructions, the 8087
checks for six classes of exception conditions.
The 8087 reports invalid operation if any of the following occurs:
•

An attempt to load a register that is not
empty, (e.g., Stack overflow),

•

An attempt to pop an operand from an empty
register (e.g., stack underflow),

•

An operand is a NAN,

•

The operands cause the operation to be indeterminate (0/0, square root of a negative
number, etc.).

Infinity Control
The 8087's system of real numbers may be closed by
either of two moliels of infinity. These two me.ans of
closing the number system, projective and affine
closure, are illustrated schematically in Figure 6-12.
The setting of the IC field in the control word selects
one model or the other. The default means of closure is projective, and this is recommended for most
computations. When projective closure is sele,cted,
the NPX treats the special values + 00 afld -00 as a
singl" unsigned infinity (similar to its treatment of
signed zeros). In the affine mode the Nf>X respects
the signs of +00 and -00.

-

·
0

+

.

o

PROJECTIVE CLOSURE

.

An invalid operation generally indicates a program
error.
If the exponent of the true result is too large for the
destination real format, the 8087 signals overflow.
Conversely, a true exponent that is too small to be
represented results in the underflow exception. If
either of these occur, the result of the opetation is
outside the range of the destination real format.
Typical algorithms are most likely to produce extremely large and small numbers in·ttle calculation
of intermediate, rather than final, results. Because
of the great range of the temporary real format
(recommended as the destination format for
intermediates), overflow and underflow are relatively rare events in'most 8087 applications.

+00
+
.~~.-------~------~~

If division of a finite non-zero operand by zero is
attempted, the 8087 reports the zerodivide exception.

AFFINE CLOSURE

If an instruction attempts to operate on a denormal,
the NPX reports the denormalized exception. This exception is provided for users who wish to
implement, in software, an option of the proposed
IEEE standard which specifies that operands must
be prenormalized before they ,are used.

Figure 6-12 Projective Versus Affine Closure

While affine mode may provide more information
than projective, there are occasions when the sign
maY in fact represent misinformation. For example,
consider an algorithm that yields an intermediate
result x of +0 ,and -0 the (the same numeric value)
in different executions. If IIx were then computed
in affine mode, two entirely different values (+00
and - 00) would result from numerically identical
values of x. Projective mode on the other hand, provides less information but never returns
misinformation. In general, then, projective mode
should be used globally, with affine mode reserved
for local computations where the programmer can
take advantage of the sign and knows for certain that
the nature of the computation will not produce misleading results.

If the result of an operation is not exactly representable in the destination format, the 8087 rounds the
number and reports the precision exception, This exception occurs frequently and indicates that some
(generally acceptable) accuracy has been lost; it is
provided for applications that need to perform exact
arithmetic only.
Invalid operation, zerodivide, and denormalized exceptions are detected before an operation begins,
while overflow, underflow, and precision exceptions
are not raised until a true result has been computed.
6-18

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

When a "before" exception is detected, the register
stack and memory have not yet been updated, and
appear as if the offending instruction has not been
executed. When an "after" exception is detected,
the register stack and memory appear as if the instruction has run to completion, i.e., they may be
updated. (However, in a store or store and pop
operation, unmasked over/underflow is handled
like a "before" exception; memory is not updated
and the stack is not popped.) In cases where multiple
exceptions arise simultaneously, one exception is
signaled according to the following precedence
sequence:
•

Denormalized (if unmasked),

•

Invalid operation,

•

Zerodivide

•

Denormalized (if masked),

•

Over/underflow,

•

Precision

(The terms "masked" and "unmasked" are explained shortly.) This means, for example, that zero
divided by zero will result in an invalid operation
and not a zerodivide exception.
The 8087 reports an exception by setting the corresponding flag in the status word to 1. It then checks
the corresponding exception mask in the control
word to determine if it should "field" the exception
(mask = 1), or if it should issue an interrupt request
to invoke a user-written exception handler
(mask = 0). In the first case, the exception is said to
be masked (from user software) and the NPX executes its on-chip masked response for that exception.
In the second case, the exception is unmasked, and
the processor performs its unmasked response. The
masked response always produces a standard result
and then proceeds with the instruction. The unmasked response always traps to user software by interrupting the CPU (assuming the interrupt path is
clear). These responses are summarized in Table
6-6. Section 6.7 contains a complete description of all
exception conditions and the NPX's masked
responses. Note that when exceptions are masked,
the NPX may detect multiple exceptions in a single

Table 6-6 Exception and Response Summary
Exception

Masked Response

Unmasked Response

Invalid
Operation

If one operand is NAN, retu rn it; if
both are NANs, return NAN with
larger absolute value; if neither is
NAN, return indefinite.

Request interrupt.

Zerodivide

Return 00 signed with "exclusive
or" of operand signs.

Request interrupt.

Denormalized

Memory operand: proceed as
usual. Register operand: convert
to valid unnormal, then re-evaluate
for exceptions.

Request interrupt.

Overflow

Return properly signed

Register destination: adjust
exponent', store result, request
interrupt. Memory destination:
request interrupt.

Underflow

Denormalize result.

Register destination: adjust
exponent', store result, request
interrupt. Memory destination:
request interrupt.

Precision

Return rounded result.

Return rounded result, request
interrupt.

00.

6-19

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

instruction, since it continues executing the instruction after performing its masked response. For
example, the 8087 could detect a denormalized
operand, perform its masked response to this
exception, and then detect an underflow.
By writing different values into the exception masks
of the control word, the user can accept responsibility for handling exceptions, or delegate this to the
NPX. Exception handling software is often difficult
to write, and the 8087's masked responses have
been tailored to deliver the most "reasonable"
result for each condition. The majority of applications will find that masking all exceptions other than
invalid operation will yield satisfactory results with
the least programming investment. An invalid operation exception normally indicates a fatal error in a
program that must be corrected; this exception
should not normally be masked.

If the NPX executes an unmasked response to an
exception, it is assumed that a user exception handier will be invoked via an interrupt from the 8087.
The 8087 sets the IR (interrupt request) bit in the
status word, but this, in itself, does not guarantee an
immediate CPU interrupt. The interrupt request
may be blocked by the IEM (interrupt-enable mask)
in the 8087 control word, by the 8259A Programmable Interrupt Controller, or by the CPU itself. If any

Store the 8087 environment (control, status
and tag words, operand and instruction
pointers) as it existed at the time of the
exception;

•

Clear the exception bits in the status word;

•

Enable interrupts on the CPU;

•

Identify the exception by examining the
status and control words in the saved
environment;

•

Take application-dependent action;

•

Return to the point of interruption, resuming
normal execution.

Possible "application-dependent actions" include:

The exception flags are "sticky" and can be cleared
only by executing the FCLEX (clear exceptions)
instruction, by reinitializing the processor, or by
overwriting the flags with an FRSTOR or FLDENV
instruction. This means that the flags can provide a
cumulative record of the exceptions encountered in
a long calculation. A program can therefore mask all
exceptions (except, typically, invalid operation), run
(he calculation and then inspect the status word to
see is any exceptions were detected at any point in
the calculation.
Note that the 8087 has another set of internal exception flags that it clears before each instruction. It is
these flags and not those in the status word that actually trigger the 8087's exception response. The flags
in the status word provide a cumulative record of exceptions for the programmer only.

•

•

Incrementing an exception counter for later
display or printing;

•

Printing or displaying diagnostic information
(e.g., the 8087 environment and registers);

•

Aborting further execution of the calculation
causing the exception;

•

Aborting all further execution;

•

Using the exception pointers to build an instruction that will run without exception and
executing it;

•

Storing a diagnostic value (a NAN) in the
result and continuing with the computation.

Notice that an exception mayor may not constitute
an error, depending on the application. For
example, an invalid operation caused by a stack
overflow could signal an ambitious exception handler to extend the register stack to memory and continue running.

6.5 INSTRUCTION SET
This section describes the operation of each of the
8087's 69 instructions. The first part of the section
describes the function of each instruction in detail.
For this discussion, the instructions are divided into
six functional groups: data transfer, arithmetic,
comparisons, transcendental, constant, and processor control. The second part provides instruction attributes such as execution speed, bus transfers, and
exceptions, as well as coding example for each combination of operands accepted by the instruction.
This information is concentrated in a table, organized alphabetically by instruction mnemonic, for
easy reference.

exceptionjlag is unmasked. it is imperative that the interrupt path to the CPU is eventually cleared so that the
user's software canfield the exception and the oj/ending
task can resume execution. Note that the 8087 remains

"busy" pending CPU intervention. Interrupts are
covered in detail in Volume 2.
A user-written exception handler takes the form of
an 8086,88/186,188 interrupt procedure. Although
exception handlers will vary widely from one application (0 the next, most will include these basic steps:
6-20

210911

THE 8087 NUMERIC PROCESSOR EXTENSION
.~

i

FADD
FADD source

Throughout this section, the instruction set is described as it appears to the ASM-86 programmer
who is coding a program. Appendix A, in Volume 2
of this set, covers the actual machine instruction
encodings, which are principally of use to those reading unformatted memory dumps, monitoring instruction fetches on the bus, or writing exception
handlers.

:~I'~:
..

FADD destination. source

When reading this section, it is important to bear in
mind that memory operahds may be coded with any
of the CPU's memory addressing modes. Table 6-20
in this chapter also provides several addressing
mode examples.

The instruction descriptions in this section concentrate on describing the normal function of each
operation. Table 6-17 lists the exceptions that can
occur for each instruction and Table 6-30 details the
causes of exceptions as well as the 8087's masked
responses.

Data Transfer Instructions
These instructions (summarized in Table 6-7) move
operands among elements of the register stack, and
between the stack top and memory. Any of the
seven data types can be converted to temporary real
and loaded (pushed) onto the stack in a single
operation; they can be stored to memory in the
same manner. The data transfer instructions automatically update the 8087 tag word to reflect the
register contents following the instruction.

The typical NPX instruction accepts one or two operands as "inputs", operates on these, and produces a
result as an "output". Operands are most often (the
contents of) register of memory locations. The operands of some instructions are predefined; for
example, FSQRT always takes the square root of the
number in the top stack element. Others allow, or
require, the programmer to explicitly code the
operand(s) along with the instruction mnemonic.
Still others accept one explicit operand and one
implicit operand, which is usually the top stack
element.

Table 6- 7 Data Transfer Instructions
Real Transfers

Whether supplied by the programmer or utilized
automatically, there are two basic types of operands,
sources and destinations. A source operand simply
supplies one of the "inputs" to an instruction; it is
not altered by the instruction. Even when an instruction converts the source operand from one format to
another (e.g., real to integer), the conversion is actually performed in an internal work area to avoid altering the source operand. A destination operand
may also provide an "input" to an instruction. It is
distinguished from a source operand, however, because its contents may be altered when it receives
the result produced by the operation; that is, the
destination is replaced by the result.

FLD
FST
FSTP
FXCH

Load real
Store real
Store real and pop
Exchange registers
Integer Transfers

FILD
FIST
FISTP

Integer load
Integer store
Integer store and pop
Packed Decimal Transfers

FBLD
FBSTP

Many instructions allow their operands to be coded
in more than one way. For example, FADD (add
real) may be written without operands, with only a
source or with a destination and a source. The instruction descriptions in this section employ the
simple convention of separating alternative operand
forms with slashes; the slashes, however, are not
coded. Consecutive slashes indicate an option of no
explicit operands. The operands for FADD are thus
described as:
/ / source/destination, source

This means that FADD may be written in any of
three ways.
6-21

Packed decimal (BCD) load
Packed decimal (BCD) store and pop

FLO source
FLD (load real) loads (pushes) the source operand
onto the top of the register stack. This is done by decrementing the stack pointer by one and then copying the contents of the source to the new stack top.
The source may be a register on the stack (STG» or
any of the real data types in memory. Short and long
real source operands are converted to temporary
real automatically. Coding FLD SI(O) duplicates the
stack top.
210911

THE 8087 NUMERIC PROCESSOR EXTENSION

FST destination

FIST destination

FST (store real) transfers the stack top to the
destination, which may be another register on the
stack, or a short or long real m,emory operand. If the
destination is short or long real, the significand is
rounded to the width of the destination according to
the RC field of the control word, and the exponent
is converted to the width and bias of the destination
format.

FIST (integer store) rounds the contents of the
stack top to an integer according to the RC field of
the control word and transfers the result to the
destination. The destination may define a word or
short integer variable. Negative zero is stored in the
same encoding as positive zero: 0000 ... 00.

FISTP destination

If, however, the stack top is tagged special (it
contains, a NAN, or a denormal) then the stack
top's significand is not rounded but is chopped (on
the right) to fit the destination. Neither is the exponent converted, but it also is chopped on the right
and transferred "as is". This preserves the value's
identification as or a NAN (exponent all ones) or a
denormal (exponent all zeros) so that it can be properly loaded and tagged later in the program if desired.

FISTP (integer store and pop) operates like FIST
and also pops the stack following the transfer. The
destination may be any of the binary integer data
types.

FBLD source

FSTP destination

FSTP (store real and pop) operates identically to
FST except that the stack is popped following the
transfer. This is done by tagging the top stack element empty and then incrementing ST. FSTP permits storing to a temporary real memory variable
while FST does not. Coding FSTP ST(O) is equivalent to popping the stack with no data transfer.

FXCHlldestination

FBLD (packed decimal (BCD) load) converts the
contents of the source operand from packed decimal
to temporary real and loads (pushes) the result onto
the stack. The sign of the source is preserved, including the case where the value is negative zero. FBLD
is an exact operation; the source is loaded with no
rounding error.
The packed decimal digits of the source are assumed
to be in the range 0-9H. The instruction does not
check for invalid digits (A-FH) and the result of attempting to load an invalid encoding is undefined.

FBSTP destination

FXCH (exchange registers) swaps the contents of
the destination and the stack top registers. If the
destination is not coded explicitly, ST(1) is used.
Many 8087 instructions operate only on the stack
top; FXCH provides a simple means of effectively
using these instructions on lower stack elements.
For example, the follqwing sequence takes the
square root of the third register from the top:

FBSTP (packed decimal (BCD) store and pop) converts the contents of the stack top to a packed decimal integer, stores the result at the destination in
memory, and pops the stack. FBSTP produces a
rounded integer from a non-integral value by adding
a value close to 0.5 to the value and chopping. Users
who are concerned about rounding may precede
FBSTP with FRNDINT.

FXCH ST(3)
FSQRT
FXCH ST(3)

Arithmetic Instructions
FILD source

FILD (integer load) converts the source memory
operand from its binary integer format (word, short,
or long,) to temporary real and loads (pushes) the
result onto the stack. The (new) stack top is tagged
zero of all bits in the source were zero, and is tagged
valid otherwise.
6-22

The 8087's arithmetic instruction set (Table 6-8)
provides a wealth of variations on the basic add,
subtract, multiply, and divide operations, and a
number of other useful functions. These range from
a simple absolute value to a square root instruction
that executes faster than ordinary division; 8087 programmers no longer need to spend valuable time
eliminating square roots from algorithms because
210911

THE 8087 NUMERIC PROCESSOR EXTENSION

they run too slowly. Other arithmetic instructions
perform exact modulo division, round real numbers
to integers, and scale values by powers of two.
The 8087's basic arithmetic instructions (addition,
subtraction, multiplication, and division) are
designed to encourage the development of very efficient algorithms. In particular, they allow the programmer to minimize memory references and to
make optimum use of the NPX register stack.

Table 6-8 Arithmetic Instructions

Table 6-9 summarizes the available operation/operand forms that are provided for basic arithmetic. In
addition to the four normal operations, two
"reversed" instructions make subtraction and division "symmetrical" like addition and multiplication.
The variety of instruction and operand forms give
the programmer unusual flexibility:
•

operands may be located in registers or
memory;

•

results may be deposited in a choice of
registers;

•

operands may be a variety of NPX data types:
temporary real, long real, short real, short
integer or word integer, with automatic conversion to temporary real performed by the
8087.

Addition
FADD
FADDP
FIADD

Add real
Add real and pop
Integer add

Five basic instruction forms may be used across all
six operations, as shown in Table 6-9. The classical
stack form may be used to make the 8087 operate
like a classical stack machine. No operands are
coded in this form, only the instruction mnemonic.
The NDP picks the source operand from the stack
top and the destination from the next stack element.
It then pops the stack, performs the operation, and
returns the result to the new stack top, effectively
replacing the operands by the result. (Note that
FADD, FSUB, FMUL and FDIV also pop ifno operands are specified, in spite of the fact that the
mnemonics do not have P as a last character.)

Subtraction
FSUB
FSUBP
FISUB
FSUBR
FSUBRP
FISUBR

Su btract real
Subtract real and pop
Integer subtract
Subtract real reversed
Subtract real reversed and pop
Integer subtract reversed
Multiplication

FMUL
FMULP
FIMUL

Multiply real
Multiply real and pop
Integer multiply

The register form is a generalization of the classical
stack form; the programmer specifies the stack top
as one operand and any register on the stack as the
other operand. Coding the stack top as the destination provides a convenient way to access a constant,
held elsewhere in the stack, from the stack top. The
converse coding (ST is the source operand) allows,
for example, adding the top into a register used as an
accumulator.

Division
FDIV
FDIVP
FIDIV
FDIVR
FDIVRP
FIDIVR

Divide real
Divide real and pop
Integer divide
Divide real reversed
Divide real reversed and pop
Integer divide reversed
Other Operations

FSQRT
FSCALE
FPREM
FRNDINT
FXTRACT
FABS
FCHS

Often the operand in the stack top is needed for one
operation but then is of no further use in the
computation. The register pop form can be used to
pick up the stack top as the source operand, and then
discard it by popping the stack. Coding operands of
ST(1),ST with a register pop mnemonic is equivalent
to a classical stack operation: the top is popped and
the result is left at the new top.

Square root
Scale
Partial remainder
Round to integer
Extract exponent and significand
Absolute value
Change sign
6-23

210911

THE 8087 NUMERIC PROCESSOR>EXTENSION

Table 6-9 Basic Arithmetic Instructions and Operands
Instruction Form

Classical stack
Register

Operand Forms
destination, source

Mnemonic
Form

Fop
Fop

ASM-86 Example

{ST(1),Sn

FADD

ST(I),ST or ST,ST(I)

FSUB

ST,ST(3)

Register pop

FopP

ST(I),ST

FMULP ST(2),ST

Real memory

Fop

{ST,} short-realilong-real

FDIV

AZIMUTH

Integer memory

Flop

{ST,} word-integerlshort-integer

FIDIV

N_PULSES

NOTES: Braces { } surround implicit operands; these are not coded, and are shown
here for information only.

op = ADD destination +- destination + source
SUB
SUBR
MUL
DIV
DIVR

destination +- destination - source
destination +- source - destination
destination +- destination • source
destination +- destination';' sou rce
destination +- source.;. destination

Normal Subtraction

The two memory forms increase the flexibility of the
8087's arithmetic instructions. They permit a real
number or a binary integer in memory to be used
directly as a source operand. This is a very useful
facility in situations where operands are not used frequently enough to justify holding them in registers.
Note that any memory addressing mode may be
used to define these operands, so they may be elements in arrays, structures or other' data
organizations, as well as simple scalars.

FSUB
FSUBP
FISUB

Iisourceidestination, source
destination, source
source

The normal subtraction instructions (subtract real,
subtract real and pop, integer subtract) subtract the
source operand from the destination and return the
difference to the destination.
Reversed Subtraction

The six basic operations are discussed further in the
next paragraphs, and descriptions of the remaining
seven arithmetic operations follow.

FSUBR
FSUBRP
FISUBR

Iisourceidestination,source
l/destination, source
source

The reversed subtraction instruction (subtract real
reversed, subtract real reversed and pop, integer
subtract reversed) subtract the destination from the
source and return the difference to the destination.
Addition
Multiplication
FADD
FADDP
FIADD

Iisourceidestination,source
destination, source
source

FMUL
FMULP
FIMUL

The addition instructions (add real, add real and
pop, integer add) add the source and destination
operands and return the sum to the destination. The
operand at the stack top may be doubled by coding:
FADD ST,ST(O)

6-24

Iisourceidestination, source
destination, source
source

The mulitplication instructions (multiply real, multiply real and pop, integer multiply) multiply the
source and destination operands and return the product to the destination. Coding FMUL ST,ST(O)
squares the contents of the stack top.
210911

THE 8087 NUMERIC PROCESSOR EXTENSION

FPREM operates by performing successive scaled
subtractions; obtaining the exact remainder when
the operands differ greatly in magnitude can consume large amounts of execution time. Since the
8087 can only be preempted between instructions,
the remainder function could seriously increase interrupt latency in these cases. Accordingly, the instruction is designed to be executed iteratively in a
software-controlled loop.

Normal Division
FDiV
FDlVP
FIDIV

Iisourceidestination,source
destination, source
source

The normal division instructions (divide real, divide
real and pop, integer divide) divide the destination
by the source and return the quotient to the
destination.
Reversed Division
FDIVR
FDIVRP
FIDIVR

FPREM can reduce a magnitude difference of up to
264 in one execution. If FPREM produces a remainder that is less than the modulus, the function is
complete and bit C2 of the status word condition
code is cleared. If the function is incomplete, C2 is
set to 1; the result in ST is then called the partial
remainder. Software can inspect C2 by storing the
status word following execution of FPREM and reexecute the instruction (using the partial remainder
in ST as the dividend), until "C" is cleared.
Alternatively, a program can determine when the
function is complete by comparing ST to STU). If
ST> ST(1) then FPREM must be executed again; if
ST=ST(1) then the remainder is 0; if ST source
0 1 ST< source
1 0 0 ST=source
1 I I ST? source

NANs and 00 (projective) cannot be compared and
return C3 =CO= I as shown above.

FCOMP//source

FXAM

FXAM (examine) reports the contents of the top
stack element as positive/negative and NAN/unnormal/denormal/normallzero, or empty. Table 6-11
lists and interprets all the condition code values that
FXAM generates. Although four different encodings
may be returned for an empty register, bits C3 and
CO of the condition code are both 1 in all encodings.
Bits C2 and Cl should be ignored.

Table 6-11 FXAM Condition Code Settings

FCOMP (compare real and pop) operates like
FCOM, and in addition pops the stack.

FCOMPP

FCOMPP (compare real and pop twice) operates
like FCOM and additionally pops the stack twice, discarding both operands. The comparison is of the
stack top to ST(l); no operands may be explicitly
coded.

Condition Code

Interpretation

C3

C2

C1

CO

0

0

0

0

0

0

0

1

+ NAN

0

0

1

0

- Unnormal

0

0

1

1

- NAN

0

1

0

0

+ Normal

0

1

0

1

+00

+ Unnormal

0

1

1

0

- Normal

FICOMsource

0

1

1

1

-00

FICOM (integer compare) converts the source
operand, which may reference a word or short
binary integer variable, to temporary real and compares the stack top to.it.

1

0

0

0

+0

1

0

0

1

Empty

1

0

1

0

-0

1

0

1

1

Empty

1

1

0

0

+ Denormal

1

1

0

1

Empty

1

1

1

0

- Denormal

1

1

1

1

Empty

FICOMPsource

FICOMP (integer compare and pop) operates identically to FICOM and additionally discards the value
in ST by popping the stack.

FTST

Transcendental I nstructions

FTST (test) tests the top stack element by comparing
it to zero. The result is posted to the condition codes
as follows:

The instructions in this group (Table 6-12) perform
the time-consuming core calculations for all common
trigonometric, hyperbolic, inverse hyperbolic, logarithmic and exponential functions. Prologue and epilogue software may be used to reduce arguments to
the range accepted by the instructions and to adjust
the result to correspond to the original arguments if
necessary. The transcendentals operate on the top
one or two stack elements and they return their results to the stack also.

C3 C2 CO Result

o
o

0 0 ST is positive and nonzero
0 1 ST is negative and nonzero
1 0 0 ST is zero (+ or - )
1 lIST is not comparable (i.e., it is a NAN or projective 00)
6-27

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

Table 6-12 Transcendental Instructions

FPTAN

Partial tangent

FPATAN

Partial arctangent

F2XM1

2L1

FYL2X

Y e lOQ2X

FYL2XP1

Y e IOQ2(X+1)

F2XM1

F2XMI (2 to the X minus 1) calculates the function
Y = 2X-1. X is taken from the stack top and must
be in the range 0~X~0.5. The result Y replaces X
at the stack top.
This instruction is designed to produce a very accurate result even when X is close to zero. To obtain
Y = 2" add 1 to the result delivered by F2XM 1.
The following formulas show how values other than
2 may be raised to a power of X:

The transcendental instructions assume that their
operands are valid and in-range. The instruction descriptions in this section provide the range of each
operation. To be considered valid, an operand to a
transcendental must be normalized; denormals,
unnormals, infinities and NANs are considered
invalid. (Zero operands are accepted by some functions and are considered out-of-range by others') If
a transcendental operand is invalid or out of range,
the instruction will produce an undefined result without signalling an exception. It is the programmer's
responsibility to ensure that operands are valid and
in-range before executing a transcendental. For
periodic functions, FPREM may be used to bring a
valid operand into range.

As shown in the next section, the 8087 has built-in
instructions for loading the constants LOG 2 10 and
LOG 2e, and the FYL2X instruction may be used to
calculate X . LOG 2Y.
FYL2X

Y/X = TAN (8). 8 is taken from the top of the

FYL2X (Y log base 2 of X) calculates the function Z
= YLOG X. X is taken from the stack top and y
from ST(f). The operands must be in the ranges
OB

FTST
±o
FCHS
+0
-0
FABS
±O
F2XM1
+0

+0
-0
'0 (5)
'0 (5)

tx (6)

-0

+0
-0
+0
-0
-0
+0
+0, underflow (7)
-0, underflow (7)

FRNDINT
+0
-0
FXTRACT
+0
-0

Zero
-0
+0
+0
+0
-0
+0
-0
Both +0
Both -0

Notes:
Arithmetic and compare operations with real memory operands interpret the memory operand signs in
the same way.
(2) Arithmetic and compare operations with binary integers interpret the integer sign in the same manner.
(3) Severe underflows in storing to short or long real may generate zeros.

(1)

(4)
(5)

(6)

Small values (lxl < 1) stored into integers may round to zero.
Sign is determined by rounding mode:
• = + for nearest, up or chop
• = -fordown
t = sign of X.
6-61

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

Infinities

NANs

The real formats support signed representations of
infinities. These values are encoded with a biased
exponent of all ones and a significand of I b" 00 ...00;
ifthe infinity is in a register, it is tagged special. The
significand dIstinguishes infinities from NANs,
including real indefinite.

A programmer may code an infinity, or it may be
created by the NPX: as its masked response to an
overflow or a zerodivide exception. Note that when
rounding is up or down, the masked response may
create the largest valid value representable in the
destination rather than infinity. See Table 6-31 for
details. As operands, infinities behave somewhat differently depending on how the infinity control field
in the control word is set (see Table 6-25). When the
projective model of infinity is selected, the infinities
behave as a single unsigned representation; because
of this, infinity cannot be compared with any value
except infinity. In affine mode, the signs of the infinities are observed, and comparisons are possible.·'

. A NAN (Not-A-Number) is a member of Ii class of
special values that exist in the real formats only. A
NAN has an exponent of 11...llB, may have either
sign, and may have any significand except I b"
OO ...OOB, which is assigned to the infinities. A NAN
in a register is tagged special.
.
The 8087 will generate the special NAN, . real
indefinite, as its masked response to an invaiid operation exception. This NAN is signed negative; its sig. nificand is encoded I b" 100... 00. All other NANs
represent programmer-created values.
Whenever the NPX uses an operand that is a NAN,
it signals invalid operation. Its masked response to
this exception is to return the NAN as the operation's result. If both operands of an instruction are
NANs, the result is the NAN with the largerabsolute value. In this way, a NAN that enters a computation propagates through the computation and will
eventually be delivered as the final result. Note,
however, that the transcendental instructions do not
check their operands, and a NAN will produce an undefined result.

Table 6-25 Infinity Operands and Results

Operation
Division
±oo + ±oo
±oo + ±X
±X + ±oo

Projective Result
Invalid operation
e~

eo

Affine Result
Invalid operation·

eoc?

.

~o

FSQRT
-00
+00

Invalid operation
Invalid operaton

Invalid operation
+00

FPREM
±oo rem ±oo
±oorem ±X
±Y rem ±oo
±O rem ±oo

Invalid operation
Invalid operation
*Y
*0

: Invalid operation
Invalid operation
*Y
*0

FRNDINT
±oo

*00

*00

FSCALE
±oo scaled by ±oo
±oo scaled by ±X
±O scaled by ±oo
± Y scaled by ±oo

Invalid operation
*00
*0
Invalid operation

Invalid operation
*00
*.0
Invalid operation

6-62

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

Table 6-25 Infinity Operands and Results (continued)

Operation
FXTRACT
±oo
Compare
±oo:±oo
±oo:±Y
±oo : ±O
FTST
±oo
Addition
+00 plus+oo
-00 plus -00
+00 plus-oo
-00 plus +00
±oo plus ±X
±X plus ±oo
Subtraction
+00 minus-oo
-00 minus +00
+00 minus +00
-00 minus -00
±oo minus ±X
±X minus±oo
Multiplication
±oo • ±oo
±oo. ±Y
±O • ±oo I ±oo * ±O

Projective Result

Affine Result

Invalid operation

Invalid operation

A=B
A ? B (and) invalid
operation
A ? B (and) invalid
operation

-00<+00
-00 <

Y<

+00

-00 <

0<

+00

A? B (and) invalid
operation

*00

Invalid
Invalid
Invalid
Invalid

operation
operation
operation
operation

*00
*00

Invalid
Invalid
Invalid
Invalid

+00
-00

Invalid operation
Invalid operation
*00
*00

operation
operation
operation
operation

+00
-00

Invalid operation
Invalid operation

*00

*00

too

too

$00

$00

(Doo
Invalid operation

Invalid operation

$00

Notes: X = zero or nonzero operand
Y = nonzero operand
• = sign of original operand

t = sign is complement of original operand's sign
$=

sign is "exclusive or" original operand signs (+ if operands had same sign,
- if operands had different signs)

By unmasking the invalid operation exception, the
programmer can use NANs to trap to the exception
handler. The generality of this approach and the
large number of NAN values that are available, provide the sophisticated programmer with a tool that
can be applied to a variety of special situations.

For example, a compiler could use NANs to reference uninitialized (real) array elements. The compiler could pre-initialize each array element with a
N AN whose significand contained the index
(relative position) of the element. If an application
program attempted to access an element that it had
6-63

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

not initialized, it would use the NAN placed there by
the compiler. If the invalid operation exception
where unmasked, an interrupt would occur, and the
exception handler would be invoked. The exception
handler could determine which element had been
accessed, since the operand address field of the exception pointers would point to the NAN, and the
NAN would contain the index number of the array
element.
NANs could also be used to speed up debugging. In
its early testing phase, a program often contains
multiple errors. An exception handler could be written to save diagnostic information in memory whenever it was invoked. After storing the diagnostic
data, it could supply a NAN as the result of the erroneous instruction, and that NAN could point to its
associated diagnostic area in memory. The program
would then continue, creating a different NAN for
each error. When the program ended, the NAN results could be used to access the diagnostic data
saved at the time the errors occurred. Many errors
could thus be diagnosed and corrected in one test
run.

right and are stored in the lowest memory
addresses. The sign bit is always the left-most bit of
the highest-addressed byte.
Notice that in every format, one encoding is interpreted as representing the special value indefinite.
The 8087 produces this encoding as its response to a
masked invalid operation exception. In the case of
the reals, indefinite can be loaded and stored like any
NAN and it always retains its special identity; programmers are advised not to use this encoding for
Table 6-26 Binary Integer Encodings

Class
III

GI

(Largest)

~

'iii
0

Q.

III

GI

0

11 ... 11

•
•
•

•

•
•

0
0
1

00 ... 01
00 ... 00
11 ... 11

(Largestllndefinite' )

1

00 ... 00

til

z

Magnitude

(Smallest)
Zero
(Smallest)

~
t\1
GI

Data Type Encoding

Sign

•
•
•

•
•
•

Word: ~15 bits-..l
Short: ~31 bits-.t
Long: ~ 63 bits ~

Tables 6-26 through 6-29 summarize how various
types of values are encoded in the seven NPX data
types. In all tables, the less significant bits are to the
Table 6-27 Packed Decimal Encodings

Class

III

i,~

III

.~

(Largest)

o
•
•

~--------+------+~~~-+~------~--~--~--~------~--~~~~~~~~~~

i

GI

Z

9 bytes
• The packed decimal indefinite encoding is stored by FBSTP in response to a masked invalid
operation exception. Attempting to load this value via FBLD produces an undefined result.
Note: "UUUU" means bit values are undefined and may contain any value,
6-64

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

Table 6-28 Real and Long Real Encodings

e....

Sign

..

I

Normals

•
1
a:

Denormals

Zero

..

Class
Zero

Denormais

..

1ft

Oi

a:

.
•r
z

Normals

1ft

.!:

00

to

~

Z

I Indefinite

Slgnlflcand"

·
··
··

11 ...11

···
0

11...11

00 ... 01

0

11...11

00 ... 00

··
·
·
··
0

11...10

11 ...11

0

00 ... 01

0

00... 00

00 ... 00
11 ... 11

0

00 ... 00

00 ... 01

·

···

00... 00

00 ... 00

Sign

Significand"

00 ... 00

00 ... 00

1

00 ... 00

1

00 ... 00

11 ... 11

1

··
·
··
·

00 ... 01

00 ... 01

00 ... 00

··
·
···
1

11...10

11...11

1

11...11

00 ... 00

1

11...11

··
·
···

00 ... 01

··
·
1

11 ... 11

NANs

;;

...
0

00

··
·
···
·
··
···

..

1ft

.!:

...

I Zero
Re.ls

I Zero

Biased
Exponent

Signitlcand
16fl..ff

···

··
·
0

11 ... 11

111...11

0

11 ... 11

100 ... 01

0

11 ... 11

100 ... 00

0

11 ... 10

Normals
111...11

"

ii0

f-

Sign

···
···
··
···
·

6""'"

1

11 ... 11

II

·
··
··
·

Biased
Exponenl

1

..
!

···

0

···

Class

6H... H

11...11

0

NANs

lined
Exponent

Table 6-29 Temporary Real Encodings

··
··
···
··
···
·

·
··

····

100 ... 00

Unnormals
011...11

··
·

0

00 ... 01

··
·
0

00 ... 00

011...11

0

··
·

00 ... 00
00 ... 00

000 ... 01

00 ... 00

000 ... 00

0
1

000 ... 00
Denormals

··
·

000 ... 00

Denormals

·
··
··
··
··
·
·
····

..

1ft

10 ... 00

~

r
z

11...11

Short. ~8 blts~23 blls~
Long: t - l l blts~52 bits~
• Integer bit is implied and not stored.

00 ... 00

000 ... 01

1

00 ... 00

011 ... 11

1

00 ... 01

Unnormals
000 ... 00

1

..

co
.!:

•r

z

NANs

I Indefinite

··
"

011...11

Normals

···

100... 00

111...11

1

11 ...11

100 ... 00

1

11 ... 11

110... 00

11 ... 11

111...11

···
··

·
1

6-65

··
··
··
··
···
·

···

11...10
11...11

1

00

·
··

1

··
·
···

100 ... 00

··
·
···

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

any other purpose. Packed decimal indefinite may be
stored by the NPX in a FBSTP instruction; attempting to use this encoding in a FBLD instruction,
however, will have an undefined result. In the
binary integers, the same encoding may represent
either indefinite or the largest negative number supported by the format (_2 15 , _2 31 or _263). The
8087 will store this encoding as its masked response
to an invalid operation, or when the value in a
source register represents, or rounds to, the largest
negative integer representable by the destination. In
situations where its origin may be ambiguous, the invalid operation exception flag can be examined to
see if the value was produced by an exception
response. When this encoding is loaded, or used by
an integer arithmetic or compare operation, it is

always interpreted as a negative number; thus indefinite cannot be loaded from a packed decimal or
binary integer.

Exception Handling Details
Table 6-30 lists every exception condition that the
NPX detects and describes the processor's response
when the relevant exception mask is set. The unmasked responses are described in Table 6-6. Note
that if an unmasked overflow or underflow occurs in
an FST or FSTP instruction, no result is stored, and
the stack and memory are left as they existed before
the instruction was executed. This gives an exception
handler the opportunity to examine the offending
operand on the stack top.

Table 6-30 Exception Conditions and Masked Responses

Masked Response

Condition
Invalid Operation
Source register is tagged empty (usually
due to stack underflow).

Return real indefinite.

Destination register is not tagged empty
(usually due to stack overflow).

Return real indefinite (overwrite
destination value).

One or both operands is a NAN.

Return NAN with larger absolute value
(ignore signs).

(Compare and test operations only):
one or both operands is a NAN.

Set condition codes "not comparable".

(Addition operations only): closure is
affine and operands are opposite-signed
infinities; or closure is projective and both
operands are 00 (signs immaterial).

Return real indefinite

(Subtraction operations only): closure is
affine and operands are like-signed
infinities; or closure is projective and both
operands are 00 (signs immaterial).

Return real indefinite.

(Multiplica.tion operations only):
O' 00.

Return real indefinite.

00'

0; or

(Division operations only): 00 .,. 00; or 0'" 0;
or 0 .,. pseudo-zero; or divisor is denormal
or unnormal.

Retu rn real indefinite.

Return real indefinite, set condition code

(FPREM instruction only): modulus
(divisor) is unnormal or denormal;
or dividend is 00.

= "complete remainder".

(FSQRT instruction only): operand is
nonzero and negative; or operand is
denormal or unnormal; or closure is affine
and operand is -00; or closure is projective
and operand is 00.

Return real indefinite.

6-66

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

Table 6-30 Exception Conditions and Masked Responses (continued)
Invalid Operation
(Compare operations only): closure is
projective and"" is being compared with 0
or a normal, or"".

Set condition code = "not comparable"

(FTST instruction only): closure is
projective and operand is "".

Set condition code = "not comparable".

(FIST, FISTP instructions only): source
register is empty, or a NAN, or denormal,
or unnormal, or 00, or exceeds representable range of destination.

Store integer indefinite.

(FBSTP instruction only): source register
is empty, or a NAN, or denormal, or
unnormal, or 00, or exceeds 18 decimal
digits.

Store packed decimal indefinite.

(FST, FSTP instructions onfy): destination
is short or long real and source register is
an unnormal with exponent in range.

Store 'real indefinite.

(FXCH instruction only): one or both
registers is tagged empty.

Change empty register(s) to real indefinite
and then perform exchange.
Denormalized Operand

(FLO instruction only): source operand is
denormal.

No special action; load as usual.

(Arithmetic operations only): one or both
operands is denormal.

Convert (in a work area) the operand to the
equivalent unnormal and proceed.

(Compare and test operations only): one
or both operands is denormal or unnormal
(other than pseudo-zero).

Convert (in a work area) any denormal to
the equivalent unnormal; normalize as
much as possible, and proceed with
operation.
Zerodivide

(Division operations only): divisor = O.

Return 00 signed with "exclusive or" of
operand signs.
Overflow

(Arithmetic operations only): rounding is
nearest or chop, and exponent of true
result> 16,383.

Return properly signed ooand signal
precision exception.

(FST, FSTP instructions only): rounding is
nearest or chop, and exponent of true
result> +127 (short real destination)
or> +1023 (long real destination).

Return properly signed
precision exception.

6-67

00

and signal

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

Table 6-30 Exception Conditions and Masked Responses (continued)

Underflow
(Arithmetic operations only): exponent of
true result <-16,382 (true).

Denormalize until exponent rises to
-16,382 (true), round significand to 64 bits.
If denormalized rounded significand =' 0,
then return true 0; else, return denormal
(tag = special, biased exponent =0).

(FST, FSTP instructions only): destination
is short real and exponent of true result
<-126 (true).

Denormalize until exponent rises to -126
(true), round significand to 24 bits, store
true 0 if denormalized rounded significand
= 0; else, store denormal (biased exponent = 0).

(FST, FSTP instructions only): destination
is long real and exponent of true result
<-1022 (true).

Denormalize until exponent rises to -1022
(true), round significand to 53 bits, store
true 0 if rounded denormalized significand
= 0; else, store denormal (biased exponent = 0).
Precision

True rounding error occurs.

No special action.

Masked response to overflow exception
earlier in instruction.

No special action.

When rounding is directed (the RC field of the control word is set to "up" or "down"), the 8087 handles a masked overflow differently than it does for
the "nearest" or "chop" rounding modes. Table
6-31 shows the NPX's masked response when the

true result is too large to be represented in it's destination real format. For a normalized result, the essence of this response is to deliver = or the largest
valid number representable in the destination
format, as dictated by the rounding mode and the

Table 6-31 Masked Overflow Response for Directed Rounding

True Result
Normalization

Sign

Rounding
Mode

Result Delivered

+00

Up

Normal

+
+

Normal

-

Up
Down

-00
+00

Normal

Normal

-

Unnormal

+

Up

Unnormal

-

Down

Unnormal

+
-

Down

Unnormal

Largest finite positive number(1)

Down

Largest finite negative number(1)

Largest exponent, result's significand(2)
Largest exponent, result's significand(2)

Up

-00

(1) The largest valid representable reals are encoded:
exponent: 11 ... 1OB
significand: (1) ~ 11 ... 1OB
(2) The significand retains its identity as an unnormal; the true result is rounded as usual (effectively chopped toward
o in this case). The exponent is encoded 11 ... 1OB.

6-68

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

to implement conditional branching following a
comparison, the basic approach is as follows:

sign of the true result. Thus, when RC=down, a
positive overflow is rounded down to the largest
positive number. Conversely, when RC=up, a negative overflow is rounded up to the largest negative
number. A properly signed 00 is returned for a positive overflow with RC = up, or a negative overflow
with RC=down. For an unnormalized result, the
action is similar except that the unnormal character
of the result is preserved if the sign and rounding
mode do not indicate that 00 should be delivered.
In all masked overflow responses for directed
rounding, the overflow flag is not set, but the precision exception is raised to signal that the exact true
result has not been returned.

•

execute the comparison,

•

store the status word,

•

inspect the condition code bits,

•

jump on the result.

Figure 6-21 is a code fragment that illustrates how
two memory-resident long real numbers might be
compared (similar code could be used with the
FTST instruction). The numbers are called A and B,
and the comparison is A toB. The comparison itself
simply requires loading A onto the top of the 8087
register stack and then comparing it to B and popping
the stack in the same instruction. The status word is
written to memory and the code waits for completion
of the store before attempting to use the result.

6.8 PROGRAMMING EXAMPLES
Conditional Branching
As discussed in Section 6.5, the comparison instructions post their results to the condition code bits of
the 8087 status word. Although there are many ways

A
DQ?
B
DQ?
STAT 87 OW
?

FLO
A
;LOAD A ONTO TOP OF 87 STACK
FCOMP B
;COMPARE A:B, POP A
FSTSW STAT 87 ;S,TORE RESULT
FWAIT
;WAIT FOR STORE
;

;LOAD CPU REGISTER AH WITH BYTE OF
STATUS WORD CONTAINING CONDITION CODE
MOV
AH, BYTE PTR STAT 87+1
;LOAD CONDITION CODES INTO CPU FLAGS
SA HF'
;

;USE CONDITIONAL JUMPS TO DETERMINE
ORDERING OF A AND B
JB
A LESS OR UNORDERED
; CF (CO)-=
JNE
A_GREATER
A EQUAL:
;CF (CO) = 0, ZF (C3) =

°- -

A GREATER:
;CF (CO)

= 0,

ZF (C3)

=

°

Figure 6-21 Conditional Branching for Compares

6-69

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

A LESS OR_UNORDERED:
; CF (CO) = 1, TEST ZF (C3)
JNE
A_LESS
A B UNORDERED:
;CF (CO) = 1, ZF (C3) =

A LESS:
; CF (CO)

1, ZF (C3)

=0

Figure 6-21 Conditional Branching for Compares (continued)

There are four possible orderings of A and B, and
bits C3 and CO of the condition code indicate which
ordering holds. These bits are positioned in the
upper byte of the status word so as to correspond to
the CPU's zero and carry flags (ZF and CF), if the
byte is written into the flags (see Figures 3-28 and
6-6). The code fragment, then, sets ZF and CF to
the values of C3 and CO and then uses the CPU
conditional jumps to test the flags. Table 3-12 shows
how each conditional jump instruction tests the CPU
flags.

since there are four condition code settings that correspond to "empty."
The program fragment performs the FXAM and
stores the status word. It then manipulates the condition code bits to finally produce a number in register
BX that equals the condition code times 2. This involves zeroing the unused bits in the byte that contains the code, shifting C3 to the right so that it is
adjacent to C2, and then shifting the code to multiply
it by 2. The resulting value is used as an index which
selects one of the displacements from FXAM_TBL
(the multiplication of the condition code is required
because of the 2-byte length of each value in
FXAM_TBL). The unconditional lMP instruction
effectively vectors through the jump table to the
labeled routine that contains code (not shown in the
example) to process each possible result of the
FXAM instruction.

The FXAM instruction updates all four condition
code bits. Figure 6-22 shows how a jump table can
be used to determine the characteri~tics of the value
examined. The jump table (FXAM_TBL) is initialized to contain the 16-bit displacement of 16 labels,
one for each possible condition code setting. Note
that four of the table entries contain the same value,

FXAM TBL
&

&
&
&

STAT 87

OW POS_UNNORM, POS_NAN, NEG_UNNORM,
NEG_NAN, POS_NORM, POS_INFINITY,
NEG_NORM, NEG_INFINITY, POS_ZERO,
EMPTY, NEG_ZERO, EMPTY, POS_OENORM,
EMPTY, NEG_OENORM, EMPTY
OW ?

Figure 6-22 Conditional Branching for FXAM

6-70

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

;EXAMINE ST, STORE RESULT, WAIT FOR COMPLETION
FXAM
FSTSW
STAT_87
F'WA IT
;CLEAR UPPER HALF OF BX, LOAD CONDITION CODE
IN LOWER HALF
MOV
BH,O
MOV
BL, BYTE PTR STAT_87+1
;COPY ORIGINAL IMAGE
MOV
AL,BL
;CLEAR ALL BITS EXCEPT C2-CO
AND
BL,00000111B
;CLEAR ALL BITS EXCEPT C3
AND
AL,01000000B
;SHIFT C3 TWO PLACES RIGHT
SHR
AL,1
SHR
AL,1
;SHIFT C2-CO' ONE PLACE LEFT (MULTIPLY BY 2)
SAL
BX,1
;DROP C3 BACK IN ADJACENT TO C2 (OOOXXXXO)
OR
BL,AL
;JUMP TO THE ROUTINE "ADDRESSED" BY CONDITION CODE
JMP
FXAM_TBL[BXl

p~s

;HERE ARE THE JUMP TARGETS, ONE TO HANDLE
EACH POSSIBLE RESULT OF FXAM
UNNORM:

POS NAN:
NEG UNNORM:

Figure 6-22 Conditional Branching for FXAM (continued)

6-71

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

EMPTY :
NEG ZERO:
POS DENORM:
NEG DENORM:

Figure 6-22 Conditional Branching for FXAM (continued)

Exception Handlers
There are many approaches to writing exception
handlers. One useful technique is to consider the exception handler interrupt procedure as consisting of
"prologue," "body" and "epilogue" sections of
code. (For compatibility with the 8087 emulators,
this procedure should be invoked by interrupt pointer (vector) number 16.)
At the beginning of the prologue, CPU interrupts
have been disabled by the CPU's normal interrupt
response mechanism. The prologue performs all
functions that must be protected from possible interruption by higher-priority sources. Typically this will
involve saving CPU registers and transferring diagnostic information from the 8087 to memory. When
the critical processing has been completed, the prologue may enable CPU interrupts to allow higherpriority interrupt handlers to preempt the exception
handler.
The exception handler body examines the diagnostic
information and makes a response that is necessarily
application-dependent. This response may range
from halting execution, to displaying a message, to
attempting to repair the problem and proceed with
normal execution.
The epilogue essentially reverses the actions of the
prologue, restoring the CPU and the NPX so that
normal execution can be resumed. The epilogue
must not load an unmasked exception flag into the
8087 or another interrupt will be requested immediately (assuming 8087 interrupts are also loaded as
unmasked).
Figures 6-23 through 6-25 show the ASM-86 coding
of three skeleton exception handlers. They show
how prologues and epilogues can be written for various situations, but only provide comments indicating

where the application-dependent exception handling
body should be placed.
Figures 6-23 and 6-24 are very similar; their only
substantial difference is their choice of instructions
to save and restore the 8087. The tradeoff here is between the increased diagnostic information provided
by FNSAVE and the faster execution of FNSTENV.
For applications that are sensitive to interrupt
latency, or do not need to examine register
contents, FNSTENV reduces the duration of the
"critical region;" during which the CPU will not
recognize another interrupt request (unless it is a
non-maskable interrupt).
After the exception handler body, the epilogues prepare the CPU and the NPX to resume execution
from the point of interruption (i.e., the instruction
following the one that generated the unmasked
exception). Notice that the exception flags in the
memory image that is loaded into the 8087 are
cleared to zero prior to reloading (in fact, in these
examples, the entire status word image is cleared).
The prologue also provides for indicating to the interrupt controller hardware (e.g., an 8259A) that the
interrupt has been processed. The actual processing
done here is application-dependent, but might typically involve writing an "end of interrupt" command
to the interrupt controller.
The examples in Figures 6-23 and 6-24 assume that
the exception handler itself will not cause an unmasked exception. Where this is a possibility, the
general approach shown in Figure 6-25 can be
employed. The basic technique is to save the full
8087 state and then to load a new control word in the
prologue. Note that considerable care should be
taken when designing an exception handler of this
type to prevent the handler from being reentered
endlessly.

6-72

210911

I

THE 8087 NUMERIC PROCESSOR EXTENSION

i
PROC
; SAVE CPU REGISTERS, ALLOCATE STACK SPACER
; FOR 8087 STATE IMAGE
; NOTE! INTERRUPTS MUST BE DISABLED.

PUSH

BP

MOV
BP,SP
SUB
SP,94
iSAVE FULL 8087 STATE, WAIT FOR COMPLETION,
iENABLE CPU INTERRUPTS
FNSAVE
[BP-941
FWA IT
STl
APPLICATION-DEPENDENT EXCEPTION HANDLING
CODE GOES HERE

Ij

CLEAR EXCEPTION FLAGS IN STATUS WORD
RESTORE MODIFIED STATE
IMAGE
MOV
BYTE PTR [BP-921, OH
FRSTOR
[BP-941
iWAIT FOR RESTORE TO FINISH BEFORE RELEASING MEMORY
FWAIT
iDE-ALLOCATE STACK SPACE, RESTORE CPU REGISTERS
MOV
SP,BP

POP

I
I
j

I

I
I

BP

i

iCODE TO SEND' 'END OF INTERRUPT"
i8259A GOES HERE

COMMAND TO

i

iRETURN TO INTERRUPTED CALCULATION
IRET
SAVE_ALL
ENDP

Figure 6-23 Full State Exception Handler
6-73

210911

THE 8087 NUMERIC PROCESSOR EXTENSION

SAVE_ENVIRONMENT PROC

,
; SAVE CPU REGISTERS, ALLOCATE STACK SPACE
; FOR 8087 ENVIRONMENT
; NOTE! INTERRUPTS MUST BE DISABLED.

PUSH

BP

MOV
BP,SP
SUB
SP,14
;SAVE ENVIRONMENT, WAIT FOR
;ENABLE CPU INTERRUPTS
FNSTENV [BP-141
FWA IT

COMPLET~ON,

.S T I

;APPLICATION EXCEPTION-HANDLING CODE GOES HERE
;CLEAR EXCEPTION FLAGS IN STATUS WORD
;RESTORE MODIFIED
;ENVIRONMENT IMAGE
MOV
BYTE PTR [BP-121, OH
FLDENV
[BP-141
;WAIT FOR LOAD TO FINISH BEFORE RELEASING MEMORY
FWAIT
;DE-ALLOCATE STACK SPACE, RESTORE CPU REGISTERS
MOV
SP,BP'

POP

BP

;CODE TO SEND' 'END OF INTERRUPT"
;8259A GOES HERE

COMMAND TO

,

;RETURN TO INTERRUPTED CALCULATION
IRET
SAVE_ENVIRONMENT ENDP

Figure 6-24 Reduced Latency Exception Handler

6-74

210911

I

THE 8087 NUMERIC PROCESSOR EXTENSION

{

!

LOCAL_CONTROL

REENTRANT

OW

?

I

iASSUME INITIALIZED

PROC

iSAVE CPU REGISTERS, ALLOCATE STACK SPACE FOR
i8087 STATE IMAGE

PUSH

BP

MOV
BP,SP
SUB
SP,94
iSAVE STATE, LOAD NEW CONTROL WORD, WAIT
iFOR COMPLETION, ENABLE CPU INTERRUPTS
FNSAVE
[BP-941
FLDCW
LOCAL_CONTROL
FWAIT
STI
iCODE TO SEND' 'END OF INTERRUPT" COMMAND TO
i8259A GOES H!RE

iAPPLICATION EXCEPTION HANDLING CODE GOES HERE.
iAN UNMASKED EXCEPTION GENERATED HERE WILL
iC~USE THE EXCEPTION HANDLER TO BE REENTERED.
iIF LOCAL STORAGE IS NEEDED, IT MUST BE
iALLOCATED ON THE CPU STACK.

iCLEAR EXCEPTION FLAGS IN STATUS WORD
iRESTORE MODIFIED STATE IMAGE
MOV
BYTE PTR [BP-921, OH
FRSTOR
[BP-941
iWAIT FOR RESTORE TO FINISH BEFORE RELEASING MEMORY
FWAIT
iDE-ALLOCATE STACK SPACE, RESTORE CPU REGISTERS
MOV
SP,BP

POP
BP
iRETURN TO POINT OF INTERRUPTION
IRET
REENTRANT
ENDP
Figure 6-25 Reentrant Exception Handler

6-75

210911

The BOB91npuflOufpuf
Processor

CHAPTER 7
THE 8089 INPUT/OUTPUT PROCESSOR

7.1 INTRODUCTION
Vss

This chapter describes the 8089 Input/Output Processor (lOP). The following topics are discussed:

A14/D14

Vee
AI5IDI5

A13/D13

AI6IS3

•

Processor Overview

A12/012

A11IS4

AI1IOII

•
•
•

AlB/55

Processor Architecture

AIO/DIO

AI 9/56

A9/D9

Input/Output
Instruction Set

BHE

A8/D8

EXT I

A1/D1

EXT 2

A6I06

ORal

A51D5

DR02

A4I04

LOCK

A3/03

•

Addressing Modes

•

Programming Facilities

A21D2

52
51

•

Programming Guidelines and Examples

AI/DI

so

AOIDO

RQ/GT

The discussion is confined to covering the hardware
in functional terms; timing, electrical characteristics
and other physical interfacing data are in Volume 2,
Chapter 4.

SINTR·I

SEL

SINTR·2

CA

CLK

READY

vss

RESET

Figure 7 -1 80891nput/Output
Processor Pin Diagram

7.2 PROCESSOR OVERVIEW

Evolution

The 8089 Input/Output Processor is a highperformance, general purpose I/O system implemented on a single chip. Within the 8089 are two
independent channels, each of which combines attributes of a CPU with those of a very flexible DMA
(direct memory access) controller. For example,
channels can execute programs like CPUs; the lOP
instruction set has about 50 different types of instructions specifically designed for efficient input/output
processing. Each channel also can perform highspeed DMA transfers; a variety of optional operations allow the data to be manipulated (e.g.,
translated or compared) as it is transferred. The
8089 is contained in a 40-pin dual in-line package
(Figure 7-1) and operates from a single + 5V power
source. An integral member of the iAPX 86,88
family, the lOP is directly compatible with both the
8086 and 8088 when these processors are configured
in maximum mode. The lOP also may be used in
any system that incorporates Intel's Multibus™
shared bus architecture, or a superset of the Multibus™ design.

Figure 7-2 depicts the general trend in CPU and 1/0
device relationships in the first three generations of
microprocessors. First generation CPU s were forced
to deal directly with substantial numbers of TTL
components, often performing transfers at the bit
level. Only a very limited number of relatively slow
devices could be supported.
Single-chip interface controllers were introduced in
the second generation. These devices removed the
lowest level of device control from the CPU and let
the CPU transfer whole bytes at once. With the
introduction of DMA controllers, high-speed
devices could be added to a system, and whole
blocks of data could be transferred without CPU
intervention. Compared to the previous generation,
I/O device and DMA controllers allowed microprocessors to be applied to problems that required
moderate levels ofI/O, both in terms of the numbers
of devices that could be supported and the transfer
speeds of those devices.
7-1

210911

THE 8089 INPUT/OUTPUT PROCESSOR

HOLe/SOLe
PROTOCOL
CONTROLLER

(FUTURE CONTROLLER)

... ,

r~;,;;,
110
I

'?)--~

DATA LINK

'" A... ./

L

~E~C': .J

,/" FLOPPY DISK
CONTROLLER

Figure 7-2 lOP Evolution

The controllers themselves, however, still required
a considerable amount of attention from the CPU,
and in many cases the CPU had to respond to an interrupt with every byte read or written. The CPU
also had to stop while DMA transfers were
performed.

Principles of Operation
Since the 8089 is a new concept in microprocessor
components, this section surveys the basic operation
of the lOP as background to the detailed descriptions
provided in the rest of the chapter. This summary
deliberately omits some operating details in order to
provide an integrated overview of basic concepts.

The 8089 introduces the third generation of
input/output processing. It continues the trend of
simplifying the CPU'S "view" of I/O devices by
removing another level of control from the CPU.
The CPU performs an I/O operation by building a
message in memory that describes the function to be
performed; the lOP reads the message, carries out
the operation and notifies the CPU when it has
finished. All I/O devices appear to the CPU as transmitting and receiving whole blocks of data; the lOP
can make both byte- and word-level transfers invisible to the CPU. The lOP assumes all device controller overhead, performs both programmed and
DMA transfers, and can recover from "soft" I/O
errors without CPU intervention; all of these activities may be performed while the CPU is attending to
other tasks.

CPU/lOP Communications
A CPU communicates with an lOP in two distinct
modes: initialization and command. The initialization sequence is typically performed when the
system is powered-up or reset. The CPU initializes
the lOP. by preparing a series of linked message
blocks in memory. On a signal from the CPU, the
lOP reads these blocks and determines from them
how the data buses are configured and how access to
the buses is to be controlled.
7-2

210911

THE 8089 INPUT/OUTPUT PROCESSOR

that the channel is to return to the CPU. Except for
the first two words, the format and the size of a
parameter block are completely open; based on the
specific 110 task, the PB may be set up to exchange
any kind of information between the CPU and the
channel program.

Following initialization, the CPU directs all communications to either of the lOP's two channels;
during normal operation the lOP appears to be two
separate devices - channell and channel 2. All CPUto-channel communications center on the channel
control block (CB) illustrated in Figure 7-3. The CB
is located in the CPU's memory space, and its address is passed to the lOP during initialization. Half
of the block is dedicated to each channel. The channel maintains the BUSY flag that indicates whether
it is in the midst of an operation or is available for a
new command. The CPU sets the CCW (channel
command word) to indicate what kind of operation
the lOP is to perform. Six different commands allow
the CPU to start and stop programs, remove interrupt requests, etc.

A task block is a channel program - a sequence of
8089 instructions that will perform an operation. A
typical channel program might use parameter block
data to set up the lOP and a device controller for a
transfer, perform the transfer, return the results,
and then halt. However, there are no restrictions on
what a channel program can do; its function may be
simple or elaborate to suit the needs of the
application.
Before the CPU starts a channel program, it links
the program (TB) to the parameter block and the
parameter block to the CB as shown in Figure 7-3.
The links are standard 8086/8088 doubleword pointer variables; the lower-addressed word contains an
offset, and the higher-addressed word contains a segment base value. A system may have many different
parameter and task blocks; however, only one of
each is ever linked to a channel at any given time.

If the CPU is dispatching a channel to run a

program, it directs the channel to a parameter block
(PB) and a task block (TB); these are also shown in
Figure 7-3. The parameter block is analogous to a
parameter list passed by a program to a subroutine;
it contains variable data that the channel program is
to use in carrying out its assignment. The parameter
block also may contain space for variables (results)

CHANNEL CONTROL BLOCK (CB)

(RESERVED)

-{

1
1
1
1
1

I-p(~~~r:.i1~RB~'s~C&K6'?~:Jf:-

J

BUSY

1
15

}

CHANNEL2

}

CHANNELl

ccw

(RESERVED)

-{

1

I
I

I

BUSY

~

1

-p(~~~':.i~\R8~'s~C&K6~~~~ir- ~

~

ccw

8 7

~-------------------------~

L-------- l
C'HANNEL 2 PARAMETER BLOCK (PS)

1

CHANNEL PROGRAM PARAMETERS

r {

I

(APPLICATION-DEFINED)

I

r

1 ,:

4
1
1---Y-A-SK-.-LO-C-K-P-O'-NY-E-.---I.2
:
(SEGMENT BASE & OFFSET)
+l

CHANNEL PROGRAM PARAMETERS

i{

(AP~LICATION-DEFINED)

1

TASK BLOCK POINTER
(SEGMENT BASE II OFFSET)

~------~
CHANNEL2TASK BLOCK (TB)

CHANNEL 1 TASK BLOCK (TB)
(CHANNEL PROGRAM)

(CHANNEL PROGRAM)

BO"

B08,

INSTRUCTIONS

INSTRUCTIONS
(APPLICATION.
DEFINED)

(APPLICATIONDEFINED)

L _ ' -_ _ _ _ _ _ _ _- - I

L_L-________________

~

Figure 7 -3 Command Communication Blocks

7-3

210911

THE 8089 INPUT/OUTPUT PROCESSOR

After the CPU has filled in the CCW and has linked
the CB to a parameter block and a task block, if
appropriate, it issues a channel attention (CA). This
is done by activating the lOP's CA (channel
attention) and SEL (channel select) pins. The state
of SEL at the falling edge of CA directs the channel
attention to channel I or channel 2. If the lOP is
located in the CPU's I/O space, it appears to the
CPU as two consecutive I/O ports (one for each
channel), and an OUT instruction to the port functions as a CA. If the lOP is memory-mapped, the
channels appear as two consecutive memory
locations, and any memory reference instruction
(e.g., MOV) to these locations causes a channel
attention.
An lOP channel attention is functionally similar to a
CPU interrupt. When the channel recognizes the
CA, it stops what it is doing (it will typically be idle)
and examines the command in the CCW. If it is to
start a program, the channel loads the addresses of
the parameter and task blocks into internal registers,
sets its BUSY flag and starts executing the channel
program. After it has issued the CA, the CPU is free
to perform other processing; the channel can perform its function in parallel, subject to limitations
imposed by bus configurations (discussed shortly).

Channels
Each of the two lOP channels operates independently, and each has its own register set, channel
attention, interrupt request and DMA control
signals. At a given point in time, a channel may be
idle, executing a program, performing a DMA
transfer, or responding to a channel attention. Although only one channel actually runs at a time, the
channels can be active concurrently, alternating
their operations (e.g., channell may execute instructions in the periods between successive DMA transfer cycles run by channel 2). A built-in priority
system allows high-priority activities on one channel
to preempt less critical operations on the other
channel. The CPU is able to further adjust priorities
to handle special cases. The CPU starts the channel
and can halt it, suspend it, or cause it to resume a
suspended operation by placing different values in
the CCW.

Channel Programs (Task Blocks)
Channel programs are written in ASM-89, the 8089
assembly language. About 50 basic instructions are
available. These instructions operate on bit, byte,
word, and doubleword (pointer) variable types; a
20- bit physical address variable type (not used by
the 8086/8088) can also be manipulated. Data may
be taken from registers, immediate constants and
memory. Four memory addressing modes allow
flexible access to both memory variables and I/O
devices located anywhere in either the CPU's one
megabyte memory space or in the 8089's 64K 110
space.

When the channel has completed its program, it notifies the CPU by clearing its BUSY flag in the CB.
Optionally, it may issue an interrupt request to the
CPU.
The CPU/IOP communication structure is summarized in Figure 7-4. Most communication takes place
via "message areas" shared in common memory.
The only direct hardware communications between
the devices are channel attentions and interrupt
requests.

The lOP instruction set contains general purpose instructions similar to those found in CPUs, as well as
instructions specifically tailored for I/O operations.
Data transfer, simple arithmetic, logical and address
manipulation operations are available. Unconditional
jump and call instructions also are provided so that
channel programs can link to each other. An individual bit may be set or cleared with a single
instruction. Conditional jumps can test a bit and
jump if it is set (or cleared), or can test a value and
jump if it is zero (or non-zero). Other instructions
initiate DMA transfers, perform a locked testand-set semaphore operation, and issue an interrupt
request to the CPU.

CHANNEL ATTENTION

CPU

H MES~:GES 1MEMORY

lOP

DMA Transfers

INTERRUPT

The 8089 XFER (transfer) instruction prepares the
channel for a DMA transfer. It executes one additional instruction, then suspends program execution
and enters the DMA transfer mode. The transfer is
governed by channel registers setup by the program
prior to executing the XFER instruction.

Figure 7-4 CPU/lOP Communication

7-4

210911

THE 8089 INPUT/OUTPUT PROCESSOR

Data is transferred from a source to a destination.
The source and destination may be any locations in
the CPU's memory space or in the lOP's 1/0 space;
the lOP makes no distinction between memory
components and I/O devices. Thus transfers may be
made from 110 device to memory, memory to I/O
device, memory to memory and I/O device to I/O
device. The lOP automatically matches 8- and 16-bit
components to each other.

A channel program typically ends by posting the
result of the operation to a field supplied in the
parameter block, optionally interrupting the CPU,
and then halting. When the channel haits, its BUSY
flag in the channel control block is cleared to indicate
its availability for another operation. As an alternative to being interrupted by the channel, the CPU
can poll this flag to determine when the operation
has been completed.

Individual transfer cycles (i.e., the movement of a
byte or a word) may be synchronized by a signal
(DMA request) from the source or from the
destination. In the synchronized mode, the channel
waits for the synchronizing signal before starting the
next transfer cycle. The transfer also may be
unsynchronized, in which case the channel begins
the next transfer cycle immediately upon completion
of the previous cycle.

.1'
"

Bus Configuration
As shown in Figure 7-5, the lOP can access memory
or ports 0/0 devices) located in a I-megabyte
system space and memory or ports located in a 64kilobyte I/O space. Although the lOP only has one
physical data bus, it is useful to think of the lOP as
accessing the system space via a system data bus and
the I/O space over an I/O data bus. The distinction
between the "two" buses is based on the typeof-cycle signals output by the 8288 Bus Controller.
Components in the system space respond to the
memory read and memory write signals, whether
they are memory or 110 devices. Components in the
I/O space respond to the 1/0 read and I/O write
signals. Thus 1/0 devices located in the system space
are memory-mapped, and memory in the I/O space
is I/O-mapped. The two basic configuration operations differ in the degree to which the lOP shares
these buses with the CPU.

A transfer cycle is performed in two steps: fetching a
byte or word from the source into the lOP and then
storing it from the lOP into the destination. The lOP
automatically optimizes the transfer to make best
use of the available data bus widths. For example, if
data is being transferred from an 8-bit device to
memory that resides on a 16-bit bus (e.g., 8086
memory), the lOP will normally run two one-byte
fetch cycles and then store the full word in a single
cycle.
Between the fetch and store cycles, the lOP can operate on the data. A byte may be translated to another
code (e.g., EBCDIC to ASCII), or compared to a
search value, or both, if desired.

Both configurations require an 8086/8088 CPU to be
strapped in maximum mode.
In the local configuration, shown in Figure 7-6, the
lOP (or lOPs if two are used) shares both buses with
the CPU. The system bus and the 1/0 bus are the

A transfer can be terminated by several
programmer-specified conditions. The channel can
stop the transfer when a specified number (up to
64K) of bytes has been transferred. An external
device may stop a transfer by signaling on the channel's external terminate pin. The channel can stop
the transfer when a byte (possibly translated) compares equal, or unequal, to a search value. Singlecycle termination, which stops unconditionally after
one byte or word has been stored, is also available.

B B

When the transfer terminates, the channel automatically resumes program execution. The channel program can determine the cause of the termination in
situations where mUltiple terminations are possible
(e.g., terminating when 80 bytes are transferred or a
carriage return character is encountered, whichever
occurs first). As an example of post-transfer
processing, the channel program could read a result
register from the I/O device controller to determine
if the transfer was performed successfully. If not
(e.g., a CRC error was detected by the controller),
the channel program could retry the operation without CPU intervention.

SYSTEM SPACE (1 MBYTE)

I/O
DATA
BUS

Figure 7-5 lOP Data Buses

7-5

210911

t

!
:~

THE80891NPUT/OUTPUTPROCESSOR

same width (8 bits if the CPU is an 8088 or 16 bits if
the CPU is an 8086). The lOP system space corresponds to the CPU memory space, and the lOP I/O
space corresponds to the CPU I/O space. Channel
programs are typically located in the system space;
I/O devices may be located in either space. The lOP
requests use of the bus for channel program instruction fetches as well as for DMA and programmed
transfers. In the local configuration, either the lOP
or the CPU may use the buses, but not both
simultaneously. The advantage of the local configuration is that intelligent DMA may be added to a
system with minimal additional components beyond
the lOP. The disadvantage is that parallel operation
of the processors is limited to cases in which the
CPU has instruction in its queue that can be executed without using the bus.

I/O devices and memory without using the shared
system bus, thereby reducing bus contention with
the CPU. Contention can further be reduced by
locating the lOP's channel programs in the local I/O
space. The lOP can then also fetch instructions without accessing the system bus. Parameter, channel
control and other CPU/lOP communication blocks
must be located in system memory, however, so
that both processors can access them. The remote
configuration thus increases the degree to which an
lOP and a CPU can operate in parallel and thereby
increases a system's throughput potential. The price
paid for this is that additional hardware must be
added to arbitrate use of the shared bus, and to
separate the shared and local buses (see Chapter 4
for details).
It is also possible to configure an lOP remote to one
CPU, and local to another CPU (see Figure 7-8).
The local CPU could be used to perform
computational-intensive routines for the lOP.

In the remote configuration (Figure 7-7), the lOP
(or lOPs) shares a common system bus with the
CPU. Access to this bus is controlled by 8289 Bus
Arbiters. The lOP's I/O bus, however, is physically
separated from the CPU in the remote
configuration. Two lOPs can share the local I/O bus.
Any number of remote lOPs may be contained in a
system, configured in remote clusters of one or two.
The local I/O bus need not be the same physical
width as the shared system bus, allowing an lOP, for
example, to interface 8-bit peripherals to an 8086. In
the remote configuration, the lOP can access local

A Sample Transaction
Figure 7-9 shows how a CPU and an lOP might work
together to read a record (sector) from a floppy disk.
This example is not illustrative of the lOP's full
capabilities, but it does review its basic operation
and its interaction with a CPU.
The CPU must first obtain exclusive use of a
channel. This can be done by performing a "test and
set lock" operation on the selected channel's BUSY
flag. Assuming the CPU wants to use channell, this
could be accomplished in PLlM-86 by coding similar
to the following:

1/0 SPACE

DO WHILE LOCKSET (@CHl,BUSY,OFFH);
END

1/0 BUS

In ASM-86 a loop containing the XCHG instruction
prefixed by LOCK would accomplish the same
thing, namely testing the BUSY flag until it is clear
(OH), and immediately setting it to FFH (busy) to
prevent another task or processor from obtaining
use of the channel.

8089 lOP

..... -

_.....

Having obtained the channel, the CPU fills in a
parameter block (see Figure 7-10). In this case, the
CPU passes the following parameters to the channel:
the address of the floppy disk controller, the address
of the buffer where the data is to be placed, and the
drive, track and sector to be read. It also supplies
space for the lOP to return the result of the
operation. Note that this is quite a "low-level"
parameter block in that it implies that the CPU has
detailed knowledge of the I/O system. For a "real"
system, a higher-level parameter block would isolate
the CPU from I/O device characteristics. Such a
block might contain more general parameters such
as file name and record key.

B
Figure 7 -6 Local Configuration

7-6

210911

THE 8089 INPUT/OUTPUT PROCESSOR

r-----------,
I
,.--,
,--7 I
I
I

(110 DEVICE)

..... __

~

'110 DEVICEI

' - __

~

!+
I

8289
BUS
ARBITER

80861
8088
CPU

L _ .2!'l!.°1:lfU°,£A.!..!I.2,S.!:!'S!i _ .J
NOT ACCESSIBLE TO lOPs

Vl
::J
III

SYSTEM SPACE

:;:
UJ
....

Vl

>a:

Vl

UJ
....

Vl



0

..J

OPTIONAL
8089
lOP

110 SPACE

NOT ACCESSIBLE TO CPU

\

r------;::;-:
I .... - - , (

I 1
: I
I
I

110
DEVICE

I

" - - I

L J ,r
MEMORY

I

I

7.

I

I

l: DEVICE

.-+:
I
I

~

:. . ~ ~

I
I
I
\...._-~ 1
I..!!,!!':!.C!. _______ ..J
- -

r---,
~~8i

Ig

•

..J

!f..,

L -.-

I
...I

I
I

r-"-}.
I

ALR~9tiA~ygN I-

I

L .....

""1

•

8089
lOP

..I

rI - - -,I

+. AR~:f~ER +IL.

- -

...II

L __
Figure 7 - 7 Remote Configuration

7-7

210911

THE80891NPUT/OUTPUTPROCESSOR

r------.,
,- - - T

I

DE~~E I
\ ___ ~

I
I
I

(

,--,
(

1/0
DEVICE

)

'--~

OPTIONAL
LOCAL 1/0 SPACE

:+----

80861
8088
CPU

8289
BUS
ARBITER

I
I
I

I NOT ACCESSIBLE TO lOP I

L!0! ,!:M2.T:!0~t.~8!.J

EJ

I/)

::>

III

SYSTEM SPACE

:;;
UJ
....

I/)

>
a:

I/)

UJ
....
I/)

«
:;;
>=
...J

8089
lOP

::>

:;;

EJ

I/)

::>

III

o

LOCAL BUS
ARBITRATION

16-"'~«

8289
BUS
ARBITER

o

o...J

110 SPACE

80861
8088

NOT ACCESSIBLE TO SYSTEM CPU

CPU

Figure 7-8 Remote lOP Configured With Local 8086/8088

7-8

210911

!
,

THE 80891NPUT/OUTPUT PROCESSOR

~

I

----B
----[J
----[J
----[]

----[J
I
I

~ig2t}~f:oy~G~~~:£~T~~~~iKs

g~i~Ls~~~~~NR~~EN;E~~SEYS~lAG

[J-r------------

I

I

I

I

-----;

I
IL
I

I

I
I

I
I
I
I
I
I
I

I

___________ _

----8----

FLOPPY

~'~--G~----

FLOPPY

01511

OISK

I
I

----8----

I
I

I
I
I
I
I

I
I

I
I
I

I
I

I
I

[}---

I
I
I
I
I
I
INTERRIJPT
1- - - - - - - - - - - - - - - I
I

----8

I
I
I

BUSJ,U':~~E I~~~~:ED.
I
I
I

Figure 7-9 Sample CPU/lOP Transaction
7-9

210911

THE 80891NPUT/OUTPUT PROCESSOR

I--

POINTER TO
CHANNEL PROGRAM
(OFFSET" SEGMENT)

-

DEVICE ADDRESS
POINTER TO BUFFER

I-(OFFSET" SEGMENT)

o
2
4

-

6

8

TRACK

DRIVE

10

RESULT

SECTOR

12

Figure 7-10 Sample Parameter Block

After setting up the parameter block, the CPU
writes a "start channel program" command in channell's CCW. Then the CPU places the address of
the desired channel program in the parameter block
and writes the parameter block address in the CB.
Notice that in this simple example the CPU
"knows" the address of the channel program for
reading from the disk, and presumably also
"knows" the address of another program for
writing, etc. A more general solution would be to
place a function code (read, write, delete, etc.) in the
parameter block and let a single channel program execute different routines depending on which function
is requested.

the 8272 issues a DMA request to the channel. The
transfer continues until the 8272 issues an interrupt
request, indicating that the data has been transferred
or that an error has occurred. The 8272's interrupt
request line is tied to the lOP's EXTl (external terminate on channel 1) pin so that the channel interprets an interrupt request as an external terminate
condition. Upon termination of the transfer, the
channel resumes executing instructions and reads
the 8272 result register to determine if the data was
read successfully. If a soft (correctable) error is
indicated, the IOP retries the transfer. If a hard
(uncorrectable) error is detected, or if the transfer
has been successful, the lOP posts the content of the
result register to the parameter block result field,
thus passing the result back to the CPU. The channel
then interrupts the CPU (to inform the CPU that
the request has been processed) and halts.
When the CPU recognizes the interrupt, it inspects
the result field in the parameter block to see if the
content of the buffer is valid. If so, it uses the data;
otherwise it typically executes an error routine.

Applications
Combining the raw speed and responsiveness of a
traditional DMA controller, an I/O-oriented instruction set, and a flexible bus organization, the 8089
lOP is a very versatile I/O system. Applications with
demanding I/O requirements, previously beyond
the abilities of microcomputer systems, can be undertaken with the lOP. These kinds of I/O-intensive
applications include:

After the communication blocks have been setup,
the CPU dispatches the channel by issuing a channel
attention, typically by an OUT instruction for an
I/O-mapped 8089, or a MOV or other memory reference instruction for a memory-mapped 8089.
The channel begins executing the channel program
(task block) whose address has been placed in the
parameter block by the CPU. In this case the program initializes the 8272 Floppy Disk Controller by
sending it a "read data" command followed by a all
other "read data" parameters except for the last
parameter. The program initializes the channel registers that define and control the DMA transfer.
Having prepared the 8272 and the channel itself, the
channel program executes a XFER instruction and
sends a final parameter (special sector size) to the
8272. (The 8272 enters DMA transfer mode immediately upon receiving the last of a series of
parameters; sending the last parameter after the
XFER instruction gives the channel time to setup
for the transfer.) The DMA transfer begins when

•

systems that employ high-bandwidth, lowlatency devices such as disks and graphics
terminals;

•

systems with many devices
asynchronous service; and

•

systems with high-overhead peripherals such
as intelligent CRTs and graphics terminals.

requiring

In addition, virtually every application that performs
a moderate amount of I/O can benefit from the
design philosophy embodied in the lOP: system functions should be distributed among special-purpose
processors. An lOP channel program is likely to be
both faster and smaller than an equivalent program
implemented with a CPU. Programming also is
more straightforward with the lOP's specialized instruction set.
Removing I/O from the CPU and assigning it to one
or more lOPs simplifies and structures a system's
design. The main interface to the I/O system can be
limited to the parameter blocks. Once these are
defined, the I/O system can be designed and implemented in parallel with the rest of the system. I/O
7-10

210911

THE 8089 INPUT/OUTPUT PROCESSOR

in parallel with the CPU, the operating system's capacity for servicing application tasks
can increase dramatically, as can its ability to
handle more, and faster, I/O devices. If both
channels of an lOP are active concurrently,
the lOP automatically gives preference to the
higher-priority activity (e.g., DMA normally
preempts channel program execution). The
operating system can adjust the priority
mechanism and also can halt or suspend a
channel to take care of a critical asynchronous
event.

specialists can work on the I/O system without
detailed knowledge of the application; conversely,
the operating system and application teams do not
need to be expert in the operation of I/O devices.
Standard high-level I/O systems can be used in
multiple application systems. Because the application
and I/O systems are almost independent, application
system changes can be introduced without affecting
the I/O system. New peripherals can similarly be incorporated into a system without impacting applications or operating system software. The lOP's
simple CPU interface also is designed to be compatible with future Intel CPUs.

•

Disk systems-The lOP can meet the speed
and latency requirements of hard disks. It can
be used implement high-level, file-oriented
systems that appear to application programs
as simple commands: OPEN, READ,
WRITE, etc. The lOP can search and update
disk directories and maintain free space maps.
"Hierarchical memory" systems that automatically transfer data among memory, highspeed disks and low-speed disks, based on
frequency of use, can be built around IOPs.
Complex database searches (reading data
directly or following pointer chains) can
appear to programs as simple commands and
can execute in parallel with application programs if an lOP is configured remotely.

•

Display terminals- The 8089 is well suited to
handling the DMA requirements of CRT
controllers. The lOP's transfer bandwidth is
high enough to support both alphanumeric
and graphic displays. The 8089 can assume responsibility for refreshing the display from
memory data; in the remote configuration,
the refresh overhead display algorithms may
be programmed to perform sophisticated
modes of display.

Keeping in mind the true general-purpose nature of
the lOP, some of the situations where it can be used
to advantage are:
•

Bus matching- The lOP can transfer data between virtually any combination of 8- and
16-bit memory and I/O components. For
example, it can interface a 16-bit peripheral to
an 8-bit CPU bus, such as the 8088 bus. The
IOP also provides a straightforward means of
performing DMA between an 8-bit peripheral
and 8086 memory that is split into odd- and
even-addressed banks. The 8089 can access
both 8- and 16-bit peripherals connected to a
16-bit bus.

•

String processing- The 8089 can perform a
memory move, translate, scan-for-match or
scan-for-nonmatch operation much faster
than the equivalent instructions in an 8086 or
8088. Translate and scan operations can be
setup so that the source and destination refer
to the same addresses to permit the string to
be operated on in place.

•

Spooling-Data from low-speed devices such
as terminals and paper tape readers can be
read by the 8089 and placed into memory or
on disk until the transmission is complete.
The lOP can then transfer the data at high
speed when it is needed by an application
program. Conversely, output data ultimately
destined for a low-speed device such as a
printer, can be temporarily spooled to disk
and then printed later. This permits batches
of data to be gathered or distributed by lowpriority programs that run in the background,
essentially using up "spare" CPU and lOP
cycles. Application programs that use or produce the data can execute faster because they
are not bound by the low -speed devices.

•

Multitasking operating systems-A multitasking operating system can dispatch I/O tasks to
channels with an absolute minimum of
overhead. Because a remote channel can run
7-11

Each time it performs a refresh operation, the
lOP can scan a keyboard for input and translate the key's row-and-column format into an
ASCII or EBCDIC character. The 8089 can
buffer the characters, scanning the stream
until an end-of-message character (e.g., carriage return) is detected, and then interrupt
the CPU.
A single lOP can concurrently support an alphanumeric CRT and keyboard on one channel and a floppy disk on the other channel.
This configuration makes use of approximately 30 percent of the available bus
bandwidth. Performance can be increased
within the available bus bandwidth by adding
an 8086 or 8088 CPU to a remote lOP configuration. This configuration can provide
scaling, rotation or other sophisticated display
transformations.
210911

,1
,".1

THE 8089 INPUT/OUTPUT PROCESSOR

7.3 PROCESSOR ARCHITECTURE

(this is discussed more fully later in this section).
The CCU also initializes the processor.

The 8089 is internally divided into the functional
units depicted schematically in Figure 7-11. The
units are connected by a 20-bit data path to obtain
maximum internal transfer rates.

Arithmetic/Logic Unit (ALU)

Common Control Unit (CCU)
All lOP operations (instructions, DMA transfer
cycles, channel attention responses, etc.) are composed of sequences of more basic processes called internal cycles. A bus cycle takes one internal cycle;
the execution of an instruction may require several
internal cycles. There are 23 different types of internal cycles, each of which takes from two to eight
clocks to execute, not including possible wait states
and bus arbitration times.
The common control unit (CCU) coordinates the activities of the lOP primarily by allocating internal
cycles to the various processor units; i.e., it determines which unit will execute the next internal
cycle. For example, when both channels are active,
the CCU determines which channel has priority and
lets that channel run; if the channels have equal
priority, the CCU "interleaves" their execution

The ALU can perform unsigned binary arithmetic
on 8- and 16-bit binary numbers. Arithmetic results
may be up to 20 bits in length. Available arithmetic
instructions include addition, increment and
decrement. Logical operations ("and," "or" and
"not") may be performed on either 8- or 16-bit
quantities.

Assembly/Disassembly Registers
All data entering the chip flows through these
registers. When data is being transferred between
different width buses, the 8089 uses the
assembly/disassembly registers to effect the transfer
in the fewest possible bus cycles. In a DMA transfer
from an 8-bit peripheral to 16-bit memory, for
example, the lOP runs two bus cycles, picking up
eight bits in each cycle, assembles a 16-bit word, and
then transfers the word to memory in a single bus
cycles. (The first and last cycles of a transfer may be
performed differently to accommodate oddaddressed words; the lOP automatically adjusts for
this condition.

SHE

TASK POINTER
I/O CONTROL

tt

ORO 1 EXT 1 SINTR-l

Figure 7-11 8089 Block Diagram

7-12

210911

THE 80891NPUT/OUTPUT PROCESSOR

Instruction Fetch Unit

shown graphically in Figure 7-12. When the last byte
of an instruction falls on an even address, the oddaddressed byte (the first byte of the following
instruction) of the fetched word is saved in the
queue. When the channel begins execution of the
next instruction, it fetches the first byte from the
queue rather than from memory. The queue, then,
keeps the processor fetching words, rather than
bytes, thereby reducing its use of the bus and increasing throughput.

The unit controls instruction fetching for the executing channel (one channel actually runs at a time). If
the bus over which the instructions are being
fetched is eight bits wide, then the instructions are
obtained one byte at a time, and each fetch requires
one bus cycle. If the instructions are being fetched
over a 16-bit bus, then the instruction fetch unit automatically employs a I-byte queue to reduce the
number of bus cycles. Each channel has its own
queue, and the activity of one channel does not
affect the other's queue.

The processor fetches bytes rather than words in two
cases. If a program transfer instruction (e.g., JMP or
CALL) directs the processor to an instruction located at an odd address, the first byte of the instruction
is fetched by itself as shown in Figure 7-13. This is
because the program transfer invalidates the content
of the queue by changing the serial flow of execution.

During sequential execution, instructions are
fetched one word at a time from even addresses;
each fetch requires one bus cycle. This process is

INSTRUCTION "Y"
r,..----'A....--.......,

INSTRUCTION "X"
r__- - - -A....- - _

II

EVEN, ODD
--1

\

I

EVEN, ODD

,~

________J I

2

I
I

I

EVEN, ODD

,~

Il

________J I

4

t

D

QUEUE

3

FETCH

INSTRUCTION BYTES

1

FIRST TWO BYTES OF "X"

2

THIRD BYTE OF "X" PLUS
FIRST BYTE OF "Y", WHICH IS
SAVED IN QUEUE

3

FIRST BYTE OF "Y" FROM
QUEUE-NO BUS CYCLE

4

LAST TWO BYTES OF "Y"

Figure 7-12 Sequential Instruction Fetching (16-Bit Bus)
7-13

210911

THE 80891NPUT/OUTPUT PROCESSOR

The BIU further distinguishes between the physical
and logical widths of the system and 110 buses. The
physical widths of the buses are fixed and are communicated to the BIU d~ring initialization. In the
local configuration, both buses must be the same
width, either 8 or 16 bits (matching the width of the
host CPU bUs). In the remote configuration, the
lOP system bus must be the same physical width as
the bus it shares with the CPU. The width of the
lOP's I/O bus, which is local to the 8089, may be
selected independently. If any 16-bit peripherals are
located in the I/O space, theI). a 16-bit I/O bus must
be used. If only 8-bit devices reside on the I/O bus,
then either an 8-bit or a l6-bit 110 bus may be
selected. A 16-bit I/O bus has the advantage of easy
accommodation of future l6-bit devices and fewer
instruction fetches if channel programs are placed in
the I/O space.

The second case arises when an LPDI instruction is
located at an odd address. In this situation, the sixbyte LPDI instruction is fetched: byte, word, byte,
byte, byte, and the queue is not used. The first byte
of the following instruction is fetched in one bus
cycle as if it had been the target of a program
transfer. Word fetching resumes with this instruction's second byte.

Bus Interface Unit (BIU)
The BIU runs all bus cycles, transferring instructions
and data between the lOP and external memory or
peripherals. Every bus access is associated with a
register tag bit that indicates to the BIU whether the
system or I/O space is to be addressed. The BIU outputs the type of bus cycle (instruction fetch from I/O
space, data store into system space, etc.) on status
lines SO, S 1, and S2. An 8288 Bus Controller
decodes these lines and provides signals that selectively enable one bus or the other (see Chapter 4 for
details).

INSTRUCTION "X"

For a given DMA transfer, a channel program specifies the logical width of the system and the I/O
buses; each channel specifies logical bus width
independently. The logical width of an 8-bit physical
bus can only be eight bits. A 16-bit physical bus,

INSTRUCTION "V"

r'------~~,~----~, r'------~~~----~,

I I
ODD

~

EVEN, ODD

'~

________

2

I

EVEN I ODD

~"~

________J'

I

EVEN, ODD

'~

______

3

LTRANSFER TARGET

FETCH

II

~~I

o
4

I

I

QUEUE

INSTRUCTION BVTES

1

FIRST ~ODD-ADDRESSED) BYTE OF "X"
(8-BIT US CYCLE)

2

SECOND AND THIRD BYTES OF "X"

3

FIRST AND SECOND BYTES OF "V".

4

THIRD BYTE OF "V"
PLUS FIRST BYTE OF NEXT INSTRUCTION,
WHICH IS SAVED IN QUEUE

Figure 7-13 Instruction Fetching Following a Program Transfer t~ an Odd Address (16-Bit Bus)

7-14

210911

THE 8089 INPUT/OUTPUT PROCESSOR

however, can be used as either an 8- or 16-bit logical
bus. This allows both 8- and 16-bit devices to be accessed over a single 16-bit physical bus. Table 7-1
lists the permissible physical and logical bus widths
for both locally and remotely configured lOPs. Logical bus width pertains to DM A transfers only. instructions are fetched and operands are read and
written in bytes or words depending on physical bus
width.

request) line before performing the next fetch-store
sequence in the transfer. If the transfer is to be terminated by an external signal, the channel monitors
its EXT (external terminate) line and stops the transfer when this line goes fictive. Between the fetch and
store cycles (when the data is in the lOP) the channel
optionally counts, translates, and scans the data, and
may terminate the transfer based on the results of
these operations. Each channel also has a SINTR
(system interrupt) line that can be activated by software to issue an interrupt request to the CPU.

Table 7-1 Physical/Logical Bus Combinations

Registers
Configuration

Local

System Bus
Physical:Logical
8:8
16:8/16

8:8
Remote

16:8/16
16:8/16

8:8

1/0 Bus

Physical:Logical
8:8
16:8/16

8:8
16:8/16

8:8
16:8/16

Figure 7-14 illustrates the channel register set, and
Table 7-2 summarizes the uses of each register. Each
channel has an independent set of registers; they are
not accessible to the other channel. Most of the
registers play different roles during channel program
execution than in DMA transfers. Channel programs
must be careful to save these registers in memory
prior to a DMA transfer if their values are needed
following the transfer.

In addition to performing transfers, the BIU is responsible for local bus arbitration. In the local
configuration, the BIU uses the RQ/GT (request/
grant) line to obtain the bus from the CPU and to
return it after a transfer has been performed. In the
remote configuration, the BIU uses RQ/GT to coordinate use of the local I/O bus with another lOP or a
local CPU, if present. System bus arbitration in the
remote configuration is performed by an 8289 Bus
Arbiter that operates invisibly to the lOP. The BIU
automatically asserts the LOCK (bus lock) signal
during execution of a TSL (test and set lock) instruction and, if specified by the channel program, can
assert the LOCK signal for the duration of a DMA
transfer. Volume 2 contains a complete discussion of
bus arbitration.

TAG
BIT

r,
.... --1

1--1
1--1
L..J

Although the 8089 is a single processor, under most
circumstances it is useful to think of it as two independent channels. A channel may perform DMA
transfers and may execute channel programs; it also
may be idle. This section describes the hardware features that support these operations.

Each channel contains its own I/O control section
that governs the operation of the channel during
D MA transfers. If the transfer is synchronized, the
channel waits for a signal on its DRQ (DMA

7

15

o

GENERAL PURPOSE A

GA

GENERAL PURPOSE B

GB

GENERAL PURPOSE C

GC

TASK POINTER

TP

PARAMETER BLOCK POINTER

PP

INDEX

Channels

I/O Control

19

IX

BYTE COUNT

BC

MASKICOMPARE

MC

CHANNEL CONTROL

CC

Figure 7-14 Channel Register Set

General Purpose A (GA). A channel program may
use G A for a general register or a base register. A
general register can be an operand of most lOP
instructions; a base register is used to address
memory operands (see Section 7.6). Before initiating
a DMA transfer, the channel program points GA to
either the source or destination address of the
transfer.
7-15

210911

THE80891NPUT/OUTPUTPROCESSOR

Table 7-2 Channel Register Summary
System
Program
or liD
Access
Pointer

Use by Channel Programs

Use in DMA Transfers

Register

Size

GA

20

Update

Either

General, base

GB

20

Update

Either

General, base

Source/destination pointer

General, base

Translate table pOinter

Procedure return,
instruction pOinter

Adjusted to reflect cause of
termination

GC

20

Update

Either

TP

20

Update

Either

PP

20

IX

16

Source/destination pointer

Reference 'System Base

N/A

Update

N/A

General, auto-increment

N/A

Update

N/A

General

Byte counter

BC

16

MC

16

Update

N/A

General, masked compare

Masked compare

CC

16

Update

N/A

Restricted use recommended

Defines transfer options

General Purpose B (GB). GB is functionally inter-

changeable with GA. If GA points to the source of a
DMA transfer, then GB points to the destination,
and vice versa.
General Purpose C (GC). GC may be used as a

general register or a base register during channel program execution. If data is to be translated during a
DMA transfer, then the channel program loads GC
with the address of the first byte of a translation
table before initiating the transfer. GC is not altered
by a transfer operation.

Index (IX). IX may be used as a general register
during channel program execution, It also may be

used as an index register to address memory operands (the address of the operand is computed by
adding the content of IX to the content of a base
register), When specified as an index register, IX
may be optionally auto-incremented as the last step
in the instruction to provide a convenient means of
"stepping" through arrays or strings, IX is not used
in DMA transfers.
Byte Count (BC). BC may be used as a general

Task Pointer (TP). The CCU loads TP from the

parameter block when it starts or resumes a channel
program. During program execution, the channel automatically updates TP to point to the next instruction to be executed; i.e" TP is used as an instruction
pointer or program counter. Program transfer instructions (JMP, CALL, etc.) update TP to cause
nonsequential execution. A procedure (subroutine)
returns to the calling program by loading TP with an
address previously saved by the CALL instruction.
The task pointer is fully accessible to channel
programs; it can be used as a general register or as a
base register. Such use is not recommended,
however, as it can make programs very difficult to
understand.
Parameter Block Pointer (PP). The CCU loads

this register with the address of the parameter block
before it starts a channel program. The register
cannot be altered by a channel program, but is very
useful as a base register for accessing data in the
parameter block. PP is not used during DMA
transfers.
7-16

register during channel program execution, If DMA
is to be terminated when a specific number of bytes
has been transferred, BC should be loaded with the
desired byte count before initiating the transfer.
During DMA, BC is decremented for each byte
transferred, whether byte count termination has
been specified. If byte count termination has not
been selected, BC "wraps around" from OH to
FFFFH and continues to be decremented,
MasklCompare (MC). A channel program may

use MC for a general register. This register also may
be used either in a channel program or in a DMA
transfer to perform a masked compare of a byte
value. To use MC in this way, the program loads a
compare value in the low-order eight bits of the
register and a mask value in the upper eight bits (see
Figure 7-15). A "1" in a mask bit selects the bit in
the corresponding position in the compare value; a
"0" in a mask bit masks the corresponding bit in the
compare value. In Figure 7-15, a value compared
with MC will be considered equal if its low-order
five bits contain the value 00100; the upper three
bits may contain any value since they are masked
out of the comparison.
210911

THE80891NPUT/OUTPUTPROCESSOR

15

transfer. When this bit is zero, the channel program
runs at a normal priority; when it is one, the priority
of the program is raised to the same level as DMA
(priorities are covered later in this section). AI·
though a channel program may use CC as a general
register, such use is not recommended because of
the side effects on the chain bit and thus on the pri·
ority of the channel program. Channel programs
should restrict their use of CC to loading control
values in preparation for a DMA transfer, setting
and clearing the chain bit, and storing the register.
When initializing or updating the CC register, the
MOV or MOVI instruction must be used.

8 7
00011111

i

10100100

MASK

COMPARE

VALUE

VALUE

I~l·~-I
~
MASKED
COMPARE
VALUE

(X

=

IGNORE VALUE OF CORRESPONDING BIT)

Program Status Word (PSW)
Each channel maintains its own program status word
(PSW) as shown in Figure 7-17. Channel programs
do not have access to the PSW. The PSW records
the state of the channel so that channel operation
may be suspended and then resumed later. When
the CPU issues a "suspend" command, the channel
saves the PSW, task pointer, and task pointer tag bit
in the first four bytes of the channel's parameter
block as shown in Figure 7-18. Upon receipt ofa subsequent "resume" command, the PSW, TP, and TP
tag bit are restored from the parameter block save
area and execution resumes.

Figure 7 -15 Mask/Compare Register
Channel Control (CC). The content of the channel

control register governs a DMA transfer (see Figure
7-16). A channel program loads this register with appropriate values before beginning the transfer
operation; Section 7.4 covers the encoding of each
field in detail. Bit 8 (the chain bit) of CC pertains to
channel program execution rather than to a DMA

15
I
-r--

o

7
I
-r--

TT
I

I

TMC
I

I

L

TERMINATE ON MASKED COMPARE
TERMINATE ON BYTE COUNT
TERMINATE ON EXTERNAL SIGNAL
TERMINATE AFTER SINGLE TRANSFER
CHAINED CHANNEL PROGRAM
EXECUTION
LOCK BUS DURING TRANSFER
SOURCE/DESTINATION
SYNCHRONIZATION
TRANSLATE
FUNCTION (PORT TO PORT,
PORT TO MEMORY, ETC.)

Figure 7 -16 Channel Control Register

7-17

210911

THE 80891NPUT/OUTPUT PROCESSOR

7

0

1·Ix-I ol,sl,*ol sI01

L~OEST'NAT'ONOUSLOG'C'LW'OTH(O""'"

~~~

SOURCE BUS LOGICAL WIDTH (0 "- 8, 1

=

16)

16)

TASK BLOCK (CHANNEL PROGRAM) IN PROGRESS
INTERRUPT CONTROL (O

~

DISABLED, , "- ENABLED)

INTERRUPT SERVICE (0 ' SINTA N INACTIVE 1

=

SINTR N ACTIVE)

8US LOAD LIMIT

TRANSFER IN PROGRESS
PRIORITY BIT

Figure 7·1 7 Program Status Word

8 7

15
TP 15-8
PSW

I
1

TP 7-0

--PP

TP 19-161 TAG10 0 0

__ PP + 2

REMAINDER OF PARAMETER BLOCK

IL

_________________

I
~

I/O space. The pointer registers may address either
memory or I/O devices (lOP instructions do not distinguish between memory and I/O devices since the
latter are memory-mapped). The tag bit associated
with each register (Figure 7-14) determines whether
the register points to an address in the system space
(tag=O) or the I/O space (tag= 1).
The CCU sets or clears TP's tag bit depending on
whether the command it receives from the CPU is
"start channel program in system space," or "start
channel program in I/O space." Channel programs
alter the tag bits of GA, GB, GC, and TP by using
different instructions for loading the registers.
Briefly, a "load pointer" instruction clears a tag bit,
a "move" instruction sets a tag bit, and a "move
pointer" instruction moves a memory value (either
o or 1) to a tag bit. Section 7.7 covers these instructions in detail.
If a register points to the system space, all 20 bits are
placed on the address lines to allow the full
megabyte to be directly addressed. If a register
points to the I/O space, the upper four bits of the address lines are undefined; the lower 16 bits are sufficient to access any location in the 64K byte I/O space.

Concurrent Channel Operation
Figure 7 ·18 Channel State Save Area

Two conditions override the normal channel priority
mechanism. If one channel is performing DMA
(priority 1) and the channel receives a channel attention (priority 2), the channel attention is serviced at
the end of the current DMA transfer cycle. This
override prevents a synchronized DMA transfer
from "shutting out" a channel attention. DMA
terminations and chained channel programs postpone recognition of a CA on the other channel; the
CA is latched, however, and is serviced as soon as
priorities permit.
The lOP's LOCK (bus lock) signal also supersedes
channel switching. A running channel will not relinquish control of the processor while LOCK is active,
regardless of the priorities of the activities on the
two channels. This is consistent with the purpose of
the LOCK signal: to guarantee exclusive access to a
shared resource in a multiprocessing system. Refer
to Sections 7.S and Volume 2 for further information
on the LOCK signal and the TSL instruction.

Tag Bits
Registers GA, GB, GC, and TP are called pointer
registers because they may be used to access, or
point to, addresses in either the system space or the

Both channels may be active concurrently, but only
one can actually run at a time. At the end of each internal cycle, the CCU lets one channel or the other
execute the next internal cycle. No extra overhead is
incurred by this channel switching. The basis for
making the determination is a priority mechanism
built into the lOP. This mechanism recognizes that
some kinds of activities (e.g., DMA) are more important than others. Each activity that a channel can
perform has a priority that reflects its relative importance (see Table 7-3).
Two new activities are introduced in Table 7-3.
When a DMA transfer terminates, the channel executes a short internal channel program. This DMA
termination program adjusts TP so that the user's
program resumes at the instruction specified when
the transfer was setup (this is discussed in detail in
Section 7.4). Similarly, when a channel attention is
recognized, the channel executes an internal program that examines the CCW and carries out its
command. Both of these programs consist of standard 8089 instructions that are fetched from internal
ROM. Intel Application Note AP-SO, Debugging
Strategies and Considerations jor 8089 Systems, lists
the instructions in these programs. Users monitoring
the bus during debugging may see operands read or
written by the termination or channel attention
programs. The instructions themselves, however,
will not appear on the bus as they are resident in the
chip.
7-18

210911

THE 8089 INPUT/OUTPUT PROCESSOR

Table 7 -3 Channel Priorities and Interleave Boundaries

Channel Activity

Priority
(1 = highest)

Interleave Boundary
ByOMA
By Instruction

DMA transfer

1

Bus cycle'

DMA termination sequence

1

Internal cycle

None

Channel program (chained)

1

Internal cycle 2

Instruction

ChannelattenHonsequence

2

Internal cycle

None

Channel program (not chained)

3

Internal cycle 2

Instruction

Idle

4

Two clocks

Two clocks

Bus cycle'

'DMA is not interleaved while LOCK is active.
2Except TSL instruction; see section 3.7.
Notice also that, according to Table 7-3, a channel
program may run at priority 3 or at priority 1. Channel program priority is determined by the chain bit
in the channel control register. If this bit is cleared,
the program runs at normal priority (3); if it is set,
the program is said to be chained, and it runs at the
same priority as DMA. Thus, the chain bit provides
a way to raise the priority of a critical channel
program.
The CCU lets the channel with the highest priority
run. If both channels are running activities with the
same priority, the CCU examines the priority bits in
the PSWs. If the priority bits are unequal, the channel with the higher value (1) runs. Thus, the priority
bits serves as a "tie breaker" when the channels are
otherwise at the same priority level. The value of the
priority bit in the PSW is loaded from a corresponding bit in the CCW; therefore, the CPU can control
which channel will run when the channels are at the
same priority level. The priority bit has no effect
when the channel priorities are different. If both
channels are at the same priority level and if both priority bits are equal, the channels run alternately
without any additional overhead.
The CCU switches channels only at certain points
called interleave boundaries; these vary according to
the type of activity running in each channel and are
shown in Table 7-3. In Table 7-3 and in the following
discussion, the terms "channel A" and "channel B"
are used to identify two active channels that are bidding for control of an lOP. "Channel A" is the channel that last ran and will run again unless the CCU
switches to "channel B." Where the CCU switches
from one channel (channel A) to another (channel
B) depends on whether channel B is performing
DMA or is executing instructions. For this
determination, instructions in the internal ROM are

considered the same as instructions executed in
user-written channel programs (chained or not
chained). Table 7-3 shows that a switch from channel
A to channel B will occur sooner if channel B is running DMA. DMA, then, interleaves instruction execution at internal cycle boundaries. Since instructions
are often composed of several internal cycles, instruction execution on channel A can be suspended
by DMA on channel B (when channel A next runs,
the instruction is resumed from the point of
suspension). DMA on channel A is interleaved by
DMA on channel B after any bus cycle (when channel A runs again, the DMA transfer sequence is
resumed from the point of suspension). If both channels are executing programs, the interleaved
boundaries are extended to instruction boundaries:
a program on channel B will not run until channel A
reaches the end of an instruction. Note that a DMA
termination sequence or channel attention sequence
on channel A cannot be interleaved by instructions
on channel B, regardless of channel B's priority.
These internal programs are short, however, and
will not delay channel B for long (see Chapter 4 for
timing information).
Table 7-4 summarizes the channel switching mechanism with several examples. It is important to
remember that channel switching occurs only when
both channels are ready to run. In typical
applications, one of the channels will be idle much of
the time, either because it is waiting to be dispatched
by the CPU, or because it is waiting for a DMA request in a synchronized transfer. (During a synchronized transfer, the channel is idle between DMA
requests; for many peripherals, the channel will
spend much more time idling than executing DMA
cycles.) The real potential for one channel "shutting
out" a priority I activity on the other channel is
largely limited to unsynchronized DMA transfers
and locked transfers (synchronized or unsynchro7-19

210911

THE 8089 INPUT/OUTPUT PROCESSOR

unsynchronized). Long, chained channel programs
and high-speed synchronized DMA will slow a priority I activity on the other channel, but will not
shut it out because the channels will alternate
(assuming their priority bits are equal). A chained
channel program will shut out any lower priority activity on the other channel, including a channel
attention. (The channel attention is latched by the
lOP, however, so it will execute when the other
channel drops to a lower priority.) Chained channel
programs should therefore be used with discretion
and should be made as short as possible.

Programmed I/O
A channel program performs I/O similar to the way
a CPU communicates with memory-mapped I/O
devices. Memory reference instructions perform the
transfer rather than "dedicated" I/O instructions,
such as the 8086,8088 IN and OUT instructions. Programmed I/O is typically used to prepare a device
controller for a DMA transfer and to obtain
statuslresult information from the controller following termination of the transfer. It may, however, be
used with any device whose transfer rate does not requireDMA.

I/O Instructions

7.4 INPUT/OUTPUT
The 8089 combines the programmed 1/0 capabilities
of a CPU with the high-speed block transfer facility
of a DMA controller. It also provides additional features (e.g., compare and translate during DMA) and
is more flexible than a typical CPU or DMA
controller. The 8089 transfers data from a source address to a destination address. Whether the component mapped into a given address is actually
memory or I/O is immaterial. All addresses in both
the system and I/O spaces are equally accessible, and
transfers may be made between the two spaces as
well as within either address space.

Since the 8089 does not distinguish between
memory components and 1/0 devices, any instruction that accepts a byte or word memory operand
can be Qsed to access an I/O device. Most memory
reference instructions take a source operand or a
destination operand, or both. The instructions generally obtain data from the source operand, operate on
the data, and then place the result of the operation in
the destination operand. Therefore, when a source
operand refers to an address where an 1/0 device is
located, data is input from the device. Similarly,
when a destination operand refers to an I/O device
address, data is output to the device.

Table 7-4 Channel Switching Examples
Channel A (Ran Last)

Channel B
Result

Activity

Chain
Bit

Priority
LOCK
Bit

Activity

Chain
Bit

Priority
Bit

DMA transfer
DMA transfer

X
X

X
X

Inactive
Inactive

Idle
Channel attention

X
X

X
X

Channel program
Channel program

X
X

0
0

Inactive
Inactive

Channel program
Channel program

X
X

0

Channel program
DMA transfer

1
X

"X
1

Inactive
Inactive,

Channel program
Channel program

1

X
1

0

1

,
Channel attention

X

X

Inactive

Channel program

1

X

DMA transfer
Channel program
(TSL instruction)

X
0

X
X

Active
Active

Channel attention
DMA transfer

X
X

X
X

A runs.
A runs until end of current
transfer cycle: then Bruns.
Bruns.
A and B alternate by
instruction.
A runs.
B runs one bus or internal
cycle following each bus cycle
run by A.'
A runs if it has started the
sequence: otherwise Bruns.
A runs until DMA terminates.
A completes TSL instruction,
LOCK goes inactive and B
runs.

'If transfer is synchronized, B also runs when A goes idle between transfer cycles.

7-20

210911

THE 8089 INPUT/OUTPUT PROCESSOR

Most 110 device controllers have one or more internal registers that accept commands and supply status
or result information. Working with these registers
typically involves:
•

reading or writing the entire register;

•

setting or clearing some bits in a register
while leaving others alone; or

•

testing a single bit in a register.

pointer registers GA, GB, or GC (PP is legal, but an
110 device would not normally be mapped into a
parameter block). The base address of the device is
taken from the specified pointer register. Any of the
memory addressing modes (see Section 7.6) may be
used to modify the base address to produce the effective (actual) address of the device. The pointer register's tag bit locates the device in the system space
(tag=O) or in the 110 space (tag=l). If the device is
in the 110 space, only the low-order 16 bits of the
pointer register are used for the base address; all 20
bits are used for a system space address. The lOP's
system and 1/0 spaces are fully compatible with the
corresponding address spaces of the other iAPX
86,186 family processors.

Table 7-5 shows some of the 8089 instructions that
are useful for performing these kinds of operations.
Section 7.5 covers the 8089 instruction set in detail.

I/O Bus Transfers

Table 7 -5 Memory Reference
Instructions Used for I/O

Table 7-6 shows the number of bus cycles the lOP
runs for all combinations of bus size, transfer size
(byte or word), and transfer address (even or odd).
Bus width refers to the physical bus implementation;
the instruction mnemonic determines whether a
byte or a word is transferred.

Effect on I/O Device

Instruction

MOV/MOVB Read or write word / byte
AND/ANDB

Clear multiple bits in word / byte

OR/ORB

Set multiple bits in word/byte

CLR

Clear single bit (in byte)

SET

Set single bit (in byte)

JBT

Read (byte) and jump if
single bit =1

JNBT

Read (byte) and jump if
single bit =0

Device Addressing

Both 8- and 16-bit devices may reside on a 16-bit
bus. All 16-bit devices should be located at even addresses so that transfers will be performed in one
bus cycle. The 8-bit devices on a 16-bit bus may be
located at odd or even addresses. The internal registers in an 8-bit device on a 16-bit bus must be assigned all-odd or all-even addresses that are two
bytes apart (e.g., IH, 3H, 5H, or 2H, 4H, 6H). All
8-bit peripherals should be referenced with byte
instructions, and 16-bit devices should be referenced
with word instructions. Odd-addressed 8-bit devices
must be able to transfer data on the upper eight bits
of the 16-bit physical data bus.

Since memory reference instructions are used to perform programmed 1/0, device addressing is very
similar to memory addressing. An operand that
refers to an I/O device always specifies one of the

Only 8-bit devices should be connected to an 8-bit
bus, and these should only be referenced with byte
instructions. An 8-bit device on an 8-bit bus may be
located at an odd or even address, and its internal

Table 7 -6 Programmed I/O Bus Transfers

Bus Width:
Instruction:
Device Address:
Bus Cycles:

16

8
byte

word'

byte

word

even

odd

even

odd

even

odd

even

odd'

1

1

2

2

1

1

1

2

• not normally used
7-21

210911

THE 80891NPUT/OUTPUT PROCESSOR

Some controllers start a DMA transfer immediately
upon receiving the last of a series of parameters. If
this type of controller is being used, the channel program instruction that sends the last parameter
should follow the 8089 XFER instruction. (The
XFER instruction places the channel in DMA mode
after the next instruction; this is explained in more
detail later in this section).

registers may be assigned consecutive addresses
(e.g., IH, 2H, 3H). Assigning all-odd or all-even
addresses, however, will simplify conversion to a
l6-bit bus at a later date.

DMA Transfers
In addition to byte- and word-oriented programmed
110, the 8089 can transfer blocks of data by direct
memory access. A block may be transferred between
any two addresses; memory-to-memory transfers
are performed as easily as memory-to-port, portto-memory or port-to-port exchanges. There is no
limitation on the size of the block that can be transferred except that the block cannot exceed 64K
bytes if byte count termination is used. A channel
program typically prepares for a DMA transfer by
writing commands to a device controller and initializing channel registers that are used during the
transfer. No instructions are executed during the
transfer, however, and very high throughput speeds
.
can be achieved.

Preparing the Channel
For a channel to perform a DMA transfer, it must
be provided with information that describes the
operation. The channel program provides this information by loading values into channel registers and,
in one case, by executing a special instruction (see
Table 7-7).
Source and destination pointers. One register is
loaded to point to the transfer source; the other
points to the destination. A bit in the channel control
register is set to indicate which register is the source
pointer. If a register is pointed at a memory location,
it should contain the address where the transfer is to
begin - i.e., the lowest address in the buffer. The
channel automatically increments a memory pointer
as the transfer proceeds. If the tag bit selects the I/O
space, the upper four bits of the register are ignored;
if the tag selects the system space, all 20 bits are
used. The source and destination may be located in
the same or in different address spaces.

Preparing the Device Controller
Most controllers that can perform DMA transfers
are quite flexible in that they can perform several different types of operations. For example, an 8272
Floppy Disk Controller can read a sector, write a
sector, seek to track 0, etc. The controller typically
has one or more internal registers that are
"programmed" to perform a given operation. Often,
certain registers will contain status information that
can be read to determine if the controller is b'usy, if
it has detected an error, etc.

Translate Table Pointer. If the data is to be
translated as it is transferred, GC should be pointed
at the first (lowest-addressed) byte in a 256-byte
translation table. The table may be located in either
the system or 110 space, and GC should be loaded
by an instruction that sets or clears its tag bit as
appropriate. The translate operation is only defined
for byte data; source and destination logical bus
width must both be set to eight bits.

An 8089 channel program views these device registers as a series of memory locations. The channel
program typically places the device's base address in
a pointer register and uses programmed 110 to communicate with the registers.

Table 7 - 7 DMA Transfer Control Information
Information

Source Pointer
Destination Pointer
Translate Table Pointer
Byte Count
Mask/Compare Values
Logical Bus Width
Channel Control

Register or Instruction

Required or Optional

GAorGB
GAorGB
GC
BC
MC
WID
CC

Required
Required
Optional
Optional
Optional
Optional'
Required

'Must be executed once following processor RESET.
7-22

210911

THE 8089 INPUT/OUTPUT PROCESSOR

For a transfer to or from an I/O device on a 16-bit
physical bus, the logical bus width should be set
equal to the peripheral's width; i.e., 8 or 16 bits.
Transfers to or from 16-bit memory will run at maximum speed if the logical bus width is set to 16, since
the channel will fetch/store words. In the following
cases, however, the logical width should be set to 8:

The channel translates a byte by treating it as an unsigned 8-bit binary number. This number is added to
the contents of register GC to form a memory
address; GC is not altered by the operation. If GC
points to the I/O space, its upper four bits are ignored
in the operation. The byte at this address (which is in
the translate table) is then fetched from memory,
replacing the source byte. Figure 7-19 illustrates the
translate process.

TRANSLATE TABLE
IN SYSTEM OR I/O SPACE

00'001-..J3FJ4CJ .. J19JB7J
GC

B

00202

:
I

~ ______ J

TRANSLATE ADDRESS

_~_

the data is being translated,

•

the data is being compared under mask, and
the 16-bit memory is the destination of the
transfer.

The WID instruction sets both logical widths and remains in effect until another WID instruction is
executed. Following processor reset, the settings of
the logical bus widths are unpredictable. Therefore,
the WID instruction must be executed before the
first DMA transfer.

•

SOURCE BYTE

•

TO DESTINATION

TRANSLATED BYTE

Channel Control. The 16 bits of the CC register

are divided into 10 fields that specify how the DMA
transfer is to be executed (see Figure 7-20). A channel program typically sets these fields by loading a
word into the register. When initializing or updating
the CC register, the MOV or MOVI instruction
must be used.

Figure 7 -1 9 Translate Operation
Byte Count. If the transfer is to be terminated on

byte count-i.e., after a specific number of bytes
have been transferred-the desired count should be
loaded into register BC as an unsigned 16-bit
number. The channel decrements BC as the transfer
proceeds, whether or not byte count termination has
been specified. There are cases (discussed later in
this section) where the difference between BC's
value before and after the transfer does not accurately reflect the number of bytes transferred to the
destination.

The junction field (bits 15-14) identifies the source
and destination as memory or ports· % devices).
During the transfer, the channel increments
source/destination pointer registers that refer to
memory, so that the data will be placed in successive
locations. Pointers that refer to I/O devices remain
constant throughout the transfer.

Mask/Compare Values. If the transfer is to be terminated when a byte (possibly translated) is found
equal or unequal to a search value, MC. should be .
loaded as described in Section 7.3. MC is not altered
during the transfer. Normally, the logical destination
bus width is set to eight bits when transferred data is
being compared. If the logical destination width is 16
bits, only the low-order byte of each word is
compared.
Logical Bus Width. The 8089 WID (logical bus

width) instruction is used to set the logical width of
the source and destination buses for a DMA
transfer. Any bus whose physical width is eight bits
can only have a logical width of eight bits. A 16-bit
physical bus, however, can have a logical width of 8
or 16 bits; i.e., it can be used as either an 8-bit or
16-bit bus in any given transfer. Logical bus widths
are set independently for each channel.

The translate field (bit 13) controls data translation.
If it is set, each incoming byte is translated using the
table pointed to by register GC. Translate is defined
only for byte transfers; the destination bus must
have a logical width of eight.
The synchronization field (bits 12-11) specifies how
the transfer is to be synchronized. Unsynchronized
("free running") transfers are typically used in
memory-to memory moves. The channel begins the
next transfer cycle immediately upon completion of
the current cycle (assuming it has the bUS). Slow
memories, which cannot run as fast as the channel,
can extend bus cycles by signaling "not ready" to
the 8284A Clock Generator, which will insert wait
states into the bus cycle. A similar technique may be
used with peripherals whose speed exceeds the channel's ability to execute a synchronized transfer: in
effect, the peripheral synchronizes the transfer
through the use of wait states. Chapter 4 discusses
synchronization in more detail.

7-23

210911

THE 8089 INPUT/OUTPUT PROCESSOR

15

o

7

£.
00
01
10
11
TR

o
1

FUNCTION
PORT TO PORT
MEMORY TO PORT
PORT TO MEMORY
MEMORY TO MEMORY
TRANSLATE
NO TRANSLATE
TRANSLATE

SYN SYNCHRONIZATION
00
NO SYNCHRONIZATION
01
SYNCHRONIZE ON SOURCE
10
SYNCHRONIZE ON DESTINATION
11
RESERVED BY INTEL
S

SOURCE
GA POINTS TO SOURCE
GB POINTS TO SOURCE

o
1

L

LOCK
NO LOCK
ACTUATE LOCK DURING TRANSFER

o
1

C

CHAIN
NO CHAINING
CHAINED: RAISE TB TO PRIORITY 1

o
1

TS

o
1

TX

00
01
10
11

TERMINATE ON SINGLE TRANSFER
NO·SINGLE TRANSFER TERMINATION
TERMINATE AFTER SINGLE TRANSFER
TERMINATE ON EXTERNAL SIGNAL
NO EXTERNAL TERMINATION
TERMINATE ON EXT ACTIVE; OFFSET
TERMINATE ON EXT ACTIVE; OFFSET
TERMINATE ON EXT ACTIVE; OFFSET

TBC TERMINATE ON BYTE COUNT
NO BYTE COUNT TERMINATION
01
TERMINATE ON BC = 0; OFFSET
10
TERMINATE ON BC
0; OFFSET
11
TERMINATE ON BC = 0; OFFSET

00

=

TMC
000
001
010
011
100
101
110
111

=0
=4
=8

=0
=8

=4

TERMINATE ON MASKED COMPARE
NO MASK/COMPARE TERMINATION
TERMINATE ON MATCH; OFFSET = 0
TERMINATE ON MATCH; OFFSET = 4
TERMINATE ON MATCH; OFFSET = 8
(NO EFFECT)
TERMINATE ON NON-MATCH; OFFSET = 0
TERMINATE ON NON-MATCH; OFFSET = 4
TERMINATE ON NON-MATCH; OFFSET = 8

Figure 7-20 Channel Control Register Fields

7-24

210911

THE80891NPUT/OUTPUTPROCESSOR

Source synchronization is typically selected when
the source is an I/O device and the destination is
memory. The I/O device starts the next transfer
cycle by activating the channel's DRQ (DMA
request) line. The channel then runs one transfer
cycle and waits for the next DRQ.
Destination synchronization is most often used
when the source is memory and the destination is an
I/O device. Again, the I/O device controls the transfer frequency by signaling on DRQ when it is ready
to receive the next byte or word.
The source field (bit 10) identifies register GA or GB
as the source pointer (and the other as the destination pointer).
The lock field (bit 9) may be used to instruct the
channel to assert the processor's bus lock (LOCK)
signal during the transfer. In a source-synchronized
transfer, LOCK is active from the time the first
DMA request is received until the channel enters
the termination sequence. In a destination synchronized transfer, LOCK is active from the first fetch
(which precedes the first DMA request) until the
channel enters the termination sequence.
The chain field (bit 8) is not used during the transfer.
As discussed previously, setting this bit raises channel program execution to priority level 1.

When a DMA transfer ends, the channel adds a
value called the termination offset to the task pointer
and resumes channel program execution at that
point in the program. The termination offset may
assume a value of 0, 4, or 8. Single transfer termination always results in a termination offset of O.
Figure 7-21 shows how the termination offsets can
be used as indices into a three-element "jump table"
that identifies the condition that caused the
termination.
As an example of using the jump table, consider a
case in which a transfer is to terminate when 80
bytes have been transferred or a linefeed character is
detected, whichever occurs first. The program
would load 50H into BC and OOOAH into MC
(ASCII line feed, no bits masked). The channel program could assign byte count termination an offset
of 0 and masked compare termination an offset of 4.
If the transfer is terminated by byte count (no linefeed is found), the instruction at location TP + 0
will be executed first after the termination. If the
linefeed is found before the byte count expires, the
instruction at TP + 4 will be executed first. The
LJMP (long unconditional jump, see Section 7.5) instruction is four bytes long and can be placed at TP
+ 0 and TP + 4 to cause the channel program to
jump to a different routine, depending on how the
transfer terminates.

The terminate on single transfer field (bit 7) can be
used to cause the channel to run one complete transfer cycle only - i.e., to transfer one byte or word
and immediately resume channel program execution. When single transfer is specified, any other termination conditions are ignored. Single transfer
termination can be used with low-speed devices,
such as keyboards and communication lines, to
translate and/or compare one byte as it is
transferred.

.... -(COUL.D BE A DIFFERENT INSTRUCTION)

(TP POINTS TO 1ST LJMP INSTRUCTION) ' -_ __

The three low-order fields in register CC instruct the
channel when to terminate the transfer, assuming
that single transfer has not been selected. Three
termination conditions may be specified singly or in
combination.

LJMP OFFSET _O_CODE

}

:r"".!I~LJ:::MP~C::F:::FS::E:-L-:4__~CC::D:-E.,
L__TP+8

THREE-ELEMENT JUMP TABLE

LJMP OFFSET _8_CODE

OFFSET

External termination allows an 110 device (typically,
the one that is synchronizing the transfer) to stop
the transfer by activating the channel's EXT
(external terminate) line. If byte count termination
is selected, the channel will stop when BC=O. If
masked compare termination is specified, the channel will stop the transfer when a byte is found that is
equal or unequal (two options are available) to the
low-order byte in MC as masked by MC's high-order
byte. The byte that stops the termination is
transferred. If translate has been specified, the
translated byte is compared.

_o_cOOEl

T

eXECUTED IF TERMINATION

OFFSET _4

OFFSET = 0

CCDEI

T

EXECUTED IF TERMINATION
OFFSET = 4

OFFSET

8

CCDEI

T

eXECUTED IF TERMINATION
OFFSET. 8

!
J
1
T
1
T

Figure 7-21 Termination Jump Table
7-25

210911

THE80891NPUT/OUTPUTPROCESSOR

If the transfer can only terminate in one way and
that condition is assigned an offset of 0, there is no
need for the jump table. Code which is to be unconditionally executed when the transfer ends can
immediately follow the instruction after XFER.This
is also the case when single transfer is specified
(execution always resumes at TP + 0).
It is possible, however, for two, or even three, termi-

nation conditions to arise at the same time. In the
preceding example, this would occur if the 80th character were a linefeed. When multiple terminations
occur simultaneously, the channel indicates that
termination resulted from the condition with the largest offset value. In the preceding example, if byte
count and search termination occur at the same
time, the channel program resumes at TP + 4.

Beginning the Transfer
The 8089 XFER (transfer) instruction puts the channel into DMA transfer mode after the following in,
struction has been executed. This technique allows
the channel time to set itself up when it is used with
device controllers, such as the 8272 Floppy Disk
Controller, that begin transferring immediately
upon receipt of the last in a series of parameters or
commands. If the transfer is to or from such a
device, the last parameter should be sent to the
device after the XFER instruction. If this type of
device is not being used, the instruction following
XFER would typically send a "start" commalld to
the controller. If a memory-to-memory transfer is
being made, any instruction may follow XFER
except one that alters GA, GB, or CC. The HLT instruction should normally not be coded after the
XFER; doing so clears the channel's BUSY flag, but
allows the DMA transfer to proceed.

If the transfer is source-synchronized, the channel
waits until the synchronizing device activates the
channel's DRQ line. The other channel is free to run
during this idle period. The channel fetches a byte or
a word, depending on the source address (contained
in GA or GB) and the logical bus width. Table 7-8
shows how a channel performs the fetch/store sequence for all combinations of addresses and bus
widths. If the destination is on a 16-bit logical bus
and the source in on an 8-bit logical bus, and the
transfer is to an even address, the channel fetches a
second byte and assembles a word internally. During
each fetch, the channel decrements BC according to
whether a byte or word is obtained. Thus BC always
indicates the number of bytes fetched.
The channel samples its EXT line after every bus
cycle in the transfer. If EXT is recognized after the
first of two scheduled fetches, the second fetch is not
run. After the fetch sequence has been completed,
the channel translates the data if this option is specified in CC.
If a word has been fetched or assembled, and bytes
are to be stored (destination bus is eight bits or
transfer is to an odd address), the channel disassembles the word into two bytes. If the transfer is
destination-synchronized (only one type of synchronization may be specified for a given transfer),
the channel waits for DRQ before running a store
cycle. It stores a word or the lower-addressed byte
(which may be the only byte or the first of two
bytes). Table 7-8 shows the possible combinations of
even/odd addresses and logical bus widths that
define the store cycle. Whenever stores are to
memory on a 16-bit logical bus, the channel stores
words, except that bytes may be stored on the first
and last cycles.

Table 7 -8 DMA Transfer Assembly/Disassembly

DMA Transfer Cycle
A DMA transfer cycle is illustrated in Figure 7-22; a
complete transfer is a series of these cycles run until
a termination condition is encountered. The figure is
deliberately simplified to explain the general operation of a DMA transfer; in particular, the updating
of the source and destination pointer (GA and GB)
can be more complex than the figure indicates.
Notice that it is possible to start an unending transfer
by not specifying a termination condition in CC or
by specifying a condition that never occurs; it is the
programmer's responsibility to ensure that the transfer eventually stops.

Address
(Source .....
Destination)

Logical Bus Width
Source ..... Destination)

8 ..... 8

8 .... 16

16..... 8

16 ..... 16

EVEN ..... EVEN
EVEN ..... ODD
ODD .... EVEN
ODD ..... ODD

B..... B
B.... B
B.... B
B.... B

B/B ..... W
B.... B
B/B--+W
B..... B

W..... B/B
W..... B/B
B.... B
B..... B

W..... W
W.... B/B
B/B ..... W
B..... B

B= Byte Fetched or Stored in 1 Bus Cycle
W= Word Fetched or Stored in 1 Bus Cycle
7-26

210911

I

THE 8089 INPUT/OUTPUT PROCESSOR

I

Figure 7-22 Simplified DMA Transfer Flowchart

The channel samples EXT again after the first store
cycle and, if it is active, the channel prevents the
second store cycle from running. If specified in the
CC register, the low-order byte is compared to the
value in MC. A "hit" on the comparison (equal or
unequal, as indicated in CC) also prevents the
second of two scheduled store cycles from running.
In both of these cases, one byte has been
"overfetched," and this is reflected in BC's value. It

would be unusual, however, for a synchronizing
device to issue EXT in the midst of a DMA cycle.
Note also that EXT is valid only when DRQ is
inactive. Chapter 4 covers the timing requirements
for these two signals in detail.
GA and GB are updated next. Only memory pointers
are incremented; pointers to 1/0 devices remain constant throughout the transfer.
7-27

210911

THE 80891NPUT/OUTPUT PROCESSOR

final value of BC from its original value provided
that:

If a termination condition has occurred during this
cycle, the channel stops the transfer. It uses the contents of the CC register to assign a value to the
termination offset, to reflect the cause of the
termination. The channel adds this offset to TP and
resumes channel program execution at the location
now addressed by TP. This offset will always be
zero, four, or eight bytes past the end of the instruction following the XFER instruction.

> final BC,

•

the original BC

•

a transfer cycle is not "chopped off" before it
completes by a masked compare or external
termination.

-

In general, programs should not use the contents of
GA, GB and BC following a transfer except as noted
above and in Table 7-9. This is because the contents
of the registers are affected by numerous conditions,
particularly when the transfer is terminated by EXT.
In particular, when a program is performing a sequence of transfers, it should reload these registers
before each transfer.

If no termination condition is detected and. another
byte remains to be stored, the channel stores this
byte, waiting for DRQ if necessary, and updates the
source and destination pointers. After the store, it
again checks for termination.

Following the Transfer
A DMA transfer updates register BC, register GA
(if it points to memory), and register GB (if it points
to memory). If the original contents of these registers are needed following the transfer, the contents
should be saved in memory prior to executing the
XFER instruction.

7.5 INSTRUCTION SET
This section divides the lOP's 53 instruction into
five functional categories:
1) data transfer,

A program may determine the address of the last
byte stored by a DMA transfer by inspecting the
pointer registers as shown in Table 7-9. The number
of bytes stored is equal to:
iasLbyte-llddress-first_byte-llddress

2) arithmetic,
3) logic and bit manipulation,

+ 1.

4) program transfer,

For port-to-port transfers, the number of bytes
transferred can be determined by subtracting the

5) processor control.

Table 7 -9 Address of Last Byte Store
Termination

Source

Destination

Synchronization

Last Byte Stored

byte count

memory
memory
port

memory
port
memory

any
any
any

destination pointer'
source pOinter
destination pointer

masked compare

memory
memory
port

memory
port
memory

any
any
any

destination pointer
source pOinter
destination pointer

external

memory
memory
port

memory
port
memory

unsynchronized
destination
source

destination pOinter
source pOinter'
destination pointer

'Source pointer may also be used.
'If transfer is BI B-W, source pOinter must be decremented by 1 to point to last byte transferred.
7-28

210911

THEBOB91NPUT/OUTPUTPROCESSOR

The description of each instruction in these categories explains how the instruction operates, and how
it may be used in channel programs. Instructions
that perform essentially the same operation (e.g.,
ADD and AD DB, which add words and bytes
respectively), are described together. A reference
table at the end of the section lists every instruction
alphabetically and provides execution time, encoded
length, and sample ASM-89 coding for each permissible operand combination.

Figure 7-23 shows how these instructions affect
register operands. Notice that when a pointer register
is specified as the destination of a MOV, its tag bit is
unconditionally set to 1. MOV instructions are therefore used to load 110 space addresses into pointer
registers.
MOVP destination, source

MOVP (move pointer) transfers a physical address
variable between a pointer register and memory. If
the source is a pointer register, the contents of the
20-bit pointer register and its tag bit are stored in
three consecutive memory bytes beginning at the
destination (memory location). If the source is a
memory location, the three consecutive bytes beginning at the source (memory location) are loaded
into the 20-bit pointer register and its tag bit. MOVP
is typically used to save and restore pointer registers.
If the destination is a memory location, this memory
location must be at an even address.

In reading this section, it is important to recall that
the instruction set does not differentiate between
memory addresses and I/O device addresses. Instructions that are described as accepting byte and
word memory operands may also be used to read
and write 110 devices.

Data Transfer Instructions

LPD destination, source

These instructions move data between memory and
channel registers. Traditional byte and word moves
(including memory-to-memory) are available, as
are special instructions that load addresses into
pointer registers and update tag bits in the process.

LPD (load pointer with doubleword) converts a doubleword pointer to a 20-bit physical address and
loads it into the destination, which must be a pointer
register. The pointer register's tag bit is unconditionally cleared to 0, indicating a system address. Two instructions are provided:

MOV destination, source

LPD
LPDI

MOV transfers a byte or word from the source to the
destination. Four instructions are provided:

Mav
MaVB
MaVI
MaVBI

An 8086 or 80186 can pass any address in its
megabyte memory space to a channel program in
the form of a doubleword pointer. The channel program can access the location by using LPD to load
the location address into a pointer register.

Move Word Variable,
Move Byte Variable,
Move Word Immediate,
Move Byte Immediate.

Register is Source

Register is Destination
Tag 19

15

7

Tag 19

0

-L 1J LS~ ~ sis S S S S S S SiR R R R R R R R

I

Word
rlr-Operation L 1J LS~ ~ siR R R R R R R R R R R R R R R R

I

Byte
Operation

r

1 r.

I

T
R
S
X
1

Load Pointer With Doubleword Variable
Load Pointer With Doubleword Immediate

15

7

~xJ0~~xlx X X X X X X XIT T T T T T TTl

bit is transferred to destination operand
bit is replaced by source operand
= bit is sign extension of high-order bit transferred
= bit is ignored
= bit is unconditionally set
=
=

Figure 7-23 Register Operands in MOV Instructions

7-29

210911

THE 80891NPUT/OUTPUT PROCESSOR

Arithmetic Instructions

ADDI
ADDBI

The arithmetic instructions interpret all operands as
unsigned binary numbers of 8, 16 or 20 bits. Signed
values may be represented in standard two's complement notation with the high-order bit representing
the sign (O=positive, I = negative). The processor,
however, has no way of detecting an overflow into a
sign bit, so this possibility must be provided for in
the user's software.

INC destination

The destination is incremented by 1. Two instructions are available:
INC
INCB

The 8089 performs arithmetic operations to 20 significant bits as follows. Byte and word operands are
sign-extended to 20 bits (e.g., bit 7 of a byte operand
is propagated through bits 8-19 of an internal
register). Sign extension does not affect the magnitude of the operand. The operation is then
performed, and the 20-bit result is returned to the
destination operand. High-order bits are truncated
as necessary to fit the result in the available space. A
carry out of, or borrow into, the high-order bit of
the result is not detected. However, if the destination
is a register that is larger than the source operand,
carries will be reflected in the upper register bits, up
to the size of the register.

Increment Word
Increment Byte

DEC destination

The destination is decremented by 1. Word and byte
instructions are provided:
DEC
DECB

Decrement Word
Decrement Byte

Logical and Bit Manipulation Instructions
The logical instructions include the boolean operators AND, OR, and NOT. Two bit manipulation instructions are provided for setting or clearing a
single bit in memory or in an 110 device register. As
shown in Figure 7-25, the logical operations always
leave the upper four bits of 20-bit destination registers undefined. These bits should not be assumed to
contain reliable values or the same values from one
operation to the the next. Notice also that when. a
register is specified as the destination of a byte
operation, bits 8-15 are overwritten by bit 7 of the
result. Bits 8-15 can be preserved in AND and OR instructions by using word operations in which the
upper byte of the source operand is FFH or OOH,
respectively.

Figure 7-24 shows how the arithmetic instructions
treat registers when they are specified as source and
destination operands.

ADD destination, source

The sum of the two operands replaces the destination operand. Four addition instructions are
provided.
ADD
ADDB

Add Word Immediate
Add Byte Immediate

Add Word Variable
Add Byte Variable

Register is Destination
Tag 19

Register is Source
Tag 19

7

15

15

7

Byte
Operation

~~~~~RIRRRRRRRRIRRRRRRRR

I

~xj~~~xlxxxxxxxxlpppppppp

I

Word
Operation

~xJ~~~RIRRRRRRRRIRRRRRRRR

I

~x~~~~xlpppppppplpppppppp

I

x
R
p

~
~
~

bit is ignored in operation
bit is replaced by operation result
bit participates in operation

Figure 7 - 24 Register Operands in Arithmetic Instructions

7-30

210911

THE 80891NPUT/OUTPUT PROCESSOR

Register is Destination
Tag 19
Byte
Operation

Word
Operation

15

7

Register is Source
0

Tag 19

r r. - - - ,--------..------...,

L~LU_U_U uis S S S S S S SiR R R R R R RR I

r:J r-LlSC:J~~

UIRR R R RR RRIR R R R RR RR
X
U
R
S
P

=
=
=
=
=

15

7

o

[xJ G~ ~ XIX X X X X X X XIp p p p p p p p I

I

bit is ignored in operation
bit is undefined following operation
bit participates in operation and is replaced by result
bit is sign-extension of high-order result bit
bit participates in operation, but is unchanged

Figure 7 -25 Register Operands in Logical Instructions
AND destination, source

The two operands are logically ANDed and the
result replaces the destination operand. A bit in the
result is set if the bits in the corresponding positions
of the operands are both set; otherwise the result bit
is cleared. The following AND instructions are
available:
AND
ANDB
AND!
ANDBI

Logical AND
Logical AND
Logical AND
Logical AND

Word Variable
Byte Variable
Word Immediate
Byte Immediate

AND is useful when more than one bit of a device
register must be cleared while leaving the remaining
bits intact. For example, ANDing an 8-bit register
with EER only clears bits 0 and 4.

with 30R sets bits 4 and 5, but does not affect the
other bits.

NOT destination/destina tion,source

NOT inverts the bits of an operand. If a single operand is coded, the inverted result replaces the original
value. If two operands are coded, the inverted bits of
the source replace the destination value (which must
be a register), but the source retains its original
value. In addition to these two operand forms, separate mnemonics are provided for word and byte
values:
NOT
NOTB

Logical NOT Word
Logical NOT Byte

NOT followed by INC will negate (create the two's
complement of) a positive number.
OR destination, source
The two operands are logically ORed, and the result
replaces the destination operand. A bit in the result
is set if either or both of the corresponding bits of
the operands are set; if both operand bits are
cleared, the result bit is cleared. Four types of OR instructions are provided:
OR
ORB
ORI
ORBI

Logical OR Word Variable
Logical OR Byte Variable
Logical OR Word Immediate
Logical OR Byte Immediate

SETS destination, bit-select

The bit-select operand specifies one bit in the
destination, which must be a memory byte, that is
unconditionally set to 1. A bit-select value of 0 specifies the low-order bit of the destination while the
high-order bit is set if bit-select is 7. SETB is handy
for setting a single bit in an 8-bit device register.

CLR des tina tion, bit-select

OR can be used to selectively set multiple bits in a
device register. For example, ORing an 8-bit register

CLR operates exactly like SETB except that the
selected bit is unconditionally cleared to O.
7-31

210911

THE 8089 INPUT/OUTPUT PROCESSOR

Program Transfer Instructions
Register TP controls the sequence in which channel
program instructions are executed. As each instruction is executed, the length of the instruction is
added to TP so that it points to the next sequential
instruction. The program transfer instructions can
alter this sequential execution by adding a signed displacement value to TP. The displacement is contained in the program transfer instruction and may
be either 8 or 16 bits long. The displacement is
encoded in two's complement notation, and the
high-order bit indicates the sign (O=positive
displacement, 1 = negative displacement). An 8-bit
displacement may cause a transfer to a location in
the range -128 through + 127 bytes from the end
of the transfer instruction, while a l6-bit displacement can transfer to any location within - 32,768
through + 32,767 bytes. An instruction containing
an 8-bit displacement is called a short transfer and
an instruction containing a 16-bit displacement is
called a long transfer.
The program transfer instructions have alternate
mnemonics. If the mnemonic begins with the letter
"L," the transfer is long, and the distance to the
transfer target is expressed as a 16-bit displacement
regardless of how far away the target is located. If
the mnemonic does not begin with "L," the
ASM-89 assembler may build a short or long displacement according to rules discussed in Section
7.7.
The "self-relative" addressing technique used by
program transfer instructions has two important
consequences. First, it promotes positionindependent code, i.e., code that can be moved in
memory and still execute correctly. The only restriction here is that the entire program must be moved
as a unit so that the distance between the transfer instruction and its target does not change. Second, the
limited addressing range of the instructions must be
kept in mind when designing large (over 32K bytes
of code) channel programs.

Notice that the 8089's facilities for implementing
subroutines, or procedures, is less sophisticated
than its counterparts in the 8086,88/80186,188. The
principal difference is that the 8089 does not have a
built-in stack mechanism. 8089 programs can implement a stack using a base register as a stack pointer.
On the other hand, since channel programs are not
subject to interrupts, a stack will not be required for
most channel programs.
JMP/LJMP target

JMP causes an unconditional transfer (jump) to the
target location. Since the task pointer is not saved,
no return to the instruction following the JMP is
implied.
JZ/LJZ source, target

JZ (jump if zero) effects a transfer to the target location if the source operand is zero; otherwise the instruction following JZ is executed. Word and byte
values may be tested by alternate instructions:
JZ/LJZ
JZB/LJZB

Jump/Long Jump if Word Zero
Jump/Long Jump if Byte Zero

Ifthe source operand is a register, only the low-order
16 bits are tested; any additional high-order bits in
the register are ignored. To test the low-order byte
of a register, clear bits 8-15 and then use the word
form of the instruction.
JNZ/LJNZ source, target

JNZ operates exactly like JZ except that control is
transferred to the target if the source operand does
not contain all O-bits. Word and byte sources may be
tested using these mnemonics:
JNZ/LJNZ
JNZB/LJNZB

Jump/Long Jump if Word Not Zero
Jump/Long Jump if Byte Not Zero

JMCE/LJMCE source, target
CALLILCALL TPsave, target

CALL invokes an out-of-line routine, saving the
value of TP so that the subroutine can transfer back
to the instruction following the CALL. The instruction stores TP and its tag bit in the TPsave operand,
which must be a physical address variable at an even
address, and then transfers to the target address
formed by adding the target operand's displacement
to TP. The subroutine can return to the instruction
following the CALL by using a MOVP instruction to
load TPsave back into TP.

This instruction (jump if masked compare equal) effects a transfer to the target location if the source (a
memory byte) is equal to the lower byte in register
MC as masked by the upper byte in register MC.
Figure 7-15 illustrates how O-bits in the upper halfof
MC cause the corresponding bits in the lower half of
MC and the source operand to compare equal,
regardless of their actual values. For example, if bits
8-15 of MC contain the value OlH, then the transfer
will occur if bit 0 of the source and register MC are
equal. This instruction is useful for testing multiple
bits in 8-bit device registers.
7-32

210911

THE 8089 INPUT/OUTPUT PROCESSOR

JMCNE/LJMCNE source, target

This instruction causes a jump to the target location
if the source is not equal to the mask/compare value
in MC. It otherwise operates identically to JMCE.

ACTIVATE
LOCK

JBT /LBJT source, bit-select, target

1BT Gump if bit true) tests a single bit in the source
operand and jumps to the target if the bit is a 1. The
source must be a byte in memory or in an I/O device
register. The bit-select value may range from 0 - 7,
with 0 specifying the low-order bit. This instruction
may be used to test a bit in an 8-bit device register. If
the target is the JBT instruction itself, the operation
effectively becomes "wait until bit is 0."

FETCH
DESTINATION

DE-ACTIVATE
LOCK

JNBT /LJNBT source, bit-select, target

This instruction operates exactly like JBT, except
that the transfer is made if the bit is not true, i.e., if
the bit is O.

ASSIGN
SET-VALUE TO
DES TINA TlON

Processor Control Instructions
STORE
DESTINA TlON

These instructions enable channel programs to control lOP hardware facilities such as the LOCK and
SINTRI-2 pins, logical bus width selection and the
initiation of a D MA transfer.

DE-ACTIVATE
~

TSL destina tion, set-value, target

Figure 7-26 illustrates the operation of the TSL (test
and set while locked) instruction. TSL can be used
to implement a semaphore variable that controls
access to a shared resource in a multiprocessor
system (see Volume 2). If the target operand specifies the address of the TSL instruction, the instruction is repetitively executed until the semaphore
(destination) is found to contain zero. Thus the
channel program does not proceed until the
resource is free.

NEXT SEQUENTIAL INSTRUCTION

Figure 7-26 Operation of TSL Instruction

WID source-width, dest-width

WID (set logical bus widths) alters bits 0 and I of
the PSW, thus specifying logical bus widths for a
DMA transfer. The operands may be specified as 8
or 16 (bits), with the restriction that the logical
width of a bus cannot exceed its physical width. The
logical bus widths are undefined following a processor RESET; therefore the WID instruction must be
executed before the first transfer. Thereafter the logical widths retain their values until the next WID instruction or processor RESET.

XFER (no operands)

XFER (enter DMA transfer mode after following
instruction) prepares the channel for a DMA transfer
operation. In a synchronized transfer, the instruction
following XFER may ready the synchronizing device
(e.g., send a "start" command or the last of a series
of parameters). Any instruction, including NOP and
WID, may follow XFER, except an instruction that
alters GA, GB or Cc.
7-33

210911

THE 8089 INPUT/OUTPUT PROCESSOR

Instruction Set Reference
Information

SINTR (no operands)
This instruction sets the interrupt service bit in the
PSW and activates the channel's SINTR line if the
interrupt control bit in the PSW is set. If the interrupt
control bit is cleared (interrupts from this channel
are disabled), the interrupt service bit is set, but
SINTRI-2 is not activated. A channel program may
use this instruction to interrupt a CPU.

NOP (no operands)

This instruction consumes clock cycles but performs
no operation. As such, it is useful in timing loops.

HLT (no operands)
This instruction concludes a channel program. The
channel clears its BUSY flag and then idles.

Table 7-12 lists every 8089 instruction alphabetically
by its ASM-89 mnemonic. The ASM-89 coding
format is shown (see Table 7-10 for an explanation
of operand identifiers) along with the instruction
name. For every combination of operand types (see
Table 7-11 for key), the instruction's execution
time, its length in bytes, and a coding example are
provided.
The instruction timing figures are the number of
clock periods required to execute the instruction
with the given combination of operands. At 5 MHz,
one clock period is 200 ns; at 8 MHz a clock period is
125 ns. Two timings are provided when an instruction operates on a memory word. The first (lower)
figure indicates execution time when the word is
aligned on an even address and is accessed over a
16-bit bus. The second figure is for odd-addressed
words on 16-bit buses and any word accessed via an
8-bit bus.

Table 7 -10 Key to ASM-89 Operand Identifiers

EXPLANATION

USED IN

IDENTIFIER

destination

data transfer,
arithmetic,
bit manipulation

A register or memory location that may contain data operated on
by the instruction, and which receives (is replaced by) the result
of the operation.

source

data transfer,
arithmetic,
bit manipulation

A register, memory location, or immediate value that is used in
the operation, but is not altered by the instruction.

target

program transfer

Location to which control is to be transferred.

TPsave

program transfer

A 24-bit memory location where the address of the next sequential instruction is to be saved.

bit-select

bit manipulation

Specification of a bit location within a byte; O=least-significant
(rightmost) bit, 7=most-significant (leftmost) bit.

set-value

TSL

Value to which destination is set if it is found O.

source-width

WID

Logical width of source bus.

dest-width

WID

Logical width of destination bus.

7-34

210911

THE 8089 INPUT/OUTPUT PROCESSOR

7.6 ADDRESSING MODES

Instruction fetch time is shown in Table 7-l3 and
should be added to the execution times shown in
Table 7-12 to determine how long a sequence of instructions will take to run. (Section 7.3 explains the
effect of the instruction queue on 16-bit instruction
fetches.) External delays such as bus arbitration,
wait states and activity on the other channel will increase the elapsed time over the figures shown in
Tables 7-12 and 7-l3. These delays are application
dependent.

8089 instruction operands may reside in registers, in
the instruction itself, or in the system or I/O address
spaces. Operands in the system and I/O spaces may
be either memory locations or I/O device registers
and may be addressed in four different ways. This
section describes how the channel processes different
types of operands and how it calculates addresses
using its addressing modes. Section 7.7 describes the
ASM-89 conventions that programmers use to specify these operands and addressing modes.

Table 7 -11 Key to Operand Types
IDENTIFIER

EXPLANATION

(no operands)

No operands are written

register

Any general register

ptr-reg

A pOinter register

immed8

A constant in the range O-FFH

immed16

A constant in the range O-FFFFH

mem8

An 8-bit memory location (byte)

mem16

A 16-bit memory location (word)

mem24

A 24-bit memory location (physical address pointer)

mem32

A 32-bit memory location (doubleword pointer)

label

A label within -32,768 to +32,767 bytes of the end of the instruction

short-label

A label within -128 to +127 bytes of the end of the instruction

0-7

A constant in the range: 0-7

8/16

The constant 8 or the constant 16

Table 7-12 Instruction Set Reference Data

ADD

destination, source
Operands

register, mem16
mem16, register

Add Word Variable
Clocks

Bytes

11/15
16/26

2-3
2-3

7-35

Coding Example

ADD BC, [GAl. LENGTH
ADD [GB], GC

210911

THE80891NPUT/OUTPUTPROCESSOR

Table 7-1 2 Instruction Set Reference Data (continued)

ADDB

destination, source
Operands

register, mem8
mem8, register

ADDBI

Operands

register, immed16
mem16, immed16

register, mem16
mem16, register

Operands

register, immed8
mem8, immed8

Clocks

Bytes

3
16

3
3-4

register, immed16
mem16, immed16

ADDB GC, [GAj.N_CHARS
ADDB [PPj.ERRORS,MC

Coding Example
ADDBI MC,lO
ADDBI [PP+IX+j,2CH

Add Word Immediate
Clocks

Bytes

3
16/26

4
4-5

Coding Example
ADDI GB,OC25BH
ADDI [GBj.POINTER,5899

Logical AND Word Variable
Clocks

Bytes

11/15
16/2.6

2-3
2-3

Coding Example
AND MC, [GAj.FLAG_WORD
AND [GCj.STATUS, BC

Logical AND Byte Variable
Clocks

Bytes

11
16

2-3
2-3

Coding Example
AND BC, [GCj
AND [GA+IXj, GA

Logical AND Byte Immediate
Clocks

Bytes

3
16

3
3-4

Coding Example
GA,OllOOOOOB
[GC+IX], 2CH

Logical AND Word Immediate

destination, source
Operands

Coding Example

Add Byte Immediate

destination, source
Operands

ANDI

2-3
2-3

destination, source

register, mem8
mem8, register

ANDBI

11
16

destination, source
Operands

ANDB

Bytes

destination, source
Operands

AND

Clocks

destination, source

register, immed8
mem8, immed8

ADDI

Add Byte Variable

Clocks

Bytes

3
16/26

4
4-5
7-36

Coding Example
IX,OH
[GB+IX],40H
210911

THE80891NPUT/OUTPUTPROCESSOR

Table 7 -1 2 Instruction Set Reference Data (continued)

CALL

TPsave, target
Operands

mem24, label

CLR

mem8,0-7

DEC
register
mem16

DECB
mem8

3-5

(no operands)

Clocks

Bytes

16

2-3

register
mem16

Clocks

Bytes

3
16/26

2
2-3

Coding Example
CLR [GAJ,3

Coding Example
DEC [PPj.RETRY

Decrement Byte By 1
Clocks

Bytes

16

2-3

Coding Example
DECB [GA+IX+l

Halt Channel Program
Clocks

Bytes

11

2

Coding Example
HLT

Increment Word by 1
Clocks

Bytes

3
16/26

2
2-3

destination
Operands

CALL [GC+IXj, GET_NEXT

Decrement Word By 1

destination
Operands

Coding Example

Clear Bit To Zero

(no operands)
Operands

mem8

17/23

destination
Operands

INCB

Bytes

destination
Operands

INC

Clocks

destination, bit select
Operands

HLT

Call

Coding Example
INC GA
INC [GAl.COUNT

Increment Byte by 1
Clocks

Bytes

16

2-3

7-37

Coding Example
INCB [GBl.POINTER

210911

THE 80891NPUT/OUTPUT PROCESSOR

Table 7 -1 2 Instruction Set Reference Data (continued)

JBT

source, bit-select, target
Operands

mem8, 0-7, label

JMCE
mem8, label

JMCNE
mem8,Iabei

Operands

3-5

mema, 0-7, label

Clocks

Bytes

14

3-5

register, label
mem16, label

JNZB

Clocks

Bytes

14

3-5

mema, label

Clocks

Bytes

3

3-4

register, label
mem16, label

JMCE [GBl.FLAG, STOP_SEARCH

Coding Example
JMCNE [GB+IX], NEXT_ITEM

Coding Example
JMP READ_SECTOR

Jump If Bit Not True (0)
Clocks

Bytes

14

3-5

Coding Example
JNBT [GCl. 3, RE_READ

Jump if Word Not Zero
Clocks

Bytss

Coding Example

5
12/16

3-4
3-5

JNZ BC, WRITE_LINE
JNZ [PP1.NUM_CHARS, PUT_BYTE

Jump if Byte Not Zero
Clocks

Bytes

12

3-5

source, target
Operands

Coding Example

Jump Unconditionally

source, target
Operands

JBT [GA].RESULLREG, 3, DATA_VALID

Jump if Masked Compare Not Equal

source, target
Operands

Coding Example

Jump if Masked Compare Equal

source, bit-select, target
Operands

JZ

14

target

label

JNZ

Bytes

source, target
Operands

JNBT

Clocks

source, target
Operands

JMP

Jump if Bit True (1)

Coding Example
JNZB [GAl. MORE_DATA

Jump if Word is Zero
Clocks

Bytes

5
12/16

3-4
3-5
7-38

Coding Example
JZ BC, NEXT_LINE
JZ [GC+IXl BUF _EMPTY
210911

THE 8089 INPUT/OUTPUT PROCESSOR

Table 7-12 Instruction Set Reference Data (continued)

JZB

source, target
Operands

mem8, label

LCALL
mem24, label

mem8, 0-7, label

LJMCE
mem8, label

LJMCNE

3-5

mem8, label

label

Bytes

Coding Example

17/23

4-5

LCALL [GCJ.RETURN_SAVE, INIT _8279

Long Jump if Bit True (1)
Clocks

Bytes

14

4-5

mem8, 0-7, label

Clocks

Bytes

14

4-5

Operands

LJBT [GAJ.RESULT,1,DATA_OK

Coding Example

LJMCE (GBl. BYTE_.FOUND

Long jump if Masked Compare Not Equal
Clocks

Bytes

14

4-5

Coding Example

LJMCNE [GC+IX+J, SCAN __ NEXT

Long Jump Unconditional
Clocks

Bytes

3

4

Coding Example

LJMP GET_CURSOR

Long Jump if Bit Not True (0)
Clocks

Bytes

14

4-5

source, target

register, label
mem16, label

Coding Example

Long jump if Masked Compare Equal

source, bit-select, target
Operands

JZB [PPJ.lINES_LEFT, RETURN

Clocks

target
Operands

Coding Example

Long Call

source, target

Operands

LJNZ

12

source, target
Operands

LJNBT

Bytes

source, bit-select, target
Operands

LJMP

Clocks

TPsave, target
Operands

LJBT

Jump if Byte Zero

Coding Example

LJNBT (GC], 6, CRCC_ERROR

Long Jump if Word Not Zero
Clocks

Bytes

5
12/16

4
4-5

7-39

Coding Example

LJNZ BC, PARTIAL_XMIT
LJNZ [GA+IXJ, PUT_DATA

210911

THE 8089 INPUT/OUTPUT PROCESSOR

Table 7 -12 Instruction Set Reference Data (continued)

LJNZe

Operands

mem8, label

LJZ

Long Jump if Byte Not Zero

source, target
Clocks

Bytes

12

4-5

register, label
mem16, label

LJZe

mem8, label

LPD

Clocks

Bytes

5
12/16

4
4-5

source, target
Operands

ptr-reg, mem32

Coding Example

LJZ IX, FIRST _ELEMENT
LJZ [GB].XMIT_COUNT, NO_DATA

Long Jump if Byte Zero
Clocks

Bytes

12

4-5

destination, source
Operands

LJNZB [GB+IX+]., BUMP _COUNT

Long Jump if Word Zero

source, target
Operands

Coding Example

Coding Example

LJZB [GAL RETURN_LINE

Load Pointer With Doubleword Variable
Clocks

BX tes

20/28*

2-3

Coding Example

LPD GA, [PP].BUF _START

*20 clocks if operand is on even address; 28 if on odd address

LPDI

Load Pointer With Doubleword Immediate

destination, source
Operands

ptr-reg, immed32

Clocks

Bytes

6

12/16*

Coding Example

LPDI GB, DISK_ADDRESS

*12 clocks if instruction is on even address; 16 if on odd address

MOV

Operands

register, mem16
mem16, register
mem16, mem16

Move

Move Word

destination, source
Clocks

Bytes

8/12
10/16
18/28

2-3
2-3
4-6

register, mem8
mem8, register
mem8, mem8

MOV IX, [GC]
MOV [GA].COUNT, BC
MOV [GA].READING, [GB]

Move Byte

destination, source
Operands

Coding Example

Clocks

Bytes

8
10
18

2-3
2-3
4-6

7-40

Coding Example

MOVB BC, [PP].TRAN_COUNT
MOVB [PP].RETURN_CODE, GC
MOVB [GB+IX+], [GA+IX+]

210911

THE 8089 INPUT/OUTPUT PROCESSOR

Table 7 -1 2 Instruction Set Reference Data (continued)

MOVBI

Move Byte Immediate

destination, source
Operands

Clocks

Bytes

3
12

3
3-4

register, immed8
mem8, immed8

MOVI

destination, source
Operands

Clocks

Bytes

3
12/18

4
4-5

ptr-reg, mem24
mem24, ptr-reg

Coding Example

MOVI BC,O
MOVI [GBl. OFFFFH

Move Pointer

destination, source
Operands

MOVBI MC, 'A'
MOVBI [PPl.RE5ULT,O

Move Word Immediate

register, immed16
mem16, immed16

MOVP

Coding Example

Clocks

Bytes

19/2716/22-

2-3
2-3

Coding Example

MOVP TP, [GC+IXl
MOVP [GBl.SAVE_ADDR, GC

- First figure is for operand on even address; second is for odd-addressed operand.

NOP

No Operation

(no operands)
Operands

Clocks

Bytes

4

2

(no operands)

NOT

register
mem16
register, mem16

NOTB

Clocks

Bytes

3
16/26
11/15

2
2-3
2-3

Operands

Clocks

Bytes

16
11

2-3
2-3

register, mem16
mem16, register

NOT MC
NOT [GAl.PARM
NOT BC, [GA+IXl

Coding Example

NOTB [GAl.PARM_REG
NOTB IX, [GBl.STATUS

Logical OR Word

destination, source
Operands

Coding Example

Logical NOT Byte

destination/destination, source

mem8
register, mem8

OR

Logical NOT Word

destination / destination, source
Operands

Coding Example

NOP

Clocks

Bytes

11115
16/26

2-3
2-3

7-41

Coding Example

OR MC, [GCl.MASK
OR [GCl, BC

210911

THE 8089 INPUT/OUTPUT PROCESSOR

Table 7 -1 2 Instruction Set Reference Data (continued)

ORB

Operands
register, mem8
mem8, register

ORBI

register, immed8
.mem8, immed8

ORI

Bytes

11
16

2-3
2-3

register, immed16
mem16,immed16

SETB

Clocks

Bytes

3
16

3
3-4

mem8,0-7

SINTR

Clocks

Bytes

3
16126

4
4-5

(no operands)

Bytes

16

2-3

Operands

*14 clocks if destination

WID

Clocks

Bytes

4

2

Clocks

Bytes

14/16*

4-5

Operands

=

SETB [GA].PARM_REG,2

Coding Example
SINTR

Coding Example
TSL [GA].FLAG, OFFH, NOT __ READY

0

Clocks

Bytes

4

2

Coding Example
WID 8,8

Enter DMA Transfer Mode After Next Instruction

(no operands)

(no operands)

Coding Example

Set Logical Bus Widths

source-width, dest-width

8/16,8116

ORI MC,OFFODH
ORI [GAl, 1000H

Test and SetWhile Locked

* 0; 16 clocks if destination

Operands

Coding Example

Set Interrupt Service Bit

destination, set-value, target

mem8, immed8, short-label

Coding Example
ORBI IX, 00010001 B
ORBI [GB].COMMAND,OCH

Set Bit to 1
Clocks

(no operands)
Operands

ORB IX, [PP].POINTER
ORB [GA+IX+l, GB

Logical OR Word Immediate

destination, bit-select
Operands

Coding Example

Logical OR Byte Immediate

destination, source
Operands

XFER

Clocks

destination, source
Operands

TSl

Logical OR Byte

destination, source

Clocks

Bytes

4

2

7-42

Coding Example
XFER

210911

THE 80891NPUT/OUTPUT PROCESSOR

operand's address be calculated in any of four different ways; these are the 8089's memory addressing
modes.

Table 7 -13 Instruction Fetch Timings
(Clock Periods)

INSTRUCTION
LENGTH
(BYTES)

2
3

4
5

BUSWIDTH

Effective Address

16

8

14
18
22
26

(1 )

(2)

7

11
11
15
15

14
14
18

An operand in the system space has 20-bit effective
address, and an operand in the I/O space has a 16-bit
effective address. These addresses are unsigned
numbers that represent the distance (in bytes) of the
low-order byte of the operand from the beginning of
the address space. Since the 8089 does not "see" the
segmented structure of the system space that it may
share with an 8086,88 or an 80186,188, the 8089 effective addresses are equivalent to 8086,88/80186,188 physical addresses.

Register and Immediate Operands

All memory addressing modes use the content of
one of the pointer registers, and the state of that
register's tag bit determines whether the operand
lies in the system or the 110 space. If the operand is
in the I/O space (tag= 1), bits 16-19 of the pointer
register are ignored in the effective address
calculation. Volume 2 describes the two fields (AA
and MM) in the encoded machine instruction that
specify the addressing mode and base (pointer)
register.

Registers may be specified as source or destination
operands in many instructions. Instructions that
operate on registers are generally both shorter and
faster than instructions that specify immediate or
memory operands.
Immediate operands are data contained in instructions rather than in registers or in memory. The data
may be either 8 or 16 bits in length. The limitations
of immediate operands are that they may only serve
as source operands and that they are constant values.

Base AddreSSing
Memory Addressing Modes
In based addressing (Figure 7-27), the effective address is taken directly from the contents of GA, GB,
GC or PP. Using this addressing mode, one instruction may access different locations if the register is
updated before the instruction executes. LPD,
MOV, MOVP or arithmetic instructions might be
used to change the value of the base register.

Whereas the channel has direct access to register
and immediate operands, operands in the system
and I/O space must be transferred to or from the
lOP over the bus. To do this, the lOP must calculate
the address of the operand, called its effective address (EA). The programmer may specify that an

rOO
R/B/P WB AA W

OPCODE

MM

MACHINE INSTRUCTION FORMAT

GA
OR

GB
OR

EA

GC
OR

PP

Figure 7-27 Based Addressing
7-43

210911

THE 80891NPUT/OUTPUT PROCESSOR

example of a structure). As shown in Figure 7-29, a
base register can be pointed at the base (first
element) in the structure, and then different offsets
can be used to access the elements within the
structure. By changing the base address, the same
structure can be relocated elsewhere in memory.

Offset Addressing
In this mode (Figure 7-28), an 8-bit unsigned value
contained in the instruction is added to the contents
of a base register to form the effective address. The
offset mode provides a convenient way to address
elements in structures (a parameter block is a typical

MACHINE INSTRUCTION FORMAT

MM

GA
OR

GB
OR

--+---"+

GC
OR

PP

Figure 7·28 Offset Addressing

,
HIGH ADDRESSES
,.....---~+

6

ERROR I LINECT

+4

BUFF _PTR

+ 2 POSITIONICURSOR

rI
I
I
I

----r--o-l

r - ... + 0

END_BUS

I

I
I
I
I
I
EA
I
I
I
L _______________

LOW ADDRESSES
f.,

~

Figure 7·29 Accessing a Structure with Offset Addressing

7-44

210911

THE 80891NPUT/OUTPUT PROCESSOR

Indexed Addressing

(see Figure 7-3 I). A base register locates the beginning of the array and the value in IX selects one
element, i.e., it acts as the array subscript. The ith
element of a byte array is selected when IX contains
(i - 1). To access the ith element of a word array. IX
should contain (ith -1)*2).

An indexed address is formed by adding the contents
of register IX (interpreted as an unsigned quantity)
to a base register as shown in Figure 7-30. Indexed
addressing is often used to access array elements

R/B/P WB AA W

OPCODE

MM

MACHINE INSTRUCTION FORMAT

GA
OR

GB

+

OR

GC

-i

IX

OR

PP

Figure 7 -30 Indexed Addressing

'r

IX

I

HIGH ADDRESSES

r

ARRAY (9)
ARRAY (8)
ARRAY (7)

I

r
I
I
I
I
I
I
I
I
I
I
I

ARRAY (6)
ARRAY (5)

EA

I

ARRAY (4)

~

ARRAY (3)
ARRAY (2)
ARRAY (1)

------

ARRAY (0)

!-1WORD_
h

LOW ADDRESSES

"

Figure 7-31 Accessing a Word Array with Indexed Addressing
7-45

210911

THE 8089 INPUT/OUTPUT PROCESSOR

LIB-86, LINK-86, LOC-86 and OH-86, described in
Section 2-9. All of these development tools run on
an INTELLEC R 800 or Series II and III microcomputer development system.

Indexed Auto-Increment Addressing
In this variation of indexed addressing, the effective
address is formed by summing IX and a base
register; IX is then incremented automatically. (See
Figure 7-32.) The incrementing takes place after the
EA is calculated. IX is incrementeq by 1 for a byte
operation, by 2 for a word operation, by 3 for a
MOVP instruction, and by 4 for a LPD instruction.
This addressing mode is very useful for "stepping
through" successive elements of an array (e.g., a
program loop that sums an array).

This section surveys the facilities of the ASM -89 assembler and discusses how LINK-86 and LOC-86
can be used in 8089 software development. For a
complete description of the 8089 assembly language,
consult 8089 Macro Assembly User's Guide, Order
No. 9800938, available from Intel's Literature
Department.

7.7 PROGRAMMING FACILITIES

ASM-89

The compatibility of the 8089 with the 8086,88 and
80186,188 extends beyond the hardware interface.
Comparing Figure 7-33 with Figure 2-45, one can
see that, except for the translate step, the software
development process is identical for both 8086/8088
and 8089 programs. The ASM-89 assembler produces a relocatable object module that is compatible
with the 8086 family software development utilities

The ASM-89 assembler reads a disk file containing
8089 assembly language statements, translates these
statements into 8089 machine instructions, and
writes the result into a second disk file. The assembly
input is called a source module, and the principal
output is a relocatable object module. The assembler
also produces a file that lists the module and flags
any errors detected during the assembly.

r
IR/B/P WB AA

11

wi

OPCODE

MM

J

MACHINE INSTRUCTION FORMAT

GA

f--

OR

-

GB
OR

GC

f--

OR

-

pp

I

I

IX

•

I

I

I

EA

I

I
I
I
I
I

I
IX

1.-0~

DELTA

I

Figure 7-32 Indexed Auto-Increment Addressing

7-46

210911

THE80891NPUT/OUTPUTPROCESSOR

(FROM PL/M·ae' ASM4e TRANSLATORS)

UPDATE
LIBRARIES

Figure 7-33 8089 Software Development Process

Statements

characters may separate fields and multiple identifiers within the operand field. Long statements may
be continued onto the next link by coding an ampersand (&) as the first character of the continued line.

Statements are the building blocks of ASM-89
programs. Figure 7-34 shows several examples of
ASM-89 statements. The ASM-89 assembler gives
programmers considerable flexibility in formatting
program statements. Variable names and labels
(identifiers) may be up to 31 characters long, and
the underscore C) character may be used to improve
the readability of longer names (e.g.,
WAIT_UNTIL_READY). The component parts of
statements (fields) need not be located at particular
"columns" of the statement. Any number of blank

A statement whose first non-blank character is a
semicolon is a comment statement. Comments have
no affect on program execution and, in fact, are
ignored by the ASM-89 assembler. Nevertheless,
carefully selected comments are included in all well
written ASM-89 programs. They summarize, annotate and clarify the logic of the program where the
instructions are too "microscopic" to make the operation of the program self-evident.

An ASM-89 instruction statement (Figure 7-35)
directs the assembler to build an 8089 machine
instruction. The optional label field assigns a symbolic identifier to the address where the instruction will
be stored in memory. A labeled instruction can be
the target of a program transfer; the transferring instruction specifies the label for its target operand. In
Figure 3-35, the labeled instruction conditionally
transfers to itself; the program will loop on this one
instruction as long as bit 3 of the byte addressed by
[GAl.STATUS is not true. The mnemonic field of
an instruction statement specifies the type of 8089
machine instruction that the assembler is to build.

; THIS STATEMENT CONTAINS A COMMENT FIELD ONLY
ADDI BC.5
; TYPICAL ASM89 INSTRUCTION
ADDI
BC,
5
; NO "COLUMN" REQUIREMENTS
MOV
[GAI.STATUS,
&
6
; A CONTINUED STATEMENT
SOURCE
EQU GA
; A SIMPLE ASM89 DIRECTIVE
LINE_BUFFER __ ADDRESS DO ; A LONG IDENTIFIER

Figure 7-34 ASM-89 Statements

7-47

210911

THE 80891NPUT/OUTPUT PROCESSOR

The operand field may contain no operands or one
or more operands as required by the instruction.
Multiple operands are separated by commas and,
optionally, by blanks. Any instruction statement
may contain a comment field (comment fields are
initiated by a semicolon).

assembler accepts 14 directives; the more commonly
used directives are discussed in this section.
The first field in a directive may be a label or a
name; individual directives may require or prohibit
names, while labels are optional for directives that
accept them. A label ends in a colon like an instruction statement label. However, a directive label
cannot be specified as the target of a program
transfer. A name does not have a colon. The second
field is the directive mnemonic, and the assembler
distinguishes between instructions and directives by
this field. Any operands required by the directive are
written next; multiple operands are separated by
commas and, optionally, by blanks. A comment
may be included in any directive by beginning the
text with a semicolon.

An ASM-89 directive statement (Figure 7-36) does
not produce an 8089 machine instruction. Rather, a
directive gives the assembler information to use
during the assembly. For example, the OS (define
storage) directive in Figure 7-36 tells the assembler
to reserve 80 bytes of storage and to assign a symbolic identifier (INPUT _BUFFER) to the first
(lowest-addressed) byte of this area. The ASM-89

II DEMO: I I

JNBT

I

IIGAI.STArs.,.o,.a l

I

;WAIT UNTIL READY

I

[ CaMM'NTlaPTlaNAll
OPERANDS (REQUIRED/PROHIBITED)
MNEMONIC (REQUIRED)
LABEL (OPTIONAL)

Figure 7-35 ASM-89 Instruction Format

• INPUT_BUFFER: I

80

T

I ;TERMINAL LINE STORED HEREJ

L

COMMENT (OPTIONAL)

' - - - - - - - - - OPERANDS (REQUIRED/PROHIBITED)
MNEMONIC (REQUIRED)

L...._ _ _ _ _ _ _ _ _ _ _ _ _ _ _

LABEL/NAME (REQUIRED/PROHIBITED)

Figure 7-36 ASM-89 Directive Format
7-48

210911

THE 8089 INPUT/OUTPUT PROCESSOR

item). For example, a character string constant
could be defined as a byte array:

Constants
Binary, decimal, octal and hexadecimal numeric constants (Figure 7-37) may be written in ASM-89 instructions and directives. The assembler can add and
subtract constants at assembly time. Numeric
constants, including the results of arithmetic
operations, must be representable in 16 bits. Positive
numbers cannot exceed 65,535 (decimal); negative
numbers, which the assembler represents in two's
complement notation, cannot be "more negative"
than - 32,768 (decimal).
Character constants are enclosed in single quote
marks as shown in Figure 7-37. Strings of characters
up to 255 bytes long may be written when initializing
storage. Instruction operands, however, can only be
one or two characters long (for byte and word instructions respectively).
As an aid to program clarity, the EQU (equate)
directive may be used to give names to constants
(e.g., DISK-STATUS EQU OFF20H).

Defining Data
Four ASM-89 directives reserve space for memory
variables in the ASM-89 program (see Figure 7-38).
The DB, DW and DD directives allocate units of
bytes, words and doublewords, respectively, initialize the locations, and optionally label them so that
they may be referred to by name in instruction
statements. The label of a storage directive always
refers to the first (lowest-addressed) byte of the area
reserved by the directive.
The DB and DW directives may be used to define
byte- and word-constant scalars (individual data
items) and arrays (sequences of the same type of

SIGN_ON..MSG: DB 'PLEASE ENTER PASSWORD'

The DD directive is typically used to define the address of a location in the system space, i.e., a doubleword pointer variable. The address may be loaded
into a pointer register with the LPD instruction.
The DS directive reserves, and optionally names,
storage in units of bytes, but does not initialize any
of the reserved bytes. DS is typically used for RAMbased variables such as buffers. As there is no special
directive for defining a physical address pointer, DS
is typically used to reserve the three bytes used by
the MOVP instruction.

Structures
An ASM-89 structure is a map or template that gives
names and relative locations to a collection of related
variables that are called structure elements or
members. Defining a structure, however, does not
allocate storage. The structure is, in effect, overlaid
on a particular area of memory when one of its elements is used as an instruction operand. Figure 7 -39
shows how a structure representing a parameter
block could be defined and then used in a channel
program. The assembler uses the structure element
name to produce an offset value (structures are used
with the offset addressing mode). Compared to
"hard coded" offsets, structures improve program
clarity and simplify maintenance. If the layout of a
memory block changes, only the structure definition
must be modified. When the program is
reassembled, all symbolic references to the structure
are automatically adjusted. When multiple areas of
memory are laid out identically, a single structure
can be used to address any area by changing the contents of the pointer (base) register that specifies the
structure's "starting address."

MOVBI
GA 'A'
; CHARACTER
MOVBI
GA: 41 H
; HEXADECIMAL
GA,65
; DECIMAL
MOVBI
MOVBI
GA,65D
; DECIMAL ALTERNATIVE
; OCTAL
MOVBI
GA,101Q
MOVBI
GA,1010
; OCTAL ALTERNATIVE
GA, 01000001 B ; BINARY
MOVBI
; NEXT TWO STATEMENTS ARE EQUIVALENT AND
ILLUSTRATE TWO'S COMPLEMENT REPRESENTATION
,
OF NEGATIVE NUMBERS
MOVBI
GA,-5
MOVBI
GA, 11111011 B

Figure 7-37 ASM-89 Constants
7-49

210911

THE80891NPUT/OUTPUTPROCESSOR

; ASM89 DIRECTIVE
; MEMORY CONTENT (HEX)
ALPHA: DB
1
i; 01
-2
DB
; FE (TWO'S COMPLEMENT)
DB
'A', '8'
; 4142
BETA:
OW
1
; 0100
-5
OW
; FAFF
OW
'AB'
; 4241
OW
400,500
I; 2410F401
OW
400H,500H ; 00040005
gamma: OW
BETA
; OFFSET OF BETA ABOVE,
; FROM BEGINNING OF PROGRAM
DELTA
DO
GAMMA
; ADDRESS (SEGMENT & OFFSET)
;OFGAMMA
ZETA:
OS
80
; 80 BYTES, UNINITIALIZED

Figure 7-38 ASM-89 Storage Directives

MEMORY MAP

OFFSETS,

+10

+8

,

HIGHER ADDRESSES

PARM_BLOCK
TP _RESERVED:
COMMAND:
RESULT:
BUFFER __ START:
BUFFER_LEN:
PARM_BLOCK

BUFFER,_START

+6

+4

STRUCTURE DEFINITION

BUFFER_LEN

COMMAND

I

RESULT

STRUC
OS
4
OS
1
OS
1
OS
4
OS
2
ENDS

+2
TP _RESERVED

LOWER ADDRESSES

h

USING "HARD-CODED" OFFSETS

USING STRUCTURE ELEMENT NAMES

LPD GA, [PPJ.6
MOVBI [PPj,5,O

LPD GA, [PPJ,BUFFER __ START
MOVBI [PPJ.RESULT,O

Figure 7-39 ASM-89 Structure Definition and Use

7-50

210911

I

THE 8089 INPUT/OUTPUT PROCESSOR

•

Addressing Modes
Table 7-14 summarizes the notation a programmer
uses to specify how the effective address of a
memory operand is to be computed. Examples of
typical ASM-89 coding for each addressing mode, as
well as register and immediate operands, are provided in Figure 7-40. Notice that a bracketed reference
to a register indicates that the contents of the register
is to be used to form the effective address of a
memory operand, while an unbracketed register
reference specifies that the register itself is the
operand.

Table 7-14 ASM-89 Memory
Addressing Mode Notation
Notation

ptr-reg
offset

Based
Offset
Indexed
Indexed Post Auto-increment

GA, GB, GC or PP
8-bit signed value; may be structure element

If GA contains the address of a memory
operand, then [GA] refers to that operand.

ADD I
ADD
ADDBI
ADDB
ADDB
ADD
ADDI
ADDB

If G A contains the starting address of an
array, then [GA + IX] addresses the array
element indexed by IX. For example, if IX
contains the value 4H, the effective address
refers to the fifth element of a byte array, or
the third element of a word array. [GA + IX
+ ] selects the same elements and additionally
auto-increments IX by I (byte operation), 2
(word operation), 3 (MOVP instruction), or
4 (LPD instruction) in anticipation of accessing the next array element.

Program Transfer Targets

The following examples summarize how the
memory addressing modes can be used to access
simple variables, structures and arrays.
•

If G A contains the base address of a
structure, then [GAl.DATA refers to the
DATA element (field) in that structure. If
DATA is six bytes from the beginning of the
structure, thel) [GA].6 refers to the same
location.

Note that any pointer register could have been substituted for GA in the previous examples.

Addressing Mode

[ptr-reg)
[ptr-reg ).offset
[ptr-reg + IX).
[ptr-reg + IX +)

•

' I:

As discussed in Section 7.5, program transfer instructions operate by adding a signed byte or word
displacement to the task pointer. Table 7-15 shows
how the ASM-89 assembler determines the sign and
size of the displacement value it places in a program
transfer machine instruction. In the table, the terms
"backward" and "forward" refer to the location of a
label specified as a transfer target relative to the
transfer instruction. "Backward" means the label
physically precedes the instruction in the source
module, and "forward" means the label follows the
instruction in the source text. The distances are
from the end of the transfer instruction; the distance
to the instruction immediately following the transfer
is 0 bytes.

GA,5
GC, [GB]
[PP],10
IX, [GB].5

; REGISTER, IMMEDIATE
; REGISTER, MEMORY (BASED)
; MEMORY (BASED), IMMEDIATE
; REGISTER, MEMORY (OFFSET)
BC, [GC].COUNT ; REGISTER, MEMORY (OFFSET)
[GC+ IX], BC
; MEMORY (INDEXED), REGISTER
[GA+ IX+],5
; MEMORY (INDEXED AUTO-INCREMENT), IMMED
[PP].ERROR, [GAJ ; MEMORY (OFFSET), MEMORY (BASED)

Figure 7-40 ASM-89 Operand Coding Examples

7-51

210911

I
'~

THE 80891NPUT/OUTPUT PROCESSOR

Table 7 -15 Program Transfer Displacement
Target Location
Mnemonic
Form

Direction

Distance

Short
(e.g., JMP)

Backward
Forward
Backward
Forward
Backward
Forward

'128
'127
'32,768
'32,767
>32,768
>32,767

Long
(e.g., LJMP)

Backward
Forward
Backward
Forward
Backward
Forward

'128
'127
'32,768
'32,767
>32,768
>32,767

Two important points can be drawn from Table 7-15.
First, a target must lie within 32K bytes of a transfer
instruction; this should not prove restrictive except
in very large programs. Second, one byte can be
saved in the assembled instruction by writing the
short mnemonic when the target is known to be
within -128 through + 127 assembled bytes of the
transfer.

'Dlsplacement
Sign Bytes

+

-

1
1
2

Error
Error
Error

+

-

+

2
2
2
2

Error
Error

As in any program transfer, the target of a
CALLILCALL instruction must be contained in the
same module and within 32K bytes of the
instruction.

Segment Control
The relocatable object module produced by the
ASM-89 assembler consists of a single logical
segment. (A segment is a storage unit up to 64K
bytes long; for a more complete description, refer to
Sections 3.4 and 3.7). The ASM-89 SEGMENT and
ENDS directives name the segment as shown in
Figure 7-42. Typically, all instructions and most
directives are coded in between these directives. The
END directive, which terminates the assembly, is an
exception.

It is also important to note that a program transfer

target must reside in the same module as the transferring instruction, i.e., the target address must be
known at assembly time.

Procedures
An ASM-89 program may invoke an out-of-line
procedure (subroutine) with the CALLILCALL
instruction. The first instruction operand specifies a
memory location where the contents of TP will be
stored as a physical address pointer before control is
transferred to the procedure. The procedure may
return to the instruction following the CALL/LCALL by using the MOVP instruction to restore
TP from the save area. Figure 7-41 illustrates one approach to procedure linkage.
A channel program may use the first two words of
its parameter block (pointed to by PP) as a task
pointer save area. However, this is not recommended if there is any chance that the CPU will issue a
"suspend" command to the channel; this command
stores the current value of TP in the same location,
possibly overwriting a return address.

The LOC-86 utility can assign this logical segment to
any memory address that is a physical segment boundary (i.e., whose low-order four bits are DODO). In a
ROM-based system, variable data (which must be in
RAM) can be "clustered" together at one "end" of
the program as shown in Figure 7-43. The ORG
directive can then be used to force assembly of the
variables to start at a given offset from the beginning
of the segment (2,000 hexadecimal bytes in Figure
7-43), As the figure shows, the segment can then be
located so that instructions and constants fall into
the ROM portion of memory, while the variable part
of the segment is located in RAM. The entire
segment, including any "unused" portions, of
course, cannot exceed 64K bytes,

7-52

210911

THEBOB91NPUT/OUTPUTPROCESSOR

I
I

CALL SAVE:

DS

3

; TP SAVE AREA

; SET UP TP SAVE AREA
NOTE:EXAMPLEASSUMESPROGRAM
;
;
IS IN 1/0 SPACE. USE LPDI
;
IF IN SYSTEM SPACE.
;
MOVI GC, CALLSAVE
; LOAD ADDRESS TO GC
; CALL IT.
LCALL [GC),DEMO

HLT

; LOGICAL END OF PROGRAM

; DEFINE THE PROCEDURE.
DEMO:
; PROCEDURE INSTRUCTIONS GO HERE.
; NOTE: PROCEDURE MUST NOT UPDATE GC
;
AS IT POINTS TO THE RETURN ADDRESS.

; RETURN TO CALLER.
MOVP TP, [GC]

Figure 7-41 ASM-89 Procedure Example

CHANNEL1

SEGMENT

; START OF SEGMENT

ASM89 SOURCE STATEMENTS

CHANNEL1

ENDS
END

; END OF SEGMENT
; END OF ASSEMBLY

Figure 7-42 ASM-89 SEGMENT and ENDS Directives

7-53

210911

THE80891NPUT/OUTPUTPROCESSOR

DEMO: SEGMENT
;CONSTANT DATA
HIGHER ADDRESSES

"

;INSTRUCTIONS

(AVAILABL E)

'~

,--------

t

VARIABLES
2000..:..:H~t-_ _ _ _ _ _""'_ RAM

ORG 2000H
;VARIABLE DATA

(UNUSED)
~~-----­
INSTRUCTIONS

DEMO ENDS
END

ROM

f-------CONSTANTS

~6~2T~~GHr.::~~T _1000H _ _ _ _ _ _ _ _
(AVAILABLE)

LOWER ADDRESSES

Figure 7-43 Using the ASM-89 ORG Directive

Intermodule Communication
An ASM-89 module can make some of its addresses
available to other modules by defining symbols with
the PUBLIC directive. At a minimum, a channel
program must make the address of its first instruction available to the CPU module that starts the
channel program. Figure 7-44 shows an ASM-89
module that contains three channel programs
labeled READ, WRITE and DELETE. The example
shows how a PLlM-86 program and an ASM-86 program could define these "entry points" as EXTERNAL and EXTRN symbols respectively. When the
modules are linked together, LINK-86 will match
the externals with the publics, thus providing the
CPU programs with the addresses they need.
Conversely, an ASM-89 module can obtain the address of a public symbol in another module by defining it with the EXTRN directive. An external
symbol, however, can only appear as the initial
value operand of a DD directive (see Figure 7-45).
This effectively means that an ASM-89 program's
use of external symbols is limited to obtaining the
addresses of data located in the system space. Another way of doing this, which may be preferable in
many cases, is to have the CPU program system
space addresses in the parameter block.

Sample Program
Figure 7-46 diagrams the logic of a sample ASM-89

program; the code is shown in Figure 7-47. The program reads one physical record (sector) from a diskette drive controlled by an 8272 Floppy Disk
Controller. No particular system configuration is implied by the program, except that the 8272 resides in
the IOP's I/O space.
Hardware address decoding logic is assumed to be
set up as follows:
•

reading location FFOOH selects the 8272
status register,

•

writing location FFOOH selects the 8272 command register,

•

reading location FFOIH selects the 8272
result register,

•

writing location FFOIH selects the 8272
parameter register,

•

decoding the address FF04H provides the
8272 DACK (DMA acknowledge) signal.

The program uses structures to address the parameter block and the 8272 registers. Register PP contains
the address of the parameter block, and the program
loads GC with FFOOH to point to the 8272 registers.
The program's entry point (the label START) is
defined as a PUBLIC symbol so that the CPU program can place its address in the parameter block
when it starts the program.
7-54

210911

THE 8089 INPUT/OUTPUT PROCESSOR

,
I

Register IX is used as a retry counter. If the transfer
is not completed successfully (bit 3 of the 8272 result
register ~ 0), the program retries the transfer up to
10 times.
Since the 8272 automatically requests a DMA transfer upon receipt of the last parameter, this parameter
is sent immediately following the XFER command.

Linking and Locating ASM-89
Modules
The LINK-86 utility program combines multiple
relocatable object modules into a single relocatable
module. The input modules may consist of modules
produced by any of the iAPX 86,88/186,188 family
language translators; ASM-89, ASM-86, PLlM-86,
PASCAL-86 or FORTRAN-86. LINK-86's principal
function is to satisfy external references made in the
modules. Any symbol that is defined with the
EXTRN directive in ASM-89 or ASM-86 or is declared EXTERNAL in PLlM-86 is an external
reference, i.e., a reference to an address contained

in another module. Whenever LINK-86 encounters
an external reference, it searches the other modules
for a PUBLIC symbol of the same name. If it finds
the matching symbol, it replaces the external reference with the address of the object.
The most common occurrence of an external reference in a system that employs one or more 8089s is
the channel program address. In order for a CPU
program to start a channel program, it must ensure
that the address of the first channel program instruction is contained in the first two words of the
parameter block. Since the channel program is assembled separately, the translator that processes the
CPU program will not typically know its address. If
this address is defined as an external (see Figure
7-44), LINK-86 will obtain the address from the
ASM-89 channel program when the two are linked
together. (The ASM-89 program must, of course,
define the symbol in a PUBLIC directive.)
Other external references may arise when one
module uses data (e.g., a buffer) that is contained in
another module, and (in PLlM-86 and ASM-86
modules) when one module executes another
module, typically by a CALL statement or
instruction.

ASM-89 MODULE DEFINES THREE PUBLIC SYMBOLS

PUBLIC

READ, WRITE, DELETE

READ:

; ASM89 INSTRUCTIONS FOR "READ" OPERATION

WRITE:

HLT
; ASM89 INSTRUCTIONS FOR "WRITE" OPERATION

DELETE:

HLT
; ASM89 INSTRUCTIONS FOR "DELETE" OPERATION
HLT

Figure 7-44 ASM-89 PUBLIC Directive

7-55

210911

:~

:1
I'

I

JI

THE 80891NPUT/OUTPUT PROCESSOR

PLlM-86 MODULE USES "WRITE" SYMBOL
DECLARE
DECLARE

(READ,WRITE,DELETE) POINTER EXTERNAL;
PARM$BLOCK STRUCTURE
(TP$START
POINTER,
BUFFER$ADDR
POINTER,
BUFFER$LEN
WORD);

"SET UP "WRITE" CHANNEL OPERATION"
PARM$BLOCK. TP$START = WRITE;

MODULE USES "READ" SYMBOL

ASM-86

EXTRN

READ,WRITE,DELETE

READ_PTR
WRITE_PTR
DELETE_PTR

DD
DD
DD

READ
WRITE
DELETE

; PARM_BLOCK
EVEN
TP _START
DD ?
BUFFER_ADDRDD ?
BUFFER_LEN DW?

; FORCE TO EVEN ADDRESS

; SET UP "READ" CHANNEL OPERATION
MOV AX, WORD PTR READ_PTR
MOV WORD PTRTP _START, AX
MOV AX, WORD PTR READ_PTR
MOV WORD PTR TP _START + 2, AX

; 1ST WORD
; 2ND WORD

Figure 7-44 ASM-89 PUBLIC Directive (continued)

7-56

210911

THE 8089 INPUT/OUTPUT PROCESSOR

The normal link and locate sequence is followed and
culminates in the production of an absolute module
in hexadecimal format. Since the records in this file
are human-readable, the file can be edited using the
ISIS-II text editor. The editing task involves finding
the 8089 I/O space records in the file, writing them
to one file, and then writing the 8086,88/80186,188
records (destined for the system space) to another
file. MCS-86 ABSOLUTE OBJECT FILE FORMATS, Order No. 9800921, available from Intel's
Literature Department, describes the records in absolute (including hexadecimal) object modules.

When an 8089 module (or modules) is to be located
in the system space, it may be linked together with
PLlM-86 or ASM-86 modules as described above
and shown in Figure 7-48. LINK-86 resolves external references and combines the input modules into
a single ~locatable object module. This module can
be input to- LOC-86 (LOC-86 assigns final absolute
memory addresses to all of the instructions and
data). This absolute object module may, in turn, be
processed by the OH-86 utility to translate the
module into the hexadecimal format. This format
makes the module readable (the records are written
in ASCII characters) and is required by some PROM
programmers and RAM loaders. Intel's Universal
PROM Programmer (UPP) and iSBC 957TM Execution Package (loader) use the hexadecimal format.

When using the previous method, it is likely that
LOC-86 will issue messages warning that segments
overlap. For example, the 8089 code would typically
be located starting at absolute location OH of the 1/0
space. However, the 8086,881186,188 interrupt
pointer table occupies these low memory addresses
in the system space. Since LOC-86 has no way to
know that the segment will ultimately be located in
different address spaces, it wi\l warn of the conflict;
the warning may be ignored.

If the 8089 code is to reside in its I/O space, a different technique is required since separate absolute
object modules must be produced for the system
and I/O spaces. Figure 7-49 shows how to link and
locate when there are external references between
I/O space modules and system space modules.

PLlM-86 PROGRAM DECLARES PUBLIC SYMBOL "BUFFER"

DECLARE BUFFER (80) BYTE PUBLIC;

ASM-89 PROGRAM OBTAINS ADDRESS OF PUBLIC SYMBOL "BUFFER"

EXTRN BU FFER

BUF _ADDRESS

LPD

DD

BUFFER

GA, BUF _ADDRESS

; POINT TO SYSTEM BUFFER

Figure 7·45 ASM·89 EXTRN Directive

7-57

210911

THE SOS91NPUT/OUTPUT PROCESSOR

may also be altered as system development proceeds
without relinking the channel programs.
External references from system space modules to
addresses in the 110 space may be eliminated by assigning the addresses values that are known at assembly or compilation time. Figure 7-51 illustrates
how the ASM-89 ORG directive can be used to force
the first instruction (entry point) of a channel program to an absolute address. In the case of the
example, one module contains two entry points
labeled "READ" and "WRITE." Assuming the
module is located at absolute address OH in the 110
space, the channel programs will begin at 200H and
600H respectively. In the example, these values
have been chosen arbitrarily; in a typical application
they would be based on the length of the programs
and the location of RAM and ROM areas. By starting
the programs at fixed addresses that are known to
the CPU programs that activate them, the channel
programs can be reassembled without needing to
relink the CPU programs.

7.S PROGRAMMING CONSIDERATIONS
This section provides two types of 8089 programming information. A series of general guidelines,
which apply to system and program design, is presented first. These guidelines are followed by specific
coding examples that illustrate programming techniques that may be applied to many different types
of applications.

Figure 7-46 ASM-89 Sample Program Flow

An alternative to linking the modules together and
then separating them is to link system space
modules separately from 110 space modules as
shown in Figure 7-50. This approach avoids the
manual edit of the absolute object module and the
segment conflict messages from LOC-86. It
requires, however, that modules in the two spaces
not use the EXTRN/PUBLIC mechanism to refer to
each other. Modules in the same space can define external and public symbols, however.
External references from 110 space modules to
system space modules can be eliminated if the CPU
programs pass all system space addresses in parameter blocks. In other words, a channel program can
obtain any address in the system space if the address
is in the parameter block. Using this approach allows
the system space addresses to be changed during
execution. If the addresses are constant values, they

Programming Guidelines
The practices in this section are recommended to
simplify system development and, particularly, for
system maintenance and enhancement. Software
that is designed in accordance with these guidelines
will be adaptable to the changing environment in
which most systems operate, and will be in the best
position to take advantage of new Intel hardware
and software products.

Segments
Although the lOP does not "see" the segmented organization of system memory, it should respect this
logical structure. The lOP should only address the
system space through pointers passed by the CPU in
the parameter block. It should not perform arithmetic on these addresses or otherwise manipulate them
except for the automatic incrementing that occurs
during DMA transfers. It is the responsibility of the
CPU to pass addresses such that transfer operations
do not cross segment boundaries.
7-58

210911

:1

THE 8089 INPUT/OUTPUTPROCESSOR

'\

,~

·I~'

!,
I

8089 ASSEMbLeR

1

ISIS-II 8089 ASS~MBLt:H Vl.0 ASSEMBLY OF MUUULE
OBJECT MODULE PLACED IN :FO:FLOPPY.OBJ
ASSEMBLER INVOKED BY ASM89 FLOPPY.A89

SEGMENT

2 FLOPPY

0000

~LUPPY

3 ; ** *

4 ;'u 8089 PROGRAM TO READ SECTOR FROM FLOPPY DISK

5 i***

6
7 ;'"

LAY OUT PARAMETER BLOCK.
STRUC
OS
DS
OS
DS
OS
ENDS

8 PARM BLOCK

0000
0004
0008
0009
OOOA
0008

9

0000
0001
0002
HOD

FF04

0000

OA4F OA 00

0004

B130 DADO

0008

5130 DOFF

OOOC

EABA 00 FC

0010

OA4E 00 12

0014

0293 08 02CE 01

001A

u130 2088

001E

AOOO

0020

238B 04

RESERVED TP:
BUFF PTR:
THACK:
SECTOR:
RETURN CODE:
PARM SLOCK

10
11
12
13
14
15
16 ;"'LAY OUT 8271 DEVICE REGISTERS.
STRUC
17 FLO PPY REGS
COMMAND STAT:
OS
18
PARM RESULT:
DS
19
ENDS
20
FLO PPY REGS
21
22 ;"'8271 ADDRESSES.
OFF DOH
;LOW-ADDRESSED REGISTER
23 FLOPPY REG ADDR EQU
24 DACK 8271
EQU
OFF04H
; DMA ACKNOWLE DGE
25
26 ;"'MAKE PROGRAM ENTHY POINT ADDRESS
AVAILABLE TO OTHER MODULES.
27
START
28 PUBLIC
29
30 ;"'CLEAR RETURN CODE IN PARAMETER BLOCK.
MOVSI
[PPJ.RETURN CODE,O
31 START:
32
:l3 ;"'INITIALIZE RETRY COUNT.
MOVI
IX,10
34
35
3b ;"'POINT GC AT Low-bRDER 8271 REGISTER.
MOVI
GC,FLOPPY REG ADDR
37
38
39 ·"*"SEND COMMAND SEQUENCE TO 8271, HOLDING FINAL PARM.
40 ~***WAIT UNTIL 8271 IS NOT BUSY.
41 RETRY:
JNBT
[GCJ.COMMAND STAT,7,RETRY
42 ;***SEND "READ SECTOR, DRIVE O· COMMAND.
MOVSI
[GeJ.COMMAND
STAT,012H
"3
44 ;"'SEND TRACK ADDRESS PARAMETER.
MOVB
[GCJ.PARM RESULT,[PPJ.TRACK
45
4b
47 ;"'LOAD CHANNEL CONTROL REGISTER SPECIFYING:
FROM PORT TO MEMORY,
48
SYNCHRONIZE ON SOURCE,
49
GA POINTS TO SOURCE,
50
TERMINATE ON EXT,
51
TERMINATION OFFSET
O.
52
MOVI
CC,08820H
53
54
55 ; "'SET SOURCE BUS = 8, DEST BUS = 16.
56
WID
8,16
57
58 ;"'POINT GB AT DESTINATION, GA AT SOURCE.
59
LPD
liB,[PPJ.BUFF PTR

Figure 7-47 ASM-89 Sample Program
7-59

210911

THE 8089 INPUT/OUTPUT PROCESSOR

0023

1130 04FF

0027

AABA 00 FC

002B

6000

002D

0293 09 02CE 01

0033

6ABE 01 05

0037

A03C

0039

A840 DO

003C

EABA 00 FC

0040

OA4E 00 2C

0044

8ABA 00 FC

0048

0292 01 02CF OA

004E

4000

0050

2048

0052

MOVI
GA,DACK8271
60
01
02 ;"'INSURE THAT 8271 IS READY FOR LAST PARAMETER.
JNBT
[GCJ.COMMAND_STAT,5,WAITl
63 WAIT1:
64
05 ;"'PREPARE FOR DMA.
XFER
06
67
08 ;"'START DMA BY SENDING FINAL PARAMETER TO 8271.
[GC J. PARM_HESULT, [PP). SECTOR
MOVB
09
70
'f 1 ;"'PROGRAM RESUMES HERE FOLLOWING EXT.
72
73 ;"'IF TRANSFER IS OK THEN EXIT, ELSE TRY AGAIN.
JET
[GCJ.PARM RESULT,3,EXIT
74
75
76 ;"'DECREMENT RETRY COUNT.
DEC
IX
77
78
79 ;"'TRY AGAIN IF COUNT NOT EXHAUSTED.
JNZ
IX, RE1'RY
80
81
82 ;···WAIT UNTIL 8271 IS NOT BUSY.
JNBT
[GC J. COMMAND -- STAT,7,EXIT
83 EXIT:
84
85 ;···SEND "READ RESULT" COMMAND TO 8271.
MOVBI
[GCJ.COMMAND_STAT,02CH
86
87
88 ; "'WAIT FOR RESULT.
JNBT
[GC J. COMMAND STAT, 4, WAIT2
89 WAIT2:
90
91 ;1tttttPOST RESULT IN PARAMETER BLOCK FOR CfU.
MOVB
[PP).RETURN_CODE,[GCJ.PARM RESULT
92
93
94 ;"'INTERRUPT CPU.
SINTR
95
96
97 ;"'STOP EXECUTION.
HLT
98
99
100 FLOPPY
ENDS
END
101

SYMBOL TABLE

-----------DEFN VALUE TYPE
10
18
24
83
2
17

23
8
19
9
41
13
12
31
11
63
89

0004
0000
FF04
003C
0000
0000
FFOO
0000
0001
0000
OOOC
OOOA
0009
0000
0008
0027
0044

SYM
SYM
SYM
SYM
SYM
STR
SYM
STR
SYM
SYM
SYM
SYM
SYM
PUB
SYM
SYM
SYM

NAME
BUFF PTR
COMMAND STAT
DACK_8271
EXIT
FLOPPY
FLOPPY REGS
FLOPPY-REG ADDR
PARMBLoCK
PARM-RESULT
RESERVED TP
RETRY
RETURN CODE
SECTOR-START
TRACK
WAIT 1
WAIT2

ASSEMBLY COMPLETE; NO ERRORS FOUND

Figure 7-47 ASM-89 Sample Program (continued)
7-60

210911

THE 8089 INPUT/OUTPUT PROCESSOR

TO SYSTEM
SPACE

Figure 7 -48 Creating a Single Absolute Object Module

TOSVSTEM
SPACE

TOIIO
SPACE

Figure 7-49 Creating Separate Absolute Object Modules
- External References in Relocatable Modules

TO SYSTEM
SPACE

TallO
SPACE

FROM
ASM-89

Figure 7-50 Creating Separate Absolute Object Modules
- No External References in Relocatable Modules

7-61

210911

THE80891NPUT/OUTPUTPROCESSOR

ASM-89 ENTRY POINT DEFINITIONS

ORG 200H
READ:

; INSTRUCTIONS FOR "READ" CHANNEL PROGRAM

ORG 600H
WRITE:

; INSTRUCTIONS FOR "WRITE" CHANNEL PROGRAM

ASM-86 DEFINITION OF ENTRY POINT ADDRESSES

READ ADDR
WRITE_ADDR

DO 200H
DO 600H

PLlM-86 DECLARATION OF ENTRY POINT ADDRESSES

DECLARE READ$ADDR POINTER;
DECLARE WRITE$ADDR POINTER;
READ$ADDR = 200H;
WRITE$ADDR = 600H;

Figure 7-51 Using Absolute Entry Point Addresses

Self-Modifying Code

Programs that alter their own instructions are difficult to understand and modify, and preclude placing
the code in ROM. They may also inhibit compatibility with future Intel hardware and software products.

Note also when the 8089 is on a 16-bit bus, its instruction fetch queue can interfere with the attempt
of one instruction to modify the next sequential
instruction. Although the instruction may be
changed in memory, its unmodified first byte will be
fetched from the queue rather than memory if it is
on an odd address. The processor will thus execute a
partially-modified instruction with unpredictable
results.
7-62

210911

THE 8089 INPUT 10UTPUT PROCESSOR

1/0 System Design
Section 2.l0 notes that 110 systems should be designed hierarchically. Application programs "see"
only the topmost level of the structure; all details
pertaining to the physical characteristics and operation of I/O devices are relegated to lower levels.
Figure 7-52 shows how this design approach might
be employed in a system that uses an 8089 to perform I/O. The same concept. can be expanded to
larger systems with multiple lOPs.
The application system is clearly separated from the
I/O system. No application programs perform lIO;
instead they send an lIO request to the I/O
supervisor. On systems with file-oriented I/O, the request might be sent to a file system that would then
invoke the I/O supervisor.) The lIO request should
be expressed in terms of a logical block of data-a
record, a line, a message, etc. It should also be
devoid of any device-dependent information such as
device address, sector size, etc.
The lIO supervisor transforms the application program's request for service into a parameter block
and dispatches a channel program to carry out the
operation. The lIO supervisor controls the channels;
therefore, it knows the correspondence between
channels and lIO devices, the locations of CBs and
channel programs, and the format of all of the
parameter blocks. The lIO supervisor also coordinates channel "events," monitoring BUSY flags and
responding to channel-generated interrupt requests.
The lIO supervisor does not, however, communicate with lIO devices that are controlled by the
channels. If the CPU performs some lIO itself (this
should be restricted to devices other than those run
by the channels), the I/O supervisor invokes the
equivalent of a channel program in the CPU to do
the physical lIO. Note that although the I/O supervisor is drawn as a single box in Figure 7-52, it is likely
to be structured as a hierarchy itself, with separate
modules performing its many functions.
The software interface between the CPU's lIO supervisor and an lOP channel program should be completely and explicitly defined in the parameter block.
For example, the I/O supervisor should pass the addresses of all system memory areas that the channel
program will use. The channel program should not
be written so that it "knows" any of these addresses,
even if they are constants. Concentrating the interface into one place like this makes the system easier
to understand and reduces the likelihood of an undesirable side effect if it is modified. It also generalizes
the design so that it may be used in other application
systems.

Figure 7 -52 shows a simple channel program running
on channell and a more complex program running
on channel 2. Channell's program performs a single
function and is therefore designed as a simple
program. The program. on channel 2 performs three
functions (e.g., "read," "write," "delete") and is
structured to separate its functions. The functions
might be implemented as procedures called by the
"channel supervisor" depending on the content of
the parameter block. Notice that to the I/O supervisor, both programs appear alike; in particular, both
have a single entry point.
In some channel programs, different functions will
need different information passed to them in the
parameter block. Figure 7-53 shows one technique
that accommodates different formats while still allowing the channel supervisor to determine which
procedure to call from the PB. The parameter block
is divided into fixed and variable portions, and a
function code in the fixed area indicates the type of
operation that is to be performed. Part of the fixed
area has been set asede so that additional parameters
can be added in the future.

Programming Examples
The first example in this section illustrates how a
CPU can initialize a group of lOPs and then dispatch
channel programs. The code is written in PL/M-86.
The remaining examples, written in ASM-89,
demonstrate the 8089 instruction set and addressing
modes in various commonly encountered programming situations. These include:
•

memory-to-memory transfers

•

saving and restoring registers

Initialization and Dispatch
The PLlM-86 code in Figure 7-54 initializes two
lOPs and dispatches two channel programs on one of
the lOPs. The same general technique can be used to
initialize any number of lOPs. The hypothetical
system that this code runs on is configured as
follows:

7-63

•

8086 CPU 06-bit system bus);

•

two remote lOPs share an 8-bit local I/O bus
via the request/grant lines operating in
mode 1;
210911

il
.~

THE80891NPUT/OUTPUTPROCESSOR

1

APPLICATION
SVr

M

iI
:

-------1
I
I
I
I
I

APPLICATION
MODULE

1

CPU DOMAIN

APPLICATION
MODULE

APPLICATION
MODULE

t

J
+

+

1/0
SUPERVISOR

~----------------~----~--------

[J

I
I

:

CPUIIOP INTERFACE

~

~

~----------------------T--------~--------

1/0 SYSTEM

I
I
I
I
I
I
I
I
I
I

I
I
I
I
I
I
I
I
I
I
I
I
I
I
I
I
I
I
I
I
I

I
I
I
I
I
I
I
I
I
I
CHANNEL
FUNCTION
lOP DOMAIN

I
I
I
I
I
I
I

CHANNEL
SUPERVISOR

CHANNEL
FUNCTION

CHANNEL
FUNCTION

DEVICE
CONTROLLER

DEVICE
CONTROLLER

CHANNEL1

CHANNEL2

CHANNEL
FUNCTION

Figure 7-52 B089-Based 1/0 System Design
7-64

210911

THE BOB9 INPUT/OUTPUT PROCESSOR

•

8089 channel attentions are mapped into four
port addresses in the CPU's I/O space;

•

channel programs reside in the 8089 I/O
space;

•

one 8089 controls a CRT terminal, one channel running the display, the other scanning
the keyboard and building input messages;

•

the function of the second 8089 is not defined
in the example.

IFor
FIXED

Two simple parameter blocks define messages to be
transmitted between the PLlM-86 program and the
CRT. Each PB contains a pointer to the beginning of
the message area and the length of the message. In
the case of the keyboard (input) message, the channel program builds the message in the buffer pointed
to by the pointer in the PB and returns the length of
the message in the PB.

o
TP/CHANNEL STATE
SAVE AREA

2
FIXED PARM11

I

FUNCTION
CODE

4

FIXED PARM2

6

FIXED PARM3

8
10

RESERVED FOR
FUTURE USE
12

VARIABLE

FOR1MAT

The code declares one CB (channel control block)
for each 8089. The CBs are declared as two-element
arrays, each element defining the structure of one
channel's portion of the CB. The SCB (system configuration block) and SCP (system configuration
pointer) are also declared as structures. The SCP is
located at its dedicated system space address of
FFFF6H. The other structures are not located at
specific addresses since they are all linked together
by a chain of pointers "anchored" at the SCPo

,"

VARIABLE PARAMETER
FORMAT
AND BY
SIZE
GOVERNED

lr~____

,"

:r

F_U_N_C_T_IO_N
__
C_O_D_E__. . .

Figure 7 ·53 Variable Format Parameter Block

The code initializes one lOP at a time since the chain
of control blocks read by the lOP during initialization
must remain static until the process is complete. To
initialize the first lOP, the code fills in the SYSBUS
and SOC fields and links the blocks to each other
using the PLiM -86 @ (address) operator. It sets
channel l's BUSY flag to FFH so that it can monitor
the flag to determine when the initialization has
been completed (the lOP clears the flag to OH when
it has finished). Channel2's BUSY flag is cleared, although this could just as well have been done after
the initialization (the lOP does not alter channel 2's
BUSY flag during initialization). The code starts the
lOP by issuing a channel attention to channell to indicate that the lOP is a bus master. PLlM-86's OUT
function is used to select the port address to which
the lOP's CA and SEL lines have been mapped. The
data placed on the bus (OH) is ignored by the lOP. It
then waits until the lOP clears the channel I BUSY
flag.

I*ASSIGN NAMES TO CONSTANTS* I
DECLARE
CHANNEL$BUSY
DECLARE
CHANNEL$CLEAR
DECLARE
CR I*CARR. RET.*I
LF I*LlNE FEED* I
DECLARE
DECLARE
DISPLAY$TB
DECLARE
KEYBD$TB

LlTERALLY'OFFH';
LlTERALLY'OH';
LITERALLY 'ODH';
LlTERALLY'OAH';
LITERALLY '200H';
LITERALLY '600H';

Figure 7·54 Initialization and Dispatch Example

7-65

210911

THE80891NPUT/OUTPUTPROCESSOR

DECLARE '*IOP CHAN N EL ATTENTION ADDRESSES * ,
IOP$A$CH1
LITERALLY
'OFFEOH',
IOP$A$CH2
LITERALLY
'OFFE1 H',
IOP$B$CH1
LITERALLY
'OFFE2H',
IOP$B$CH2
LITERALLY
'OFFE3H';
DECLARE I*CHANNEL CONTROL BLOCK FOR 10P$A)
CB$A(~
STRUCTURE
(CCW
BYTE
BUSY
BYTE
PB$PTR
POINTER
WORD);
RESERVED
DECLARE

I*CHANNEL CONTROL BLOCK FOR 10P$B' I
CB$B(2)
STRUCTURE
(CCW
BYTE
BUSY
BYTE
PB$PTR
POINTER
WORD);
RESERVED

DECLARE

I*SYSTEM CONFIGURATION BLOCK";
SCB
STRUCTURE
(SOC
BYTE
RESERVED
BYTE
CB$PTR
POINTER);

DECLARE

/*SYSTEM CONFIGURATION POINTER';
SCP
STRUCTURE
BYTE
(SYSBUS
RESERVED
BYTE,
SCB$PTR
POINTER) AT (OFFFF6H);

DECLARE

MESSAGE$PB STRUCTURE
(TB$PTR
POINTER,
MSG$PT-R
POINTER,
MSG$LENGTH WORD);

DECLARE

KEYBD$PB STRUCTUE
(TP$PTR
POINTER,
BUFF_PTA
POINTER,
MSG$SIZE
WORD);

DECLARE

SIGN$ON BYTE (*) DATA
(CR, LF, 'PLEASE ENTER USER ID');

DECLARE

KEYBD$BUFF BYTE (256);

,*

*INITIALIZE 10P$A, THEN 10P$B

*,

'*PREPARE CONTROL BLOCKS FOR 10P$A*'
SCP .SCB$PTR = @ SCB;
SCP.SYSBUS = 01H; '*16-BIT SYSTEM BUS*'
SCB.SOC = 02H; '*RQ'GT MODE1, 8-BIT I/O BUS"'
SCB.CB$PTR = @ CB$A(O); .
CB$A(O).BUSY = CHANNEL$BUSY
CB$A(1 ).BUSY = CHANNEL$CLEAR;

Figure 7 -54 Initialization and Dispatch Example (continued)

7-66

210911

THE 8089 INPUT/OUTPUT PROCESSOR

,il

'"ISSUE CA FOR CHANNEL1, INDICATING lOP IS MASTER*'
OUT (lOP$A$CH1) = OH;
'"WAIT UNTIL FINISHED"'
DO WHILE CB$A(O).BUSY = CHANNEL$BUSY;
END;
'"PREPARE CONTROL BLOCKS FOR 10P$B"'
SCB.CB$PTR = @CB$B(O);
CB$B(O).BUSY = CHANNEL$BUSY;
CB$B(1).BUSY = CHANNEL$CLEAR;
'"ISSUE CA FOR CHANNEL2, INDICATING SLAVE STATUS"'
OUT (IOP$B$CH2) = OH;
'"WAIT UNTIL lOP IS READY"'
DO WHILE CB$B(O).BUSY = CHANNEL$BUSY;
END;

,"

,

'SEND SIGN ON MESSAGE TO CRT CONTROLLED
"BY
, CHANNEL 1 OF 10P$A

"WAIT UNTIL CHANNEL IS CLEAR, THEN SETTO BUSY',
DO WHILE LOCKSET (@CB$A(O).BUSY, CHANNEL$BUSY);
END;
,'SETCCW AS FOLLOWS:
"
PRIORITY = 1,
NO BUS LOAD LIMIT,
DISABLE INTERRUPTS,
START CHANNEL PROGRAM IN I/O SPACE',
CB$A(O).CCW = 10011001 B;
'"LINK MESSAGE PARAMETER BLOCK TO CB',
CB$A(O).PB$PTR = @ MESSAGE$PB;
'"FILL IN PARAMETER BLOCK',
MESSAGE$PB.TB$PTR = DISPLAY$TB;
MESSAGE$PB.MSG$PTR = @SIGN$ON;
MESSAGE$PB. MSB$LENGTH = LENGTH (SIGN$ON);
'"DISPATCH THE CHANNEL"'
OUT (lOP$A$CH1) = OH;

,
'

'DISPATCH CHANNEL 2 OF 10P$ATO
'CONTINUOUSLY SCAN KEYBOARD, INTERRUPTING
"WHEN A COMPLETE MESSAGE IS READY

"'

"WAIT UNTIL CHANNEL IS CLEAR, THEN SET TO BUSY"'
DO WHILE LOCKSET (@ CB$A(1).BUSY, CHANNEL$BUSY);
END;

Figure 7 -54 Initialization and Dispatch Example (continued)

7-67

210911

THE 8089 INPUT/OUTPUT PROCESSOR

I*SET CCW AS FOLLOWS:
*
PRIORITY = 0
BUS LOAD LIMIT,
ENABLE INTERRUPTS,
START CHANNEL PROGRAM IN 1/0 SPACE* I
CB$A(1).CCW = 00110001 B;
I*LlNK KEYBOARD PARAMETER BLOCK TO CB* I
CB$A(1).PB$PTR = @ KEYBD$PB;
I*FILL IN PARAMETER BLOCK* I
KEYBD$PB.TB$PTR = KEYBD$TB;
KEYBD$PB.BUFF$PTR = @ KEYBD$BUFF;
KEYBD$PB.MSG$SIZE = OH;
I*DISPATCH THE CHANNEL * I
OUT (IOP$A$CH2) = OH;

Figure 7 -54 Initialization and Dispatch Example (continued)

The second lOP is initialized in the same manner,
first changing the pointer in the SCB to point to the
second lOP's channel control block. If this lOP were
on a different I/O bus, the SOC field would have
been altered if a different request/grant mode were
being used or if the lOP had a 16-bit 110 bus. The
second lOP is a slave so its initialization is started by
issuing a CA to channel 2 rather than channell.
After both lOPs are ready, the code dispatches two
channel programs (not coded in the example); one
program is dispatched to each channel of one of the
lOPs. To avoid external references, the system has
been set up so that the PLlM-86 code "knows" the
starting addresses of these channel programs (200H
and 600H). The code uses the PLlM-86 LOCKSET
function to:
•

lock the system bus;

•

read the BUSY flag;

•

set the BUSY flag to FFH ifit is clear;

•

unlock the system bus.

This operation continues until the BUSY flag is
found to be clear (indicating that the channel is
available). Setting the flag immediately to FFH prevents another processor (or another task in this program activated as a result of an interrupt) from using
the channel. The code fills in the parameter block
with the address and length of the message to be
displayed, sets the CCW and then links the channel
program (task block) start address to the parameter
block and links the parameter block to the CB. The
channel is dispatched with the OUT function that effects a channel attention for channell.

A similar procedure is followed to start channel 2
scanning the terminal keyboard. In this case, the
code allows channel 2 to generate an interrupt request (which it might do to signal that a message has
been assembled). An interrupt procedure would
then handle the interrupt request.

Memory-to-Memory Transfer
Figure 7-55 shows a channel program that performs
a memory-to-memory block transfer in seven
instructions. The program moves up to 64K bytes
between any two locations in the system space. A
16-bit system bus is assumed, and the CPU is assumed to be monitoring the channel's BUSY flag to
determine when the program has finished.

To attain maximum transfer speed, the program
locks the bus during each transfer cycle. This ensures
that another processor does not acquire the bus in
the interval between the DMA fetch and store
operations. By setting this channel's priority bit in
the CCW to 1 and the other Channel's to 0, the CPU
could effectively prevent the other channel from
running during the transfer. Byte count termination
is selected so that the transfer will stop when the
number of bytes specified by the CPU has been
moved. Since there is only a single termination
condition, a termination offset of 0 is specified. The
transfer begins after the WID instruction, and the
HLT instruction is executed immediately UP\ln
termination.
7-68

210911

THE 80891NPUT/OUTPUT PROCESSOR

Saving and Restoring Registers

A more general solution is shown in Figure 7-56.
This is a program that does nothing but save the contents of the channel registers. The registers are
saved in the parameter block because PP is the only
register that is known to point to an available area of
memory. A similar program could be written to restore registers from the same parameter block.

A CPU program can "interrupt" a channel program
by issuing a "suspend" channel command. The channel responds to this command by saving the task
pointer and PSW in the first two words of the
parameter block. The suspended program can be restarted by issuing a "resume" command that loads
TP and the PSW from the save area.

Using this approach, the CPU would "interrupt" a
running program as follows:

If the CPU wants to execute another channel program between the suspend and resume operations,
the suspended program's registers will usually have
to be saved first. If the "interrupting" program
"knows" that the registers must be saved, it can perform the operation and also restore the registers
before it halts.

•

suspend the running program,

•

run the register save program,

•

run the "interrupting" program,

•

run the register restore program,

•

resume the suspended program.

MEMEXAMP
SEGMENT
;**MEMORY-TO-MEMORY TRANSFER PROGRAM"
PB
STRUC
TP_RESERVED:
DS
4
FROM_ADDR:
DS
4
TO_AD DR:
DS
4
SIZE:
DS
2
PB
ENDS
;POINT GA AT SOURCE, GB AT DESTINATION.
GA, [PPl.FROM_ADDR
LPD
GB, [PP .TO_ADDR
LPD
;LdAD BYTE COUNT INTO BC.
MOV
BC, [PPJ.SIZE
;LOAD CC SPECIFYING:
MEMORY TO MEMORY,
NO TRANSLATE,
UNSYNCHRONIZED,
GA POINTS TO SOURCE,
LOCK BUS DURING TRANSFER,
NO CHAINING,
TERMINATING ON BYTE COUNT,OFFSET = o.
MOV
CC, OC208H
;PREPARE CHANNEL FOR TRANSFER.
XFER
;SET LOGICAL BUS WIDTH.
WID

16,16

;STOP EXECUTION AFTER DMA.
HLT
MEMEXAMP
ENDS
END

Figure 7 -55 Memory-to-Memory Transfer Example
7-69

210911

THE BOB9 INPUT/OUTPUT PROCESSOR

SAVEREGS
SEGMENT
;SAVE ANOTHER CHANNEL'S REGISTERS IN PB
PB
STRUC
TP _RESERVED:
DS
4
GA_SAVE:
DS
3
GB_SAVE:
DS
3
GC_SAVE:
DS
3
IX_SAVE:
DS
2
BC_SAVE:
DS
2
MC_SAVE:
DS
2
CC __ SAVE:
DS
2
PB
ENDS

SAVEREGS

MOVP
MOVP
MOVP
MOV
MOV
MOV
MOV
HLT
ENDS
END

Figure 7-56 Register Save Example

7-70

210911

The 80130 Operating
System Firmware
Component

-

- - - \

:

I,

CHAPTER 8
THE 80130 OPERATING SYSTEM
FIRMWARE COMPONENT
8.1 INTRODUCTION

•

Management of Objects

This chapter describes the 80130 'Operating System
Firmware (OSF) component. The 80130 OSF
component (software in silicon) is a processor extension in the form of of an extremely sophisticated integrated circuit. In conjunction with the 8086,88 or
the 80186,188 CPU, it forms the nucleus of a highperformance, real-time multitasking operating
system. The 80130 adds task management, interrupt
management, message passing, synchronization and
memory allocation capabilities to the CPU, and extends the basic data types of the CPU by adding new,
system data types (JOB'S, TASK'S, MAILBOX's,
SEGMENT's, and REGION's). To create, manipulate and delete these new data types, the 80130 uses
35 operating-system instructions- or "primitives."
Programs using the 80130 primitives may be written
in ASM-86, PL/M-86, Fortran-86, or Pascal-86.

•

Management of Exceptions

•

Management ofInterrupts

•

Extendability

•

Primitives

•

Programming Considerations

•

iRMX 86 Features

.

:;:
'i

The following sections describe all of these features
in detail.

I,

In addition, the 80130 OSF contains a programmable
interrupt controller, 16-bit operating-system and
delay timers, and a variable baud-rate generator. It
is connected directly to the multiplexed address/data
bus of the CPU. The 80130 is compatible with the
MULTIBUS system as well as the iRMX 86 operatingsystem.

This chapter contains a discussion of the software aspects of the OSF. Hardware considerations are discussed in Chapter 5, Volume 2 ofthis set.

The 8087 Numeric Processor Extension (NPX) can
be added to either pair of components. Figure 8-2
shows the notation used to refer to these
combinations.

The OSF provides the foundation of an operating
system. To do so, it provides a collection of features
that can serve as the heart of any operating system.
Specifically, the OSP processor (see below) provides:
Object-Oriented Architecture

•

Multitasking

•

Multiprogramming

•

Intertask Coordination

•

Dynamic Memory Allocation

i

The 80130 is a component that is designed to work
in conjunction with either the 8086,88 or the
80186,188 microprocessor. When the 80130 is combined with the iAPX 86/10 (8086) microprocessor,
the pair of components is called the iAPX 86/30
Operating System Processor (OSP). When the 80130
is combined with the iAPX 186/10 (80186)
microprocessor, the pair of components is called the
iAPX 186/30 Operating System Processor. Figure
8-1 shows the names of these combinations of
components. In order to simplify nomenclature, this
manual uses the term OSP to refer to either pair of
components.

For additional information about the 80130 OSF
component, the reader is referred to the iOSP 86
Support Package Reference Manual, Order Number:
14443, which has been used as the reference document for this chapter.

•

n

8.2 80130 OSF OVERVIEW

The 80130 component expands the capabilities of
the microprocessor to provide a new set of functions
called primitives. These primitives are designed specifically to serve as the foundation for a real-time,
multitasking operating system.
In other words, the OSP provides an expanded instruction set. In addition to the instructions provided
by the microprocessor alone, the OSP provides
more sophisticated instructions that can be used to
build a real-time operating system.
8-1

210911

!I

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

iAPX 86110
(8086)

iAPX 86130

80130

iAPX 88110

(8088)

iAPX 88130

80130

Figure 8-1 Combining the 80130 and a Microprocessor

iAPX 86110
(8086)

iAPX 88110
(8088)
iAPX 86140

80130

80130

iAPX 88140

8087

8087

Figure 8-2 Adding the 8087 Numeric Processor Extension

In the same way that high-level programming languages reduce the manpower needed to write a
program, the more powerful instructions of the asp
reduce the manpower needed to write an operating
system. This results in less development time and
expense.

Explanation of Object-Oriented
Architecture
An Object-Oriented Architecture is a means of
humanizing an operating system. It uses a collection
of building blocks that are manipulated by operators.
For purposes of illustration, the architecture of FORTRAN will be used as an example.

8.3 ARCHITECTURE
The asp uses an object-oriented architecture in
order to make operating systems easy to learn about
and to use.
An operating system is a collection of functions
meant to be used by software engineers. Many
operating systems are so complex that the majority
of the engineers using them are unable to fully grasp
their organization. In contrast, systems having
object-oriented architectures are easier to
understand. Their mechanisms are well defined, and
they demonstrate a consistency that makes the
operating system seem less awesome.

FORTRAN has a typed architecture. Its building
blocks are variables of several types. For instance, it
has integers, real numbers, double-precision real
numbers, etc. It also has operators (+, -, *, /, *',
and others) that act on variables to produce understandable results.

The asp provides building blocks called objects. As
with FORTRAN variables, asp objects are of several types. The types are tasks, jobs, mailboxes,
regions, and segments.
8-2

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

Just as the variables in a FORTRAN program are
acted upon by operators, the objects in an aSP-based
system are acted upon by primitives. "Primitives"
are procedures that the asp provides to allow you to
manipulate objects. For instance, the CREATE$TASK primitive does precisely what its name suggests as shown in Figure 8-3.

the asp provides TOKENs. A TOKEN is a 16-bit
value that the asp gives to you whenever you create
an object. This value is unique in that no two objects
can have the same TOKEN at the same time. In
order to manipulate a particular object, the appropriate primitive is invoked using the object's TOKEN
as one of the parameters.

In the text portions of this manual, the pflmltlves
are consistently referred to by their informal names,
such as CREATE$TASK. In the example in Figure
8-3 and throughout most of Chapter 8, the primitives
are referred to by their formal names. A formal
name is derived from an informal name by adding
"RQ$" or "RQ" at the beginning. Consequently,
the formal counterpart of CREATE$TASK is
RQ$CREATE$TASK.

8.4 MULTITASKING
The asp provides multitasking to simplify the development of systems that process real-time events.
The essence of real-time operating systcms is the
ability to process numerous events occurring at
seemingly random times. These events are asynchronous because they can occur at any time, and they
are potentially concurrent because one event might
occur while another is being processed.

The purpose of this example is to show that primitives are invoked as PLlM-86 procedures. Figure
8-3 shows how to create a task using the CREATE$TASK primitive. The parameters of the primitive
vary according to the type of task you are creating.
An object-oriented architecture makes a system
easier to learn and to use. It does this by taking advantage of classification of objects. In the case of
FORTRAN, the variables are classified into types,
because each type exhibits certain characteristics.
For instance, all integer variables are similar,
though they can take on different values. This similarity makes FORTRAN easy to master. For the
same reasons, the asp objects are classified into
types. Each object type (such as a mailbox) has a
specific set of attributes. Once the programmer, has
become familiar with the attributes of a mailbox, he
is familiar with all mailboxes. There are no special
cases.

Any single program that attempts to process
multiple, concurrent, asynchronous events is bound
to be complex. The program must perform several
functions. It must process the events. It must
remember which events have occurred and the
order in which they occurred. It must remember
which events have occurred but have not been
processed. The complexity obviously grows greater
as the system monitors more events.
Multitasking is a technique that dissipates unwinds
this confusion. Rather than writing a 5ingle program
to process N events, N programs can be written,
each of which processes a single event. This technique eliminates the need to monitor the order in
which events occur.
Each of these N programs forms an as P task, one of
the types of objects in the object-oriented
architecture. Tasks are the only active objects provided by the aSP, as only tasks can invoke primitives.

Classification by type also applies to as P primitives.
Each type of asp object has an associated set of
primitives. These primitives cannot be used to manipulate objects of another type without causing an
error. (The analogy breaks down at this point. FORTRAN operators almost always work on several
types ofvariables.l

Multitasking simplifies the process of building a
system. This allows systems to be built faster and
with less expense. Furthermore, because of the oneto-one relationship between events and tasks, the
system's code is less complex and is easier to
maintain.

The beauty of the object-oriented architecture of the
asp can be summed up in one statement: Once the
programmer learns the attributes and the primitives
associated with a type of object, he has complete
knowledge of the behavior of the object type.

Tasks
Means of Referring to an Object

Tasks are the active objects provided by the aSP.
For each task in a running operating system, the
asp keeps track of a code segment, a task priority, a
task state, and other attributes that are described
below.

One of the by-products of an object-oriented architecture is that the programmer must have a means
of referring to a particular object. For this purpose,
8-3

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

/***********************************************************************
* This example illustrates how the CREATE$TASK primitive can be used.*
***********************************************************************/
$INCLUDE(:F1:0SXPRM.EXT);

/* Declares all primitive calls */

TAS~CODE: PROCEDURE EXTERNAL;
END TASK_CODE;

DECLARE TOKEN

DECLARE
DECLARE
DECLARE
DECLARE
DECLARE
DECLARE

task$token
priority$level$66
start$address
data$seg
stack$pointer
stack$size$512

DECLARE task$flags
DECLARE status
SAMPLE PROCEDURE:
PROCEDURE;
start$address
@TAS~CODE;
data$seg = 0;
stack$pointer
0;
task$flags = 0;

.: }

LITERALLY 'SELECTOR';
/* if your PL/M compiler does not
support this variable type,
declare TOKEN a WORD */
TOKEN;
LITERALLY '66';
POINTER;
WORD;
POINTER;
LITERALLY '512';
/* new task's stack
size is 512 bytes */
WORD;
WORD;

/*
/*
/*
/*

first instruction of the new task */
task sets up own data segment */
automatic stack allocation */
designates no floating-point
instructions */

Typical PL/M-86 Statements

/************************************************************************
* The task TASK CODE is created when the calling task invokes the
*
* CREATE$TASK primitive.
*
************************************************************************/
task$token = RQ$CREATE$TASK
(priority$level$66,
start$address,
data$seg,
stack$pointer,
stack$size$512,
task$flags,
@status);

.: }

Typical PL/M-86 Statements

END SAMPLE_PROCEDURE;

Figure 8-3 Example Showing How to Use a Primitive

8-4

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

resume operation before the task can leave
the suspended state.

CODE SEGMENTS FOR TASKS

A code segment is simply an iAPX 86/186 segment
that contains code. Each task has an associated code
segment that contains instructions for the task to
execute. When writing code for a task, whether the
code is in assembly language or a high-level
language, procedures rather than main modules,
must be used.

•

When a sleeping task is suspended, it enters
the asleep-suspended state. In effect, it is
then in both the asleep and suspended states.
While asleep-suspended, the task's sleeping
time might expire, putting the task in the suspended state. Also, if another task resumes
an asleep-suspended task, the latter task will
enter the asleep state.

TASK PRIORITY

A task's priority is an integer value between 0 and
255 (decimal). The lower the priority number, the
higher the priority of the task. A high priority task
has favored status as it competes with other tasks for
the microprocessor.

•

The Ready State

A task is ready if it is not asleep, suspended,
or asleep-suspended.

Unless a task is involved in processing interrupts
(described later in this chapter), its priority should
be between 129 and 255. When a task having a priority in the range 0 to 128 is running, certain external
interrupt lines are disabled, depending on the
priority.

•

The Running State

For a task to become the running (executing)
task, it must be the highest priority task in the
ready state. A system built upon the OSP can
have only one funning task at any given
instant.

Also, if a task's code uses instructions that execute
on the 8087 NPX (Numeric Processor Extension),
that task should not have a priority high enough to
disable the interrupt line of the 8087 NPX, or a deadlock situation could result. The interrupt line of the
8087 is configurable. Refer to Section 8.8 of this
chapter for a correlation between priorities and interrupt lines.

Task State Transitions

The OSP does not use a time-slicing algorithm to allocate the processor to tasks. Instead, it uses a
priority-based, event-driven algorithm. As the
operating system executes, events occur which
cause tasks to pass from state to state. Figure 8-4
shows the paths of transition between states.

TASK STATES

A task is always in one of five execution states. The
states are asleep, suspended, asleep-suspended,
ready, and running.
•

The Asleep-Suspended State

The following list describes, by number, the events
that cause the transitions in Figure 8-4. In the list,
the migrating task is called "the task."

The Asleep State
1) When the task is created, it is placed in the

A task is in the asleep state when it is waiting
for a request to be granted. Also, a task can
put itself to sleep for a specified amount of
time by using the SLEEP primitive.
•

ready state.
2) The task goes from the ready state to the running state when one of the following occurs:
•

The task has just become ready and has
higher priority than does any other
ready task.

•

The task is ready, no other ready task
has higher priority, no other task of
equal priority has been ready for a
longer time, and the previously running
task has just left the running state by
transitions (4), (6), or (10).

The Suspended State

A task enters the suspended state when it is
placed there by another task, when it is waiting for a interrupt, or when it suspends itself.
Associated with each task is a suspension
depth, which reflects the number of
"suspends" outstanding against it. Each suspend operation must be countered with a
8-5

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

(NON-EXISTENT)

t(1)
READY

I""
(9)

(5)

1"')

(7)

(2)

~_A_S_L_E~E_P~I~~~____(4_)____

RUNNING

I

_~

____(_6_)

I

SUSPENDED

1:J
(8)

(7)
(5)

(9)

I

ASLEEP-SUSPENDED

I

(8)~

~ (10)
~-343

(NON-EXISTENT)

Figure 8-4 Task State Transition Diagram

3) The task goes from the running state to the
ready state when the task is preempted by a
higher priority task that has just become ready.
4) The task goes from the running state to the

asleep state when one of the following occurs:
•

The task puts itself to sleep (by the
SLEEP primitive).

•

The task makes a request (by the LOOKUP$OBJECT, RECEIVE$MESSAGE,
or RECEIVE$CONTROL primitive)
that cannot be granted immediately and
expresses, in the request, its willingness
to wait.

The task's designated waiting period expires without its request being granted.

•

The task's request is granted (because
another task called the CATALOG$OBJECT, SEND$MESSAGE, or the
SEND$CONTROL primitive. These
calls correspond to those mentioned earlier in (4).)

6) The task goes from the running state to the suspended state when the task suspends itself (by
the SUSPEND$TASK or WAIT$INTERRUPT
primitive.)

5) The task goes from the asleep state to the ready
state or from the asleep-suspended state to the
suspended state when one of the following
occurs:
•

•

7) The task goes from the ready state to the suspended state or from the asleep state to the
asleep-suspended when the task is suspended
by another task (by the SUSPEND$TASK
primitive.)

The time period specified in the invocation of the SLEEP primitive expires.
8-6

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

8) The task remains in the suspended state or the
asleep-suspended state when one of the following occurs:
•

•

Primitives for Tasks
The OSP provides the following primitives to manipulate tasks:

The task is, once again, suspended by
another task using the SUSPEND$TASK primitive.

•

CREATE$TASK
The CREATE$TASK primitive creates a task
and returns a token for it.

The task has a suspension depth greater
than one and the task is resumed by
another task (by the RESUME$TASK
primitive.)

•

DELETE$TASK
The DELETE$TASK primitive deletes a task
from the system.

•

SUSPEND$TASK
The SUSPEND$TASK primitive increases a
task's suspension depth by one, and suspends
the task if it is not already suspended.

•

RESUME$TASK
The RESUME$TASK primitive decreases a
task's suspension depth by one. If the depth
becomes zero and the task was suspended,
this primitive makes the task ready. If the
depth becomes zero and the task was asleepsuspended, this primitive puts the task into
the asleep state.

•

SLEEP
The SLEEP primitive places the calling task
in the asleep state for a specified amount of
time.

•

GET$TASK$TOKENS
The GET$TASK$TOKENS primitive allows
a task to obtain a token for any of the following 0 bjects:

9) The task goes from the suspended state to the
ready state or from the asleep-suspended state
to the asleep state when the task has a suspension depth of one and the task is resumed by
another task (by the RESUME$TASK or SIGNAL$INTERRUPT primitive) or when a task
awaiting an interrupt receives the interrupt.
10) The task goes from any state to non-existence
when it is deleted (by the DELETE$TASK, or
RESET$INTERRUPT primitives.)

ADDITIONAL TASK ATTRIBUTES

In addition to priority, execution state, and suspension depth, the OSP maintains the following attributes for each task: containing job, contents of
registers, starting address of its exception handler,
the task's exception mode, whether the task is an interrupt task, and whether the task uses the 8087
NPX. Jobs, interrupts, exception handlers, and exception modes are discussed later in this chapter.

- the job containing the task
- the parameter object for the job containing
the task

Task Resources
When a task is created, the OSP takes any resources
that it needs at that time (such as memory) from the
task's job. If the task is subsequently deleted, the
OSP returns those resources to the task's job. (Jobs
are discussed in detail in the section of this chapter
entitled "Multiprogramming.")

- the system's root job
- the task itself

•

The task's code, however, is not a resource in this
sense. It does not come from nor does it return to
the task's job, because it is static during system
operation.
8-7

SET$PRIORITY
The SET$PRIORITY primitive allows a task
to change its own priority or that of another
task.
210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

The programmer must decide which tasks belong in
the same job. In general, tasks should be placed in
the same job if:

8.5 MULTIPROGRAMMING
Multiprogramming is a technique used to run several
applications on a single hardware system. In order to
take full advantage of multiprogramming, the asp
provides each application with a separate
environment; that is, separate memory and objects.
The reason for this isolation is to prevent
independently-developed applications from causing
problems for each other.
The asp provides a type of object that can be used
to obtain this kind of isolation. The object is called a
job, and it has the following characteristics:
•

Unlike tasks, jobs are passive. They cannot
invoke primitives.

•

Each job includes a collection of tasks and
those resources needed by those tasks.

•

•

•

They have similar or related purposes

•

They share many resources

Job Tree and Resource Sharing
The jobs in a system are arranged in the form of a
tree. The root job is a job provided by the asp. The
remaining jobs, including jobs that are created dynamically while the system runs, are descendants of
the root job. A job containing tasks that create other
jobs is a parent job. A newly created job is a child of
the job whose task created it.
Associated with each job is a set of limits. The limits
of ajob are as follows:

Jobs serve as useful boundaries for dynami• cally allocating memory. When two tasks of
one job request memory, they share the
memory associated with their job. Two tasks
in different jobs do not directly compete for
memory.
An application consists of one or more jobs.

Multiprogramming provides application systems
with two benefits:
•

•

Multiprogramming increases the amount of
work a system can do. By running several applications rather than one, hardware is being
utilized a greater percentage of the time, thus
reducing hardware implementation costs.

•

Maximum and minimum allowable sizes of
the job's memory pool.

•

Maximum allowable number of simultaneously existing objects that the job can contain.

•

Maximum allowable number of simultaneously existing tasks that the job can contain.

•

Highest allowable priority of any task contained in the job.

These limits must be specified whenever a job is
created. These limits apply collectively to the job and
all of its descendant jo bs.
For example, suppose Job A creates Job B. When
this happens:

Because of the correspondence between jobs
and applications, new jobs can be added to a
system without affecting other jobs. This
makes system modifications easier and faster.

Definition of JOB
A JOB is an asp object that serves as an environment in which other asp objects such as tasks,
mailboxes, regions, segments, and (offspring) jobs
reside. In addition, each job has a pool of memory.
The job's memory pool provides the raw material
from which objects can be created by the tasks in the
job.

•

The memory for Job B's memory pool is
taken from Job A's memory pool.

•

The numbers of tasks and total objects that
Job A can contain are reduced by the corresponding values specified for Job B.

•

The specified maximum priority for tasks in
Job B cannot exceed the maximum priority
for tasks in Job A.

Job Creation
Applications consist of one or more jobs. Although
the jobs within an application can be independent of
one another, they can share resources. Objects may
be shared between jobs, although each object is
owned by only one job.

When a job is created it has one task. The functions
of this task include doing some initializing for the
new jo b. Initializing activities can include housekeeping and creating other objects in the new job.
8-8

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

When a task creates ajob, it has the option of passing
a token for a parameter object to the newly created
job. The parameter object can be an OSP object of
any type and it can be used for any purpose. For
example, the parameter object might be a segment
containing data, arranged in a predefined format,
needed by tasks in the new job. Tasks in the new job
can obtain a token for the job's parameter object by
means of the GET$TASK$TOKENS primitive, described in Chapter 3.

strokes from a terminal until a carriage return is
encountered. It then passes the entire line of text to
another task, which is responsible for decoding
commands.
The second reason for passing data is to draw attention to a specific object in the application system. In
effect, one task says to another, "I am talking about
that object."
The OSP facilitates intertask communication by supplying objects called mailboxes along with primitives
to manipulate mailboxes. The primitives associated
with mailboxes are CREATE$MAILBOX, DELETE$MAILBOX, SEND$MESSAGE, and RECEIVE$MESSAGE. Tasks use the first two primitives to build and eradicate a particular mailbox.
They use the second two to communicate with each
other. If Task A wants Task B to become aware of a
particular object, Task A uses the SEND$MESSAGE primitive to mail a token for the object
to the mailbox. Task B uses the RECEIVE$MESSAGE primitive to get the token from the
mailbox.

Jobs differ from other OSP objects in duration. Once
ajob is created, it exists as long as the system exists.

Primitives for Jobs
The OSP provides one primitive that relates to jobs.
The CREATE$JOB primitive creates a job containing one task. During the creation, the primitive
draws resources for the new job from the resources
of the parent job (the job containing the calling
task). After the job has been created, the primitive
returns a token for the job to the calling task.

8.6 INTERTASK COORDINATION

NOTE: The foregoing example, along with all of the
examples in this section, is somewhat simplified in
order to serve as an introduction. For detailed
information, refer to Section 8.10, in which each
OSP primitive is individually described.

The OSP provides simple techniques for tasks to
coordinate their activities. These techniques allow
tasks in a multitasking system to mutually exclude,
synchronize, and communicate with each other.
Multitasking is a technique used to simplify the
design of real-time application systems that monitor
multiple, concurrent, asynchronous events. Multitasking allows engineers to focus their attention on
the processing of a single event rather than having to
contend with numerous other events occurring in an
unpredictable order.

As mentioned previously, tasks can use mailboxes
to send information to each other. This is accomplished by putting the information into a segment (an
OSP object consisting of a contiguous block of
memory) and using the SEND$MESSAGE primitive
to mail a token for the segment. The other task invokes the RECEIVE$MESSAQE primitive to get
the token for the segment containing the message.

However, the processing of several events may be
related. For instance, the task processing Event A
may need to know how many times Event B has occurred since Event A last occurred. This kind of processing requires that tasks be able to coordinate with
each other. The OSP provides for this coordination.

Why don't tasks just send tokens for messages
directly between each other, rather than through
mailboxes? Because tasks are asynchronous-they
run in unpredictable order. If two tasks want to communicate with each other, they need a place to store
messages and to wait for messages. If the receiver
uses the RECEIVE$MESSAGE primitive before the
message has been sent, the receiver can wait at the
mailbox until a message arrives. Similarly, if the
sender uses the SEND$MESSAGE primitive before
the receiver is ready to receive, the message is held
at the mailbox until a task requests a message from
the mailbox. In other words, mailboxes allow tasks
to communicate with each other even though tasks
are asynchronous.

Tasks can interract with each other in three ways.
They can exchange information, mutually exclude
each other, and synchronize with each other. Each
of these will be examined in the following sections.
EXCHANGING INFORMATION

Tasks exchange information for two purposes. One
purpose is to pass data from one task to another. For
instance, suppose that one task accumulates key8-9

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

MUTUAL EXCLUSION

•

Task A is in the process of reading information from a segment.

ensure that only one task has access to the shared
data at any instant, and that the task having access
cannot be preempted by other tasks desiring access.
This protocol for sharing data is called mutual
exclusion, and providing mutual exclusion is the
function of regions, which are described later in this
chapter.

•

An interrupt occurs and Task B, which has
higher priority than Task A, preempts Task A.

SYNCHRONIZATION

Occasionally, when tasks are running concurrently,
the following kind of situation arises:

•

Task B modifies the contents of the segment
that Task A was in the midst of reading.

•

Task B finishes processing its event and surrenders the processor.

•

Task A resumesreading the segment.

The problem is that Task A might obtain information that is completely invalid. For instance, suppose
the application is air traffic control. Task A is responsible for detecting potential collisions, and Task
B is responsible for updating the Plane Location
Table with the new X- and Y-coordinates of each
plane's location. Unless Task A can obtain exclusive
use of the Plane Location Table, Task B can make
Task A fail to spot a collision.
Here's how it could happen. Task A reads the Xcoordinate of the plane's location and is preempted
by Task B. Task B updates the entry that Task A was
reading, changing both the X- and Y-coordinates of
the plane's location. Task B finishes its function and
surrenders the processor. Task A resumes execution
and reads the new Y-coordinate of the plane's
location. As a direct result of Task B changing the
Plane Location Table while Task A was reading it,
Task A thinks the plane is at old X and new Y.
This problem can be avoided by mutual exclusion. If
Task A can prevent Task B from modifying the table
until after A has finished using it, A can be assured
of valid information. Somehow, Task A must obtain
exclusive use of the table.
Corruption of data can occur in this manner whenever the following three conditions are met:
•

The data is shared between two or more tasks.

•

The tasks sharing the data run concurrently.
(In other words, one of the tasks could possibly preempt another.)

•

At least one of the tasks changes the data.

Whenever all three of these conditions can exist,
special precautions must be taken to protect the
validity of the shared data. The programmer must

As mentioned earlier, tasks are asynchronous.
Nonetheless, occasionally a task must know that a
certain event has occurred before the task starts
running. For instance, suppose that a particular application system requires that Task A cannot run until
after Task B has run. This kind of requirement calls
for synchronizing Task A with Task B.
Application systems can achieve synchronization by
using mailboxes. Before executing either Task A or
Task B, a mailbox must be created. Then Task A invokes the RECEIVE$MESSAGE primitive for that
mailbox. Task A is forced to wait at the mailbox
un til Task B sends a message. This achieves the
desired synchronization.
The intertask coordination supplied by the asp is
flexible and simple to use. Mailboxes and regions
can accommodate a wide variety of situations. A particular application system is not limited to some arbitrary number of mailboxes or regions; it can create
as many as it needs.

Mailboxes
The principal function of mailboxes is to support intertask communication and synchronization. A sending task uses a mailbox to pass a token for an object
to another task. For example, the object might be a
segment containing data needed by the receiving
task.
NOTE: Throughout the remainder of this chapter
we refer to the passing of objects between jobs or between tasks. Be aware that this does not actually
occur, that tokens, not objects, are passed, and that
this means of description is adopted for convenience
only.
MAILBOX QUEUES

Each mailbox has two queues, one for tasks that are
waiting to receive objects, the other for objects that
have been sent by tasks but have not yet been
received. The OSP ensures that waiting tasks receive
objects as soon as they are available. So, at any given
time, at least one of the mailbox's queues is empty.
8-10

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

MAILBOX MECHANICS

HIGH-PERFORMANCE OBJECT QUEUE

When a task sends a token to a mailbox, using the
SEND$MESSAGE primitive, one of two things
happens. If no tasks are waiting at the mailbox, the
object is placed at the rear of the object queue
(which might be empty). Object queues are processed in a first-inlfirst-out (FIFO) manner, so the
object remains in the queue until it makes its way to
the front and is given to a task.

Directly associated with each mailbox is a highperformance object queue. A task, when creating a
mailbox with the CREATE$MAILBOX primitive,
can specify the number of objects this queue can
hold, from 4 to 60. By using this high-performance
object queue, the task can greatly improve the performance of SEND$MESSAGE and RECEIVE$MESSAGE when these primitives actually get or
place objects on the queue. (It has no effect when
tasks are already waiting at the task queue). When
more objects than the high-performance queue can
hold are queued at a mailbox, the objects overflow
into a slower queue whose size is limited only by the
amount of memory in the job containing the
mailbox.

On the other hand, if there are tasks waiting, the
task at the front of the task queue receives the object
and goes either from the asleep state to the ready
state or from the asleep-suspended state to the suspended state.

NOTE: If the receiving task has a higher priority

than the sending task and is not suspended, then the
receiving task preempts the sender and becomes the
running task.

When a task attempts to receive an object from a
mailbox via the RECEIVE$MESSAGE primitive,
and the object queue at the mailbox is not empty,
the task receives the object immediately and remains
ready. However, if there are no objects at the mailbox two things can happen:
If the task, in its request, elects to wait, it is placed in
the mailbox's task queue and is put to sleep. If the
designated waiting period elapses before the. task
gets an object, the task is made ready and receives
an E$TIME exception code.

The high-performance queue obtains its high speed
because the OSP allocates memory space for it when
the mailbox is created. This memory space is permanently allocated to the mailbox, even ifno objects
are queued there. No space is allocated for the overflow portion of the queue until the space is needed to
contain objects. Thus the overflow portion of the
queue is slower.
The user must weigh performance against size when
deciding how large to make the high performance
queue. Specifying a high performance queue that is
too large wastes memory. Conversely, a smaller
queue that is constantly overflowing slows down the
system.
PRIMITIVES FOR MAILBOXES

The following primitives manipulate mailboxes:
If the task is not willing to wait, it remains ready and
immediately receives an E$TIME exception code.

When using the SEND$MESSAGE primitive, a task
has the option of specifying that it wants acknowledgment from the receiving task. Thus, any task using
the RECEIVE$MESSAGE primitive should check
to see if an acknowledgment has been requested.
For details, see the description of the RECEIVE$MESSAGE primitive in Section 8.11.

As stated earlier, the object queue for a mailbox is
processed in a first-in/first-out manner. However,
the task queue of a mailbox can be either firstinlfirst-out or priority-based, with higher-priority
tasks toward the front of the queue. When a task creates a mailbox, the task specifies which kind of task
queue the mailbox is to have.
8-11

•

CREATE$MAILBOX-creates a mailbox
and returns a token for it.

•

DELETE$MAILBOX-deletes a mailbox
from the system.

•

SEND$MESSAGE-sends an object to a
mailbox.

•

RECEIVE$MESSAGE-sends the calling
task to a mailbox for an object; the task has
the option of waiting ifno objects are present.

Regions
A region is an OSP object that tasks can use to guard
a specific collection of shared data such as a table of
data. Each task desiring access to shared data can
wait its turn at the region associated with that data.
When the task currently using the shared data no
210911

THE 801.30 OPERATING SYSTEM FIRMWARE COMPONENT

NOTE: In the following example, the only primitive

longer needs access, it notifies the Operating System
Processor, which then allows the next task to access
the shared data.
The following
noteworthy:

facts

regarding

regions

used to gain access is the RECEIVE$CONTROL
primitive. Tasks using the ACCEPT$CONTROL
primitive cannot deadlock at a region unless they
keep trying endlessly to. accept control.

are

Suppose that two tasks, A (high priority) and B (low
priority), both need access to two collections of
shared data. Call the two collections of data Set I
and Set 2. Access to each set is governed by a region
(Region 1 and Region 2) .

The priority of the task that currently has access to
the shared data may temporarily be raised. This happens automatically whenever the region has a priority queue and the task at the head of the region's
queue has a priority higher than that of the task that
has access. Under such circumstances, the priority of
the task having access is raised to match that of the
task at the head of the queue. When the task having
access surrenders access, its priority automatically
reverts to its original value.

Now suppose that the following events take place in
the order listed:
1) Task B requests access to Set 1 via Region 1.
Access is granted.

2) Before Task B can request access to Set 2, an interrupt occurs and Task A preempts Task B.

Once a task gains access to shared data through a
region, the task cannot be suspended or deleted
until it surrenders access. This characteristic prevents
tasks from tying up shared data.

3) Task A requests access to Set 2 via Region 2.
Access is granted.
4) Task A requests access to Set 1 via Region 1.
Task A must wait because Task B already has access.
5) Task B resumes running and requests access to
Set 2 via Region 2. Task B must wait because Task A
already has access.

When a task gains access through a
region, it must not attempt to suspend or
delete itself. Any attempt to do so will
lock up the region, preventing other tasks
from accessing the data guarded by the
region. In addition, the task will never run
again and its memory will not be returned
to the memory pool. Also, if the task in
the region attempts to delete itself, all
other tasks that later attempt to delete
themselves will be unable to do so.

At this point Task A is waiting for Task B and vice
versa. Tasks A and B are hopelessly deadlocked, and
any other tasks that request access to either set of
data will also become deadlocked.
This type of deadlock situation applies only to systems in which regions are nested. For systems which
must use nested regions, team deadlock can be prevented by adhering to the following rule:
A strict ordering must be applied to all the regions in
a system, and tasks must be written so that they gain
access to these regions according to the specified
order. The precise order is unimportant as long as all
tasks obey it. If this rule is followed consistently, regions can be nested to any depth.

When a region is created, one of two rules must be
specified to determine which waiting task next gains
access to the shared data. One rule is first-in/first-out
(FIFO), and the other is priority.
REGIONS AND DEADLOCK' >

PRIMITIVES FOR REGIONS

A major concern in any multitasking system is avoiding deadlock. Deadlock occurs when one or more
tasks permanently lock each other out of required
resources. The following hypothetical situation illustrates a method for quickly causing deadlock by
using nested regions. An explanation of how to
avoid the illustrated deadlock situation follows the
example.

The following primitives manipulate regions:

8-12

•

ACCEPT$CONTROL
This primitive' allows a task to gain access to
shared data only when access is immediately
available. If a different task already has
access, the requesting task remains ready but
receives an exception ,code.
210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

•

CREATE$REGION
This primitive creates a region and returns a
token for it. One of the parameters passed
during this call specifies the queuing rule
(FIFO or priority.)

•

DELETE$REGION
This primitive deletes a region.

•

RECEIVE$CONTROL
This primitive causes a task to wait at the
region until the task gains access to the
shared data.

•

SEND$CONTROL
This primitive, when issued by a task, frees
the OSP to grant a different task access to the
shared data.

identical in structure to the hierarchy of jobs.
Memory that a job borrows from its parent remains
in the pool of the parent as well as being in the pool
of the child. Such memory, however, is available for
use only by tasks in the child job, and not by tasks in
the parent job. Figure 8-5 illustrates the relationship
between the job and memory hierarchies. In the
figure, the pool sizes shown are actually the maximum sizes of those pools.
Two parameters, pool$min and pool$max, of the
CREATE$JOB primitive, dictate the range of sizes
(in 16-byte paragraphs) of a new job's memory pool.
Initially, the pool size is equal to pool$min, the pool
minimum. Memory allocated to tasks in the job is
still considered to be in the job's pool.

Movement of Memory Between Jobs
8.7 DYNAMIC MEMORY ALLOCATION
Occasionally a task needs more memory than was
initially allocated to its job. By using OSP primitives
for allocating and deallocating memory, tasks can
usually satisfy their memory needs.

Segments
Allocated memory is treated as a collection of
segments. A segment is a contiguous collection of
16-byte paragraphs, with its starting address evenly
divisible by 16. In addition to serving as an address,
the base address functions as a token for the
segment. For each segment, the OSP maintains, as
attributes, the base address, the length in bytes, and
the containing job.

When a task tries to create a segment (or an object
of any other type), and the unallocated part of its
job's pool is not sufficient to satisfy the request, the
OSP tries to borrow more memory from the job's
parent (and then, if necessary, from its parent's
parent, and so on). Such borrowing increases the
pool size of the borrowing job and is thus restricted
by the pool maximum attribute of the borrowing
job. The smallest contiguous piece of memory that a
job may borrow from its parent is a configuration
parameter.
Observe that, if a job has equal pool minimum and
pool maximum attributes, then its pool is fixed at
that common value. This means that the job may
not borrow memory from its parent.

Memory Allocation
When a task needs a segment, it can request one of
the desired length by calling the CREATE$SEGMENT primitive. If enough memory is available,
the OSP returns a token for the segment.
NOTE: The token of a segment can be used as the

base portion of a pointer to the segment. Thus, the
token can be used as a base address (as when writing
a message in the segment) or as an object reference
(as when sending the segment-with-message to a
mailbox). The PLlM-86 SELECTOR data type is especially useful when used to refer to the segment.

Memory Pools
A memory pool is the memory available to a job and
its descendants. Each job has a memory pool. When
a job is created, the memory for its pool is allocated
from the pool of its parent job. Thus, there is effectively a tree-structured hierarchy of memory pools,

The memory pool of a job consists of two classes of
memory: allocated and unallocated. Memory in ajob
is unallocated unless it has been requested, either explicitly or implicitly, by tasks in the job or if it is on
loan to a child job. A task's request for memory is
explicit when it calls the CREATE$SEGMENT
primitive. A request is implicit when the task attempts to create any type of object other than a
segment.
The OSP borrows small amounts of memory from a
job's pool each time a task in that job creates an
object. This memory is needed for bookkeeping
purposes. When the object is deleted, the borrowed
memory is returned to the pool.
When a task no longer needs a segment, it can
return the segment to the unallocated part of the
job's pool by using the DELETE$SEGMENT
primitive. Figure 8-6 shows how memory "moves."

8-13

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

Deadlocks

Primitives for Segments

Under certain circumstances, memory allocation
and the use of some primitives can cause deadlock,
For a description of the deadlock concept and
preventive measures, as well as techniques for eliminating deadlocks, see the iOSP Support Package
Reference Manual.

The OSP provides the following primitives for manipulating segments:
•

CREATE$SEGMENT-creates a segment
and returns a token for it.

•

DELETE$SEGMENT -returns a segment to
the pool from which it was allocated,

JOB A

POOL A

/~

JOB B

POOL

POOL

O@

JOB C

/

JOB 0

Figure 8-5 Comparison of Job and Memory Hierarchies

PARENT JOS'S POOL
CREATESJOB

CREATESSEGMENT
(BORROWING)

CREATESSEGMENT
(NORMAL)
UNALLOCATED
MEMORY

DElETESSEGMENT

ALLOCATED
MEMORY

)

CHILD JOB'S POOL

Figure 8-6 Memory Allocation and Deallocation
8-14

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

8.8 MANAGEMENT OF OBJECTS
Three OSP primitives apply to all objects. These
primitives allow tasks to inquire about an object's
type and to use object directories.

OBJECT TYPES

The GET$TYPE primitive enables a task to present
a token to the OSP and get an object's type code in
return. (Type codes for OSP objects are listed in Section 8.10, description of the GET$TYPE primitive.)

When a task wants to share an object with the other
tasks in a job (not necessarily its own job), its can
use the CATALOG$OBJECT primitive to put the
object in that job's object directory. Typically, the
task that created the object does this.
When using an object directory, a task must present
a token for the job directory. The root job's object
directory, called the root object directory, is special
in that its token is easily accessible. Any task can call
the GET$TASK$TOKENS primitive to obtain a
token for the root job.
PRIMITIVES FOR ANY OBJECTS

This primitive is useful, for example, when a task is
expecting to receive objects of several different
types. By invoking the GET$TYPE primitive, the
task can ascertain the type of object it received.

The following primitives apply to all objects:
•

CATALOG$OBJECT -places a name and an
associated token in an object directory.

•

LOOKUP$OBJECT -accepts a name and returns a token if the OSP can find an entry
with the name in the specified time.

•

GET$TYPE-accepts a token for an object
and returns the object's type code.

USING OBJECT DIRECTORIES

Each job has its own object directory. An entry in an
object directory consists of a token for an object and
the object name. The name contains from one to
twelve characters, where a character is a one-byte
value (from 0 to OFFH). Such a feature is often
needed because some tasks might only know some
objects by their associated names.

Management of Exceptions
The OSP allows operating systems to specify an
error handling procedure for each task. This procedure is called an exception handler.

By using the LOOKUP$OBJECT primitive, a task
can present the name of an object to the OSP, The
OSP consults the object directory corresponding to
the specified job and, if the object has been cataloged
there, returns the token.

EXCEPTION HANDLING
NOTE: In object directories, upper and lower case

The OSP does provides protection from some types
of errors. The concepts involved in the OSP exception handling scheme are condition codes, exception
handlers, and exception modes:

alphabetic characters are treated as being different.
The OSPsees the name as just a string of bytes. It
does not interpret these bytes as ASCII characters.
If the object has not yet been cataloged, and the task
is not willing to wait, the task remains ready and receives an E$TIME exceptional condition. However,
if the task is willing to wait, it is put to sleep; then
there are two possibilities:

•

Condition Codes

Whenever a task invokes a primitive, the
OSP attempts to perform the requested
function. Whether or not the attempt is
successful, the OSP generates a condition code.
This code indicates two things. First, it shows
whether. the primitive succeeded or failed.
Second, in the case of failure, the code, which
is then called an exception code shows which
exception prevented successful completion.

If the designated waiting period elapses before the
task gets its requested token, the task is made ready
and receives an E$TIME exceptional condition.
If the task gets its requested token within the
designated waiting period, it is made ready with no
exceptional condition. This case is possible because
another task can, while the requesting task is
waiting, catalog the appropriate entry in the specified
object directory.

For the sake of flexibility in processing exception codes, they are divided into two
categories. The first category, environmental
8-15

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

exception codes, consists of errors that a task
cannot anticipate. An example of such an
error is insufficient memory. The second
category, programming exception codes, consists of two subcategories:

codes. This means that the code segment of the task must explicitly provide code to process any exceptions
caused by environmental conditions.
The task's exception handler processes
both environmental exception codes
and programming error exception
codes.

Errors Detected by the Processor
The 8086 or 8088 microprocessor
detects several kinds of errors. One of
these, for instance, is an attempted division by zero. Such errors can be
avoided by using good programming
techniques.
Incorrect Invocation of a Primitive
If a task makes an impossible request,
such as trying to SLEEP forever, the
problem is considered a programming
error. This kind of error can usually be
avoided by good programming
techniques.

Table 8-1 lists the condition codes, with their
associated mnemonics and numeric values.
Values not listed are reserved.
•

•

Exception Handlers
An exception handler is a procedure that the
OSP can invoke when a task receives an exception code. The alternative to using exception handlers is to explicitly incorporate in
each task any code needed to process exception codes.
Exception Modes
An exception mode is an attribute of a task.
Once a task is running, it can invoke the
SET$EXCEPTION$HANDLER primitive to
set its exception mode to any of four values.
This value governs the processing of exception codes received by the task. The exception
mode indicates one ofthe following:

No exception handling. This means
that the code segment of the task must
explicitly provide code to process any
exceptions.
The task's exception handler processes
only environmental exception codes.
This means that the code segment of
the task must explicitly provide code
to process any exceptions caused by
programming errors.
The task's exception handler processes
only programming error exception

When control passes to an exception handler,
the errant task is still the running task.

NOTE: The E$INTERRUPT$SATURATION and
the E$INTERRUPT$OVERFLOW condition codes
never· cause control to be passed to an exception
handler. These exceptional conditions must be
handled in-line or not at aiL

In summary, exception handling works as follows.
The OSP generates a condition code for each invocation of each primitive. If the code indicates successful
completion, the OSP detected no problems. If the
code indicates an error, the problem can be processed in either of two ways:
•

Within the code segment of the task that invoked the primitive.

•

By the task's exception handler, which is invoked by the OSP.

The decision as to which way the error is to be dealt
with is a function of the task's exception mode and
the category of the exception code (programming
error or environmental condition).
The actions of a task's error handler can be controlled because the programmer writes the handler.
Consequently, the handler can recover from the
error, merely log the error, delete the task containing the error, warn the operator of the error, or
ignore the error altogether.

ADVANTAGE OF EXCEPTION HANDLING

Exception handling provides an operating system
with several methods of reacting to unusual
conditions. One of these methods, having the OSP
automatically invoke a task's exception handler,
greatly simplifies error processing. The other
method, dealing with some or all unusual conditions
within a task's code segment, allows the user to provide special processing for very unusual
circumstances. The OSP .allows an operating system
to use both methods.

8-16

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

Table 8·1 Conditions and Their Codes
NUMERIC CODE
CATEGORY
MNEMONIC

MEANING

HEX

DECIMAL

The most recent primitive ran
successfully.

OH

0

E$TIME

A time limit (possibly a limit of zero
time) expired without a task's request
being satisfied.

1H

1

E$MEM

There is not sufficient memory
available to satisfy a task's request.

2H

2

E$BUSY

Another task currently has access to
data protected by the specified
region.

3H

3

E$LlMIT

A task attempted on operation which,
if it had been successful, would have
violated an iOSP processor-enforced
limit.

4H

4

E$CONTEXT

A primitive was issued out of context
or the iOSP processor was asked to
perform an impossible operation

5H

5

E$EXIST

A token parameter has a value which
is not a token for an existing object.

6H

6

E$STATE

A task attempted an operation which
would have caused an impossible
transition of a task's state.

7H

7

E$NOT$CONFIGURED

The most recently called primitive is
not in the preset configuraton.

8H

8

E$INTERRUPT$SATURATION

An interrupt task has accumulated
the maximum allowable number of
SIGNAL$INTERRUPT requests.

9H

9

E$INTERRUPT$OVERFLOW

An interrupt task has accumulated
more than the maximum allowable
number of SIGNAL$INTERRUPT
requests.

OAH

10

A task attempted to divide by zero.

8000H

32768

E$OK

Environmental Exceptions

Programmer Errors
E$ZERO$DIVIDE

8-17

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

Table 8-1 Conditions and Their Codes (continued)
NUMERIC CODE
CATEGORY
MNEMONIC

MEANING

HEX

DECIMAL

E$OVERFLOW

An overflow interrupt occurred.

8001H

32769

E$TYPE

A token parameter referred to an
existing object that is not of the
required type.

8002H

32770

E$BOUNDS

An offset parameter is out of a
segment's boundaries.

8003H

32771

E$PARAM

A parameter which is neither a token
nor an offset has invalid value.

8004H

32772

E$BAD$CALL

When you configured your operating
system, you used an OSP diskette
that was designed for a different
version of the 80130 component.

8005H

32773

E$ARRAY$BOUNDS

Hardware or Language has detected
an array overflow.

8006H

32774

E$NDP$ERROR

An 8087 (Numeric Processor
Extension) error has been detected;
the 8087 status information is
contained in a parameter to the
exception handler.

8007H

32775

a significant amount of the processor's time is spent
in such checking, and, if events have not occurred,
the processor's time has been wasted.

CREATING EXCEPTION HANDLERS

For a complete description of exception handler creation and assignment, as well as in-line exception
handling and primitives for exception handlers see
the iOSP Support Package Reference Manual.

Management of Interrupts
The OSP manages interrupts. When an interrupt
occurs, the iOSP processor can schedule a task to
process the interrupt. This method of event detection improves the system performance.

The second method of controlling processing is interrupt processing. In this method, when an event
occurs the processor is literally interrupted. Rather
than executing the next sequential instruction, the
processor executes an interrupt handler, which may
then invoke a task associated specifically with the
detected event.

ADVANTAGES OF INTERRUPT PROCESSING
INTERRUPT PROCESSING

Interrupt processing of external events provides
three benefits for an operating system:

There are two ways that computer systems can
schedule processing associated with detecting and
controlling events in the real world-polling and interrupt processing. Polling is implemented by having
the software periodically check to see if certain
events have occurred. Its major shortcoming is that
8-18

•

Better Performance
Interrupt processing allows the system to
spend all of its time running the tasks that
process events, rather than executing a polling
loop to see if events have occurred.
210911

I

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

•

•

6-55
56-63
64-127
128-183

More Flexibility
Because of the direct correlation between interrupts and tasks, the system can easily be
modified to process different events. The
user simply writes the tasks to process the
new (or old) types of interrupts.

184-223
224-255

Economic Benefits
Because interrupt processing allows the
system to respond to events by means of
modularly coded tasks, a system's code is
more structured and easier to understand.
Modular code is less costly to develop and
maintain, and it can be developed more quickly than unstructured code.

reserved for Intel
external interrupts (PIC master lines)
external interrupts (PIC slave lines)
unused (available to users for software
interrupts)
reserved for Intel
unused (available to users for operating
system extensions)

The interrupt lines, programmable interrupt controller and other hardware related topics are discussed
in Chapter 5, Volume 2 of this set.

INTERRUPT LINES
INTERRUPT MANAGEMENT IN THE OSP

In the discussion that follows, the word "line" refers
directly to a pin on a component. This is synonomous
with the word "level".

An interrupt, signalling the occurrence of an external
event, triggers an implicit "call" to a location specified in a section of memory known as the Interrupt
Vector Table. From there, control is redirected to an
interrupt procedure called an interrupt handler. At
this point, one of two things happens. If handling the
interrupt takes little time and requires no primitives,
other than certain interrupt-related primitives, the
interrupt handler processes the interrupt. Otherwise,
the interrupt handler signals an interrupt task which
deals with the interrupt. After the interrupt has been
serviced, control returns to the ready application
task with highest priority.

External interrupts are funneled through one or
more hardware programmable interrupt controllers
(PICs). The master controller is part of the 80130
component, but additional PICs (such as the Intel
8259A PIC) can be used to obtain additional interrupt lines.
The on-chip PIC that is part of the OSP can manage
interrupts from as many as eight external sources.
However, the OSP also supports an expended (or
cascaded) environJ1lent in which up to seven input
lines of the on-chip PIC (the master interrupt
controller) are each connected to a 8259A PIC
(called a slave interrupt controller). One input line
from the master PIC cannot be attached to a slave
because it must be connected directly to the system
clock.

OSP INTERRUPT MECHANISMS

Three major concepts in OSP interrupt processing
are the Interrupt Vector Table, interrupt lines, and
the ability to enable and disable interrupts.
THE INTERRUPT VECTOR TABLE

The Interrupt Vector Table is composed of 256
entries. The entries are numbered 0 to 255, and the
purpose of each entry is to contain the address of the
first instruction to be executed when the corresponding interrupt occurs.
Some of the entries in the Interrupt Vector Table are
reserved and therefore are not available to be
defined by user tasks. The entries are allocated as
follows:
o
1
2
3
4
5

divide by zero
single step (used by the iSBC 957B package)
non-maskable interrupt (used by the iSBC
957B package)
one byte interrupt instruction (used by the
iSBC 957B package)
interrupt on overflow (used by the hardware)
runtime array bounds error (used by compilers and assembler)

Since each of the slaves can manage eight interrupts,
and as many as seven slaves can be attached to the
master PIC, the OSP can support as many as 56 interrupt lines from external sources. These 56 lines are
in addition to the one master line required for the
system clock.
The interrupt lines of the master PIC and the interrupt lines of the slave 8259A PICs are each assigned
entries to the Interrupt Vector Table, as shown in
Figure 8-7. The master interrupt lines, numbered
MO through M7, correspond to entries 56 through
63 (decimal) in the Interrupt Vector Table. The
slave interrupt lines, numbered xO to x7 (where x
ranges from 0 to 7 and identifies the master line to
which the slave PIC is attached) correspond to entries 64 through 127 (decimal) of the Interrupt
Vector Table. Table 8-2 shows the numbered interrupt lines and their corresponding entries in the Interrupt Vector Table.

8-19

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

./

/'

/

/

/

/
/
I
I
I

SLAVE 1

8259A PIC
LINES

10·17

I
I
I
I

I

/
/
/

80130 PIC

MO
M1
M2
M3
M4
M5
M6

.....

/'

/

---

-SLAVE 3

M7

8259A PIC
LINES

30·37

SLAVE 7

8259A PIC
LINES

70·77

Figure 8-7 80130 On-Chip Master PIC with 8259A Slave PICs
8-20

210911

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

Table 8-2 Interrupt Line Numbers
and Interrupt Vector Numbers
Line Numbers

Vector Table Entry

MO-M7
00-07
10-17
20-27
30-37
40-47
50-57
60-67
70-77

53-63
64-71
72-79
80-87
88-95
96-103
104-111
112-119
120-127

Regarding the second factor, an interrupt handler
should always invoke an interrupt task unless the
handler can service interrupts quickly. This is because an interrupt signal disables all interrupts, and
they remain disabled until the interrupt handler
either services the interrupt or invokes an interrupt
task. Invoking an interrupt task allows higher priority
interrupts (and in some cases, the same priority
interrupts) to be accepted.

For more information about interrupt handlers and
interrupt tasks, consult the iOSP 86 Support Package
Reference Manual.

DISABLING AND ENABLING
INTERRUPT LINES

Occasionally the user may want to prevent signals
from causing an immediate interrupt. For example,
it is desirable to prevent low priority interrupts from
interfering with the servicing of a high priority
interrupt. The OSP provides mechanisms for disabling and enabling interrupts.

PRIMITIVES FOR INTERRUPTS

The following primitives manipulate interrupts:
•

SET$INTERRUPT -Assigns an interrupt
handler and, if desired, an interrupt task to
an interrupt line.

•

RESETS$INTERRUPT -Cancels the assignment made to a line by SET$INTERRUPT
and, if applicable, deletes the interrupt task
for that line.

•

EXIT$INTERRUPT-Used by interrupt handlers to send an end-of-interrupt signal to
hardware.

•

SIGNAL$INTERRUPT - Used by interrupt
handlers to invoke interrupt tasks.

INTERRUPT HANDLERS AND
INTERRUPT TASKS

•

Whether an interrupt handler services an interrupt
line by itself or invokes an interrupt task to service
the interrupt depends on two factors:

WAIT$INTERRUPT -Suspends the calling
interrupt task until it is called into service by
an interrupt handler.

•

ENABLE- Enables an external interrupt line.

•

DISABLE- Disables an external interrupt
line.

•

GET$LEVEL-Returns the highest priority
interrupt line for which an interrupt handler
has started but has not yet finished
processing.

•

ENTER$INTERRUPT -Sets up a previously
designated data segment base address for the
calling interrupt handler.

If a signal is received on a line that is enabled, the
8086 and 8088 microprocessor traf\sfers control to
the address contained in the Interrupt Vector Table
entry that corresponds to the line on which the interrupt occurred.
On the other hand, if a signal is received on a line
that is disabled, the processor will continue running,
uninterrupted, until the interrupt line is again
enabled. Once re-enabled, the interrupt will occur if
the interrupt signal is still active. For more information on interrupt enabling and disabling, see the
iOSP 86 Support Package Reference Manual.

•

the kinds of primitives needed

•

the amount of time required

Regarding the first factor, interrupt handlers can
invoke only the ENTER$INTERRUPT, EXIT$INTERRUPT, GET$LEVEL, DISABLE and SIGNAL$INTERRUPT primitives. If it is necessary to
use other primitives to service the interrupt, an interrupt task can be used in conjunction with the interrupt handler.
8-21

210911

THE80130 OPERATING SYSTEM FIRMWARE COMPONENT

8.9 EXTENDABILITY
The services provided by the OSP are extendable.
The user can create his own primitives and add them
to the operating system without having to modify
any OSP codes. From the standpoint of an application programmer, these customized primitives are
just as much a part of the operating system as are the
primitives provided by the OSP.

NOTE: Another way of extending the OSP is to add
features and/or subsystems of the iRMX 86 Operating System. This is the subject of Section 8.11 of this
chapter.

System Extension or OS extension. From the application programmer's standpoint, an OS extension
appears to be a collection of one or more customized
primitives, no different in style than, say, the primitives for manipulating mailboxes.

Creating an Operating System
Extension
Creating an OS extension involves both writing
several procedures and initializing the Interrupt
Vector Table of the iAPX 86/186 microprocessor.
For detailed treatment of procedures used in operating system extensions see the iOSP 86 Support Package Reference Manual.

Three Ways of Adding Functionality
Whenever more than one job in an application
system requires a function not supplied by the OSP,
the following three methods of adding the needed
function may be used:

1) The function can be written as a procedure and

Primitives Used in Extending the
Operating System
The following primitives are used exclusively by OS
extensions:

placed it ina library by using LIB86. After each job
that requires the function has been compiled,
LINK86 can be used to link the library to the object
module for the job.

•

DISABLE$DELETION
This primitive increases the deletion disabling
depth of an object by one.

•

ENABLE$DELETION
This primitive removes one level of deletion
disabling from an object, reversing the effect
of one DISABLE$DELETION call.

•

SET$EXTENSION
This primitive can be used either to place an
address in a specific entry of the Interrupt
Vector Table or to remove such an entry.

•
The relative advantages and disadvantages of the
three alternatives are summarized in Table 8-3.

SIGNAL$EXCEPTION
This primitive advises a task that an exception
has occurred in an OS extensjon that the task
has called.

Alternative 3 involves extending the operating
system. The procedures that must be added in order
to support the added function are. called an Operating

The uSe of these primitives is covered in detail in the
following section 8.10.

2) The function can be written as a task, and application tasks can invoke the function through a
mailbox-segment interface.

3) The function can be written as a procedure and
added to the operating system. Application programs
then invoke the function by means of a primitive.

8-22

210911

,

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

Table 8-3 Comparison of Techniques for Creating Command Functions
PROCEDURE
LIBRARY

TASK

OS EXTENSION

APPLICATION
PROGRAMMER'S
INTERFACE

SIMPLE

COMPLEX

SIMPLE

RELATIVE
PERFORMANCE

GOOD (for all
functions)

POOR (for quick
functions)
MODERATE (for
slower functions)

MODERATE (for quick
functions)
GOOD (for slower
functions)

SYNCHRONOUS or
ASYNCHRONOUS
CALLS

BOTH

ASYNCHRONOUS
ONLY

BOTH

SYSTEM
PROGRAMMER

NOT REQUIRED

NOT REQUIRED

REQUIRED

DUPLICATE CODE

Difficult to avoid

Easy to avoid

Automatically avoided

POTENTIAL FOR
COSTLY
MAINTENANCE

YES

NO

NO

SUPPORTS NEW
OBJECT TYPES

NO

NO

YES

8.10 OSP PRIMITIVES
This section contains the calling sequences and other
information about the OSP primitives. The descriptions of the primitives are in alphabetical order. Information for each primitive is organized into the
following categories:
•

A brief sketch of the effects of the primitive.

•

The PL/M -86 calling sequence for the
primitive.

•

Definitions of the output parameters, if any.

•

A detailed description of the effects of the
primitive.

•

An example of how the primitive can be used.

•

The condition codes that can result from
using the primitive, with a description of the
possible causes of each exception.

The examples used in this section assume that the
reader is familiar with PLlM-86. In these examples,
the appropriate DECLARE statements are made
first. Before the first of these DECLARE statements
is an INCLUDE statement that declares all of the
primitive calls included in the OSF firmware. For the
sake of simplicity, the examples assume that an established exception handler is to deal with exceptional conditions. Consequently, they do not illustrate inline exception processing.

Additional condition codes can be returned if the
OSF firmware is extended to include parameter validation (see Section 8.9).

Following the individual descriptions of the primitives is a command dictionary, in which the calls are
grouped according to type. The dictionary includes a
short description and the page number of the primitive's complete description in this section.
8-23

210911

ACCEPT$CONTROL

ACCEPT$CONTROL

The ACCEPT$CONTROL primitive requests immediate access to data protected by a region.

CALL RQ$ACCEPT$CONTROL (region, except$ptr);

INPUT PARAMETER

region

A WORD containing a TOKEN for the target region.

OUTPUT PARAMETER

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.

except$ptr

DESCRIPTION

The ACCEPT$CONTROL primitive provides access to data protected by a region if access is immediately available. If
access is not immediately available, the primitive generates the E$BUSY condition code and the calling task remains
ready.

EXAMPLE

,..........................................................................................................................
This example illustrates how the ACCEPT$CONTROL primitive can be used to access data protected
by a region .

........ ............ _._ ......................................................................... ., .e ................ * ............. * ........ ** ................. * ....... ,., ** ................ ** ........ /
$INCLUDE(:F1 :OSXPRM.EXT);
DECLARE TOKEN

r

declares all primitive calls *f

LITERALLY 'SELECTOR';

/* if your 'PLfM compiler does not support this variable
DECLARE region$token
DECLARE priority$queue
DECLARE status

type, declare TOKEN a WORD *f
TOKEN;
literally '1'; f* tasks wait in priority order *f
WORD;

SAMPLE PROCEDURE:
PROCEDURE;

.:}

Typical PLlM-86 Statements

/ *........ _...................................... * ...........................................................................................................

In order to access the data within a region, a task must know the TOKEN for that region. In this example,
the needed TOKEN is known because the calling task creates the region.
_•• e" ..... _.a ••• _•• __ ••• _••••••• _•••••••••••••••••••• _••••••• _e_e ........... __ ................... _••• * ••••• _••••••••••••••••••• /

region$token =

...}

RQ$~REATE$REGION

(priority$q ueue,
@status);

Typical PLlM-86 Statements

8-24

210911

ACCEPT$CONTROL

/*_*** ... **_**_************************,.._.*************************w********************_.***********_*********_*.*._*._ ••• _

At some point in the task, access is needed to the data protected by the region. The calling task then invokes the ACCEPT$CONTROL primitive and obtains access to the data if access is immediately
available.
*_iII •••• _111._ ... _........ 'II"" _.,., *_,., *. *'" **** ** •• ",,., * * * ••• "' .. * * ... * * * ** "'_*. *'" *."'_ *_ illiII • • * ",.iII • • • • • ,., * * * *

CALLRQ$ACCEPT$CONTROL

.:}

*_. '" * * _.*

ill ill

*,., * * •• * ..... * * ... * .... * * ... *.iII /

(region$token,
@status);

Typical PLlM-86 Statements

/******************* ••• *****"'.*************************-_ •• _••••• _•••• _•••••••• * ••• * •• *. __ •• __ •• _•••••• _••• -**-*,.,-* ••• _•••

When the task is ready to relinquish access to the data protected by the region, it invokes the SEND$CONTROL primitive.
**********-**********************************************:iII** •• **********************************************.,.,._ ••

CALLRQ$SEND$CONTROL

..• }

_*.*_ .• I

(@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$BUSY

Another task currently has access to the data.

E$EXIST

The region parameter does not refer to an existing object.

E$TYPE

The region parameter is a TOKEN for an object that is not a region.

8-25

210911

CATALOG$OBJECT

CATALOG$OBJECT
The CATALOG$OBJECT primitive places an entry for an object in an object directory.

CALL RQ$CATALOG$OBJECT (job, object, name, except$ptr);

INPUT PARAMETERS
job

A WORD that indicates where the object is to be cataloged.
•

If zero, the WORD indicates that the object is to be cataloged in the object directory of the job to which the calling task belongs.

•

If not zero, the WORD contains the TOKEN for the job in whose object directory
the object is to be cataloged.

object

A WORD containing a TOKEN for the object to be cataloged.

name

A POINTER to a STRING containing the name under which the object is to be
cataloged. The name itself must not exceed 12 characters in length. Each character
can be a byte consisting of any value from 0 to OFFH.

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.

DESCRIPTION
The CATALOG$OBJECT primitive places an entry for an object in the object directory of a specific job. The entry consists of both a name and a TOKEN for the object. There may be several such entriet? for a single object in a directory,
because the object may have several names. (However, in a given object directory, only one object may be cataloged
under a given name.) If another task is waiting, via the LOOKUP$OBJECT primitive, for the object to be cataloged, that
task is awakened when the entry is cataloged.

EXAMPLE

1············_--_··························· __ ·_-_···-............. _...... _----_ .............. ----.... _..... --_. __ .. _.. _.This example illustrates how the CATALOG$OBJECT primitive can be used to place an entry in an
object directory.
................. '* ..................... '* .. '* .... '* .................................. '* ........ '* ...... '* .. '* '* ........ ** '* ...... '* '* .. '* .... '* ................ '* '* ............. '* ................ '* ........ oil .. "''''''''''" '* .. '* '* '* .... '* '* '* .... /
/* Declares all primitive calls * /

$INCLUDE(:F1 :OSXPRM.EXT);

LITERALLY 'SELECTOR';

DECLARE TOKEN

/* if your PL/M compiler does not support this variable
type, declare TOKEN a WORD * /

TOKEN;
WORD;
TOKEN;
WORD;

DECLARE mbx$token
DECLARE mbx$flags
DECLARE job
DECLARE status

8-26

210911

CATALOG$OBJECT

SAMPLE PROCEDURE:
PROCEDURE;
mbx$flags

job

~

~

0;

/. designates four objects to be queued on the high
performance object queue; designates a firstin/first-out task queue .• /

0;

I" indicates objects to be cataloged into the object
directory of the calling task's job ./

Typical PLlM-86 Statements
/ '* ........ *** ..... * .... ** ....................... ** ................................ ** ** ...................................... * .................. *. *** .......... "' ..................... "' ......................... ..

The calling task creates an object, in this example a mailbox, before cataloging the object's TOKEN.
** •• ,.,* ..... ** •• _••••••••• *** ...... ** •• ** ••• ************.* **.**********_ • .""" ••• ******_**"'*****************«***1t** *.*********** /

mbx$token

~

-:}

(mbx$flags,
@status);

RQ$CREATE$MAILBOX

Typical PLlM-86 Statements

/ **** .................... ** ........... * ........................ **** ..... '* ....... *. *.* ... '11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ** ** ...... ** .... * ................................................. ..

After creating the mailbox, the calling task catalogs the mailbox TOKEN in the object directory of its
own job .
• ** •••••• **.* •• **,.,* •• ***,. ••••• ********* •• ** •• ***** .... "'.***** ••• **** •••• *** ••••• ***.****.**.***** ..... **"'.*****************'* /

CALL RQ$CATALOG$OBJECT

:-}

ijob,
mbx$token,
@(3, 'MBX'),
@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditior\s.

E$CONTEXT

At least one of the following is true:
-

The name being cataloged is already in the designated object directory.

-

The directory's maximum allowable size is O.

E$LlMIT

The designated object directory is full.

E$PARAM

The first BYTE of the STRING pOinted to by the name parameter contains a zero or a value
greater than 12.

8-27

210911

CREATE$JOB

CREATE$JOB
The CREATE$JOB primitive creates a job containing a single task.

job

=

RQ$CREATE$JOB (directory$size, param$obj. pool$min, pool$max, max$objects, max$tasks,
max$priority, except$handler, job$flags, task$priority, start$address, data$seg, stack$ptr,
stack$size, task$flags, except$ptrl;

INPUT PARAMETERS
directory$size

A WORD specifying the maximum allowable number of entries a job can have in its
object directory. The value zero is permitted, for the case where no object directory is
desired. The maximum value for this parameter is OFFOH.

param$obj

A WORD indicating the presence or absence of a parameter object. See Chapter 2 for
an explanation of parameter objects.
•

If zero, it indicates that the new job has no parameter object.

•

If not zero, it contains a valid TOKEN for the new job's parameter object.

pool$min

A WORD which contains the minimum allowable size of the new job's pool, in 16-byte
paragraphs. The pool$min parameter is also the initial size of the new job's pool.
Pool$min should be at least 32 (decimai.llf the stack$ptr parameter has a base value
of 0, pool$min should be at least 32 (decimal) plus the value of stack$size in 16-byte
paragraphs.

pool$max

A WORD which contains the maximum allowable size of the new job's memory in
16-byte paragraphs.

max$objects

A WORD that specifies the maximum number of objects that the created job can own.

max$tasks

max$priority

except$handler

•

If not OFFFFH, it contains the maximum number of objects, created by tasks in the
new job, that can exist at one time.

•

If OFFFFH, it indicates that there is no limit to the number of objects.

A WORD that specifies the maximum number of tasks that can exist simultaneously
in the new job.
•

If not OFFFFH, it contains the maximum number of tasks that can exist simultaneously in the new job.

•

If OFFFFH, it indicates that there is no limit to the number of tasks that tasks in the
new job can create.

A BYTE that sets an upper limit on the priority of the tasks created in the new job.
•

If not zero, it contains the maximu m allowable priority of tasks in the new job.

•

If zero, it indicates that the new job is to inherit the maximum priority attribute of
its parent job.

A POINTER to a structure of the following form:
STRUCTURE(
EXCEPTION$HANDLER$PTR
EXCEPTION$MODE

8-28

POINTER,
BYTE);

210911

CREATE$JOB

I
,'j

t
:~
'I

;j
If exception$handler$ptr is not zero, then it is a POINTER to the first instruction of
the new job's own exception handler. If exception$handler$ptr is zero, the new job's
exception handler is the system default exception handler. In both cases, the exception handler for the new task becomes the default exception handler for the job. The
exception$mode indicates when control is to be passed to the exception handler. It is
encoded as follows:
Value

o
1
2
3

When Control Passes
To Exception Handler
Never
On programmer errors only
On environmental conditions only
On all exceptional conditions

job$flags

A reserved WORD which should be set to 2 (decimal.)

task$priority

A BYTE that controls the priority of the new job's initial task.
•

If not zero, it contains the priority of the new job's initial task.

•

If zero, it indicates that the new job's initial task is to have a priority equal to the
new job's maximum priority attribute.

start$address

A POINTER to the first instruction of the new job's initial task.

data$seg

A WORD that specifies which data segment the new job is to use.

stack$ptr

stack$size

•

If not zero, it contains the base address of the data segment of the new job's initial
task.

•

If zero, it indicates that the new job's initial task assigns its own data segment.
Refer to Chapter 5 for more information about data segment allocation.

A POINTER that specifies the location of the stack for the new job's initial task.
•

If the base portion is not zero, the pOinter points to the base of the user-provided
stack of the new job's initial task.

•

If the base portion is zero, it indicates that the OSP Processor is to allocate a
stack for the new job's initial task. The length of the allocated stack will be equal
to the value of the stack$size parameter.

A WORD containing the size, in bytes, of the stack of the new job's initial task. This
size must be at least 16 (decimal) bytes. The OSP Processor increases specified
values that are not multiples of 16 up to the next (higher) multiple of 16.
The stack size should be at least 300 (decimal) bytes if the new task is going to
invoke primitives. See Chapter 4 for more information about stack space required by
primitives.

task$flags

A WORD containing information that the OSP Processor needs in order to create and
maintain the job's initial task. The bits (where bit 15 is the high order bit) have the following meanings:
Bit
15-1

o

Meaning
Reserved bits which should be set to zero.
If one, the initial task contains floating-point instructions. These instructions require the 8087 Numeric Processor Extension for
execution.
If zero, the initial task does not contain floating-point instructions.

8-29

210911

1
. ,·

,•.

CREATE$JOB

OUTPUT PARAMETERS
job

A WORD containing a TOKEN for the new job.

except$ptr

A POINTER to a WORD toto which the
by the primitive.

asp will

return the condition code generated

DESCRIPTION
The CREATE$JOB primitive creates a job with an initial task and returns a TOKEN for the job. The new job's parent is
the calling task's job. The new job counts as one against the' parent job's object limit. The new task counts as one
against the new job's object and task limits. The new job's resources come from the parent job, as described in Chapter 2. In particular, the max$task and max$objects values are deducted from the creating job's maximum task and
maximum objects attributes, respectively.

EXAMPLE
/ '" '" '" '" '" **" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" "' .. '" "' .. '" '" '" '" '" "' .. '" "' .. "' .. III' '" *,* '" '" '" '" "''' "' ... '" "' .. '" ** "' ... '" ** '" '" '" "' .. '" '" '" '" * "' ...... '" '" '" "' •• "' .. '" '" '" '" ** '" '" "' •• '" "' .. "' ...... "' ... " "' ... '" '" '" ** .... "' .. '" '"

This example illustrates how the CREATE$JOB primitive can be used.
*** ... ** ***** '" '" * .. ******** '" '" '" ** **** ** ** '" '" '" **** ** **.,. '" '" '" *** '" '" '" "''' '" **** *** "' ... '" ** '" ******** **.'" '" '" '" '" **** '" '" *** '" "''' ** *****'" ** ** '" ***_."" /

$INCLUDE(:F1 :OSXPRM.EXT);

I' Declares all primitive calls' f

INITIAL TASK: PROCEDURE EXTERNAL;
END INITIAL_TASK;
DECLARE TOKEN

LITERALLY 'SELECTOR';
!' i.1 yourPLfM compiler does not support this variable
type, declare TOKEN a WORD' f
TOKEN;
WORD;
WORD;
WORD;
WORD;
WORD;
WORD;
BYTE;
POINTER;
WORD;
BYTE;
POINTER;
WORD;
POINTER;
WORD;
WORD;
WORD;

DECLARE job$token
DECLARE directory$size
DECLARE param$obj
DECLARE pool$min
DECLARE pool$max
DECLARE max$objects
DECLARE max$tasks
DECLARE max$priority
DECLARE except$handler
DECLARE job$flags
DECLARE task$priority
DECLARE start$address
DECLARE data$seg
DECLARE stack$pointer
DECLARE stack$size
DECLARE task$flags
DECLARE status

SAMPLE PROCEDURE:
PROCEDURE;
directory$size = 10;
param$obj = 0;
pool$min = 1FFH;
pool$max = OFFFFH;
max$objects = OFFFFH;
max$tasks = OAH;
max$priority = 0;
except$handler = 0;
job$flags = 0;
task$priority = 0;
start$address = @INITIAL_TASK;

I' max 10 entries in object directory' f
!' new job has no parameter object' f
I' min 1 FFHf max OFFFFH 16-byte • f
I'paragraphs in job pool'f
!' no limit to number of objects' f
I' OAH tasks can exist simu Itaneously • f
!' inherit max priority of parent' f
I' use·system default except handler' f
f' no flags set' f
1* set initial task to max priority' f
I' points to first instruction of initial task' f

8-30

210911

CREATE$JOB

r

initial task sets up own data segment */
/* allocate a stack for initial task */
r 512 bytes in stack of initial task */
r no floating-point instructions */

data$seg = 0;
stack$pointer = 0;
stack$size = 512;
task$flags = 0;

-:}

Typical PLlM-86 Statements

1······_·······································_--_··· ............................... **.*** •••••••••••• ***** •••

iI • • • • _ • • • • _ • • •

The calling task creates a job with an initial task labeled INITIAL_TASK .
•••••••••••••••••• **_ ••••••••••••• _.. **_ ............ ** __ .",***********" •• ** •• ,,*"11*** .. ***-******************** ••

job$token = RQ$CREATE$JOB

---}

_*.**.*_*_. __ /

(directory$size,
param$obj,
pool$min,
pool$max,
max$objects,
max$tasks,
max$priority,
except$handler,
job$flags,
task$priority,
start$address,
data$seg,
stack$pointer,
stack$size,
task$flags,
@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$LlMIT

At least one of the following is true:

E$MEM

-

max$objects is larger than the unused portion of the object allotment in the calling task's
job.

-

max$tasks is larger than the unused portion of the task allotment in the calling task's job.

At least one of the following is true:
-

The memory available to the new job is not sufficient to create the job.

-

The memory available to the new job is not sufficient to satisfy the pool$min parameter.

-

The memory available to the new job is not sufficient to create the initial task as specified.

8-31

210911

CREATE$MAILBOX

CREATE$MAILBOX
The CREATE$MAILBOX primitive creates a mailbox.

mailbox

=

RQ$CREATE$MAILBOX (mailbox$flags, except$ptrl;

INPUT PARAMETER
mailbox$flags

A WORD containing information about the new mailbox. The bits (where bit 15 is the
high-order bit) have the following meanings:

Bit

Meaning

15-5

Reserved bits, which should be set to zero.

4-1

A value that, when multiplied by four, specifies the number of objects
that can be queued on the high-performance object queue. Additional
objects are queued on the slower, overflow queue. Four is the minimum
size for the high performance queue; that is, specifying zero or one in
these bits results in a high performance queue that holds four objects.

o

A bit that determines the queuing scheme for the task queue of the
new mailbox, as follows:
Value

o

Queueing Scheme
First-i ntfirst-out
Priority based

OUTPUT PARAMETERS
mailbox

A WORD containing a TOKEN for the new mailbox.

except$ptr

A POINTER to a WORD to which the
the primitive.

asp will

return the condition code generated by

DESCRIPTION
The CREATE$MAILBOX primitive creates a mailbox and returns a TOKEN for it. The new mailbox counts as one
against the object limit of the calling task's job.

EXAMPLE
/ •• - * .. * ** ... * .. * ...... _•• *"' •• _.... ." * .. * ...... * * .. * .. * ............ * .. * ..

-*- ._* . . '* ...... * .. * .................. * ...... ** ........... * .. * .. * .. * * .. ** ............ * ...... * .............. * .. * ........ ..

This example illustrates how the CREATE$MAILBOX primitive can be used.

_._***_ ... ********_**********************'*.********_***.'***************************.'*****'****'***'*.*** ••• w**_.************ /
$INCLUDE(:F1 :OSXPRM.EXT);

t* Declares all primitive calls * t

DECLARE TOKEN

LITERALLY 'SELECTOR';
/* if your PLIM compiler does not support this variable
type, declare TOKEN a WORD * t
TOKEN;
WORD;
WORD;

DECLARE mbx$token
DECLARE mbx$flags
DECLARE status

8-32

210911

CREATE$MAILBOX

SAMPLE PROCEDURE:
PROCEDURE;
mbx$flags

=

I" designates four objects to be queued on the high
performance object queue; designates a firstin/first-out task queue. ", /

0;

Typical PLlM-86 Statements
/ *,. .. ,. ................ **'* .... ,.,. *,. ... ,. ......... * .... ,.,. .......... '* .. * .. *,. ...................... * .. *,. .. ,. .. 111 * ........ ,. .... * '/I"""" **,. .. ,. ........ * .... * * ** ................. * ... **,.,. .... * * * * .. * * ...... ..

The TOKEN mbx$token is returned when the calling task invokes the CREATE$MAILBOX primitive .
• *.****** •• **** •••• *.*.*.***.*.****_.* ••• *** ••• *.*.********************.*****'11******************** •••• ****** ••••••• *.**** /

mbx$token

=

---}

(mbx$flags,
@status);

RQ$CREATE$MAILBOX

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$LlMIT

The requested mailbox would exceed the object limit of the calling task's job.

E$MEM

The memory available to the calling task's job is

8-33

210911

I

I

CREATE$REGION

CREATE$REGION

The CREATE$REGION primitive creates a region.

region

= RQ$CREATE$REGION (region$flags, except$ptr);

INPUT PARAMETER
A WORD that specifies the queueing protocol of the new region. If the low order bit
equals zero, tasks await access in FIFO order. If the low order bit equals one, tasks
await access in priority order. The other bits in the WORD are reserved and should be
set to zero.

region$flags

OUTPUT PARAMETERS

asp will return a TOKEN for the new region.

region

A WORD to which the

except$ptr

A POINTER to a WORD to which the
the primitive.

asp will

return the condition code generated by

DESCRIPTION
The CREATE$REGION primitive creates a region and returns a TOKEN for the region.

EXAMPLE

/ .... '* '* ** .... _.. '" "' .... '* ** - ** '* '* 11 '* '* '* * '* '* ** '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '*.'* '* '* ** '* .. '* '* '* '* '* '* .. '* '* '* '* * '*,. '* '* .. '* '* '* '* '* '* '* '* '* '* '* '" '* ..... '* '* '* '* '* '* '*.* '* '* '* '* '* '* '* '* '* .. '* .. '* '* ** .... '* '* '* '* '*
This example illustrates how the CREATE$REGION primitive can be used .
•• ****_."'.***********"'*******"'**'***********-*****"'******.******.**** •• ** ••• _*********** •• **** •• _***********---'* •• ---- •• *- /

$INCLUDE(:F1 :OSXPRM.EXT);

f* Declares all primitive calls * f

DECLARE TOKEN

LITERALLY 'SELECTOR';
f* if your PLIM compiler does not support this variable
type, declare TOKEN a WORD * f
TOKEN;
LITERALLY '1 '; f* tasks wait in priority order *f
WORD;

DECLARE region$token
DECLARE priority$queue
DECLARE status

SAMPLE PROCEDURE:
PROCEDURE;

-:}

Typical PLlM-86 Statements

/ '* '* '* ** '* '* '* '* '* '* '* '* '* '* '* *** ... '* '* ** '* '* .. '* '* '* *.* '* '* _.- '* ** .**** .. '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* **** '* .. '* '*.* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* '* ** '* '* '* '* '* *** '* '* '* '* '* '* *** '*
The TOKEN region$token is return when the calling task invokes the CREATE$REGION primitive.
******.*****"'.,.,******** •• ********************************************._.***** •• *******************************-**********/

region$token = RQ$CREATE$REGION

(priority$queue,
@status);

8-34

210911

CREATE$REGION

-:}

Typical PL/M-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$L1MIT

The calling task's job has reached its object limit.

E$MEM

The memory pool of the calling task's job does not contain a sufficiently large block to satisfy
the request.

8-35

210911

CREATE$SEGMENT

CREATE$SEGMENT
The CREATE$SEGMENT primitive creates a segment.

segment = RQ$CREATE$SEGMENT (size, except$ptr);

INPUT PARAMETER
A WORD that specifies the size of the new segment.

size

-

If not zero, the WORD contains the size, in bytes, of the requested segment. If the
size parameter is not a multiple of 16, it will be rounded up to the nearest higher
mu Itiple of 16 before the OSP Processor creates the segment.

-

If zero, the WORD indicates that the size of the request is 65536 (64K) bytes.

OUTPUT PARAMETERS
segment

A WORD to which the asp will return a TOKEN for the new segment.

except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
the primitive.

DESCRIPTION
The CREATE$SEGMENT primitive creates a segment and returns the TOKEN for it. The memory for the segment is
taken from the free portion of the memory pool of the calling task's job, unless borrowing from the parent job is both
necessary and possible. The new segment counts as one against the object limit of the calling task's job.
To gain access to the segment, you should base an array or structure on a pointer by setting the base portfon equal to
the segment TOKEN and the offset portion equal to zero. Or, if you have a PLlM-86 compiler that supp0tts the SELECTOR data type, you can accomplish the same thing by setting a variable of type SELECTOR equal to the TOKEN value.

EXAMPLE
/ *.* ....................... '" ** '* .......................... ** ** ................ "** *** ** ............... * ............. *** ** '* ....................... ** ** ................................... flo ** *. ** ........... ..

This example illustrates how the CREATE$SEGMENT primitive can be used.
***-*****************************-****************-*** ****~********* . . ********.*.******.***.""."'****.********* *****-*******/

$INCLUDE(:Fl :OSXPRM.EXT);

1* Declares all primitive calls· f

DECLARE TOKEN

LITERALLY 'SELECTOR';
f· if your PLIM compiler does not support this variable
type, declare TOKEN a WORD· f
TOKEN;
WORD;
WORD;

DECLARE seg$token
DECLARE.size
DECLARE status

SAMPLE PROCEDURE:
PROCEDURE;
size = 64;

-:}

f· designates new segment to contain 64 bytes·f

Typical PLlM-86 Statements

8-36

210911

CREATE$SEGMENT

/ **,.,.. .... _*._,.. * * 11 .... * '* *,. .. * * '* '* '* * III *,.. .. * ... * '* * .. * •• * * * * * * '* * •• * * '* * .. * .. * * .. '* * * * '* * '* * * ..... * .. '* * .................... * ...... * ... * ... *. * .. * ........ * ••• _._ * ... .
The TOKEN seg$token is returned when the calling task invokes the CREATE$SEGMENT primitive .
• *.**********"**************.**********.**.*.******.iI.*._**.* ____ ••• _. _____ ._._ •• ".*_ .... _••••••••••••• "'. __ •••••••••••••••• /

set$token

~

RQ$CREATE$SEGMENT

-:}

(size,
@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$LlMIT

The requested segment would exceed the object limit of the calling task's job.

E$MEM

The memory available to the calling task's job is not sufficient to create the specified
segment.

8-37

210911

I

CREATE$TASK

CREATE$TASK

The CREATE$TASK primitive creates a task.

task

= RQ$CREATE$TASK (priority, start$address, data$seg, stack$ptr, stack$size, task$flags,
except$ptr) ;

INPUT PARAMETERS
priority

A BYTE that specifies the priority of the new task.
•

If not zero, the BYTE contains the priority of the new task. The priority parameter
must not exceed the maximum allowable priority of the calling task's job.

•

If zero, the BYTE indicates that the new task's priority is to equal the maximum allowable priority of the calling task's job.

start$address

A POINTER to the first instruction of the new task.

data$seg

A WORD that specifies the new task's data segment.

stack$ptr

stack$size

•

If not zero, the WORD contains the base address of the new task's data segment.

•

If zero, the WORD indicates that the new task assigns its own data segment. Refer
to Chapter 5 for further information on data segment allocation.

A POI NTER that specifies the

I~cation

of the stack for the new task.

•

If the base portion is not zero, the POINTER pOints to the base of the new task's
stack.

•

If the base portion is zero, the OSP Processor will allocate a stack to the new task.
The length of the stack will be equal to the value of the stack$size parameter.

A WORD containing the size, in bytes, of the new task's stack segment. The staCk
size must be at least 16 bytes. The OSP Processor increases values that are not
multiples of 16 up to the next higher multiple of 16.
The stack size should be at least 300 (decimal) bytes if the new task is going to
invoke OSP primitives. See Chapter 4 for more information about stack size required
by primitives.

task$flags

A WORD containing information that the OSP Processor uses to create and maintain
the task. The bits (where bit 15 is the high-order bit) have the following meanings:

Bit
15-1
o

Meaning
Reserved bits which should be set to zero.
If one, the task contains floating-point instructions. These instructions
require the 8087 Numeric Processor Extension for execution.
If zero, the task does not contain floating-point instructions.

OUTPUT PARAMETERS
task

A WORD in which the OSP will return a TOKEN for the new task.

except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.
.

8-38

210911

CREATE$TASK

DESCRIPTION
The CREATE$TASK primitive creates a task and returns a TOKEN for it. The new task counts as one against the object
and task limits of the calling task's job. Attributes of the new task are initialized upon creation as follows:
•

priority: as specified in the invocation.

•

execution state: ready.

•

suspension depth:

•

containing job: the job that contains the calling task.

•

exception handler: the exception handler of the containing job.

•

exception mode: the exception mode of the containing job.

o.

EXAMPLE
/ ..... '* ......... 'II!""'''''''' 111"""'" "" "' ..... _........ ." "" .......................................... * ........... "" ........... "' .... "' ............ * ...... * ................. * ...... * ... * ... * ... ** ............... 11"''''''''''''' "' .................... ,., ... "' ..................... * ... "' ... "' ... '" * ...

This example illustrates how the CREATE$TASK primitive can be used.
"'**********-****'11**-*******"'***************.*****************************""*****_******11*."'.***********_***** ***********"'. /

$INCLUDE(:F1 :OSXPRM.EXT);

/* Declares all primitive calls */

TASK CODE: PROCEDURE EXTERNAL;
END TASK_CODE;
DECLARE TOKEN

LlTERALLY'SELECTOR';
/* if your PUM compiler does not support this variable
type, declare TOKEN a WORD */
TOKEN;
LlTERALLY'66';
POINTER;
WORD;
POINTER;
LITERALLY '512'; /* new task's stack size is 512 bytes
*/
WORD;
WORD;

DECLARE task$token
DECLARE priority$level$66
DECLARE start$address
DECLARE data$seg
DECLARE stack$pointer
DECLARE stack$size$51 2
DECLARE task$flags
DECLARE status

SAMPLE PROCEDURE:
PROCEDURE;
start$address = @TASK CODE;
data$seg = 0;
stack$pointer = 0;
task$flags = 0;

.:}

/*
/*
/*
/*

first instruction of the new task */
task sets up own data segment */
automatic stack allocation */
designates no floating-point instructions */

Typical PUM-B6 Statements

/ ............ ** ** ............ "' ........... ." ... "' ... "' .. "' ... It"'"",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, "' ........... * ... * ... * '" "' ... *,. ...... "' ............ * .......... * .................. .,. ................. * ... 1<"''''''' * ........................... "' ... ...

The task TASK_CODE is created when the calling task invokes the CREATE$TASK primitive.
****." ** ,, ___ * ______ 'II'" * ** ... "'*_*'" _* __ "'_ '" "__ **_*.,, ** .*-_'11 **_*'" '" ** 11 ... '" '/I ** "" *** ** 'II."'''' 11 ... "'", ****** .. '/I'" '/I ******* ** _* **'" '" '" '" '" '" '" '" '" "'''' '" '" '" '" '" '" '" '" /

8-39

210911

I'',I',·
; '~

CREATE$TASK

task$token = RQ$CREATE$TASK

.:}

(priority$level$66,
start$address,
data$seg,
stack$pointer,
stack$size$512,
task$flags,
@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$LlMIT

The new task would exceed the object limit or the task limit of the calling task's job.

E$MEM

The memory available to the calling task's job is not sufficient to create a task as specified.

8-40

210911

DELETE$MAILBOX

The DELETE$MAILBOX primitive deletes a mailbox.

CALL RQ$DELETE$MAILBOX (mailbox, except$ptr);

INPUT PARAMETER
mailbox

A WORD containing a TOKEN for the mailbox to be deleted.

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the
this primitive.

asp will return

the condition code generated by

DESCRIPTION
The DELETE$MAILBOX primitive deletes the specified mailbox. If any tasks are queued at the mailbox at the moment
of deletion, they are awakened with an E$EXIST exceptional condition. If there is a queue of object TOKENs at the
moment of deletion, the queue is discarded. Deleting the mailbox counts as a credit of one toward the object total of
the containing job.

EXAMPLE
/ '" '* '" "' •• '" '" '" '" '" '"
******.* .... '" '" '" '" ••• '*. '" '" '" '" '" '" '" '" '" '" '" '" ft. '" '" "' ...... * '" '" '" '" '" '" '" '" '" '" '" '" '" "' .. '" '" '" '" '" "' .. '" '" '" '" '" '" '* .. '* '" "' .. '" '" '" '" '* '" '" "'.* ••• '"
This example illustrates how the DELETE$MAILBOX primitive can be used.
11"""".* •• ****.****** ••••••••• * ..... "'*** ••••• ** •••••••••••• •••••• *********.'*****"'***",******************* ••• ******** •• ***_*** •• /
'lit • • '" "' .. "' .. "' .... '" '" "' . . . . . . . _ ..

DECLARE TOKEN

LITERALLY 'SELECTOR';
/* if your PL/M compiler does not support this variable
type, declare TOKEN a WORD * /
TOKEN;
WORD;
WORD;

DECLARE mbx$token
DECLARE mbx$flags
DECLARE status

SAMPLE PROCEDURE:
PROCEDURE;
mbx$flags

~

0;

/* designates four objects to be queued on the high

performance object queue; designates a firstin/first-out task queue. */

-:}

Typical PLlM-86 Statements

/,. '" '" ••• '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" "" '" '" '* '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" **** '" '" '" '" ** '" '" '" '" '" '" "' .... '" '* '" '" '" '" '" '" '" '" '" '" '" '" "' .. '" '" '" '" '" *. '" '"

*.

'* ... '" '" '" "'.* •• '" ** '" '" '" "' ... '" '* '" '" '" '" '" '" '" '" '" '*

In order to delete a mailbox, a task must know the name of the TOKEN for that mailbox. In this example,
the needed TOKEN is known because the calling task creates the mailbox .
••• - ******* "'."" .-- •••••• "' ••••••••••••••••••••• *** •••• * ••• * * '" *. -'" '" '" '" '" '* '" '" '" .*** '" ••• "' •••• * .... ****,.,********* ... * "'''''''''''''-''' '" ** "' •• '" '" "'* '" /

mbx$token ~ RQ$CREATE$MAILBOX

(mbx$flags,
@status);

8-41

210911

I

·DELETE$MAILBOX

-:}

Typical PLlM-86 Statements

/*****.**************-******************************** •• _•• _--_._._ •••• _. __ ._. __ •• _-_ •••••••• _-.-.-.---------_ ••• __ .... _._.

When the mailbox is no longer needed, it may be deleted by any task that knows the TOKEN for the
mailbox.
* •• _1t"' .. "" .. * "" .... _.... * .... * * * .. * * * * .. * "" """" """". * "" * * * * .. "" * * "" "" * * * * •• "" .. * * *."" '" "" * *"" .. "' .. "" •• "" * .... * * * * "" * * * * "" * * "". * "" "". * "" * "". * "" * "" * "" * * * *_ * .. * * * * * * "" .. * * /

(mbx$token,
@status);

CALL RQ$DELETE$MAILBOX

-:}

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$EXIST

Either the mailbox parameter is not a TOKEN for an existing object.

E$TYPE

The mailbox parameter is a TOKEN for an object that is not a mailbox.

8-42

210911

DELETE$REGION

DELETE$REGION

The DELETE$REGION primitive deletes a region.

CALL RQ$DELETE$REGION (region, except$ptr);

INPUT PARAMETER
region

A WORD containing a TOKEN for the region to be deleted.

OUTPUT PARAMETER
A POINTER to a WORD to which the
this primitive.

except$ptr

asp will return the condition code generated by

DESCRIPTION
The DELETE$REGION primitive deletes a region. If a task that has access to data protected by the region requests
that the region be deleted, the task receives an E$CONTEXT exceptional condition. If a task requests deletion while
another task has access, deletion is delayed until access is surrendered. When the region is deleted, any waiting
tasks awaken with an E$EXIST exceptional condition.

EXAMPLE
/ ** ...... ** '* *** ** '* .......................... *** ** ** *** ........ *** ........ **** ................ '* .... '* ** ................ '* '* .. '* ... _.... ** ** ........ '* .. ** ** ........ **,., .. ** .......................... ..

This example illustrates how the DELETE$REGION primitive can be used.

"'_._* ___ ._."'. _____________ •__ ."'. ____ ._ ••. ______ •.• ____ ********_*******."'.********_*******.****_*************_."'.fI ________ /
$INCLUDE(:F1 :OSXPRM.EXT);

/* Declares all primitive calls * /

DECLARE TOKEN

DECLARE region$token

LITERALLY 'SELECTOR';
/* if your PLIM compiler does not support this variable
type, declare TOKEN a WORD * /
TOKEN;

DECLARE priority$queue
DECLARE status

LITERALLY '1 '; /* tasks wait in priority order * /
WORD;

SAMPLE PROCEDURE:
PROCEDURE;

.:}

Typical PLlM-86 Statements

/-*** ••• *************** •• *******************************.*************.**** •••• ****.*********.*.* •• *********.*.-.-._--_ •••

In order to delete a region, a task must know the name of the TOKEN for that region. In this example, the
needed TOKEN is known because the calling task creates the region .
.. ", .. ,..fIo _* '* .. ,. '* .. '* '* '* * '* '* * '* '" '* .. ** '* flo"" * ...... ,. '* .. '* '* .. '* .. '*,. .... '* '* '" '* ... **.

'*. '" * '* '* '* '* * '* '* .. * ... '* .... '* .. '* '* * .. * *,. ** '* '* '* ...... ** '* '* '* '* .. '* .... '* ** '* '*,.,. .... * * '* '* .. '* * ...... '* '* '* /

region$token = RQ$CREATE$REGION

(priority$queue,
@status);

8-43

210911

I

DELETE$REGION

.:}

Typical PLlM-86 Statements

/ .... * ....... _... * ........ _._ ...... * ..... *. flo 'It_ ....... _* .... * ....... _.... l1li * ••• * ..

*._ .... * .................. *"' ........... __ ................. *....................... "' ....... _...... *._ . .

When the region is no longer needed, it may be deleted by any task that knows the TOKEN for the
region .
• *****.'*****_.*****"'*******_********** ••• "'************"'****_."'***********_**.*********'***'*********_.*** ••• ** ••••

(region$token,
@status);

CALL RQ$DELETE$REGION

.•. }

_.It .. _.. _/

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$CONTEXT

The deletion is being requested by a task that currently holds access to data protected by
the region.
.

E$EXIST

The region parameter does not contain a TOKEN for an existing object.

E$TYPE

The region parameter is a TOKEN for an object that is not a region.

8-44

210911

DELETE$SEGMENT

The DELETE$SEGMENT primitive deletes a segment.

CALL RQ$DELETE$SEGMENT (segment, except$ptr);

INPUT PARAMETER
segment

A WORD containing a TOKEN for the segment that is to be deleted.

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the
this primitive.

asp will

return the condition code generated by

DESCRIPTION
The DELETE$SEGMENT primitive returns the specified segment to the memory pool from which it was allocated. The
deleted segment counts as a credit of one toward the object total of the containing job.

EXAMPLE
/ * ...... ** .. **** •• ____ .. ** * ........... 'It. ___ ._ ............... ** ................................................ * .......... 'It""" ** * ............. flo ...................................... 'It ............. "" .... ..

This example illustrates how the DELETE$SEGMENT primitive can be used.
----_._._--_."'._---_. __ .. _---,.._._ •••• _-----------------*********************************************-*********.-._------"'. /

$INCLUDE(:F1 :OSXPRM.EXT);

1* Declares all primitive calls 0 f

DECLARE TOKEN

LITERALLY 'SELECTOR';
1* if your PLIM compiler does not support this variable
type, declare TOKEN a WORD of
TOKEN;
WORD;
WORD;

DECLARE seg$token
DECLARE size
DECLARE status
SAMPLE PROCEDURE:
PROCEDURE;
size = 64;

1* designates new segment to contain 64 bytes

Of

Typical PLlM-86 Statements
/ ** ....................................... _•• _• 'It 'It •

....

* ............. *** .......... ., .............................................. " ........ 'It_" ...................................... ft ........................... 1ft .......... ..

In order to delete a segment, a task must know the name of the TOKEN for that segment. In this
example, the needed TOKEN is known because the calling task creates the segment.
**************************************************.fI******* •• **********«._._******** • .,,*************_.*********_****,*.***fI /

seg$token = RQ$CREATE$SEGMENT

.:}

(size,
@status);

Typical PLfM-86'8tatements

8-45

210911

I

DELETE$SEGMENT

/ ... flo'" * * .. flo * __ .... * __ flo flo * * * * * flo flo * '* ... _'" '" flo ... '" "' ... * 'It ...... * *.

**._ ........... "' ....................................... "' ............... "' ................... * '* .............................. "' ...... '* .............................. * ...... '" * ... * ... "' ...... * '"

flo

When the segment is no longer needed, it may be deleted by any task that knows the TOKEN for the
segment.
**************""************************************fr******_***_*_************""**_*******""******"'*******"''''***_",,,,*fIo ____ "''''_,,, /

(seg$token,
@status);

CALL RQ$DELETE$SEGMENT

---}

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$EXIST

The segment parameter is not a TOKEN for an existing object.

E$TYPE

The segment parameter is a TOKEN for an object that is not a segment.

8-46

210911

DELETE$TASK

DELETE$TASK

The DELETE$TASK primitive deletes a task.

CALL RQ$DELETE$TASK (task, except$ptr);

INPUT PARAMETER
task

A WORD that identifies the task to be deleted.
•

If not zero, the WORD contains a TOKEN for the task that is to be deleted.

•

If zero, the OSP Processor will delete the calling task.

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the
this primitive.

asp will return the condition code generated by

DESCRIPTION
The DELETE$TASK primitive deletes the specified task from the system and from any queues in which the task was
waiting. Deleting the task counts as a credit of one toward the object count of the containing job. It also counts as a
credit of one toward the containing job's task count.
You cannot successfully delete an interrupt task by invoking this primitve. Any attempt to do so will result in an
E$CONTEXT exceptional condition. To delete an interrupt task, invoke the RESET$INTERRUPT primitive.

EXAMPLE
/ •••• _••• _._ ... * ... * * ........ * .. * .. * * .... * ... * ** * ........

_*_ ................................. ***.* ........ ** **,. ...... ** ..... * ... * .................. _.* . *** ***

11 .. ,. ........ """""""

This example illustrates how the DELETE$TASK primitive can be used .
••• ******_*******************_*** •• *********************11*****.***********************.****.******."' ... • •• * .... • __ ••• _._ •••• _/

r

$INCLUDE(:F1 :OSXPRM.EXT);

Declares all primitive calls * /

TASK CODE: PROCEDURE EXTERNAL;
END TASK_CODE;
LITERALLY 'SELECTOR';

DECLARE TOKEN

/* if your PLIM compiler does not support this variable
type, declare TOKEN a WORD * /

DECLARE task$token
DECLARE priority$level$66
DECLARE start$address
DECLARE data$seg
DECLARE stack$pointer
DECLARE stack$size$512

TOKEN;
LITERALLY '66';
POINTER;
WORD;
POINTER;
LITERALLY '512';

r

new task's stack size is 512 bytes

*/

WORD;
WORD;

DECLARE task$flags
DECLARE status

8-47

210911

f

DELETE$TASK

SAMPLE PROCEDURE:
PROCEDURE;

r
r

start$address = @TASK CODE;
data$seg = 0;
stack$pointer = 0;
task$flags = 0;

pOints to first instruction of the new task *1
task sets up own data segment * /
1* automatic stack allocation * /
r indicates no floating-point instructions * /

/ ** .. *,., * ** ............ * .... ** ** ........ * .... ** ........ * .... ** ....... * * .. * .......... ""* ** .... * * ...... ** ............ -_ ............ ** ........................ ** .. '" "' .. ** ** .. * .... ** .. * ........ ** ........ ..

In order to delete a task, a task must know the name of the TOKEN for that task. In this example, the
needed TOKEN is known because the calling task creates the new task (labeled TASK_CODE).
*************************.'***************_***","'*********** •••• * ••• **** •• ***** •• .".*** •••••• ********* ••• *fI*********"'******* /

(priority$level$66,

task$token = RQ$CREATE$TASK
start$add ress,
data$seg,
stack$pointer,
stack$size$512,
task$flags,
@status);

.:}

Typical PLlM-86 Statements

/ * ...... *** .. "' .................................. **

*.-_..... "' . ** ........

* * .......... ** .... 111''''' "' .......... * ........ * ...... ** ...... ** .. * .. * ...................... "' ...... * ................ * .... ." ................ '"

The calling task has created TASK_CODE which is not an interrupt task. When TASK_CODE is no
longer needed, it may be deleted by any task that knows its TOKEN.
_****"'********** •• **w***** •• "'***""*****_*************"'.******** •• ."*** •• **************,,******."'*******,,,*******""""""""*_._""""*_'" /

(task$token,
@status);

CALLRQ$DELETE$TASK

..• }

Typical PL/M-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$CONTEXT

The task parameter is a TOKEN for an interrupt task.

E$EXIST

The task parameter is not a TOKEN for an existing object.

E$TYPE

The task parameter is a TOKEN for an object which is not a task.

8-48

210911

DISABLE

DISABLE

The DISABLE primitive disables an interrupt line.

CALL RQ$DISABLE (line, except$ptr);

INPUT PARAMETER

line

A WORD that specifies an interrupt line encoded as follows (bit 15 is the high-order
bit):
Bits

Value

15-7

0

6-4

first digitof the interrupt line (0-71

3

if one, the line is a master line and bits 6-4 specify the entire line
number
if zero, the line is on a slave interrupt controller and bits 2-0 specify
the second digit of the line

2-0

second digit of the interrupt line (0-71. if bit 3 is zero

OUTPUT PARAMETER

except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive. The calling task must process all exceptional conditions in-line, as
control does not pass to an exception handler.

DESCRIPTION

The DISABLE primitive disables the specified interrupt line. It has no effect on other lines. The line must have an interrupt handler assigned to it.
The line reserved for the system clock should not be disabled. This line is specified during system configuration.
Refer to Chapter 5 for configuration information.

EXAMPLE

/

.............................................................................................-...........................
This example illustrates how the DISABLE primitive can be used to disable an interrupt line .
•• • _•••• * •••• _•• _••••• * ... * ................................ a_ ..................... _........

_.* ........ * ......................* ........... * ................... */

1* Declares all primitive calls .,

$INCLUDE(:F1 :OSXPRM.EXT);
INTERRUPT HANDLER: PROCEDURE EXTERNAL;
END INTERRUPT_HANDLER;

LITERALLY '0000 0000 0111 1000B';
1* specifies master interrupt line 7·'
BYTE;
POINTER;
WORD;
WORD;

DECLARE interrupt$line$7
DECLARE interrupt$task$flag
DECLARE interrupt$handler
DECLARE data$segment
DECLARE status

8-49

210911

i'

I
SAMPLE PROCEDURE:
PROCEDURE;
interrupt$task$flag
data$segment ~ 0;

~

f* indicates no interrupt task on line 7 *f
f* indicates that interrupt handler will load its own data
segment *f

0;

interrupt$handler ~ INTERRUPT$PTR (@INTERRUPT HANDLER);
-f* pOints to first instruction of interrupt handler * f

.:}

Typical PLfM-86 Statements

/". *.. * .... _". '* '* * '* * '* * * * * * ... * * *. flo .. * .. '* '* * ••• '*

'*._.* '* .. '* '* * '* * '* .... '* '* .. '* '* * '* '* * ••• _'* * '* '* *. *" .. '* ... '* '* '* '* * •• _.. '* ..... * '* ..... '* .... '* '* '* .. '* * '* '* '* * .. '* '*._.* .... '" _.* *.

An interrupt line must have an interrupt handler or an interrupt task assigned to it. Invoking the SET$INTERRUPT primitive, the calling task assigns INTERRUPT_HANDLER to interrupt line 7.
**_.*******'*************-********'*************-**************"'**********************."'***'****'***_._"'********_.""."'"."'"."''''. /

{interrupt$line$7,
interrupt$task$flag,
interrupt$handler,
data$segment,
@status);

CALL RQ$SET$INTERRUPT

.:}
/ ... *'* '* *_ '" '* '* * ___ *_

Typical PLlM-86 Statements

*._._ .... _, * '* * *_ ...... * '" '* * * '* .. *_ ... _*" '* '* '* '* * __ "••• '* '* '* '* *_ * •••• '* '* '* * .. *

11''' '* '*. '* It .• '* '*

*_ *"

*._ '* '* .. * "" __ '* '* .. "' ...... *_ *._

111

'* ... '* ... '* *" It" *

The SET$INTERRUPT primitive enabled interrupt line 7. In order to disable line 7, the calling task invokes the DISABLE primitive.
**************"'oIio***""*******"'******""********************** •• ********* .... ***********.************ •• ***_*******_* ••• " •••• .,,"' •• /

CALL RQ$DISABLE

.:}

{interruPt$line$7,
@status);

Typical PLfM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$CONTEXT

The line indicated by the line parameter is already disabled.

E$PARAM

The lin.e parameter is invalid.

8-50

210911

DISABLE$DELETION

DISABLE$DELETION

The DISABLE$DELETION primitive makes an object immune to ordinary
deletion.

CALL RQ$DISABLE$DELETION (object, except$ptr);

INPUT PARAMETER

A WORD containing a TOKEN for the object whose deletion is to be disabled.

object

OUTPUT PARAMETER

A POINTER to a WORD to which the
this primitive.

except$ptr

asp will

return the condition code generated by

DESCRIPTION

The DISABLE$DELETION primitive increases by one the disabling depth of an object, making it immune to deletion. If
a task attempts to delete the object while it is immune, the task sleeps until the immunity is removed. At that time, the
object is deleted and the task is awakened.

NOTE
An attempt to raise an object's disabling depth above 255 causes an E$LlMIT exceptional
condition.

EXAMPLE
/.'* ••••• * .......... '* .. ** *** .. ** '* .. '*.* .. '* ..... * ................. ** ...... * ...................................... *** '* .............. ** .................... ** ............ * ..................... we .......... ..

This example illustrates how the DISABLE$DELETION primitive can be used to make an object immune
to ordinary deletion .
................ .,. ........... ** .......................................... ** * ...................... ." .......... '/II" * ...................... ." * * .............. ** .................... "" .......... '* '* ....................................... /

$INCLUDE(:F1 :OSXPRM.EXT);

f* Declares all primitive calls *f

DECLARE TOKEN

LITERALLY 'SELECTOR';
/* if your PLIM compiler does not support this variable
type, declare TOKEN a WORD * f
TOKEN;
LITERALLY '0';
WORD;

DECLARE task$token
DECLARE calling$task
DECLARE status

SAMPLE PROCEDURE:
PROCEDURE;

-:}

Typical PLfM-86 Statements

/ ...... ******* .... *** ........................ *** ................ "' ... * ..... ** .. ** *. __ * ...... ***** ........................ ** flo .. "" ** ** .. ** *** ................ ** ........ * * .............. 111 .......... ..

In this example the calling task will be the object to become immune to ordinary deletion. The GET$TASK$TOKEN is invoked by the calling task to obtain its own TOKEN.
*********************-******111**********,***************************************._*************************'11'***************/

8-51

210911

DISABLE$DELETION

(calling$task,
@status);

task$token = RQ$GET$TASK$TOKENS

e:}

Typical PLlM-86 Statements

/ ...... *.......... * *..... * •••• * .......................................................................................................*.* ••• * •• * ...................... *.* ........ *
Using its own TOKEN, the calling task invokes the DISABLE$DELETION primitive to increase its own
disabling depth by one. This makes the calling task immune to deletion.
* ....... "' .............. * ....... _........................ *.* ................... * ...... ** ...... * ................................. * ................. " ............................................ 11''''''''''''''''' 'III"""""" _/

CALL RQ$DISABLE$DELETION

e:}

(task$token,
@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional condltions.

E$LlMIT

The object's disabling depth is already 255.

8-52

210911

ENABLE

ENABLE

The ENABLE primitive enables an interrupt line.

CALL RQ$ENABLE (line, except$ptr);

INPUT PARAMETER
line

A WORD that specifies the an interrupt line encoded as follOWS (bit 15 is the highorder bit):

Bits

Value

15-7

a

6-4

first digit of the interrupt line (0-7)

3

if one, the line is a master line and bits 6-4 specify the entire line
number
if zero, the line is on a slave interrupt controller and bits 2-0 specify
the second digit of the line

2-0

second digit of the interrupt line (0-7), if bit 3 is zero

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the
this primitive.

asp will return

the condition code generated by

DESCRIPTION
The ENABLE primitive enables the specified interrupt line. The line must have an interrupt handler assigned to it. A
task must not enable the line associated with the system clock.

EXAMPLE
/ * * flo * * flo flo * _•• flo flo .. fIo .. « '* ... * flo • • " * ••• * ... * ..

*. * *., * * * * '* * * *_., * .. *. * * * ••
*

flo

flo

flo

flo • • • • • •

* .... * ... "' .. '" "' •••• "" •• * .... #I . . . . * ... '" * 'lit .. *

*. '" *. * ..
flo

flo flo

*. '" * ..... ."

This example illustrates how the ENABLE primitive can be used to enable an interrupt line .
•• *** •••••••• **.**** ••••••••••• * •••• * •• *********.* •••• *._**"' •••• ***."'***.* •••• ***** •• ***************.******* •••• _._-_ ... _.- /

r

$INCLUDE(:Fl :OSXPRM.EXT);

Declares all primitive calls * j

INTERRUPT HANDLER: PROCEDURE EXTERNAL;
END INTERRUPT_HANDLER;
LITERALLY '0000 0000 0111 1000B';
j* specifies master interrupt line 7 * j
BYTE;
POINTER;
WORD;
WORD;

DECLARE interrupt$line$7
DECLARE interrupt$task$flag
DECLARE interrupt$handler
DECLARE data$segment
DECLARE status

8-53

210911

I

ENABLE

SAMPLE PROCEDURE:
PROCEDURE;

interrupt$task$flag = 0;
data$segment = 0;

f* indicates no interrupt task on line 7 * f
f* indicates that interrupt handler will load its own data
segment *f
interrupt$handler = INTERRUPT$PTR (@INTERRUPT_HANDLER);
1* pOints to first instruction of interrupt handler * f

.:}

Typical PLfM-86 Statements

/ *. *.* ***** .... ** ** .. ** ...... ** ........ **_ .................... ** ... * ........... * .......... *......... ** ** ... * .................................... ** ................ * ..... * ** ••• * .* •• * ........ ..
An interrupt line must have an interrupt handler or an interrupt task assigned to it. Invoking the SET$INTERRUPT primitive, the calling task assigns INTERRUPT_HANDLER to interrupt line 7 .
.............. * ............ * ........................... ** ........... "' ...... * .................................................... "" * ...... * .......... * ......................... * ...... ** .................... '* ..... * ....... '* lit .... ." .. /

(interrupt$line$7,
interrupt$task$flag,
interrupt$handler,
data$segment,
@status);

CALL RQ$SET$INTERRUPT

.:}

Typical PLfM-86 Statements

/ ......... _.......... * .. *** ** .... * ••• **. ** ...... **** •• * .......... ** .* ........ *** .. *** ............................... *.* ................ * ............ '* ......................................... ..

The SET$INTERRUPT primitive enabled interrupt line 7. In order to illustrate the use of the ENABLE
primitive, interrupt,line 7 must first be disabled. The calling task invokes the DISABLE primitive to disable interrupt line 7 .
.. * ....... * .. * .......................................... * ............................. * ............................... "' ....................... *_ ............................................................................ * ** ...... /

CALL RQ$DISABLE

.:}

(interrupt$line$7,
@status);

Typical PLlM-86 Statements

j************ •• **** •••• *.* •••••••••••••••••••• * ••••••• •••••••••••• * ••••••••••• * •••••••• ** •• * ••••••• **.* •• * •••••••••••• *.*.

When an interrupt line needs to be enabled, a task must invoke the ENABLE primitive.
* •••••••••••••••••••••• *. * ••• * •••• *. * *. * * * ••••••• *. * •••• * •••••••••••••••••••••• * * * * * •• *. * •• *. *. *." •••••••• * *,..,. * *. * * •••• * /

CALL RQ$ENABLE

... }

(interrupt$line$7,
@status);

Typical PLfM-86 Statements

END SAMPLE_PROCEDURE;
CONDITION CODES

E$OK

No exceptional conditions.

E$CONTEXT

At least one of the following is true:

E$PARAM

•

A non-interrupt task tried to enable a line that was already enabled.

~

There is not an interrupt handler assigned to the specified interrupt line.

•

There has been an interrupt overflow on the specified interrupt line.

The line parameter is invalid.

8-54

210911

ENABLE$DELETION

ENABLE$DELETION

The ENABLE$DELETION primitive enables the deletion of objects that have had deletion disabled.

CALL RQ$ENABLE$DELETION (object, except$ptr);

INPUT PARAMETER
object

A WORD containing a TOKEN for the object whose deletion is to be enabled.

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.

DESCRIPTION
The ENABLE$DELETION primitive decreases by one the disabling depth of an object. If there is a pending deletion request against the object, and the ENABLE$DELETION primitive makes the object eligible for deletion, the object is
deleted and the task which made the deletion request is awakened.

EXAMPLE

/ '" '" '" '" '" '" '" "'.,. "''''II '" "' ... '" "' ..... "' •• '" * .. '" '" "' ...... '" '" 111 "' .. '" "'''' '*.,. '" '" '" '" '" '" '" '" '" '" '" '" '" '" "'.it "' ... '" "'. "' .. '" '" '" '" '" '" '" '" "' .. '" '" * '" '" '" "' ... '" "',. '" *.* ... "'.,. .. '" '" '" "' •• '" '" * '" '" '" "'" '" "' ... '" "'.,. '" '" "' ... '" '"

This example illustrates how the ENABLE$DELETION primitive can be used to enable the deletion of a
task that had been deletion disabled.
****** .... ",,,.****** •• ***w**.******.********* •• ******.**.***"'********"'*****************************************_* __ ._. ______ /

$INCLUDE(:F1 :OSXPRM.EXT);

1* Declares all prim itive calls *I

DECLARE TOKEN
DECLARE task$token
DECLARE calling$task
DECLARE status

LlTERALLY'SELECTOR';
TOKEN;
LlTERALLY'O';
WORD;

SAMPLE PROCEDURE:
PROCEDURE;

.:}

Typical PL/M-86 Statements

/ '" '" '" *'" '" '" '" '" '" '" '" '" '" '" __ •• _... '" "' ... '" '" "' ... "' .... '" '" '" '" '" 'fl. '* '" '" '" '" '" '" '" '" '" '" '" '" "'.* '" '" * _•• "' .. '" '" '" '" '" '" '" '" '" '" "' ... '" '" "' .. ,. "'.it '" '" '" *.* '" '" '" "' .. '" '" '" 'lit • • '" * '" '" '" '" '" *. '" '" 'lit '" '" '" '" '" '" '" '" '"
In this example the calling task will be the object to become immune to deletion. The GET$TASK$TOKEN is invoked by the calling task to obtain its own TOKEN.
**********.***.**.** •• * •••••• ***** .... ****.*******.*** .... **.******** •• *.**** ••• ***********.*.**************.***-- ••••••

task$token

.:}

~

RQ$GET$TASK$TOKENS

_*-*- I

(calling$task,
@status);

Typical PLlM-86 Statements

8-55

210911

I

ENABLE$DELETION

/ ................... ** .. ** ............................ ** .. ** ......... _* ..... *** .......... **.*. 111 .... """" • • """""""""''' ** .... ** ** ............ ***** .................................... ** flo .... **

Using its own TOKEN, the calling task invokes the DISABLE$DELETION primitive to increase its own
disabling depth by one. This makes the calling task immune to deletion .
• :IIr**."._****_*************_._.************************._****tr********************************************«r**_ .. "".**."'***** /

CALL RQ$DISABLE$DELETION

-:}

(task$token,
@status);

Typical PLlM-86 Statements

/ ... * ... _... - ** * ........................... ** ...... ** ** ** .......... ** ** ... - _... ** .................... '" * ........ ** ** ••• ** ........... _............. "' .. ** .................................... ** .. ..
In order to allow itself to be deleted, the calling task invokes the ENABLE$DELETION primitive. This
primitive decreases by one the disabling depth of an object. In this example, the object is the calling
task.
********************"'."'***."'**********************************-*********************"'**"'****"'**************************** /

CALL RQ$ENABLE$DELETION

-:}

(task$token,
@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$CONTEXT

The object's deletion is not disabled.

8-56

210911

, ENTER$INTERRUPT

ENTER$INTERRUPT

ENTER$INTERRUPT is used by interrupt handlers to load a previously specilied segment base address into the DS
register.

CALL RQ$ENTER$INTERRUPT (line, except$ptr);

INPUT PARAMETER

line

A WORD specifying an interrupt line that is encoded as follows (bit 15 is the highorder bit):
Bits

Value

15-7

0

6-4

first digit of the interrupt line (0-7)

3

if one, the line is a master line and bits 6-4 specify the entire line
number
if zero, the line is on a slave device and bits 2-0 specify the second
digit of the interrupt line

2-0

second digit of the interrupt line (0-7), if bit 3 is zero

OUTPUT PARAMETER

except$ptr

A POINTER to a WORD to which the asp will return the condition code generated by
this primitive. The calling interrupt handler must process all exceptional conditions
in-line, as control does not pass to an exception handler.

DESCRIPTION

ENTER$INTERRUPT, on behalf of the calling interrupt handler, loads a base address value into the DS register. The
value is what was specified when the interrupt handler was set up by an earlier call to SET$INTERRUPT.
If the handler is gOing to call an interrupt task, ENTER$INTERRUPT allows the handler to place data in the 8086 data
segment that will be used by the interrupt task. This provides a mechanism for the interrupt handler to pass data to the
interrupt task.

EXAMPLE
/ ,., *

*._,.,._ *,.,.,.. * ._ •••• _.,., .. * _.,., _._,., .... _.,.,,., * ••• '* *,., * *,.,. __ • * * .. ** * * * * * * * * * * *,.. .. * ... *,., * * * *._ . * * * * *. * ..

lit

lit. * .. * * * * '"

'lit

*._ * * * '* * * * * * * * * * *,., * * * *

This example illustrates how the ENTER$INTERRUPT primitive can be used to load a segment base address into the data segment register.
*.. * * * *,., * *,., * *- *,.. * *." *,., *,., * * * * '" * '" * * * * * * .. * * * *,., * * ... ." * '" * * * * * * * * * * * * * * .. *,.. * '" '" * * * * .. * * * ... * * *,.." * * * * "' .. * * * * * * ... * * * * * *,., '* * * * .. * * * * * *,., * * * * * * .. * /
$INCLUDE(:Fl :OSXPRM.EXT);

!" Declares all primitive calls * /

DECLARE the$first$word
DECLARE interrupt$line$7

WORD;
LITERALLY '000000000111 tO008';
/* specifies master interrupt line 7 * /
BYTE;
POINTER;
WORD;

DECLARE interrupt$task$flag
DECLARE intrpt$handlr$addrs
DECLARE data$segment

8-57

210911

IENTERSINT.ERRUPT

WORD;
WORD;
POINTER;
LITERALLY 'STRUCTURE (offset WORD, base
WORD)';
1* establishes a structure for overlays *1
PTR$OVERLAY AT (@ds$pointer);
1* using the overlay structure, the base address of the
interrupthandler's data segment is identified *I

DECLARE status
DECLARE interrupt$status
DECLARE ds$pointer
DECLARE PTR$OVERLAY

DECLARE ds$pointer$ovly

INTERRUPT_HANDLER: PROCEDURE INTERRUPT 59 PUBLIC;

-:}
/ ... _* •••

fI. * ......

fl . . . . . . . .

Typical PL/M-86 Statements

fI._"" ..

flfI.

*."' ............. *. '" * ............ * ...........

fI . . . "" • __ ..................... _._ .......................... _._ ............ "' . . . . . . . . . . . . . . . . . . . . _ ...... .

The calling interrupt handler invokes the ENTER$INTERRUPT primitive which loads a base address
value (defined by ds$pointer$ovly.base) into the data segment register.
........ * ................ III<

*.

* "' ......... * * .................... * .......... "' .... * * ...... "' .............. * * * ........... * ........ * .... * ......... '" "' .......... * ... * ............ * '" * .. "' .. * ......... _ ...... "' ..... _ * ...... /

CALL RQ$ENTER$INTERRUPT

(jnterrupt$line$7,
@interrupt$status);
(j nterru pt$statu s);

CALL INLlNE_ERROR_PROCESS

-:}

Typical PLlM-86 Statements

/ .... * ............ fl • • * .......... * ... * ................ _.......... * ..

*. *..... _..........

* .............. * ............ *_ .... fl."""" * * * * .... * ..

fI_. * .. * ......... * ........ * .......... ..

Interrupt handlers that do not invoke interrupt tasks need to invoke the EXIT$INTERRUPT primitive to
send an end-of-interrupt signal to the hardware.
'It • • • • • • _ • • • • • _ . _ • • • • • • • • • • • • • • • • • • • • • • • • •

* ........... _•• *flfI • • • • • • • • • • • • • • • • • • • • • • • _._ • • • • • _ • • • • • • _"' • • • • • • • • • • • • • • • • • • • • • • • • /

CALL RQ$EXIT$INTERRUPT

(jnterrupt$line$7,
@interrupt$status);
(j nterrupt$statu s);

CALL INLINE ERROR PROCESS
END INTERRUPT_HANDLER;INLINE ERROR PROCESS: PROCEDURE(jnterrupt$status);
IF internJPt$status < > E$OK THEN
DO;

-:}

In-line Error Processing PLlM-86 Statements

END;
END INLlNE_ERROR_PROCESS;
SAMPLE PROCEDURE:
PROCEDURE;

ds$pointer

1* a dummy identifier used to pOint to interrupt handier's data segment *I
data$segment = ds$pointer$ovly.base;
1* identifies the base address of the interrupt handler's
data segment *I
intrpt$handlr$adqrs = INTERRUPT$PTR (@INTERRUPT HANDLER);
I*-points to the first instruction of the interrupt handler
*I
interrupt$task$flag = 0;
/* indicates no interrupt task on line 7 */

-:}

=

@the$first$word;

Typical PL/M-86 Statements

8-58

210911

ENTER$INTERRUPT

, ••••••••••• ** ••••••••••••••••••••••••••• ** ••••••••••••••••••••••••••••••••••••••••••••••• _•••••••••••••••••••••••••••••••

By first invoking the SET$INTERRUPT primitive, the calling task sets up an interrupt line .
.................... '*

.*...............-._ . . . .

** ** •••• * ......................................................... '* ................. * ................ ** * ... ** ..... * ................. * ........

(interrupt$line$7,
interrupt$task$flag,
interrupt$handler,
data$segment,
@status);

CALL RQ$SET$INTERRUPT

-:}

*'

Typical PL/M-86 Statements

END SAMPLE_PROCEDURE;

NOTE
Because the OSP initializes the Interrupt Vector Table, you should use the NOINTVECTOR control when you compile your interrupt handlers.

CONDITION CODES

E$OK

No exceptional conditions.

E$CONTEXT

No data segment base address had previously been specified in the call to
SET$INTERRUPT.

E$PARAM

The line parameter is invalid.

8-59

210911

EXIT$INTERRUPT

EXIT$INTERRUPT

The EXIT$INTERRUPT primitive is used by interrupt handlers when they don't invoke interrupt tasks. This primitive
sends an end-of-interrupt·signalto the hardware.

CALL RQ$EXIT$INTERRUPT (line, except$ptr);

INPUT PARAMETER

line

A WORD specifying an interrupt line that is encoded as follows (bit 15 is the highorder bit):
Bits

Value

15-7

0

6-4

first digit of the interrupt line (0-7)

3

if one, the line is a master line and bits 6-4 specify the entire line
number
If zero, the line is on a slave device and bits 2-0 specify the second
digit of the interrupt line

2-0

second digit of the interrupt line (O-7l.lf bit3 is zero

OUTPUT PARAMETER

except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
th)s primitive. The calling interrupt handler must process all exceptional conditions
in-line, as control does not pass to an exception handler.

DESCRIPTION

The EXIT$INTERRUPT primitive sends an end-of-interrupt signal to the hardware. This sets the stage for re-enabling
interrupts. The re-enabling actually occurs when control passes from the interrupt handler to an application task.

EXAMPLE
/ ....................... w..... _._ ................................... * ••••••• _....................... e ••••••• w............................... ..

This example illustrates how the EXIT$INTERRUPT primitive can be used to send an end-of-interrupt
signal to the hardware .
.. ** .................. ** ... * •••• - .-...... ** ........... *•••••••• e .................. ...... *.... * .... * ......................................... ** ............ _._ ........... ** I
~

/* Declares all primitive calls *f

$INCLUDE(:F1 :OSXPRM.EXT);

LITERALLY 'DODO 0000 0111 1000B';

DECLARE interrupt$line$7

f* specifies master interrupt line 7 *f

DECLARE interrupt$task$flag
DECLARE interrupt$handler
DECLARE data$segment
DECLARE status
DECLARE interrupt$status

BYTE;
POINTER;
WORD;
WORD;
WORD;

INTERRUPT_HANDLER: PROCEDURE INTERRUPT 59 PUBLIC;

8-60

210911

EXIT$INTERRUPT

Typical PLtM-86 Statements

/ .............. *. ** ...... ** .. ** .... * ...... ** ... * _••

fIo ...................................

*. ** ................ '* ........................ * ...... *.* ............ * .. * ... '* ........ _._ ........ "' .......... ..

Interrupt handlers that do not invoke interrupt tasks need to invoke the EXIT$INTERRUPT primitive to
send an end-of-interrupt signal to the hardware .

............. _... _.......... _-*---_._ ... _----... _....... _---_ .. _--------------_ ..... "' ......... _........ --._-._ .. *._-•.. _. /
CALL RQ$EXIT$INTERRUPT
IF interrupt$status
DO;

<>

-:}

(interrupt$line$7,
@interrupt$status);

E$OK THEN

In-line Error Processing PLiM-86 Statements

END;
END INLlNE_ERROR_PROCESS;

SAMPLE PROCEDURE:
PROCEDURE;
interrupt$task$flag
data$segment = 0;
interrupt$handler

=

0;

t* indicates no intrpt task on line 7 * /
t* indicates that the interrupt handler will load its own
data segment * t
INTERRUPT$PTR (@INTERRUPT HANDLER);
-t* pOints to the first instruction of the interrupt handler

=

*t

-:}

Typical PLtM-86 Statements

/ .................................... _.................. _..................... ** ........... * ................. * ....... * ... *.* * ••••• _........... *.**. ** .............................. '*

By first invoking the SET$INTERRUPT primitive, the calling task sets up an interrupt line .
..................... '* '* .. '* •• '* "' ......... * .................. '* ...... '* ....... '* ....... '* .. ** .. "' ................... '* .................... '* .... "' ............ *

'* ..... '* ............ '* ....... '* '* .. I

(interrupt$line$7,

CALL RQ$SET$INTERRUPT
interrupt$task$ilag,
interrupt$handler,
data$segment,
@status);

-:}

*. ** ..................... ** .... "' .. * ...

Typical PLiM-86 Statements

END SAMPLE_PROCEDURE;

NOTE
Because the OSP initializes the Interrupt Vector Table, you should use the NOINTVECTOR control when you compile your interrupt handlers.

CONDITION CODES
E$OK

No exceptional conditions.

E$CONTEXT

The SET$INTERRUPT primitive has not been invoked for the specified line.

E$PARAM

The line parameter is invalid.

8-61

210911

I

I

GET$EXCEPTION$HANDLER

GET$EXCEPTION$HANDLER

The GET$EXCEPTION$HANDLER primitive returns information about the calling task's exception handler.

CALL RQ$GET$EXCEPTION$HANDLER (exception$info$ptr, except$ptr);

OUTPUT PARAMETERS
exception$info$ptr

A POINTER to a structure of the following form:
STRUCTURE (
EXCEPTION$HANDLER$OFFSET
EXCEPTlON$HANDLER$BASE
EXCEPTlON$MODE

WORD,
WORD,
BYTE);

Where, after the call,
•

exception$handler$offset contains the offset of the first instruction of the exception handler.

•

exception$handler$base contains a base for the segment containing the first instruction of the exception handler.

•

exception$mode contains an encoded indication of the calling task's curren! exception mode. The value is interpreted as follows:

Value

o
1
2
3
except$ptr

When to Pass Control
to Exception Handler
Never
On programmer errors only
On environmental conditions only
On all exceptional conditons

A POINTER to a WORD to which the
this primitive.

asp will

return the condition code generated by

DESCRIPTION
The GET$EXCEPTION$HANDLER primitive returns both the address of the calling task's exception handler and the
current value of the task's exception mode.

EXAMPLE
/ •••• _. __ ._ ....... * .. "'''' .... * _. __ * ••• _. "''''''' .. 'It'" "'''''''._ ...... * * ............ * .... * .............. 'Ii * .... "'''' ........ "'''' "'''' "'''' .... "'''' ....... * ...... * .... * ........ * .... * ...... * * .... * * .. * * .... *

This example illustrates how the GET$EXCEPTION$HANDLER primitive can be used to return information abo.ut the calling task'(:l exception handler.
**********_**************** •• *****_*******'IiI'*********************************************,.,*******_************ ___ ••• _•••• _/

$INCLUDE(:F1 :OSXPRM.EXT);

/* Declares all primitive calls *f

DECLARE x$handler STRUCTURE

(x$handler$offset WORD,

DECLARE status

8-62

x$handler$base

WORD,

x$mode
WORD;

BYTE);

210911

GET$EXCEPTION$HANDLER

SAMPLE PROCEDURE:
PROCEDURE;

-:}

Typical PLlM-86 Statements

/ •• * * * *,.. *.* ._ •• **,.. **,.. *,.. w•• ,.. *.,... _._,.. *,...,..,...,.. *,...,.. •• ,..,..,.. *,.. *,...,..,...,...*,.. ... _........... * ....... * ..... * ...... ,.. .. "' ..... ,.. ............ ,.. .. ,..,.. * .. * ....... ,.. .. ,.. .... ,..,.. .. ,..,..,..

The address of the calling task's exception handler and the value of the task's exception mode (which
specifies when to pass control to the exception handler) are both returned when the calling task invokes
the GET$EXCEPTlON$HANDLER primitive.
** •••• *** ••••• *** •• * ••••••• * •• *****.**** ..... ******.** •• *.********************.""*.*.****iI***"*********_***_***._._* ________ /

CALL RQ$GET$EXCEPTION$HANDLER

-:}

(@x$handler,
@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

8-63

210911

GET$LEVEL

GET$LEVEL
The GET$LEVEL primitive returns the number of the highest priority interrupt line being serviced.

line

=

RQ$GET$LEVEL (except$ptr);

OUTPUT PARAMETERS
line

A WORD whose value is interpreted as follows (bit 15 is the high-order bit):
Bits

Value

15-8

ignore

7

if zero, some line is being serviced and bits 6-0 are significant
if one, no line is being servicedand bits 6-0 are not significant

6-4
3

first digit of the interrupt line (0-7)
if one, the line is a master line and bits 6-4 specify the entire line
number
if zero, the line is on a slave device and bits 2-0 specify the second
digit

2-0

second digit of the interrupt line (0-7), if bit 3 is zero

A POINTER to a WORD to which the asp will return the condition code generated by
this primitive. The calling task must process all exceptional conditions in-line, as
control does not pass to an exception handler.

except$ptr

DESCRIPTION
The GET$LEVEL primitive returns to the calling task the highest priority (numerically lowest) line which an interrupt
handler has started servicing but has not yet finished. To interpret the returned line number with more ease, strip
away unwanted one bits by logically ANDing the returned value with OOFFH.

EXAMPLE

,.**........

** •••••••• ****** ••••••• ***.******.****** ••

*.-*-_. __ ._ •.. -_._._---._.-.. -.-_.-.... -.-_._.---_._ . -_._.*. __ ._._--

This example illustrates how the GET$LEVEL primitive can be used .
• '* '* '* *** '* * '* '* '* .. *." *

*.- * ** * .. * *-- **. ** *.- * '" * * * * * * * *

'*." * '* * * * '* * * * * * '* * * * * * '* .. * '* .. * * * '* * * * '* '* * '* '* * '* * * * '* '* * *

'*.,. '* * '* '* * '* '* * * '* * * * * * * '* '* * '* * '* * * * * * * /

$INCLUDE(:F1 :OSXPRM.EXT);

t* Declares all primitive calls * t

DECLARE interrupt$line
DECLARE status

WORD;
WORD;

SAMPLE PROCEDURE:
PROCEDURE;

-:}

Typical PLtM-86 Statements

8-64

210911

GET$LEVEL

/ .. * .......... * * * ..... * *

*._ * .... ***., .... ** "'., .................................. * .. * ........................ * •••• * •• * * * .. * .... * .......... * .... * **.* .............. * .....

flo .. """"""

* ........ *** .. ..

The GET$LEVEL primitive returns to the calling task the number of the highest interrupt line being
serviced .
••• ** ••• ** ........ ** •••• ***.*******.*********** .. *************** •• ****.*** •• **** •••••• ****** •••• _*** •• **.************ ••• **** /

(@status);

interrupt$line = RQ$GET$LEVEL

e:}

Typical PL/M-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

8-65

210911

GET$TASK$TOKENS

GET$TASK$TOKENS
The GET$TASK$TOKENS primitive returns the TOKEN requested by the calling task.

token

RQ$GET$TASK$TOKENS (selection, except$ptr);

=

INPUT PARAMETER
A BYTE that tells the asp Processor what information is desired. Encoded as follows:

selection

Value

o

Object for which a Token is Requested

The calling task.
The calling task's job.

2

The parameter object of the calling task's job.

3

The root job.

OUTPUT PARAMETERS
token

A WORD to which the asp will return the requested TOKEN.

except$ptr

A POINTER to a WORD to which the
this primitive.

asp will

return the condition code generated by

DESCRIPTION
The GET$TASK$TOKENS primitive returns a TOKEN for either the calling task, the calling task's job, the parameter
object of the calling task's job, or the root job, depending on the encoded request.

EXAMPLE
/ .................. ** .................... *** ...................................... *** .. **** .... ** .... ** ...................................................................... * •••• * ...................... * .. ..

This example illustrates how the GET$TASK$TOKENS primitive can be used to return the TOKEN
requested by the calling task .
.. "" ........................................ ** .......................................................... ** ............................................................. _................ "" ..................... _........ * .. * .............. /

Declares all primitive calls Of

$INCLUDE(:Fl :OSXPRM.EXT);

fO

DECLARE TOKEN

LITERALLY 'SELECTOR';
1* if your PLfM compiler does not support this variable
type, declare TOKEN a WORD °f
TOKEN;
LITERALLY '0';
WORD;

DECLARE task$token
DECLARE calling$task
DECLARE status
SAMPLE PROCEDURE:
PROCEDURE;

-:}

Typical PLlM-86 Statements

8-66

210911

GET$TASK$TOKENS

/ .................. ** ........ **.* ......................... * .. * ** .. * ** ****** * ..................... * .................................. * .............. * ......................

_.* ............................ .

By setting the selection parameter to zero, the GET$TASK$TOKENS primitive will return a TOKEN for
the calling task.
*** ••• *.* ........ * .. ** * ••• ** * ........... __ ••• _............ *** •• **.It ****** ••• '" *.**** .....

task$token

= RQ$GET$TASK$TOKENS

.:}

_*._ " _. ___ •*** ... _* •••• ___ * ••• _. __ •••• *** /

(calling$task,
@status);

Typical PUM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$PARAM

The selection parameter is greater than 3 .

•

8-67

210911

GET$TYPE

GET$TYPE

The GET$TYPE primitive returns the encoded type of an object.

type$code

=

RQ$GET$TYPE (object, except$ptr);

INPUT PARAMETER

object

A WORD containing the TOKEN for an object.

OUTPUT PARAMETERS

A WORD to which the OSP will return the encoded type ot the specified object. The
types for OSP objects are encoded as follows:

type$code

Value

1
2

3
4
5
6

except$ptr

Type

job
task
mailbox
not used by the OSP
region
segment

A POINTER to a WORD to which the OSP will return the condition code generated by
this prim itive.

DESCRIPTION

The GET$TYPE primitive returns the type code for an object.

EXAMPLE
/ ........ ** .......... *. *** .. _. ** ...... *** .................... _._ ** _......... *............... * .............. *** .......... ** ** .................... ** ....................... * 11 ....

*._.* . . **

fI'

This example illustrates how the GET$TYPE primitive can be used to return the encoded type of an
object.
*.* •• *.*************.**w******.** •• **"' ••• ************************************** •• ***_***.* ••• ***** ••••• ****._flflflflfI.""* ____ /

$INCLUDE(:F1 :OSXPRM.EXT);

1* Declares all primitive caTls *1

DECLARE TOKEN
DECLARE type$code
DECLARE mbx$token
DECLARE calling$tasks$job
DECLARE wait$forever
DECLARE object$token
DECLARE response
DECLARE status

LITERALLY 'SELECTOR';
WORD;
TOKEN;
LITERALLY '0';
LlTERALLY'OFFFFH';
TOKEN;
TOKEN;
WORD;

SAMPLE PROCEDURE:
PROCEDURE;

-:}

Typical PL/M-86 Statements

8-68

210911

GET$TYPE

I
,I

/ .................... '* ............ '* .... * ....................... _._ .................. ., ........

'II._ ..........

fIo" ..

* flo .............. * ........ it • • _ .................. * •• * .................... ** .. * ................... ..

In order to invoke the GET$TYPE primitive, the calling task must have the TOKEN for an object. In this
example, the calling task invokes the LOOKUP$OBJECT primitive and then the RECEIVE$MESSAGE
primitive to receive the TOKEN for an object of unknown type (object$token).
........ *.*.*:1''''' *****« .. ." ........ ** _._. __ ._ ..... ***** ••• _____ .'II" *** ...... ***"' ... ** *.* _•••• _•• _............. ,.*.*.* •• *.* ** ...... * ........... /

mbx$token

~

RQ$LOOKUP$OBJECT

-:}
/ .... ** .................... III ...... "

(calling$tasks$job,
@(3:MBX'),
wait$forever,
@status);

Typical PLlM-86 Statements

......

** * ......... * ...................................................................................................................................* .................................... ..

The RECEIVE$MESSAGE primitive returns object$token to the calling task after the calling task invoked LOOKUP$OBJECT to receive the TOKEN for the mailbox named 'MBX'. 'MBX' had been predesignated as the mailbox another task would use to send an object.
*****.****** •••• *****.**lI*******************W*********." ••• ____ •••• __ ••••••• _ ••••••• ___ ••••• _._. ___ ._._._ •••••••• ** ••••••• /
~

object$token

-:}
/

RQ$RECEIVE$MESSAGE

(mbx$token,
wait$forever,
@response,
@status);

Typical PL/M-86 Statements

.........................................................................................................................
'

Using the type code returned by the GET$TYPE primitive, the calling task can determine if the object is
a job, a task, a mailbox, a region, or a segment.
*.* •••••• _•• _•• - •• _-------*********-*-***************** ••• **.******-******--**-_._ •• _* •••• **.**** ••••••• _-*-.**-* •• _._*.* I

type$code

~

RQ$GET$TYPE

(object$token,
@status);

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$EXIST

The object parameter is not a TOKEN for an existing
object.

8-69

210911

I

LOOKUP$OBJECT

LOOKUP$OBJECT

The LOOKUP$OBJECT primitive returns a TOKEN for a cataloged object.

object = RQ$LOOKUP$OBJECT Oob, name, time$limit, except$ptrl;

INPUT PARAMETERS

job

A WORD indicating the object directory to be searched.
•

If not zero, the WORD contains a TOKEN for the jOb whose object directory is to
be searched.

•

If zero, the object directory to be searched is that of the calling task's job.

name

A POINTER to a STRING containing the name under which the object is cataloged.
During the lookup operation, upper and lower case letters are treated as being
different.

time$limit

A WORD indicating the task's willingness to wait.
•

If zero, the WORD indicates that the calling task is not willing to wait.

•

If OFFFFH, the WORD indicates that the task will wait as long as is necessary.

•

If between 0 and OFFFFH, the WORD indicates the number of clock intervals that
the task is willing to wait. The length of a clock interval is a configuration option.
Refer to Chapter 5 for further information.

OUTPUT PARAMETERS

object

A WORD containing the requested TOKEN.

except$ptr

A POINTER to a WORD to which the OSP will return the condition code for this
primitive.

DESCRIPTION

The LOOKUP$OBJECT primitive returns the TOKEN for the specified object after searching for its name in the specified object directory. Because it is possible that the object is not cataloged at the time of the call, the calling task has
the option of waiting, either indefinitely or for a specific period of time, for another task to catalog the object.

EXAMPLE
/ ...... * .. * * .. ** ...... ** ...... * .... **. * ...... * .. * •• _.... * * ....

*. ** ..... *

* * "' ...

*_.- * * * *,.. * •• - '* .... * * * .. * ._.--.- *. * * * *.. * ._ ... * * * *...... * *.. * ... *. * .. * *.. *** *. *
*

This example illustrates how the LOOKUP$OBJECT primitive can be used to return a TOKEN for a cataloged object.
* ... ** *_ * * *." .. * * ...... * * * .. * .. * .... '1/ * .... * .... '* .. * ........................ * '* .... * .......................... '* .... * ........ * flo .......... * .............. ** .... * .............. '* .... * ...... * .......... ,. ........... /

$INCLUDE(:Fl :OSXPRM.EXT);

/* Declares all primitive calls * /

DECLARE TOKEN
DECLARE mbx$token
DECLARE calling$tasks$job
DECLARE wait$forever
DECLARE status

LITERALLY 'SELECTOR';
TOKEN;
LITERALLY '0';
LlTERALLY'OFFFFH';
WORD;

8-70

210911

LOOKUP$OBJECT

SAMPLE PROCEDURE:
PROCEDURE;

.:}

Typical PLlM-86 Statements

/ .......... * .......... * .......................................................... * .. "' .. *« .............. * ...................................... *. "' ... - _. * ......... _ ................ * ....... -- --._.- .............. '"
In this example, the calling task invokes LOOKUP$OBJECT in order to search the object directory of
the calling task's job for an object with the name 'MBX' .
••••••• •••••• "' __ ....... '" * •••• 11 • • • • • • • • • '" • • • • * '/I • • • _ . . . _ .. 'II" "' .. * ,,_* • __ • ___ * '" '" * __ .. * ... * *_ * * '" __ * __ .... _fIo __ " * __ *. __ •••• _... '* ..... _fIo __ fIo __ * .. /
mbx$token

~

... }

RQ$LOOKUP$OBJECT

(calling$tasks$job,
@(3.'MBX').
wait$forever,
@status);

Typical PL/M-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$CONTEXT

The specified job has an object directory of size O.

E$EXIST

The name was found, but the cataloged object has a null (zero) TOKEN.

E$LlMIT

The specified object directory is full and the object being looked-up has not yet been
cataloged.

E$PARAM

The first BYTE of the STRING pOinted to by the name parameter contains a zero or a value
greater than 12.

E$TIME

One of the following is true:
•

The calling task indicated its willingness to wait a certain amount of time, then waited
without satisfaction.

•

The task was not willing to wait, and the entry indicated by the name parameter is not in
the specified object directory.

8-71

210911

,

RECEIVE$CONTROL

RECEIVESCONTROL

The RECEIVE$CONTROL primitive allows the calling task to gain access to data protected by a region.

CALL RQ$RECEIVE$CONTROL (region, except$ptr);

INPUT PARAMETER

region

A WORD containing a TOKEN for the region protecting the data to which the calling
task wants access.

OUTPUT PARAMETER

except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.

DESCRIPTION

The RECEIVE$CONTROL primitive requests access to data protected by a region. If no task currently has access,
entry is immediate. If another task currently has access, the calling task is placed in the region's task queue and goes
to sleep. The task remains asleep until it gains access to the data.

If the region has a priority-based task queue, the OSP boosts the priority of the task currently having access, if
necessary, to match that of the task at the head of the queue. See Chapter 2 for a discussion of how regions affect task
priority.

EXAMPLE

*.

/ ~ .. ** ............ *** *** *** ** ***** .. ** .. **._ ......... ** .. ** .. ** *** *** ** .. ** ...... *.*. * ..... * ............ ** ... * ...... * .... ** ***** ............. **** .. ** ••• * .. ..

This example illustrates how the RECEIVE$CONTROL primitive can be used to gain access to data protected by a region .
... flo

.*._ ....... ***.*** •••••••••••• "" ......................... * ................. /

**._ .... **** •••••••• ** ••• ***.** .............. _••• _

$INCLUDE(:F1 :OSXPRM".EXT);

/* Declares all primitive calls */

DECLARE TOKEN
DECLARE region$token
DECLARE priority$queue
DECLARE status

LITERALLY 'SELECTOR';
TOKEN;
LITERALLY '1'; /* tasks wait in priority order * /
WORD;

SAMPLE PROCEDURE:
PROCEDURE;

... }

Typical PLlM-86 Statements

/ .................. ** ........ *** * .......... * ....... * ... * ...... *** .............. * •• *.* .................................................................... ** .................... '*

In order to access the data within a region, a task must know the name of the TOKEN for that region. In
this example, the needed TOKEN is known because the calling task creates the region.
** _.lIt .............. ,. * ... *"'* ••••• "' ••••••••••• **.** ••••• *** •••••••• *** •••• **.** ....................................... _. _•••••••• /

region$token

=

RQ$CREATE$REGION

(priority$queue,
@status);

. 8-72

210911

RECEIVE$CONTROL

Typical PLlM-86 Statements
/ ....... * •• *....... *... * ...... *

.*... * ....... * .. * *. * •••• _........ "" * ..... _...... *** .. * .......... * .... ** ................................ ** .............. ** ........................................ * ..... * '*

When access to the data protected by a region is needed, the calling task may invoke the RECEIVE$CONTROL primitive .
• **.*** •••• ***.** ••• "" ••••••• *** •••• ** ••• "' ••••• *.** •••• * ...... * ••••• "' ••••• *** ••••• *** ••••••• "" ..... *****"" •• **** ••• ***.*.*** •• **/

CALL RQ$RECEIVE$CONTROL

.:}

(region$token, @status);

Typical PL/M-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$CONTEXT

The region parameter refers to a region already accessed by the calling task.

E$EXIST

The region parameter does not contain a TOKEN for an existing object.

E$TYPE

The region parameter is a TOKEN for an object that is not a region.

210911

RECEIVE$MESSAGE

RECEIVE$MESSAGE

The RECEIVE$MESSAGE primitive queues the calling task at a mailbox, where it can wait for an object TOKEN to be
returned.

object = RQ$RECEIVE$MESSAGE (mailbox, time$limit, response$ptr, except$ptrl;

INPUT PARAMETERS
mailbox

A WORD containing a TOKEN for the mailbox at which the calling task expects to receive an object TOKEN.

time$limit

A WORD which,
•

if zero, indicates that the calling task is not willing to wait.

•

if OFFFFH, indicates that the task will wait as long as is necessary.

•

if between 0 and OFFFFH, indicates the number of clock intervals that the task is
willing to wait. The length of a clock interval is configurable. Refer to Chapter 5
for further information.

OUTPUT PARAMETERS
object

A WORD containing the TOKEN for the object being received.

response$ptr

A POINTER to a WORD to which the

asp returns a value. The returned word,

•

if not zero, contains a TOKEN for the mailbox to which the receiving task is to
send a response.

•

if zero, indicates that no response is expected by the sending task.

The response$ptr points to a location for the sending task to use. If you specify a constant value
for response$ptr, be careful to ensure that the value does not conflict with system requirements.

except$ptr

A POINTER to a WORD to which the
this primitive.

asp will

return the condition code generated by

DESCRIPTION
The RECEIVE$MESSAGE primitive causes the calling task either to get the TOKEN for an object or to wait for the
TOKEN in the task queue of the specified mailbox. If the object qUeue at the mailbox is not empty, then the calling task
immediately gets the TOKEN at the head of the queue and remains ready. Otherwise, the calling task goes into the
task queue of the mailbox and goes to sleep, unless the task is not willing to wait. In the latter case, or if the task's waiting period elapses without a TOKEN arriving, the task is awakened with an E$TIME exceptional condition.
It is possible that the TOKEN returned by RECEIVE$MESSAGE is a TOKEN for an object that has already been
deleted. To verify that the TOKEN is valid, the receiving task can invoke the GET$TYPE primitive. However, you can
avoid receiving an invalid TOKEN by adhering to proper programming practices.
One such practice is for the sending task to request a response from the receiving task and not delete the object until
it gets a response. When the receiving task finishes with the object, it sends a response, the nature of which must be
determined by the writers of the two tasks, to the response mailbox. When the sending task gets this response, it can
then delete the original object if it so desires.

8-74

210911

RECEIVE$MESSAGE

EXAMPLE
/ ........ ***** .................. ** ...... *** * ..................... * ............ ** .......... * .......................................... _.- .......... - ...... *.* ....................... _••••• ,.

This example illustrates how the RECEIVE$MESSAGE primitive can be used to receive a message
segment.
** ................ ** ••••••••••••• ** •••••••• '* ............ **** •• *. * ..... ***** ***** .....

it._ ...... "'' .*.* .... **.* .... **.* *** .......... "' .......... _/

$INCLUDE(:F1 :OSXPRM.EXT);

1* Declares all primitive calls· I

DECLARE TOKEN
DECLARE mbx$token
DECLARE calling$tasks$job
DECLARE wait$forever
DECLARE seg$token
DECLARE response
DECLARE status

LITERALLY 'SELECTOR';
TOKEN;
LITERALLY '0';
LlTERALLY'OFFFFH';
WORD;
WORD;
WORD;

SAMPLE PROCEDURE:
PROCEDURE;

-:}

Typical PL/M-86 Statements

/ ... * ............................................... * ........... *** ........... * ........ *** .. ** ............... it . . . . . . . . . . . . . . . . . . . . . . . . '* ........................................................................ ..

In this example the calling task looks up the TOKEN for the mailbox prior to invoking the RECEIVE$MESSAGE primitive .
........... _........ '* 11 "' ................. * ................ "' .. * ... '/II ............................. "' ....................... '* ............ '* ............................ ." ...................................................................I

mbx$token ~ RQ$LOOKUP$OBJECT
@(3,'MBX'),
wait$forever,
@status);

-:}
/ .... * _._ * .. * *

(call i ng$tasks$job,

Typical PLlM-86 Statements

_*._ *_. * * .. * • .,. * ..........

'It . . . . . . . . . .

* ........ ** .. * * ... _•• _......

*._ ...... * .. * .................. _

flo ...

* ........ * flo * * * _... * * ...... __ * ..... * .. * .. * .................... '/I

Knowing the TOKEN for the mailbox, the calling task can wait for a message from this mailbox by invoking the RECEIVE$MESSAGE primitive.
******** ••• ****_********_****"'****_*********_****._***._*********.*.'*.,,**_********************** •• *** ••• w*.** __ '111 _ _ _ _ _ _ "' _ _ /

seg$token ~ RQ$RECEIVE$MESSAGE
wait$forever,
@response,
@status);

-:}

(mbx$token,

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;
CONDITION CODES
E$OK

No exceptional conditions.

E$EXIST

The mailbox was deleted while the task was waiting.

E$TIME

One of the following is true:
-

The calling task was not willing to wait and there was not a TOKEN available.

-

The task waited in the task queue, and its designated waiting period elapsed before the
task got the desired TOKEN.

8-75

210911

RESET$INTERRUPT

RESET$INTERRUPT

The RESET$INTERRUPT primitive cancels the assignment of an interrupt handler to an interrupt line.

CALL RQ$RESET$INTERRUPT (line, excepl$ptr);

INPUT PARAMETER
line

A WORD specifying an interrupt line that is encoded as follOWS (bit 15 is the highorder bit):
Bits

Value

15-7

0

6-4

first digit of the interrupt line (0-7)

3

if one, the line is a master line and bits 6-4 specify the entire line
number
if zero, the line is on a slave device and bits 2-0 specify the second
digit of the interrupt line

2-0

second digit of the interrupt line (0-7), if bit 3 is zero

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.

DESCRIPTION
The RESET$INTERRUPT primitive cancels the assignment of the current interrupt handler to the specified interrupt
line. If an interrupt task had also been assigned to the line, the interrupt task is deleted. RESET$INTERRUPT also disables the line.
The line reserved for the system clock should not be reset and is a configuration option. Refer to the Chapter 5 for further information.

EXAMPLE

/ "' .................. ,., ........ * ...... * * ......... * ..... * ........ * * ...... '" ** .. '" '" "' ... '" "' ... "' .. '" '" **

"'_*.*. '" '" '" "'* '" '" '" '" '" '" '" '" "' .. '" '" '" '" '" '" "',., '" '" '" '" '" '" '" '" '" "' .. '" '" '" "'. "' ...... _._* '" "' •• "'. '" * '" '" '" '" '" '" '" '" '"

l1li "' .. '"

This example illustrates how the RESET$INTERRUPT primitive can be used to cancel the assignment
of an interrupt handler to an interrupt line.
***********-*"''''*******'11'***.*************'************_ •• _****_"'*******************************"'***********.* •.************* /

$INCLUDE(:Fl :OSXPRM.EXT);

I' Declares all primitive calls * /

DECLARE TOKEN
DECLARE task$token
DECLARE priority$level$66
DECLARE start$address
DECLARE data$segment
DECLARE stack$pointer
DECLARE stack$size$512

LITERALLY 'SELECTOR';
TOKEN;
LITERALLY '66';
POINTER;
WORD;
POINTER;
LITERALLY '512'; /* new task's stack size is 512 bytes
*/

8-76

210911

RESET$INTERRUPT

DECLARE task$flags
DECLARE interrupt$line$7

WORD;
LITERALLY '0000 0000 0111 1000B';
f* specifies master interrupt line 7 * f
BYTE;
POINTER;
WORD;
WORD;

DECLARE interrupt$task$flag
DECLARE intrpt$handlr$addrs
DECLARE interrupt$status
DECLARE status
INTERRUPT_TASK: PROCEDURE PUBLIC;

interrupt$task$flag = 001 H;
/* indicates that calling task is to be interrupt task *f
data$segment = 0;
f* use own data segment * f
intrpt$handlr$addrs = INTERRUPT$PTR ( @INTERRUPT_HANDLER);
/* pOints to the first instruction of the interrupt handler

/... -*- **••••• *

* .... *. * ... * * •• *.* ••••• * ......... * .... * ................ * ... * ... * .................................. * ............... * * * • __ ._ •• *. * ... * ...... * ...... * ... * ...... * * ......... * * * * ... * * ........ * ...

The first primitive in this example, SET$INTERRUPT, makes the calling task (INTERRUPT TASK) the
interrupt task for the interrupt line.
_•••• _•••••••• _._ •••••••• _._. __ •••••••••••••• _ .......... _....... _._ ••• *

CALL RQ$SET$INTERRUPT

.*. ___ ._._ ._ ...... _." . "' .. _. _..........

w__

w_

.*.

* ** ... ** ** ** /

(interrupt$line$7,
interrupt$task$flag,
intrpt$handlr$addrs,
data$segment,
@interrupt$status);

/ ..................... - ................................. * .............. * .... *.* ................. ." .. *.*." ........................................................... * ....................................... ...
The second primitive, WAIT$INTERRUPT, is used by the interrupt task to signal its readiness to service
an interrupt.
_••••• _._._._._._ ... _* ....................... _* __ e •• ____ ...... ___ * ... '/1''''''

CALL RQ$WAIT$INTERRUPT

... }

*. "' .. **** ................ *._

** •••• ___ •• **

*._ . . * ••• __ ._ •• _.... * ...... /

(interrupt$line$7;
@interrupt$status);

Typical PLlM-86 Statements

/ ...... '** ••• *'* '*'* ••••••• '* ••• '*'* '* ••••••••• '* •••••••• '* * * * *. * * •••••••••••• **. '* '*. '*. '* •• '*. '*. '* '*. '* '* '* •• '* '*. '* '* '*. '* '* '*'* '* '*. '* '* * •• '*- '*-- - - '* - - - _.

When the interrupt task invokes the RESET$INTERRUPT primitive, the assignment of the current interrupt handler to interrupt line 7 is canceled and, because an interrupt task has also been assigned to the
line, the interrupt task is deleted .
••••• * •• * '*. - _••••••• '* •••• '* ••••••••••••• _•••••••••• '* •••• '* •••• '* •••••••••••••• '*. * '*. '*. * '* '* ••• *. * * '*'* '* '*'* '*. * * * •••••• '* '* '* * '* '* * * * * * * * /

CALL RQ$RE;SET$INTERRUPT

(interrupt$line$7,
@interrupt$status);

END INTERRUPT_TASK;

SAMPLE PROCEDURE:
PROCEDURE;
start$address = @INTERRUPT TASK;
stack$pointer = 0;
task$flags = 0;
data$segment = 0;

.:}

f*
f*
f*
/*

1 st instruction of interrupt task * f
automatic stack allocation * f
indicates no floating-point instructions * f
use own data segment *f

Typical PLfM-86 Statements

8-77

210911

RESET$INTERRUPT

/************* •• *************-*******_.***************-_ •••••••••••••••••••• _•• _••• _.- •••• - ........ _._._--_._.**************

In this example the SAMPLE_PROCEDURE is needed to create the task labeled INTERRUPT_TASK.
... _...... * * ................................. "' ...................................... IiI!"""""""''''''''''''''''''''''''''' * * .. * * .................................. * ............................................... * .............. /

task$token = RQ$CREATE$TASK

... }

(priority$level$66,
start$address,
data$segment,
stack$poi nter,
stack$size$512,
task$flags,
@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES

E$OK

No exceptional conditions.

E$CONTEXT

There is not an interrupt handler assigned to the specified interrupt line.

E$PARAM

The line parameter is invalid.

8-78

210911

RESUME$TASK

RESUME$TASK

'I
The RESUME$TASK primitive decreases by one the suspension depth of a task.

CALL RQ$RESUME$TASK (task, except$ptr);

INPUT PARAMETER
task

A WORD containing a TOKEN for the task whose suspension depth is to be
decremented.

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the
this primitive.

asp will

return the condition code generated by

DESCRIPTION
The RESUME$TASK primitive decreases by one the suspension depth of the specified non-interrupt task. The task
should be in either the suspended or asleep-suspended state, so its suspension depth should be at least one. If the
suspension depth is still positive after being decremented, the state of the task is not changed. If the depth becomes
zero, and the task is in the suspended state, then it is placed in the ready state. If the depth becomes zero, and the
task is in the asleep-suspended state, then it is placed in the asleep state.

EXAMPLE
/ .. * ****._.,., ......... _. **** .. ** .............. * ....... *** ....... _............ * ................... ** .......... * ................... ** .............. ** .............. _'It ..... ., .................... ** .......... ."

This example illustrates how the RESUME$TASK primitive can be used to decrease by one the suspension depth of a task.
*********************************."._****-********************************************.*****************.'***************** /

$INCLUDE(:F1 :OSXPRM.EXT);

/* Declares all primitive calls '/

TASK CODE: PROCEDURE EXTERNAL;
END TASK_CODE;
DECLARE TOKEN
DECLARE task$token

LITERALLY 'SELECTOR';
TOKEN;

DECLARE priority$level$200
DECLARE start$address
DECLARE data$seg
DECLARE stack$pointer
DECLARE stack$size$512

LITERALLY '200';
POINTER;
WORD;
POINTER;
LITERALLY '512'; /* new task's stack size is 512 bytes
'/
WORD;
WORD;

DECLARE task$flags
DECLARE status

SAMPLE PROCEDURE:
PROCEDURE;
start$address = @TASK CODE;
data$seg = 0;
stack$pointer = 0;
task$flags = 0;

/' first instruction of the new task '/
/* task sets up own data seg '/
/* automatic stack allocation '/
/* indicates no floating-point instructions '/

8-79

210911

,

RESUME$TASK

.:}
/ * ...

Typical PL/M-86 Statements

_._e. *** ...... ** ** ** .......... ** ....... ** '* _'It ............

'It .............

* •• _•• _*_ ..................................... _.............. * ..... *.....

*._ ........ _........... '* •• '* ..

In this example the calling task creates a non-interrupt task and suspends that task before invoking the
RESUME$TASK primitive .
........................................... _................................................... '* ............... * ............ ** .................................

task$token

~

RQ$CREATE$TASK

.:}

*._ ..................................................................../

(priority$level$200,
start$address
data$seg
stack$pointer,
stack$size$512,
task$flags,
@status);

Typical PLlM-86 Statements

.......................................... _........................................... _........... -_ ........................................... -.................................................. .

/ ...... _

After creating the task, the calling task invokes SUSPEND$TASK. This primitive increases by one the
suspension depth of the new task (TASK_CODE).
............ '* _......................... '* ............................................ '* ........ * .............................. '* .... III ........ "" '* .................................................................. '* .... _......... /

(task$token,
@status);

CALLRQ$SUSPEND$TASK

.:}

Typical PL/M-86 Statements

/ ....................................... __ ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• *. * * * * *. * * •••••••• *
Using the TOKEN for the suspended the task (TASK_CODE)' the calling task invokes RESUME$TASK
to decrease by the one the suspension depth of TASK_CODE.
*
* *. * * * * * * •••••••••••••••• 'III • • • • 'III • • • • • • 'III,
* * *. *••• * •••• * * ••••••••••••••• *
'III. 'III • • • • • • • 'III. 'III • • • • • • • • • • • 'III • • • • 'III • • • • • • • • • • 'III.

CALL RQ$RESUME$TASK

'III • • • • 'III.

'III.

(task$token,
@status);

END SAMPLE_PROCEDURE;

CONDITION CODES

E$OK

No exceptional conditions.

E$STATE

The task indicated by the task parameter was not suspended when the call was made.

8-80

210911

SEND$CONTROL

The SEND$CONTROL primitive allows a task to surrender access to data protected by a region.

CALL RQ$SEND$CONTROL (except$ptrl;

OUTPUT PARAMETER

except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.

DESCRIPTION

When a task finishes using data protected by a region, the task invokes the SEND$CONTROL primitive to surrender
access. If the task is using more than one set of data, each of which is protected by a region, the SEND$CONTROL
primitive surrenders the most recently obtained access. When access is surrendered, the OSP Processor allows the
next task in line to gain access.
If a task invoking SEND$CONTROL has had its priority boosted while it had access through a region, its priority is restored when it relinquishes the access.

EXAMPLE

/ •••• ** •• _._._._._ ..... * ._ ........ * .. * •• '* .................................... _e __ ...... ** ......... _._ ........ ** •••• * .......... _._ ............. '*.* ........ .

This example illustrates how the SEND$CONTROL primitive can be used to surrender access to data
protected by a region .
...................................... ." .................... ** ........ '* ... *.* ...............................................................a. * ......... ** ... fIo .......... '* ....... * ....................... ** '* * ........... /

$INCLUDE(:FI :OSXPRM.EXT);

/* Declares all primitive calls *1

DECLARE TOKEN
DECLARE region$token
DECLARE priority$queue
DECLARE status

LITERALLY 'SELECTOR';
WORD;
LITERALLY 'I'; 1* tasks wait in priority order *1
WORD;

-:}

Typical PL/M-86 Statements

SAMPLE PROCEDURE:
PROCEDURE;

/ .............. '* '* .. *. '*.* '* •• '* .. '* ... * ................... - ............................ * '* ........... * ................ * ......

*.-•. *. _.-.. *.......... * ..... ..

In order to access the data within a region, a task must know the TOKEN for that region. In this example,
the needed TOKEN is known because the calling task creates the region .
• * ...... * .... * ......... _...... * .............. _. __ ...................... * .................... * ......................... _.................. * ....... *_ ... * .. ** ...................... ** ...... /

region$token

-:}

=

RQ$CREATE$REGION

(priority$q ueue,
@status);

Typical PL/M-86 Statements

8-81

210911

I

SEND$CONTROl

·1

/ ........ *** .... *** ** .................. ** **** .... *** ***** ... * *** ........ **** .................... * ...... **.* ................... ***.* ........ ** ......... * .................................. *** ..

When access to the data protected by a region is needed, the calling task may invoke the RECEIVE$CONTROL primitive .
.. ** .................... "" "' .................................................... * .. * .................. * ........ "" ...... ** ............................................... * ............. ** ............................................ * .. /

CALL RQ$RECEIVE$CONTROL

.:}

(region$token,
@status);

Typical PL/M-86 Statements

/ ..... * ....... - ........... ***.* ............... * ................................ *.* ...... *** .......... *. *.* *** ... * ................................ **** .. **** .. *.* ............................ ** ** ..

When a task finishes using data protected by a region, the task invokes the SEND$CONTROL primitive
to surrender access .
....................... ** ................... ** ........................................................... ** ................................................................................................................................I

CALLRQ$SEND$CONTROL

.:}

(@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES

E$OK

No exceptional conditions.

E$CONTEXT

A task invoking the SEND$CONTROL primitive did not have access to data protected by any
region.

8-82

210911

SEND$MESSAGE

SEND$MESSAGE

The SEND$MESSAGE primitive sends an object TOKEN to a mailbox.

CALL RQ$SEND$MESSAGE (mailbox, object, response, except$ptr);

INPUT PARAMETERS

mailbox

A WORD containing a TOKEN for the mailbox to which an object TOKEN is to be sent.

object

A WORD containing an object TOKEN that is to be sent.

response

AWORDthat,
•

if not zero, contains a TOKEN for the desired response mailbox.

•

if zero, indicates that no response is requested.

OUTPUT PARAMETER

except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.

DESCRIPTION

The SEND$MESSAGE primitive sends the specified object TOKEN to the specified mailbox. If there are tasks in the
task queue at that mailbox, the task at the head of the queue is awakened and is given the TOKEN. Otherwise, the
object TOKEN is placed at the tail of the object queue of the mailbox. The sending task has the option of specifying a
mailbox at which it will wait for a response from the task that receives the object. The nature of the response must be
agreed upon by the writers of the two tasks.

EXAMPLE
/ .. ** *** .... '*.* ... * ** .. ***.*

*._ ........... * •• *.**** ....... ** ...... ***** ............ ** .................... ** ...................... ** ......... *** .... ** ........ ** ** ............................... .. ..
~

This example illustrates how the SEND$MESSAGE primitive can be used to send a segment TOKEN to
a mailbox .
.. *** ........ ** ............ _.....................

*._ ..................... * .............. * ................ * ........... ** .. It""'''''''''''''''''''''''''''''''' •• ''''''''''' ** .................... ** ............... '* ............................. I

$INCLUDE(:Fl :OSXPRM.EXT);

/* Declares all primitive calls */

DECLARE TOKEN
DECLARE seg$token
DECLARE size
DECLARE mbx$token
DECLARE mbx$flags
DECLARE no$response
DECLARE status
DECLARE job

LITERALLY 'SELECTOR';
TOKEN;
WORD;
TOKEN;
WORD;
LITERALLY '0';
WORD;
WORD;

SAMPLE PROCEDURE:
PROCEDURE;

size = 64;
mbx$flags = 0;

I' designates new segment to contain 64 bytes */
/* designates four objects to be queued on the high
performance object queue; designates a firstin/first-out task queue. */
/* indicates objects to be cataloged into the object
directory of the calling task's job */

job=O;

8-83

210911

, SEND.$MESSAGE

-:}
/

Typical PL/M-86 Statements

__ . _ ...... __ . . . . . . . . . . . . . . . . . . . _ • • • __ .. _._ ................ _ . . . . _ . _ . _ ............ "' ........ __ ......................... _ ...... __ .... _ . . . ___ . _ ............... _ . . . . . . . . 'It __ ............. _ ......... ..

The calling task creates a segment and a mailbox and catalogs the mailbox TOKEN. The calling task
then uses the TOKENs for both objects to send a message .
........ *........ '" * * .......... "" ................................................................ "" ........ *.......................................... * ........................ * ................ _'It ........ * .. __ ...... __ .. '* ............ /
seg$token

=

RQ$CREATE$SEGMENT

mbx$token = RQ$CREATE$MAILBOX

/ .... 111 ..

(size,
@status);
(mbx$fiags,
@status);

_'It_ .......... ___ ........ _....................... _.... _... 'It ..................................... *............... *_ *. __ * ........ _............................. _........ _............ _....... __ •• _* ..
It is not mandatory for the calling task to catalog the mailbox TOKEN in order to send a message. It is
necessary, however, to catalog the mailbox TOKEN if another task is to receive the message .

• _************ ...... ***************._*******************,***************************.*.* •• **************'''1''**. ____ ._. ____ ._. __ /

CALL RQ$CATALOG$OBJECT

-:}

Oob,
mbx$token,
@(3,'MBX'),
@status);

Typical PL/M-86 Statements

/ -------------_._--_._._-********************************************************.******************************************

The calling task invokes the SEND$MESSAGE primitive to send the TOKEN for the segment to the
specified mailbox.
************************************************************************************************************************* /

CALLRQ$SEND$MESSAGE

-:}

(mbx$token,
seg$token,
no$response,
@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$MEM

The high performance queue is full and there is not sufficient memory in the job containing
the mailbox for the OSP Processor to do the housekeeping that supports a send message
operation.

8-84

210911

SET$EXCEPTION$HANDLER

t

I

SET$EXCEPTION$HANDLER

The SET$EXCEPTION$HANDLER primitive assigns an exception handler to the calling task.

I

CALL RQ$SET$EXCEPTION$HANDLER (exception$info$ptr, except$ptr);

INPUT PARAMETER

exception$info$ptr

A POINTER to a structure of the following form:
STRUCTURE(
EXCEPTION$HANDLER$OFFSET
EXCEPTION$HANDLER$BASE
EXCEPTION$MODE

WORD,
WORD,
BYTE);

Where:
•

exception$handler$offset contains the offset of the first instruction of the exception handler.

•

exception$handler$base contains the base of the 8086 segment containing the
first instruction of the exception handler.

•

exception$mode specifies the calling task's exception mode. The value is encoded as follows:

Value

o
1
2
3

When to Pass Control
To Exception Handler

Never
On programmer errors only
On environmental conditions only
On all exceptional conditions

If exception$handler$offset and exception$handler$base both contain zeros, the exception handler of the calling task's parent job is assigned.

OUTPUT PARAMETER

except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.

DESCRIPTION

The SET$EXCEPTION$HANDLER primitive enables a task to set its exception handler and exception mode attributes.

EXAMPLE

/*._-.•.......•

* *.* •• *. '" "'. **** '" ** ................ * * ..... *** .. ** .............. '" **.* * ** flo * ............. fIo .................... "' .. "' .. * ... '* .................. * .................... ..

This example illustrates how the SET$EXCEPTION$HANDLER primitive can be used to assign an exception handler to the calling task .
• _•••••••••• _. ____ • __ ......................... __ ••••••••• *.* •••• ***."'.*********'**_.****_**"'._**************.'It ... ************* /

8-85

210911

SET$EXCEPTION$HANDLER

$INCLUDE(:F1 :OSXPRM.EXT);

/* Declares all primitive calls */

EXCEPTION HANDLER: PROCEDURE EXTERNAL;
END EXCEPTION_HANDLER;
DECLAREX$HANDLER$STRUCTURE

LITERALLY 'STRUCTURE offset WORD,
base WORD,
mode BYTE)';
/* establishes a structure for exception handlers */

DECLARE x$handler

X$HANDLER$STRUCTURE;
/* using the exception handler structure, the pointer to
the old exception handler is defined */
X$HANDLER$STRUCTURE;
/* using the exception handler structure, the new exception handler is defined */
LITERALLY '3';
/* control is passed to the exception handler on all exceptional conditions */
LITERALLY 'STRUCTURE offset WORD,
base WORD)';
/* establishes a structure for overlays */
POINTER;
PTR$OVERLAY AT (@seg$pointer);
/* using the overlay structure, the first instruction of
the exception handler is identified */
WORD;

DECLARE new$x$handler
DECLARE all$exceptions
DECLARE PTR$OVERLAY

DECLARE seg$pointer
DECLARE seg$pointer$ovly
DECLARE status

SAMPLE PROCEDURE:
PROCEDURE;

seg$pointer = @EXCEPTION_HANDLER;
new$x$handler.offset = seg$pointer$ovly.offset;

/* pointer to exception handler */
/* offset of the first instruction of the exception handler
*/

new$x$handler.base

=

seg$pointer$ovly.base;
/* base address of the exception handler 8086 segment
containing the first instruction of the exception handler
*/

new$x$handler.mode

=

all$exceptions;
/* pass control on all conditions */

.:}

Typical PLlM-86 Statements

/., ..... ., .. ., .. ** .. ____ *_*_., * .. .,., * ** ***., *.,., * * ..... *., *.,., ... **_.,., * ** * * * * * * __ .fIo .. __ * * * * * * * * * *** * * * * * * * ••• * ** * * ** ** * * ..

*._ * * * * ... * ** * * .. '" * * * * * * ....

The address of the calling task's exception handler and the value of the task's exception mode (when to
pass control to the exception handler) are both returned when the calling task invokes the GET$EXCEPTION$HANDLER primitive .

•_*--*-------_. __ .... _.•• _-----"'-"'-_.-•• -._---*-_ .... *-******************************"''''.**************** .. ********"'**"'***** /
(@x$handler,
@status);

CALL RQ$GET$EXCEPTlON$HANDLER

.:}

Typical PLlM-86 Statements

/****************************************-************--_ •• _-_. __ ••• _-----------_.----_._-------_ ....

_----------*--------_.

The calling task may invoke the SET$EXCEPTION$HANDLER primitive to first set a new exception handier and then to later reset the old old exception handler.
* * .. * * ........... * .. * * * ** .. * ** .. ** 11" "' .. "' .. * .. * ...... * * .... * .. *., ** .. * * .. * .... * .......... * * **.'* * .. * * .. * '" * * .. *_ .... * * .... * * .. * .. * '" * ...... * * * .... * * * * * '" * * * * * * * * * * * * * * * * /

8-86

210911

SET$EXCEPTION$HANDLER

CALL RQ$SET$EXCEPTION$HANDLER

.:}

(@new$x$handler,
@status);

Typical PLlM-86 Statements

/ ....... '" '" '" '" • • • • '" '" '" "',., ...... '" '" '" '" '" '" '" '" "' .. '" "' • • '" '" '" "'._ .. '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" "' .. '" "'II' '" '" . . . . . . . . "' ...... '" '" '" '" '" '" '" "' • • '" '" '" '" '" '" '" '" '" '" "' .... '" '" '" '" '" '" "' • • "' • • '" '" "' .. "' .... "' ........ '"

No longer needing the new exception handler, the calling task uses the address and mode of the old exception handler to return exception handling to its original exception handler.
******.** ••••••• ***.:111."' •••••• ** •••••• ** •••••• "'**.** ••••• **** .. ******** •• "' •••••••• **_ ......... """' ••• ***."'***** ••••••••• _-."'._. I

(@x$handler,
@status);

CALL RQ$SET$EXCEPTION$HANDLER

.:}

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$PARAM

The exception$mode parameter is greater than 3.

8-87

210911

SET$INTERRUPT

SET$INTERRUPT

The SET$INTERRUPT primitive assigns an interrupt handler to an interrupt line and, optionally, makes the calling task
the interrupt task for the line.

CALL RQ$SET$INTERRUPT (line, interrupt$task$flag, interrupt$handler, interrupt$handler$ds,
except$ptr) ;

INPUT PARAMETERS
line

A WORD containing an interrupt line that is encoded as follows (bit 15 is the highorder bit):
Bits

Value

15-7

0

6-4

first digit of the interrupt line (0-7)

3

if one, the line is a master line and bits 6-4 specify the entire line
number
if zero, the line is on a slave interrupt controller and bits 2-0 specify
the second digit of the interrupt line

2-0
interrupt$task
$flag

second digit of the interrupt line (0-7), if bit 3 is zero

A BYTE which,
•

if zero, indicates that no interrupt task is to be associated with the specified interrupt line and that the new interrupt handler will not invoke the SIGNAL$INTERRUPT primitive.

•

if not equal to zero, indicates that the calling task is to be the interrupt task that
will be invoked by the interrupt handler being set. The priority of the calling task
is adjusted by the asp Processor according to the interrlJpt lin~_being silrviced.
Table 2-4 lists the interrupts lines and the corresponding interrupt task priorities.
Be certain that priorities set in this manner do not violate the max$priority attribute of the containing job.
The value of this parameter indicates the number of outstanding SIGNAL$INTERRUPT requests that can exist for this line. When this limit is reached, the associated interrupt line is disabled. The maximum value for this parameter is 255
decimal. Chapter 2 describes this feature in more detail.

interrupt$handler

A POINTER to the first instruction of the interrupt handler. To obtain the proper start
address for interrupt handlers written in PLlM-86, place the following instruction
before the call to SET$INTERRUPT:
interrupt$handler
= interrupt$ptr (inter);
where interrupt$ptr is a PL/M-86 built-in procedure and inter is the name of your interrupt handling procedure.

interrupt$handler$ds

A WORD which,
•

if not zero, contains the base address of the interrupt handler's data segment. See
the description of ENTER$INTERRUPT in this chapter for information concerning
the significance of this parameter.

8-88

210911

SET$INTERRUPT

I
.~

1
.'

It is often desirable for an interrupt handler to pass information to the interrupt
task that it calls. The following PLlM-86 statements. when included in the interrupt task's code (with the first statement listed here being the first statement in
the task's code). will extract the DS register value used by the interrupt task and
make it available to the interrupt handler. which in turn can access it by calling
ENTER$INTERRUPT:
DECLARE BEGIN WORD; f* A DUMMY VARIABLE *f
DECLARE DATA$PTR POINTER;
DECLARE DATA$ADDRESS STRUCTURE (
OFFSET WORD.
BASE WORD) AT (@DATA$PTR);f*THIS MAKES ACCESSIBLE THE TWO
HALVES OF THE POINTER DATA$PTR *f
DATA$PTR = @BEGIN; /* PUTS THE WHOLE ADDRESS OF THE DATA
SEGMENT INTO DATA$PTR AND DATA$ADDRESS *f
DS$BASE

=

DATA$ADDRESS.BASE;

CALL RQ$SET$INTERRUPT (.. .• DS$BASE •... );
•

if zero. indicates that the interrupt handler will load its own data segment and may
not invoke ENTER$INTERRUPT.

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.

DESCRIPTION
The SET$INTERRUPT primitive informs the OSP Processor that the specified interrupt handler is to service interrupts
which come in on the specified line. In a call to SET$INTERRUPT. a task must indicate whether the interrupt handler
will invoke an interrupt task and whether the interrupt handler has its own data segment. If the handler is to invoke an
interrupt task. the call to SET$INTERRUPT also specifies the number of outstanding SIGNAL$INTERRUPT requests
that the handler can make before the associated interrupt line is disabled. This number generally corresponds to the
number of buffers used by the handler and interrupt task. Refer to Chapter 2 for further information.
If there is to be an interrupt task. the calling task becomes that interrupt task. If there is no interrupt task. SET$INTERRUPT also enables the specified line. which must be disabled at the time of the call.
EXAMPLE
/ w•••••••••••••••• _ •••••••••••••••••• '* ...................... _._._ * ....................... _._._ ............ _............. * ....

*.

'* .... '* '* '* .. *...
This example illustrates how the SET$INTERRUPT primitive can be used.
* ....... '* ........................... _.................. _....................
**.* .. '* ................ **.* * ...... *.* ................................................................ /

-*._ ......

$INCLUDE(:F1 :OSXPRM.EXT);

f* Declares all primitive calls *f

INTERRUPT HANDLER: PROCEDURE EXTERNAL;
END INTERRUPT_HANDLER;
DECLARE interrupt$line$7

LITERALLY '000000000111 1000B';
/* specifies master interrupt line 7 *f
BYTE;
POINTER;
WORD;
WORD;

DECLARE interrupt$task$flag
DECLARE interrupt$handler
DECLARE data$segment
DECLARE status

8-89

210911

1

SET$INTERRUPT

SAMPLE PROCEDURE:
,PROCEDURE;

interrupt$task$flag = 0;
data$segment = 0;

r Indicates no interrupt task on line 7 of

r

indicates that the interrupt handler will load its own
data segment 0 f
interrupt$handler = INTERRUPT$PTR (@INTERRUPT_HANDLER);
/* points to the first instruction of the interrupt handler
Of

-:}

Typical PLfM-86 Statements

1·* ••• ** ............ * .......................... * ........................................ ** ••••••••••••••••••••••••••••••••••••

An interrupt line must have an interrupt handler and may have an interrupt task assigned to it. If there is
no interrupt task ass'igned to the line, the level is enabled by this primitive Invocation. Otherwise, the
line is enabled by a call to WAIT$INTERRUPT. By invoking the SET$INTERRUPT primitive, the calling
task assigns INTERRUPT_HANDLER to interrupt line 7 .
......... •••••••••• * .. '* .. * ............
*** •.*** .................. '* ............. * '* ... '* ...... ** * ..... ** **** ....... ** .................... '* .......

*._ ...................

CALL RQ$SET$INTERRUPT

-:}

*'

(jnterrupt$line$7,
interrupt$task$flag,
interrupt$handler,
data$segment,
@status);

Typical PLfM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES

E$OK

No exceptional conditions.

8-90

210911

SET$OS$EXTENSION

The SET$OS$EXTENSION primitive either enters the address of an entry (or function) procedure in the Interrupt
Vector Table or it deletes such an entry.

CALL RQ$SET$OS$EXTENSION (os$extension, start$address, except$ptr);

INPUT PARAMETERS
os$extension

A BYTE designating the entry of the Interrupt Vector Table to be set or reset. This
value must be between 224 and 255 (decimal), inclusive. The values in the range 192
to 223 will not cause exceptions, but are reserved for Intel use.

start$address

A POINTER to the first instruction of an entry (or function) procedure. If start$address
contains a zero value, the specified entry of the Interrupt Vector Table is being reset
(deallocated.)

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.

DESCRIPTION
The SET$OS$EXTENSION primitive sets or resets anyone of the 32 operating system extension entries in the Interrupt Vector Table. An entry must be reset before its contents can be changed. An attempt to set an already set entry
causes an E$CONTEXT exceptional condition.

EXAMPLE
/

........................ :It __ ........ _ . _ . _ ...... flo .. flo . . . ., ..................

* .... 'It ............ •

___ ............ it ..................................... _ ........................... _ ..................................... ..

This example illustrates how the SET$OS$EXTENSION primitive can be used to reset an entry in the Interrupt Vector Table. The example assumes that the entry for the level (number 250) was set earlier by
another procedure .
.. _...... _. ____ •••• _._ •••••••••••••••••••••• ******** •••••• ***** ** .. ***." * *_ •• 11" .,,_. _ . _ . __ • • • *** •••• ** •• * __

$INCLUDE(:F1 :OSXPRM.EXT);

/* Declares all primitive calls * /

DECLARE vector$entry$250
DECLARE reset
DECLARE status

LITERALLY '250';
LITERALLY '0';
WORD;

*._ ................. * ... /

SAMPLE PROCEDURE:
PROCEDURE;

:-}

Typical PLlM-86 Statements

/ .................... -_ ............... - ._. _•••••• _............ * ................................... - •••• _................................................................................................... ..

The calling task invokes the SET$OS$EXTENSION primitive to reset entry 250 (decimal) of the Interrupt
Vector Table .
•• ***** •••• *****.** ............. ** ••••• " •• ************* •••• -.---_ ••••••• __ •••• _. __ ._ ••••• __ ._. __ ••• _------_._ ••• *"*****_.* ••• /

8-91

210911

SET$OS$EXTENSION

CALL RQ$SET$OS$EXTENSION

: }

(vector$entry$250,
reset,
@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$CONTEXT

An attempt is being made to set an entry that already is set.

E$PARAM

The os$extension byte value is less than 192.

8-92

210911

SET$PRIORITY

SET$PRIORITY

The SET$PRIORITY primitive changes the priority of a task.

CALL RQ$SET$PRIORITY (task, priority, except$ptrl;

INPUT PARAMETERS
task

A WORD containing a TOKEN for the task whose priority is to be changed. A zero
value specifies the invoking task.

priority

A BYTE containing the task's new priority. A zero value specifies the maximum priority of the specified task's containing job.

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.

DESCRIPTION
The SET$PRIORITY primitive allows the priority of a non interrupt task to be altered dynamically.
If the priority parameter is set to the zero, the task's new priority is its containing job's maximum priority. Otherwise,
the priority parameter contains the new priority of the specified task. The new priority, if explicitly specified, must not
exceed the containing job's maximum priority.

EXAMPLE

/*._ * * '* '* *** '* * '* * '* '* * '* '* '* '* '* '* •••• '" '*. '* * * * "" '* * * * * .*. * "" '* *. * ••• '* ........ '* '* '*. * '* '* '* '*. * *. '* * '* * '* '* '* '* '* '* '* "" * '* '* * '* '* •• '* * '* '* '* .iII. '* '* '* '* ... ** ... '* .. '* '* '* * .. * '* *
fI'

11

'* * '*

This example illustrates how the SET$PRIORITY primitive can be used to change the priority of a task .
• ** •••• **** ••• ft***.l1************.***** ••• **** ••• ****** ***** •••• ********* •• ********* •• **** •• **_************* •••

$INCLUDE(:F1 :OSXPRM.EXT);

*_. ___ *_._. /

/* Declares all primitive calls' /

TASK CODE: PROCEDURE EXTERNAL;
END TASK_CODE;
DECLARE TOKEN
DECLARE task$token
DECLARE priority$level$66
DECLARE priority$level$O
DECLARE start$address
DECLARE data$seg
DECLARE stack$pointer
declare stack$size$512

LITERALLY 'SELECTOR';
TOKEN;
LlTERALLY'66';
LITERALLY '0';
POINTER;
WORD;
POINTER;
LITERALLY '512'; /* new task's stack size is 512 bytes

DECLARE task$flags
DECLARE status
DECLARE job

WORD;
WORD;
WORD;

*/

SAMPLE PROCEDURE:
PROCEDURE;
start$address
data$seg = 0
stack$pointer
tsk$flags = 0;

= @TASK CODE;
-

= 0;

/*
/*
/*
/*

8-93

pOinter to first instruction of interrupt task * /
task sets up own data seg * /
automatic stack allocation
designates no floating-point instructions' /

210911

I

SET$PR!ORITY.

e:}

Typical PLlM-86 Statements

1-··_·····················_········_·············_···· ..................................... _............... -..............
In this example, the calling task creates a task whose priority is to be changed. The new task initially
has a priority level 6 6 . '
........... * .............. * ............................ * .................. w.................. * .... .;, ....... _.. ." ........................................................... * ............ w•• ** ... * ................ /

task$token = RQ$CREATE$TASK

(priority$level$66,
start$address,
data$seg,
stack$pointer,
stack$size$512,
task$flags,
@status);

/••••• --,...* _._ .................* ...... _._ ............ _•• - ** .............................. _....................................... _............. ** .. ..
The calling task in this example does not need to invoke the CATAlOG$OBJECT primitive to ensure the
successful use of the SET$PRIORITY primitive. To allow other tasks access to the new task, however,
requires that the task's object TOKEN be cataloged .
• * ......... * ............ _'It_._ ............................. * ................... * .......................... '* .......................... * .. "" ....................................... ~ .... ** ......................... /

CAll RQ$CATAlOG$OBJECT

e:}

GOb,
task$token,
@(12,'TASK CODE'),
@status); -

Typical Pl/M-86 Statements

I·····················································....................................................................
The new task, TASK_CODE, is not an interrupt task, so its priority may be changed dynamically by
invoking the SET$PRIORITY primitive .

..................................................................................................................... ......./
~

CAll RQ$SET$PRIORITY

eee}

(task$token,
priority$level$O,
@status);

Typical Pl/M-86 Statements

/ .................................................................................* •••••••••••••• *..........................

) Once the need for the higher priority is no longer present, the priority of TASK_CODE can be changed
back to its original priority by invoking SET$PRIORITY a second time .
• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • *- • • • • • • • • • • • • • • • • •

CAll RQ$SET$PRIORITY

e:}

* •• /

(task$token,
priority$level$66,
@status);

Typical Pl/M-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES

E$OK

No exceptional conditions~

8-94

210911

I

SIGNAL$EXCEPTION

SIGNALSEXCEPTION

The SIGNAL$EXCEPTION primitive is invoked by extensions of the OS Processor to signal the occurrence of an exceptional condition.

,i

CALL RQ$SIGNAL$EXCEPTION(exception$code, param$num, stack$pointer, reserved$param,
NPX$status$word, except$ptr);

INPUT PARAMETERS

exception$code

A WORD containing the code (see list in Appendix B) for the exceptional condition
detected.

param$num

A BYTE containing the number of the parameter which caused the exceptional
condition. If param$num equals zero, then no parameter is at fault.

stack$pointer

A WORD which, if not zero, must contain the value of the stack pointer saved on entry
to the operating system extension (see the entry procedure in Chapter 2 for an
example). The top five words in the stack (where BP is at the top of the stack) must be
as follows:
FLAGS
CS
IP

Saved by software interrupt to as Processor extension

OS
BP

Saved by as Processor extension on entry

Upon completion of SIGNAL$EXCEPTION, control is returned to either of two
instructions. If the stack$pointer contains a zero, control returns to the instruction
following the call to SIGNAL$EXCEPTION. Otherwise, control returns to the instruction identified in CS and IP.
~eserved$param

A WORD reserved for Intel use. Set this word to zero.

NPX$status$word

A WORD containing the status of the 8087 NPX.

OUTPUT PARAMETER

except$ptr

A POINTER to a WORD to which the
parameter.

asp

will return the condition code for this

DESCRIPTION

asp extensions use the SIGNAL$EXCEPTION primitive to signal the occurrence of exceptional conditions. Depending
on the exceptional condition and the calling task's exception mode, control mayor may not pass directly to the task's
exception handler.
If the exception handler does not get control, the exceptional condition code is returned to the calling task. The task
can then access the code by checking the contents of the word pOinted to by the except$ptr parameter for its call (not
for the call to SIGNAL$EXCEPTION).
EXAMPLE
/ •••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• e ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••

This example Illustrates how the SIGNAL$EXCEPTION primitive can be used to signal the occurrence
of the exceptional condition E$CONTEXT.
• * .-•••••••• * fII._ ................................................... eft .. * ..... * .................. * ... * •• * *.ft ... '* * .... * .. * ....... * •• * * .. * ..... - * * .. I

*.

8-95

210911

"
SIGNAL$EX.CEPTION

$INCLUDE(:F1 :OSXPRM.EXT);

r

DECLARE e$context
DECLARE param$num
DECLARE stack$pointer
DECLARE reserved$word
DECLARE status

LlTERALLY'5H';
BYTE;
WORD;
LITERALLY '0';
WORD;

Declares all primitive calls 0/

SAMPLE PROCEDURE:
PROCEDURE;

param$num = 0;
stack$pointer = 0;

-:}

1* no parameter at fault 0/
1* return control to instruction following call"/

Typical PL/M-86 Statements

j***************** •• **** ••••• *.* •••• ** ••• ******** ••••• •••••••••••••••••••••••••••••••••••••••••••••••••••• **** ••••••••••••

In this example the SIGNAL$EXCEPTION primitive is invoked by extensions of the OSP to signal the occurrence of an E$CONTEXT exceptional condition.
* ••••••••••••• _•••• __ •••••••••••••••••••••••••••• __ ••••••••••••••• **.*:11 •••• **** ••.• *****.** •••••• **** ••••••• ***********.** /
(e$context,
param$num,
stack$pointer,
reserved$word,
reserved$word,
@status);

CALL RQ$SIGNAL$EXCEPTION

-:}

Typical PL/M-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES

E$OK

No exceptional conditions.

8-96

210911

I

SIGNAL$INTERRUPT

SIGNAL$lNTERRUPT
The SIGNAL$INTERRUPT primitive is used by an interrupt handler to activate an interrupt task.

CALL RQ$SIGNAL$INTERRUPT (line, except$ptr);

INPUT PARAMETER
line

A WORD specifying an interrupt line which is encoded as follows (bit 15 is the highorder bit):
Bits

Value

15-7

0

6-4

first digit of the interrupt line (0-7)

3

if one, the line is a master line and bits 6-4 specify the entire line
number
if zero, the line is on a slave interrupt controller, and bits 2-0 specify
the second digit

2-0

second digit of the interrupt line (0-7). if bit 3 is zero

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive. The calling interrupt handler must process all exceptional conditions
in-line, as control does not pass to an exception handler.

DESCRIPTION
An interrupt handler uses SIGNAL$INTERRUPT to start up its associated interrupt task. The interrupt task runs in its
own environment with higher (and possibly the same) interrupt lines enabled, whereas the interrupt handler runs in
the environment of the interrupted task with all interrupts disabled. The interrupt task can also make use of exception
handlers, whereas the interrupt handler always handles exceptions in-line.

EXAMPLE
/ ... * _._ ** .. ,. ........ ,. .......... _._._. _._._ ... _**.* ...... * .... _._ **

.w ........ ** ** ............ ill""""""" '* .... _....... _._ .........................................* ....

fIo . . .

* ............. ..

This example illustrates how the SIGNAL$INTERRUPT primitive can be used to activate an interrupt
task.
_._._ ••••• ____ ._ •••••••• _•••••••••• ,. •• _•••• _..... _._._ •• "'_._ ..... * .................. * *. _•••• _.. * ............ * ** ..... _._._._ '" _•• _,.. .. flo /

$INCLUDE(:F1 :OSXPRM.EXT);

/' Declares all primitive calls '/

DECLARE the$first$word
DECLARE interrupt$line$7

WORD;
LITERALLY '000000000111 1OOOB';
1* specifies master interrupt line 7 '/
BYTE;
POINTER;
WORD;
WORD;
WORD;
POINTER;

DECLARE interrupt$task$fiag
DECLARE interrupt$handler
DECLARE data$segment
DECLARE status
DECLARE interrupt$status
DECLARE ds$pointer

8-97

210911

I

SU:;NAL$INTERRUPT

DECLAREPTR$OVERLAY

LITERALLY 'STRUCTURE (offset WORD,
base WORD)';
f* establishes a structure for overlays * f
PTR$OVERLAY AT (@ds$pointer);
f* using the overlay structure, the base address of the
interrupt handler's data segment is identified *f

DECLARE ds$pointer$ovly

INTERRUPT_HANDLER: PROCEDURE INTERRUPT 59 PUBLIC;

.:}

Typical PlIM-86 Statements

/ .................... ** .... *** ........... *~*** .... "' .............. ,.. .. "' .. "' .... '" '" "' ...... *. ** ***,*""""" *.

*.- *** *.- ** "'.* ....... _. '" "' .. *. "' . . . "' . . . '" *. *. "' ....... _.. **.* "' .... '" '" '"

The calling interrupt handler invokes the ENTER$INTERRUPT primitive which loads a base address
value (defined by ds$pointer$ovly.base) into the data segment register. This register provides a mechanism for the interrupt handler to pass data to the interrupt task to be started up by the SIGNAL$INTERRUPT primitive.
-***** .. 11<******************************-*** •• ""'*******. __ ",-a. __ **_", __ * ________ .",._"' ___ ._.",,,,.,,, __ **.,,,,,,_.,,, •• __ * __ "''''*''' •• '''''''''''' ___ /

CALL RQ$ENTER$INTERRUPT

.:.

}

(interrupt$line$7,
@i nterru pt$status);
(interrupt$status) ;

Typical PlIM-86 Statements

/ "' ............ '" '" "' .. '" "'.'It '" "' .. * •• _..... "' .. it. "'*_ *. '" "' .... "' .................... '" "' .. "' .... '" '" '" '" "' .. "' ... _'" "' .. "' .... '" '" "' .... '" '" "' .......... "' .. "' .... '" * __ .. _.... ** .. '" '" "'.* **** ** .... '" '" "' .. '" '"
The interrupt handler uses SIGNAL$INTERRUPT to start up its associated interrupt task.
"' .. "' ........ '" '" "' .. * .... * * .... ,...._ .. '" "' .. "'. "' .. '* "' .. "' .. * '" "' .... "' .. * '" "' .. "' .... '" '" '" '" "' .... '" '" '" '" "' .. "' .... "' .. '" '" '" "' .. '" "' .. '" '" '" * '" * * "' ...... '" "' .... '" '" '" 'II"" "' .. * '" "' .. "' .... '" "' .... '" "' .. '" *_ .... '" "' .. '" '" /

CALlRQ$SIGNAL$INTERRUPT

(interrupt$line$7,
@interrupt$status);
(i nterru pt$status);

CALLINlINE_ERROR_PROCESS
END INTERRUPT_HANDLER;
INlINE_ERROR_PROCESS: PROCEDURE(interrupt$status);
IF interrupt$status < > E$OK THEN
DO;

.:}

In-line Error Processing PLfM-86 Statements

END;
END INlINE_ERROR_PROCESS;

SAMPLE PROCEDURE:
PROCEDURE;
ds$pointer = @the$first$word;

f* a dummy identifier used to point to interrupt handier's data segment * f
data$segment = ds$pointer$ovly.base;
1* identifies the base address of the interrupt handler's
data segment * f
intrpt$handlr$addrs = INTERRUPT$PTR (@INTERRUPT HANDLER);
I*-points to the first instruction of the interrupt handler
*f
interrupt$task$flag = 01 H;
1* indicates that calling task istobe interrupt task *f

.:}

Typical PLfM-86 Statements

8-98

210911

SIG NAL$INTERRUPT

/ ••• "' ......... * ...................................... * .... *.* .......... * ....................... * ... * ................................................... ,. ..................................................... oil ........................ ** ................................ ...

By first invoking the SET$INTERRUPT primitive, the calling task enables an interrupt line and becomes
the interrupt task for line 7.
_**.**.**.* •• ************ •• _.IIIr*******.*****.**.*.**.*._"' ••••••••••• _."' ...... _•••• _•• _•••••••• __ ... "' ___ ••• _______ ••••••••• _._. /

CALL RQ$SET$INTERRUPT

..• }

(j nterru pt$1 i ne$7,
interrupt$task$flag,
interrupt$handler,
data$segment,
@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

NOTE
Because the OSP initializes the Interrupt Vector Table, you should use the NOINTVECTOR control when you compile your interrupt handlers.

CONDITION CODES
E$OK

No exceptional conditions.

E$CONTEXT

There is not an interrupt task assigned to the specified interrupt line.

E$INTERRUPT$ The interrupt task has accumulated the maximum allowable number of SIGNAL$INTERRUPT
SATURATION requests. This is an informative message only. It does not indicate an error.
E$INTERRUPT$ The interrupt task has accumulated more than the maximum allowable number of SIGNAL$INTERRUPT requests. It had reached its saturation pOint and then called ENABLE to allow
OVERFLOW
the handler to receive further interrupt signals. It subsequently received an additional SIGNAL$INTERRUPT request before calling WAIT$INTERRUPT.
E$LlMIT

An overflow has occurred because the interrupt task has received more than 255 SIGNAL$INTERRUPT requests.

E$PARAM

The line parameter is invalid.

8-99

210911

.

.. ~

~

.

SLEEP

SLEEP

The SLEEP primitive puts the calling task to sleep.

CALL RQ$SLEEP (time$limit, except$ptr);

INPUT PARAMETER

time$limit

A WORD which,
_

if not zero and not OFFFFH, causes the calling task to go to sleep for that many
clock intervals, after which it will be awakened. The length of a clock interval is
configurable. Refer to Chapter 5 for further information.

-

if zero, causes the calling task to be placed on the list of ready tasks, immediately
behind all tasks of the same priority. If there are no such tasks, there is no effect
and the calling task continues to run.

_

if OFFFFH, is invalid.

OUTPUT PARAMETER

A POINTER to a WORD to which the
this primitive.

except$ptr

asp will

return the condition code generated by

DESCRIPTION

The SLEEP primitive has two uses. One use places the calling task in the asleep state for a specific amount of time.
The other use allows the calling task to defer to the other ready tasks with the same priority. When a task defers in this
way it is placed on the list of ready tasks, immediately behind all other tasks of equal priority.

EXAMPLE
/ ....... *. ** .... *** ................ ** ........................ ** ....................................

_.* ................ * ........... ** .....................................* ................. ** ................. ..

This example illustrates how the SLEEP primitive can be used .
............ * * .................. "' .............. * ................. "' ........................................................................11\''''''''''''' "' .................................... ** ............................................. /

$INCLUDE(:Fl :OSXPRM.EXT);

1* Declares all primitive calls * I

DECLAR~ time$limit
DECLARE status

WORD;
WORD;

SAMPLE PROCEDURE:
PROCEDURE;

time$limit = 100;

--.}

/* sleep for 100 clock ticks *1

Typical PL/M-86 Statements

/ •• * ••• * •••••••• *** •• *** ••••••••••••••• ** ••••••••• ** ••••• ** ••••••• ** ••• ****.*** ••• * •••••••••••• * •••••••••• **.**.*.********

The calling task puts itself in the asleep state for one second by invoking the SLEEP primitive.
* .......... *********** •• ***.* •••• *** ••• *.*** ••• ** •••••• *** •••• "' .... **** ••• *.,,"' •••• ** •••• ***.*****.***.**** •••• ** •••• *.***.*.* /

8-100

210911

SLEEP

CALL RQ$SLEEP

:-}

,I

(time$limit,
@status);

;

Typical PLlM-B6 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$PARAM

The time$limit parameter contains the invalid value OFFFFH.

8-101

I

210911

SUSPEND$TASK

SUSPEND$TASK

The SUSPEND$TASK primitive increases by one the suspension depth of a task.

CALL RQ$SUSPEND$TASK (task, except$ptr);

INPUT PARAMETER
task

A WORD which,
•

if not zero, contains a TOKEN for the task whose suspension depth is to be
incremented.

•

if zero, indicates that the calling task is suspending itself.

OUTPUT PARAMETER
except$ptr

A POINTER to a WORD to which the
this primitive.

asp will

return the condition code generated by

DESCRIPTIONS
The SUSPEND$TASK primitive increases by one the suspension depth of the specified task. If the task is already in
either the suspended or asleep-suspended state, its state is not changed. If the task is in the ready or running state, it
enters the suspended state. If the task is in the asleep state, it enters the asleep-suspended state.
The SUSPEND$TASK primitive should not be used to suspend interrupt tasks.

EXAMPLE
/ ............ * ............. * ...... **.*._ .. *** .............. ** ............ * '" ** .... * *** ** ........ ** ........................................ "' .................. *** * ...... *. ** *.**.* .................... ..

This example illustrates how the SUSPEND$TASK primitive can be used to increase the suspension
depth of a non-interrupt task .
.. * ............................ * ........ * .. * * .... * * * .. * * .. * ',"fr" * ...... * * * * * .. * * * * * .. * ...... * * .... * ...... * .......... "' .......... "" ........................ 'III! "' .................. * .................... * ............ "" /
$INCLUDE(:F1 :OSXPRM.EXT);

f* Declares all primitive calls *f

TASK CODE: PROCEDURE EXTERNAL;
END TASK_CODE;
DECLARE TOKEN
DECLARE task$token
DECLARE priority$level$200
DECLARE start$address
DECLARE data$seg
DECLARE stack$pointer
DECLARE stack$size$512
DECLARE task$flags
DECLARE status

LITERALLY 'SELECTOR';
TOKEN;
LITERALLY '200';
POINTER;
WORD;
POINTER;
LITERALLY '512'; /* new task's stack size Is 512 bytes
*f
WORD;
WORD;

SAMPLE PROCEDURE:
PROCEDURE;

8-102

210911

SUSPEND$TASK

start$address ~ @TASK CODE;
data$seg ~ 0;
stack$pointer = 0;
task$flags = 0;

eee}

!" first instruction of the new task '/
!" task sets up own data seg '/
/' automatic stack allocation '/
/' designates no floating-point instructions '/

Typical PL/M-86 Statements

/ '" "''' '*" '" '" '" '" 110""" '" "''' '" '" '*« _•• _•••• '" "' .. "' .... '" '" "'" .. '" "''' '" '" '" '" "' .. '" "' .. '" '" 111" "'''" .. "' .. " '/II"" .. ,."" *,." "''''''' *"""" '" '" '" "''''' "''''' ill" "''''''' '" '" '" '" '" "',. '" "''' '" '" '" '" '" '" "''' "' .... '* 111" '"
In order to suspend a task, a task must know the TOKEN for that task. In this example, the needed
TOKEN is known because the calling task creates the new task (labeled TASK_CODE).
•• ********w**********************.***.***************.**._****1r*****************fI*************************** •• ** •• *****11. /

task$token

=

e:}

RQ$CREATE$TASK

(priority$level$200,
start$address,
data$seg,
stack$pointer,
stack$size$512,
task$flags,
@status);

Typical PLlM-86 Statements

/ '" '" '" '" "' .... '" '" '" "' .. '" '" '" __ "' .. '" 11" '" "' .. '" "' .. '" '" '" '" '" "''' "''' '" '" '" "''' '" '" '" '" '" '" '" '" '" '" '" "' .. '" '" '" '" '" '" '" 111 .... "' .... "' . . . "' .. '" '" '" '" '" '" "' .. '" '" '" '" "''' '" '" '" '" '" "' .. '" "' .. '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" '" "' .. '"

After creating the task, the calling task invokes SUSPEND$TASK. This primitive increases by one the
suspension depth of the new task (TASK_CODE).
**fI*********,**********************************_.*****_*************************************************** ••• ****.******** /

CALLRQ$SUSPEND$TASK

e:}

(task$token,
@status);

Typical PLlM-86 Statements

END SAMPLE_PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$CONTEXT

The task indicated by the task parameter is an interrupt task.

E$EXIST

The task parameter is not a TOKEN for an existing object.

8-103

210911

WAIT$INTERRUPT

WAIT$INTERRUPT

The WAIT$INTERRUPT primitive is used by an interrupt task to signal its readiness to service an interrupt.

CALL RQ$WAIT$INTERRUPT (line, except$ptr);

INPUT PARAMETER

line

A WORD specifying an interrupt line which is encoded as follows (bit 15 is the highorder bit):
Bits

Value

15-7

0

6-4

firstdigitofthe interrupt line (0-7)

3

if one, the line is a master Une and bits 6-4 specify the entire line
number
if zero, the line is on a slave interrupt controller and bits 2-0 specify
the second digit of the interrupt line

2-0

second digit olthe interrupt line (0-7), if bit 3 is zero

OUTPUT PARAMETER

except$ptr

A POINTER to a WORD to which the OSP will return the condition code generated by
this primitive.

DESCRIPTION

The WAIT$INTERRUPT primitive is used by interrupt tasks immediately after initializing and immediately after servicing interrupts. Such a call suspends an interrupt task until the interrupt handler for the same line resumes the task by
invoking the SIGNAL$INTERRUPT primitive.
While the interrupt task is running, all lower-priority interrupt lines are disabled. The aSSOCiated interrupt line is either
disabled or enabled, depending on the option originally specified with the SET$INTERRUPT primitive. If the associated interrupt line is enabled, all SIGNAL$INTERRUPT calls that the handler makes (up to the limit specified with
SET$INTERRUPT) are logged. If this count of SIGNAL$INTERRUPT calls is greater than zero when the interrupt task
invokes WAIT$INTERRUPT, the task is not suspended. Instead it continues processing the next SIGNAL$INTERRUPT
request.
If the associated interrupt line is disabled while the interrupt task is running and the number of outstanding SIGNAL$INTERRUPT requests is less than the user-specified limit, the call to WAIT$INTERRUPT enables that line.

EXAMPLE
/ .................... *** * ... ** ... * ..........

e._ ••••••• *. ** .... _•••••••••••••• __ ........... ** ......... * ............. _............. *.* ••••• ** .e •••••

This example illustrates how the WAIT$INTERRUPT primitive can be used to signal a task's readiness
to service an interrupt.
.. * ... **** ."'* .. *--* ........... ** ........ * ......................... *. *** ••• *_ .. --._ ........................ ** ** .................... ** .... ** ............ ** **** .............. ***.* ................ /

8-104

210911

WAIT$INTERRUPT

$INCLUDE(:F1 :OSXPRM.EXT);

I' Declares ali primitive calls' I

DECLARE TOKEN
DECLARE task$token
DECLARE priority$level$66
DECLARE start$address
DECLARE data$segment
DECLARE stack$pointer
DECLARE stack$size$512

LITERALLY 'SELECTOR';
TOKEN;
LITERALLY '66';
POINTER;
WORD;
POINTER;
LITERALLY '512'; I' new task's stack size is 512 bytes
'I
WORD;
LITERALLY '000000000111 1000B';
I' specifies master interrupt line 7 'I
BYTE;
POINTER;
WORD;
WORD;

DECLARE task$flags
DECLARE interrupt$line$7
DECLARE interrupt$task$flag
DECLARE interrupt$handler
DECLARE interrupt$status
DECLARE status
INTERRUPT_TASK: PROCEDURE PUBLIC;

interrupt$task$flag = 01 H;
r indicates that calling task is to be interrupt task' I
data$segment = 0;
I' use own data segment 'I
intrpt$handlr$addrs = INTERRUPT$PTR (@INTERRUPT HANDLER);
I'-points to the first instruction of the interrupt handler
,I

/ ............................ * .... * ................... *.* _III ...... *.............. * ............. * ............. * .............................. * .. * ............... ..

The first primitive in this example, SET$INTERRUPT, makes the calling task (INTERRUPT_TASK) the
interrupt task for interrupt line seven .
... * ... * ............ 'It .... ** ...... ** ................................... * ............. * ............. * ............. ** .......... * ... * ................................................... ** ...... ** ....... * .......... /
CALL RQ$SET$INTERRUPT

-:}

(interrupt$line$7,
interrupt$task$flag,
interruptShandler,
data$segment,
@interrupt$status);

Typical PUM-86 Statements

/ ....... *.* ................................................................* ............................ ** .... III • • • * ..................... **** .............. ..

The calling interrupt task invokes WAIT$INTERRUPT to suspend itself until the interrupt handler for
the same line resumes the task by invoking the SIGNAL$INTERRUPT primitive.
............... * .. *** .................................. ." ........ * .. '" * ...... * ............ *** ....... * .............. * .............................................. * ... * ** ....................... I
CALL RQ$WAIT$INTERRUPT

-:}

(interrupt$line$7,
@interrupt$status);

Typical PL/M-86 Statements

I·····················································....................................................................
When the interrupt task invokes the RESET$INTERRUPT primitive, the assignment of the current interrupt handler to interrupt line 7 is canceled and, because an interrupt task has also been assigned to the
line, the interrupt task is deleted .
••••••• ••••••••••••••• •••••••••••• ••••••••••• ••••••••• •••••••••• ••• •••••••••••••••••••••• •••••••••••••••••••••••••••••••• I
CALL RQ$RESET$INTERRUPT

(interrupt$line$7,
@interrupt$status);

END INTERRUPT_TASK;

8-105

210911

I

WAIT$INTERRUPT

SAMPLE PROCEDURE:
PROCEDURE;
start$address = @INTERRUPT TASK;
stack$pointer = 0;
task$flags = 0;
data$segment = 0;

.•. }

I'
I'
/"
/"

1st instruction of interrupt task" /
automatic stack allocation"/
designates no floating-point instructions" /
use own data segment" /

Typical PLlM-86 Statements

/ .*****.*********.**** ... * •• * ••• **.** •• **-*************.****************** ••• ** •••• ** ••• *****.*** •••••• ** •• *** ••• **** ••••••

In this example the calling task invokes the primitive CREATE$TASK to create a task labeled
INTERRUPT _TASK .
.... "' .. ** ...... * .... ", .................. ", ....... ** .. "' .... ot. ** .. "' .. "' .... "' ....................................................................... * ................ '* .... 111 ................................................................ /

task$token

=

.:}
END

RQ$CREATE$TASK

(priority$level$66,
interrupt$task,
data$segment,
stack$pointer,
stack$size$512,
task$flags,
@status);

Typical PLlM-86 Statements

SAMPLE~PROCEDURE;

CONDITION CODES
E$OK

No exceptional conditions.

E$CONTEXT

The calling task is not the interrupt task for the given interrupt line.

E$PARAM

The line parameter is invalid.

8-106

210911

COMMAND DICTIONARY

Command

Page

Command

PRIMITIVES FOR JOBS

SEND$MESSAGE ................. 8-83
Sends an object to a mailbox.

CREA TE$JOB .................... 8-28
Creates a job with a task and returns a
TOKEN for the job.

RECEIVE$MESSAGE ............. 8-74
Causes the calling task to obtain an object
from a mailbox. The task. has the option of
waiting if no objects are present.

PRIMITIVES FOR TASKS
CREATE$T ASK .................. 8-38
Creates a task and returns a TOKEN for it.

PRIMITIVES FOR REGIONS

DELETE$TASK .................. 8-47
Deletes a task that is not an interrupt task.

CREA TE$REGION. . . . . . . . . . . . . . . . 8-34
Creates a region and returns a TOKEN for
it.

SUSPEND$TASK ................ 8-102
Increases a task's suspension depth by one.
Suspends the task if it is not already
suspended.

DELETE$REGION ................ 8-43
Deletes a region.
SEND$CONTROL. ................ 8-81
Relinquishes control to the next task waiting
at the region.

RESUME$T ASK .................. 8-79
Decreases a task's suspension depth by one.
Resumes (unsuspends) the task if the suspension depth becomes zero.

RECEIVE$CONTROL ............. 8-72
Causes the calling task to wait at the region
until the task receives control.

SLEEP. . . . . . . . . . . . . . . . . . . . . . . . .. 8-100
Places the calling task in the asleep state for
a specified amount of time.

ACCEPT$CONTROL .............. 8-24
Causes the calling task to accept control
from the region only if control is immediately available. If control is not available, the
calling task does not wait at the region.

SET$PRIORITY ................... 8-93
Changes a task's priority.
GET$TASK$TOKENS ............. 8-66
Returns to the calling task a TOKEN for
either itself, its job, its job's parameter
object, or the root job.

Page

PRIMITIVES FOR SEGMENTS AND
MEMORY POOLS

PRIMITIVES FOR MAILBOXES
CREATE$MAILBOX .............. 8-32
Creates a mailbox and returns a TOKEN for
it.
DELETE$MAILBOX .............. 8-41
Deletes a mailbox.
8-107

CREATE$SEGMENT .............. 8-36
Creates a segment and returns a TOKEN
for it.
DELETE$SEGMENT .............. 8-45
Returns a segment to the memory pool
from which it was allocated.
210911

COMMAND DICTIONARY

Command

Page

Command

Page

RESET$INTERRUPT .............. 8-76
Cancels the assignment of an interrupt handler to an interrupt line and, if applicable,
deletes the interrupt task for that line.

PRIMITIVES FOR ALL OBJECTS
CATALOG$OBJECT .............. 8-26
Places an entry for an object in an object
directory.

*ENTER$INTERRUPT ............ 8-57
Sets up a previously designated data segment base address for the calling interrupt
handler.

DISABLE$DELETION ............. 8-51
Makes an object immune to ordinary
deletion.

*EXIT$INTERRUPT ............... 8-60
Used by interrupt handlers to send an endof-interrupt signal to hardware.

ENABLE$DELETION ............. 8-55
Makes an object susceptible to ordinary
deletion. Required only if the object has had
its deletion diabled.

*SIGNAL$INTERRUPT ......... , .. 8-97
Used by interrupt handlers to invoke interrupt tasks.

G ET$TYPE ...................... 8-68
Accepts a TOKEN for an object and returns
the object's type code.

WAIT$INTERRUPT .............. 8-104
Puts the calling interrupt task to sleep until
it is called into service by an interrupt
handler.

LOOK$UP ....................... 8-70
Returns a TOKEN for a cataloged object.

ENABLE ......................... 8-53
Enables an external interrupt line.

PRIMITIVES FOR EXCEPTION
HANDLERS

*DISABLE ....................... 8-49
Disables an external interrupt line.

SET$EXCEPTION$HANDLER ..... 8-85
Sets the exception handler and exception
mode attributes of the calling task.

*GET$LEVEL .................... 8-64
Returns the interrupt line number of the
highest priority for which an interrupt handier has started by has not yet finished
processing.

GET$EXCEPTION$HANDLER ..... 8-62
Returns the current values of the exception
handler and exception mode attributes for
the calling task.

PRIMITIVES FOR EXTENDING THE
OPERATING SYSTEM PROCESSOR

PRIMITIVES FOR INTERR UPT
HANDLERS, TASKS, AND LINES
(An asterisk (*) marks primitives that an interrupt handler can invoke.)

SET$OS$EXTENSION ............. 8-91
Either enters the address of an entry (or
function) procedure in tile Interrupt Vector
Table or it deletes such an entry.

SET$INTERRUPT ................. 8-88
Assigns an interrupt handler and, if desired,
an interrupt task to an interrupt line.

SIGNAL$EXCEPTION............. 8-95
Used by extensions of the OS Processor to
signal the occurrence of an exception.

8-108

210911

'~
,~

THE 80130 OPERATING SYSTEM FIRMWARE COMPONENT

8.11 ADDING iRMX 86 FEATURES
TOTHEOSP
There are two ways to add functionality to the OSP.
One way, discussed in Section 8.9, is to create OS
extensions. The other way is adding iRMX 86
system calls (and possibly object types as well) to the
OSP.
The iRMX 86 Operating System is a functional superset of the OSP and consists of the following parts:

•

Formatting and verifying device volumes

•

Backing up and restoring files on devices

•

Reading commands from a file, rather than
from a terminal

•

Communicating with the iSBC 957B package
to debug programs and to copy files to and
from an Intel development system

The Human Interface also provides a number of
system calls that applications programs can invoke to
utilize Human Interface services.

Nucleus: The Nucleus is the core of the iRMX 86

Operating System and includes all of the features
and primitives of the OSP, among other things.
Every application system built upon the iRMX 86
Operating System includes the Nucleus.

Terminal Handler: The Terminal Handler provides

a real-time interface between a terminal and an application system. It is useful for users who require the
ability to communicate with their systems but who
do not need the full services of an I/O System.

Basic I/O System: The Basic I/O System provides

file management and a device-independent interface
to input and output devices. It supplies all file drivers
and a number of device drivers. It offers an
asynchronous interface for I/O operations, allowing
I/O functions to run concurrently with other
operations.

Debugger: The debugger provides the facilities for
debugging tasks interactively. It allows several tasks

to be debugged while the remainder of the system
continues to run.
For readers who want to know more about the
iRMX 86 Operating System, its documentation package consists of the following:

Extended I/O System: The Extended I/O System

provides higher-level management of files than does
the Basic I/O System. It offers a simple synchronous
interface for I/O operations and automatically performs read-ahead and write-behind buffering.

TITLE

Application Loader: The Application Loader pro-

vides a mechanism for loading application code and
data files from I/O devices into system memory. It
can load absolute code into fixed locations and reloeatable code. into dynamically-allocated locations,
and it can load files containing overlays.

NUMBER

Introduction to the iRMX 86 Operating System

9803124

iRMX 86 Nucleus Reference Manual

9803122

iRMX 86 Basic I/O System Reference Manual

9803123

iRMX 86 Extended I/O System Reference Manual
iRMX 86 Loader Reference Manual
iRMX 86 Human Interface Reference Manual

143308
143318
9803202

Bootstrap Loader: The Bootstrap Loader provides

iRMX 86 Terminal Handler Reference Manual

143324

a means of loading the entire application system into
system memory from an I/O device. It can be configured to load from a -specific device or to use the first
device that becomes ready once the system has been
started. It can also be configured to load a file specified by an operator at a terminal.

iRMX 86 Debugger Reference Manual

143323

iRMX 86 Programming Techniques

142982

iRMX 86 System Programmer's Reference Manual

142721

Guide to Writing Device Drivers for the iRMX 86
and iRMX 88 I/O Systems

Human InterfaO'e: The Human Interface is an interactive interface and an application system. It gives

the operator the ability to invoke an application program from a terminal.

142926

iRMX 86 Installation Guide

9803125

iRMX 86 Configuration Guide

9803126

Guide to Using the iRMX 86 Languages

143907

iRMX 86 Disk Verification Utility Reference Manual 144133

Supplied with the Human Interface are commands
that perform the following operations:

iRMX 86 System Debug Monitor Reference Manual 143908
iRMX 86 Pocket Reference

142861

•

Creating, copying, renaming, and deleting
files

Run-Time Support Manual for iAPX 86,88
Applications

121776

•

Loading and starting application programs

Getting Started with the iRMX 86 System

144340

8-109

210911



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.3
Linearized                      : No
XMP Toolkit                     : Adobe XMP Core 4.2.1-c041 52.342996, 2008/05/07-21:37:19
Create Date                     : 2016:04:04 09:44:12-08:00
Modify Date                     : 2016:04:04 10:25:39-07:00
Metadata Date                   : 2016:04:04 10:25:39-07:00
Producer                        : Adobe Acrobat 9.0 Paper Capture Plug-in
Format                          : application/pdf
Document ID                     : uuid:2c22bfc5-a984-f145-9abf-819a92e7a57c
Instance ID                     : uuid:ccb0f709-b4db-1e45-abe4-ec9a1cf6f0ac
Page Layout                     : SinglePage
Page Mode                       : UseNone
Page Count                      : 550
EXIF Metadata provided by EXIF.tools

Navigation menu