Pallete affects scroll value
Moderator: Moderators
Re: Pallete affects scroll value
This is the list of It Red text shows what was deleted green shows what was added
forever:
JSR 2
RTS -2
NMI/ IRQ 3
RTI -3
JSR RC1 +2 2
RTS RC1 -2 0
JSR Player +2 2
RTS Player -2 0
RTI -3;crash
NMI +3 3
JSR DNA 2 5
RTS DNA -2 3
JSR DNC 2 5
JSR ls 2 7
RTS ls -2 5
RTS DNC -2 3
JSR SC 2 5
RTS SC -2 3
RTI -3 0
Goal 1: Get game 'running'; notes: thank you dougleff The chart above shows the info in practice.
Goal 2: Get game to stop stuttering; notes: Pokun has info about vblanking with forever.
forever:
JSR 2
RTS -2
NMI/ IRQ 3
RTI -3
JSR RC1 +2 2
RTS RC1 -2 0
JSR Player +2 2
RTS Player -2 0
RTI -3;crash
NMI +3 3
JSR DNA 2 5
RTS DNA -2 3
JSR DNC 2 5
JSR ls 2 7
RTS ls -2 5
RTS DNC -2 3
JSR SC 2 5
RTS SC -2 3
RTI -3 0
Goal 1: Get game 'running'; notes: thank you dougleff The chart above shows the info in practice.
Goal 2: Get game to stop stuttering; notes: Pokun has info about vblanking with forever.
- Attachments
-
- KitsuneTales.nes
- (40.02 KiB) Downloaded 98 times
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Re: Pallete affects scroll value
The stack resides at $0100-$01FF. This is what happens when you press left in FCEUX:
so you still have some type of stack issue.
so you still have some type of stack issue.
Re: Pallete affects scroll value
Is there another thing I have to record to fixit because that's something new I've encountered.
Apart from before nmi Problems
delete the scroll stack if you want that effect again
Apart from before nmi Problems
delete the scroll stack if you want that effect again
- Attachments
-
- Kitsunetales.asm
- (19.67 KiB) Downloaded 98 times
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Re: Pallete affects scroll value
GOT IT TO WORK
Main code:
Main code:
Code: Select all
LDA $01
STA NMIB+1
LDA NMIB+1
cmp $00
BCS waitforframe
jsr ReadController1 ;read controllers
jsr Player ;moves a sprite vertically across screen
waitforframe:
lda NMIB+1
beq waitforframe
LDA $00
STA NMIB+1
- Attachments
-
- KitsuneTales.nes
- (40.02 KiB) Downloaded 109 times
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Re: Pallete affects scroll value
lda $00 is equivalent to lda speed in your program.
cmp $00 = cmp speed.
lda $01 is equivalent to lda temp.
lda $XX reads the value from RAM location $00XX and puts that into A. lda #$XX puts the actual value $XX into A.
The only reason this code works is because your program starts by setting all RAM to zero.
cmp $00 = cmp speed.
lda $01 is equivalent to lda temp.
lda $XX reads the value from RAM location $00XX and puts that into A. lda #$XX puts the actual value $XX into A.
The only reason this code works is because your program starts by setting all RAM to zero.
Re: Pallete affects scroll value
Is that a problem
if yes:
How can I fix?
if yes:
How can I fix?
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Re: Pallete affects scroll value
This is what ive referencedPokun wrote:Here is your main loop, here you can put all logic (except sound which is better off in the NMI to avoid sound lag).Code: Select all
Forever: JMP Forever ;jump back to Forever, infinite loop
Mine look something like this:.Code: Select all
main: jsr con_read ;read controllers jsr logic ;state machine with all game logic, like: input handlers, moving objects, collisions gravity etc lda #$01 sta draw_flag ;allow NMI to draw, prevents incomplete buffering nmi_wait: lda nmi_end_flag beq nmi_wait ;wait for NMI to finish, this limits logic to a fixed frame rate lda #$00 sta nmi_end_flag ;clear NMI completion flag jmp main
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Re: Pallete affects scroll value
But you copied it incorrectly. You used lda $01, that code uses #$01 and they are very different.This is what ive referenced
First, for understanding. Here is some example code:
Code: Select all
lda #$FF;A=#$FF
sta $00;$00 = A. A=#$FF. So $00 has the value #$FF inside.
lda $00;A=#$FF
lda #$00;A=#$00
lda #$00
If you want to load a value in ROM or RAM, don't. like so
lda $00
But usually you would never do with a number. You'd usually use named RAM like
lda speed
instead if you wanted that.
So look for places in your code where you forgot the '#' symbol. Here's one:
Code: Select all
Player:
INC $0200
INC scroll
LDA $00;You probably want lda #$00 here.
STA scroll
RTS
Re: Pallete affects scroll value
Alright. So that Sta temp from the PHA could be used to load it into that stack
BTW Code stop
P.S. How ca I yse this knowledge to fix vblanking
BTW Code stop
P.S. How ca I yse this knowledge to fix vblanking
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Re: Pallete affects scroll value
Code: Select all
Forever:
LDA NMIB+1
cmp #$01
BEQ waitforframe
jsr ReadController1 ;read controllers
jsr Player ;moves a sprite vertically across screen
jsr Direction
JSR AniFrame
LDA #$01
STA NMIB+1
waitforframe:
lda NMIB+1
Cmp #$01
beq waitforframe
LDA NMIB+1
cmp #$01
BEQ waitforframe
LDA #$00
STA NMIB+1
jmp Forever
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Re: Pallete affects scroll value
You have a much harder problem. After the NMI happens, you have about 2270 "cycles" to safely write to parts of the PPU. A "cycle" is a bit like a measure of time. Each instruction takes a certain amount of time.
From NMI:
to
STA $4014
in your program takes 2427 cycles. You have to optimize your code for speed and that's... not an easy topic to cover. But to start with, here's two facts.
1. The NMI lets you know when a brief period of time starts that allows you to write to places like $2007 safely while the screen is being rendered.
2. In your "Forever" loop, you have quite a lot of time, but can't write to places like $2007 safely.
The solution: Do absolutely everything you can in your forever loop, short of actually writing to $2007.
Your NMI could look something like this:
That copy loop could be made faster, but let's keep it simple for now.
This makes it so your NMI does very few things.
1. Pushes your registers (X, Y and A) to the stack. This is pretty much required.
2. Write the top row of nametable0's address to $2006
3. Reads 32 bytes from $0500-$051F and stores them to $2007.
So effectively, it copies 32 bytes from $0500 to the top row of the first nametable.
4. Sets your scroll to 0, 0.
5. increments NMIB+1 so your main loop stops waiting.
6. pulls your registers from the stack. (Also pretty much required.)
Since your NMI (in this example) is copying bytes from $0500-$051F, your next step is to ready that data in your forever loop. So code like DrawNewColumn would be run in the forever loop, but instead of storing to $2007, it'd store to $0500,y. And then when the next NMI happens, it will be read from $0500,y and written to $2007 when it's safe to do so.
This is a super simplified way to approach this, but that's the theory. Say you want to copy to a different address. No problem. Create two variables to store the address you want to write to in your forever loop, and then read that from RAM in your NMI. Say you don't want to draw a new row every frame. No problem. Create a variable that says whether your NMI should copy a new row. Set it in your Forever loop. Read it in your NMI and skip the $2007 writes if it says to. Say you want to copy new columns instead of rows. No problem. Create a new variable that specifies the type of copying to be done.
You want your NMI to be making as few decisions as possible because the time is very limited, so this approach (write to $0500 or elsewhere in RAM while you have a lot of time, then directly copy when you don't) is a good one.
From NMI:
to
STA $4014
in your program takes 2427 cycles. You have to optimize your code for speed and that's... not an easy topic to cover. But to start with, here's two facts.
1. The NMI lets you know when a brief period of time starts that allows you to write to places like $2007 safely while the screen is being rendered.
2. In your "Forever" loop, you have quite a lot of time, but can't write to places like $2007 safely.
The solution: Do absolutely everything you can in your forever loop, short of actually writing to $2007.
Your NMI could look something like this:
Code: Select all
NMI:
PHA
TXA
PHA
TYA
pha
lda #$20;Always write to one nametable for the example
sta $2006
lda #$00
sta $2006
LDA #%10110000
sta $2000;increment by one
ldy #0
nmiloop:
lda $0500,y;4 cycles
sta $2007;4 cycles
iny ;2 cycles
cpy #32;2 cycles
bne nmiloop;3 cycles taken
LDA #$00
STA $2003
LDA #$02
STA $4014 ; sprite DMA from $0200
LDA #%10110000
ora nametablescroll
sta $2000
lda #$00;reset scroll to zero
sta $2005
sta $2005
INC NMIB+1
PLA
TAY
PLA
TAX
PLA
RTI ; return from interrupt
This makes it so your NMI does very few things.
1. Pushes your registers (X, Y and A) to the stack. This is pretty much required.
2. Write the top row of nametable0's address to $2006
3. Reads 32 bytes from $0500-$051F and stores them to $2007.
So effectively, it copies 32 bytes from $0500 to the top row of the first nametable.
4. Sets your scroll to 0, 0.
5. increments NMIB+1 so your main loop stops waiting.
6. pulls your registers from the stack. (Also pretty much required.)
Since your NMI (in this example) is copying bytes from $0500-$051F, your next step is to ready that data in your forever loop. So code like DrawNewColumn would be run in the forever loop, but instead of storing to $2007, it'd store to $0500,y. And then when the next NMI happens, it will be read from $0500,y and written to $2007 when it's safe to do so.
This is a super simplified way to approach this, but that's the theory. Say you want to copy to a different address. No problem. Create two variables to store the address you want to write to in your forever loop, and then read that from RAM in your NMI. Say you don't want to draw a new row every frame. No problem. Create a variable that says whether your NMI should copy a new row. Set it in your Forever loop. Read it in your NMI and skip the $2007 writes if it says to. Say you want to copy new columns instead of rows. No problem. Create a new variable that specifies the type of copying to be done.
You want your NMI to be making as few decisions as possible because the time is very limited, so this approach (write to $0500 or elsewhere in RAM while you have a lot of time, then directly copy when you don't) is a good one.
Re: Pallete affects scroll value
SO if I'm reading this correctly, Put Drawcolems,Drawattributes into Forever and put this in the nmi?Kasumi wrote:You have a much harder problem. After the NMI happens, you have about 2270 "cycles" to safely write to parts of the PPU. A "cycle" is a bit like a measure of time. Each instruction takes a certain amount of time.
From NMI:
to
STA $4014
in your program takes 2427 cycles. You have to optimize your code for speed and that's... not an easy topic to cover. But to start with, here's two facts.
1. The NMI lets you know when a brief period of time starts that allows you to write to places like $2007 safely while the screen is being rendered.
2. In your "Forever" loop, you have quite a lot of time, but can't write to places like $2007 safely.
The solution: Do absolutely everything you can in your forever loop, short of actually writing to $2007.
Your NMI could look something like this:
That copy loop could be made faster, but let's keep it simple for now.Code: Select all
NMI: PHA TXA PHA TYA pha lda #$20;Always write to one nametable for the example sta $2006 lda #$00 sta $2006 LDA #%10110000 sta $2000;increment by one ldy #0 nmiloop: lda $0500,y;4 cycles sta $2007;4 cycles iny ;2 cycles cpy #32;2 cycles bne nmiloop;3 cycles taken LDA #$00 STA $2003 LDA #$02 STA $4014 ; sprite DMA from $0200 LDA #%10110000 ora nametablescroll sta $2000 lda #$00;reset scroll to zero sta $2005 sta $2005 INC NMIB+1 PLA TAY PLA TAX PLA RTI ; return from interrupt
This makes it so your NMI does very few things.
1. Pushes your registers (X, Y and A) to the stack. This is pretty much required.
2. Write the top row of nametable0's address to $2006
3. Reads 32 bytes from $0500-$051F and stores them to $2007.
So effectively, it copies 32 bytes from $0500 to the top row of the first nametable.
4. Sets your scroll to 0, 0.
5. increments NMIB+1 so your main loop stops waiting.
6. pulls your registers from the stack. (Also pretty much required.)
Since your NMI (in this example) is copying bytes from $0500-$051F, your next step is to ready that data in your forever loop. So code like DrawNewColumn would be run in the forever loop, but instead of storing to $2007, it'd store to $0500,y. And then when the next NMI happens, it will be read from $0500,y and written to $2007 when it's safe to do so.
This is a super simplified way to approach this, but that's the theory. Say you want to copy to a different address. No problem. Create two variables to store the address you want to write to in your forever loop, and then read that from RAM in your NMI. Say you don't want to draw a new row every frame. No problem. Create a variable that says whether your NMI should copy a new row. Set it in your Forever loop. Read it in your NMI and skip the $2007 writes if it says to. Say you want to copy new columns instead of rows. No problem. Create a new variable that specifies the type of copying to be done.
You want your NMI to be making as few decisions as possible because the time is very limited, so this approach (write to $0500 or elsewhere in RAM while you have a lot of time, then directly copy when you don't) is a good one.
Also when MMC5 is enabled, black screen is inevitvlble. Is bank switching needed
also is the back ground normal?
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Re: Pallete affects scroll value
You can't only put Drawattributes/Drawcolumns into forever because they write to $2006/$2007. You have to modify them so they write to RAM instead. Your NMI must then read from this RAM and write that data to $2007 as fast as possible.
You last ROM used mapper 4, which is MMC3 not MMC5. Has something changed? I would not recommend switching mappers right now.
The background for your ROM only appeared normal in less accurate emulators, your last write to $2007 in your NMI cannot occur as late as it does.
You last ROM used mapper 4, which is MMC3 not MMC5. Has something changed? I would not recommend switching mappers right now.
The background for your ROM only appeared normal in less accurate emulators, your last write to $2007 in your NMI cannot occur as late as it does.
Re: Pallete affects scroll value
No just wondering. mmc question
Also one more thing.
'For the background, does this have a bad effect on it?
Also one more thing.
'For the background, does this have a bad effect on it?
Code: Select all
DrawNewColumn:
LDA scroll ; calculate new column address using scroll register
LSR A
LSR A
LSR A ; shift right 3 times = divide by 8
STA columnLow ; $00 to $1F, screen is 32 tiles wide
LDA nametable ; calculate new column address using current nametable
EOR #$01 ; invert low bit, A = $00 or $01
ASL A ; shift up, A = $00 or $02
ASL A ; $00 or $04
STA switchrender
CLC
ADC #$20 ; add high byte of nametable base address ($2000) can change to lower name table $2000 = ADC #$20 $2800 = ADC #$28
STA columnHigh ; now address = $20 or $24 for nametable 0 or 1
LDA columnNumber ; column number * 32 = column data offset
ASL A
ASL A
ASL A
ASL A
ASL A
STA sourceLow
LDA columnNumber
LSR A
LSR A
LSR A
STA sourceHigh
JSR levelselect
DrawColumn:
LDA #%00100100 ; set to increment +32 mode
STA $2000
LDA $2002 ; read PPU status to reset the high/low latch
LDA columnHigh
STA $2006 ; write the high byte of column address
LDA columnLow
STA $2006 ; write the low byte of column address
LDX #$0F ; copy 30 bytes
LDY #$1E
DrawColumnLoop:
LDA [sourceLow], y
STA $2007
CLC
ADC #$01
STA $2007
INY
DEX
BNE DrawColumnLoop
LDA switchrender
CLC
ADC #$28
STA columnHigh
LDA columnHigh
STA $2006 ; write the high byte of column address
LDA columnLow
STA $2006
LDX #$0F ; copy 30 bytes
DrawColumnLoopP2:
LDA [sourceLow], y
STA $2007
CLC
ADC #$01
STA $2007
INY
DEX
BNE DrawColumnLoopP2
RTS
- Attachments
-
- Kitsunetales.asm
- (19.19 KiB) Downloaded 94 times
-
- KitsuneTales.nes
- (40.02 KiB) Downloaded 101 times
In Progress:
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Tengu Tales (MMC3 Test first)[360 degress bullet direction math]
Baseball Brawlers (MMC5 full features, "Yoshi's Island")[Square root table, SPG ]
Smash ("port",MMC5 )[Character Movement]
Re: Pallete affects scroll value
I'm not sure I understand why those changes were made. You're writing the value from [sourcelow],y to $2007, then adding 1 that value and writing that to $2007. So for every byte in the address pointed to in sourcelow, you're writing two bytes. You're also not starting from zero. (LDY #$1E), which I'm not sure is correct. (Maybe you did that before? I forget)
But aside from that, your rom is smaller than it should be. (I probably should have mentioned this a while ago.) NESASM considers a bank to be 8KB always. The header for an NES rom considers PRG banks (code/data) to be 16KB and CHR banks (graphics) to be 8KB.
Your code starts like this:
16*1 (the size in KB of PRG banks)
+
4*8 (the size in KB of CHR banks)
=
48
48/8 (the size in KB of a bank to NESASM)
=
6
So you should have 6 .bank directives in your code. 2 for PRG, and 4 for chr. Your two for prg are correct.
But aside from that, your rom is smaller than it should be. (I probably should have mentioned this a while ago.) NESASM considers a bank to be 8KB always. The header for an NES rom considers PRG banks (code/data) to be 16KB and CHR banks (graphics) to be 8KB.
Your code starts like this:
Code: Select all
.inesprg 1 ; 1x 16KB PRG code
.ineschr 4 ; 1x 8KB CHR data
+
4*8 (the size in KB of CHR banks)
=
48
48/8 (the size in KB of a bank to NESASM)
=
6
So you should have 6 .bank directives in your code. 2 for PRG, and 4 for chr. Your two for prg are correct.
Code: Select all
.bank 2
.org $0000
.incbin "Electro_and_Shiro.chr"
;;;;;;;;;;;;;;;;;;;;
.bank 3
.org $0000;This might change how your rom behaved? But I don't think $A000 was right
.incbin "Kitsunetales.chr"
;;;;;;;;;;;;;;;;;;;
.bank 4
.org $0000
.bank 5
.org $0000