I'm creating a NES emulator.

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

User avatar
LordEmilio
Posts: 18
Joined: Sat Oct 01, 2022 11:39 am

Re: I'm creating a NES emulator.

Post by LordEmilio »

Thanks both of you for your replies.

Actually, I've made a debugger inside of my software.

It's showing a lot of data, like the latest opcodes followed by the CPU registries content.

It's also featuring a PPU viewer (registries, OAM data) and a Pattern Table data viewer + Name Table data viewer + Image/Sprite palette data viewer.

The PPU registries are often accessed and modified, the Pattern Table is filled when necessary, but all of the Name Tables are empty.

I'm right now only using Mapper #0 ROMs to test out, like Flame Demo, Cart, Junkrom, Boing, etc. But still I'm thinking there are some addressing problems in CPU/PPU routines.

As for APU and MMC, I'm willing to add them later, but for now, I'm not working on it at all (except MMC, I'm studying it a bit :lol: ).

Best regards,

LordEmilio.
User avatar
LordEmilio
Posts: 18
Joined: Sat Oct 01, 2022 11:39 am

Re: I'm creating a NES emulator.

Post by LordEmilio »

Well, after fixing a few reading and writing routines on the PPU registers ($2000 - $2007), I've finally managed getting an image on screen. Though it is not perfect.

Image

It still has no sprites, because I've only implemented the tile rendering (I'm using a code from another emulator, waiting to get more knowledge before I write my own rendering engine). Plus the sprite RAM is still empty on running, despite my DMA channel code, and the $2004 reading/writing routines. I'm checking that right now.

The game should look like this, normally :

Image

Super Mario Bros. doesn't run for a long time before encountering some "unknown opcode" errors. I don't know what that means, maybe the PC register is incremented too much at some point, or some jump instructions are badly implemented. However, I have fixed a lot of bugs in the CPU, NMI interruption, and PPU registers writing/reading routines already. The tiles on my emulator's screenshot are like "blown away" by the wind, so it's barely readable. It doesn't display much more with other NES games, it only handles mapper #0 for now, and even with mapper #0, it's displaying black screens or gray screens most of the time.

I'm still working on it, but if you have some useful tips, then you can send me responses or PM. :)

C ya l8er
posit
Posts: 15
Joined: Tue Oct 11, 2022 11:40 pm

Re: I'm creating a NES emulator.

Post by posit »

tl;dr Start with passing some basic CPU tests from https://www.nesdev.org/wiki/Emulator_tests
---
I too started an NES emulator recently (about 3 months ago). In my limited experience:

Goal #1 - Get Donkey Kong working
  • Get the CPU going first. i.e. Try to pass as many cpu tests as possible. Official instructions, then unofficial though only a handful ever seem to be used in the wild. Then interrupt tests. Then timing tests.
  • On the CPU journey, APU frame and DMC IRQs will eventually need to be on point. Read readme files etc that accompany tests!
  • Then PPU NMI and vblank
  • At this point you should be able to pass most of the CPU tests
I implemented a working APU before PPU, but I'm a weirdo. Before diving into the proper PPU, the easiest thing (and where some emulators stop according to their blogs) is to be able to view the tiles from a nametable. Then you can just blit sprites on top. That should be enough for Donkey Kong and a rather exciting sense of accomplishment.
---
Then of course, you can dig further into proper PPU implementation and tests, APU and tests if you haven't done it yet, more mappers, more tests...
As that continues, more and more games will be able to run, and you'll have more and more questions.

I can also say all the information is here on the wiki or forums. Some of the very specific information is tricky to comprehend or has bits and pieces spread over multiple wiki pages, esp. regarding cycle accuracy (when does PPU data need to be latched for valid reading in relation to a CPU cycle? Just before M2 rising edge? etc) - but much of that is many steps and many already perfectly running games in the future.

The folks here, and the folks that used to be here, are simply amazing human beings. We have at our disposal tests to cover all the basics and then some, documentation, endless discussions going back 20+ years, and a community with an everlasting willingness to help.
User avatar
LordEmilio
Posts: 18
Joined: Sat Oct 01, 2022 11:39 am

Re: I'm creating a NES emulator.

Post by LordEmilio »

Thanks for the tips,

Actually, implementing APU might sound a bit odd, except if you are really skilled in development.

Donkey Kong (NES) is a good example to test an emulator, even if I'm personnaly using CART.NES, Super Mario Bros, and other ROMs to do so.

I don't know what I messed up with, but the render looks nice with some ROMs, and scrambled with the first one working under my emu.

Here is a screenshot taken from JadeNES running "Zelda Demo.NES" (this is not the real game :lol: ) :

Image

