Code: Select all
.inesprg 2 .ineschr 1 .inesmap 4 .inesmir 0 .code .bank 3 .org $E000 palettedata: .incbin "scroll\pal.bin" vblank: lda $2002 bpl vblank rts main: sei cld sta $e000 ldx #$01 stx $a000 ldx #$80 stx $a001 ldx #$ff txs jsr vblank inx stx $2000 stx $2001 lda #$00 clearzp: sta <$00, x inx bne clearzp ldy #$01 sty <$01 dey ldx #$07 clearwram: sta [$00], y iny bne clearwram inc <$01 dex bne clearwram lda $2002 lda #$3f sta $2006 stx $2006 ldy #$20 loadpal: lda palettedata, x sta $2007 inx dey bne loadpal jsr vblank lda #$28 sta $2006 sty $2006 ldx #$04 lda #$01 clearvram: sta $2007 iny bne clearvram dex bne clearvram jsr vblank lda #$20 sta $2006 sty $2006 ldx #$04 lda #$00 clearvram.b: sta $2007 iny bne clearvram.b dex bne clearvram.b jsr vblank lda #$2b sta $2006 lda #$00 sta $2006 lda #$10 ldx #$c0 clearvram.c: sta $2007 iny dex bne clearvram.c lda #$00 sta $8000 sta $8001 lda #$01 sta $8000 lda #$02 sta $8001 sta $8000 lda #$04 sta $8001 lda #$03 sta $8000 lda #$05 sta $8001 lda #$04 sta $8000 lda #$06 sta $8001 lda #$05 sta $8000 lda #$07 sta $8001 lda #$06 sta $8000 lda #$00 sta $8001 lda #$07 sta $8000 lda #$00 sta $8001 lda #$2 sta $4014 lda #%10001000 sta $2000 lda #%00001010 sta $2001 sta $e000 cli eternity: jmp eternity nmi: pha lda $2002 lda #$00 sta $2006 sta $2006 inc <$30 lda <$30 cmp #$c0 bcs reset finishnmi: lda $2002 lda #$00 sta $2005 lda <$30 sta $2005 lda #$bf sta $c000 sta $c001 sta $e001 pla rti reset: lda #$00 sta <$30 jmp finishnmi irq: sta $e000 pha tya pha ldy #$0f timer: dey bne timer lda $2002 lda #$00 sta $2005 bit $2002 lda #$0b sta $2006 lda #$00 sta $2006 pla tay pla rti .org $FFFA .dw nmi .dw main .dw irq .bank 4 .incbin "scroll\chr.bin"
This program works fine with Quietust's emulator, Nintendulator, LoopyNES, JNES, NNNesterJ, etc., but it does not work in FCEU or any of its derivatives, such as FCEUXD, that I have tried. This program uses the mapper MMC3 and does split-screen (vertical only) scrolling. When it finishes the beginning of the program, it writes to E000, which disables the IRQ counter, and then clears the interrupt-disable flag. When the NMI comes on, it does the scrolling, and then writes to C000, C001, and E001 the IRQ counter (thereby enabling it and starting the countdown). When the IRQ hits, it writes to E000 again to disable the IRQ counter, and then it does the graphics for the bottom part of the screen which do not scroll.
Now, when I ran a trace of this in Nintendulator, I saw the code work fine, and it went through the number of scanlines necessary before calling the IRQ. But when I ran a trace in FCEUXD, I find that as soon as the interrupt-disable flag is cleared, after every instruction an IRQ is called, despite my writes to E000. When the IRQ is finished, it goes for an instruction and calls the IRQ again. This of course, causes the display to be completely messed up. My question is, Why does FCEU and its derivatives seem to ignore my writes to E000 and call the IRQs anyway, when no other emulator seems to? I would greatly appreciate an answer to this question.