DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 963,503 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Qiwen Yu
Qiwen Yu

Posted on

6502- Lab4(Option 1): Adding Calculator

Introduction

In this blog, I'm going to create a calculator using 6502 assembly language. I will create a subroutine which enables the user to enter two numbers of up to two digits and provide appropriate user prompts and feedback.

Add Calculator Requirements

  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 add the two numbers (each of which is in the range 0-99) and print the result.

Thoughts and Steps

-> The first number, the second number and the result can be stored and to be displayed on the screen.
-> Prompt the appropriate sentence for user.
"Please enter the first number: "
-> Take the user input for the first number.
-> User can use "ENTER" to store the number, use backspace to delete.
-> Prompt the appropriate sentence for user.
"Please enter the second number: "
-> Take the user input for the second number.
-> User can use "ENTER" to store the number, use backspace to delete.
-> Prompt the result for user and display it on the screen.

Define Variables

define NUM1   $15;   for the first number of user's input 
define NUM2   $16;   for the second number of user's input

define ENTER  $0d;   for the ENTER key
define BACKSPACE $08; for the BACKSPACE key
define RIGHT  $81;   for the RIGHT Key
define LEFT  $83;    for the LEFT key

define  SCREEN  $ffed; for getting the screen size
define  PLOT    $fff0; for getting or setting the cursor coordinates
define  SCINIT  $ff81; for initializing or clearing the screen
define  CHRIN  $ffcf; for taking the input character from keyboard
define  CHROUT  $ffd2; for displaying the output character to screen

Enter fullscreen mode Exit fullscreen mode

Solution to this Lab

define NUM1   $15;   for the first number of user's input 
define NUM2   $16;   for the second number of user's input

define ENTER  $0d;   for the ENTER key
define BACKSPACE $08; for the BACKSPACE key
define RIGHT  $81;   for the RIGHT Key
define LEFT  $83;    for the LEFT key

define  SCREEN  $ffed; for getting the screen size
define  PLOT    $fff0; for getting or setting the cursor coordinates
define  SCINIT  $ff81; for initializing or clearing the screen
define  CHRIN  $ffcf; for taking the input character from keyboard
define  CHROUT  $ffd2; for displaying the output character to screen

jsr SCINIT

mainLoop:
     ldy #$00
     jsr firstNumInput ; first number input question
     jsr getNum; receive the first number
     jsr firstNumStore  ; store the input number

     ldy #$00
     jsr secondNumInput  ; second number input question
     jsr getNum; receive the second number
     jsr secondNumStore  ; store the input number

     ldy #$00
     jsr resultStr  ; for displaying the result string
     jsr result ; for displaying the calculation result
     jmp mainLoop  ; go back to the first step


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

getNumLoop:
     sec
     jsr PLOT
     jsr CHRIN

keyboardCheck: 
     cmp #BACKSPACE ; after using BACKSPACE, one digit will be deleted
     beq delete

     cmp #RIGHT ; using RIGHT arrow key, the program goes to the first digit
     beq moveR

     cmp #LEFT ; using LEFT arrow key, the program goes to the second digit
     beq moveL

     cmp #ENTER ; after pressing ENTER, the program goes to the next process
     beq move

drawNum:
     cmp #$30
     bcc getNumLoop

     clc
     cmp #$3a
     bcs getNumLoop

     jsr CHROUT

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

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

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

delete:
 cpx #$15
     beq getNumLoop
     jsr CHROUT
     jmp getNumLoop


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

     clc
     sbc #$2F

     asl
     asl
     asl
     asl

     pha

     ldx #$16
     clc
     jsr PLOT
     sec
     jsr PLOT

     clc
     sbc #$2F
     pha

     ldx #$00
     iny
     clc
     jsr PLOT
     sec
     jsr PLOT

     pla
     tax
     pla

     rts

firstNumStore:
     sta NUM1
     txa
     eor NUM1
     sta NUM1
     rts


secondNumStore:
     sta NUM2
     txa
     eor NUM2
     sta NUM2
     rts


calculateAdd:
     lsr
     lsr
     lsr
     lsr
     clc
     adc #$30;
     jsr CHROUT

     pla
     and #$0F
     clc
     adc #$30;
     jsr CHROUT

     sec
     jsr PLOT
     ldx #$00
     iny
     clc
     jsr PLOT

     rts

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

     sed
     lda NUM1
     adc NUM2
     cld
     pha

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

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

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


firstNumInput:
 lda firstNum,y
        beq goback_main
        jsr CHROUT
        iny
        bne firstNumInput

secondNumInput:
 lda secondNum,y
        beq goback_main
        jsr CHROUT
        iny
        bne secondNumInput

resultStr:
 lda results,y
        beq goback_main
        jsr CHROUT
        iny
        bne resultStr

goback_main:
     rts


Enter fullscreen mode Exit fullscreen mode

Result

Image description

Thoughts

6502 is getting harder and harder for me to understand now. I have met a lot of difficulties during this lab. It is important to write the pseudo code first and then follow the pseudo code to write the actual code. The point of doing this is to help myself have a clearer view of this task. To retrieve the value of user's input, to store the value, and to display the results are three big tasks for me during this lab. I am still not so familiar with using the language properly right now. I have to look up the cheatsheet again and again. But this process did help me to understand more on how the register works, how the 6502 assembly language works.

Top comments (0)

🌚 Browsing with dark mode makes you a better developer.

It's a scientific fact.