This
document
is a detailed software-level presentation of the MPU 6916 microprocessor
core, and assumes
the reader has fundamental knowledge of
microprocessor architectures.
@toc@Table of Contents@
MPU 6916 Programming Model
The MPU 6916 is an 8-bit processor core that retains binary
compatibility with the Motorola M6800 and M6811 microprocessors. Its
main design goal was to extend the M6811 architecture with minimal
hardware overhead, while providing a powerful set of compiler-friendly
instruction set enhancements.
Fig.1 presents the programming model of the MPU 6916.
Fig.1: MPU 6916 Programming Model
In the above programming model representation (Fig.1), the A, B, H, and
L registers are general purpose 8-bit accumulators, the X, Y, and Z
registers are a 16-bit index registers used to form the indexed
addressing modes, the S register is the 16-bit stack pointer, the PC
register is the 16-bit program conter, and the 8-bit CCR acts as the
CPU's condition codes register (the individual bits within CCR are
commonly referred to as
flags).
The MPU 6916 instructions set contains a number of 16-bit instructions
that operate on the "double accumulators" D and E formed by
concatenating the A and B, and respectively H and L accumulators (with A
being the high 8 bits of D, B being the low 8 bits of D, H being the
high 8 bits of E, and L being the low 8 bits of E).
Memory Origanization
The MPU 6916 architecture is based on a
unified memory model,
where the program code, the program data, and the system stack reside
within a common logical addressing space. The width of the address bus
is 16 bits (supported by the 16-bit index registers, stack pointer, and
program conter) and the memory is organized with one byte/address
(supported by the internal 8-bit accumulators architecture), thus
resulting the total processor addressing capability of 64 KBytes.
The processor can access memory data as both 8-bit (byte) and 16-bit
(two-byte) operands.
For 8-bit memory-referencing instructions the operand is located in one
single memory cell, and thus the 16-bit address indicated by the
instruction is directly used to access the specified memory location.
For 16-bit memory-referencing instructions the operand is stored in two
consecutive memory cells, with the high-order 8 bits of the operand
being located at the 16-bit address indicated by the instruction and the
low-order 8 bits being located at the next consecutive memory location.
This type of memory organisation where 16-bit data is stored at
consecutive locations with the high-order byte at the lower address and
the low-order byte at the higher address is known as "
big-endian"
or "
high-byte-first" memory architecture.
[Remark:] a predefined set of memory locations is
reserved for
special processor operations (such as initialization, interrupts, etc).
See the
MPU 6916 internal architecture
for details.
Stack Layout
The MPU 6916 stack resides in the main memory ("
software stack"),
and it grows towards lower memory addresses with each "push" operation
(i.e. the "stack top" is located at a lower address than the "stack
bottom").
The stack pointer register SP always indicates the next
free
memory location that will be claimed by the stack during any subsequent
push.
Stack operations can access both 8-bit and 16-bit data, with 16-bit data
being stored on the stack in big-endian format, consistent with the
general memory organization.
Following is a C-like description of the generic "push" and "pull" stack
operations, with Mem[] being a 65536-location (64K) array representing
the system memory bytes, S being the processor's stack pointer, Operand8
being an 8-bit operand, Operand16 being a 16-bit oeprand, and .LOW and
.HIGH representing the low-order and respectively the high-order byte of
a 16-bit operand:
PUSH Operand8: Mem[S--] := Operand8;
PULL Operand8: Operand8 := Mem[++S];
PUSH Operand16: Mem[S--] := Operand16.LOW; Mem[S--] := Operand16.HIGH;
PULL Operand16: Operand16.HIGH := Mem[++S]; Operand16.LOW := Mem[++S];
» See also:
memory organization ,
special
SP operations
Interrupts
The MPU 6916 architecture supports two types of interrupts:
hardware
interrupts and
software interrupts. The processor only
accepts the hardware interrupt requests if the
hardware interrupt
mask bit in the Condition Codes Register (the CCR[I] bit) is
reset.
The processor treats both types of interrupts in a similar way, with the
following differences:
- hardware interrupts are triggered by the assertion of a dedicated
"processor interrupt" electrical signal and can be disabled by
setting the hardware interrupt mask bit CCR[I], while
software interrupts are triggered by the exectution of a dedicated
SWI software Interrupt instruction and can not be disabled
(masked).
- two separate interrupt routines are invoqued for serving the
hardware- and software interrupts; the addresses of these routines
are known as the hardware interrupt vector and respectively
the software interrupt vector, and are both 16-bit data
located at two fixed memory locations defined by the MPU 6916
architecture: the hardware
interrupt vector location and the software interrupt
vector location.
Following is a detailed description of the interrupt response sequnce:
- For hardware interrupts, first the interrupt mask bit
CCR[I] is tested and, if clear, the processor eneters the interrupt
acknowledge phase; else the processor continues with the execution
of the sequentially-next instruction.
For software interrupts the processor always proceeds to the
interrupt acknowledge phase.
- during the interrupt acknowledge phase the following sequence of
micro-operations is performed:
- the processor's internal registers Z, H, and L are
sequentially pushed onto the stack, in this exact order
- the processor pushes the "return from interrupt address"
onto the stack; for software interrupts the return address is
the next sequential address after the SWI instruction, while for
hardware interrupts the return address is the address of the
next instruction that was to be executed when the interrupt was
acknowledged
- the processor's internal registers Y, X, A, B, and CCR are
sequentially pushed onto the stack, in this exact order
- the interrpt mask bit CCR[I] is set in order to prevent
recurring interrupts of the interrupt-routine itself; note
however that the state of the interrupt mask bit prior to the
interrupt was saved onto the stack (when CCR was saved), thus
allowing the procesor to revert to the exact state it
had prior to the interrupt (this can be accomplished by
executing the dedicated return from interrupt RTI
instruction)
- one of the two 16-bit "software interrupt vector" or "hardware
interrupt vector" is read from its corresponding memory
location (according to the interrupt type), and then loaded into
the Program Counter register PC (i.e. the 16-bit interrupt
vector is interpreted as a Jump address).
[Remark:] the unusual push sequence described above (i.e. the return
from
interrupt address being pushed "between" the internal
registers) is implemented such that the closest possible
compatibility is maintained between the MPU 6916 and the M6811
microprocessor (the latter does not implement the Z and E
registers); this way the
exact post-interrupt "top of stack" structure is maintained
compatible with the M6811.
» See also:
stack operations ,
condition
codes register ,
RTI instruction ,
SWI
instruction
Processor Reset
The MPU 6916 processor can be reset by asserting its dedicated "Reset"
electrical signal. Following is a detailed description of the reset
sequence of micro-operations:
- first the processor reads the 16-bit reset vector stored
in memory at the reset vector location; this location is a
fixed memory address defined by the MPU 6916 architecture
- the Condition Codes Register CCR bits are all set (the register
is loaded with hex 0xff); this ensures that all interrupts are
initially disabled after a processor reset
- finally the reset vector is loaded in the Program Counter
register PC, effectively starting program execution beginning with
the instruction located at the memory address "reset vector"
(for example, if the reset vector location stores 0x0000,
the reset vector is 0x0000 and thus program execution will start
with the instruction located at address 0)
» See also:
condition codes register
The Condition Codes Register - CCR
The 8-bit Condition Codes Register (CCR) stores various processor status
bits (known as "
falgs") that are related to the results of
previously-executed instructions, and also several monitor bits that
control and/or report the general state of the processor. Following is
the list of the CCR bits, their bit-position within the CCR, and a brief
explanation of their function.
Name |
Position |
Description |
Special-purpose Flags |
CCR[S]: Stop disable |
bit 7 |
this bit controls the behavior of the proessor when exectuting
a STOP instruction (see STOP instruction) |
CCR[X]: Reserved |
bit 6 |
this bit is reserved for future processor functionality and
should not be relyed upon in software. |
CCR[H]: Half-carry |
bit 5 |
various arithmetic instructions copy the "half-carry" bit that
results during their exectution into this special-purpose flag;
the half-carry is the carry value between bit 3 and bit 4 during
an arithmetic operation (most logic operations do not affect
this flag). |
CCR[I]: Hardware interrupt mask |
bit 4 |
this bit controls the behavior of the proessor when reacting
to a hardware interrupt request (see interrupts). |
General Arithmetic Flags |
CCR[N]: Negative (sign) |
bit 3 |
set by various instructions if the result was a signed
negative value, and reset if the result was a signed positive
value |
CCR[Z] Zero |
bit 2 |
various instructions set this flag if the result was zero, and
reset it otherwise |
CCR[V] oVerflow |
bit 1 |
most arithmetic instructions set this flag if the result
generated a signed-arithmetic overflow, and reset it otherwise
(the shift and rotate instructions load this flag with
result_sign ^ resulting_carry, and most logic instructions clear
this flag) |
CCR[C]: Carry |
bit 0 |
various arithmetic instructions set this flag if the result
generated a carry, and reset it otherwise (most logic
instructions leave this flag unchanged) |
Addressing Modes
The MPU 6916 features a
highly orthogonal
memory-to-register-oriented intruction set, with limited support
for register-to-register operations. The following addressing modes are
supported for memory operands:
- immediate: the instruction operand is an 8-bit or 16-bit
numeric value, and is stored within the program memory area
imediately after the instruction opcode
Operand assembler syntax: #value
- zero-page: the instruction specifies the operand by
providing the low-order 8 bits of its address, while the upper 8
bits of the address are always zero (thus the operand is always
located in memory page zero, in the address range 0x0000 to 0x00ff)
Operand assembler syntax: (addr8)
- direct: the instruction specifies a 16-bit address for
the operand, thus providing direct access to 64K of memory
Operand assembler syntax: (addr16)
- indexed: the instruction provides an 8-bit offset that is
added with the contents of one of the index registers (X, Y, or Z),
thus resultig a 16-bit memory address for the operand (the index
register contents is not altered). Both signed and unsigned
offsets are supported, thus the effective offset range is
[-128,255]. The unsigned offset is supported by the MPU 6916 for
backwards compatibiliy with the M6811 (as a side-effect, offset
values in range [0...127] may be coded both as unsigned or signed)
Operand assembler syntax: (offset8,X) , (offset8,Y) , (offset8,Z)
- relative: the instruction provides a 16-bit signed offset
that is added with the contents of the program counter PC, thus
resultig a 16-bit memory address for the operand
Operand assembler syntax: (offset16,PC)
- short relative control flow: the instruction provides an
8-bit signed offset that is added with the contents of the program
counter PC, thus resultig a 16-bit memory address for the operand. This
addressing mode is only used by some control flow instructions.
Operand assembler syntax: (offset8)
Instruction Set
Table 1 lists the complete MPU 6916 instruction set, together with the
applicable addressing modes for each instruction. The following
notations are used:
- in the "Mnemonic", "Description", and "Operation" fields, oper
represents an operand accessed using any of the addressing modes
allowed for each instruction as specified in the instruction's
"Modes" field; short is the special short-relative
addressing mode operand used only by the branch control-flow
instructions; mask is a special 8-bit operand used by a
small set of bitwise instructions; a represents any of the
four 8-bit accumulators A, B, H, L, d represents any of the
16-bit double accumulators D, E; and x represents any of the
three 16-bit index registers X, Y, Z.
- the "Operand" field specifies the instruction's valid addressing
modes types for single-operand instructions, or the for the second
source operand for two-operand instructions (in this latter case one
of the processor's internal registers act as the instruction's first
source operand and also as the instruction's destination register):
i for immediate; a for accumulators A, B, H, L; x
for indexed addressing (using any of the X, Y, Z index registers,
and any of signed or unsigned 8-bit offsets); z for zero
page addressing; d for direct addressing; r for
relative addressing; and short for the short-relative
addressing mode (this addressing mode is supported by the branch
control-flow instructions olny).
- the Mem[...] notation in the "Operation" field
represents the system memory locations. For 16-bit operands, the
notation Mem[n] represents a pair of two consecutive locations
{Mem[n],Mem[n+1]}, with Mem[n] holding the high-order 8 bits of the
operand, and Mem[n+1] holding the low-order 8 bits ("big-endian"
memory architecture).
- the way the Condition Codes register's bits are affected by each
individual instruction is indicated in the "NZVC" field (i.e. the
CCR bits): N represents the sign ("Negative") CRR bit; Z
represents the Zero CRR bit; V represents the oVerflow CRR
bit; and C represents the Carry CRR bit.
Mnemonic |
Description |
Operation |
Operand |
N
|
Z
|
V
|
C
|
Notes |
8-bit OPERATIONS GROUP |
Note |
LDA a oper |
Load a |
a:=oper |
i z d x r |
N |
Z |
0 |
|
STA a oper |
Store a |
oper:=a |
z d x r |
N |
Z |
0 |
|
TAB |
Transfer A to B |
B:=A |
|
N |
Z |
0 |
|
TBA |
Transfer B to A |
A:=B |
|
N |
Z |
0 |
|
THL |
Transfer H to L |
L:=H |
|
N |
Z |
0 |
|
TLH |
Transfer L to H |
H:=L |
|
N |
Z |
0 |
|
PSH a |
Push a on stack |
Mem[S- -]:=a |
|
|
|
|
|
PUL a |
Pull a from stack |
a:=Mem[++S] |
|
|
|
|
|
ADD a oper |
Add to a |
a+=oper |
i z d x r |
N |
Z |
V |
C |
ADC a oper |
Add with carry to a |
a+=oper+CCR[C] |
i z d x r |
N |
Z |
V |
C |
SUB a oper |
Subtract from a |
a-=oper |
i z d x r |
N |
Z |
V |
C |
SBC a oper |
Subtract with carry from a |
a-=oper+CCR[C] |
i z d x r |
N |
Z |
V |
C |
CMP a oper |
Compare a |
a-oper |
i z d x r |
N |
Z |
V |
C |
BIT a oper |
Bitwise test a |
a&oper |
i z d x r |
N |
Z |
0 |
|
AND a oper |
And with a |
a&=oper |
i z d x r |
N |
Z |
0 |
|
ORA a oper |
Or with a |
a|=oper |
i z d x r |
N |
Z |
0 |
|
EOR a oper |
Exclusive Or with a |
a^=oper |
i z d x r |
N |
Z |
0 |
|
INC oper |
Increment |
++oper |
a d x r |
N |
Z |
V |
|
DEC oper |
Decrement |
- -oper |
a d x r |
N |
Z |
V |
|
NEG oper |
Negate |
oper:=0-oper |
a d x r |
N |
Z |
V |
C |
COM oper |
One's Complement |
oper^=-1 |
a d x r |
N |
Z |
0 |
1 |
Note |
CLR oper |
Clear |
oper:=0 |
a d x r |
0 |
1 |
0 |
0 |
BSET oper mask |
Set bits |
oper|=mask |
z d x r |
N |
Z |
0 |
|
BCLR oper mask |
Clear bits |
oper&=!mask |
z d x r |
N |
Z |
0 |
|
TST oper |
Test vs zero |
oper-0 |
a d x r |
N |
Z |
0 |
0 |
LSR oper |
Logic Shift Right |
|
a d x r |
N |
Z |
V |
C |
Note |
ASL oper |
Logic Shit Left |
oper<<=1 |
a d x r |
N |
Z |
V |
C |
Note |
ASR oper |
Arithmetic Shift Right |
oper>>=1 |
a d x r |
N |
Z |
V |
C |
Note |
ROR oper |
Rotate Right |
|
a d x r |
N |
Z |
V |
C |
Note |
ROL oper |
Rotate Left |
|
a d x r |
N |
Z |
V |
C |
Note |
ABA |
Add B to A |
A+=B |
|
N |
Z |
V |
C |
ALH |
Add L to H |
H+=L |
|
N |
Z |
V |
C |
SBA |
Subtract B from A |
A-=B |
|
N |
Z |
V |
C |
SLH |
Subtract L from H |
H-=L |
|
N |
Z |
V |
C |
CBA |
Compare B to A |
A-B |
|
N |
Z |
V |
C |
CLH |
Compare L to H |
H-L |
|
N |
Z |
V |
C |
SXTB |
Sign-extend B in D |
|
|
N |
Z |
0 |
0 |
Note |
SXTL |
Sign-extend L in E |
|
|
N |
Z |
0 |
0 |
Note |
MUL |
Unsigned 8-bit multiply |
D:=A*B |
|
|
|
|
C |
DAA |
Decimal Adujst A after addition |
|
|
N |
Z |
V |
C |
Note |
CCR OPERATIONS GROUP |
CLC |
Clear Carry Flag |
CCR[C]:=0 |
|
|
|
|
0 |
SEC |
Set Carry Flag |
CCR[C]:=1 |
|
|
|
|
1 |
CLV |
Clear Overflow Flag |
CCR[V]:=0 |
|
|
|
0 |
|
SEV |
Set Overflow Flag |
CCR[V]:=1 |
|
|
|
1 |
|
TAP |
Transfer A to CCR |
CCR:=A |
|
N |
Z |
V |
C |
TPA |
Transfer CCR to A |
A:=CCR |
|
|
|
|
|
16-bit ACCUMULATOR GROUP |
Note |
LD d oper |
Load d |
d:=oper |
i z d x r |
N |
Z |
0 |
|
ST d oper |
Store d |
oper:=d |
z d x r |
N |
Z |
0 |
|
XGDE |
Exchange D with E |
E <-> D |
|
N |
Z |
0 |
|
ADD d oper |
Add to d |
d+=oper |
i z d x r |
N |
Z |
V |
C |
SUB d oper |
Subtract from d |
d-=oper |
i z d x r |
N |
Z |
V |
C |
CMP d oper |
Compare d |
d-oper |
i z d x r |
N |
Z |
V |
C |
AED |
Add E to D |
D+=E |
|
N |
Z |
V |
C |
SED |
Subtract E from D |
D-=E |
|
N |
Z |
V |
C |
CED |
Compare D to E |
D-E |
|
N |
Z |
V |
C |
MED |
16-bit unsigned integer multiply |
D*=E |
|
|
|
|
C |
LSR d |
Logic Shift Right d |
|
|
N |
Z |
V |
C |
Note |
ASR d |
Arithmetic Shift Right d |
d>>=1 |
|
N |
Z |
V |
C |
Note |
ASL d |
Logic Shift Left d |
d<<=1 |
|
N |
Z |
V |
C |
Note |
IDIV |
16-bit unsigned integer divide |
|
|
|
|
|
|
Note |
FDIV |
16-bit unsigned fractional divide |
|
|
|
|
|
|
Note |
16-bit POINTERS OPERATIONS GROUP |
Note |
LD x oper |
Load x with r |
x:=oper |
i z d x r |
N |
Z |
0 |
|
ST x oper |
Store x |
oper:=x |
z d x r |
N |
Z |
0 |
|
PSH x |
Push x on stack |
Mem[S- -]:=x |
|
|
|
|
|
PUL x |
Pull x from stack |
x:=Mem[++S] |
|
|
|
|
|
XG d x |
Exchange d with x |
d <-> x |
|
|
|
|
|
CP x oper |
Compare x |
x-oper |
i z d x r |
N |
Z |
V |
C |
IN x |
Increment x |
++x |
|
|
Z |
|
|
DE x |
Decrement x |
- -x |
|
|
Z |
|
|
ADD x oper |
16-bit Add to x |
x+=oper |
i d x r |
|
|
|
|
Note |
AB x |
Add zero-extended B to x |
x+=ZeroXT(B) |
|
|
|
|
|
Note |
STACK POINTER OPERATIONS GROUP |
Note |
LDS oper |
Load S |
S:=oper |
i z d x r |
N |
Z |
0 |
|
STS oper |
Store S |
oper:=S |
z d x r |
N |
Z |
0 |
|
T S x |
Special transfer S to x |
x:=S+1 |
|
|
|
|
|
T x S |
Special transfer x to S |
S:=x-1 |
|
|
|
|
|
INS |
Increment S |
++S |
|
|
|
|
|
DES |
Decrement S |
- -S |
|
|
|
|
|
CONTROL FLOW GROUP |
Note |
NOP |
No opeartion |
|
|
|
|
|
|
JMP oper |
Jump |
PC:=&oper |
d x r |
|
|
|
|
JSR oper |
Jump to soubroutine |
Mem[S- -]:=Next_PC; PC:=&oper |
z d x r |
|
|
|
|
Note |
RTS |
Return from soubroutine |
PC:=Mem[++S] |
|
|
|
|
|
Note |
BSR short |
Branch to soubroutine |
Mem[S- -]:=Next_PC; PC+=&oper |
short |
|
|
|
|
Note |
BRA short |
Branch |
PC+=&oper |
short |
|
|
|
|
B cond short |
Branch if condition true |
cond ? PC+=&oper |
short |
|
|
|
|
Note |
PROCESSOR CONTROL GROUP |
CLI |
Enable Interrupts |
CCR[I]:=0 |
|
|
|
|
|
SEI |
Disable Interrupts |
CCR[I]:=1 |
|
|
|
|
|
SWI |
Software Interrupt |
|
|
|
|
|
|
Note |
WAI |
Wait for Interrupt |
|
|
|
|
|
|
Note |
RTI |
Return from Interrupt |
|
|
N |
Z |
V |
C |
Note |
STOP |
CPU Stop |
|
|
|
|
|
|
Note |
Table 1: the MPU 6916 instruction
set
The individual instructions' object codes are detailed in the
MPU
6916 internal architecture document.
Instruction Set Notes
In the instruction set table above, notes attached to an entire
instruction group (next to the group title) apply to all instructions
belonging to that group, while notes attached to individual instructions
apply to those specific instructions only. [
skip notes »]
- as a general rule within the 8-bit instructions group, all
instructions that access a memory operand can utilize any of the
immediate, zero-page, direct, relative, or indexed addressing modes
for the memory reference (exception: memory-modifying instructions
cannot use the immediate addressing mode).
[Remark:] the 8-bit register-to-register instructions are highly
irregular, and are limited to operations between the two 8-bit
accumulators that "belong" to the same 16-bit double accumulator
(i.e. A and B, and respectively H and L). For example, TAB (transfer
A to B) is a valid instruction, but TBL (transfer B to L) is not
valid.
- the unusual way the COM instruction affects the Confition Codes
Register (CCR) is meant to ensure that all conditional branches
will perform consistently after complementing a signed value.
However, only the BEQ and BNE conditional branches will perform
consistently after an unsigned value is complemented.
» See also: conditional branches
- the MPU 6916 implements three types of shift instructions:
Arithmetic Shift Left (ASL), Arithmetic Shift Right (ASR), and Logic
Shift Right (LSR).
- ASL shifts the operand's bits one position "to the left" by
inserting a 0 bit in the least significant bit position (bit 0);
the C-equivalent operator is "<<"
- ASR is similar to the LSR, but the operand is shifted "to the
right" by inserting a copy of its own sign bit into the most
significant bit (i.e. the operand sign is preserved via ASR) ;
the C-equivalet operator is ">>"
- LSR shifts the operand's bits one position "to the right" by
inserting a 0 bit in the most significant bit position (bit 7
for 8-bit operands, and bit 15 for 16-bit operands); there is no
C-equivalent operator
For all the three instruction, the bit that is "shifted out"
from the operand is loded into the condition codes register's CCR
Carry bit (CCR[C]).
Examples
LSRD; 0 -> D[15] -> D[14] ... D[0] -> CCR[C]
ASRA; A[7] -> A[7] -> A[6] ... A[0] -> CCR[C]
ASL (addr16); CCR[C] <- (addr16)[7] <- (addr16)[6] ... (addr16)[0] <- 0
- the Rotate Right (ROR) and Rotate Left (ROL) instructions perform
a bit-by-bit rotation of the operand through the condintion code
register's CCR Carry bit (CCR[C]).
Examples:
RORA; CCR[C] -> A[7] -> A[6] ... A[0] -> CCR[C]
ROL (addr16); CCR[C] <- (addr16)[7] <- (addr16)[6] ... (addr16)[0] <- CCR[C]
- the Sign eXtend instructions operate on the double accumulators D
and E by sign-extending their low-order half (i.e. the B and L 8-bit
accumulators respectively) into their high-order half (i.e. the A
and H 8-bit accumulators respectively).
Example
SXTB; B[7]==1 ? A:=0xff : A:=0x00
- the Decimal Adjust Accumulator A (DAA) must be used immediately
after an 8-bit addition that has accumulator A as destination, and
it assumes the operands of the addition were in BCD (binary coded
decimal) reprezentation; in this case, the instruction execution
converts the binary result of the addition stored in A into BCD
reprezentation.
Example:
LDAA #$25; load hexa 0x25 (high nibble=0x2, low nibble=0x5); binary value=37
ADDA #$38; add hexa 0x38 (high nibble=0x3, low nibble=0x8); binary value=56
; the addition result in A is 37+56=93, i.e. hex 0x5D
DAA ; convert the 8-bit binary value 93 (hex 0x5D) to hex 0x93, which is
; the correct BCD addtion result
- as a general rule within the 16-bit accumulator group, all
instructions that access a memory operand can utilize any of the
immediate, zero-page, direct, relative, or indexed addressing modes
for the memory reference (exception: memory-modifying instructions
cannot use the immediate addressing mode).
- the IDIV and FDIV instructions perform special 16-bit division
operations on the M6811 architecture, but are implemented as a
special type of software interrupts on the MPU 6916.
The only difference between the IDIV/FDIV "software interrupts" and
SWI consists in the interrupt vector location used in each
of the three cases: specifically, in addition to the software
interrupt vector location used by SWI, the MPU 6916
architecture defines a dedicated interrupt vector location
for the FDIV and IDIV instructions, and it is the responsibility of
the software interrupt routine to detect which instruction code
generated the software interrupt and proceed accordingly. Any
processor configuration can be returned by the IDIV/FDIV software
interrupt subroutine upon its completion.
- note: the IDIV/FDIV software interrupt vector is in fact used
for any software-emulated instructions, i.e. any instruction
code that the processor does not recognize will trigger the
above-mentioned software interrupt subroutine.
» See also: software interrupts
- the 16-bit pointers operations gruop gathers the index registers
X, Y, and Z operations. The index register increment/decrement
operations (INx, DEx) alter the Condition Code Register's zero bit
CCR[0] thus allowing them to be directly used as 16-bit loop
conters.
- the "ADDx oper" instructions allow adding a signed 16-bit value
to the index registers, and are specially intended for providing a
convenient set of pointer-manipulation functions that do not
affect any of the Condition Codes Register bits.
- the ABx instruction adds the zero-extended 8-bit value
stored in B to an index register, and no condition code register
bits are affected. Because this addition instruction
interprets the contents of the source accumulator as an unsigned
positive value (in range 0 ... 255), the index registers
cannot be decremented using this instruction.
[Remark:] this instruction is included in the MPU 6916 instruction
set only for backwards compatibility with the M6811
- The stack pointer (SP) is a special-purpose register, and its
associated instructions have special functionality compared to
the index registers
- the TxS and TSx instructions perform special transfer
operations meant to compensate the fact that the stack
pointer register SP is pointing to the next free location on
the stack. In order to allow indexed addressing modes to directly
access the stack data, a transfer from the SP register
actually transfers the value SP+1 into an index register
(thus making the index register point to the first available
data on the stack), and a transfer from an index register
into the SP register actually transfers the value x-1
(thus preparing future stack operations).
- the stack pointer increment/decrement opeartions (INS, DES) do
not alter any Condtion Code Register (CCR) bits
» See also: stack layout
- the control flow group includes some dedicated instructions ("branches"
in Motorola terminology) that utilize the short relative
addressing mode (see the description of the MPU 6916 addressing
modes at the beginning of this section).
a particularity of the control flow instructions is that
they use a special variation of the standard MPU 6916 addressing
modes, where the address indicated by the instructions (via the
addressing mode) is itslef used as the instruction argument
rather than being interpreted as the address of a memory operand
(this is outlined in the "description" field in Table 1 by the
"&oper" C-like dereferencing notation). For example, if X is
1000, a JMP (20,X) instruction will result in a jump to location
1020, contrary to the standard interpretation of the (20,X)
addressing mode which would have resulted in reading the 16-bit
memory location Mem[1020] and using its contents as a 16-bit Jump
target.
Examples:
BRA (20) ; the BRA instruction implies relative addressing mode;
; the Branch target is 20+PC, and not the 16-bit
; value stored in memory location Mem[20+PC]
JMP (20,X); the instruction address is calculated by adding 20
; to the contents of the X index register, and the
; resulting address itself (i.e. 20+X) is the Jump target
[Remark:] The correct assembler notation for a Jump instruction
targeting the location target would be "JMP target" instead
of the standard Motorola notation "JMP (target)". The M6916
assemblers allows this form of correct notation for all
control flow instructions.
- the JSR instruction performs a subroutine call, and the BRS
instruction is the special short-relative addressing mode
equivalent of the JSR instruction.
A subroutine call operation consists of two main sequential stages:
first the address immediately following the subroutine call
instruction is pushed onto the system stack (using a standard 16-bit
operand "push" sequence), and then the program counter register (PC)
is loaded with the target address as specified by the subroutine
call.
The RTS instruction is the reciprocal of a subroutine call: the
original subroutine-caller program is "resumed" by pulling out from
the stack the resume address (using a standard 16-bit "pull"
sequence), and loading it into the program counter register (PC).
» See also: stack operations
- conditional branches are the only condition-based control flow
instructions in the MPU 6916 instruction set. These instruction
behave as standard branches if the specified condition holds true,
and as NOP (no operation) instructions if the condition is evaluated
as false.
The following table lists the complete set of conditional branches
included in the MPU 6916 instruction set. The "syntax" field
lists the complete assembler syntax of a conditional branch
operation, the "description" field specifies the
interpretation of the branch condition (in the signed and unsigned
comparison sections, the Conditional Branch semantics assumes the
branch immediately follows a comparison instruction), and the "condition"
field specifies the formula used to evaluate the condition.
The following notations are used:
- short is the short-relative addressing mode target of
the branch instruction
- oper is the 8-bit memory-based operand used by the
bitwise-test branches; all addressing modes are supported
(zero-page, direct, indexed, relative)
- mask is the 8-bit immediate operand used by the
bitwise-test branches
- N, Z, V, C are shorts for the Condition Codes Register
bits CCR[N], CCR[Z], CCR[V], and CCR[C]
Syntax |
Description |
Condition |
Bitwise tests |
BRSET oper mask short |
branch if selected bits are set |
!oper & mask |
BRCLR oper mask short |
branch if selected bits are clear |
oper & mask |
Direct CCR-bits tests |
BMI short |
branch if minus |
S==1 |
BPL short |
branch if plus |
S==0 |
BEQ short |
branch if equal |
Z==1 |
BNE short |
branch if not equal |
Z==0 |
BCS short |
branch if carry set |
C==1 |
BCC short |
branch if carry clear |
C==0 |
BVS short |
branch if overflow set |
V==1 |
BVC short |
branch if overflow clear |
V==0 |
Signed comparisons tests |
BGT short |
branch if greater than |
Z | (N^V) == 0 |
BLT short |
branch if less than |
N^V == 1 |
BGE short |
branch if greater or equal |
N^V == 0 |
BLE short |
branch if less or equal |
Z | (N^V) == 1 |
Unsigned comparisons tests |
BHI short |
branch if higher |
C | Z == 0 |
BLO short |
branch if lower (equiv. to BCS) |
C==1 |
BHS short |
branch if higher or same (equiv. to BCC) |
C==0 |
BLS short |
branch if lower or same |
C | Z == 1 |
[Remark:] the BRSET and BRCLR instructions are special cases of
conditional branches, where the branch condition results from a
bitwise test between an 8-bit mask and a memory location.
Apart from the specificity of these instruction's format (i.e. these
are the only branches that use operands for specifying the test
condition), they are similar with the rest of conditional branches
found in the MPU 6916 instruction set.
- the SWI ("software interrupt") instruction can be used to trigger
an interrupt response sequence at a specific position within a
program. The overall behavior of the processor when executing a SWI
instruction is similar to a subroutine call, except:
- before entering the software interrupt routine all the
processor registers are automatically pushed on the stack and future
interrupts are disabled
- the 16-bit interrupt routine address is automatically
extracted from the fixed software interrupt vector location.
This behavior makes the SWI instruction a favorite choice for
operating system calls in many applications.
» See also: interrupts
- the WAI "wait for interrupt" instruction is similar to the SWI
instruction, with the following differences:
- the hadware interrupt vector is used as the interrupt
routine address (instead of the software interrupt vector for
the SWI instruction)
- loading the Program Counter register PC with the 16-bit
harware interrupt vector (i.e. triggering the execution of the
hardware interrupt routine) is postponed until a hardware
interrupt is detected. Furthermore, the hardware
interrupt routine will not be entered if the hardware
interrupt mask bit is set (i.e. if interrupts are
disabled)
Thus, the WAI instruction prepares the processor for accepting a
hardware interrupt request, but does not actually initiate the
interrupt routine until an interrupt is detected.
» See also: the SWI instruction
[Remark:] if the hardware interrupt mask bit is set (i.e. interrupts
are disabled) the processor will eneter a wait state that can only
be exited by resetting the processor. However, because the processor
does push the contents of its internal register on the stack,
the pushed data could potentially be used after a reset operation to
detect/restore the processor state prior to the WAI execution.
- the "Return From Interrupt" RTI instruction is specifically
intended to complete the execution of an interrupt routine
regardless of the interrupt type (hardware or software), and it is
the reciprocal of a SWI (Softwave Interrupt) instruction.
Following is a detailed description of the sequence of
micro-operations performed by the RTI instruction:
- first the CCR, B, A, X, and Y processor registers are pulled
from the stack in this exact order (i.e. in reverse
order compared to the one in which they are pushed by a SWI
instruction or a hardware interrupt)
- the 16-bit return from interrupt address is pulled
from the stack
- the L, H, and Z processor registers are pulled from the stack
in this exact order (i.e. in reverse order compared to
the one in which they are pushed by a SWI instruction or a
hardware interrupt)
- the return from interrupt address (that was previously pulled
from the stack) is loaded into the Program Counter PC register,
thus allowing the processor to resume the interrupted program
starting with the next instruction after the last executed
instruction.
Because the complete processor state (as determined by its internal
registers) can be restored to the exact value at the time of the
(hardware or software) interrupt, a proper usage of the RTI
instrucition can allow interrupted programs to run unaffected by
interrupts.
» See also: interrupts
[Reamark:] because the interrupt routine can assemble from the stack
the complete processor state at the moment of the interrupt, RTI can
also be used to change the course of the normal program flow by
altering the processor registers in a controlled way (for example,
this method is widely used to switch threads in multi-threaded
applications).
- the STOP instruction first checks the stop disable bit in
the Condition Codes Register (CCR[S]) and, if the bit is reset,
the CPU is completely halted until it is reset via the hardware
reset pin; if the CCR[S] bit is set (i.e. stop is disabled) then the
STOP instruction is interpreted as a NOP (no operation) instruction
and no action is taken. No flags in the CCR are affected in any of
the two cases.
MPU 6916
Compatibility Details
This section summarizes the differences between the MPU 6916 and the
M6800/M6811 microprocessors (see also the
MPU
6916 Overview document for a comparative introduction to the three
architectures).
M6800 Compatibility
The MPU 6916 microprocessor core extends the M6800
architecture, but retains object-code and functional compatibility with
the M6800 microprocessor.
The following architectural features are MPU 6916-specific and are
not
available
on the M6800
- index registers Y and Z are not implemented in the M6800
- the Y-based and Z-based indexed addressing modes are not
available on the M6800
- all instructions that use the Y and/or Z index registers as
operands are not implemented on the M6800
- signed offset for the indexed addressing mode is not suppoted by
the M6800
- the relative addressing mode is not implemented in the M6800
(however the short-relative addressing mode used only by the branch
control-flow instructions is available on the M6811)
- the H and L 8-bit accumulators (and the E double accumulator) are
not implemented in the M6800, and thus all instructions utilizing
any of H, L, or E are not available on the M6800
- the following instructions are not implemented in the M6800 (in
addition to the ones that utilize the MPU 6916-specific registers)
- BSET, BCRL (bitwise memory operations)
- BRSET, BRCLR (bitwise test-based conditional branches)
- SXTB (sign-extend B inside the double accumulator D)
- CMPD (16-bit comparisons)
- ASRD (16-bit arithmetic shift right)
- ABX, ADDX (16-bit pointer operations)
- MUL (8-bit unsigned multiplication)
- MULD (16-bit unsigned multiplication)
M6811 Compatibility
The MPU 6916 microprocessor core retains object-code and
functional compatibility with the M6811 microprocessor, with the
following exceptions:
- the M6811 interrupts can use more than one hardware interrupt
vector (with the selection being made based on a set of
hardware inputs), while the MPU 6916 uses a single hardware
interrupt vector. See also: interrupts
- the CCR[X] bit is implemented as interrupt mask for an
M6811-specific type of hardware interrupt, while the MPU 6916
architecture defines this bit as reserved
- the M6811 implements the IDIV and FDIV instructions in hardware,
while the MPU 6916 architecture defines these instructions as
special SWI-like instructions (a specific software interrupt
vector location is defined for IDIV and FDIV, and these
instructions must be implemented as software subroutines). See also:
FDIV, IDIV
- the M6811 system-debug TEST instruction is not implemented by the
MPU 6916
The following architectural features are MPU 6916-specific and are
not
available
on the M6811
- index register Z is not implemented in the M6811
- the Z-based indexed addressing mode is not available on the
M6811
- all instructions that use the Z index register as operand are
not implemented on the M6811
- signed offset for the indexed addressing mode is not suppoted by
the M6811
- the relative addressing mode is not implemented in the M6811
(however the short-relative addressing mode used only by the branch
control-flow instructions is available on the M6811)
- the H and L 8-bit accumulators (and the E double accumulator) are
not implemented in the M6811
- all instructions utilizing any of H, L, or E are not available
on the M6811.
- direct addressing mode for the following instructions is not
supported by the M6811
- BSET, BCLR (set and clear bits in memory)
- BRSET, BRCLR (bitwise test-based conditional branches)
- the following instructions are not implemented in the M6811 (in
addition to the ones that utilize the MPU 6916-specific registers)
- SXTB (sign-extend B inside the double accumulator D)
- ASRD (16-bit arithmetic shift right)
- ADDX, ADDY (16-bit pointer operations)
- MULD (16-bit unsigned multiplication)