Developing Software in Assembly Language
		Overview
		By Jonathan W. Valvano
		
		     This article, which discusses assembly language programming,
		accompanies the book Embedded Microcomputer Systems: Real Time Interfacing published by Brooks-Cole 1999. This document has four overall
		parts
		     Overview (this document)
		     Syntax (fields, pseudo ops)
		     Local variables
		     Examples
		     Writing assembly language software is similar to other software
		development processes. For general information on the process
		of software development see Chapter 2 of Embedded Microcomputer Systems: Real Time Interfacing by Jonathan W. Valvano. Again, this article will focus on assembly
		language developing using the TExaS application. There are two types of commands that exist in our
		assembly source code. Op codes are regular instructions that translate into machine code to
		be executed by the computer when the program runs. We use pseudo-op
		codes in our source code to give instructions to the assembler
		itself. The following lists the default color settings of the
		TExaS editor. 
		     The labels are shown in purple
		     The op codes are shown in blue
		     The pseudo-op codes are shown in gray
		     The numbers are shown in dark blue
		     The strings are shown in magneta
		     The operands are shown in black 
		     The comments are shown in green
		     The assembly errors are shown in red
--------------------------------------------------------------------------------------
		Case Study: Microcomputer-Based Lock
		      To illustrate the software development process, we will implement
		a simple digital lock. The lock system has 7 toggle switches and
		a solenoid as shown in the following figure. If the 7-bit binary
		pattern on Port A bits 6-0 becomes 0100011 for at least 10 ms,
		then the solenoid will activate. The 10 ms delay will compensate
		for the switch bounce. For information on switches and solenoids
		see Chapter 8 of Embedded Microcomputer Systems: Real Time Interfacing by Jonathan W. Valvano. For now what we need to understand is
		that Port A bits 6-0 are input signals to the computer and Port
		A bit 7 is an output signal.
		
      
Before we write assembly code, we need to develop a software plan.
		Software development is an iterative process. Even though we list
		steps the development process in a 1,2,3... order, in reality
		we iterative these steps over and over. 
		      1) We begin with a list of the inputs and outputs. We specify
		the range of values and their significance. In this example we
		will use PORTA. Bits 6-0 will be inputs. The 7 input signals represent
		an unsigned integer from 0 to 127. Port A bit 7 will be an output.
		If PA7 is 1 then the solenoid will activate and the door will
		be unlocked. In assembly language, we use equ pseudoops to assign a symbolic names, PORTA DDRA, to the corresponding addresses of the ports, $0000 $0002.
		PORTA  equ   $0000   ; PA6-PA0 switches, PA7 solenoid lock
		DDRA   equ   $0002   ; specifies input or output
		
		      2) Next, we make a list of the required data structures.
		Data structures are used to save information. If the data needs
		to be permanent, then it is allocates in global space. If the
		software will change its value then it will be allocated in RAM.
		In this example we need a 16-bit unsigned counter. We use the
		org pseudoop to place the data structures in RAM, $0800. The rmb pseudoop reserves bytes for the structure. These lines also assign
		the symbolic name CNT to the corresponding address of the information $0800.
		cnt    rmb   2       ; 16-bit counter
		       org   $F000   ; EEPROM
If data structure can be defined at assembly time and will remain
		fixed, then it can be allocated in EEPROM. In this example we
		will define an 8 bit fixed constant to hold the key code, which
		the operator needs to set to unlock the door. We will place these
		lines directly after the program so that they will be defined
		in ROM or EEPROM memory. The fcb pseudoop defines an 8-bit constant. This line also assigns the
		symbolic name key to the corresponding address of the information. 
		key    fcb   %00100011    ; key code
It is not real clear at this point exactly where in EEPROM this
		constant will be, but luckily for us, the assembler will calculate
		the exact address automatically. After the program is assembled,
		we can look at the line in the listing file or in the symbol table
		to see where in memory each structure is allocated.
		      3) Next we develop the software algorithm, which is a sequence
		of operations we wish to execute. There are many approaches to
		describing the plan. Experienced programmers can develop the algorithm
		directly in assembly language. On the other hand, most of us need
		an abstractive method to document the desired sequence of actions.
		Flowcharts, pseudo code, and high-level language code are three
		common descriptive formats. The TExaS application is unique in regards that if you draw the flowchart
		on the computer, you can paste it directly into the program as
		a comment. There are no formal rules regarding pseudo code, rather
		it is a shorthand for describing what to do and when to do it.
		We can place our pseudo code as documentation into the comment
		fields of our program. The following shows a flowchart on the
		left and pseudo code and C code on the right for our digital lock
		example.
		
		Normally we place the programs in ROM or EEPROM. On the MC68HC812A4
		EEPROM begins at $F000, so we put the following org pseudoop before the program.
		      org   $F000   ; EEPROM
