6502 Assembly Loops

102 Views Asked by At

I'm working on 6502 assembly using Kick Assembler and its scripting language to compile and build the .prg/.sym files and working on the following problem.

Write a program using absolute indexed mode that will fill every 5th character on the screen with letter X.

The implementation I came up with looks like this.

:BasicUpstart2(main)

.const SCREEN_MEMORY1 = $0400

main:
    ldx #0                        // Initialize X register to 0
    lda #X_CHAR    

.for(var j = 0; j < 4; j++) {

loop:
    sta SCREEN_MEMORY + j*250, X  // Store X at the screen location indexed by X
.for(var i = 0; i < 5; i++ ) {
    inx                           // Increment X by 1
}
    cpx #$FF                      // Check if X has reached 255 (end of screen)
    bne loop                      // If not, continue looping

    ldx #0   
}

end:
    jmp end

This works fine but I would like to understand how to write the raw assembly code for this. I came up with the following implementation but I'm wondering if there less repetitive way to do this.

:BasicUpstart2(main)

.const SCREEN_MEMORY1 = $0400
.const SCREEN_MEMORY2 = $04FA
.const SCREEN_MEMORY3 = $05F4
.const SCREEN_MEMORY4 = $06EE
.const X_CHAR = 24

main:
    ldx #0                // Initialize X register to 0
    lda #X_CHAR

loop1:     
    sta SCREEN_MEMORY1, X // Store X at the screen location indexed by X
    inx
    inx
    inx
    inx
    inx
    cpx #$ff
    bne loop1

  ldx #0                // Initialize X register to 0

loop2:     
    sta SCREEN_MEMORY2, X // Store X at the screen location indexed by X
    inx
    inx
    inx
    inx
    inx
    cpx #$ff
    bne loop2

    ldx #0                // Initialize X register to 0

loop3:     
    sta SCREEN_MEMORY3, X // Store X at the screen location indexed by X
    inx
    inx
    inx
    inx
    inx
    cpx #$ff
    bne loop3

    ldx #0                // Initialize X register to 0

loop4:     
    sta SCREEN_MEMORY4, X // Store X at the screen location indexed by X
    inx
    inx
    inx
    inx
    inx
    cpx #$ff
    bne loop4

    end:
    jmp end

Is there a way to increment the original screen memory variable by x*250 in a similar way to the for loop?

1

There are 1 best solutions below

4
On BEST ANSWER

One possibility is to do something like this:

:BasicUpstart2(main)

.const screen_base   = $0400
.const fill_char     = 24

* = $c000 "main"
main:
  jsr fill_every_5
  rts

fill_every_5:
  lda #fill_char
  ldx #$fa
!:
  dex
  dex
  dex
  dex
  dex
  sta screen_base,x
  sta screen_base+(1*$fa),x
  sta screen_base+(2*$fa),x
  sta screen_base+(3*$fa),x
  bne !-

  rts

We only need a single loop, but in each iteration we write into 4 different locations.