Pallete affects scroll value

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

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.
Attachments
KitsuneTales.nes
(40.02 KiB) Downloaded 97 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]
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Pallete affects scroll value

Post by Kasumi »

The stack resides at $0100-$01FF. This is what happens when you press left in FCEUX:
Image
so you still have some type of stack issue.
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

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
Attachments
Kitsunetales.asm
(19.67 KiB) Downloaded 97 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]
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

GOT IT TO WORK

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 108 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]
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Pallete affects scroll value

Post by Kasumi »

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.
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

Is that a problem
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]
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

Pokun wrote:

Code: Select all

Forever:

  JMP Forever     ;jump back to Forever, infinite loop
Here is your main loop, here you can put all logic (except sound which is better off in the NMI to avoid sound lag).

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
.
This is what ive referenced
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]
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Pallete affects scroll value

Post by Kasumi »

This is what ive referenced
But you copied it incorrectly. You used lda $01, that code uses #$01 and they are very different.

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
If you want to load a number, precede it with # like so
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
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

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
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]
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

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
Got it... I think.....
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]
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Pallete affects scroll value

Post by Kasumi »

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:

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
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.
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

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:

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
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.
SO if I'm reading this correctly, Put Drawcolems,Drawattributes into Forever and put this in the nmi?
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]
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Pallete affects scroll value

Post by Kasumi »

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.
User avatar
IMAGICA
Posts: 61
Joined: Thu Jul 13, 2017 5:17 pm
Contact:

Re: Pallete affects scroll value

Post by IMAGICA »

No just wondering. mmc question
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 99 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]
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Pallete affects scroll value

Post by Kasumi »

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:

Code: Select all

.inesprg 1  ; 1x 16KB PRG code
.ineschr 4   ; 1x  8KB CHR data
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.

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
Post Reply