In my experiments last night I tried to update the attribute table for a single screen with 64 random values.
Boy was I in for a surprise - 64 random values within the vblank is out of the question for the NES. Glitch city. I was able to make a for loop in C that wrote 54 immediate values without glitching the screen. However, by my calculations I should have been able to do something in the area of 80 values. If there are 113.667 CPU cycles per scanline and 20 scanlines in the vblank, and an itteration of my loop was around 27 cycles (I counted the CA65 output's cycles) that's what it works out to (working very roughly here - my math habits are often fuzzy.) But that's well more than 54 iterations. What's going on here? Assuming I counted the instruction timings correctly.
Here's my setup: I do everything in the NMI - and the very first thing is to call the main loop routine, therefore anything done there first should be within vblank. And here is the asm of the main routine:
Just curious here. If 6502's listed timings are different on the NES for some reason that would be good to know.
Boy was I in for a surprise - 64 random values within the vblank is out of the question for the NES. Glitch city. I was able to make a for loop in C that wrote 54 immediate values without glitching the screen. However, by my calculations I should have been able to do something in the area of 80 values. If there are 113.667 CPU cycles per scanline and 20 scanlines in the vblank, and an itteration of my loop was around 27 cycles (I counted the CA65 output's cycles) that's what it works out to (working very roughly here - my math habits are often fuzzy.) But that's well more than 54 iterations. What's going on here? Assuming I counted the instruction timings correctly.
Here's my setup: I do everything in the NMI - and the very first thing is to call the main loop routine, therefore anything done there first should be within vblank. And here is the asm of the main routine:
Code:
.segment "CODE"
.proc _main: near
.dbg func, "main", "00", extern, "_main"
.segment "CODE"
;
; poke( PPU_CTRL, 0x90 );
;
.dbg line, "game.c", 57
lda #$90
sta $2000
;
; vram_adr( 0x23c0 );
;
.dbg line, "game.c", 58
ldx #$23
lda #$C0
jsr _vram_adr
;
; for ( i=0; i != 50; i++ ) {
;
.dbg line, "game.c", 59
lda #$00
L003E: sta _i
cmp #$32
beq L002F
;
; poke( PPU_DATA, 1 );
;
.dbg line, "game.c", 60
lda #$01
sta $2007
;
; for ( i=0; i != 50; i++ ) {
;
.dbg line, "game.c", 59
lda _i
clc
adc #$01
jmp L003E
;
; j++;
;
.dbg line, "game.c", 62
L002F: lda _j
clc
adc #$01
sta _j
;
; }
;
.dbg line, "game.c", 67
rts
.dbg line
.proc _main: near
.dbg func, "main", "00", extern, "_main"
.segment "CODE"
;
; poke( PPU_CTRL, 0x90 );
;
.dbg line, "game.c", 57
lda #$90
sta $2000
;
; vram_adr( 0x23c0 );
;
.dbg line, "game.c", 58
ldx #$23
lda #$C0
jsr _vram_adr
;
; for ( i=0; i != 50; i++ ) {
;
.dbg line, "game.c", 59
lda #$00
L003E: sta _i
cmp #$32
beq L002F
;
; poke( PPU_DATA, 1 );
;
.dbg line, "game.c", 60
lda #$01
sta $2007
;
; for ( i=0; i != 50; i++ ) {
;
.dbg line, "game.c", 59
lda _i
clc
adc #$01
jmp L003E
;
; j++;
;
.dbg line, "game.c", 62
L002F: lda _j
clc
adc #$01
sta _j
;
; }
;
.dbg line, "game.c", 67
rts
.dbg line
Just curious here. If 6502's listed timings are different on the NES for some reason that would be good to know.