Page 1 of 1

can write nametable hard coded to $2007, but looping=problem

Posted: Sat Jan 31, 2009 7:02 pm
by GradualGames
For some reason I'm finding it a real struggle to write 1024 bytes to the PPU from my nametable data. I've verified that I indeed have 960 bytes of nametable tiles followed by 64 bytes of attributes. But for some reason they just won't load properly. Manually writing tile numbers to the PPU, with repeated writes to $2007, seems to work fine, on the other hand.

I must be doing something wrong somewhere else in my code as well though, because Nestopia appears to be unable to load the background palette. Jnes loads it, FCEUXD loads it, but Nestopia does not. Thus, something bad must be happening somewhere in the bowels of my code.

Anyone want to check out my code?

BTW, My P65 version of this code works perfectly. I've attempted to translate it to NESASM, this is when I ran into these problems.

Posted: Sat Jan 31, 2009 7:12 pm
by tokumaru
Are you doing those writes with rendering disabled or during VBlank? Data can only be written to the PPU during those times. You can post the code here, if it's not ridiculously large. If it is, omit what you think is irrelevant (although the problem could very well be in those parts, but let's just see what happens).

Posted: Sat Jan 31, 2009 7:18 pm
by GradualGames
I'm one step ahead of you. I've omitted everything that initialized sprites or input routines---all I'm doing is loading the background here.

Code: Select all

        .inesprg    1
        .ineschr    1
        .inesmir    1
        .inesmap    0

        .bank 0
        .org $0000
buttonA:      
        .db 0
lobyte:
        .db 0
hibyte:
        .db 0
sprite:

; Actual program code.  We only have one PRG-ROM chip here, so the
; origin is $C000.
         .org $C000

reset:  sei
	cld
	; Wait two VBLANKs.
wb1:	lda $2002
	bpl wb1
wb2:	lda $2002
	bpl wb2

	; Clear out RAM.
        lda #$00
        ldx #$00
clear:  sta $000,x
        sta $100,x
        sta $200,x
        sta $300,x
        sta $400,x
        sta $500,x
        sta $600,x
        sta $700,x
        inx
        bne clear

	; Reset the stack pointer.
        ldx #$FF
        txs

	; Disable all graphics.
        lda #$00
        sta $2000
        sta $2001


	jsr initgraphics

	; Set basic PPU registers.  Load background from $0000,
	; sprites from $1000, and the name table from $2000.
        lda #%10001000
        sta $2000
        lda #%00011110
        sta $2001

	cli

	; Transfer control to the VBLANK routines.
loop:   jmp loop

initgraphics:
        jsr loadpalette
        jsr loadnametables
        rts


; Load palette into $3F00
loadpalette:
        lda #$3F
        ldx #$00
        sta $2006
        stx $2006
ldpal:  lda palette,x
        sta $2007
        inx
        cpx #$20
        bne ldpal
        rts

loadnametables:
        lda #low(bg)
        sta lobyte
        lda #high(bg)
        sta hibyte
        lda #$20
        sta $2006
        lda #$00
        sta $2006
        ldy #$00
        ldx #$01
ldnam:  lda [lobyte],y
        sta $2007
        iny
        bne ldnam
        inc hibyte
        dex
        bne ldnam

        rts

vblank:
irq:    rti

; palette data
palette:

;Image Palette
       .db $21,$1a,$2a,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00

;Sprite Palette
       .db $21,$3f,$27,$2a,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00

; Background data

;Name Table

bg:
;Name Table
      .db $01,$02,$01,$02,$01,$02,$01,$02,$01,$02,$01,$02,$01,$02,$01,$02,$01,$02,$01,$02,$01,$02,$01,$02,$01,$02,$01,$02,$01,$02,$01,$02
      .db $03,$04,$03,$04,$03,$04,$03,$04,$03,$04,$03,$04,$03,$04,$03,$04,$03,$04,$03,$04,$03,$04,$03,$04,$03,$04,$03,$04,$03,$04,$03,$04
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
      .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00