However, when it's about running SMB or cpu_dummy_reads, after ~120.000 cycles, my emulator starts finding unknown opcodes. I don't know if there are missing ones, or if the PC register is messed up because of wrong mem reads. But here is a log of the latest 8192 called opcodes by my emulator before encountering a bad opcode : https://cdn.discordapp.com/attachments/ ... pcodes.log

Sorry if there's too much carriage return, each "new line" starts with the A register. If there are any mistake or missing information, then send me a message for me to give more details.

Thanks all,
Matthias
User avatar
Memblers
Site Admin
Posts: 4044
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: I'm creating a NES emulator.

Post by Memblers »

LordEmilio wrote: Fri Oct 28, 2022 6:36 pm However, when it's about running SMB or cpu_dummy_reads, after ~120.000 cycles, my emulator starts finding unknown opcodes. I don't know if there are missing ones, or if the PC register is messed up because of wrong mem reads. But here is a log of the latest 8192 called opcodes by my emulator before encountering a bad opcode : https://cdn.discordapp.com/attachments/ ... pcodes.log
High byte of the address looks wrong after $E51C, there is $90 $02 (BCC $E520) but the next logged address is $E420.
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: I'm creating a NES emulator.

Post by Quietust »

LordEmilio wrote: Fri Oct 28, 2022 6:36 pm However, when it's about running SMB or cpu_dummy_reads, after ~120.000 cycles, my emulator starts finding unknown opcodes. I don't know if there are missing ones, or if the PC register is messed up because of wrong mem reads. But here is a log of the latest 8192 called opcodes by my emulator before encountering a bad opcode : https://cdn.discordapp.com/attachments/ ... pcodes.log
There's something odd about your logging code - it looks like you're recording the Opcode for the previous instruction rather than the one that's going to execute next:

Code: Select all

A:8 X:0 Y:0 PC:$E523 P:36 SP:$FB Opcode:$20 Ticks:185422
A:8 X:0 Y:0 PC:$E518 P:36 SP:$F9 Opcode:$20 Ticks:185428
A:8 X:0 Y:0 PC:$E51A P:36 SP:$F9 Opcode:$A5 Ticks:185431
A:8 X:0 Y:0 PC:$E51C P:36 SP:$F9 Opcode:$C9 Ticks:185433
A:8 X:0 Y:0 PC:$E420 P:36 SP:$F9 Opcode:$90 Ticks:185437
A:8 X:0 Y:0 PC:$E421 P:36 SP:$F9 Opcode:$37 Ticks:185439
Compare to what's actually executing:

Code: Select all

E523  20 18 E5  JSR $E518                       A:08 X:00 Y:00 P:24 SP:FB PPU: 29, 56 CYC:92657
E518  A5 1A     LDA $1A = 08                    A:08 X:00 Y:00 P:24 SP:F9 PPU: 29, 74 CYC:92663
E51A  C9 E8     CMP #$E8                        A:08 X:00 Y:00 P:24 SP:F9 PPU: 29, 83 CYC:92666
E51C  90 02     BCC $E520                       A:08 X:00 Y:00 P:24 SP:F9 PPU: 29, 89 CYC:92668
E520  69 08     ADC #$08                        A:08 X:00 Y:00 P:24 SP:F9 PPU: 29, 98 CYC:92671
E522  60        RTS                             A:10 X:00 Y:00 P:24 SP:F9 PPU: 29,104 CYC:92673
(as Members noted, your Branch instruction is also landing in the wrong page)
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
LordEmilio
Posts: 18
Joined: Sat Oct 01, 2022 11:39 am

Re: I'm creating a NES emulator.

Post by LordEmilio »

Thanks! It was a bug with the relative addressing mode. This is now fixed.

I have other issues with the JSR instruction. In Super Mario Bros. ROM, and other ROMs, it's calling the JSR instruction, and then the PC register lands somewhere else, leading to unknown opcode errors.

Here's a piece of the latest instructions executed by my emulator before the bad opcode bug :

Code: Select all

