nestest rom中有错误吗?
Is there a bug in the nestest rom?
我目前正在为 NES(像许多其他人一样)制作一个模拟器,并在针对 Kevtris 的 nestest rom 测试我的模拟器时(在此处找到:https://wiki.nesdev.com/w/index.php/Emulator_tests),
我遇到了一个奇怪的错误,在嵌套日志的指令 877 中(这个:http://www.qmtpro.com/~nes/misc/nestest.log,在 CE42 行)。
该指令是一个 PLA,它从堆栈中取出累加器,同时堆栈指针在 $7E 开始。 (我为堆栈指针使用了一个 1 字节的值,因为它从 0x0100 到 0x01FF,所以当我写 $7E 谈论堆栈时,它是 0x017E,而不是 zeropage
;) )
因此,当 PLA 在第 877 行执行时,堆栈指针移动到 $7F 并检索第一个字节并存储到累加器中。
问题在这里:在最嵌套的日志中,这个字节是 0x39,然后,在也是 PLA 的指令 878 上,在 $80(堆栈指针递增 + 1)处检索到的字节是 0xCE,这有反转低字节和高字节。
写入堆栈 (0xCE39) 的值源自 CE37 行的 JSR 指令,这是我对 JSR 操作码的实现:
uint8_t JSR(){
get() ; // fetch the data of the opcode , like an absolute address operand or a value
uint16_t newPC = PC - 1 ; // the program counter is decremented by 1
uint8_t low = newPC & 0x00FF ;
uint8_t high = (newPC & 0xFF00) >> 8;
write_to_stack(SP-- , low) ; //we store the PC , highest address in stack takes the low bytes
write_to_stack(SP-- , high) ; //lower address on the stack takes the high bytes
PC = new_address ; // the address we read that points to the subroutine.
return 0 ;
}
这是来自 nestest 的日志:
CE37 20 3D CE JSR $CE3D A:69 X:80 Y:01 P:A5 SP:80 PPU:233, 17 CYC:2017
CE3D BA TSX A:69 X:80 Y:01 P:A5 SP:7E PPU:251, 17 CYC:2023
CE3E E0 7E CPX #E A:69 X:7E Y:01 P:25 SP:7E PPU:257, 17 CYC:2025
CE40 D0 19 BNE $CE5B A:69 X:7E Y:01 P:27 SP:7E PPU:263, 17 CYC:2027
CE42 68 PLA A:69 X:7E Y:01 P:27 SP:7E PPU:269, 17 CYC:2029
CE43 68 PLA A:39 X:7E Y:01 P:25 SP:7F PPU:281, 17 CYC:2033
CE44 BA TSX A:CE X:7E Y:01 P:A5 SP:80 PPU:293, 17 CYC:2037
使用我的代码,我的 0xCE 价格为 7F 美元,0x39 价格为 80 美元。
因此,带有我的代码的第一个 PLA 将 0xCE 存储在 accumulator 中,第二个 PLA 存储 0x39,这与 nestest 日志显示的内容相反。
不知道是不是我的JSR代码有误,一直成功到现在。
当存储在堆栈上时,我尝试反转程序计数器的低字节和高字节,但是,正如预期的那样,指令在 rom 的第一个 JSR 处变得无效。
那么,你们认为我缺少什么?
错误不在嵌套;错误在于您对 JSR 和 RTS 的实现!
需要先压高位,再压低位。 (这样可以先获取低字节,然后在获取高字节的同时递增)
我目前正在为 NES(像许多其他人一样)制作一个模拟器,并在针对 Kevtris 的 nestest rom 测试我的模拟器时(在此处找到:https://wiki.nesdev.com/w/index.php/Emulator_tests), 我遇到了一个奇怪的错误,在嵌套日志的指令 877 中(这个:http://www.qmtpro.com/~nes/misc/nestest.log,在 CE42 行)。
该指令是一个 PLA,它从堆栈中取出累加器,同时堆栈指针在 $7E 开始。 (我为堆栈指针使用了一个 1 字节的值,因为它从 0x0100 到 0x01FF,所以当我写 $7E 谈论堆栈时,它是 0x017E,而不是 zeropage ;) )
因此,当 PLA 在第 877 行执行时,堆栈指针移动到 $7F 并检索第一个字节并存储到累加器中。
问题在这里:在最嵌套的日志中,这个字节是 0x39,然后,在也是 PLA 的指令 878 上,在 $80(堆栈指针递增 + 1)处检索到的字节是 0xCE,这有反转低字节和高字节。
写入堆栈 (0xCE39) 的值源自 CE37 行的 JSR 指令,这是我对 JSR 操作码的实现:
uint8_t JSR(){
get() ; // fetch the data of the opcode , like an absolute address operand or a value
uint16_t newPC = PC - 1 ; // the program counter is decremented by 1
uint8_t low = newPC & 0x00FF ;
uint8_t high = (newPC & 0xFF00) >> 8;
write_to_stack(SP-- , low) ; //we store the PC , highest address in stack takes the low bytes
write_to_stack(SP-- , high) ; //lower address on the stack takes the high bytes
PC = new_address ; // the address we read that points to the subroutine.
return 0 ;
}
这是来自 nestest 的日志:
CE37 20 3D CE JSR $CE3D A:69 X:80 Y:01 P:A5 SP:80 PPU:233, 17 CYC:2017
CE3D BA TSX A:69 X:80 Y:01 P:A5 SP:7E PPU:251, 17 CYC:2023
CE3E E0 7E CPX #E A:69 X:7E Y:01 P:25 SP:7E PPU:257, 17 CYC:2025
CE40 D0 19 BNE $CE5B A:69 X:7E Y:01 P:27 SP:7E PPU:263, 17 CYC:2027
CE42 68 PLA A:69 X:7E Y:01 P:27 SP:7E PPU:269, 17 CYC:2029
CE43 68 PLA A:39 X:7E Y:01 P:25 SP:7F PPU:281, 17 CYC:2033
CE44 BA TSX A:CE X:7E Y:01 P:A5 SP:80 PPU:293, 17 CYC:2037
使用我的代码,我的 0xCE 价格为 7F 美元,0x39 价格为 80 美元。 因此,带有我的代码的第一个 PLA 将 0xCE 存储在 accumulator 中,第二个 PLA 存储 0x39,这与 nestest 日志显示的内容相反。
不知道是不是我的JSR代码有误,一直成功到现在。 当存储在堆栈上时,我尝试反转程序计数器的低字节和高字节,但是,正如预期的那样,指令在 rom 的第一个 JSR 处变得无效。
那么,你们认为我缺少什么?
错误不在嵌套;错误在于您对 JSR 和 RTS 的实现!
需要先压高位,再压低位。 (这样可以先获取低字节,然后在获取高字节的同时递增)