An application that is truly user-friendly calls for significant resources that the 68HC11 doesn't have space for.  While Buffalo has certain quirks and lacks in comfort, its simplicity and honesty in not hiding details is refreshing.  The following will get you started with Buffalo, version 3.4.  Please connect the 68HC11 development board, attach the serial cable, and run an ASCII terminal program.  Perform each command as you read along. 

Register Modify Command

When Buffalo produces its command prompt “>” we say that Buffalo has control of the development board.  In this sense, Buffalo saves the actual CPU register values associated with your program.  Buffalo has commands that transfer control to your program.  In transferring control, the CPU register values associated with your program are restored.  The RM command displays and modifies the stored CPU register values.  Enter the following command:

> rm A

The command first lists all the registers and their values, and then gives you the opportunity to change the value.  Be sure to remember that Buffalo is case insensitive and only understands hexadecimal numbers. 

P-E50A Y-FFFF X-0115 A-00 B-FF C-D0 S-0041
A-00 FF

After you change the A register value, repeat the rm command to see the change.  Simply pressing the Enter key makes no change to the affected register.  Any CPU register value can be changed in this fashion, the registers are named as: A, B, C, X, Y, and S. It is important to remember, the values reported are safe and are not the current register values being used by Buffalo.  Rather, these will be the register values when Buffalo transfers control to your program.

The 68HC11E9 chip in the Axiom board has 512 bytes of RAM starting at address $0000.  Buffalo version 3.4 sets aside addresses $0000 to $0041 as the stack for your program.  Addresses $0042 to $00FF are reserved by Buffalo, for its own stack, variables, and a jump table that we discuss later.  After you've played with the rm command, press the reset button to restore some of the initial register values. 

Memory Dump and Memory Modify Commands

The MD command provides a dump of a range of memory locations, the following is the general format.  If the number of bytes is not given then 144 byte values are listed.

MD <address> [bytes]
The first 256 bytes are generally reserved for use by Buffalo, we will use addresses starting at $100 for a simple example program.  Use the following command to look at 16 bytes, starting at $100.

>md 100 10

0100 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

The following is the format of the MM command

> MM <address>
The MM command first lists the memory contents of the given address and then gives you the opportunity to change that value.  If you enter a new value and press the enter key, the new value is inserted. 
>mm 100

0100 FF AA

>md 100 16

0100 AA FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
>mm 100

0100 AA FF

>

The MM command allows you to easily change the contents of a range of addresses.  Enter the MM command again, but don't press the enter key to accept the value. Rather, press the equal sign key '=', so the same address is repeated.  Pressing '+' key ( you may have to press shift and '+') advances to the next address and pressing '-' changes to the preceeding address.

Assembler/Disassembler Command

Buffalo provides a very rudimentary assembler/disassembler you can use to enter very short programs, or to examine machine code.  The ASM command disassembles and assembles one instruction at a time.  The general format is as follows, where <address> is the starting address:

> asm <address>

After you press the Enter key, the instruction at the start address is listed in mnemonic form, along with a new prompt.  Pressing the Enter key causes the next instruction to be listed.  Entering a new instruction replaces that at the current address and also advances to the next instruction.  To exit this assembler/disassembler mode, press the control-A key combination.

At the command prompt enter the following:

> asm 100

Buffalo returns with the following:

0100 STX  $FFFF      >

Enter text so that you see the following.  In the line that begins with 0106 just press the control-A key combination.

0100 STX  $FFFF      > LDAA #10
     86 40
0102 STX  $FFFF      > STAA 1000
     B7 10 00
0105 STX  $FFFF      > rts
     39
0106 STX  $FFFF      >

Enter the command asm 100 as you did before.  This time you the commands that you entered should be disabled from memory.  Check to make sure that the code is entered correctly.

Call Command

The CALL command transfers control to your program by using the assembly language jsr instruction.  Because this instruction uses the stack to save the return address, your code must end with a return from interrupt instruction (RTS).  With the code that you entered in the previous step still in memory, enter the following command:

> call 100