A:16 X:7 Y:0 PC:$816B P:36 SP:$FC Opcode:$AD Ticks:182568
A:16 X:7 Y:0 PC:$816C P:36 SP:$FB Opcode:$48 Ticks:182571
A:16 X:7 Y:0 PC:$816F P:36 SP:$FB Opcode:$8D Ticks:182575
A:0 X:7 Y:0 PC:$8172 P:38 SP:$FB Opcode:$AD Ticks:182579
A:0 X:7 Y:0 PC:$8173 P:38 SP:$FB Opcode:$4A Ticks:182581
A:0 X:7 Y:0 PC:$8175 P:38 SP:$FB Opcode:$B0 Ticks:182584
A:0 X:7 Y:0 PC:$8212 P:38 SP:$F9 Opcode:$20 Ticks:182590
A:0 X:7 Y:0 PC:$8215 P:38 SP:$F9 Opcode:$AD Ticks:182594
A:0 X:7 Y:0 PC:$8E04 P:38 SP:$F7 Opcode:$20 Ticks:182600
A:0 X:7 Y:0 PC:$8E05 P:36 SP:$F7 Opcode:$A Ticks:182602
A:0 X:7 Y:0 PC:$8E06 P:38 SP:$F7 Opcode:$A8 Ticks:182604
A:23 X:7 Y:0 PC:$8E07 P:36 SP:$F8 Opcode:$68 Ticks:182608
A:23 X:7 Y:0 PC:$8E09 P:36 SP:$F8 Opcode:$85 Ticks:182611
A:130 X:7 Y:0 PC:$8E0A P:164 SP:$F9 Opcode:$68 Ticks:182615
A:130 X:7 Y:0 PC:$8E0C P:164 SP:$F9 Opcode:$85 Ticks:182618
A:130 X:7 Y:1 PC:$8E0D P:36 SP:$F9 Opcode:$C8 Ticks:182620
A:49 X:7 Y:1 PC:$8E0F P:36 SP:$F9 Opcode:$B1 Ticks:182625
A:49 X:7 Y:1 PC:$8E11 P:36 SP:$F9 Opcode:$85 Ticks:182628
A:49 X:7 Y:2 PC:$8E12 P:36 SP:$F9 Opcode:$C8 Ticks:182630
A:130 X:7 Y:2 PC:$8E14 P:164 SP:$F9 Opcode:$B1 Ticks:182635
A:130 X:7 Y:2 PC:$8E16 P:164 SP:$F9 Opcode:$85 Ticks:182638
A:130 X:7 Y:2 PC:$8231 P:164 SP:$F9 Opcode:$6C Ticks:182640
A:0 X:7 Y:2 PC:$8234 P:38 SP:$F9 Opcode:$AD Ticks:182644
A:0 X:7 Y:2 PC:$8E04 P:38 SP:$F7 Opcode:$20 Ticks:182650
Error: Unknown opcode $14 at address $8E05
I think it might be an addressing mode issue, even if I checked everything. :D

The Donkey Kong ROM also drives to an horrible issue of PC register not wrapping around after reading $FFFF value. I don't know why, but the last read address is $F214, so why is it landing on $10000 ? Dunno.

Code: Select all

