It is currently Mon May 21, 2018 6:16 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 31 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Mon Jul 07, 2014 3:06 pm 
Offline

Joined: Tue Jul 01, 2014 4:02 pm
Posts: 285
I'm bashing my head against ASM at the moment, (using ASM6 to assemble) and I'd like to reach out and thank those who have given in depth responses. I'm very competent in high level languages such as javascript and C# for development, and generally get the logic in ASM after a few days of muscling through.

The new monster is nametables. Literally, I can not update my code to show a background. Even doing it the longhand way is giving me some unexpected results. I thought creating a .nam file from a capable program and using a loop to load it would work, but so far...nothing. I'm successfully .incbin-ing .chr files and .pal files, so I'm making the assumption the .nam file is loading just dandy, too...but I'll be damned if I can get anything to draw to the screen no matter what I try.

Sprites are showing. Palettes are correct. Just no background. I'm stumped and I'm going crosseyed playing with it, so hopefully someone can demonstrate my (probably very obvious) mistake(s).

Here's my very general process:

Code:
;;;After header, I declare variables for high and low bytes:
   .enum $0000
   addrLo .dsb 1
   addrHi .dsb 2
   .ende

   ;;I've tried setting up the PPU prior to and after loading background,
   ;;neither of which had any different affect.
   ;; load the background:


   lda $2002
   lda #$20
   STA $2006
   LDA #$00
   STA $2006
   
   ;; load nametable
   LDA #>myNam
   sta addrLo
   lda #<myNam
   sta addrHi
   
   jsr LoadBkg

    ;;I've then tried putting LoadBkg just about everywhere...
    ;;prior to the main game loop (which is where   
    ;;I thought I should put it...like, where I load the palatte data and whatnot),
    ;;IN the main game loop, in the interupts...just trial and error, really...
    ;; since it was not working.

LoadBkg:
   ldx #4
   ldy #00

loadData:
   lda (addrLo),y
   sta $2007
   iny
   bne loadData
   
   inc addrHi
   dex
   bne loadData
   rts

    ;; and then load the binaries for chr data and nam file...I
    ;; I've tried these both ways in case the order mattered...
    ;; again, trial and error.

   .incbin "main.chr"
myNam:   .incbin "mainBkg.nam"
 



I fully, humbly admit that I may have some dramatic misconceptions about things, but man...I feel like I was really getting it very well and then bam...hit a brick wall, and despite scouring and experimenting with advice from online resources, couldn't make this simple thing work.

If anyone can shed some light on what I am doing wrong and/or glaring misconceptions I may have, please let me know!

BTW - so far this forum has rocked. Thank you so much for the help, to all of you who have helped!


Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 3:25 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6286
Location: Canada
Some ideas:

  • Is the background not showing, or is the nametable not filled with the expected data? What does the nametable debug view in FCEUX show?
  • When you are writing the nametable through $2007, did you first disable rendering (i.e. write 0 to $2001)?
  • When you resume rendering, did you enable the background (another write to $2001)?
  • Is the correct nametable and tileset selected via $2000?
  • Did you set the scroll after you finished writing the nametables (using $2006/$2007 clobbers the scroll position, you need to write $2005 twice to reset it after writing to the nametable)?


Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 4:15 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3520
Location: Indianapolis
JoeGtake2 wrote:
Code:
   ;; load nametable
   LDA #>myNam
   sta addrLo
   lda #<myNam
   sta addrHi
 



That would be the problem. You've got the > and < switched around, so it's loading the upper byte into addrLo, and vice-versa.

I normally use a macro for this (it's for ca65, but I guess should convert to ASM6 easily enough), makes the source easier to read IMHO, and less typing hopefully means less typos. :)
Code:
;---------------------------------------------------------
;---------------------------------------------------------
;       Load 16-bit pointer (for indirect addressing)
;       (macro: pointer target,zeropage)
;---------------------------------------------------------
.macro  pointer   addr,addr2
                lda #<addr
                sta addr2
                lda #>addr
                sta addr2+1
.endmacro


edit: Also don't forget to set $2006 to $0000 when you're done.


Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 5:05 pm 
Offline

Joined: Tue Jul 01, 2014 4:02 pm
Posts: 285
Thanks so much, both of you guys.

Rainwarrior - debugging shows that the nametable is not filled with the right data (all with tile 0 instead). Also, I noticed that my palette file only seemed to load sprite palette and not bkg palette, so I just threw up the longhand way for now...I think that was my fault.

As for points 2 and 3, I think I've done that correctly, I'll post the code below to where I disabled and re-enabled rendering (at $2001)...could absolutely be incorrect placement on my part.

I believe that the correct nametable and tileset are selected via $2000...if they are not, I'm not certain how to do it. I'm only playing with a single nametable right now.

There is no scrolling in this yet. I'm not sure if I still have to write to $2005 for a static screen...if so, I haven't seen that on any resources I've looked at yet.


Memblers - I made that correction...I think that was just sloppiness on my part. Unfortunately, fixing this did not fix the problem.

I'm going to post the code in its entirety (with comments for the amendments you suggested that were either there or that I've updated). Please feel free to eviscerate it if it's messy and let me know what it is I'm doing wrong! I have no pride here, I'm just learning, but I feel like I get the code, it's just not doing what it's supposed to be doing. I assume it is a case of mistaken placement of something or otherwise some little tidbit I haven't learned yet. Does anything jump out at you?

