This week for my lab we get to decide a program to write in our 6502 emulator. This program must fit the following criteria:
- You must output to the character screen as well as the graphics (bitmapped) screen.
- You must accept user input from the keyboard in some form.
- You must use some arithmetic/math instructions (to add, subtract, do bitwise operations, or rotate/shift
My choice of program to meet these requirements will be an addition and subtraction calculator that takes in two numbers for user input then performs either addition or subtraction to the two numbers. We already have an addition calculator as an example and I will follow that to build the subtraction portion of the lab.
; Adding calculator
; ROM routine entry points
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
; zeropage variables
define PRINT_PTR $10
define PRINT_PTR_H $11
define value $14
define value_h $15
; absolute variables
define GETNUM_1 $0080
define GETNUM_2 $0081
; constants
; --------------------------------------------------------
jsr SCINIT
jsr CHRIN
jsr PRINT
dcb "A","d","d","i","n","g",32
dcb "c","a","l","c","u","l","a","t","o","r",00
start: jsr PRINT
dcb $0d,$0d,"E","n","t","e","r",32,"a",32,"n","u","m","b","e","r"
dcb "(","0","-","9","9",")",":"
dcb 32,32,32,32,32,32,32,32,00
lda #$00
sta value_h
jsr GETNUM
sta value
jsr PRINT
dcb "E","n","t","e","r",32,"a","n","o","t","h","e","r"
dcb 32,"n","u","m","b","e","r",32,"(","0","-","9","9",")",":",32,00
jsr GETNUM
sed
clc
adc value
cld
sta value
bcc result
inc value_h
result: pha
jsr PRINT
dcb "R","e","s","u","l","t",":",32
dcb 32,32,32,32,32,32,32
dcb 32,32,32,32,32,32,32
dcb 32,32,32,32,32,32,32
dcb 00
lda value_h
beq low_digits
lda #$31
jsr CHROUT
jmp draw_100s
low_digits: lda value
and #$f0
beq ones_digit
draw_100s: lda value
lsr
lsr
lsr
lsr
ora #$30
jsr CHROUT
ones_digit: lda value
and #$0f
ora #$30
jsr CHROUT
jsr start
; --------------------------------------------------------
; Print a message
;
; Prints the message in memory immediately after the
; JSR PRINT. The message must be null-terminated and
; 255 characters maximum in length.
PRINT: pla
clc
adc #$01
sta PRINT_PTR
pla
sta PRINT_PTR_H
tya
pha
ldy #$00
print_next: lda (PRINT_PTR),y
beq print_done
jsr CHROUT
iny
jmp print_next
print_done: tya
clc
adc PRINT_PTR
sta PRINT_PTR
lda PRINT_PTR_H
adc #$00
sta PRINT_PTR_H
pla
tay
lda PRINT_PTR_H
pha
lda PRINT_PTR
pha
rts
; ---------------------------------------------------
; GETNUM - get a 2-digit decimal number
;
; Returns A containing 2-digit BCD value
GETNUM: txa
pha
tya
pha
ldx #$00 ; count of digits received
stx GETNUM_1
stx GETNUM_2
getnum_cursor: lda #$a0 ; black square
jsr CHROUT
lda #$83 ; left cursor
jsr CHROUT
getnum_key: jsr CHRIN
cmp #$00
beq getnum_key
cmp #$08 ; BACKSPACE
beq getnum_bs
cmp #$0d ; ENTER
beq getnum_enter
cmp #$30 ; "0"
bmi getnum_key
cmp #$3a ; "9" + 1
bmi getnum_digit
jmp getnum_key
getnum_enter: cpx #$00
beq getnum_key
lda #$20
jsr CHROUT
lda #$0d
jsr CHROUT
lda GETNUM_1
cpx #$01
beq getnum_done
asl
asl
asl
asl
ora GETNUM_2
getnum_done: sta GETNUM_1
pla
tay
pla
tax
lda GETNUM_1
rts
getnum_digit: cpx #$02
bpl getnum_key
pha
jsr CHROUT
pla
and #$0f
sta GETNUM_1,x
inx
jmp getnum_cursor
getnum_bs: cpx #$00
beq getnum_key
lda #$20
jsr CHROUT
lda #$83
jsr CHROUT
jsr CHROUT
lda #$20
jsr CHROUT
lda #$83
jsr CHROUT
dex
lda #$00
sta GETNUM_1,x
jmp getnum_cursor
Above is the adding calculator for the 6502. In this blog I will discuss and dissect how this program works.
First, the ROM routines entry points are pre written routines in 6502 memory located at its specified address. The routines that is used here are for input and output purposes, as is shown in the commented section of the code.
Second, zero page variables are stored in the first 256 bytes of memory for faster processing of instructions, we are using them here as pointers when printing messages and to store values of the inputted numbers and final result.
Thirdly I will discuss how the program overall works. The jsr SCINIT will jump to sub routine and clear up the screen for the output. From here on we will be using lots of jsr (jump to subroutine) instructions so I will just refer to it as jsr. Then it will jsr to the print routine which displays the text "Adding Calculator" then it waits for the user input. It will then prompt for the first number and then "get" the first number using the GETNUM subroutine and it will store it in value. It will do the same thing for the second number then it moves onto the actual addition part of the program. Before it starts adding it will convert the two numbers into BCD format. BCD format means it is binary coded decimal which means it represents decimal point numbers as binary numbers. Moving on, these two BCD formatted numbers are added using the ADC instruction. Finally the program converts back to decimal and displays the result.
To add the subtraction part will be fairly easy as most of the ground work is already laid out. We will first have to prompt the user to select either subtraction or addition. We will have to add a new zero page variable to store this selection and request the user to either input "+" or "-" for selection. Next we should branch our selections using BEQ and have them split into either addition or subtraction based on user input. Next we can simply use SBC instruction and handle the operation similarly to the ADC instruction.
In my next report I will implement this to the best of my abilities. However, like the previous lab I always think the job will be simple until I actually try it so this project may be harder than I think it is.
Comments
Post a Comment