Page 1 of 3

Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 8:17 am
by miguelfsp
Hello guys,

After lots of work I now seem to be kind of stuck in trying to emulate Super Mario Bros. The problem is that I'm stuck at the menu. I can never enter the real game, it is not responding to key presses! Now that I implemented sprite0 hit and scrolling, after waiting a while Mario starts "moving by himself", like it should, but I can never really start a game to play by pressing start!

I pass all the 11 Nestress first PPU tests. When I run a sprite0 hit basic test, it only fails with code "4" (4) Should miss when background rendering is off), but so fails JNes emulator... And it perfectly runs SMB1, so this shouldn't be related.

Also, pacman's screen has a yellow "something" in the top-left part of the screen (please check out the screenshot). I don't know if there's some odd bug in scrolling/sprite0 but I just can't figure it out... Do you guys have any suggestions or something like that? I'm really stuck

*Edit: All right, this pacman "bug" is ok, I was using JNes and it's JNes fault...*

Thanks a lot for your patiente guys!

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 9:05 am
by thefox
miguelfsp wrote:Also, pacman's screen has a yellow "something" in the top-left part of the screen (please check out the screenshot). I don't know if there's some odd bug in scrolling/sprite0 but I just can't figure it out... Do you guys have any suggestions or something like that? I'm really stuck
When you encounter something like that, the first thing you should try is to see if other "good" emulators behave the same way (in which case 99.995% of the time that behavior is correct). In this case the answer is yes.

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 9:46 am
by miguelfsp
Oh, you're right, sorry! I was convinced that it was wrong. Just tried with nintendulator and works the same way... I guess my emulator is better than jnes then :)

But still can't figure out the SMB1 messed up menu... It simply does not respond to keys (and yes, the main standart controller is implemented and works fine in all the other games). You got any suggestions or something? :/

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 10:58 am
by blargg
What are you returning when the game reads more than 8 bits from the controller?

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 11:05 am
by Drag
In most cases, if there's some garbage in the top left corner of the screen (usually hidden because NTSC doesn't show the top 8 to 16 scanlines), it's because the game initializes the sprite OAM with all 0s, which gets interpreted as "put sprite tile 0 at x=0 y=0".

(The correct way to "disable" a sprite is to set its Y position to F0 or beyond.)

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 11:23 am
by miguelfsp
I'm returning "1". Is this correct? I just made some experiments (returning 0, etc...) and still doesn't work.
Reading address 0x4016 (controller 2 at 0x4017 is "unconnected").

Code: Select all

        private int n = 0;

        public byte Read()
        {
            byte retval;

            retval = (n < 8) ? Convert.ToByte(state[n]) : (byte)1;

            n++;

            return retval;
        }
So I don't know... maybe the issue is somewhere else? NesStress menu didn't work, till I implemented sprite hit 0 detection and scrolling. Btw an ODD thing: I fully pass nestest BUT when I test the CPU with NESTRESS, in the last "page" of CPU tests.... my emulation crashes at some point (in STACK ADDR) it never writes anything, because it tries to read from address "$5569", which raises an exception... I don't understand whats wrong here with the CPU AND I don't think that the problems are connected because this issue only happens in Nestress, but maybe you can associate both problems, I don't know.

