68HC08 Introduction

        .cr     68hc08      To load this cross overlay

The Motorola 68HC08 family of micro controllers are the successors of the popular 6805 family. The CPU core of this family is referred to as the CPU08. Don't mistake the 68HC08 with the very early 6808, which was basically a 6800 with on chip crystal oscillator. Thus apart from the fact that they are both Motorola products, they are totally unrelated to each other.
The 68HC08 is downward compatible with the 68HC05, both in source code as in object code. This means that a program created for the 68HC05 should be able to run unchanged on a 68HC08, it will only be a lot faster. Motorola has increased the execution speed of the processor and has added some extra instructions and addressing modes. And the most welcome enhancement is the extended index register, which is now capable of indexing 16-bit addresses.

Please refer to Motorola's application note AN1218 which gives a clear comparison between the 68HC05 and 68HC08 cores.

Programming Model

The programming model of the 68HC08 is still very modest, compared to other processors. I only include a little summary about the features of the 68HC08's programming model here. It is not my intention to make the original documentation obsolete, so please refer to the original documentation for further details.

68hc08 programming model

Don't be alarmed by the small number of registers compared to other processor types. The 68HC08 has a very powerful addressing mode called direct page addressing. This way all 256 bytes of page 0 in memory can be addressed with only 8 bits. These 256 addresses can be considered the "registers" of the 68HC08!
All I/O related memory is also located in page 0, which makes I/O access quite fast.

The Accumulator A

The Accumulator is used for all arithmetic operations.

The Condition Code Register

The CCR register holds all the system flags. Most flags reflect the status of the machine after mathematical instructions.

The CCR contains 6 system flags:

Bit 7VTwo's complement overflow Flag
Bit 61Aleays reads 1
Bit 51Aleays reads 1
Bit 4HHalf Carry Flag
Bit 3IInterrupt Mask Flag
Bit 2NNegative Flag
Bit 1ZZero Flag
Bit 0CCarry Flag

IRQ interrupts are disabled when the I bit is set.
The two unused bits always read as "1".

The Index register X

The 16-bit index register allows the user to index or address a 64k memory space. The concatenated 16-bit register is called H:X. The upper byte of the index register is called H, while the lower byte of the index register is called X. H is cleared by reset and if you don't use any instructions that change H, the H:X register will behave identical to the 6805's IX register.
This register can be used as a 16-bit unsigned index to a 0, 8 or 16-bit constant offset.
The official notation of the indexed addressing mode is offset,X, where offset is a 0, 8, or 16-bit unsigned offset value. Usually the offset value is $00 and that can be written in three different ways in the SB-Assembler:

         LDA   $00,X
         LDA   ,X
         LDA   X

All three instructions have the same effect and all use an offset value of $00.

The SB-Assembler will automatically choose the most economical addressing mode, depending on the offset value. The assembler will opt for the worst case situation if the offset expression uses a forward referenced label.

The Stack Pointer

The 68HC08 has a 16-bit stack pointer, which will be reset to $00FF to behave identical to the 6805's stack pointer which was only 6-bits wide. Although reset will set the stack pointer to $00FF, you may change the stack pointer to point anywhere in RAM.
New instructions are added to push processor registers to the stack, something that was not possible on the 6805.
The stack pointer always points to the first available stack location. A value to be pushed is stored at the location that is pointed to by SP, then SP is decremented.
The stack on a 68HC08 grows down in memory when data is pushed on to it. Words are pushed with their LSB first. Subroutine calls and interrupts push the return address on the stack. This is the address of the instruction that has to be executed when the subroutine or interrupt is completed.

Interrupts save all registers on the stack. The order in which all data is pushed is shown below:


It goes without saying that the pull order is just the other way around!

Please note that the new H register is NOT stacked during an interrupt! This is done to maintain compatibility with 6805 code. It is the programmer's responsibility to push H on the stack during interrupts if H is going to be changed or if the index register is going to be used.

The Program Counter

The program counter PC is normally incremented after fetching each instruction or operand byte during program execution. The only way you can change this behaviour is with the jump, subroutine and return instructions. Interrupts can also change the program counter's value.
The program counter on the 68HC08 is 16-bits wide, which allows it to address the full 64k memory range.