Even though this program will not use the stack, we will initialize
		the stack pointer to the last location of RAM. On the 6812, we
		execute the following instruction to initialize the stack.
		main  lds   #$0C00
		Next we write assembly code to implement the algorithm as illustrated
		in the above flowchart and pseudo code. In step 1), we initialize
		Port A so that PA7 is an output and PA6-PA0 are inputs. For information
		on ports and direction registers see Chapter 1 of Embedded Microcomputer Systems: Real Time Interfacing by Jonathan W. Valvano. 
		      movb  #$80,DDRA   ; PA6-PA0 input, PA7 output
In step 2), we turn off the solenoid. 
		      bclr  PORTA,#$80  ; disable solenoid lock
In step 3), we initialize the counter to 4000, which is the number
		of loops required to wait 10 ms.
		      movw  #4000,cnt  ; 10,000,000ns/(125*20)
In step 4) we implement the indefinite loop. We place an assembly
		label at the program locations to which we wish to branch. The
		bra instruction is an unconditional branch.
		loop
		      bra   loop
Inside the indefinite loop we test to see if the switch pattern
		matches the key code. In this implementation we branch to off if the switches do not match the key code. If they do match we
		will execute the instruction immediately after the bne off.
		loop   ldaa  PORTA   ; [3] input from 7 switches
		       anda  #$7F    ; [1]
		       cmpa  key     ; [3] match key code?
		       bne   off     ; [3]
If the switches match the key code, then the 16-bit counter is
		decremented.
		       ldx   cnt     ; [3]
		       dex           ; [1]
		       stx   cnt     ; [3]
If the counter becomes zero, then the door is unlocked. The bne instruction will go to loop if cnt is not equal to zero. The bset instruction will set PA7 to 1.
		       bne   loop    ; [2]=20 cycles/loop
		       bset  PORTA,#$80   ; enable solenoid lock
		       bra   loop 
If the switches do not match the key code, then the solenoid is
		turned off and the cnt set back to 4000.
		off    movw  #4000,cnt    ; 10,000,000ns/(125*20)
		       bclr  PORTA,#$80   ; disable solenoid lock
		       bra   loop   
We put the above pieces together to create the source code. The
		order of the instructions is very important because it determines
		the sequence of execution. The last two lines will define where
		the computer will start execution after a reset.
		; ******lock.rtf************
		; activate solenoid (PA7=1) if switches match key code
		; switch bounce is less than 10 ms
		PORTA  equ   $0000   ; PA6-PA0 switches, PA7 solenoid lock
		DDRA   equ   $0002   ; specifies input or output
		       org   $0800   ; RAM
		cnt    rmb   2       ; 16-bit counter
		       org   $F000   ; EEPROM
		main   lds   #$0C00
		       movb  #$80,DDRA   ; PA6-PA0 input, PA7 output
		       bclr  PORTA,#$80  ; disable solenoid lock
		       movw  #4000,cnt   ; 10,000,000ns/(125*20)
		loop   ldaa  PORTA   ; [3] input from 7 switches
		       anda  #$7F    ; [1]
		       cmpa  key     ; [3] match key code?
		       bne   off     ; [3]
		       ldx   cnt     ; [3]
		       dex           ; [1]
		       stx   cnt     ; [3]
		       bne   loop    ; [2]=20 cycles/loop
		; 7 switches match key code for more than 10 ms
		       bset  PORTA,#$80   ; enable solenoid lock
		       bra   loop   
		off    movw  #4000,cnt    ; 10,000,000ns/(125*20)
		       bclr  PORTA,#$80   ; disable solenoid lock
		       bra   loop   
		key    fcb   %00100011    ; key code
		       org   $FFFE
		       fdb   main
