My question is: What can cause this bug?
Because, if I don't exceed the 20 Vblank scanlines in PAL, it should not exceed them in NTSC too, right?
PAL :

NTSC :

Thanks for your answers !
Moderator: Moderators


Why use shiru lib? On my side to display a tile I use your technique, I have pointer to memory addresses, so to write a tile I use that:dougeff wrote:C code is probably going to be too slow to be useful as a PPU update / NMI system.
Have you thought about Shiru's neslib?
Code: Select all
PPU_ADDRESS = hi-hex position value;
PPU_ADDRESS = lo-hex position value;
PPU_DATA = tile hex value;Code: Select all
lda # hi-hex position value
sta $ 2006
lda # lo-hex position value
sta $ 2006
lda #tile hex value
sta $ 2007Yes I looked a little on the forum, and I saw that we could use the stack as a buffer, I think it's a good idea, it would allow me to use the cpu to do all the calculations to find right tiles of the next column during my update. Then during the Vblank I load all the buffer in vram.na_th_an wrote:Even if you don't use Shiru's neslib, you should build your updates during rendering time in a buffer and then blast it to VRAM during vblank.
This code doesn't use pointers (indirect addressing) at all. If this is the assembly your code is resulting in, then it sounds like you're using either macros or something that resulted in unrolled code. And if all of your PPU updates are written in this fashion, then this could/would explain why much of your NMI time is wasted, especially for large sequential updates of PPU RAM.MS-DOS wrote:Why use shiru lib? On my side to display a tile I use your technique, I have pointer to memory addresses, so to write a tile I use that:So when I compile it turns intoCode: Select all
PPU_ADDRESS = hi-hex position value; PPU_ADDRESS = lo-hex position value; PPU_DATA = tile hex value;Code: Select all
lda # hi-hex position value sta $ 2006 lda # lo-hex position value sta $ 2006 lda #tile hex value sta $ 2007
Code: Select all
#define PPU_ADDRESS *((unsigned char*)0x2006)
#define PPU_DATA *((unsigned char*)0x2007)Yeah, I think I use this technique! I'm going to take a look at Popslide.tepples wrote:Ideally, your main program, be it in C or assembly language or whatever, fills a buffer of addresses and data values in otherwise unused memory, such as $0100-$01BF in the stack page. Then during vblank, your program calls a subroutine written in assembly language that reads the buffer, copying addresses and data from the buffer to the PPU's ports. There's one such subroutine in neslib; I wrote my own called Popslide that uses pointer arithmetic and (ab)use of the stack pointer to allow a fast unrolled loop that C on a 6502 can't practically match.
Of course, this is just an example of how I draw ONE tile ^^dougeff wrote:Looking at the distribution of incorrect tiles on that NTSC picture, I would guess that there is a lot more to your update code than just
LDA byte
STA 2006
LDA byte
STA 2006
LDA byte
STA 2007
I would have to guess that it is inside a loop that is calculating each PPU address in real time.
loops can be MUCH more efficient in ASM [edit, autocorrect]
Addresses should be calculated beforehand (buffered), or selected from a table of precalculated addresses.
EDIT, also, in my latest blog posts, I DO use neslib, and I prefer that sort of approach. I have abandoned my earlier code, and plan to rewrite all the example code some day.