What's new

Announcement: Cycle-accurate N64 development underway.

OP
MarathonMan

MarathonMan

Emulator Developer
4 cores could technically still be viewed as following AMD's "MOAR CORES!" strategy since they're planning on having quad-core parts in Kabini, and not to mention starting with Richland that all non-jaguar-based APUs will be quad-core parts.

Quad cores have been around on both sides for well over half a decade...
 

Nintendo Maniac

New member
And yet Intel seems to only use them in their highest-end parts. Heck they've even made non-low voltage Sandy Bridge i7s that are only dual core (with hyper-threading of course) in the laptop space.
 
Last edited:

angrylion

New member
1) Not cycle accurate; just pixel-accurate.

Right. I have a few RDP test roms on my hard drive that my thingie cannot pass, because they need cycle accuracy. Cycle accuracy of the emulated RDP involves, among other things: correct emulation of RDP cycle counter registers; setting different RDP status bits at the correct cycle; synchronizing the RDP and various RDRAM accesses it makes with the RSP, CPU and VI; emulating the effects of absent Sync commands; emulating some interesting anomalies of the LOD unit, particularly in one-cycle mode; calculating the exact cycle when Load commands with certain parameters start DMAing junk into the TMEM and why do they do it; what the hell do RDP span registers do; correct rendering of primitives with certain, unusual properties (spans look completely different to normal primitives, and then the RDP may or may not crash); calculating the exact cycle when the RDP deadlocks, depending on a particular method to achieve that employed by the display list (there are several such methods I'm aware of). If we talk about real cycle accuracy with respect to the RDP, it is also indispensable that we emulate its internal span buffers and all the IO operations that happen with them. The RDP has several DMA engines, so imo for perfect accuracy it's also important to emulate the arbitration mechanisms that resolve conflicts among them.
 
OP
MarathonMan

MarathonMan

Emulator Developer
Right. I have a few RDP test roms on my hard drive that my thingie cannot pass, because they need cycle accuracy. Cycle accuracy of the emulated RDP involves, among other things: correct emulation of RDP cycle counter registers; setting different RDP status bits at the correct cycle; synchronizing the RDP and various RDRAM accesses it makes with the RSP, CPU and VI; emulating the effects of absent Sync commands; emulating some interesting anomalies of the LOD unit, particularly in one-cycle mode; calculating the exact cycle when Load commands with certain parameters start DMAing junk into the TMEM and why do they do it; what the hell do RDP span registers do; correct rendering of primitives with certain, unusual properties (spans look completely different to normal primitives, and then the RDP may or may not crash); calculating the exact cycle when the RDP deadlocks, depending on a particular method to achieve that employed by the display list (there are several such methods I'm aware of). If we talk about real cycle accuracy with respect to the RDP, it is also indispensable that we emulate its internal span buffers and all the IO operations that happen with them. The RDP has several DMA engines, so imo for perfect accuracy it's also important to emulate the arbitration mechanisms that resolve conflicts among them.

Care to name a couple -- for when I cross that path?
 
OP
MarathonMan

MarathonMan

Emulator Developer
New cores and framework is stable enough to begin loading instructions and data off 6105 carts!

Code:
...@...:~/Projects/cen64$ ./cen64 data/pifrom.bin data/zelda.rom 8175
[PIF]: "Initializing PIF."
[RDRAM]: "Initializing RDRAM."
[RSP]: "Initializing CPU."
[RSP]: "Initializing COP0."
[RSP]: "Initializing COP2."
[VR4300]: "Initializing CPU."
[VR4300]: "Initializing COP0."
[XBUS]: "Initializing XBUS."
[CEN64]: "Connecting devices to XBus."
[PIF]: "Initializing the cartridge."
[VR4300]: "Handling fault: RST"
[RSP]: "RSPWrite: Unimplemented function."
[XBUS]: "Write WORD to unmapped address [0x04600010]."
[XBUS]: "Write WORD to unmapped address [0x0440000c]."
[XBUS]: "Write WORD to unmapped address [0x04400024]."
[XBUS]: "Write WORD to unmapped address [0x04400010]."
[XBUS]: "Write WORD to unmapped address [0x04500000]."
[XBUS]: "Write WORD to unmapped address [0x04500004]."
[XBUS]: "Read WORD from unmapped address [0x04800018]."
[PIF]: "PIF ROM: Detected write [0x1fc0003c]"
[XBUS]: "Write WORD to unmapped address [0x04600014]."
[XBUS]: "Write WORD to unmapped address [0x04600018]."
[XBUS]: "Write WORD to unmapped address [0x0460001c]."
[XBUS]: "Write WORD to unmapped address [0x04600020]."
[XBUS]: "Write WORD to unmapped address [0x04600014]."
[XBUS]: "Write WORD to unmapped address [0x04600018]."
[XBUS]: "Write WORD to unmapped address [0x0460001c]."
[XBUS]: "Write WORD to unmapped address [0x04600020]."
[XBUS]: "Read WORD from unmapped address [0x0410000c]."
[VR4300]: "Unimplemented function: MULTU."
 

didado

New member
You are going serious fast with this project. Cant wait for the first (demo) screens or video's. :bouncy:

Having coding as a hobby is always better when making a emulator.
Keep it up! :)
 
OP
MarathonMan

MarathonMan

Emulator Developer
Another landmark...

Code:
...@...:~/Projects/cen64$ ./cen64 data/pifrom.bin data/zelda.rom 8000000
[PIF]: "Initializing PIF."
[ROM]: "Initializing Interface."
[RDRAM]: "Initializing RDRAM."
[RSP]: "Initializing CPU."
[RSP]: "Initializing COP0."
[RSP]: "Initializing COP2."
[VR4300]: "Initializing CPU."
[VR4300]: "Initializing COP0."
[BUS]: "Initializing Bus."
[BUS]: "Connecting devices."
[ROM]: "Preparing the image."
[CEN64]: "Booting the console."
[VR4300]: "Handling fault: RST"
[RSP]: "SPRegRead: Reading from register [SP_STATUS_REG]."
[RSP]: "SPRegWrite: Writing to register [SP_STATUS_REG]."
[RSP]: "SPRegRead: Reading from register [SP_DMA_BUSY_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_STATUS_REG]."
[BUS]: "Write WORD to unmapped address [0x0440000c]."
[BUS]: "Write WORD to unmapped address [0x04400024]."
[BUS]: "Write WORD to unmapped address [0x04400010]."
[BUS]: "Write WORD to unmapped address [0x04500000]."
[BUS]: "Write WORD to unmapped address [0x04500004]."
[RSP]: "SPRegRead: Reading from register [SP_STATUS_REG]."
[PIF]: "SIRegRead: Reading from register [SI_STATUS_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_BSD_DOM1_LAT_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_BSD_DOM1_PWD_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_BSD_DOM1_PGS_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_BSD_DOM1_RLS_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_BSD_DOM1_LAT_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_BSD_DOM1_PWD_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_BSD_DOM1_PGS_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_BSD_DOM1_RLS_REG]."
[BUS]: "Read WORD from unmapped address [0x0410000c]."
[PIF]: "SIRegRead: Reading from register [SI_STATUS_REG]."
[PIF]: "SIRegRead: Reading from register [SI_STATUS_REG]."
[PIF]: "SIRegRead: Reading from register [SI_STATUS_REG]."
[PIF]: "SIRegRead: Reading from register [SI_STATUS_REG]."
[VR4300]: "Unimplemented function: MTC0 [rd = 13]."
[VR4300]: "Unimplemented function: MTC0 [rd = 9]."
[VR4300]: "Unimplemented function: MTC0 [rd = 11]."
[RDRAM]: "RIRegRead: Reading from register [RI_SELECT_REG]."
[RDRAM]: "RIRegWrite: Writing to register [RI_CONFIG_REG]."
[RDRAM]: "RIRegWrite: Writing to register [RI_CURRENT_LOAD_REG]."
[RDRAM]: "RIRegWrite: Writing to register [RI_SELECT_REG]."
[RDRAM]: "RIRegWrite: Writing to register [RI_MODE_REG]."
[RDRAM]: "RIRegWrite: Writing to register [RI_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[BUS]: "Write WORD to unmapped address [0x03f80008]."
[BUS]: "Write WORD to unmapped address [0x03f80014]."
[BUS]: "Write WORD to unmapped address [0x03f80004]."
[VR4300]: "MIRegRead: Reading from register [MI_VERSION_REG]."
[BUS]: "Write WORD to unmapped address [0x03f04004]."
[RDRAM]: "RDRAMRegWrite: Writing to register [RDRAM_MODE_REG]."
[RDRAM]: "RDRAMRegWrite: Writing to register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RDRAMRegRead: Reading from register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RDRAMRegRead: Reading from register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RDRAMRegWrite: Writing to register [RDRAM_MODE_REG]."
[RDRAM]: "RDRAMRegWrite: Writing to register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RDRAMRegRead: Reading from register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RDRAMRegRead: Reading from register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RDRAMRegWrite: Writing to register [RDRAM_MODE_REG]."
[RDRAM]: "RDRAMRegWrite: Writing to register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RDRAMRegRead: Reading from register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RDRAMRegRead: Reading from register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RDRAMRegWrite: Writing to register [RDRAM_MODE_REG]."
[RDRAM]: "RDRAMRegWrite: Writing to register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RDRAMRegRead: Reading from register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RDRAMRegRead: Reading from register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RDRAMRegWrite: Writing to register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[BUS]: "Write WORD to unmapped address [0x03f8000c]."
[BUS]: "Write WORD to unmapped address [0x03f80004]."
[BUS]: "Write WORD to unmapped address [0x03f04004]."
[RDRAM]: "RDRAMRegWrite: Writing to register [RDRAM_MODE_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[RDRAM]: "RIRegWrite: Writing to register [RI_REFRESH_REG]."
[RDRAM]: "RIRegRead: Reading from register [RI_REFRESH_REG]."
[VR4300]: "Unimplemented function: MTC0 [rd = 28]."
[VR4300]: "Unimplemented function: MTC0 [rd = 29]."
[RSP]: "SPRegWrite: Writing to register [SP_STATUS_REG]."
[RSP]: "SPRegWrite: Writing to register [SP_PC_REG]."
[RSP]: "SPRegWrite: Writing to register [SP_STATUS_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_DRAM_ADDR_REG]."
[ROM]: "PIRegRead: Reading from register [PI_STATUS_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_CART_ADDR_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_WR_LEN_REG]."
[ROM]: "DMA | Request: Read from cart."
[ROM]: "DMA | DEST   : [0x00000400]."
[ROM]: "DMA | SOURCE : [0x00001000]."
[ROM]: "DMA | LENGTH : [0x00100000]."
[BUS]: "[HACK] Copying payload to DRAM."
[ROM]: "PIRegRead: Reading from register [PI_STATUS_REG]."
[RSP]: "SPRegWrite: Writing to register [SP_SEMAPHORE_REG]."
[RSP]: "SPRegWrite: Writing to register [SP_STATUS_REG]."
[VR4300]: "MIRegWrite: Writing to register [MI_INTR_MASK_REG]."
[PIF]: "SIRegWrite: Writing to register [SI_STATUS_REG]."
[BUS]: "Write WORD to unmapped address [0x0450000c]."
[VR4300]: "MIRegWrite: Writing to register [MI_INIT_MODE_REG]."
[ROM]: "PIRegWrite: Writing to register [PI_STATUS_REG]."
[VR4300]: "Passed PIF/CIC security checks!"

VR4300 core is stable enough to pass the CIC/PIF checks again. Just a little more support in the core and it'll be at the magical game entry point.

EDIT: That was easier than I expected. The core crashes into a breakpoint at 0x80000400... so I can succesfully boot commercial CIC-6105 ROMs. Cool beans.
 
Last edited:
OP
MarathonMan

MarathonMan

Emulator Developer
Dynamically determining the lockout chip and setting the seed accordingly...

Code:
[BUS]: "== Hardware Initialized =="
[BUS]: "Connecting devices."
[ROM]: "No hugepage support."
[ROM]: "Preparing the image."
[ROM]: "Loaded: [ZELDA MAJORA'S MASK ]"
[ROM]: "Detected: CIC-NUS-6105."
[CEN64]: "== Booting the Console =="

Also fixed a really annoying bug that cropped up yesterday and prevented aggressive optimizations.

And, of course, being a Linux freak... support for mmap'd ROMs with hugepages. Linux users should only see ~10MB of memory used, even with a ROM loaded:
Code:
[RSP]: "SPRegRead: Reading from register [SP_STATUS_REG]."
==6494== 
==6494== HEAP SUMMARY:
==6494==     in use at exit: 0 bytes in 0 blocks
==6494==   total heap usage: 11 allocs, 11 frees, 8,404,112 bytes allocated
==6494== 
==6494== All heap blocks were freed -- no leaks are possible
==6494== 
==6494== For counts of detected and suppressed errors, rerun with: -v
==6494== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
 
Last edited:

chiburunga

New member
Dynamically determining the lockout chip and setting the seed accordingly...

Code:
[BUS]: "== Hardware Initialized =="
[BUS]: "Connecting devices."
[ROM]: "No hugepage support."
[ROM]: "Preparing the image."
[ROM]: "Loaded: [ZELDA MAJORA'S MASK ]"
[ROM]: "Detected: CIC-NUS-6105."
[CEN64]: "== Booting the Console =="

Also fixed a really annoying bug that cropped up yesterday and prevented aggressive optimizations.

And, of course, being a Linux freak... support for mmap'd ROMs with hugepages. Linux users should only see ~10MB of memory used, even with a ROM loaded:
Code:
[RSP]: "SPRegRead: Reading from register [SP_STATUS_REG]."
==6494== 
==6494== HEAP SUMMARY:
==6494==     in use at exit: 0 bytes in 0 blocks
==6494==   total heap usage: 11 allocs, 11 frees, 8,404,112 bytes allocated
==6494== 
==6494== All heap blocks were freed -- no leaks are possible
==6494== 
==6494== For counts of detected and suppressed errors, rerun with: -v
==6494== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

You are the man!!!! I want you to be the father of my sons! And Im a guy!
 

Zuzma

New member
It sounds like there'd just be two dads unless someone else wanted some sandwich action or something. :D

Edit: Nice job with getting games booting MarathonMan! Haha, I shouldn't go off topic like this.. ugh.
 
Last edited:

mrmudlord

New member
sdz2CAY.jpg

x9STeDN.jpg
 
Last edited:

didado

New member
Nice pictures kidmudlord.. Self made emu? ;) Why you wanna always hate that much? or troll.. or is this humor you like.
I know you can code to. But i never see the reason of actions like these you made.

MarathonMan please ignore the haters. :)
 
OP
MarathonMan

MarathonMan

Emulator Developer
Don't know how many of you followed my previous implementations, but: optimized my TLB module and linked it into the core tonight.

I take a completely different approach to TLB implementation than other emulators, so it'll be interesting to see how it plays out. I know for a fact that my lookups are considerably faster than any other emulator to date (as I filter out the entries using a tree and only have to look at a fraction of them to determine whether I have a hit or not), but my replacement logic is a bit more complex and certainly not as fast. It'll be interesting to see how games like Goldeneye are impacted by these changes.
 

Top