This week for my lab we get to decide a program to write in our 6502 emulator. This program must fit the following criteria: 

  1. You must output to the character screen as well as the graphics (bitmapped) screen.
  2. You must accept user input from the keyboard in some form.
  3. 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

Popular posts from this blog

Early stages of project

Building GCC again on aarch64-002

Project Stage 2: Testing