Serious Issue With FCEU and Its Derivatives (e.g. FCEUXD)

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Serious Issue With FCEU and Its Derivatives (e.g. FCEUXD)
by on (#2819)
Here is the source code to a program I wrote for the NES. Note that it is written to be assembled using NESASM:

Code:
   .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"


You can download the program here:

http://www.freewebs.com/beneficii/scroll.nes

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.

Thanks. :)

by on (#2820)
Ah, I see the problem now (after having patched my emulator to fix another issue) - you never disabled Frame IRQs (by writing #$40, #$80, or #$C0 to $4017), so THOSE are the ones messing up your display (and being mistaken for MMC3 IRQs).

by on (#2823)
Another minor note in your init code: Don't touch $2003-$2007 until you've got two vblanks from $2002. Fix: move the second call to vblank up to just below the clearwram loop.

by on (#2826)
OK! Thanks you guys! Quietust, I hope you've implemented that. ^_^

In fact, I think this program will serve as a good example of split-screen scrolling. I do timing and everything. Let me do a little cleaning up of it, then I'll post a good copy of it on-site for whoever wants to try split-screen scrolling on the MMC3. ^_^

EDIT: It works on FCEU now, btw. ^_^

by on (#2828)
It's much like the SMB3 intro. :)