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 .
Page Count: 550
Download | |
Open PDF In Browser | View 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 & And9 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 O B 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 : 550EXIF Metadata provided by EXIF.tools