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
The detailed instruction for this lab is demonstrated here.
1. Design
1.1. Pseudo Code
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
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.
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
- 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 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
- Store "Enter the first number", "Enter the second number", "result" to output on the screen
- Print the "Enter the first number: "
- Receive the first number from the user. User can use enter to store the number and backspace to erase a number
- Store the received first number from the user
- Print the "Enter the second number: "
- Receive the second number from the user. The user can use enter to store the number and backspace to erase the number.
- Store the received second number from the user
- Print a string "Result: "
- Print the result
- 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
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
Post a Comment