Top Banner
1 METU EE447 LABORATORY EXPERIMENT #2 UTILITY SUBROUTINES (Please send an e-mail to [email protected] for any questions related to this experiment.) Purpose: To learn the subroutine subject and get familiar with the utility subroutines of M68HC11EVBU. 2.1. BACKGROUND INFORMATION The BUFFALO (bit user fast friendly aid to logical operations) monitor program is supplied with the EVBU. The EVBU monitor program is stored in the MCU internal ROM and communicates with the external world (user) via the MCU serial communications interface (SCI). The BUFFALO monitor program consists of five parts (or sections) as follows: 1. Initialisation 2. Command interpreter 3. I/O routines 4. Utility subroutines 5. Command table In this experiment utility subroutines will be examined. The monitor program uses the MCU internal RAM located at $0042-$00FF (Remember the memory map for EVBU from Experiment-1 manual.) BUFFALO variables are located within this address region and these variables are accessed within the BUFFALO monitor program. Some of them are explained here: SHFTREG: is a 2-byte reserved location at $0096 and $0097. This 2-byte register is used by HEXBIN and CHGBYT subroutines for reading input data from user (See Supplementary Note following the Experimental Work section at the end for details.) NOTE: Exact address of this register depends on the Buffalo version; hence instead of directly accessing it, use HEXBIN and CHGBYT subroutines as a good programming practice. $0096 SHFTREG $0097 SHFTREG+1 COUNT: is a one byte location at address $00A4 and reserved for storing the number of characters that have been read from the serial communication interface until we reach this register. CHRCNT: is a one byte location at address $00A5 reserved for storing the number of characters output on current line. TMP1: is a one byte reserved location at address $00BA and is used by HEXBIN as detailed in the Utility Subroutines section. Several subroutines are available for performing I/O tasks. By default, all I/O performed with these routines are received from/sent to the terminal port. A jump table has been set up in ROM directly before the interrupt vectors. To use these subroutines, execute a jump to subroutine (JSR) command to the appropriate entry in the jump table. You must not forget to initialize the Stack Pointer (SP) to a suitable value whenever you use JSR (or Pull / Push / BSR) command(s) in a program (e.g., LDS #$0041). 8 bit 8 bit
12
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: EE447_2013_EXP2

1

METU EE447 LABORATORY

EXPERIMENT #2

UTILITY SUBROUTINES

(Please send an e-mail to [email protected] for any questions related to this experiment.)

Purpose: To learn the subroutine subject and get familiar with the utility subroutines of

M68HC11EVBU.

2.1. BACKGROUND INFORMATION

The BUFFALO (bit user fast friendly aid to logical operations) monitor program is supplied with

the EVBU. The EVBU monitor program is stored in the MCU internal ROM and communicates with the external world (user) via the MCU serial communications interface (SCI).

The BUFFALO monitor program consists of five parts (or sections) as follows:

1. Initialisation 2. Command interpreter

3. I/O routines

4. Utility subroutines 5. Command table

In this experiment utility subroutines will be examined.

The monitor program uses the MCU internal RAM located at $0042-$00FF (Remember the

memory map for EVBU from Experiment-1 manual.) BUFFALO variables are located within this address region and these variables are accessed within the BUFFALO monitor program. Some of them are

explained here:

SHFTREG: is a 2-byte reserved location at $0096 and $0097. This 2-byte register is used by

HEXBIN and CHGBYT subroutines for reading input data from user (See Supplementary Note following the Experimental Work section at the end for details.) NOTE: Exact address of this register

depends on the Buffalo version; hence instead of directly accessing it, use HEXBIN and CHGBYT subroutines as a good programming practice.

$0096 SHFTREG

$0097 SHFTREG+1

COUNT: is a one byte location at address $00A4 and reserved for storing the number of

characters that have been read from the serial communication interface until we reach this register.

CHRCNT: is a one byte location at address $00A5 reserved for storing the number of

characters output on current line.

TMP1: is a one byte reserved location at address $00BA and is used by HEXBIN as detailed

in the Utility Subroutines section.

Several subroutines are available for performing I/O tasks. By default, all I/O performed with these routines are received from/sent to the terminal port. A jump table has been set up in ROM

