Adding Calculator

Add Calculator

In this post, I will be discussing how we implemented opcode using 6502 chip architecture to take user input of 2 digits and add them together to get a final result. This calculator will take only positive numbers ranging from 0-99. This will be done using a combination of instructions and ROM routines built into the chip.

Setting the Cursor Position

; ROM routines
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
 
	jsr SCINIT
        ldy #$00
	 
cursorPos:     	 	;set cursor position
    	clc     	;clear carry for PLOT
    	ldy #$03    	;set coordinate Y
    	ldx #$00    	;set coordinate X
    	jsr PLOT    	;call PLOT
	jmp idle
idle:     
        lda $f000,y
        eor #$80
        sta $f000,y
    	jmp cursorPos

Here is a code using plot to set the cursor position for where the user will begin to input their unsigned integers to calculate. The label cursorPos will set this position. Once the position is set, we include the idle label. This label allows the user to see where their current position is on the character display. The next step is to take user input and display it onto the character display box.

Accepting User Input

cursorPos:     	 	;set cursor position
    	clc     	;clear carry for PLOT
    	ldy #$03    	;set coordinate Y
    	ldx #$00    	;set coordinate X
    	jsr PLOT    	;call PLOT
	
input:
    	jsr CHRIN
	bne display
    	jmp idle
 
display:
	jsr CHROUT
	iny
    	jmp input
idle:     
        lda $f000,y
        eor #$80
        sta $f000,y
	lda $ff
    	jmp input

We have added the labels display and input. I will first explain what the input label’s main function is. Calling the ROM routine, CHRIN, accepts a user input and stores it in the Accumulator and using branch if not equal (bne) is how we will be accepting user input and displaying it onto the character display box. If there is nothing stored in the accumulator, then the program will skip the branch to display and jump to the label idle. Although, if CHRIN returns a character to the accumulator, then the display label will be called. Once in the display label, CHROUT will take what ever is stored in the accumulator and output it to the character display box.

Notice that normally we would have to manage the memory location $ff, if we were using only instructions. CHROUT and CHRIN remove the hassle of managing $ff, which the chip architecture uses to store the last key pressed from the keyboard.

Store User Input

; ROM routines
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
 
    
	jsr SCINIT
        ldy #$00
	lda #$00
	sta $20
	 
cursorPos:     	 	;set cursor position
    	clc     	;clear carry for PLOT
    	ldy #$03    	;set coordinate Y
    	ldx #$00    	;set coordinate X
    	jsr PLOT    	;call PLOT
	
input:
    	jsr CHRIN
	bne display
    	jmp idle
 
display:
	jsr CHROUT
	iny
	cmp #$2b
	bne store
	beq input2
    	jmp input


store2:
	sta $21		;store second user input into memory location $21
	brk
	rts

store:
	sta $20		;store first user input into memory location $20
	jmp input   

add:
	clc
	lda $20
	adc $21
	jsr CHROUT
	brk            ;end of program

idle:     
        lda $f000,y
        eor #$80
        sta $f000,y
	lda $ff
    	jmp input

input2:
    	jsr CHRIN
	bne display2
    	jmp idle2
display2:
	jsr CHROUT
	iny
	jsr store2
	cmp #$0d
	beq add
    	jmp input2
idle2:     

        lda $f000,y
        eor #$80
        sta $f000,y
	lda $ff
    	jmp input2
 
brk ;in case program runs pass

In expanding our code, we have created a label called store. This label’s purpose is to store the first digit inputted by user into memory location $20. Once the first input was stored, we had to figure out a way to store the second digit that a user inputs. This is where we expanded our code to include 4 more labels, store2, input2, display2, and idle2. These label’s purposes are the same as the previous but they take into account that the user had already previously entered a digit value.

On line 28, 29, and 30 we added 3 lines of code to out label display. We compare the value entered by a user, which is returned to the accumulator, and compare to #$2b. This value is represented by a ‘+’ ASCII character. If the accumulator does not contain #$2b, then we know that the user has yet to enter the first value, otherwise we branch to our 4 labels that we created.

Not much has change for labels input2 and idle2, they are the same as the previous ones we have created. What has been modified that has to be highlighted is label’s store2 and display2. In store2, we would store the second value into memory location $21. The program knows that it is the second value because of our display label. If #$2b is returned to our accumulator, the program understands that following the user input should be stored and used as the second value when we do our addition.

Things to be Completed

Adding two values in memory – We have stored both of the user input into memory locations $20 and $21. We found that if we stored the number 1, we would get the hex ASCII value of 31. We need to convert our digit into an ASCII character to display.

Conclusion

In Conclusion, I have found that using CHROUT and CHRIN have been easier to manage then only using instructions. The built-in management of last key pressed being returned to the accumulator has allowed me to avoid managing memory location $ff. PLOT has been helpful in determining the cursor position. When dealing with the character display box, the rows and pages do not necessarily mean the first pixel on the row. Using PLOT, which handles coordinates in rows and columns, has helped me manage new lines. I would recommend using ROM routines because they handle a lot of management in the back end.

Published by Danny Nguyen

I am a curious person. I find interest in all aspects of software development cycle, software stacks, and how the same software is used in different industries in different ways

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create your website with WordPress.com
Get started
%d bloggers like this: