MPU 6916 Software Reference Guide

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


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: Following is a detailed description of the interrupt response sequnce: » 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: » 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:

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:
Mnemonic Description Operation Operand N
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
ALH Add L to H H+=L
SBA Subtract B from A A-=B
SLH Subtract L from H H-=L
CBA Compare B to A A-B
CLH Compare L to H H-L
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

DAA Decimal Adujst A after addition

N Z V C Note
CLC Clear Carry Flag CCR[C]:=0

SEC Set Carry Flag CCR[C]:=1

CLV Clear Overflow Flag CCR[V]:=0

SEV Set Overflow Flag CCR[V]:=1

TAP Transfer A to CCR CCR:=A
TPA Transfer CCR to A A:=CCR

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
SED Subtract E from D D-=E
CED Compare D to E D-E
MED 16-bit unsigned integer multiply D*=E

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

FDIV 16-bit unsigned fractional divide

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


DE x Decrement x - -x


ADD x oper 16-bit Add to x x+=oper i    d x r

AB x Add zero-extended B to x x+=ZeroXT(B)

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

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

RTS Return from soubroutine PC:=Mem[++S]

BSR short Branch to soubroutine Mem[S- -]:=Next_PC; PC+=&oper short

BRA short Branch PC+=&oper short

B cond short Branch if condition true cond ? PC+=&oper short

CLI Enable Interrupts CCR[I]:=0

SEI Disable Interrupts CCR[I]:=1

SWI Software Interrupt

WAI Wait for Interrupt

RTI Return from Interrupt

N Z V C 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 »]
  1. 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.

  2. 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

  3. 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]).
    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
  4. 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]).
    RORA; CCR[C] -> A[7] -> A[6] ... A[0] -> CCR[C]
    ROL (addr16); CCR[C] <- (addr16)[7] <- (addr16)[6] ... (addr16)[0] <- CCR[C]
  5. 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).
    SXTB; B[7]==1 ? A:=0xff : A:=0x00
  6. 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.
    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
  7. 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).

  8. 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

  9. 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.

  10. 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.

  11. 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

  12. 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

  13. 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.
    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.

  14. 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

  15. 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.

  16. 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

  17. 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.

  18. 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).

  19. 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

M6811 Compatibility

The MPU 6916 microprocessor core retains object-code and functional compatibility with the M6811 microprocessor, with the following exceptions: The following architectural features are MPU 6916-specific and are not available on the M6811