directly before the interrupt vectors. To use these subroutines, execute a jump to subroutine (JSR)

command to the appropriate entry in the jump table. You must not forget to initialize the Stack Pointer (SP) to a suitable value whenever you use JSR (or Pull / Push / BSR) command(s) in a

program (e.g., LDS #$0041).

8 bit

8 bit

Page 2: EE447_2013_EXP2

2

Name of Subroutine

Address of Subroutine

Description (Assume in all examples SP is initialized appropriately)

WARMST $FF7C

Go to ">" prompt point (skip BUFFALO... message). You may use this

subroutine to return control to the user at the end of your program.

Ex: ORG $2000 ; Start of the program

LDAA #$41 ; $41 is the Hex of the ASCII character ‘A’ JSR $FFB8 ; Call ‘OUTA’ subroutine

JSR $FF7C ; Call ‘WARMST’ subroutine

LDAA #$42 ; $42 is the Hex of the ASCII character ‘B’ JSR $FFB8 ; OUTA

END Output of the program:

>G 2000 // User starts the program A // Program prints ‘A’ then goes to BUFFOLA prompt

> // Following program lines skipped and control

// returns to Buffalo monitor program.

OUTA $FFB8

Output character in accumulator A (Acc-A). This subroutine calls

OUTPUT subroutine.

Ex: ORG $2000 ; Start of the program

LDAA #$41 ; Load ‘A’ in Acc-A JSR $FFB8 ; Call OUTA

LDAA #$42 ; Load ‘B’ in Acc-A JSR $FFB8 ; Call OUTA

JSR $FF7C ; Call WARMST

END Output of the program:

>G 2000 // User starts the program AB // Program prints the content of the Acc-A

>

OUTCLR $FFC4

Output ASCII carriage return (ENTER). Consider the previous example and compare with this one:

Ex:

ORG $2000 ; Start of the program LDAA #$41 ; Load ASCII of the ‘A’

JSR $FFB8 ; Call OUTA JSR $FFC4 ; Call ‘OUTCLR’ subroutine

LDAA #$42 ; Load ASCII of the ‘B’ JSR $FFB8 ; Call OUTA

JSR $FF7C ; Call WARMST

END Output of the program:

>G 2000 // User starts program A // Program prints ‘A’ then goes to the next line

B // then prints ‘B’

> Be careful: Using this subroutine CHANGES the content of the Acc-

A, it is loaded with the ASCII of the carriage return, i.e., Acc-A =$0D ($0D in ASCII means carriage return) after OUTCLR.

Page 3: EE447_2013_EXP2

3

OUTRHL $FFB5

Convert the right nibble of Acc-A contents to ASCII and output to

terminal port

Ex: ORG $2000 ;

LDAA #$9F ; Acc-A =$9F, hence its right nibble is 'F' JSR $FFB5 ; Call OUTRHL subroutine. Now, Acc-A =$46,

; which is the ASCII of the character ‘F’) JSR $FF7C ; WARMST

END

Output of the program: >G 2000

F >

Be careful while using this subroutine since the content of the Acc-A changes after execution!

OUTLHL $FFB2

Convert the left nibble of Acc-A content to ASCII and output to

terminal port

Ex: ORG $2000 ;

LDAA #$E3 ; Acc-A =$E3 JSR $FFB2 ; Call OUTLHL subroutine, Acc-A =$45 (ASCII

; of the character ‘E’)

JSR $FFB5 ; OUTRHL with the new content of Acc-A JSR $FF7C ; WARMST

END Output of the program:

>G 2000 E5

>

Be careful while using this subroutine since the content of the Acc-A

changes after execution!

OUT1BY $FFBB

Convert binary byte at address pointed by index register X to two

ASCII characters and output. Return address in index register X pointing to the next byte.

Ex:

ORG $2000 LDAA #$FE

STAA $2100 ; Content of the memory location $2100 is $FE LDX #$2100 ; X is pointing to address $2100

JSR $FFBB ; Address of ‘OUT1BY’ subroutine JSR $FF7C ; WARMST

END

Output of the program: >G 2000

FE >

Page 4: EE447_2013_EXP2

4

OUT1BS $FFBE

Convert binary byte at address pointed by index register X to two

ASCII characters and output followed by a space. Return address in

