65C816汇编内存调色板加载异常,求添加secondary colors方案
65C816汇编调色板加载:主色+次色连续实现方案
问题背景
使用65C816汇编实现内存调色板加载时,主色加载正常,但取消注释次色表后,添加次色存储代码出现数据偏移。需求是让次色紧跟主色存储(如内存地址$E19E20处为00 00 B0 00 D9 0A...格式),但当前代码存在寄存器冲突,无法正确读取下一个次色值。
颜色表定义
; ; --- Tables for setting SCB and color tables for color -------- ; ENTRY logocolor logocolor DC.W $00B0 DC.W $0AD9 DC.W $0FF0 DC.W $0FFB DC.W $0F60 DC.W $0FA7 DC.W $0E10 DC.W $0E99 DC.W $0F0A DC.W $0E7C DC.W $000D DC.W $0AAE ENTRY scanbyte scanbyte DC.B 1 DC.B 1 DC.B 1 DC.B 2 DC.B 3 DC.B 4 DC.B 5 DC.B 6
现有加载代码片段
ldx #6 ;I think this is keeping track of each line of the logo ldy #22 ;this used to be 10, but we have 6 more colors lop202 phx Save. phy Save. ;each time we loop back y is decreased by 2, x by 1 lda logocolor,y ; Load defined color value in the table, using y as index into a ldy #ColorTable+2 ; Load value of ColorTable + 2 sta [<data],y ; Store read defined color ; ;--- here we need some operation to get the next color in the table ----- ; ldy #ColorTable+4 ; then load value of ColorTable + 4 sta [<data],y ; Store read defined color from our imagary operation ldy <screenmode beq ok202 ;640 mode??? Yes, most certainly is for 640 mode. Need to add the second color here as well. ldy #ColorTable+10 sta [<data],y ldy #ColorTable+18 sta [<data],y ldy #ColorTable+26 sta [<data],y ok202 phx Table number. jsr pushColorTable _SetColorTable ply Restore. plx Restore. dey dey dex bne lop202 brl pop0bytes no error ENDP
解决方案
核心问题分析
现有代码中,读取主色后用ldy #ColorTable+2覆盖了logocolor的索引Y,导致无法直接获取下一个次色的位置。需要先保存索引Y,再恢复并调整索引读取次色,同时修正循环的索引步长。
修改后的代码实现
ldx #6 ; 处理6组主色+次色 ldy #20 ; 初始指向最后一个主色的索引(对应$000D),次色在y+2 lop202 phx ; 保存X寄存器 phy ; 保存当前logocolor的主色索引Y ; --- 存储主色 --- lda logocolor,y ; 读取主色 ldy #ColorTable+2 ; 主色存储位置 sta [<data],y ; 写入主色 ; --- 存储次色 --- ply ; 恢复主色索引Y iny ; 偏移到次色索引(主色索引+2) iny lda logocolor,y ; 读取次色 phx ; 临时保存X ldy #ColorTable+4 ; 次色存储位置(紧跟主色) sta [<data],y ; 写入次色 phy ; 保存次色索引,用于后续循环调整 ; --- 640模式下的额外存储(补充次色写入) --- ldy <screenmode beq ok202 ; 先写入主色到额外位置 ply ; 恢复次色索引 dey dey lda logocolor,y ; 重新读取主色 ldy #ColorTable+10 sta [<data],y ldy #ColorTable+18 sta [<data],y ldy #ColorTable+26 sta [<data],y ; 再写入次色到对应额外位置 iny iny lda logocolor,y ldy #ColorTable+12 sta [<data],y ldy #ColorTable+20 sta [<data],y ldy #ColorTable+28 sta [<data],y phy ; 重新保存次色索引 ok202 phx ; 传入表号给pushColorTable jsr pushColorTable _SetColorTable ply ; 恢复次色索引 plx ; 恢复X dey ; 调整索引到上一组的主色(次色索引-4) dey dey dey dex bne lop202 brl pop0bytes no error ENDP
代码重构建议
为提升效率和可读性,推荐使用零页变量存储临时索引,减少栈操作开销:
; 定义零页临时变量,用于存储logocolor的当前索引 temp_idx DC.W 0 InitPalette ldx #6 ; 6组颜色 ldy #20 ; 初始主色索引 sty temp_idx ; 保存初始索引到零页 lop202 phx ; --- 存储主色 --- ldy temp_idx lda logocolor,y ldy #ColorTable+2 sta [<data],y ; --- 存储次色 --- ldy temp_idx iny iny lda logocolor,y ldy #ColorTable+4 sta [<data],y ; --- 640模式处理 --- ldy <screenmode beq skip_640 ; 主色写入额外位置 ldy temp_idx lda logocolor,y ldy #ColorTable+10 sta [<data],y ldy #ColorTable+18 sta [<data],y ldy #ColorTable+26 sta [<data],y ; 次色写入额外位置 ldy temp_idx iny iny lda logocolor,y ldy #ColorTable+12 sta [<data],y ldy #ColorTable+20 sta [<data],y ldy #ColorTable+28 sta [<data],y skip_640 phx jsr pushColorTable _SetColorTable plx ; 更新索引:下一组主色 = 当前主色索引 -4 lda temp_idx sec sbc #4 sta temp_idx lda temp_idx+1 sbc #0 sta temp_idx+1 dex bne lop202 brl pop0bytes ENDP
重构后的代码优势:
- 用零页变量替代栈操作,减少CPU周期开销
- 逻辑更清晰,避免寄存器冲突
- 减少重复代码,便于维护
内容的提问来源于stack exchange,提问作者cjp
相关产品推荐
相关产品推荐

