SPO600 - Lab 4 - Option 1
Tags: beginners, opensource
Published: 2021-11-04 17:40:12

In the [previous lab](https://dev.to/tcvan0707/spo600-lab-3-58m4), 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.