index register X pointing to next byte. Ex:

ORG $2000 LDAA #$FE

STAA $2100 LDAA #$AB

STAA $2101

LDX #$2100 ; X is pointing to address $2100 JSR $FFBE ; Address of ‘OUT1BS’ subroutine – X=X+1

JSR $FFBE ; Once more call OUT1BS with X pointing to $2101 JSR $FF7C ; WARMST

END

Output of the program:

> G 2000 FE AB

>

OUT2BS $FFC1

Convert two consecutive binary bytes starting at the address in index register X to four ASCII characters and the output is followed by a

space. Return address in index register X pointing to the address following the two bytes, i.e. X is incremented by 2.

Ex:

ORG $2000 LDD #$1234

STD $2100 LDD #$5678

STD $2102 LDX #$2100

JSR $FFC1

JSR $FFC1 JSR $FF7C

END

Output of the program:

>G 2000 1234 5678

>

UPCASE $FFA0

If character in Acc-A is lower case alpha, convert it to upper case. Ex:

If Acc-A =$74 (character t), then replaces it with Acc-A =$54 (character ‘T’)

WCHECK $FFA3

Test character in Acc-A and return with Z bit of the CCR set if character is a white space (space (SP), comma, tab (HT)).

DCHECK $FFA6

Tests character in Acc-A and return with Z bit set if character is a delimiter (carriage return (CR) or white space).

Page 5: EE447_2013_EXP2

5

INCHAR $FFCD

Input ASCII character to Acc-A and ECHO (output) the received

character back. This routine loops until character is actually

received from the terminal port.

OUTSTR

$FFC7

Output string of ASCII bytes whose initial address is pointed by index

register X until the ‘End of Transmission’ character is encountered. In ASCII, EOT: ($04).

Ex:

Memory Contents: Program: $00: $45 ORG $2000

$01: $45 LDX #$0000 $02: $34 JSR $FFC7 ; OUTSTR

$03: $34 JSR $FF7C ; WARMST

$04: $37 $05: $4C Output of the program:

$06: $41 >G 2000 $07: $42

$08: $04 EE447LAB >

Be careful while using this subroutine since the contents of the Acc-

A and index register X change after execution!

OUTST0 $FFCA

Same as OUTSTR except leading carriage return is skipped.

Consider previous memory contents:

Program 1: Program 2: ORG $2000 ORG $2000

LDX #$0000 LDX #$0000 JSR $FFC7 ; OUTSTR JSR $FFCA ; OUTST0

LDX #$0000 LDX #$0000 JSR $FFC7 ; OUTSTR JSR $FFCA ; OUTST0

JSR $FF7C JSR $FF7C

END END

Output of program 1: Output of program 2: >G 2000 >G 2000

EE447LABEE447LAB

EE447LAB > EE447LAB

> OUTST0 also affects content of index register X!

HEXBIN $FF85

Convert ASCII character in Acc-A to 4-bit binary number and shift this

binary number into SHFTREG from the right. If Acc-A is not

hexadecimal, location TMP1 is incremented and SHFTREG is left unchanged.

NOTE: Acc-A is hex if $30≤Acc-A≤$39 OR $41≤Acc-A≤$46

CHGBYT $FF8E Write value from SHFTREG+1 ($97) to memory location pointed by

X. (See the Supplementary Note at the end for details)

OUTPUT $FFAF Output character in Acc-A. CHRCNT indicates the current column on the output display. It is incremented every time a character is

outputted, and cleared whenever the subroutine OUTCLR is called.

Page 6: EE447_2013_EXP2

6

2.2. SAMPLE PROGRAM

Assume your program has an interaction with the user. You have to display some messages

and have to get data from user. Here is an example. ORG $2000

MSG1 FCC “Enter the option (1 or 2)”

FCB $04 ; EOT

MSG2 FCC “Your option is:”

FCB $04

ORG $2100

LDS #$0041 ; Initialize Stack Pointer

LDX #MSG1 ; IX is now pointing to start of MSG1

JSR $FFC7 ; OUTSTR subroutine

JSR $FFC4 ; OUTCLR subroutine

JSR $FFCD ; INCHAR subroutine

STAA $00 ; Store the value entered by the user

