Lab 4 - SPO600 Part 1
Tags: beginners
Published: 2021-11-13 19:02:51

## Introduction
Hello everyone, my name is Dustin. Today, I'd like to talk about my experience working with Assembly language in SPO class. 

For this lab, we got to choose 2 out of 4 options that my professor gave to me which are Adding Calculator, Data Input Form, Hexdump, Screen Colour Selector. As I've worked with math lab before in the previous week, so I decided to go with the option of Adding Calculator, which seems like very interesting.

## Requirement
- 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 (A) register.
- Using this subroutine, write a program which add the two numbers (each of which is in the range 0-99) and print the result.

## Thought?
Although it looks quite easy and not a big deal at first time, but it took me way too much time. Compared to other languages I have learnt including C, C++, Java, Javascript, Assembler is way too difficult and it takes much more effort to get the same things done. Normally, for such a program, it would only take me round 5 minutes but this one took me a day. 

For this lab, I used [6502 assembler](http://6502.cdot.systems/) to run my program. 

Declare variables for screen input and 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
```

Key values
```
define RIGHT  $81
define LEFT  $83
define ENTER  $0d
define BACKSPACE $08
```

Catch numbers entered by user
```
define NUM1    $15;
define  NUM2    $16;
```

Clear screen
```
jsr SCINIT
```

Prompt to get input from user, and calculate
```
     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
```

Check to see if user enters a number from 0 to 9

```
     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
```
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 num
```
storeFirstNum:
     sta NUM1
     txa
     eor NUM1
     sta NUM1
     rts

storeSecondNum:
     sta NUM2
     txa
     eor NUM2
     sta NUM2
     rts
```

Print
```
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
```

Calculate two nums
```
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 numbers in format "00"
```
 lda firstNum,y
        beq goback_main
        jsr CHROUT
        iny
        bne firstNumPrint

secondNumPrint:
 lda secondNum,y
        beq goback_main
        jsr CHROUT
        iny
        bne secondNumPrint
```

Print the result
```
resultPrintString:
 lda result,y
        beq goback_main
        jsr CHROUT
        iny
        bne resultPrintString
```

go back to main loop
```
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
```