A:2 X:190 Y:43 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:249928
A:2 X:190 Y:43 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:249931
A:2 X:190 Y:43 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:249934
A:2 X:190 Y:44 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:249936
A:2 X:190 Y:44 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:249941
A:2 X:190 Y:44 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:249945
A:2 X:189 Y:44 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:249947
A:2 X:189 Y:44 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:249950
A:2 X:189 Y:44 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:249953
A:2 X:189 Y:45 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:249955
A:26 X:189 Y:45 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:249960
A:26 X:189 Y:45 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:249964
A:26 X:188 Y:45 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:249966
A:26 X:188 Y:45 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:249969
A:26 X:188 Y:45 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:249972
A:26 X:188 Y:46 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:249974
A:2 X:188 Y:46 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:249979
A:2 X:188 Y:46 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:249983
A:2 X:187 Y:46 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:249985
A:2 X:187 Y:46 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:249988
A:2 X:187 Y:46 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:249991
A:2 X:187 Y:47 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:249993
A:30 X:187 Y:47 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:249998
A:30 X:187 Y:47 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:250002
A:30 X:186 Y:47 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250004
A:30 X:186 Y:47 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250007
A:30 X:186 Y:47 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250010
A:30 X:186 Y:48 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250012
A:32 X:186 Y:48 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:250017
A:32 X:186 Y:48 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:250021
A:32 X:185 Y:48 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250023
A:32 X:185 Y:48 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250026
A:32 X:185 Y:48 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250029
A:32 X:185 Y:49 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250031
A:30 X:185 Y:49 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:250036
A:30 X:185 Y:49 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:250040
A:30 X:184 Y:49 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250042
A:30 X:184 Y:49 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250045
A:30 X:184 Y:49 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250048
A:30 X:184 Y:50 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250050
A:0 X:184 Y:50 PC:$F216 P:102 SP:$F5 Opcode:$B1 Ticks:250055
A:0 X:184 Y:50 PC:$F219 P:102 SP:$F5 Opcode:$8D Ticks:250059
A:0 X:183 Y:50 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250061
A:0 X:183 Y:50 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250064
A:0 X:183 Y:50 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250067
A:0 X:183 Y:51 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250069
A:90 X:183 Y:51 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:250074
A:90 X:183 Y:51 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:250078
A:90 X:182 Y:51 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250080
A:90 X:182 Y:51 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250083
A:90 X:182 Y:51 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250086
A:90 X:182 Y:52 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250088
A:66 X:182 Y:52 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:250093
A:66 X:182 Y:52 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:250097
A:66 X:181 Y:52 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250099
A:66 X:181 Y:52 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250102
A:66 X:181 Y:52 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250105
A:66 X:181 Y:53 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250107
A:86 X:181 Y:53 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:250112
A:86 X:181 Y:53 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:250116
A:86 X:180 Y:53 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250118
A:86 X:180 Y:53 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250121
A:86 X:180 Y:53 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250124
A:86 X:180 Y:54 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250126
A:86 X:180 Y:54 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:250131
A:86 X:180 Y:54 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:250135
A:86 X:179 Y:54 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250137
A:86 X:179 Y:54 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250140
A:86 X:179 Y:54 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250143
A:86 X:179 Y:55 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250145
A:0 X:179 Y:55 PC:$F216 P:102 SP:$F5 Opcode:$B1 Ticks:250150
A:0 X:179 Y:55 PC:$F219 P:102 SP:$F5 Opcode:$8D Ticks:250154
A:0 X:178 Y:55 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250156
A:0 X:178 Y:55 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250159
A:0 X:178 Y:55 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250162
A:0 X:178 Y:56 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250164
A:9 X:178 Y:56 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:250169
A:9 X:178 Y:56 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:250173
A:9 X:177 Y:56 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250175
A:9 X:177 Y:56 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250178
A:9 X:177 Y:56 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250181
A:9 X:177 Y:57 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250183
A:7 X:177 Y:57 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:250188
A:7 X:177 Y:57 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:250192
A:7 X:176 Y:57 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250194
A:7 X:176 Y:57 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250197
A:7 X:176 Y:57 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250200
A:7 X:176 Y:58 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250202
A:5 X:176 Y:58 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:250207
A:5 X:176 Y:58 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:250211
A:5 X:175 Y:58 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250213
A:5 X:175 Y:58 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250216
A:5 X:175 Y:58 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250219
A:5 X:175 Y:59 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250221
A:0 X:175 Y:59 PC:$F216 P:102 SP:$F5 Opcode:$B1 Ticks:250226
A:0 X:175 Y:59 PC:$F219 P:102 SP:$F5 Opcode:$8D Ticks:250230
A:0 X:174 Y:59 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250232
A:0 X:174 Y:59 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250235
A:0 X:174 Y:59 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250238
A:0 X:174 Y:60 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250240
A:202 X:174 Y:60 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250245
A:202 X:174 Y:60 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250249
A:202 X:173 Y:60 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250251
A:202 X:173 Y:60 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250254
A:202 X:173 Y:60 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250257
A:202 X:173 Y:61 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250259
A:138 X:173 Y:61 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250264
A:138 X:173 Y:61 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250268
A:138 X:172 Y:61 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250270
A:138 X:172 Y:61 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250273
A:138 X:172 Y:61 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250276
A:138 X:172 Y:62 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250278
A:138 X:172 Y:62 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250283
A:138 X:172 Y:62 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250287
A:138 X:171 Y:62 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250289
A:138 X:171 Y:62 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250292
A:138 X:171 Y:62 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250295
A:138 X:171 Y:63 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250297
A:202 X:171 Y:63 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250302
A:202 X:171 Y:63 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250306
A:202 X:170 Y:63 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250308
A:202 X:170 Y:63 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250311
A:202 X:170 Y:63 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250314
A:202 X:170 Y:64 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250316
A:202 X:170 Y:64 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250321
A:202 X:170 Y:64 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250325
A:202 X:169 Y:64 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250327
A:202 X:169 Y:64 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250330
A:202 X:169 Y:64 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250333
A:202 X:169 Y:65 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250335
A:206 X:169 Y:65 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250340
A:206 X:169 Y:65 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250344
A:206 X:168 Y:65 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250346
A:206 X:168 Y:65 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250349
A:206 X:168 Y:65 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250352
A:206 X:168 Y:66 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250354
A:202 X:168 Y:66 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250359
A:202 X:168 Y:66 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250363
A:202 X:167 Y:66 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250365
A:202 X:167 Y:66 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250368
A:202 X:167 Y:66 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250371
A:202 X:167 Y:67 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250373
A:206 X:167 Y:67 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250378
A:206 X:167 Y:67 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250382
A:206 X:166 Y:67 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250384
A:206 X:166 Y:67 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250387
A:206 X:166 Y:67 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250390
A:206 X:166 Y:68 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250392
A:202 X:166 Y:68 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250397
A:202 X:166 Y:68 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250401
A:202 X:165 Y:68 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250403
A:202 X:165 Y:68 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250406
A:202 X:165 Y:68 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250409
A:202 X:165 Y:69 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250411
A:206 X:165 Y:69 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250416
A:206 X:165 Y:69 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250420
A:206 X:164 Y:69 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250422
A:206 X:164 Y:69 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250425
A:206 X:164 Y:69 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250428
A:206 X:164 Y:70 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250430
A:142 X:164 Y:70 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250435
A:142 X:164 Y:70 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250439
A:142 X:163 Y:70 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250441
A:142 X:163 Y:70 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250444
A:142 X:163 Y:70 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250447
A:142 X:163 Y:71 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250449
A:142 X:163 Y:71 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250454
A:142 X:163 Y:71 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250458
A:142 X:162 Y:71 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250460
A:142 X:162 Y:71 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250463
A:142 X:162 Y:71 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250466
A:142 X:162 Y:72 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250468
A:206 X:162 Y:72 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250473
A:206 X:162 Y:72 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250477
A:206 X:161 Y:72 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250479
A:206 X:161 Y:72 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250482
A:206 X:161 Y:72 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250485
A:206 X:161 Y:73 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250487
A:206 X:161 Y:73 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250492
A:206 X:161 Y:73 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250496
A:206 X:160 Y:73 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250498
A:206 X:160 Y:73 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250501
A:206 X:160 Y:73 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250504
A:206 X:160 Y:74 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250506
A:210 X:160 Y:74 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250511
A:210 X:160 Y:74 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250515
A:210 X:159 Y:74 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250517
A:210 X:159 Y:74 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250520
A:210 X:159 Y:74 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250523
A:210 X:159 Y:75 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250525
A:206 X:159 Y:75 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250530
A:206 X:159 Y:75 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250534
A:206 X:158 Y:75 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250536
A:206 X:158 Y:75 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250539
A:206 X:158 Y:75 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250542
A:206 X:158 Y:76 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250544
A:210 X:158 Y:76 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250549
A:210 X:158 Y:76 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250553
A:210 X:157 Y:76 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250555
A:210 X:157 Y:76 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250558
A:210 X:157 Y:76 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250561
A:210 X:157 Y:77 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250563
A:206 X:157 Y:77 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250568
A:206 X:157 Y:77 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250572
A:206 X:156 Y:77 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250574
A:206 X:156 Y:77 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250577
A:206 X:156 Y:77 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250580
A:206 X:156 Y:78 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250582
A:0 X:156 Y:78 PC:$F216 P:102 SP:$F5 Opcode:$B1 Ticks:250587
A:0 X:156 Y:78 PC:$F219 P:102 SP:$F5 Opcode:$8D Ticks:250591
A:0 X:155 Y:78 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250593
A:0 X:155 Y:78 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250596
A:0 X:155 Y:78 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250599
A:0 X:155 Y:79 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250601
A:255 X:155 Y:79 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250606
A:255 X:155 Y:79 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250610
A:255 X:154 Y:79 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250612
A:255 X:154 Y:79 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250615
A:255 X:154 Y:79 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250618
A:255 X:154 Y:80 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250620
A:95 X:154 Y:80 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:250625
A:95 X:154 Y:80 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:250629
A:95 X:153 Y:80 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250631
A:95 X:153 Y:80 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250634
A:95 X:153 Y:80 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250637
A:95 X:153 Y:81 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250639
A:200 X:153 Y:81 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250644
A:200 X:153 Y:81 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250648
A:200 X:152 Y:81 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250650
A:200 X:152 Y:81 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250653
A:200 X:152 Y:81 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250656
A:200 X:152 Y:82 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250658
A:158 X:152 Y:82 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250663
A:158 X:152 Y:82 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250667
A:158 X:151 Y:82 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250669
A:158 X:151 Y:82 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250672
A:158 X:151 Y:82 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250675
A:158 X:151 Y:83 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250677
A:199 X:151 Y:83 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250682
A:199 X:151 Y:83 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250686
A:199 X:150 Y:83 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250688
A:199 X:150 Y:83 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250691
A:199 X:150 Y:83 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250694
A:199 X:150 Y:84 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250696
A:240 X:150 Y:84 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250701
A:240 X:150 Y:84 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250705
A:240 X:149 Y:84 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250707
A:240 X:149 Y:84 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250710
A:240 X:149 Y:84 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250713
A:240 X:149 Y:85 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250715
A:255 X:149 Y:85 PC:$F216 P:228 SP:$F5 Opcode:$B1 Ticks:250720
A:255 X:149 Y:85 PC:$F219 P:228 SP:$F5 Opcode:$8D Ticks:250724
A:255 X:148 Y:85 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250726
A:255 X:148 Y:85 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250729
A:255 X:148 Y:85 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250732
A:255 X:148 Y:86 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250734
Thanks in advance.
C u later.
User avatar
LordEmilio
Posts: 18
Joined: Sat Oct 01, 2022 11:39 am

