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
- 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.
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
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
Result
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)