;Attribute Table
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00
           .db $00

        .bank 1
        .org $FFFA
        .dw vblank
        .dw reset
        .dw irq

      .bank 2
      .org $0000

;Pattern Table
         .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
         .db $ff,$99,$b3,$e6,$cc,$99,$b3,$e6,$00,$66,$4c,$19,$33,$66,$4c,$19
         .db $ff,$99,$33,$67,$cd,$99,$33,$67,$00,$66,$cc,$98,$32,$66,$cc,$98
         .db $cc,$99,$b3,$e6,$cc,$99,$b3,$ff,$33,$66,$4c,$19,$33,$66,$4c,$00
         .db $cd,$99,$33,$67,$cd,$99,$33,$ff,$32,$66,$cc,$98,$32,$66,$cc,$00

       .org $1000

;Pattern Table
         .db $00,$01,$02,$04,$08,$10,$21,$60,$00,$00,$01,$03,$07,$0f,$1e,$1f
         .db $c0,$98,$b0,$d0,$90,$98,$3c,$3e,$00,$00,$00,$20,$60,$60,$d8,$d0
         .db $00,$00,$01,$02,$04,$08,$10,$21,$00,$00,$00,$01,$03,$07,$0f,$1e
         .db $00,$80,$90,$b0,$d0,$90,$98,$3c,$00,$00,$00,$00,$20,$60,$60,$d8
         .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
         .db $70,$40,$60,$70,$40,$20,$10,$0c,$0f,$3f,$1f,$0f,$3f,$1f,$0f,$03
         .db $1a,$06,$06,$02,$22,$24,$18,$10,$e4,$f8,$f8,$fc,$dc,$d8,$e0,$e0
         .db $60,$70,$40,$60,$70,$40,$20,$10,$1f,$0f,$3f,$1f,$0f,$3f,$1f,$0f
         .db $3e,$1a,$06,$06,$02,$22,$24,$18,$d0,$e4,$f8,$f8,$fc,$dc,$d8,$e0
         .db $07,$07,$08,$10,$32,$22,$32,$22,$00,$00,$07,$0f,$0d,$1d,$0d,$1d
         .db $e0,$e0,$10,$08,$44,$44,$44,$44,$00,$00,$e0,$f0,$b8,$b8,$b8,$b8
         .db $0c,$07,$07,$08,$10,$30,$22,$31,$03,$00,$00,$07,$0f,$0f,$1d,$0e
         .db $10,$e0,$e0,$10,$88,$44,$24,$24,$e0,$00,$00,$e0,$70,$b8,$d8,$d8
         .db $0c,$07,$07,$08,$10,$31,$22,$32,$03,$00,$00,$07,$0f,$0e,$1d,$0d
         .db $10,$e0,$e0,$10,$88,$04,$24,$44,$e0,$00,$00,$e0,$70,$f8,$d8,$b8
         .db $31,$20,$10,$08,$07,$04,$08,$07,$0e,$1f,$0f,$07,$00,$03,$07,$00
         .db $84,$04,$08,$10,$e0,$18,$04,$f8,$78,$f8,$f0,$e0,$00,$e0,$f8,$00
         .db $20,$30,$20,$10,$28,$47,$32,$0f,$1f,$0f,$1f,$0f,$17,$38,$0c,$00
         .db $c4,$04,$76,$09,$01,$e2,$24,$18,$38,$f8,$88,$f6,$fe,$1c,$18,$00
         .db $21,$30,$20,$20,$20,$43,$31,$0f,$1e,$0f,$1f,$1f,$1f,$3c,$0e,$00
         .db $84,$04,$06,$09,$11,$e2,$24,$18,$78,$f8,$f8,$f6,$ee,$1c,$18,$00



