关于绕过C64的PETSCII转屏幕代码映射的技术问询
C64 PETSCII/屏幕代码转换与ROM补丁方案
关于PETSCII到屏幕代码转换的理解确认
- 你的判断完全正确:C64的KERNAL确实存在PETSCII到屏幕代码的转换逻辑。
PRINT CHR$(65)能输出正确的'A',是因为CHR$()传入的PETSCII码会经过KERNAL的CHOUT(地址$F1CA)处理,而CHOUT确实会跳转到$E716的屏幕输出例程——这个例程负责把PETSCII码映射为对应的屏幕代码(比如把65转为1)后写入显存($0400起始的1024地址区域)。- 直接
POKE 1024,65会输出移位后的A,是因为显存存储的是屏幕代码而非PETSCII/ASCII,65对应的是C64默认字符集中的移位A图形,和PETSCII的'A'不属于同一映射规则。
补丁方案的可行性与实现思路
完全可行,具体操作思路如下:
1. 复制KERNAL ROM到RAM并修改转换逻辑
C64的KERNAL ROM位于$E000-$FFFF,要修改它需先切换内存映射让该区域指向RAM:
- 执行
POKE 1,56:切换内存映射,使$E000-$FFFF指向RAM(原KERNAL ROM会被屏蔽) - 用循环复制ROM内容到对应RAM地址:
FOR I=57344 TO 65535: POKE I,PEEK(I): NEXT I - 找到
$E716附近的PETSCII转屏幕代码映射逻辑,将其替换为直接传递原码——也就是让输入的PETSCII码直接作为屏幕代码写入显存。比如原逻辑里的查表或加减运算代码,改成直接把A寄存器的值(输入的PETSCII码)作为屏幕代码使用。 - 修改完成后执行
POKE 1,48切换回默认内存映射,此时KERNAL会调用你修改后的RAM版本。
2. 复制字符ROM到RAM并调整字符映射
C64的字符ROM位于$D000-$DFFF,同样需要先切换内存映射让该区域指向RAM:
- 执行
POKE 1,32:切换内存映射,使$D000-$DFFF指向RAM - 复制字符ROM内容到RAM:
FOR I=53248 TO 57343: POKE I,PEEK(I): NEXT I - 调整字符点阵:默认字符ROM中屏幕代码1对应'A'的点阵,你需要把屏幕代码65的点阵替换为'A'的点阵,同时将其他字符的点阵对应到ASCII码的位置——比如把原屏幕代码0-25的字母点阵,复制到屏幕代码65-90的位置,匹配ASCII大写字母的映射规则。
- 修改完成后切换回合适的内存映射,让系统使用RAM中的自定义字符集。
完成以上操作后,执行PRINT "A"再用PEEK(1024)就能得到65,且屏幕显示的字符会完全匹配ASCII编码规则。
内容的提问来源于stack exchange,提问作者KungPhoo
相关产品推荐
相关产品推荐