Code:
   
   .enum $0000
   addrLo .dsb 1
   addrHi .dsb 2
   .ende
   
   .org $c000

RESET:
   SEI
   CLD
   LDX #$40
   STX $4017
   LDX #$FF
   TXS
   INX
   STX $2000
   STX $2001
   STX $4010
   
   BIT $2002
Vwait1:
   BIT $2002
clrmem:
   STA $000,x
   STA $100,x
   STA $300,x
   STA $400,x
   STA $500,x
   STA $600,x
   STA $700,x
   INX
   BNE clrmem
   
Vwait2:
   bit $2002
   BPL Vwait2
   
;;---Load Palettes
   LDA $2002
   LDA #$3F
   STA $2006
   LDA #$10
   STA $2006

   LDX #$00
LoadPaletteLoop:
   LDA PaletteData,x
   STA $2007
   INX
   CPX #$20
   BNE LoadPaletteLoop
   
   
;;---Set up PPU   
  LDA #%10000000
  STA $2000

  LDA #%00011110   
  STA $2001   
      

;;--load a background--;

   lda #$00   ;load 0
   STA $2001   ;write it to $2001 to disable rendering
   lda $2002
   lda #$20
   STA $2006
   LDA #$00
   STA $2006

;; load nametable
   LDA #<myNam   ; fixed symbol
   sta addrLo
   lda #>myNam    ; fixed symbol
   sta addrHi
   
   jsr LoadBkg
   LDA $0000  ; update
   STA $2006  ; update
;; Load a sprite to center of screen
   LDA #$80
   STA $0200
   STA $0203
   LDA #$00
   STA $0201
   LDA #$01
   STA $0202
   

NMI:
   LDA #$00
   STA $2003
   LDA #$02
   STA $4014
   RTI


mainLoop:   

LoadBkg:
   ldx #4
   ldy #00

loadData:
   LDA #$00   ; update - writing 0
   STA $2001  ; to $2001
   lda (addrLo),y
   sta $2007
   iny
   bne loadData
   
   inc addrHi
   dex
   bne loadData
   
   LDA #%00011110   ; enabling rendering / background--
   STA $2001        ; again.
   rts

  JMP mainLoop
 

PaletteData:
   ;.incbin "mainPal.pal"

   .db $0F,$3C,$38,$35,  $0F,$2A,$26,$24, $0F,$1C,$18,$12, $0F,$0C,$08,$03
   .db $0F,$36,$39,$3C,  $21,$24,$29,$2C, $11,$14,$17,$1A, $02,$05,$08,$0C
   

  .org $fffa
  .dw NMI
  .dw RESET
  .dw 0

   .incbin "main.chr"
myNam:   .incbin "mainBkg.nam"





Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 5:21 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3520
Location: Indianapolis
Stuff I noticed:

Palette is writing 32 bytes starting at $3F10, should write 32 bytes starting at $3F00 to set both BG and sprites.

NMI is turned on too early. With something like this I usually wait until just before turning the screen on (actually I tend to only turn the screen on inside the NMI, otherwise you might see the screen jump). Since the NMI isn't saving the register state, in this case the accumulator is getting corrupted whenever it interrupts. Also, the program flow is running right into the NMI routine instead of mainLoop. Though I can see your mainLoop is sorta mixed up with a subroutine, you'll want some kind of main loop, even if it's just an infinite JMP loop. Seems like it would crash or do something weird when it hits that RTI.

And yeah, even without scrolling you'll want to set $2005 to zero, or some known value.


Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 5:42 pm 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
If you want to have a separate NMI thread (which I like best) you need a flag to check if the other thread is is ready for the NMI logic to run. If it's not, generally the NMI thread needs to exit with all the CPU registers intact. http://wiki.nesdev.com/w/index.php/NMI_thread

Also, related to what Memblers was saying, I have a shadow variable for PPU registers, and once I turn on NMI, I normally only actually write to the PPU registers inside NMI from the shadow registers. So if the main thread wants to turn rendering on or whatever, write the new register value to the shadow location and update it in NMI and there will be no weird screen tearing.


Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 6:18 pm 
Offline

Joined: Tue Jul 01, 2014 4:02 pm
Posts: 285
Alright, the plot thickens...

