Nestest ROM 是否有错误?

Ami*_*lem 3 c assembly 6502 nes

我目前正在为 NES 制作一个模拟器(像许多其他模拟器一样),并在针对 Kevtris 的 Nestest ROM 测试我的模拟时(在这里找到: https: //wiki.nesdev.com/w/index.php/Emulator_tests),有这是我在nestest日志的指令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 ; 
}
Run Code Online (Sandbox Code Playgroud)

以下是来自 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 #$7E                        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
Run Code Online (Sandbox Code Playgroud)

通过我的代码,我的 0xCE 价格为 $7F,0x39 价格为 $80。因此,我的代码的第一个 PLA 在累加器中存储 0xCE,第二个 PLA 存储 0x39,这是嵌套日志显示的内容的反转。

不知道是不是我的JSR代码有错,到现在为止都成功了。我尝试在存储在堆栈上时反转程序计数器的低字节和高字节,但是,正如预期的那样,指令在 ROM 的第一个 JSR 处变得无效。

那么,你们认为我缺少什么?

Wil*_*son 5

错误不在于巢穴,而在于巢穴。错误在于您的 JSR 和 RTS 实现!

您需要先推送高字节,然后推送低字节。(这样可以先检索低字节,并在获取高字节的同时递增)