Unfortunately I can't guide you through the process of creating a base ROM mixing C and Assembly, but there are probably some guides and sample code for that out there. I can answer questions that are specifically about plotting pixels, though.
"Pointer" is a variable in zero page that contains an address that you can access indirectly. It's the common 6502 way to access large blocks of data. The example code I wrote calculates the address of the tile that needs to be changed and puts it into this variable.
NES lookalike graphics
Moderator: Moderators
Re: NES lookalike graphics
Pointers in 6502 are also always 2 byte in size so that they can hold a full 16-bit address.
Re: NES lookalike graphics
The variables used in this function are:
PixelColor: (1 byte) temporarily holds the color bits until they're needed;
PixelPlane0: (1 byte) holds the lower bit of the color in the correct position before it's written to the tile;
PixelPlane1: (1 byte) holds the upper bit of the color in the correct position before it's written to the tile;
Pointer: (2 bytes) holds the address of the buffered tile in RAM that will be modified.
In addition to these variables, a copy of all the patterns needs to be stored in RAM, I called this "PatternBuffer". If you're using 256 dynamic tiles, this buffer will be 4096 bytes, too large to fit in the NES' internal RAM, so you'll need extra RAM on the cartridge for this to work.
PixelColor: (1 byte) temporarily holds the color bits until they're needed;
PixelPlane0: (1 byte) holds the lower bit of the color in the correct position before it's written to the tile;
PixelPlane1: (1 byte) holds the upper bit of the color in the correct position before it's written to the tile;
Pointer: (2 bytes) holds the address of the buffered tile in RAM that will be modified.
In addition to these variables, a copy of all the patterns needs to be stored in RAM, I called this "PatternBuffer". If you're using 256 dynamic tiles, this buffer will be 4096 bytes, too large to fit in the NES' internal RAM, so you'll need extra RAM on the cartridge for this to work.
Re: NES lookalike graphics
my eye is already twitching... please tell me, if the PPU 6538 does not have its own firmware that generates a video signal, then where is the video signal generation algorithm? In a cartridge? I didn't find him there.
Re: NES lookalike graphics
The PPU doesn't have a firmware, all the logic is implemented directly in hardware. The rendering logic is explained in detail in the wiki:
https://www.nesdev.org/wiki/PPU_rendering
https://www.nesdev.org/wiki/PPU_sprite_evaluation
In a nutshell, the PPU fetches data from all the different regions of video memory (name tables, attribute tables, pattern tables, palettes, OAM) to generate an image pixel by pixel, every frame. Games create the illusion of movement by manipulating the video memory a little every frame (there's no time for big changes), as well as other rendering parameters (the scroll, memory mapping options, etc.).
https://www.nesdev.org/wiki/PPU_rendering
https://www.nesdev.org/wiki/PPU_sprite_evaluation
In a nutshell, the PPU fetches data from all the different regions of video memory (name tables, attribute tables, pattern tables, palettes, OAM) to generate an image pixel by pixel, every frame. Games create the illusion of movement by manipulating the video memory a little every frame (there's no time for big changes), as well as other rendering parameters (the scroll, memory mapping options, etc.).
Re: NES lookalike graphics
It turns out that the logic is sewn into the PPU, which builds a video signal without a program. The output is carried out by characters. Each character contains a letter or a sprite. The processor writes data to the video memory during the beam return, but this time is very short. The PPU algorithm outputs pixel-by-pixel bits from the video memory. This data may be on the cartridge. And how to directly transfer a symbol or sprite to the PPU processor from the cartridge memory?
- Individualised
- Posts: 310
- Joined: Mon Sep 05, 2022 6:46 am
Re: NES lookalike graphics
I'm curious. Are you coming to NES development from originally developing for a platform like the Sinclair ZX series or a 2nd generation console where you're expected to do a lot of the work in software, with little hardware "acceleration"? It seems that stuff such as a tilemap and a dedicated PPU are new concepts for you in terms of retro systems.
Re: NES lookalike graphics
You can't access the PPU address space directly. You use MMIO registers $2006 and $2007 to send data indirectly.
PPU address is automatically incremented by either 1 or 32 (depending on what you set it to in register $2000) each time you write to $2007, so you can write a series of adjacent bytes pretty quickly to PPU space.
Only OAM (the sprite attribute table) can be accessed directly via DMA, but OAM is in its own address space and isn't useful for anything but sprites.
Code: Select all
;Example:
lda ppu_addr_hi
sta $2006
lda ppu_addr_lo
sta $2006 ;set destination PPU address
lda data
sta $2007 ;write data to designated PPU address
Only OAM (the sprite attribute table) can be accessed directly via DMA, but OAM is in its own address space and isn't useful for anything but sprites.