Re: I'm creating a NES emulator.

Post by LordEmilio »

Quietust wrote: Sat Oct 29, 2022 4:43 am
There's something odd about your logging code - it looks like you're recording the Opcode for the previous instruction rather than the one that's going to execute next:
Oops sorry I have posted before reading this.

Well, in my log, I'm just taking the current instruction and the modified registers after executing it.

I think I should have put the "trace code" before the instruction gets executed into the memory. :oops:
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: I'm creating a NES emulator.

Post by Quietust »

LordEmilio wrote: Sat Oct 29, 2022 5:39 am Thanks! It was a bug with the relative addressing mode. This is now fixed.

I have other issues with the JSR instruction. In Super Mario Bros. ROM, and other ROMs, it's calling the JSR instruction, and then the PC register lands somewhere else, leading to unknown opcode errors.

Here's a piece of the latest instructions executed by my emulator before the bad opcode bug :

Code: Select all

A:16 X:7 Y:0 PC:$816B P:36 SP:$FC Opcode:$AD Ticks:182568
A:16 X:7 Y:0 PC:$816C P:36 SP:$FB Opcode:$48 Ticks:182571
A:16 X:7 Y:0 PC:$816F P:36 SP:$FB Opcode:$8D Ticks:182575
A:0 X:7 Y:0 PC:$8172 P:38 SP:$FB Opcode:$AD Ticks:182579
A:0 X:7 Y:0 PC:$8173 P:38 SP:$FB Opcode:$4A Ticks:182581
A:0 X:7 Y:0 PC:$8175 P:38 SP:$FB Opcode:$B0 Ticks:182584
A:0 X:7 Y:0 PC:$8212 P:38 SP:$F9 Opcode:$20 Ticks:182590
A:0 X:7 Y:0 PC:$8215 P:38 SP:$F9 Opcode:$AD Ticks:182594
A:0 X:7 Y:0 PC:$8E04 P:38 SP:$F7 Opcode:$20 Ticks:182600
A:0 X:7 Y:0 PC:$8E05 P:36 SP:$F7 Opcode:$A Ticks:182602
A:0 X:7 Y:0 PC:$8E06 P:38 SP:$F7 Opcode:$A8 Ticks:182604
A:23 X:7 Y:0 PC:$8E07 P:36 SP:$F8 Opcode:$68 Ticks:182608
A:23 X:7 Y:0 PC:$8E09 P:36 SP:$F8 Opcode:$85 Ticks:182611
A:130 X:7 Y:0 PC:$8E0A P:164 SP:$F9 Opcode:$68 Ticks:182615
A:130 X:7 Y:0 PC:$8E0C P:164 SP:$F9 Opcode:$85 Ticks:182618
A:130 X:7 Y:1 PC:$8E0D P:36 SP:$F9 Opcode:$C8 Ticks:182620
A:49 X:7 Y:1 PC:$8E0F P:36 SP:$F9 Opcode:$B1 Ticks:182625
A:49 X:7 Y:1 PC:$8E11 P:36 SP:$F9 Opcode:$85 Ticks:182628
A:49 X:7 Y:2 PC:$8E12 P:36 SP:$F9 Opcode:$C8 Ticks:182630
A:130 X:7 Y:2 PC:$8E14 P:164 SP:$F9 Opcode:$B1 Ticks:182635
A:130 X:7 Y:2 PC:$8E16 P:164 SP:$F9 Opcode:$85 Ticks:182638
A:130 X:7 Y:2 PC:$8231 P:164 SP:$F9 Opcode:$6C Ticks:182640
A:0 X:7 Y:2 PC:$8234 P:38 SP:$F9 Opcode:$AD Ticks:182644
A:0 X:7 Y:2 PC:$8E04 P:38 SP:$F7 Opcode:$20 Ticks:182650
Error: Unknown opcode $14 at address $8E05
I think it might be an addressing mode issue, even if I checked everything. :D
That code should correspond to this:

Code: Select all

816B  48        PHA                             A:10 X:07 Y:00 P:24 SP:FC PPU:261,189 CYC:119072
816C  8D 00 20  STA $2000 = FF                  A:10 X:07 Y:00 P:24 SP:FB PPU:261,198 CYC:119075
816F  AD 76 07  LDA $0776 = 00                  A:10 X:07 Y:00 P:24 SP:FB PPU:261,210 CYC:119079
8172  4A        LSR A                           A:00 X:07 Y:00 P:26 SP:FB PPU:261,222 CYC:119083
8173  B0 03     BCS $8178                       A:00 X:07 Y:00 P:26 SP:FB PPU:261,228 CYC:119085
8175  20 12 82  JSR $8212                       A:00 X:07 Y:00 P:26 SP:FB PPU:261,234 CYC:119087
8212  AD 70 07  LDA $0770 = 00                  A:00 X:07 Y:00 P:26 SP:F9 PPU:261,252 CYC:119093
8215  20 04 8E  JSR $8E04                       A:00 X:07 Y:00 P:26 SP:F9 PPU:261,264 CYC:119097
8E04  0A        ASL A                           A:00 X:07 Y:00 P:26 SP:F7 PPU:261,282 CYC:119103
8E05  A8        TAY                             A:00 X:07 Y:00 P:26 SP:F7 PPU:261,288 CYC:119105
8E06  68        PLA                             A:00 X:07 Y:00 P:26 SP:F7 PPU:261,294 CYC:119107
8E07  85 04     STA $04 = 00                    A:17 X:07 Y:00 P:24 SP:F8 PPU:261,306 CYC:119111
8E09  68        PLA                             A:17 X:07 Y:00 P:24 SP:F8 PPU:261,315 CYC:119114
8E0A  85 05     STA $05 = 00                    A:82 X:07 Y:00 P:A4 SP:F9 PPU:261,327 CYC:119118
8E0C  C8        INY                             A:82 X:07 Y:00 P:A4 SP:F9 PPU:261,336 CYC:119121
8E0D  B1 04     LDA ($04),Y = 8217 @ 8218 = 31  A:82 X:07 Y:01 P:24 SP:F9 PPU:  0,  1 CYC:119123
8E0F  85 06     STA $06 = 00                    A:31 X:07 Y:01 P:24 SP:F9 PPU:  0, 16 CYC:119128
8E11  C8        INY                             A:31 X:07 Y:01 P:24 SP:F9 PPU:  0, 25 CYC:119131
8E12  B1 04     LDA ($04),Y = 8217 @ 8219 = 82  A:31 X:07 Y:02 P:24 SP:F9 PPU:  0, 31 CYC:119133
8E14  85 07     STA $07 = 00                    A:82 X:07 Y:02 P:A4 SP:F9 PPU:  0, 46 CYC:119138
8E16  6C 06 00  JMP ($0006) = 8231              A:82 X:07 Y:02 P:A4 SP:F9 PPU:  0, 55 CYC:119141
8231  AD 72 07  LDA $0772 = 00                  A:82 X:07 Y:02 P:A4 SP:F9 PPU:  0, 70 CYC:119146
8234  20 04 8E  JSR $8E04                       A:00 X:07 Y:02 P:26 SP:F9 PPU:  0, 82 CYC:119150
8E04  0A        ASL A                           A:00 X:07 Y:02 P:26 SP:F7 PPU:  0,100 CYC:119156
8E05  A8        TAY                             A:00 X:07 Y:02 P:26 SP:F7 PPU:  0,106 CYC:119158
Somehow, you got the wrong instruction from the right address - are you sure you're not running a bad dump?
LordEmilio wrote: Sat Oct 29, 2022 5:39 am The Donkey Kong ROM also drives to an horrible issue of PC register not wrapping around after reading $FFFF value. I don't know why, but the last read address is $F214, so why is it landing on $10000 ? Dunno.