4) The last stage is debugging. You can run this example on the TExaS simulator by loading the files lock.rtf, lock.uc and lock.io. There are versions for all four microcomputers, located in the MC6805, MC6808, MC6811 and MC6812 directories. For information on debugging see Chapter 2 of Embedded Microcomputer Systems: Real Time Interfacing by Jonathan W. Valvano.
--------------------------------------------------------------------------------------
		Assembler Basics
		     Assemblers are programs that process assembly language source
		program statements and translate them into executable machine
		language object files. Cross assemblers (such as TExaS) allow source programs written and edited on one computer (the
		host) to generate executable code for another computer (the target).
		In our case the target is microcomputer simulator, but since TExaS generates S19 records, you could download the S19 file onto a real computer
		for execution. 
		     The symbolic language used to code source programs to be
		processed by the Assembler is called assembly language. The language
		is a collection of mnemonic symbols representing: operations (i.e.,
		machine instruction mnemonics or directives to the assembler),
		symbolic names, operators, and special symbols. The assembly language
		provides mnemonic operation codes for all machine instructions
		in the instruction set. The instructions are defined and explained
		in the Programming Reference Manual (for the 6805, 6808, 6811
		or 6812), which can be found in the pdf directory of the CD. Printed copies of these Motorola manuals
		can be obtained from the Motorola Literature Center. A brief overview
		of each instruction and example usage can be found by searching
		the Contents page of the help engine included with the TExaS application. The assembly language also contains mnemonic directives
		that specify auxiliary actions to be performed by the Assembler.
		These directives are not always translated into machine language.
		Many pseudo-op codes are supported by this assembler.
     The TExaS assembler is a two-pass assembler. During the first pass, the
		source program is read to develop the symbol table. During the
		second pass, the object file is created (assembled) using the
		symbol table developed in pass one. It is during the second pass
		that the source program listing is also produced. The symbol table
		is recreated in the second pass. A Phasing Error occurs if the symbol table values calculated in the two passes
		are different.
		      Errors that occur during the assembly process (e.g., undefined
		symbol, illegal op code, branch destination too far, etc.) are
		explained in the listing file (I shortened the comments so each
		line would fit on the page). 
		Copyright 1999-2000 Test EXecute And Simulate - Version 1.00
		                                           ; ******lock.rtf*******
		                                           ; activate solenoid (PA7=1)
		                                           ; bounce is less than 10 ms
		$0000                                      PORTA equ  $0000
		$0002                                      DDRA  equ  $0002
		$0800                                            org  $0800
		$0800                                      cnt   rmb  2
		$F000                                            org  $F000
		$F000 CF0C00          [ 2](  0){OP        }main  lds  #$0C00
		$F003 180B800002      [ 4](  2){OPwP      }      movb #$80,DDRA
		$F008 4D0080          [ 4](  6){rPOw      }off   bclr PORTA,#$80
		$F00B CC115C          [ 2]( 10){OP        }look  ldd  #4444
		$F00E 7C0800          [ 3]( 12){WOP       }      std  cnt
		$F011 9600            [ 3]( 15){rfP       }loop  ldaa PORTA 
		$F013 847F            [ 1]( 18){P         }      anda #$7F
		$F015 B1F028          [ 3]( 19){rOP       }      cmpa key
		$F018 26EE            [ 3]( 22){PPP/P     }      bne  off
		$F01A FE0800          [ 3]( 25){ROP       }      ldx  cnt
		$F01D 09              [ 1]( 28){O         }      dex 
		$F01E 7E0800          [ 3]( 29){WOP       }      stx  cnt
		$F021 26EE            [ 3]( 32){PPP/P     }      bne  loop
		                                           ; 7 switches match key code
		$F023 4C0080          [ 4]( 35){rPOw      }      bset PORTA,#$80
		$F026 20E3            [ 3]( 39){PPP       }      bra  look
		$F028 23                                   key   fcb  %00100011
		$FFFE                                            org  $FFFE
		$FFFE F000                                       fdb  main
		                                           
		***************Symbol Table*********************
		DDRA         $0002 
		PORTA        $0000 
		cnt          $0800 
		key          $F028 
		look         $F00B 
		loop         $F011 
		main         $F000 
		off          $F008 
		Assembly successful
     The source code is a file of ASCII characters usually created
		with an editor. Each source statement is processed completely
		before the next source statement is read. As each statement is
		processed, the Assembler examines the label, operation code, and
		operand fields. The operation code table is scanned for a match
		with a known opcode. During the processing of a standard operation
		code mnemonic, the standard machine code is inserted into the
		object file. If an assembler directive is being processed, the
		proper action is taken.
		     Any errors that are detected by the Assembler are displayed after the actual
		line containing the error is printed. If no source listing is
		being produced, error messages are still displayed in the TheLog.RTF
		to indicate that the assembly process did not proceed normally.
		Object code is the binary values (instructions and data) that,
		when executed by the computer, perform the intended function.
		The listing file contains the address, object code, and a copy
		of the source code. You can optionally include the number of cycles
		to execute the instruction, a running total of cycles, and explicit
		details of the cycles types required to execute the instruction.
		The listing file also provides a symbol table describing where
		in memory the program and data will be loaded. The symbol table
		is a list of all the names used in the program along with the
		values. A symbol is created when you put a label starting in column
		1. Examples of this type are DATA, CNT, Start, Rep, Inp, NAME
		and SIZE. The symbol table value for this type is the absolute
		memory address where the instruction, variable or constant will
		reside in memory. The second type of label is created by the equ
		pseudo-op. The value for this type of symbol is simply the number
		specified in the operand field. When the assembler processes an
		instruction with a symbol in it, it simply substitutes the fixed
		value in place of the symbol. Therefore we will use symbols to
		clarify (make it easier to understand) our programs. The symbol
		table for this example is
		***************Symbol Table*********************
		      DDRA     $0002 
		      PORTA    $0000 
		      cnt      $0800 
		      key      $F033 
		      loop     $F011 
		      main     $F000 
		      off      $F028 
