Lab3 - 6502 Math and Strings Lab

Today, the task is creating a simple program using the 6502 assembly language. I will create an adding calculator.

As a beginner, it is really hard to create the code from scratch, so I will use Chris Tyler's code as a foundation. This is the GitHub repository that I referenced.

Here is the original code:

; 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

As you can see, it shows you the addition of two numbers from 0 to 99.

Let me improve the code to allow for the addition of three numbers from 0 to 99.

Here is the code that I made improvements.

; 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		firstNum	$14 ;first number input
define		secondNum	$15 ;second number input
define		thirdNum	$16 ;third number input

; absolute variables
define		GETNUM_1	$0080
define		GETNUM_2	$0081
define		GETNUM_3	$0082

; 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,"f","i","r","s","t",32,"n","u","m","b","e","r"
dcb "(","0","-","9","9",")",":"
dcb 32,32,32,32,32,00

		lda #$00
		jsr GETNUM
		sta firstNum

		jsr PRINT

dcb "E","n","t","e","r",32,"s","e","c","o","n","d",
dcb 32,"n","u","m","b","e","r",32,"(","0","-","9","9",")",":",32,32,32,00

		lda #$00
		jsr GETNUM
		sta secondNum

		jsr PRINT

dcb "E","n","t","e","r",32,"t","h","i","r","d",
dcb 32,"n","u","m","b","e","r",32,"(","0","-","9","9",")",":",32,32,32,32,00

		lda #$00
		jsr GETNUM

		sed
		clc
		adc firstNum
		cld

		sed
		clc
		adc secondNum
		cld

		sta firstNum
		bcc result
		inc thirdNum

result:		pha
		jsr PRINT

dcb "R","e","s","u","l","t",":",32,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 thirdNum
		beq low_digits
		lda #$31
		jsr CHROUT
		jmp draw_100s

low_digits:	lda firstNum
		and #$f0
		beq ones_digit

draw_100s:	lda firstNum
		lsr
		lsr
		lsr
		lsr
		ora #$30
		jsr CHROUT

ones_digit:	lda firstNum
		and #$0f
		ora #$30
		jsr CHROUT

       lda #$00    ; set a pointer at $40 to point to $0200
        sta $40
        lda #$02
        sta $41

        lda firstNum    ; colour number
        sta $10 ; store colour number to memory location $10

        ldy #$00    ; set index to 0

loop:    sta ($40),y    ; set pixel at the address (pointer)+Y

        iny ; increment index
        bne loop    ; continue until done the page

        inc $41 ; increment the page

        inc $10 ; increment the color number
        lda $10 ; colour number

        ldx $41 ; get the current page number
        cpx #$06 ; compare with 6
        bne loop ; continue until done all pages
		

		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 firstNum

GETNUM:		txa
		pha
		tya
		pha

		ldx #$00	; count of digits received
		stx GETNUM_1
		stx GETNUM_2
		stx GETNUM_3

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	;limit the digit of number input
		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

The expected output is:


It loops after it calculates all three user inputs. As you can see, it can accept three of from 0 to 99 numbers and it works correctly.


Small addition to the code

After I check the addition works correctly, I added a simple fun thing to the code. The idea is from the code in Lab 2. However, in this program, the color code is not fixed. It will be assigned as a unit digit of the addition result. Everytime you calculate the numbers, it displays different colors.






Reflection

I'm still a beginner, so it takes me a lot of time to understand and use assembly language. I'm not very familiar with it yet, and it can be challenging. It took me more time than I expected. In addition, I was also surprised that, despite the time I had to invest, the result seemed simpler than I expected. I had some difficulties when trying to add three numbers together because it was printing a strange number, possibly in binary format. I've realized that I need to invest more time in studying the areas because I'm not familiar with.



Comments

Popular posts from this blog

Unveiling the World of Software Development Methodologies: Agile, Scrum, and DevOps Made Simple

Understanding Docker: A Comprehensive Guide

Lab1 - Code Review