Code: Select all

A:2 X:190 Y:43 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:249928
A:2 X:190 Y:43 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:249931
A:2 X:190 Y:43 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:249934
A:2 X:190 Y:44 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:249936
A:2 X:190 Y:44 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:249941
A:2 X:190 Y:44 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:249945
A:2 X:189 Y:44 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:249947
A:2 X:189 Y:44 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:249950
A:2 X:189 Y:44 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:249953
A:2 X:189 Y:45 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:249955
A:26 X:189 Y:45 PC:$F216 P:100 SP:$F5 Opcode:$B1 Ticks:249960
A:26 X:189 Y:45 PC:$F219 P:100 SP:$F5 Opcode:$8D Ticks:249964
...
A:255 X:148 Y:85 PC:$F21A P:228 SP:$F5 Opcode:$CA Ticks:250726
A:255 X:148 Y:85 PC:$F211 P:228 SP:$F5 Opcode:$D0 Ticks:250729
A:255 X:148 Y:85 PC:$F213 P:228 SP:$F5 Opcode:$B0 Ticks:250732
A:255 X:148 Y:86 PC:$F214 P:100 SP:$F5 Opcode:$C8 Ticks:250734
The trace log you posted doesn't contain any apparent jumps to $10000 - are you sure you posted the right one?

