DEV Community

gus
gus

Posted on

6502 Math and Strings Part III

This is part 3 in a series on writing a program in assembly for the 6502 processor. You can find part 1 here and part 2 here.

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 I wrote code to display "Even" or "Odd" depending on the result.

Image description

Image description

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)