LDX #MSG2 ; IX points to MSG2

JSR $FFC7 ; OUTSTR subroutine (affects Acc-A!)

LDAA $00 ; Reload Acc-A with user entry

JSR $FFB8 ; OUTA subroutine

JSR $FF7C ; WARMST

Output of the Program: >G 2100

Hello. This is a sample program. Enter the option (1 or 2) 2 //user enters the number

Your option is: 2 >

2.3. PRELIMINARY WORK

2.3.1. A simple program is written and placed between $2100-$2122 memory locations. a) Disassemble it and write the output of the execution.

2100: 8E 00 41 86 49 97 00 86 3C 97 01 CE 33 45 DF 02 2110: 86 45 97 04 86 04 97 05 C6 05 CE 00 00 BD FF CA

2120: 5A 26 F7 BD FF 7C

b) Write the same program using AS11 assembler directives and utility subroutines.

2.3.2. a) Write a program that asks user to enter a character and returns a message whether it is a

whitespace or not. The program must continue until ‘ESC’ character is entered. Think of an

application area for such a program. b) Write a program that asks user to enter a character and returns a message whether it is a

delimiter or not. The program must continue until ‘ESC’ character is entered. Think of an application area for such a program.

Execution example for whitespace test: ENTER A CHARACTER (PRESS ESC TO EXIT)

2 // user enters 2 THE CHARACTER ENTERED IS NOT A WHITESPACE // message is displayed

ENTER A CHARACTER (PRESS ESC TO EXIT) // program continues , // user enters comma

THE CHARACTER ENTERED IS A WHITESPACE // message is displayed

ENTER A CHARACTER (PRESS ESC TO EXIT) (ESC) // user enters ESC

> // program returns to command line

This part just stores text messages at $2000 and the following memory area. It does not contain any instruction.

Main program starts here (at address $2100).

Page 7: EE447_2013_EXP2

7

2.3.3. Write an addition program for two unsigned 2-digit DECIMAL numbers to do the following: a) display the first number (2 decimal digits) input from the keyboard immediately

b) display a plus sign (+) after the first number

c) display the second number (again 2 decimal digits) input from the keyboard immediately d) display an equal sign (=) following the second number

e) do the addition (addition of two 2-digit decimal numbers) and display the result beside the equal sign (=). Your program should be able to display results with 3 digits as well. In case at

least one of the numbers entered by the user is not decimal, the text “Error, non-decimal input!” should be displayed next to the equal sign.

f) wait for a key to be stroked and then repeat the same procedure after moving to the next line

at the output. The program has to exit to the Buffalo command line at any time if the user presses the ESC (in ASCII ESC=$1B) button.

Note that all the display operation will not be done at once, but the two input numbers will be displayed as soon as they are entered (i.e. the plus sign will not appear before the first

number is entered, and so is the equal sign). Also remember that INCHAR subroutine echoes

back any input character back to the display without any need for an extra OUTA subroutine (whereas this is not the case for the EVBU 0.6 Simulator).

Examples: 68+02=70

00+53=53 39+87=126

1A+34=Error, non-decimal input!

2.3.4. Write a “number guess” game program that has the following properties:

a) Assume that the program is trying to find a number (a two-digit decimal number between 01-

99) that is known by the user.

b) The program will use the Binary Search algorithm to minimize the number of guesses made in

the average sense. The initial ordered set of possible numbers is {01, 02, ..., 99}. For each

step in guessing the number, the program will simply try the number that is in the middle of the ordered set of possible numbers. Hence it will try 50 as its first guess.

c) At any step, assume that the ordered set of possible numbers is {Nlow, ..., Nhigh}. Then the

guess of the program is Nguess = round[(Nhigh + Nlow)/2]. If this guess is lower than the user’s number, user is expected to enter the letter U representing “Upwards”. In this case the

ordered set of possible numbers will be updated to {Nguess+1, ..., Nhigh}. Otherwise, if the guess is higher than the user’s number, user will enter D representing “Downwards” and the

new set will be {Nlow, ..., Nguess-1}. If the guess is correct, user is expected to enter C representing “Correct” and the program will return to the command line.

d) At any step after the guess is made, the program should ask the user for the direction of the

