Random Stupid Questions I Think Of
Moderator: Moderators
Random Stupid Questions I Think Of
I want to use this thread to basically ask any stupid short question I think of that doesn't deserve its own thread, and that I can't find a simple answer to elsewhere. I have a couple of questions right off the bat, and I'll ask more in different posts if/when I think of any.
1. Does $2002 have to be reread everytime something has to be written to a new area of the PPU?
2. What is the difference between bit shifts and bit rotations?
3. Does trying to draw things outside of vblank damage the PPU?
4. Are there any situations when programming the NES where (indirect,x) addressing would come in handy? Also I don't completely understand how this works. I know that (indirect),y addressing gets the address from the value in the pointer and adds y to it, so then does x get added to the pointer itself, and then the address comes from the value in the pointer+x?
5. When I was using NESASM, there was a way to see how much of each 8kb bank had been used. (I believe it was the -s command?) Is there any way to do something like this in ASM6?
1. Does $2002 have to be reread everytime something has to be written to a new area of the PPU?
2. What is the difference between bit shifts and bit rotations?
3. Does trying to draw things outside of vblank damage the PPU?
4. Are there any situations when programming the NES where (indirect,x) addressing would come in handy? Also I don't completely understand how this works. I know that (indirect),y addressing gets the address from the value in the pointer and adds y to it, so then does x get added to the pointer itself, and then the address comes from the value in the pointer+x?
5. When I was using NESASM, there was a way to see how much of each 8kb bank had been used. (I believe it was the -s command?) Is there any way to do something like this in ASM6?
Re: Random Stupid Questions I Think Of
No. It's just easier to read $2002 rather than remember what state you left $2005/$2006 's flipflop.Sogona wrote:1. Does $2002 have to be reread everytime something has to be written to a new area of the PPU?
BIT SHIFT2. What is the difference between bit shifts and bit rotations?
IT SHIFT0
T SHIFT00
SHIFT000
SHIFT0000
BIT ROTATE
IT ROTATEB
T ROTATEBI
ROTATEBIT
It does cause the PPU's output drivers to get in a fight with the ROM, which isn't great ... and it could randomly scribble over CHR RAM or nametable RAM, so ... don't do that.3. Does trying to draw things outside of vblank damage the PPU?
Arrays of pointers.4. Are there any situations when programming the NES where (indirect,x) addressing would come in handy?
Yes.does x get added to the pointer itself, and then the address comes from the value in the pointer+x?
- rainwarrior
- Posts: 8735
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Random Stupid Questions I Think Of
No, it only needs to be read when you don't know what state the $2005/2006 latch is in. It's a good idea to read it the first time you're using $2005/2006 in your NMI, and then after every pair of two writes to $2005/2006 it will be back to where it started. No need to read $2002 again.Sogona wrote:1. Does $2002 have to be reread everytime something has to be written to a new area of the PPU?
When you shift/rotate, you move all the bits over. One bit falls out the end (goes into the carry bit) and a hole is created at the other end. To fill that hole: a shift (asl/lsr) moves a 0 into the hole. A rotate (rol/ror) moves whatever is in the carry flag into that hole.2. What is the difference between bit shifts and bit rotations?
No, it does not harm the PPU. (This would be a huuuuge design flaw if it did! Don't let programmers break your hardware with their bugs!) It just results in corruptions to the VRAM, i.e. visual problems.3. Does trying to draw things outside of vblank damage the PPU?
It's not that commonly used, but the intent is that you can create a table of pointers in zeropage RAM, and use X to index those pointers. X is added to the address of the pointer (i.e. the result will be on the zero page still), it is not added to the address the pointer points to (e.g. indirect Y), nor the value the pointer fetches.4. Are there any situations when programming the NES where (indirect,x) addressing would come in handy? Also I don't completely understand how this works. I know that (indirect),y addressing gets the address from the value in the pointer and adds y to it, so then does x get added to the pointer itself, and then the address comes from the value in the pointer+x?
There are a few ways to do this using cc65, such as using the linker flag that generates a "map" file. If you need it in code, you may be able to use * to find the position of a piece of code, so you could put something at the end that calculates (* - $8000) or wherever the bank started.5. When I was using NESASM, there was a way to see how much of each 8kb bank had been used. (I believe it was the -s command?) Is there any way to do something like this in ASM6?
Re: Random Stupid Questions I Think Of
One nice feature of STA (foo,x) is that it doesn't generate dummy reads, so if you happen to have a pointer to a hardware register with side-effects on reads and need to access it, that can be done safely (with X=0). STA (foo),y always generates a dummy read. I admit this is not a common occurrence, but I took advantage of it in my generic memory copy/fill routines.
Similarly, LDA (foo,x) has a property that it always takes the same amount of time (unlike LDA (foo),y), so it can be useful for pointer dereferencing in timed code (again, only applicable if indexing is not needed, so X=0).
Similarly, LDA (foo,x) has a property that it always takes the same amount of time (unlike LDA (foo),y), so it can be useful for pointer dereferencing in timed code (again, only applicable if indexing is not needed, so X=0).
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
Re: Random Stupid Questions I Think Of
I prefer not to. I always use $2005 and $2006 in pairs, so the latch should never be left in the wrong state. But if by any chance it is, I want this bug to show during development, so I can fix it. I do read $2002 every once in a while though (not every frame).Sogona wrote:1. Does $2002 have to be reread everytime something has to be written to a new area of the PPU?
I remember people mentioning it could be useful for reading music tracks. A music engine could use generic code to process tracks, so it would simply change the index register and be ready to read data from any track.4. Are there any situations when programming the NES where (indirect,x) addressing would come in handy?
I'm not aware of anything of the kind in ASM6. You can generate a listing file (with -l), open it and look at the address of the last thing in the bank. If you want something more automatic, you can make a macro to warn you when there are less than X bytes until the next boundary:5. When I was using NESASM, there was a way to see how much of each 8kb bank had been used. (I believe it was the -s command?) Is there any way to do something like this in ASM6?
Code: Select all
.macro CheckBoundary Size, Limit
Mask = Size - 1
Remaining = Size - ($ & Mask)
.if Remaining < Limit
.error "The limit was reached!"
.endif
.endm
The bank size has to be a power of 2, the limit can be anything. It's not perfect, since it doesn't give you an exact number, and won't detect overflows, but it's something.
Re: Random Stupid Questions I Think Of
Unless you're disciplined enough to always leave it in "ready for first write" state except when doing raster effects. Somehow tokumaru and I have never had a problem with this.lidnariq wrote:No. It's just easier to read $2002 rather than remember what state you left $2005/$2006 's flipflop.Sogona wrote:1. Does $2002 have to be reread everytime something has to be written to a new area of the PPU?
Cleverlidnariq wrote:BIT SHIFT
IT SHIFT0
T SHIFT00
SHIFT000
SHIFT0000
BIT ROTATE
IT ROTATEB
T ROTATEBI
ROTATEBIT
Probably not. And in fact, you're encouraged to draw things out of vblank if you have forced blank turned on ($2001 = $00).Sogona wrote:3. Does trying to draw things outside of vblank damage the PPU?
Specifically, the only time I've seen an array of pointers on zero page being useful is a music engine, as tokumaru mentioned, with one or more pointers for each channel. In the music engine I used in RHDE: Furniture Fight and previous games, pointers on zero page represent position in a musical phrase, position in an instrument envelope, and position in sound effect data.lidnariq wrote:Arrays of pointers.Sogona wrote:4. Are there any situations when programming the NES where (indirect,x) addressing would come in handy?
For example, I rigged the credits screen of development versions of RHDE to display how full the ROM was. But it's tricky to get right because the size across all source files isn't known until link time, and .byte .sprintf(...) in ca65 requires that its argument be constant at assembly time. So instead I had to construct each ASCII digit like this (untested, as my RHDE project files are in another castle at the moment), which is resolved properly at link time:rainwarrior wrote:If you need [amount used in a memory area] in code, you may be able to use * to find the position of a piece of code, so you could put something at the end that calculates (* - $8000) or wherever the bank started.
Code: Select all
permill_full = (__CODE_SIZE__ + __RODATA_SIZE__) * 1000 / 32768
tenths_full = permill_full / 100
hundredths_full = (permill_full .MOD 100) / 10
thousandths_full = permill_full .MOD 10
.byte tenths_full|'0', hundredths_full|'0', '.', thousandths_full|'0', "% full", 0
Re: Random Stupid Questions I Think Of
Rotate is more like this though:lidnariq wrote:BIT SHIFT
IT SHIFT0
T SHIFT00
SHIFT000
SHIFT0000
BIT ROTATE
IT ROTATEB
T ROTATEBI
ROTATEBIT
Code: Select all
BIT ROTATE
IT ROTATE?
T ROTATE?B
ROTATE?BI
ROTATE?BIT
Re: Random Stupid Questions I Think Of
How about this approach?copy bit 7 (when rotating left) or bit 0 (when rotating right) into the carry before rotating.
Code: Select all
LDA $00
rol a ;puts bit 7 in carry
rol $00
Code: Select all
LDA $00
ror a ;puts 0 bit in carry
ror $00
Last edited by dougeff on Tue Oct 06, 2015 8:50 am, edited 1 time in total.
nesdoug.com -- blog/tutorial on programming for the NES
Re: Random Stupid Questions I Think Of
Good point. But on an 8-bit system, doesn't B start in the gap?tokumaru wrote:Rotate is more like this though:
Where "?" depends on the state of the carry when you start rotation. If you want to avoid the "?" gap actually have it like lidnariq posted, you have to copy bit 7 (when rotating left) or bit 0 (when rotating right) into the carry before rotating.Code: Select all
BIT ROTATE IT ROTATE? T ROTATE?B ROTATE?BI ROTATE?BIT
Code: Select all
C:Accum...
B:ITROTATE
I:TROTATEB
T:ROTATEBI
R:OTATEBIT
Code: Select all
lda #ROTATION ; X:ROTATION
cmp #$80 ; R:ROTATION
rol a ; R:OTATIONR
cmp #$80 ; O:OTATIONR
rol a ; O:TATIONRO
cmp #$80 ; T:TATIONRO
rol a ; T:ATIONROT
Re: Random Stupid Questions I Think Of
Like tepples pointed out, when rotating left you can copy bit 7 to the carry using CMP $80. I use that a lot. Rotating right has to be like you wrote though, AFAIK.dougeff wrote:Code: Select all
LDA $00 rol a ;puts bit 7 in carry rol $00
Are you saying that because the phrase "BIT ROTATE" has more than 8 characters? I assumed we were abstracting the register size, since lidnariq's examples had 9 and 10 characters, respectively. I just assumed the whole phrase could be loaded into the accumulator, at which point the carry would be in whatever state the previous instructions left it in.tepples wrote:But on an 8-bit system, doesn't B start in the gap?
Re: Random Stupid Questions I Think Of
nesdoug.com -- blog/tutorial on programming for the NES
Re: Random Stupid Questions I Think Of
What's the deal with color $0D of the PPU's palette?
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: Random Stupid Questions I Think Of
I don't know the specifics, but for a short answer, I think it's something like the color is a signal outside of what the TV is expecting, so depending on the TV, it will either show as black and nothing else, or it will show as black but make the whole scanline screwy.
This is actually a picture demonstrating how it looks from the forum:
I still think it would look cool for if you were trying to make a trippy effect on the game.
This is actually a picture demonstrating how it looks from the forum:
I still think it would look cool for if you were trying to make a trippy effect on the game.
Re: Random Stupid Questions I Think Of
There are so many things you could mean by "What's the deal".
Answers include:
It's "darker" (a lower voltage) than black
It's an accident of how the PPU generates colors, and its inclusion is an oversight.
The TV accidentally perceives this too low voltage as maybe the start of a new horizontal line of pixels. (TVs were originally entirely analog devices, so it can be halfway to thinking something)
Answers include:
It's "darker" (a lower voltage) than black
It's an accident of how the PPU generates colors, and its inclusion is an oversight.
The TV accidentally perceives this too low voltage as maybe the start of a new horizontal line of pixels. (TVs were originally entirely analog devices, so it can be halfway to thinking something)
Re: Random Stupid Questions I Think Of
I'm a little confused on the difference between the negative flag and the overflow flag on the 6502. From what I've read, the latter is only affected by math, bit testing, and some stack operations. So for example, if I just want to check if something's negative or positve, I'd use BPL and BMI, but if, after adding something to the accumulator, you'd use BVS or BVC instead?
P.S when I say overflow flag, I mean the flag in the status byte, not in $2000, if there was any ambiguity.
P.S when I say overflow flag, I mean the flag in the status byte, not in $2000, if there was any ambiguity.