Modified by: Ahmed Abu-Hajar, Ph.D. Lecture #10 - DIGITAVID
Modified by: Ahmed Abu-Hajar, Ph.D. Lecture #10 - DIGITAVID
Modified by: Ahmed Abu-Hajar, Ph.D. Lecture #10 - DIGITAVID
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>Modified</strong> <strong>by</strong>: <strong>Ahmed</strong> <strong>Abu</strong>-<strong>Hajar</strong>, <strong>Ph</strong>.D.<br />
<strong>Lecture</strong> <strong>#10</strong>
Outline<br />
Subroutines<br />
D-BUG12 Utility Tool
Subroutines<br />
Subroutines: Separate, independent module of the<br />
program<br />
Performs a specific task<br />
Shortens code, provide “reusable code”<br />
Good subroutine:<br />
Independence: does not depend on other codes<br />
Registers: Stores/restores key registers upon<br />
entrance/exit using PSH and PUL commands (Store Key<br />
registers on the Stack)<br />
Data and code independent: Local variables do not use<br />
direct and extended addressing modes
Subroutines<br />
How to Call a Subroutine?<br />
• The main program exist with<br />
sequential execution order.<br />
Call Subroutine <strong>by</strong> changing PC<br />
to the subroutine location<br />
This is done <strong>by</strong> using Branching<br />
(BSR or JSR)<br />
BSR limited <strong>by</strong> (-128- 127}<br />
JSR jumps anywhere<br />
Before Branching Must store all<br />
key registers including PC in<br />
memory (or Stack)<br />
Once the subroutine finished, PC<br />
goes back to the next step.<br />
RTS is used to return.<br />
Every subroutine MUST have RTS.<br />
Program (*.asm)<br />
Main Program:<br />
Call Subroutine 1<br />
Subroutine 1<br />
Return
Subroutine: Example<br />
STACKTOP = $8000<br />
_main::<br />
LDS #STACKTOP ;initialize SP<br />
JSR DOIT ;jump to subroutine<br />
HERE: BRA HERE<br />
DOIT: PSHA ;store key registers on stack<br />
PSHB<br />
: ;subroutine actions<br />
PULB ;restore key register values<br />
PULA<br />
RTS ;return from subroutine
Subroutine:<br />
Passing Parameters: Pass parameter to the<br />
subroutine when the program calls that<br />
subroutine<br />
Two types of calls<br />
Call <strong>by</strong> Value: pass the actual value of the<br />
parameter to the subroutine<br />
Call <strong>by</strong> Reference: pass the memory address which<br />
contains the parameter’s address
Subroutine:<br />
Example of call <strong>by</strong> Value<br />
This Example Swaps the values of<br />
two consecutive memory locations<br />
Org $4000<br />
BASE EQU $4000<br />
Num_ONE FCB $23<br />
NUM_TWO FCB $3F<br />
ORG $4100<br />
LDS #$8000<br />
LDX #BASE<br />
LDAA $0,X<br />
LDAB $1,X<br />
BSR SWAP<br />
STAA NUM_ONE<br />
STAB NUM_TWO<br />
END<br />
SWAP PUSA<br />
PUSB<br />
PULA<br />
PULB<br />
RTS<br />
Note: The opcode EXG A, B would<br />
swap A& B. We did it here to<br />
show how to use subroutine
Subroutine:<br />
Example of call <strong>by</strong> Reference<br />
Copy the ten consecutive values from<br />
location $5000 to $6000<br />
FIRST EQU $5000<br />
SECON EQU $6000<br />
ORG $4000<br />
NUM_DATA FCB $0A<br />
ORG $4100<br />
LDS #$8000<br />
LDX #BASE<br />
LDAA NUM_DATA<br />
LDX #FIRST<br />
LDY #SECOND<br />
JSR COPY<br />
END<br />
COPY COMPA #S00<br />
BEQ DONE<br />
LDAB 1,X+<br />
STAB 1,Y+<br />
DECA<br />
BRA COPY<br />
DONE RTS
D-BUG12 Utility<br />
Subroutines for HC12<br />
D-BUG12: Contains built-in subroutines for to monitor and or<br />
debug the program.<br />
Stored within ROM of the controller<br />
Allows the programmer to alter memory locations or modify<br />
registers or debug the program.<br />
Contains 18 utility subroutines which are listed as follows:<br />
Routine vector Address Comment<br />
Main() $FE00 ;Start the D-Bug12 monitor program<br />
getchar() $FE02 ;Fetch Character form Keyboard<br />
Putchar() $FE04 ;Display Character form on Screen<br />
printf() $FE06 ;Display formatted string on screen<br />
GetCmdLine() $FE08 ;Fetch a command from keyboard<br />
Scanhex() $FE0A ;Convert Hexadecimal to integer<br />
isXdigit() $FE0C ;Check for hexadecimal digit<br />
toupper() $FE0E ;Converts lowercase to uppercase
D-BUG12 Utility<br />
Subroutines for HC12<br />
Continue: Utility subroutines<br />
Routine vector Address Comment<br />
isalpha() $FE10 ;Check for alphabet character<br />
strlen() $FE12 ;Return the length of the string<br />
Srtcpy() $FE14 ;copies a string to another string<br />
out2hex() $FE16 ;Output a <strong>by</strong>te of a two hexadecimal<br />
;number<br />
Out4hex() $FE18 ;Output two <strong>by</strong>te of four hexadecimal ;<br />
;Numbers<br />
setUserVector() $FE1A ;set user-specified ISR routine address<br />
IWriteEEByte() $FE1C ;write a <strong>by</strong>te to the on chip EEPROM<br />
EraseEE() $FE1E ;Erase a block of on-chip EEPROM<br />
ReadMem() $FE20 ;Read Data From Memory<br />
WriteMem() $FE22 ;Write data to memory
D-BUG12 Utility<br />
Subroutines for HC12<br />
For D-BUG12 routines, the 68HC12 insists on using<br />
stack to transfer parameter variables<br />
Treat parameters as 16-bit values<br />
Parameters must be pushed onto the stack<br />
Starting with parameter n to 1<br />
Load vector address of the subroutine in index<br />
register X
D-BUG12 Utility: Example<br />
Use out2hex() utility subroutine to display $45 on<br />
the computer screen<br />
Store $0045 to stack before calling subroutine<br />
LDD #$45 ;value for display<br />
PSHD<br />
LDX #$FE16 ;16-bit addr of subr<br />
JSR 0,X ;call the subroutine<br />
PULX ;clean up the stack