next guess. As an example, it may display: My guess is 50. Is this (C)orrect? Or, should the next move be (U)pwards or (D)ownwards?

C, U, or D: (user enters one of the characters C, U, or D)

e) The program will ignore any user characters other than C, U, D, or ESC. ESC will again be

utilized for ending the program.

f) At the last step the user may try to cheat and give a command that may force the program to set Nhigh< Nlow. In this case, the program should display a warning message and should return

to the command prompt immediately. As an example, say that the current set of possible

guesses is {4,5} and the current guess is Nguess=round[(5 + 4)/2]=5. If the user enters “U”, clearly this cannot be a correct direction for the next guess. Similar argument is valid for the

same set with Nguess=4 and user input “D” as well.

Page 8: EE447_2013_EXP2

8

2.4. EXPERIMENTAL WORK

2.4.1. a) Execute the program given in preliminary work 1.a. and check if you have disassembled it

correctly. b) Execute the program you have written in preliminary work 1.b. Compare the result with

part a. 2.4.2. Execute the programs you have written in preliminary work 2.a. and 2.b.

2.4.3. Execute the program you have written in preliminary work 3.

2.4.4. Execute the program you have written in preliminary work 4.

Note: You will be able to use ASCII table and “Utility Subroutines” table provided by the assistant, during the quiz.

Neslihan Bayramoğlu, October 2004

Tuğcan Aktaş, October 2011 İlker Buzcu, November 2013

Page 9: EE447_2013_EXP2

9

EE 447 LABORATORY EXPERIMENT # 2

SUPPLEMENTARY NOTE

Purpose: This supplementary note is prepared with the aim of explaining HEXBIN and CHGBYT

subroutines in detail.

Assume all memory content is initially zero, Stack Pointer is initialized to a suitable value and Index

Register (IX), Acc. A and SHFTREG have following contents:

IX : $2000 (index register points to $2000 location in the memory)

Acc. A : $38 ASCII value for character ‘8’.

SHFTREG : Given in binary

SHFTREG (located at address $96) : 0000 0000 ($00)

SHFTREG+1 (located at address $97) : 0000 0000 ($00)

If the code segment given below is executed then the contents of Acc A and SHFTREG will be as

follows:

HEXBIN EQU $FF85

INCHAR EQU $FFCD

CHGBYT EQU $FF8E

JSR HEXBIN This subroutine converts $38 (content of A) to “1000” (binary) and shifts this

number to SFHTREG from right. Now the content of SHFTREG is:

SHFTREG (located at address $96) : 0000 0000 ($00)

SHFTREG+1 (located at address $97) : 0000 1000 ($08)

JSR INCHAR Assume user enters “7” Acc.A: $37

JSR HEXBIN This subroutine converts $37 (content of A) to “0111” (binary) and shifts this

number to SFHTREG. Now the content of SHFTREG is:

SHFTREG (located at address $96): 0000 0000 ($00)

SHFTREG+1 (located at address $97): 1000 0111 ($87)

JSR CHGBYT Write the value from location $97 (SHFTREG+1) to memory location pointed

by IX (in this case to memory location $2000). Now the content of memory

location $2000 becomes $87

JSR INCHAR Assume user enters “A” Acc.A: $41

JSR HEXBIN This subroutine converts $41 (content of A) to “1010” (binary) and shifts this

number to SFHTREG. Now the content of SHFTREG is:

SHFTREG (located at address $96): 0000 1000 ($08)

SHFTREG+1 (located at address $97): 0111 1010 ($7A)

JSR INCHAR Assume user enters “E” Acc.A: $45

JSR HEXBIN This subroutine converts $45 (content of A) to “1110” (binary) and shifts this

number to SFHTREG. Now the content of SHFTREG is:

SHFTREG (located at address $96): 1000 0111 ($87)

SHFTREG+1 (located at address $97): 1010 1110 ($AE)

INX Now IX points to $2001

JSR CHGBYT Write the value from location $97 (SHFTREG+1) to memory location pointed

by IX (in this case to memory location $2001). Now the content of $2001

becomes $AE

You can use either CHGBYT in your programs or you can read $96 and $97 directly. However, address mapping of Buffalo registers depends on the version of the Buffalo program. So be careful