At this moment the LED that you connected to the development board should be illuminated.  To turn off the LED it is only necessary to assign the value zero to the register at $1000. In using the MM command, it's normal that Buffalo cannot change all the bit values of that register.

Adding a Simple Delay Loop

To make the program more useful, let's design a delay loop that will leave the LED on for approximately one second before turning off.  The following is assembly language code for the delay loop.  Since the Buffalo assembler is very simple, it will not understand this assembly language code.  Buffalo does not understand labels so you will have to substitute in the actual values of N1 and N2 by hand.

* Repeat the outer loop N1 times
      LDAA    #N1    ; 2 cycles

* Inner delay loop - ten milliseconds
L1:   LDX     #N2    ; 3 cycles
L2:   NOP            ; 2 cycles
      DEX            ; 3 cycles
      BNE     L2     ; 3 cycles

* Rest of the outer loop
      DECA           ; 2 cycles
      BNE     L1     ; 3 cycles

The CPU bus cycle rate in our development board is 2MHz.  To execute the inner delay loop in ten milliseconds the CPU must consume approximately 2MHz * 10msec = 20 thousand bus cycles.  Thus we write the following equation and solve for N2 and round to the nearest integer.

3 + N2*(2+3+3) = N2*8 + 3 = 20,000

N2 = 2,500(decimal) or $09C4 (hexadecimal)
With this value for N2, the inner loop executes in 20,003 bus cycles.  To execute in one second, a total of 2 million bus cycles are required.  Here we include the outer loop and solve for N1.  In hind-sight, we can produce this number using a simple approximation.  Because the delay in the inner loop is much longer than the workings of the outer loop, it's enough to repeat the inner loop one hundred times.

2 + N1*(20,003 + 5) = 2,000,000

N1 = 100(decimal) = $64 (hexadecimal)
We will be using a much better assembler later, but for now write the code in a format Buffalo can understand.  Buffalo doesn't 'do' labels; while Buffalo will calculate offset branch values, you must know the target address.  If you don't know the target address, temporarily enter an arbitrary address that you know is within range, then use the ASM command again later to insert the correct address value. 

A minor change is made to the program, so that after the delay the LED is turned off.  Make special notice that the $ symbol isn't used as Buffalo only knows hexadecimal notation.

0100  LDAA  #10
0102  STAA  1000
0105  LDAA  #64
0107  LDX   #09C4
010A  NOP
010B  DEX
010C  BNE   010A
010E  DECA  
010F  BNE   0107
0111  CLR   1000
0114  RTS

Use the ASM command as you did before to enter the code above, the starting address will be $0100.  Use the call command as before, to run the code. 

Go Command

The GO command provides another mechanism to transfer control to your program, but provides no means to return.  Rather, your program will then use a jump to a special address to transfer control back to Buffalo.  Use the ASM command to replace the RTS instruction with a JMP instruction to the warm-start pseudovector $FF7C. 
>asm 114

0114 RTS             >jmp FF7C
     7E FF 7C
0117 STX  $FFFF      > (control-A)
>
The CALL command is simpler than GO in that the CALL doesn't save a return address on the stack.  Ending your program with a JMP $FF7C instruction provides the mechanism to transfer control back to buffalo.  Use GO to execute the code.  If the LED is on already, it should turn off in a brief moment. 
> go 100

Execution Strategy

Lets take a moment to reconsider the differences between the CALL and GO commands.  The CALL command is commonly used to execute subroutines.  In nearly all cases a subroutine uses an RTS intruction to return to the caller.  Like the JSR instruction, the CALL command saves the return address on the stack, where RTS finds it. 

Buffalo version 3.4 initializes the stack pointer register to $41, but you can use the 'RM S' command to manually set the stack pointer register to what you like.  In writing your own subroutines, don't initialize the stack pointer register.  A subroutine that initializes the stack pointer register will likely remove its own return address and cause the RTS instruction to jump to an unknown address. 

However, in writing a complete program you will want to initialize the stack pointer register.  The GO command is like a jump instruction in that control is simply passed to your program, hence the return address back to Buffalo is not saved.  A jump to the warm-start pseudovector ($FF7C) provides a means to transfer control back to Buffalo.

Breakpoint Set Commands

