Есть ли ошибка в nestest rom?
В настоящее время я делаю эмулятор для NES (как и многие другие), и пока я тестирую свою эмуляцию на nestest rom от Кевтриса (можно найти здесь: https://wiki.nesdev.com/w/index.php/Emulator_tests), там - странная ошибка, с которой я столкнулся в инструкции 877 в журнале nestest (этот: http://www.qmtpro.com/~nes/misc/nestest.log, в строке CE42) .
Инструкция представляет собой PLA, который извлекает аккумулятор из стека, имея указатель стека в $7E в начале. (Я использую 1-байтовое значение для указателя стека, поскольку он идет от 0x0100 до 0x01FF, поэтому, когда я пишу $7E, говоря о стеке, это 0x017E, а не zeropage;))
Итак, когда PLA выполняется в строке 877, указатель стека перемещается на $7F и извлекает первый байт и сохраняет его в аккумуляторе.
Проблема здесь: в журнале nestest этот байт равен 0x39, затем по инструкции 878, которая также является PLA, полученный байт по адресу $80 (указатель стека увеличен на 1) равен 0xCE, и это инвертирует младший байт и старший байт.
Значения, записанные в стеке (0xCE39), берут свое начало в инструкции JSR в строке CE37, и вот моя реализация кода операции 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 #$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
С моим кодом у меня 0xCE за 7F и 0x39 за 80 долларов. Итак, первый PLA с моим кодом хранит 0xCE в аккумуляторе, а второй PLA хранит 0x39, и это инверсия того, что показывает журнал nestest.
Я не знаю, ошибочен ли мой код JSR, до сих пор это удавалось. Я попытался инвертировать младший и старший байт программного счетчика при хранении в стеке, но, как и ожидалось, инструкции стали недействительными в первом JSR ROM.
Так что вы думаете, ребята, мне не хватает?
0 ответов
Ошибка не в nestest; ошибка в вашей реализации JSR и RTS!
Вам нужно сначала вставить старший байт, а затем младший. (Это сделано для того, чтобы младший байт мог быть извлечен первым и увеличен, пока выбирается старший байт)