You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ZX Spectrum Z80汇编:如何用变量作为PRINT AT坐标

ZX Spectrum Z80汇编:动态替换UDG输出的AT坐标值

我正在用ZX Spin模拟器学习Z80汇编,80年代写过BASIC游戏。现在写了一段创建UDG并打印到屏幕的代码,但不知道怎么用初始化好的TIT_X_POS和TIT_Y_POS变量,替换TIT_STR中DEFB里固定的_AT坐标值。


方法1:动态修改固定字符串中的坐标值

因为TIT_STR存储在ZX Spectrum的可写RAM区域(ORG 30000属于RAM范围),可以在调用PRINTSTRING前直接修改字符串中_AT控制码后的坐标字节。

修改后的SUB_PRINT_TIT代码

SUB_PRINT_TIT               
    LD HL, TIT_UDGS                                         ; 获取UDG数据地址
    LD (UDGPOINTER), HL                                     ; 设置UDG系统变量指针
    LD A, 2                                                 ; 选择输出通道2(上屏幕)
    CALL OUTCHAN                                            ; 激活输出通道

    ; 动态替换第一行的AT坐标
    LD A, (TIT_Y_POS)
    LD (TIT_STR + 1), A   ; 替换原固定Y值(原DEFB中的0)
    LD A, (TIT_X_POS)
    LD (TIT_STR + 2), A   ; 替换原固定X值(原DEFB中的0)

    ; 动态替换第二行的AT坐标(Y为第一行Y+1)
    LD A, (TIT_Y_POS)
    INC A
    LD (TIT_STR + 16), A  ; 替换原固定Y值(原DEFB中的1)
    LD A, (TIT_X_POS)
    LD (TIT_STR + 17), A  ; 替换原固定X值(原DEFB中的0)

    LD DE, TIT_STR                                          ; 字符串起始地址
    LD BC, TIT_STR_END-TIT_STR                              ; 字符串长度
    CALL PRINTSTRING                                        ; 打印字符串

RET                                                         ; 从子程序返回

说明

  • TIT_STR + 1和TIT_STR + 2对应第一行_AT控制码后的Y、X坐标位置
  • TIT_STR + 16和TIT_STR + 17对应第二行_AT控制码后的Y、X坐标位置(第一行共15个字节,第二行从TIT_STR+15开始,_AT占1字节,Y在+16,X在+17)
  • 每次调用SUB_PRINT_TIT都会更新坐标值,确保使用最新的TIT_X_POS和TIT_Y_POS

方法2:拆分输出,完全动态生成控制序列

放弃固定字符串,用ROM的RST 10H调用逐个输出控制码、坐标、属性和UDG,这种方式更灵活,适合需要频繁调整输出内容的场景。

修改后的SUB_PRINT_TIT代码

SUB_PRINT_TIT               
    LD HL, TIT_UDGS                                         ; 获取UDG数据地址
    LD (UDGPOINTER), HL                                     ; 设置UDG系统变量指针
    LD A, 2                                                 ; 选择输出通道2(上屏幕)
    CALL OUTCHAN                                            ; 激活输出通道

    ; 输出第一行:AT坐标 → 属性 → UDG
    LD A, _at
    RST 10H         ; 输出AT控制码
    LD A, (TIT_Y_POS)
    RST 10H         ; 输出Y坐标
    LD A, (TIT_X_POS)
    RST 10H         ; 输出X坐标
    ; 输出属性控制
    LD A, ink
    RST 10H
    LD A, blk
    RST 10H
    LD A, paper
    RST 10H
    LD A, wht
    RST 10H
    LD A, flash
    RST 10H
    LD A, off
    RST 10H
    LD A, bright
    RST 10H
    LD A, off
    RST 10H
    ; 输出UDG
    LD A, ua
    RST 10H
    LD A, ub
    RST 10H
    LD A, ue
    RST 10H
    LD A, uf
    RST 10H

    ; 输出第二行:AT坐标(Y+1) → 属性 → UDG
    LD A, _at
    RST 10H
    LD A, (TIT_Y_POS)
    INC A
    RST 10H
    LD A, (TIT_X_POS)
    RST 10H
    ; 输出属性控制
    LD A, ink
    RST 10H
    LD A, blk
    RST 10H
    LD A, paper
    RST 10H
    LD A, wht
    RST 10H
    LD A, flash
    RST 10H
    LD A, off
    RST 10H
    LD A, bright
    RST 10H
    LD A, off
    RST 10H
    ; 输出UDG
    LD A, uc
    RST 10H
    LD A, ud
    RST 10H
    LD A, ug
    RST 10H
    LD A, uh
    RST 10H

RET                                                         ; 从子程序返回

说明

  • RST 10H是ZX Spectrum ROM的标准调用,功能是输出累加器A中的字符/控制码到当前输出通道
  • 这种方式不需要预定义固定字符串,所有输出内容都可以动态调整,包括坐标、属性和UDG选择
  • 代码量比方法1大,但灵活性更高

内容的提问来源于stack exchange,提问作者Davy C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 20:35:04