I did a few more things based on your suggestions.

1. I handled the accumulator to push the values to the stack and then restore them at the end of the NMI (is this what you meant?). I think I did that right.

2. Palette issue is fixed. That's just me being an idiot...plain and simple.

3. I pushed the NMI down and made it so PPU setup is here (is this what you meant?)

4. I added a 0 write to $2005 just before re-enabling the rendering (is this the correct place?)

5. Please define shadow variable in context - I looked at the NMI thread that you posted, but am not sure how to implement it here. I'm still a little fuzzy on it, truthfully.


Now, this did not fix the problem (other than palettes...doh!), however, I found something funky. Just for kicks, I loaded the ROM file into yy-chr. The chr data started at $4000 rather than at $0000. When I load the .chr file directly, it is at $0000. My powers of deduction tell me this may be related to my problem, however I'm not sure how.

Here's an update to the entire code...

Thanks so much for your patience. I really don't think this should be this difficult, and it's probably something minor! But every piece of advice you guys give me helps tremendously.

Here's updated, still broken, code:

Code:
   
   .enum $0000
   addrLo .dsb 1
   addrHi .dsb 2
   .ende
   
   .org $c000

RESET:
   SEI
   CLD
   LDX #$40
   STX $4017
   LDX #$FF
   TXS
   INX
   STX $2000
   STX $2001
   STX $4010
   
   BIT $2002
Vwait1:
   BIT $2002
clrmem:
   STA $000,x
   STA $100,x
   STA $300,x
   STA $400,x
   STA $500,x
   STA $600,x
   STA $700,x
   INX
   BNE clrmem
   
Vwait2:
   bit $2002
   BPL Vwait2
   
;;---Load Palettes
   LDA $2002
   LDA #$3F
   STA $2006
   LDA #$00       ;;****YES, I believe this fixed the palette issue.
   STA $2006

   LDX #$00
LoadPaletteLoop:
   LDA PaletteData,x
   STA $2007
   INX
   CPX #$20
   BNE LoadPaletteLoop
   
;; Load a sprite to center of screen
   LDA #$80
   STA $0200
   STA $0203
   LDA #$04
   STA $0201
   LDA #$01
   STA $0202
;;--load a background--;

   lda #$00   ;load 0
   STA $2001   ;write it to $2001 to disable rendering
   lda $2002
   lda #$20
   STA $2006
   LDA #$00
   STA $2006


 ;; load nametable
   LDA #<myNam   ; fixed symbol
   sta addrLo
   lda #>myNam    ; fixed symbol
   sta addrHi
   
   jsr LoadBkg
   LDA $0000  ; update
   STA $2006  ; update



mainLoop:   

  JMP mainLoop

LoadBkg:
   ldx #4
   ldy #00

loadData:
   LDA #$00   ; update - writing 0
   STA $2001  ; to $2001
   lda (addrLo),y
   sta $2007
   iny
   bne loadData
   
   inc addrHi
   dex
   bne loadData
   LDA #$00      ;**** load zero
   STA $2005       ;****write to $2005
   LDA #%00011110   ; enabling rendering / background--
   STA $2001        ; again.

   
   rts
NMI:      ;****** updated NMI to write to stack and
         ;****** restore accumulators when finished
   PHA
   TXA
   PHA
   TYA
   PHA
;;---Set up PPU   
         ;***** Now only being called in the NMI
   LDA #%10000000
   STA $2000

   LDA #%00011110   
   STA $2001      

   LDA #$00
   STA $2003
   LDA #$02
   STA $4014
   
   PLA
   TAY
   PLA
   TAX
   PLA

   RTI
   
PaletteData:         ;***** YES, this fixed the dumb palette
                  ;**** issue.  Just me being dumb.
   .incbin "charPal.pal"
   .incbin "bkgPal.pal"

  .org $fffa
  .dw NMI
  .dw RESET
  .dw 0

   .incbin "main.chr"
myNam:   .incbin "mainBkg.nam"





Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 6:44 pm 
Offline
Formerly 43110
User avatar

Joined: Wed Feb 05, 2014 7:01 am
Posts: 322
Location: us-east
I'm confused about one thing. Where/what is the iNES header? because I can't tell if it's CHR ROM or RAM. I'm guessing it's supposed to be CHR ROM because you include main.chr after the vectors, but yet you also include binary data (myNam) to be read by the cpu after that.

tokumaru's ASM6 templates shows an example of an iNES header.


Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 7:02 pm 
Offline

Joined: Tue Jul 01, 2014 4:02 pm
Posts: 285
My mistake for not including that. Yes, from Tokumaru's template, I actually have a 'header.asm' file which has this header, and then its body includes this file. This has been working for the other things I've been messing around with fine (setting up a meta-sprite character, making character move, keeping him within the boundaries of the screen). But this is stumping me.

