It is currently Thu Dec 14, 2017 1:43 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Problems with test ROMs
PostPosted: Thu Nov 16, 2017 12:56 pm 
Offline

Joined: Fri Jul 21, 2017 2:29 am
Posts: 8
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.

_________________
emugaboy - uncomplicated gameboy emulator
noexcept nes emulator


Last edited by Donqustix on Thu Nov 16, 2017 1:09 pm, edited 2 times in total.

Top
 Profile  
 
PostPosted: Thu Nov 16, 2017 1:05 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
Yes. In fact, they expect register $4017 to be functional.


Top
 Profile  
 
PostPosted: Fri Nov 17, 2017 8:04 am 
Offline

Joined: Fri Jul 21, 2017 2:29 am
Posts: 8
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?

_________________
emugaboy - uncomplicated gameboy emulator
noexcept nes emulator


Top
 Profile  
 
PostPosted: Sun Nov 19, 2017 5:15 am 
Offline

Joined: Fri Jul 21, 2017 2:29 am
Posts: 8
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?

_________________
emugaboy - uncomplicated gameboy emulator
noexcept nes emulator


Top
 Profile  
 
PostPosted: Mon Nov 20, 2017 7:55 am 
Offline

Joined: Fri Jul 21, 2017 2:29 am
Posts: 8
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;
            }

_________________
emugaboy - uncomplicated gameboy emulator
noexcept nes emulator


Top
 Profile  
 
PostPosted: Sat Nov 25, 2017 9:18 am 
Offline

Joined: Fri Jul 21, 2017 2:29 am
Posts: 8
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;
        }
    }

_________________
emugaboy - uncomplicated gameboy emulator
noexcept nes emulator


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: krzysiobal and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group