6502 仿真增强型基本无限循环 $C000 至 $E0ED
6502 Emulation Enhanced Basic Infinite Loop $C000 to $E0ED
我的 6502 模拟器终于通过了 AllSuiteA.asm 中的所有测试,但我的模拟器无法模拟增强型基本版,我以 $C000 的价格加载了它。 PC 慢慢攀升至 $C03E,然后 JSR 攀升至 $C892。之后它稳步上升直到 $C908,然后 JSR 再次上升到 $E0ED,然后 JMP 间接上升到 $0。
为什么 Enhanced Basic 会无限循环,尽管 AllSuiteA 说我的模拟器没问题?
相关函数如下:
操作码:
JSR:
case "JSR":
var t = pc + 1;
memory[0x0100 + sp] = (t & 0xFF00) >> 8;
sp--;
memory[0x0100 + sp] = t & 0x00FF;
sp--;
pc = address - opcode[2];
break;
JMP:
case "JMP":
pc = address - opcode[2];
break;
寻址模式:
IND:
case "IND":
var b1 = memory[pc + 1];
var b2 = memory[pc + 2];
var mem = (b2 << 8) | b1;
var bb1 = memory[mem];
var bb2 = memory[mem + 1];
address = (bb2 << 8) | bb1;
break;
ABS:
case "ABS":
var b1 = memory[pc + 1];
var b2 = memory[pc + 2];
address = (b2 << 8) | b1;
break;
注:opcode[2]是正在执行的opcode的字节数
And here is a JSFiddle of the running program. 包含在这个 fiddle 中的是 ehbasic.bin 的十六进制表示。
简短版本:当您配置了 assemble 时,您的 CPU 需要模拟重置,而不仅仅是在 C000
处跳入。如果您只想在一行中解决问题,请跳转到 FF80
。
从源代码开始工作:
C892
是LAB_CRLF
,应该是"print CR/LF".
例程做的第一件事是用 0D
加载 A,然后 JSR LAB_PRNA
输出它。这会将您带到 C8ED
.
那里的代码将要打印的字符与 ' ' 进行比较,并在发现它正在打印控制字符时分支到 LAB_18F9
/ C90A
。
在C90A
处是到E0ED
的跳远,也就是V_OUTP
。这只是 JSR
到 VEC_OUT
的间接 0207
。您的代码似乎只在 0207
和 0208
处找到 00
s,因此向量不正确。
您似乎在使用 min_mon.asm
。这将相关的 input/output 向量设置为 FF80
处的重置例程的一部分(从 FFFC
处的 6502 重置向量到达)。但是,您的模拟器不会模拟重置,它只是以 PC = C000
.
开头
因此向量永远不会被初始化,并且跳跃虽然被正确模拟,但没有到达它应该去的地方。
我的 6502 模拟器终于通过了 AllSuiteA.asm 中的所有测试,但我的模拟器无法模拟增强型基本版,我以 $C000 的价格加载了它。 PC 慢慢攀升至 $C03E,然后 JSR 攀升至 $C892。之后它稳步上升直到 $C908,然后 JSR 再次上升到 $E0ED,然后 JMP 间接上升到 $0。
为什么 Enhanced Basic 会无限循环,尽管 AllSuiteA 说我的模拟器没问题?
相关函数如下:
操作码:
JSR:
case "JSR":
var t = pc + 1;
memory[0x0100 + sp] = (t & 0xFF00) >> 8;
sp--;
memory[0x0100 + sp] = t & 0x00FF;
sp--;
pc = address - opcode[2];
break;
JMP:
case "JMP":
pc = address - opcode[2];
break;
寻址模式:
IND:
case "IND":
var b1 = memory[pc + 1];
var b2 = memory[pc + 2];
var mem = (b2 << 8) | b1;
var bb1 = memory[mem];
var bb2 = memory[mem + 1];
address = (bb2 << 8) | bb1;
break;
ABS:
case "ABS":
var b1 = memory[pc + 1];
var b2 = memory[pc + 2];
address = (b2 << 8) | b1;
break;
注:opcode[2]是正在执行的opcode的字节数
And here is a JSFiddle of the running program. 包含在这个 fiddle 中的是 ehbasic.bin 的十六进制表示。
简短版本:当您配置了 assemble 时,您的 CPU 需要模拟重置,而不仅仅是在 C000
处跳入。如果您只想在一行中解决问题,请跳转到 FF80
。
从源代码开始工作:
C892
是LAB_CRLF
,应该是"print CR/LF".
例程做的第一件事是用 0D
加载 A,然后 JSR LAB_PRNA
输出它。这会将您带到 C8ED
.
那里的代码将要打印的字符与 ' ' 进行比较,并在发现它正在打印控制字符时分支到 LAB_18F9
/ C90A
。
在C90A
处是到E0ED
的跳远,也就是V_OUTP
。这只是 JSR
到 VEC_OUT
的间接 0207
。您的代码似乎只在 0207
和 0208
处找到 00
s,因此向量不正确。
您似乎在使用 min_mon.asm
。这将相关的 input/output 向量设置为 FF80
处的重置例程的一部分(从 FFFC
处的 6502 重置向量到达)。但是,您的模拟器不会模拟重置,它只是以 PC = C000
.
因此向量永远不会被初始化,并且跳跃虽然被正确模拟,但没有到达它应该去的地方。