6502汇编循环

huangapple go评论49阅读模式
英文:

6502 Assembly Loops

问题

我正在使用Kick Assembler和其脚本语言来编译和构建.prg/.sym文件,解决以下问题。

使用绝对索引模式编写一个程序,将屏幕上每第5个字符填充为字母X。

我提出的实现如下。

:BasicUpstart2(main)

.const SCREEN_MEMORY = $0400
.const X_CHAR = 88 ; ASCII码中字母X的值

main:
    ldx #0 ; 初始化X寄存器为0
    lda #X_CHAR

loop:
    sta SCREEN_MEMORY, X ; 将X存储在由X索引的屏幕位置
    inx ; X加1
    cpx #$FF ; 检查X是否达到255(屏幕末尾)
    bne loop ; 如果没有,继续循环

    ldx #0

end:
    jmp end

这个代码可以正常工作,但我想了解如何编写这个程序的原始汇编代码。我提出了以下实现,但我想知道是否有更少重复的方法。

: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 ; 初始化X寄存器为0
    lda #X_CHAR

loop1:     
    sta SCREEN_MEMORY1, X ; 将X存储在由X索引的屏幕位置
    inx
    inx
    inx
    inx
    inx
    cpx #$ff
    bne loop1

  ldx #0 ; 初始化X寄存器为0

loop2:     
    sta SCREEN_MEMORY2, X ; 将X存储在由X索引的屏幕位置
    inx
    inx
    inx
    inx
    inx
    cpx #$ff
    bne loop2

    ldx #0 ; 初始化X寄存器为0

loop3:     
    sta SCREEN_MEMORY3, X ; 将X存储在由X索引的屏幕位置
    inx
    inx
    inx
    inx
    inx
    cpx #$ff
    bne loop3

    ldx #0 ; 初始化X寄存器为0

loop4:     
    sta SCREEN_MEMORY4, X ; 将X存储在由X索引的屏幕位置
    inx
    inx
    inx
    inx
    inx
    cpx #$ff
    bne loop4

end:
    jmp end

是否有一种方法可以类似于for循环一样将原始屏幕内存变量增加x*250?

英文:

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

得分: 3

一种可能的方法是像这样做:

: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

我们只需要一个单一的循环,但在每次迭代中,我们会写入4个不同的位置。

英文:

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.

huangapple
  • 本文由 发表于 2023年7月13日 23:05:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76680886.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定