6502 Math and Strings Part III
Tags: opensource, assembly, 6502, assemblylanguage
Published: 2022-03-15 00:06:20

This is part 3 in a series on writing a program in assembly for the 6502 processor. You can find part 1 [here](https://dev.to/gusmccallum/6502-math-and-strings-3b0e) and part 2 [here](https://dev.to/gusmccallum/6502-math-and-strings-part-ii-37oa).

After covering the necessary tools for building our program, today I'm getting into the coding. I've chosen to write a simple program to get input from the user and determine if a number is even or odd using the Logical Shift Right I discussed in my last post. 

First up, I set up a subroutine to draw the result of the operation on the bitmapped display. Referencing the example [here](https://wiki.cdot.senecacollege.ca/wiki/6502_Emulator_Example_Code#Place_a_Graphic_on_the_Screen) I wrote code to display "Even" or "Odd" depending on the result.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o6vz9s3ywtm4z0thegyi.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gx347jfkovfu4yeqtpko.png)

Here's the code for just the "Odd" portion. From here I need to add character input, logic to perform the LSR operation, logic to get the remainder (through the carry flag I believe?) and finally print one of the two results to the bitmapped display. 

```
define WIDTH 	  32 ; width  of sprite
define HEIGHT 	  8  ; height of sprite

done:   brk

; win sprite print subroutine 
	lda #$26 ; create a pointer at $26
 	sta $17	 ; which points to where
 	lda #$02 ; the sprite should be drawn
 	sta $18
 
 	lda #$00 ; number of rows we've drawn
 	sta $19	 ; is stored in $19
 
 	ldx #$00 ; index for data
 	ldy #$00 ; index for screen column
 
odddraw:lda oddmsg ,x
 	sta ($17),y
 	inx
 	iny
 	cpy #WIDTH
 	bne odddraw
 	inc $19	    ; increment row counter
 	lda #HEIGHT ; are we done yet?
 	cmp $19
 	beq done    ; ...exit if we are
 
 	lda $17	    ; load pointer
 	clc
 	adc #$20    ; add 32 to drop one row
 	sta $17
 	lda $18     ; carry to high byte if needed
 	adc #$00
 	sta $18

 	ldy #$00
 	beq odddraw

; sprite
oddmsg:               
dcb 00,18,18,00,00,00,18,18,00,00,00,18,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00

dcb 18,00,00,18,00,00,18,00,18,00,00,18,00,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 18,00,00,18,00,00,18,00,00,18,00,18,00,00,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 18,00,00,18,00,00,18,00,00,18,00,18,00,00,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 18,00,00,18,00,00,18,00,18,00,00,18,00,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 00,18,18,00,00,00,18,18,00,00,00,18,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
```

Unfortunately I ran into some issues with my program's execution so I'm going to have to leave it at that and move on, but the code for what I wrote is as follows:

```
; ROM Subroutines
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


;CONSTANTS

define 	WIDTH 	  	32 ; width  of sprite
define 	HEIGHT 	  	8  ; height of sprite


define 	INPUT		$10
define	NUM		$00

	ldy #$00

init:	lda msg,y
	beq getnum
	jsr CHROUT
	iny
	bne init

getnum:

	lda #NUM
	sta INPUT

    	ldy #$00
    	jsr CHRIN

    	cmp #$00
    	beq getnum

    	cmp #$30
    	bmi getnum

    	cmp #$39
    	bpl getnum

    	jsr CHROUT
	sta input
	jmp modulomsg

modulomsg:

	lda msg2,y
	beq printinput
	jsr CHROUT
	iny
	bne modulomsg

printinput:

	lda INPUT
	jsr CHROUT
	jmp result

result:		
	lda input
	clc
	jsr chrout
	lsr x
	lda x
	jsr CHROUT
	bcc evendraw
	bcs odddraw
	

msg:
dcb "E","n","t","e","r",32,"a",32,"n","u","m","b","e","r",":",32,0, 

msg2:
dcb $0d,$0d,$0d,"Y","o","u",32,"e","n","t","e","r","e","d",":",32,0


done:   brk

odddraw:
	lda #$20 ; create a pointer at $26
 	sta $17	 ; which points to where
 	lda #$02 ; the sprite should be drawn
 	sta $18
 
 	lda #$00 ; number of rows we've drawn
 	sta $19	 ; is stored in $0a
 
 	ldx #$00 ; index for data
 	ldy #$00 ; index for screen column

	lda odddata ,x
 	sta ($17),y
 	inx
 	iny
 	cpy #WIDTH
 	bne odddraw
 	inc $19	    ; increment row counter
 	lda #HEIGHT ; are we done yet?
 	cmp $19
 	beq done    ; ...exit if we are
 
 	lda $17	    ; load pointer
 	clc
 	adc #$20    ; add 32 to drop one row
 	sta $17
 	lda $18     ; carry to high byte if needed
 	adc #$00
 	sta $18

 	ldy #$00
 	beq odddraw

evendraw:
	lda #$20 ; create a pointer at $20
 	sta $17	 ; which points to where
 	lda #$02 ; the sprite should be drawn
 	sta $18
 
 	lda #$00 ; number of rows we've drawn
 	sta $19	 ; is stored in $0a
 
 	ldx #$00 ; index for data
 	ldy #$00 ; index for screen column

	lda evendata ,x
 	sta ($17),y
 	inx
 	iny
 	cpy #WIDTH
 	bne evendraw
 	inc $19	    ; increment row counter
 	lda #HEIGHT ; are we done yet?
 	cmp $19
 	beq done    ; ...exit if we are
 
 	lda $17	    ; load pointer
 	clc
 	adc #$20    ; add 32 to drop one row
 	sta $17
 	lda $18     ; carry to high byte if needed
 	adc #$00
 	sta $18

 	ldy #$00
 	beq evendraw

; odd sprite
odddata:               
dcb 00,18,18,00,00,00,18,18,00,00,00,18,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00

dcb 18,00,00,18,00,00,18,00,18,00,00,18,00,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 18,00,00,18,00,00,18,00,00,18,00,18,00,00,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 18,00,00,18,00,00,18,00,00,18,00,18,00,00,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 18,00,00,18,00,00,18,00,18,00,00,18,00,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 00,18,18,00,00,00,18,18,00,00,00,18,18,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00

; even sprite
evendata:               
dcb 05,05,05,05,00,00,05,00,00,00,00,05,00,00,05,05,05,05,00,00,05,05,00,00,05,00,00,00,00,00,00,00

dcb 05,00,00,00,00,00,05,00,00,00,00,05,00,00,05,00,00,00,00,00,05,05,00,00,05,00,00,00,00,00,00,00
dcb 05,05,05,05,00,00,00,05,00,00,05,00,00,00,05,05,05,05,00,00,05,05,05,00,05,00,00,00,00,00,00,00
dcb 05,00,00,00,00,00,00,05,00,00,05,00,00,00,05,00,00,00,00,00,05,00,05,00,05,00,00,00,00,00,00,00
dcb 05,00,00,00,00,00,00,00,05,05,00,00,00,00,05,00,00,00,00,00,05,00,00,05,05,00,00,00,00,00,00,00
dcb 05,05,05,05,00,00,00,00,05,05,00,00,00,00,05,05,05,05,00,00,05,00,00,05,05,00,00,00,00,00,00,00
dcb 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
dcb 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
```

For some reason it stops running after the character input is received and the subroutines for getting the result of the LSR and printing the appropriate message aren't triggered. And that concludes this series on math and strings in assembly on the 6502, hopefully it's been informative.