At this point, it would be very helpful to adjust your logging code a bit - print all of the registers in hexadecimal, pad all of them to the correct number of digits (e.g. "$0A" instead of "$A") so that all of the columns line up, and put PC+Opcode on the left and the other registers on the right (and also show the current opcode instead of the previous one, as noted earlier).
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
LordEmilio
Posts: 18
Joined: Sat Oct 01, 2022 11:39 am

Re: I'm creating a NES emulator.

Post by LordEmilio »

Well, my friend, the log from Donkey Kong appears to be the right one. I've tested thru VB's debugger, and it appears that the latest called opcode $B1 at address $F215 is LDA, and it uses the IndirectY addressing mode to add register Y to the next PC.

But the current address is $F215, and using this addressing mode makes the next PC jump at address $100000, so in conclusion I think it should just wrap around the current memory bank ($C000 - $FFFF), and rather go at address $C000. Is it how the NES works? :? Not sure.

I'll try this out.

Thanks for your answers,
LordEmilio.
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: I'm creating a NES emulator.

Post by Quietust »

LordEmilio wrote: Sat Oct 29, 2022 9:05 am Well, my friend, the log from Donkey Kong appears to be the right one. I've tested thru VB's debugger, and it appears that the latest called opcode $B1 at address $F215 is LDA, and it uses the IndirectY addressing mode to add register Y to the next PC.
That's not how indirect addressing works.

The instruction at $F214 (not $F215) is LDA ($00),Y, and what that instruction does is as follows:
1. It reads bytes from RAM at $0000 and $0001. The very first time that code runs, those bytes are $D9 and $F8, respectively.
2. It combines those two bytes to form a 16-bit address. In this case, that address is $F8D9 (because the 6502 is Little Endian, it fetches the low byte first and the high byte second).
3. It adds the value in the Y register to that address to yield the final Effective Address for the instruction. If that addition resulted in a page boundary crossing, the CPU will perform an extra read from the "wrong" page while it fixes itself.
4. Finally, It reads from that Effective Address and stores the result in the A register.

At no point is the PC register ever involved.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
LordEmilio
Posts: 18
Joined: Sat Oct 01, 2022 11:39 am

Re: I'm creating a NES emulator.

Post by LordEmilio »

Hello everyone,

thanks again for the accurate answer.

I think I've found a huge bug in the CPU, actually, I would allow the NES program to write values to the upper banks ($8000-$FFFF), which is normally not possible. This lead to odd values written to the RAM, and thus, this explains why the address was good but the instruction was wrong, like you said in an earlier post. This is because the program ROM was overwritten while emulating.

As usual it was just under my nose, and I didn't see it. :lol:

The trip is not over, however. I'm still encountering the "PC going too far" problem, or even going under 0. But I'm still searching. Maybe there are some branching problems in some parts of my code, or some addressing issues. :roll:

Whenever I find another bug, or cannot find a solution, I might come back within the upcoming next days. :wink:

Thanks again.

LordEmilio
User avatar
LordEmilio
Posts: 18
Joined: Sat Oct 01, 2022 11:39 am

Re: I'm creating a NES emulator.

Post by LordEmilio »

My mistake... Program ROMs can actually write into the upper banks ($8000-$BFFF and $C000-$FFFF), but because of bad addressings, it starts writing at random places (including the upper banks) before it drives to "unknown opcode" errors.

Though I've added a few unofficial opcodes like SBC, DOP, TOP, and KIL to my emulator, to avoid future problems.

So, to conclude this message, I'm still searching for mistakes, fellows. :|
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: I'm creating a NES emulator.

Post by Fiskbit »

Outside of some edge cases, the program data mapped at $8000-FFFF is read-only, and thus not affected by writes. Writes to that region are instead targeting mapper registers, which can do things like swap what program data is mapped where.
User avatar
LordEmilio
Posts: 18
Joined: Sat Oct 01, 2022 11:39 am

Re: I'm creating a NES emulator.

Post by LordEmilio »

Thanks for your response.

Actually I've tried to prohibit any write to this memory address range ($8000-$FFFF), however when I ran games, I was encountering problems emulating some of them (mapper #0 is the only one emulated rn), like Pacman which didn't want to run anymore, displaying a black screen.

So I put this writing routine back, and Pacman worked again. I don't know how emulators manage with this, on their side. I've seen they don't allow Program ROM to write any value to this range, in their source code, but they still work this way. This is really crippling. :|
Post Reply