can write nametable hard coded to $2007, but looping=problem
Moderator: Moderators
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
can write nametable hard coded to $2007, but looping=problem
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.
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.
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).
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
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
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?
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?
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
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.
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.
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!
BTW, for longer code pastes like this, you might try pastey.net. It even does syntax highlighting for 6502 code!
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
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.
I'll try pastey next time. Speaking of code highlighting, it'd be fun to find a highlighter for 6502 for use with ConTEXT.
Yeah NESASM is just full of surprises.. It has a way of not really telling you when there's an assembly error.
http://www.parodius.com/~memblers/nes/6502_Assembly.chl
I use ConTEXT also, here's the highlighter I use with it: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.
http://www.parodius.com/~memblers/nes/6502_Assembly.chl
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
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.
I notice some of the highlighting looks strange in my .db directives. Some hex numbers are highlighted red, others black.
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).
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).