Lab 4 (6502 Assembly Language String Lab): Option 1: Adding Calculator

Introduction
In this posting, I will describe a design and implementation for option 1, lab 4: Adding Calculator. There is a previous posting to describe a code for option 4: Screen Colour Selector.

Option 1: Adding Calculator
  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 (A) register.
  2. Using this subroutine, write a program which adds the two numbers (each of which is in the range 0-99) and print the result.

The detailed instruction for this lab is demonstrated here.

1. Design
1.1. Pseudo Code
  1. Store "Enter the first number", "Enter the second number", "result" to output on the screen
  2. Print the "Enter the first number: "
  3. Receive the first number from the user. User can use enter to store the number and backspace to erase a number
  4. Store the received first number from the user
  5. Print the "Enter the second number: "
  6. Receive the second number from the user. The user can use enter to store the number and backspace to erase the number.
  7. Store the received second number from the user
  8. Print a string "Result: "
  9. Print the result
  10. Goes back to the second step

1.2. Variables
; ======== 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

; ======== variables for Numbers that user input ========
define NUM1    $15;
define  NUM2    $16;

1.3. Subroutines

  • mainLoop: main looping for the steps described in the psuedo code
  • receiveNum: initialize index x to #$15. This place is the start point of output the received number on the screen
  • receiveNum_loop: waiting for inputting value
  • charCheck: check the inputted value. 
    • If it is backspace, it erases the #$15 digit. 
    • If it is the right arrow, it goes to the first digit
    • If it is the left arrow, it goes to the second digit
    • If it is the enter, it goes to the next process
  • drawNum: if the user enters number (#$30 - #$39), it stores the value. If there are already 2 digits received, the second digit will be changed
  • move_back: it will be executed when the user enters the backspace
  • move_left: it will be executed when the user enters the left arrow
  • move_right: it will be executed when the user enters the right arrow
  • move: it will be executed when the user enters 
  • firstNum_store: store the first number the user inputs
  • secNum_store: store the second number the user inputs
  • result_print: add the first number with the second number and goes to the outputAddition subroutine
  • outputAddition: add #$30 to convert into ASCII format
  • firstNumPrint: print "ENTER FIRST NUMBER: 00"
  • secNumPrint: print "ENTER SECOND NUMBER: 00"
  • resultPrint: print "RESULT: "
  • goback_main: to go back to the mainLoop subroutine. It will be used in the firstNumPrint, secNumPrint, resultPrint subroutines
2. Implementation
Whole Code
; ======== 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

; ======== variables for Numbers that user input ========
define NUM1    $15;
define  NUM2    $16;

        jsr SCINIT

; ======= main Loop: print first num input question -> receive first Number
;                   -> print second num question -> receive second Number -> print result
;                   -> go back to the first step
mainLoop:
    ldy #$00
    jsr firstNumPrint ; first number input question
    jsr receiveNum; receive first number
    jsr firstNum_store ; store the received number
    ldy #$00
    jsr secNumPrint ; second number input question
    jsr receiveNum; receive second number
    jsr secNum_store ; store the received number
    ldy #$00
    jsr resultPrint ; print a string 'Result'
    jsr result_print ; print the result
    jmp mainLoop ; go back to the first step
 

receiveNum:
    sec
    jsr PLOT
    ldx #$15
    clc
    jsr PLOT

receiveNum_loop:
    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 receiveNum_loop
 
    clc
    cmp #$3a
    bcs receiveNum_loop
 
    jsr CHROUT

    sec
    jsr PLOT
    cpx #$17
    bne receiveNum_loop
    dex
    clc
    jsr PLOT
    jmp receiveNum_loop

move_back:
cpx #$15
beq receiveNum_loop
jsr CHROUT
jmp receiveNum_loop

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

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

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 (hexadecimal for number 0: #$30)

    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 (hexadecimal for number 0: #$30)
    pha

    ldx #$00
    iny
    clc
    jsr PLOT
    sec
    jsr PLOT

    pla
    tax
    pla

    rts

; ======== store the first number =========
firstNum_store:
    sta NUM1
    txa
    eor NUM1
    sta NUM1
    rts

; ======== store the second number =========
secNum_store:
    sta NUM2
    txa
    eor NUM2
    sta NUM2
    rts

; ========= print result ========
result_print:
    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 for result 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

; ======== print 'ENTER FIRST NUMBER: 00 =======
firstNumPrint:
lda firstNum,y
        beq goback_main
        jsr CHROUT
        iny
        bne firstNumPrint

; ======== print "ENTER SECOND NUMBER: 00" ==========
secNumPrint:
lda secondNum,y
        beq goback_main
        jsr CHROUT
        iny
        bne secNumPrint

; ======== print "RESULT: " ==============
resultPrint:
lda result,y
        beq goback_main
        jsr CHROUT
        iny
        bne resultPrint

; ========= goes back to the 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

3. What I have learned from this lab
I have a lot of difficulties to do this lab. The process about getting the value from the user, store the received value into the register to use and output the result are still confusing. I should spend more time to learn how to handle the string in the 6502 assembler.

Comments

Popular posts from this blog

Open Source Project: Lab2 (Pull Request)

Release 4.0 - Part 3: Release

Lab 8: Automated Testing and Continuous Integration