A compiler converts high level language source code into object code. A cross-compiler also converts source code into object code and creates a listing file except that the object code is created for a target machine that is different from the machine running the cross-compiler. The TExaS is a cross-assembler because it runs on an Intel computer but creates 6805/6808/6811/6812 object code. Hiware and ImageCraft's ICC11 and ICC12 include both a cross-assembler and a cross-compilers because they run on the PC and create 6805/6808/6811/6812 object code. For general information on C language software development see Chapter 2 of Embedded Microcomputer Systems: Real Time Interfacing by Jonathan W. Valvano.
Motorola uses S-records to store object code. The 16 bit values are stored in memory with the most significant byte first. For more information about the specific format of the S-record see S19 records contain object code. The S-record for the above example is as follows. The actual object code is colored in blue.
S121F000CF0C00180B8000024D008018030FA008009600847FB1F033260EFE0800091F
		S119F01E7E080026EE4C008020E918030FA008004D008020DE23A9
		S105FFFEF0000D
		S903F0000C
--------------------------------------------------------------------------------------
		Running on an Evaluation Board 
		     When debugging involves controlling real hardware, we must use
		an actual microcomputer running in real time. Because the programs
		are stored in ROM or EEPROM on the single chip microcomputer it
		is difficult to debug. To solve this problem there are evaluation
		boards that run the microcomputer in expanded mode and include
		a debugger. With this development system, we also use a cross-assembler
		or a cross-compiler to convert our source programs into a listing
		file and object file. The object file is transmitted via the serial
		port to the evaluation board and loaded into RAM. A simple debugger
		(like the 6811 EVB using the BUFFALO debugger) allows us to test
		our software. Typical debugger features include:
		     start execution at a specific address
		     set breakpoint at a specific address
		     read/modify microcomputer registers
		     read/modify microcomputer I/O ports
		     read/modify RAM
		     read/erase/program EEPROM
		     load object code into RAM received from the HOST PC.
		Sophisticated development environments integrate the editor, compiler,
		assembler, serial port communication and debugger into a single
		application running on the PC. For more information on software
		development see Chapter 2 of Embedded Microcomputer Systems: Real Time Interfacing by Jonathan W. Valvano. For information about hardware development
		platforms, see the Lab Manual that accompanies this book.
--------------------------------------------------------------------------------------
		Simulation
		     When developing software using a simulator, we use a cross-assembler
		or a cross-compiler running on a PC to convert our source programs
		into a listing file and object file. We then "run" our program
		on a simulator that emulates microcomputer with its external component.
		Simulation in this environment is more difficult than other computer
		application because of the software execution is tightly coupled
		to (extremely dependent on) the hardware. Simulation of an embedded
		system is only effective if all the software, computer, external
		mechanical, and external electrical components are modeled. Another
		complicating issue is the real time nature of the external mechanical
		and electrical devices. The following figure outlines the software
		development process using a simulator.

Additional topics include.
		    Assembly Language Syntax
		    Label Field 
		    Operation Field
		    Operand Field
		    Comment Field
		    Assembly listing gives results of the assembly
		    Assembly errors lists the types of assembly errors
		    Assembly pseudo-op's are assembly-time operations
		    S19 records contain object code
For a detailed explanation of the instructions and their addressing modes, see the help system with the TExaS application. Sometimes the best way to learn a new technique is to observe examples. See the ReadMe.txt file for a list of examples that can be run on the simulator. There are many assembly language examples included with the TExaS application. Some simple 6812 examples are included in this document.
This document has four overall parts
		     Overview (this document)
		     Syntax (fields, pseudo ops)
		     Local variables
		     Examples