**EDIT** On that note, placing the .incbin for the nametable just after the .incbin for palette data (rather than at the end with the chr data) helped marginally - now I DO have a background drawn, however there are two things wrong - it is certainly showing the wrong tiles (though they are in the right arrangement), and also the whole nametable is offset by a noticeable amount of pixels (I didn't count...maybe -64 both vertically and horizontally). So that's progress at least!

Any thoughts?


Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 7:39 pm 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
Step through your code with a debugging emulator and breakpoints, etc. That is often the best way to see where things are going wrong. A "shadow register" is just a memory location/variable to hold what you want to write at a later time .. like in NMI.


Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 7:43 pm 
Offline
Formerly 43110
User avatar

Joined: Wed Feb 05, 2014 7:01 am
Posts: 322
Location: us-east
You missed a BPL for Vwait1, and Keep in mind that $2005 and $2006 are double write registers. In LoadBkg you write to $2005 only once, and after the jsr LoadBkg, that might have interfered with the single write to $2006 with the contents of addrLo.

Also writing 0 to PPU_MASK every byte sent to PPU_DATA?


Last edited by JRoatch on Mon Jul 07, 2014 7:52 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 7:51 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10480
Location: Rio de Janeiro - Brazil
JoeGtake2 wrote:
it is certainly showing the wrong tiles (though they are in the right arrangement)

When you set $2000 you're telling the PPU to fetch tiles from $0000 (i.e.) the first pattern table, for both sprite and background. Could the background tiles be at $1000 instead?

Quote:
and also the whole nametable is offset by a noticeable amount of pixels (I didn't count...maybe -64 both vertically and horizontally).

A common cause for this is not resetting the scroll after using $2006/$2007 to write to the PPU. I'm not seeing you reset the scroll anywhere... You do have this weird piece of code, which is probably not doing what you expect it to:

Code:
   LDA $0000  ; update
   STA $2006  ; update

This will load a byte from $0000 (i.e. the first byte of RAM) and write it to $2006. A single write doesn't set the PPU address, and I doubt that's the value you wanted to write. You probably meant to do this:

Code:
lda #$00
sta $2006
sta $2006

Which is one way to reset the scroll (the wrong way, because it doesn't fully reset the scroll). the correct way is to select the name table through $2000 and then writing #$00 to $2005 twice, to clear both horizontal and vertical scroll.


Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 7:57 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3520
Location: Indianapolis
I think the screen offset is caused by the LDA $0000 / STA $2006, that's actually reading from RAM, your addrLo variable, in fact. So you'll want to do LDA #0 / STA $2006 / STA $2006, and the same for $2005.

By the "shadow registers", we mean making a variable (I call them v2000 and v2001), so in your NMI routine you would do LDA v2001 / STA $2001, and would only write to v2001 in the main thread of the program. The exception of course is when enabling NMI from the main thread, for that I do one of these (in case v2000 already has some other settings): LDA v2000 / ORA #%10000000 / STA v2000 / STA $2000. In your current program, I think the NMI will never happen because it's only getting enabled from within the NMI.


Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 8:16 pm 
Offline

Joined: Tue Jul 01, 2014 4:02 pm
Posts: 285
You guys are awesome. Seriously. I fully realize I'm asking some newbish questions, and not a single troll or impatient response yet. What a wonderful part of the interwebs this is!

Tokumaru - you nailed it on the clearing the scrolling. That fixed the issue 100% as far as that weird offset I was getting. Now everything is lined up, but is still showing the same issue with the tiles. I believe that you are absolutely right - I'm looking for background sprites at $1000 and it is pulling from $0000. Wouldn't the method to do this be in the PPU - in the load to $2000?

Code:
LDA #%00010000
STA $2000


I've tried this...also tried reversing this. Both seemed to do nothing.

I've even tried moving the PPU setup around in case the NMI was never being accessed (Memblers, I was a step ahead of you on that thought), but that didn't seem to do anything either.

Is there a concept I'm missing to access from $1000 rather than $0000, or am I right in the concept and something else is getting in the way negating that?



Memblers - I think I get what you are saying. I'm going to try it out and hopefully you won't mind checking my work haha.


Top
 Profile  
 
PostPosted: Mon Jul 07, 2014 8:23 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 3065
Location: Tampere, Finland
43110 wrote:
I'm guessing it's supposed to be CHR ROM because you include main.chr after the vectors, but yet you also include binary data (myNam) to be read by the cpu after that.

^ THAT is your problem (one of them). You need to put the nametable in the PRG-ROM part of the ROM (before the vectors), not in CHR-ROM.

EDIT: Oops, I missed the fact that you already mentioned fixing this this in an earlier post.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi


Last edited by thefox on Mon Jul 07, 2014 8:51 pm, edited 1 time in total.

Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 31 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: cpow and 4 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