Thanks Drag, but this time it seems that pacman is really programmed like that (don't ask me why...). I was comparing with JNes and it seems that JNes is wrong.

Thank you for your anwsers.

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 11:38 am
by Alegend45
Your controllers aren't implemented properly. That's all there is to it.

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 11:41 am
by miguelfsp
Well... I beleive you... But what is wrong?

http://wiki.nesdev.com/w/index.php/Standard_controller

When reading from $4016, in the first 8 bytes I return the state of each key, then I return 1... Till I have a write in $4016 (=0), where I set n = 0 and in the next read everything starts again. Isn't it supposed to be like this?

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 1:17 pm
by Alegend45
Your writes to $4016 are wrong. You have to write 1 before writing 0.

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 1:18 pm
by miguelfsp
I did!

Code: Select all

        public void Write(byte value)
        {
            if ((value & 1) == 0)
            {
                latch = false;
                n = 0;
            }
            else
                latch = true;
        }

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 1:21 pm
by Alegend45
It has to write 1 before 0.

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 1:37 pm
by miguelfsp
Still not working... :( I guess something really messed up is going on...

Code: Select all

        bool one = false;

        public void Write(byte value)
        {
            if ((value & 1) == 0)
            {
                if (one)
                {
                    latch = false;
                    n = 0;
                    one = false;
                }
            }
            else
            {
                latch = true;
                one = true;
            }
        }

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 1:42 pm
by koitsu
miguelfsp wrote:Still not working... :( I guess something really messed up is going on...
I don't mean to dishearten you, but comments like "I guess something really messed up is going on" when you're the author of the emulator do not give the impression that you necessarily understand the code you're writing. :-/

Maybe step back and explain using pseudo-code how you're doing doing your controller stuff, from the main part of your emulator all the way down to the register emulation? More often than not you can't just paste some arbitrary C/C++ code into a forum and have everyone understand how it's being used -- "here's a function, what's wrong with it" "Um, I dunno, why don't you tell us how you're using this function?" :-)

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 1:56 pm
by miguelfsp
koitsu, thing is, I don't know if it's not working because of the controller - because all the other games that I tested work great (Donkey Kong, Mario Bros, nestest menu, Nestress menu, etc...), only SMB doesn't work.

When the CPU tries to read from $4016, I call the read function in the controller, when it tries to write to $4016, I call the write function.

When a key is up/down, I change the state[8] array to reflect the state of the key press. When I read from $4016, I sequencially read that array, till I read 8 bytes. Then it will always return "1". To "restart" and to return the key values again, you must write 1 to the controller, and then 0. Thats what the write function does.

$4017 second controller IS NOT implemented

I say there's something messed up going on, because of what I wrote about Nestress in my reply to blarggs a few posts above (please check it and tell me what you think :/), so perhaps, its possible that the issue is not exacly on the controller itself, but maybe, possible some other completely remote thing is affecting the correct behaviour of the game itself being emulator.

Quoting myself:
So I don't know... maybe the issue is somewhere else? NesStress menu didn't work, till I implemented sprite hit 0 detection and scrolling. Btw an ODD thing: I fully pass nestest BUT when I test the CPU with NESTRESS, in the last "page" of CPU tests.... my emulation crashes at some point (in STACK ADDR) it never writes anything, because it tries to read from address "$5569", which raises an exception... I don't understand whats wrong here with the CPU AND I don't think that the problems are connected because this issue only happens in Nestress, but maybe you can associate both problems, I don't know.
Thank you very much for your anwsers!

Re: Super Mario Bros 1 Menu not working

Posted: Sun Jan 27, 2013 2:02 pm
by 3gengames
Mae sure all bits return 0 like they would if those data bits wouldn't be used. It OR's bits 0 and 1 together.

From doppleganger's disassembly:

Code: Select all

;$00 - temp joypad bit

ReadJoypads: 
              lda #$01               ;reset and clear strobe of joypad ports
              sta JOYPAD_PORT
              lsr
              tax                    ;start with joypad 1's port
              sta JOYPAD_PORT
              jsr ReadPortBits
              inx                    ;increment for joypad 2's port
ReadPortBits: ldy #$08
PortLoop:     pha                    ;push previous bit onto stack
              lda JOYPAD_PORT,x      ;read current bit on joypad port
              sta $00                ;check d1 and d0 of port output
              lsr                    ;this is necessary on the old
              ora $00                ;famicom systems in japan
              lsr
              pla                    ;read bits from stack
              rol                    ;rotate bit from carry flag
              dey
              bne PortLoop           ;count down bits left
              sta SavedJoypadBits,x  ;save controller status here always
              pha
              and #%00110000         ;check for select or start
              and JoypadBitMask,x    ;if neither saved state nor current state
              beq Save8Bits          ;have any of these two set, branch
              pla
              and #%11001111         ;otherwise store without select
              sta SavedJoypadBits,x  ;or start bits and leave
              rts
Save8Bits:    pla
              sta JoypadBitMask,x    ;save with all bits in another place and leave
              rts