nesdev.com
http://forums.nesdev.com/

Problems with test ROMs
http://forums.nesdev.com/viewtopic.php?f=3&t=16713
Page 1 of 1

Author:  Donqustix [ Thu Nov 16, 2017 12:56 pm ]
Post subject:  Problems with test ROMs

My emulator supports all official instructions (instr_test-v5) and basics of VBL handling (ppu_vbl_nmi - single rom #1), but I have a problem with cpu_timing_test6 and branch_timing_tests test ROMs.

Do they use any APU length counter? Because when my emulator executes these ROMs, they are stuck in an infinite loop.

Author:  Zepper [ Thu Nov 16, 2017 1:05 pm ]
Post subject:  Re: Problems with test ROMs

Yes. In fact, they expect register $4017 to be functional.

Author:  Donqustix [ Fri Nov 17, 2017 8:04 am ]
Post subject:  Re: Problems with test ROMs

So, I've implemented some basics of the APU frame counter but it still doesn't work. Is it not enough for just running the tests?
Code:
        void write_frame_counter(unsigned v) noexcept
        {
            frame_counter_mode = FrameCounterMode(v >> 7);
            if ((inhibit_frame_irq = v & 0x40))
                mem_pointers.cpu->set_irq(false);
            delayed_frame_timer_reset = apu_clk1_is_high ? 4 : 3;
        }
        void clock_frame_counter_clock() noexcept
        {
            switch (frame_counter_mode)
            {
                case M4:
                    if (delayed_frame_timer_reset > 0 && --delayed_frame_timer_reset == 0)
                        frame_counter_clock = 0;
                    else
                        if (++frame_counter_clock == 2*14914 + 2) {
                            frame_counter_clock = 0;
                            if (!inhibit_frame_irq) {mem_pointers.cpu->set_irq(true);}
                        }
                    switch (frame_counter_clock)
                    {
                        case 2*14914:
                        case 2*14914 + 1:
                            if (!inhibit_frame_irq) mem_pointers.cpu->set_irq(true);
                            break;
                    }
                    break;
                case M5:
                    if (delayed_frame_timer_reset > 0 && --delayed_frame_timer_reset == 0)
                        frame_counter_clock = 0;
                    else
                        if (++frame_counter_clock == 2*18640 + 2)
                            frame_counter_clock = 0;
                    break;
            }
        }
        void tick() noexcept {apu_clk1_is_high = !apu_clk1_is_high; clock_frame_counter_clock();}


Or I should implement all APU registers and channels in order to run the tests?

Author:  Donqustix [ Sun Nov 19, 2017 5:15 am ]
Post subject:  Re: Problems with test ROMs

Hm. Now, I can't pass 3-nmi_and_irq.nes from cpu_interrupts_v2 and the last one from ppu_vbl_nmi (even_odd_timing). Does someone know, if APU works properly but not very accurate, can it cause my emulator to fail the nmi_and_irq test?

Author:  Donqustix [ Mon Nov 20, 2017 7:55 am ]
Post subject:  Re: Problems with test ROMs

My emulator has passed all tests :o (not including nmi_and_irq and ppu_sprite_hit).
I added the following lines into the write_mask function to pass 10-even_odd_timing:
Code:
            if ((mask ^ open_bus_data) & MASK_MASK_RENDERING_ENABLED)
            {
                if (scanline == 261 && clks == 339 && odd_frame)
                    clks = open_bus_data & MASK_MASK_RENDERING_ENABLED ? 338 : 340;
            }

Author:  Donqustix [ Sat Nov 25, 2017 9:18 am ]
Post subject:  Re: Problems with test ROMs

I don't understand something. In the second level of Battletoads, when I move the main character to the bottom of the screen, it becomes "immortal" because enemies always attack below the main character, despite his location.

I've found, the problem is the time of rising the sprite overflow flag. When the flag is set true immediately, it fixes Battletoads and breaks the third test of ppu_sprite_overflow (timing). When the setting of the flag is delayed by 1 PPU cycle, it breaks Battletoads and fixes ppu_sprite_overflow.

Code:
    switch (clks & 1)
    {
        case 1: oam_tmp = oam[oam_addr]; break;
        case 0:
        {
            const bool in_range = (scanline - oam_tmp < (ctrl & CTRL_MASK_SPRITE_SIZE ? 16 : 8));
            if (clks == 66) s0_next_scanline = in_range;
            if (!scan_oam_addr_overflow && !oam_addr_overflow)
                scan_oam[scan_oam_addr] = oam_tmp;
            else
                oam_tmp = scan_oam[scan_oam_addr];
            if (oam_copy > 0)
            {
                --oam_copy;
                if (!(++     oam_addr &= 0xFF))      oam_addr_overflow = true;
                if (!(++scan_oam_addr &= 0x1F)) scan_oam_addr_overflow = sprite_overflow_detection = true;
            }
            else if (in_range && !scan_oam_addr_overflow && !oam_addr_overflow)
            {
                oam_copy = 3;
                if (!(++     oam_addr &= 0xFF))      oam_addr_overflow = true;
                if (!(++scan_oam_addr &= 0x1F)) scan_oam_addr_overflow = sprite_overflow_detection = true;
            }
            else if (sprite_overflow_detection)
            {
                if (in_range && !oam_addr_overflow) {sprite_overflow = true; sprite_overflow_detection = false;}
                else
                {
                    const u16 temp = ((oam_addr + 4) & ~3) | ((oam_addr + 1) & 3); oam_addr = temp & 255;
                    if (temp & 256) oam_addr_overflow = true;
                }
            }
            else
            {
                const u16 temp = oam_addr + 4; oam_addr = temp & 0xFC;
                if (temp & 256) oam_addr_overflow = true;
            }
        break;
        }
    }

Page 1 of 1 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/