It is currently Thu Dec 14, 2017 3:03 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 92 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7  Next
Author Message
PostPosted: Sat Nov 11, 2017 8:11 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 42
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 10 times
Top
 Profile  
 
PostPosted: Sat Nov 11, 2017 8:27 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1046
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.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Sat Nov 11, 2017 8:41 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 42
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 10 times
Top
 Profile  
 
PostPosted: Sat Nov 11, 2017 9:07 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 42
GOT IT TO WORK

Main code:
Code:
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 13 times
Top
 Profile  
 
PostPosted: Sat Nov 11, 2017 9:21 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1046
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.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Sat Nov 11, 2017 9:27 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 42
Is that a problem
if yes:
How can I fix?


Top
 Profile  
 
PostPosted: Sat Nov 11, 2017 9:31 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 42
Pokun wrote:
Code:
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:
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


Top
 Profile  
 
PostPosted: Sat Nov 11, 2017 9:34 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1046
Quote:
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:
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:
Player:
 
  INC $0200
  INC scroll
  LDA $00;You probably want lda #$00 here.
  STA scroll
 
  RTS

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Sat Nov 11, 2017 9:42 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 42
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


Top
 Profile  
 
PostPosted: Sat Nov 11, 2017 10:19 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 42
Code:
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.....


Top
 Profile  
 
PostPosted: Sat Nov 11, 2017 10:53 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1046
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:
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.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Thu Nov 16, 2017 2:45 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 42
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:
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?


Top
 Profile  
 
PostPosted: Thu Nov 16, 2017 6:02 pm 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1046
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.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Thu Nov 16, 2017 8:01 pm 
Offline
User avatar

Joined: Thu Jul 13, 2017 5:17 pm
Posts: 42
No just wondering. mmc question
Also one more thing.
'For the background, does this have a bad effect on it?
Code:
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 9 times
KitsuneTales.nes [40.02 KiB]
Downloaded 8 times
Top
 Profile  
 
PostPosted: Fri Nov 17, 2017 12:38 am 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1046
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:
.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:
.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

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 92 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6, 7  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: 93143, Google [Bot], Google Adsense [Bot] and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group