About the addressing of the registers and to be in the safe side prefer using CHGBYT. Following codes do the same job in case SHFTREG resides at memory locations $96 and $97 and hence Code 3

is preferable as a well-written source code segment:

Page 10: EE447_2013_EXP2

1

0

Code 1: Code 2: Code 3:

JSR INCHAR

JSR HEXBIN

JSR INCHAR

JSR HEXBIN

LDAA $97

STAA $2000

JSR INCHAR

JSR HEXBIN

JSR INCHAR

JSR HEXBIN

LDAA $97

STAA $2001

JSR INCHAR

JSR HEXBIN

JSR INCHAR

JSR HEXBIN

JSR INCHAR

JSR HEXBIN

JSR INCHAR

JSR HEXBIN

LDD $96

STD $2000

LDX #$2000

JSR INCHAR

JSR HEXBIN

JSR INCHAR

JSR HEXBIN

JSR CHGBYT

JSR INCHAR

JSR HEXBIN

JSR INCHAR

JSR HEXBIN

INX

JSR CHGBYT

Neslihan Bayramoğlu October 2004

Page 11: EE447_2013_EXP2
Page 12: EE447_2013_EXP2

Utility Subroutine Jump Table

Address Routine Description

$FF7C .WARMST Go to ">" prompt point (skip BUFFALO... message).

$FF7F .BPCLR Clear breakpoint table.

$FF82 .RPRINT Display user’s registers.

$FF85

.HEXBIN Convert ASCII character in A register to 4-bit binary number. Shift binary number into SHFTREG from the right. SHFTREG is a 2-byte (4 hexadecimal digits) buffer. If A

register is not hexadecimal, location TMP1 is incremented and SHFTREG is

unchanged.

$FF88 .BUFFAR Read 4-digit hexadecimal argument from input buffer to SHFTREG.

$FF8B .TERMAR Read 4-digit hexadecimal argument from terminal device to SHFTREG.

$FF8E

.CHGBYT

Write value (if any) from SHFTREG+1 to memory location pointed to by X. (Operation also applicable to EEPROM locations.)

$FF91 .READBU Read next character from INBUFF.

$FF94 .INCBUF Increment pointer into input buffer.

$FF97 .DECBUF Decrement pointer into input buffer.

$FF9A .WSKIP Read input buffer until non-whitespace character found.

$FF9D .CHKABR Monitor input for (CTRL)X, (DELETE), or (CTRL)W requests.

$FFA0 .UPCASE If character in accumulator A is lower case alpha, convert to upper case.

$FFA3 .WCHECK Test character in accumulator A and return with Z bit set if character is white space

(space, comma, tab).

$FFA6 .DCHECK Test character in accumulator A and return with Z bit set if character is delimiter (carriage return or white space).

$FFA9 .INIT Initialize I/O device.

$FFAC .INPUT Read I/O device.

$FFAF .OUTPUT Write I/O device.

$FFB2 .OUTLHL Convert left nibble of accumulator A contents to ASCII and output to terminal port.

$FFB5 .OUTRHL Convert right nibble of accumulator A contents to ASCII and output to terminal port.

$FFB8 .OUTA Output accumulator A ASCII character.

$FFBB .OUT1BY Convert binary byte at address in index register X to two ASCII characters and output. Returns address in index register X pointing to next byte.

$FFBE .OUT1BS Convert binary byte at address in index register X to two ASCII characters and output

followed by a space. Returns address in index register X pointing to next byte.

$FFC1 .OUT2BS Convert two consecutive binary bytes starting at address in index register X to four ASCII characters and output followed by a space. Returns address in index register X

pointing to next byte.

$FFC4 .OUTCLR Output ASCII carriage return (CR) followed by a line feed, i.e. move to a new line.

$FFC7 .OUTSTR Output string of ASCII bytes pointed to by address in index register X until character is an end of transmission ($04).

$FFCA .OUTST0 Same as OUTSTR except leading carriage return and line feed is skipped.

$FFCD .INCHAR Input ASCII character to accumulator A and echo back. This routine loops until

character is actually received.

$FFD0 .VECINIT Used during initialization to preset indirect interrupt vector area in RAM. This routine or a similar routine should be included in a user program which is invoked by the

jump to $B600 feature of BUFFALO.