The BR command is used to set a breakpoint which causes execution to halt just before a specified address.  Enter the following to set a breakpoint in the above program.

> BR 10B

Buffalo responds by listing the breakpoint table.  Buffalo allows for at most four breakpoints. 

010B 0000 0000 0000

Execute the code using the go 100 command, this time the program halts just before the instruction at address $010B.  The action of a breakpoint causes the program to halt, report the contents of the CPU registers, and essentially freeze the state of execution. 

10B 0000 0000 0000
>go 100

P-010B Y-FFFF X-09C4 A-64 B-FF C-D0 S-0041
>

While your program is halted, you can use the RM, MD, and MM commands as usual to examine the program state. The following table lists variations of the BR command that you will find useful. 

List of BR command variations
BR : Display the breakpoint table
BR <address> : Set a breakpoint
BR -<address> : clear a breakpoint
BR - : clear all breakpoints
BR -<address1> <address2> : change a breakpoint address

Proceed Command

After you have examined the state of your halted program, use the proceed command P to restore program execution.  The command simply passses control back to your program.

>P

P-010B Y-FFFF X-09C3 A-64 B-FF C-90 S-0041
>

The program hit the breakpoint a second time, but the X register now contains the value $09C3, one less than before.  A point to make if you use other debuggers is that Buffalo does not have a command named continue.  Resist the urge to issue the abbreviated command 'C' as it executes the Buffalo call command. 

Trace Command

The trace command is similar to the step command in the THRSim11 tools, but the trace command allows you to specify the number of instructions to execute before returning control to Buffalo. 

> T <n>

Here is the trace command in use, remember that pressing the enter key alone repeats the previous command.

>T 1
DEX                  P-010C Y-FFFF X-09C2 A-64 B-FF C-90 S-0041
>
BNE   $010A          P-010A Y-FFFF X-09C2 A-64 B-FF C-90 S-0041
>
NOP                  P-010B Y-FFFF X-09C2 A-64 B-FF C-90 S-0041
>
DEX                  P-010C Y-FFFF X-09C1 A-64 B-FF C-90 S-0041
>T 3
BNE   $010A          P-010A Y-FFFF X-09C1 A-64 B-FF C-90 S-0041
NOP                  P-010B Y-FFFF X-09C1 A-64 B-FF C-90 S-0041
DEX                  P-010C Y-FFFF X-09C0 A-64 B-FF C-90 S-0041
>

StopAt Command

The STOPAT command runs code, stopping execution at an address that you specify.  Use the following to clear the existing breakpoint and stop execution at $10B. 

>br -

0000 0000 0000 0000
>stop 10b

P-010C Y-FFFF X-09C0 A-64 B-FF C-90 S-0041
>

While the trace command discussed earlier is useful, you won't always want to step into every subroutine call.  Given that Buffalo doesn't have a command to step over subroutine calls, the STOPAT command provides an alternative.  Given the address of a following instruction, STOPAT conveniently executes all the intermediate code. 

Unfortunately, the STOPAT command executes code slowly.  In the case of slow running code, as in a busy-wait delay loop the wait can seem unbearable.  In such cases its better to place a break point and then use the PROCEED command to run the intermediate code at full speed.  Take a moment to experiment with the STOPAT, breakpoint, and PROCEED commands.

From here on, you can use the proceed command to run the program to completion.  In closing, Buffalo provides commands useful in developing applications.  While the built in assembler does provide some use, it is not convenient for processing larger programs.  In the next part we examine the Motorola assembler and how to down-load S19 files. 

Copyright Notice

This tutorial page was written for EE332, the Introduction to Microprocessors course offered by the Electrical Engineering Department in the College of Engineering at the University of Hartford.  Copyright is dated October 18, 2001 and is reserved by the author, Jonathan Hill.  Permission is granted to make copies of this document for educational use as-is, provided that this statement remains attached.  I do strive to improve this document, so please forward constructive criticism for my review along with suggestions.  Credits will be added as improvements are made to this document.
Original Author: Jonathan Hill (jmhill@mail.hartford.edu)
Last Modified: Wed Jun 5 21:09:02 2002 EST