Contents
Part I Target Processors
1
1 The 6809 Microprocessor: Its Hardware 2
1.1 Architecture 3
1.2 Outside the 6809 6
1.3 Making the Connection 9
2 The 6809 Microprocessor: Its Software 19
2.1 Its Instruction Set 19
2.2 Address Modes 30
2.3 Example Programs 41
3 The 68000/8 Microprocessor : Its Hardware 56
3.1 Inside the 68000/8 57
3.2 Outside the 68000/8 64
3.3 Making the Connection 71
4 The 68000/8 Microprocessor: Its Software 86
4.1 Its Instruction Set 86
4.2 Address Modes 106
4.3 Example Programs 114
5 Subroutines, Procedures and Functions 122
5.1 The Call-Return Mechanism 123
5.2 Passing Parameters 129
6 Interrupts plus Traps equals Exceptions 141
6.1 Hardware Initiated Interrupts 143
6.2 Interrupts in Software 161
Part II C
167
7 Source to Executable Code 168
7.1 The Assembly Process 170
7.2 Linking and Loading 178
7.3 The High-Level Process 189
14.1 Data Structure and Program 355
14.2 6809 – Target Code 359
14.3 68008 – Target Code 370
15 Looking For Trouble 383
15.1 Simulation 384
15.2 Resident Diagnostics 397
15.3 In-Circuit Emulation 408
16 C'est la Fin 416
16.1 Results 416
16.2 More Ideas 420
Contents vii
A Acronyms and Abbreviations 423
List of Figures
1.1 Internal 6809/6309 structure. 4
1.2 6809 pinout. 7
1.3 A snapshot of the 6809 MPU reading data from a peripheral device. 10
1.4 Sending data to the outside world. 11
1.5 The structure of a synchronous common-bus microcomputer. 12
1.6 An elementary address decoding scheme. 14
1.7 A simple byte-sized output port. 15
1.8 Talking to a 6116 2 kbyte static RAM chip. 15
1.9 Interfacing a 6821 Peripheral Interface Adapter to the 6809. 17
2.1 Postbyte for pushing and pulling. 20
2.2 Moving 16-bit data at òne go'. 22
2.3 Stacking registers in memory. 23
2.4 16-bit binary to decimal string conversion. 48
2.5 Evaluating factorial n. 51
2.6 A memory mapof the factorial process. 52
3.1 Internal structure pf the 68000. 58
3.2 Internal 68008 structure. 63
6.6 Using an external interrupt flag to drive a level-sensitive interrupt line. 153
6.7 Servicing four peripherals with one interrupt. 157
6.8 External interrupt hardware for the 68000 MPU. 158
7.1 Onion skin view of the steps leading to an executable program. 170
7.2 Assembly-level machine code translation. 172
7.3 Assembly environment. 188
7.4 Syntax tree for sum = (n+1) * n/2; 191
7.5 The Whitesmiths C compiler process. 194
8.1 Structure of C programs. 203
8.2 Properties of simple object types. 204
8.3 Basic set of C data types. 205
8.4 Type promotions. 222
8.5 Simple 2-way decisions. 224
8.6 Using else-if to make a multi-way decision. 227
8.7 switch-case multi-way decision. 229
8.8 Loopconstructs. 231
9.1 Layout of C programs. 237
9.2 The System stack as seen from within power(), lines 21 – 38. 243
9.3 Array storage in memory. 249
9.4 A simple write-only port at 0x9000. 255
9.5 Register structure of a 6821 PIA. 262
11.1 A typical long-persistence display. 311
11.2 Characteristic scrolling display of a time-compressed memory. 312
11.3 Block diagram of the electrocardiograph time compressed memory. 316
11.4 A broad outline of system development. 318
11.5 Fundamental chip-level design. 320
11.6 A cost versus production comparison. 322
12.1 The quantization process. 325
12.2 The analog–digital process. 328
12.3 Illustrating aliasing. 329
2.3 Shifting Instructions. 26
2.4 Logic instructions. 27
2.5 Data test operations. 28
2.6 Operations which affect the Program Counter. 29
2.7 The M6809 instruction set 33
2.8 Initializing a 256-byte array. 34
2.9 Source code for sum of n integers program. 45
2.10 Object code generated from Table 2.9. 46
2.11 A superior implementation. 47
2.12 16-bit binary to an equivalent ASCII-coded decimal string. 49
2.13 Fundamental factorial-n code. 53
2.14 Factorial using a look-uptable. 54
4.1 Move instructions. 88
4.2 Arithmetic operations. 91
4.3 Shifting instructions. 95
4.4 Logic Instructions. 97
4.5 Bit-level instructions. 98
4.6 Data testing instructions. 99
4.7 Instructions which affect the Program Counter. 100
4.8 Summary of 68000 instructions. 105
4.9 A summary of 68000 address modes. 113
4.10 Object code for sum of n integers program. 115
4.11 A superior implementation. 116
4.12 Binary to decimal string conversion. 118
4.13 Mathematical evaluation of factorial n. 119
4.14 Factorial using a look-uptable. 120
5.1 Subroutine instructions. 125
5.2 A simple subroutine giving a fixed delay of 100 ms when called. 127
5.3 Transparent 100 ms delay subroutine. 129
5.4 Using a register to pass the delay parameter. 130
8.7 An else-if Real-Time Clock interrupt service routine. 226
8.8 Generating factorials using the else-if construct. 228
8.9 Generating factorials using the switch-case construct. 230
8.10 Generating factorials using a while loop. 232
8.11 Generating factorials using a for loop. 234
9.1 The C program as a collection of functions. 240
9.2 Generating factorials using a look-uptable. 247
9.3 Altering an array with a function. 250
9.4 Sending out a digit to a 7-segment port. 256
9.5 Displaying and updating heartbeat. 260
9.6 The PIA as a structure of pointers. 265
9.7 Sending pointers to structures to a function. 267
9.8 Unions. 270
9.9 Using #define for text replacement. 272
9.10 A typical math.h library header (with added comments). 276
10.1 Elementary startupfor a 6809-based system. 280
10.2 Using arrays of pointers to functions to construct a vector table. 281
10.3 A simple Startup/Vector routine for a 68000-based system. 282
10.4 A C-compatible assembler function evaluating the square root. 283
10.5 Using in-line assembly code to set upthe System stack. 284
10.6 Calling a resident function at a known address. 286
10.7 6809 startupfor the system of Table 9.5. 287
LIST OF TABLES xiii
10.8 68000 startupfor the system of Table 9.5. 288
10.9 clock() configured as an interrupt function. 290
10.10A startupfor the Aztec compiler initializing statics/globals. 294
10.11A typical lod68k file to produce an image of initialized data in ROM 295
10.12A startupinitializing statics/globals and setting upthe DPR for zero page. 296
10.13Zero-page storage with the Cosmic 6809 compiler. 297
10.14A portable C program using ANSII library I/O routines. 299
Target Processors
A major advantage of the use of a high-level language is its independence of
the hardware its generated code will eventually run on; that is, its portability.
However, one of the main strands of this book is the interaction of software with
its hardware environment, and thus it is essential to use real products in both
domains. For clarity, rather than describing a multitude of devices, most of the
examples are based on just two microprocessors. Two, rather than one, not to
loose sight of the portability aspects of high-level code.
In this part I describe the Motorola 6809 and 68000/8 microprocessors, the
chosen devices. This gives us a hardware target spectrum ranging from 8 through
32-bit architecture. As both microprocessors share a common ancestor, the com-
plexity is reduced compared with a non-related selection. Where necessary, other
processors are used as examples, but in general the principles are similar irre-
spective of target. If the hardware detail seems excessive to a reader with a
software background, much may be ignored if building the miniproject circuitry
of Part 3 is to be omitted.
CHAPTER 1
The 6809 Microprocessor: Its
Hardware
The microprocessor revolution began in 1971 with the introduction of the Intel
4004 device. This featured a 4-bit data bus, direct addressing of 512 bytes of
memory and 128 peripheral ports. It was clocked at 108 kHz and was imple-
mented with a transistor count of 2300. Within a year, the 8-bit 200 kHz 8008
appeared, addressing 16 kbyte of memory and needing a 3500 transistor imple-
mentation. The improved 8080 replacement appeared in 1974, followed a few
months later by the Motorola 6800 MPU [1]. Both processors could directly ad-
dress 64 kbytes of memory through a 16-bit address bus and could be clocked at
upto 2 MHz. These two families, together with descendants and inspired close
relatives, have remained the industry standards ever since.
The Motorola 6800 MPU [2] was perceived to be the easier of the two to use
THE MILL
A rather old fashioned term used by Babbage [8] for his mechanical computer
of the last century to identify the arithmetic and logic processor which `ground'
the numbers. In our example the 6809 has an 8-bit arithmetic logic unit (ALU)
implementing Addition, Subtraction, Multiplication, AND, OR, Exclusive-OR, NOT
and Shift operations. Associated with the ALU is the Code Condition (or Sta-
tus) register (CCR). Five of the eight CCR bits indicate the status of the result of
ALU processes. They are: C indicating a Carry or borrow, V for 2's complement
oVerflow, Z for a Zero result, N for Negative (or bit 7 = 1) and H for the Half carry
between bits 3 and 4. These flags are set as a result of executing an instruction,
and are normally used either for testing and acting on the status of a process, or
for multiple-byte operations. The remaining three bits are associated with inter-
rupt handling. The I bit is used to lock out or mask the IRQ interrupt, and the
F bit carries out the same function for the FIRQ interrupt. During an interrupt
service routine the E flag may be consulted to see if the Entire register state has
been saved (IRQ, NMI and SWI) or not (FIRQ). More details are given in Section 6.1.
REGISTER ARRAY
The 6809 has two Data registers, termed Accumulators A and B. These Data reg-
isters are normally targeted by the ALU as the source and destination for at least
one of its operands. Thus ADDA #50 adds 50 to the contents of Accumulator_A (in
register transfer language, RTL, this is symbolized as [A] <- [A] + 50, which
reads `the contents of register A become the original contents of A plus 50'). Op-
erations requiring one operand can seemingly be done directly on external mem-
ory; for example, INC 6000h which increments the contents of location 6000h
([6000] <- [6000] + 1). The suffix h indicates the hexadecimal number base,
whilst b denotes binary. However, in reality the MPU executes this by bringing
down the contents of 6000h (written as [6000]), uses the ALU to add one and
returns it. Whilst this fetch and execute process is invisible to the programmer,
the penalty is space and time; INC M (3 bytes length) takes 7 µs and INCA or INCB
(1 byte length) takes 2 µs (at a 1 MHz clock rate). Thus while it is always better