Thanh Van

Posted on

# SPO600 - Lab 4 - Option 1

In the previous lab, we were working with Math in Assembly Language. However, in this lab, we will be working on Assembly Language String. We have four options to pick this time, and implement two of them:

• Adding Calculator
• Data Input Form
• Hexdump
• Screen Colour Selector

For the first option, I choose Adding Calculator to work on.

## Instruction

1. Create a subroutine which enables the user to enter two numbers of up to two digits. Indicate where the cursor is, and allow the user to use the digit keys (0-9), backspace, and enter keys. Return the user's input value in the accumulator register.
2. Using this subroutine, write a program which add the two numbers (each of which is in the range 0-99) and print the result.

## Program

``````; ======== variables for screen input/output ========
define  SCINIT  \$ff81 ; initialize/clear screen
define  CHRIN  \$ffcf ; input character from keyboard
define  CHROUT  \$ffd2 ; output character to screen
define  SCREEN  \$ffed ; get screen size
define  PLOT    \$fff0 ; get/set cursor coordinates

; ======== variables for key ========
define RIGHT  \$81
define LEFT  \$83
define ENTER  \$0d
define BACKSPACE \$08

; numbers given by user
define NUM1    \$15;
define  NUM2    \$16;

jsr SCINIT

; prompts to get input from user, do calculation and print the result
mainLoop:
ldy #\$00
jsr firstNumPrint ; ask for input for first number
jsr getNum; get the first number
jsr storeFirstNum  ; then store the first number
ldy #\$00
jsr secondNumPrint  ; ask for input for second number
jsr getNum; get the second number
jsr storeSecondNum  ; store the second number
ldy #\$00
jsr resultPrintString  ; print a string 'Result'
jsr printResult ; print the result
jmp mainLoop  ; go back to the first step

getNum:
sec
jsr PLOT
ldx #\$15
clc
jsr PLOT

getNumLoop:
sec
jsr PLOT
jsr CHRIN

charCheck:
cmp #BACKSPACE ; if user enter backspace, it erase the #\$15 digit
beq move_back

cmp #RIGHT ; if user enter right arrow, it goes to the first digit
beq move_right

cmp #LEFT ; if user enter left arrow, it goes to the second digit
beq move_left

cmp #ENTER ; if user enter enter, it goes to the next process
beq move

drawNum:
; check whether user enters number (#\$30-#\$39)
cmp #\$30
bcc getNumLoop

clc
cmp #\$3a
bcs getNumLoop

jsr CHROUT

sec
jsr PLOT
cpx #\$17
bne getNumLoop
dex
clc
jsr PLOT
jmp getNumLoop

move_back:
cpx #\$15
beq getNumLoop
jsr CHROUT
jmp getNumLoop

move_left:
cpx #\$15 ; first digit
beq getNumLoop
jsr CHROUT
jmp getNumLoop

move_right:
cpx #\$16 ; second digit
beq getNumLoop
jsr CHROUT
jmp getNumLoop

move:
sec
jsr PLOT
ldx #\$15 ; first degit
clc
jsr PLOT
sec
jsr PLOT

clc
sbc #\$2F ; to calculate it, it should be subtracted by #\$2f

asl
asl
asl
asl

pha

ldx #\$16
clc
jsr PLOT
sec
jsr PLOT

clc
sbc #\$2F ; to calculate it, it should be subtracted by #\$2f
pha

ldx #\$00
iny
clc
jsr PLOT
sec
jsr PLOT

pla
tax
pla

rts

; store the first number
storeFirstNum:
sta NUM1
txa
eor NUM1
sta NUM1
rts

; store the second number
storeSecondNum:
sta NUM2
txa
eor NUM2
sta NUM2
rts

; print out the result
printResult:
sec
jsr PLOT
ldx #\$15
clc
jsr PLOT
sec
jsr PLOT

sed
lda NUM1
adc NUM2
cld
pha

bcc outputAddition
ldx #\$14
clc
jsr PLOT
sec
jsr PLOT
lda #\$31
jsr CHROUT

; calculation of the two number
outputAddition:
lsr
lsr
lsr
lsr
clc
adc #\$30 ; as the received number does not fit for ASCII, it needs to add #\$30
jsr CHROUT

pla
and #\$0F
clc
adc #\$30 ; as the received number does not fit for ASCII, it needs to add #\$30
jsr CHROUT

sec
jsr PLOT
ldx #\$00
iny
clc
jsr PLOT

rts

; prompt to get first number, format "00"
firstNumPrint:
lda firstNum,y
beq goback_main
jsr CHROUT
iny
bne firstNumPrint

; prompt to get the second number, format "00"
secondNumPrint:
lda secondNum,y
beq goback_main
jsr CHROUT
iny
bne secondNumPrint

; print our the result line
resultPrintString:
lda result,y
beq goback_main
jsr CHROUT
iny
bne resultPrintString

; go back to the "mainLoop"
goback_main:
rts

firstNum:
dcb "E","N","T","E","R",32,"F","I","R","S","T",32,"N","U","M","B","E","R",":",32,32,"0","0"
dcb 00

secondNum:
dcb "E","N","T","E","R",32,"S","E","C","O","N","D",32,"N","U","M","B","E","R",":",32,"0","0"
dcb 00

result:
dcb "R","E","S","U","L","T",":"
dcb 00

``````

## What I have learned from this lab?

This lab definitely takes a lot of my time, I always encounter error related to subroutines. Since I am not used to Assembly Language yet, however, this is why I have to spend some times working on it.