SB-Assembler Version 3 can show you the cycle times of each instruction when the TON list flag is switched on. The numbers presented are the number of clock pulses the processor needs to execute the instruction.

Reserved Words

The SB-Assembler 68HC08 cross overlay has only two reserved words, which are the register X and SP. For the rest you may choose any label name you like.

Special Features

Indexed addressing mode

The official notation of the indexed addressing mode is offset,X, where offset is a 0, 8 or 16-bit unsigned offset value. Usually the offset value is $00 and that can be written in three different ways in the SB-Assembler:

        LDAA   $00,X
        LDAA   ,X
        LDAA   X

All three instructions have the same effect and all use an offset value of $00.

In version 2 of the SB-Assembler this is only true if the X register is used as index register. If you use the SP register as index register you are required to specify the offset, even if it is zero.
Version 3 of the SB-Assembler also allows the SP register to be used with 0 offset omission.

Forced direct page and extended addressing modes

One of the strongest features of the 68HC08 family is its direct page addressing mode. Direct page addressing mode is also called zero page addressing mode, because the 68HC08 can only use memory page 0 for direct addressing. With direct addressing mode you specify a memory location that can be addressed with only one byte (instead of 2 for all other memory locations). This way the 68HC08 can be seen as a microprocessor with 256 registers.

The SB-Assembler automatically selects direct addressing mode when that mode is available and the high byte of the address is $00 (being the zero page). We only know for sure that the high byte of the address is $00 if there was no unresolved label in the expression identifying the address. If a forward referenced label is used in an address expression we automatically assume the worst case situation and opt for extended addressing mode if that exists (2 bytes address field).
You may override this automatic selection of addressing mode by preceding the address field with a < or a > symbol.
The < symbol forces the assembler to use direct page addressing mode, even if the address expression contains a forward referenced label.
On the other hand the > symbol will force the assembler to use the extended addressing mode, even if the address could be resolved to a direct address.
But a Out of range error will be reported if you try to force to use the direct addressing mode where the high byte of the address isn't zero.


0010-           LABEL     .EQ   $10           A zero page address
8000-B6 10                LDA   LABEL         Appears to be zero page
8002-B6 11                LDA   <FORWARD      Clearly a forward referenced label
8004-B7 12                STA   $12           Is a zero page address
8006-C7 00 11             STA   >$11          Force extended addressing mode
0011-           FORWARD   .EQ   $11           A zero page address

Alias and compatibility mnemonics

With alias mnemonics I mean a mnemonic that does exactly the same as Motorola's original mnemonic, but may be used instead. There may be different reasons for you to use these alias mnemonics. Maybe because they are easier to remember, or because they are the same as mnemonics of other Motorola processors you're used to.
The opcode test file highlights all the alias and compatibility mnemonics you may use and tells you what the original equivalents are.

Small difference in bit addressing notation

With bit-branch instructions the operand notation on the SB-Assembler differs slightly from the original Motorola notation. This is because the SB-Assembler won't allow spaces in operand fields, while Motorola recommends them at that point.


         BRSET   0,$12,OFFSET       Almost the same as Motorola ;-)

Please note that the comma in front of all the bit masks would have been a space with the Motorola assembler.

Overlay Initialization

Two options are set while initializing the 68HC08 overlay family every time it is loaded by the .CR directive.

  • Big endian model is selected for 16-bit addresses and for the .DA and .DL directives. This means that words or long words are stored with their high byte first.
  • The maximum address size is set to 64k.

Differences Between Other Assemblers

There are some differences between the SB-Assembler and other assemblers for the 68HC08 family of processors. These differences require you to adapt existing source files before they can be assembled by the SB-Assembler. This is not too difficult though, and is the (small) price you have to pay for having a very universal cross assembler.

  • Not all assemblers allow you to use the shorter indexed mode.
  • Not all assemblers will understand forced direct page and extended addressing modes.
  • Not all assemblers will understand the alias mnemonics.
  • The obvious differences in notation of directives and radixes common to all SB-Assembler crosses.
  • Don't forget that the SB-Assembler does not allow spaces in or between operands. Only Version 3 will allow one space after each comma separating operands in the operand field.