Posted: Sat Jan 31, 2009 8:32 pm
by tokumaru
I can't see anything terribly wrong, but I also don't know what results you are seeing with this code. I noticed though that in the loadnametables routine, you load X with 1. For it to load the 1KB that makes up a full screen, it should be 4 (256 * 4 = 1024).

Also, you never set the scroll after drawing the tiles. Before enabling rendering, be sure to reset the scroll by writing 0 twice to $2005.

Oh, and what's the reason for that CLI instruction?

Posted: Sat Jan 31, 2009 10:30 pm
by GradualGames
Yes, I set X=1 because I wanted to see if I could even write just a single chunk of 256 tiles correctly. I originally had all my nontransparent tiles at the bottom of the nametable, to look like "the ground." I moved them to the top to see if I could properly write ANY tiles to the nametable. If however I load a tile # into a, and then manually write to 2007 (repeatedly), I have no problems whatsoever. It's so strange, because the exact same code (unless I made a mistake somewhere), produces a nice, neat, "ground" when assembled by P65. Maybe I should ditch NESASM and try dasm or another assembler.

Setting the scroll seemed to have no effect in this case. FCEUXD shows the scroll lines set at 0.

*edit* I just tried unrolling the loop. It turns out I can reproduce the odd behavior with the top row. I have 32 instances of tile 1 and tile 2 in the top of my nametable---yet after about 23 of them, it seems to "jump" into the next row (tiles 3 and 4 repeated). I'll keep looking into it but this is very strange to me, unless my cerebellum is lying to me when I've counted 32 tiles across in my name table.

Posted: Sun Feb 01, 2009 1:53 am
by blargg
Your code still isn't waiting for vblank before disabling the PPU, though that should only cause glitches for one frame. You wait for vblank after reset, but then clear memory, which takes over 9000 cycles, longer than vblank. After you load graphics, you then must set the scroll when you re-enable the PPU. And you should again wait for vblank before re-enabling, otherwise you'll get another one-frame glitch.

BTW, for longer code pastes like this, you might try pastey.net. It even does syntax highlighting for 6502 code!

Posted: Sun Feb 01, 2009 9:23 am
by GradualGames
Thanks for all the advice. It turned out my main problem was that NESASM only reads a certain amount of characters per line. My nametable was encoded as .db statements, and it was 32x30, just like the actual nametable. NESASM ignored the db's after about the 24th one, so the nametable came out all wonky. I suppose most people use incbin on .chr files, so this problem hasn't been encountered often.

I'll try pastey next time. Speaking of code highlighting, it'd be fun to find a highlighter for 6502 for use with ConTEXT.

Posted: Sun Feb 01, 2009 9:52 am
by Memblers
Yeah NESASM is just full of surprises.. It has a way of not really telling you when there's an assembly error.
ZomCoder wrote: I'll try pastey next time. Speaking of code highlighting, it'd be fun to find a highlighter for 6502 for use with ConTEXT.
I use ConTEXT also, here's the highlighter I use with it:
http://www.parodius.com/~memblers/nes/6502_Assembly.chl

Posted: Sun Feb 01, 2009 10:01 am
by GradualGames
Thanks for the link. What's your ConTEXT setup like? I have it set up to assemble .p65 and .asm files and then run the .nes in jnes, nestopia, and fceuxd with the f9, f10, and f11 keys, and capture the console output. It's really convenient!

I notice some of the highlighting looks strange in my .db directives. Some hex numbers are highlighted red, others black.

Posted: Sun Feb 01, 2009 10:11 am
by Memblers
The only feature from Context I'm really missing because I never tried to make it work, is error highlighting. But I get by just fine without that.

The .db highlighting I think always turns out red if it's starts with a number, black if with a hex letter. I'm not sure why, it never bothered me much.

My set up I ended up just having it run "n.bat" from the current directory with the F9 key. This is because all the steps involved with my ca65 setup, assemble, link, copy binary togther. F10 then calls another batch file that will upload it to my EPROM emulator or run it in an emulator (unless I put that in n.bat).