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?
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.