Home Artists Posts Import Register

Downloads

Content

Hi Everyone!

As the last post was about one fix alone, this post will cover all the others changes of more than 2 weeks. The list is long, so let's start!


RDP: fix load block overflow when loading max line length

The result is visible in the screenshot of this post: Kirby is no longer freezing when going ingame. 

The reason for this crash was that the loading pipeline hang up. The pixel counter is checked to be greater than the required length, but as the game uses the maximum line length, the counter increased further and wrapped around to zero before ever being larger, resulting in endless loading.


FPU: fix add/sub handling of infinity

Floating point numbers are allowed to be infinity, or to be more specific, negative and positive infinity. Until this point, the floating point unit in the core could not add or subtract two numbers if both were infinity, instead it would raise a exception, telling the game that this operation is not supported.

However, some combinations are indeed possible. For example: you can add positive infinity to positive infinity and it will still be positive infinity. But adding positive infinity to negative infinity must trigger the exception as the result is not defined. After this was fixed, "007: TWINE" was no longer freezing ingame.


RDP: add dual texturing

The left image uses dual textures. You can see that hyrule field has a low res base texture and a repeating high res detail grass texture which is missing in the image on the right. This is just one possibility of dual texturing.

In general: when using the RDP in 2 pass rendering mode, two different textures can be used for each pixel. Those can be combined in plenty of possible ways. Just some more examples:

- as alpha texture

- as fog texture

- as light map


Implement flash save handling

Majoras Mask is only one of several games that use flash memory on the cartridge to save the game. The handling was more complicated than SRAM, as the flash memory will handle different commands for erasing a memory page and set it into read or write mode.

With this feature, the saving of all cartridge based memories was fully implemented. Only save type missing was....


Implement Controller Pak handling

Controller Paks can now be selected, with one for each of the 4 controllers in the OSD. Each game will keep it's own controller paks this way, so no page juggling or file select required.

With this added, finally all save methods are implement.


Implement Rumble Pak

Next to the Controller Pak in the OSD is also the option for Rumble Pak now. Make sure your controller is supported in case you want to try it.


RDP: interpret 4/8bit RGBA as CI

Fix loading of TLUTs from unaligned RDRAM address

Some fixes to the RDP led to several games rendering correct now.

The first fix is for games like Glover or Extreme-G that use a texture mode that is usually "undefined". It means that the mode usually doesn't make any sense to use, but as the hardware will do something in any case, it can and will be used by some games as we see. After finding the solution on what to do in these cases, it was quite obvious as the RDP just falls back to one of the defined modes.

The second fix was implementation specific for the RDP in the core, which is fetching from DDR3 with 64 bit per pixel. A texture fetch is also always in chunks of 64 bits, so that would be a good match, right?

Unfortunatly not, as such a copy operation doesn't have to start at the beginning of these 64 bit, it could also start at bit 16 and therefore wrap around two reads. Without special handling for these cases, the textures and colors would be wrong as seen in Harvest Moon and some occasions in Ocarina of Time.


RDP: fix palette mode for 16/32bit textures

Another one of the "undefined" texture modes: Palette mode can work with either 16 or 256 color palettes, therefore needs 4 Bit or 8 Bit textures for the color lookup. Still, that doesn't prevent games from just using 16 or 32 bit textures and wasting those additional bits for the color lookup. Mario Kart was using it in only one instance.


RDP: stop zero or negative length DMA request

The RDP is using a DMA to fetch draw requests. Whenever the read address matches the end address of the DMA after data has been copied, it would stop the drawing and is finished.

Ocarina of Time, only on the first screen with the rotating N64 logo, would set the start address already to the end address and therefore the DMA should not run at all. As the core was waiting for data to be read, so the end-check was performed, the DMA was busy forever and the game hang.


RDP: added dithering

You can see the color banding of the grass on the right side, which is removed on the left side with dithering.

The N64 renders all graphics at 8 bits per color, so 24 Bits in total. It also stores 3 Bits of coverage information for each pixel to do Anti Aliasing. Therefore needs 27 Bits. There is a normal 32 Bit framebuffer mode to save that to a framebuffer and it can be output. So where is the issue?

32 Bit per pixel not only costs a lot of memory, it also costs a lot of memory bandwidth, which was the biggest performance issue of the console due to the memory being shared with all the other components.

Because of that, most games store only 5 bits per color, so only half the memory and bandwidth is required. As 5 bits per color will introduce banding, dithering is used before cutting off the lower 3 bits to keep some of the illusion of higher color depth. The downside of that is a dithering pattern visible on the screen.


And with that we both close this review and also look ahead to the next one: I'm currently working on the VI or Video Interface. This is the unit in the RCP chip that outputs the framebuffer contents to the screen.

While doing that, it has several processing steps to filter the image:

- Dedither: to remove the dithering pattern we just introduced

- Anti Aliasing

- Divot: to remove artifacts introduced by Anti Aliasing

- Bilinear Scaling

- Gamma adjustment

So the next post will be when the VI is implemented and I can cover these techniques in detail and show comparisons of what each of them does.


A new core is attached that contains all the fixes and new features.

Have fun!

Files

Comments

Anonymous

Thanks for the great work, Robert. If anyone can help with this, it would be greatly appreciated. I don't know why I cannot run Super Mario 64 on any version of the rom I could obtain (z64, n64, v64, shindou edition), I tried on my 2 mister setups (one with analog board connected to a pvm on 15khz rgb and another with dual memory modules connected through hdmi to a vga converter hooked to an svga crt monitor) and I just get a pixelated smudge on the top third of the screen and the rest is black screen after the Super Mario 64 logo. I can run other games like mario kart 64, the zeldas, super smash bros, etc. Anyone have any ideas/suggestions?

FPGAzumSpass

Hi Adrian, i recommend using the NTSC version together with the patch(first) and the online patcher linked here: https://vampier.net/N64/

David Filskov

Thanks again, Robert :) There's a weird flickering bug when you turn on Anti-alias in Super Mario (intro). You can see it here: https://www.youtube.com/watch?v=a7p0GmRQtZc