Mapper 58 and Game Star 68-in-1

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Mapper 58 and Game Star 68-in-1
by on (#178751)
I recently implemented mapper 58 in my own emulator, which seems fairly straightforward according to the specs at http://wiki.nesdev.com/w/index.php/INES_Mapper_058. I managed to get the Game Star 68-in-1 ROM working (CRC: 2BA377FC), except for the game Galaxin 00, Galaxin 01 etc., which for some reason is switching to the game selection menu. The PRG, CHR, Mirroring and PRG mode registers are all encoded in the lower byte of the address when written from $8000 upwards. I am aware that for the 32K PRG mode, the bank number has to be right-shifted so I don't think that's the problem. I'm beginning to wonder if it's a case of implementing a latch of some sort but I could not determine that from the specs.

Does anyone have any experience with this mapper? I can share code if that helps.

Thanks
Re: Mapper 58 and Game Star 68-in-1
by on (#178752)
Problems with Galaxian in pirate multis often happen when the menu is in the same PRG ROM bank as Galaxian, whose PRG ROM is only 8 KiB. (Every other commercial-era NES game I can think of has at least a 16 KiB PRG ROM.) Does the mapper have an 8K mode that you aren't enabling?
Re: Mapper 58 and Game Star 68-in-1
by on (#178762)
According to the wiki page, there's a 16k mode and a 32k mode, and that's it.
Re: Mapper 58 and Game Star 68-in-1
by on (#178764)
The multicart seems to work correctly in FCEUX...
Re: Mapper 58 and Game Star 68-in-1
by on (#178766)
The wiki is a little vague about the program mode. Maybe you misinterpreted the information there.

In program mode 1, the program bank comes from the lower 3 bits of the address, not the value written to that address. And, the bank value is used twice; both 16K blocks reference the same bank (there are 8 of them).

In program mode 0, only bits 2 and 1 of the address are relevant; bit 0 is ignored. It is used to establish a 32K bank (there are only 4 of them).
Re: Mapper 58 and Game Star 68-in-1
by on (#178818)
I think my mapper 58 implementation is already in line with all your suggestions. Here's the relevant code (C#) for reading and writing to the mapper:

Code:
        public override byte this[ushort address]
        {
            get
            {
                if (address < 0x2000)
                {
                    return Cartridge.CharacterRom[characterBank * 0x2000 + address];
                }
                else if (address >= 0x8000)
                {
                    int bankSize = programMode == 0 ? 0x8000 : 0x4000;
                    int bankOffset = address % bankSize;
                    int selectedBank = programMode == 0 ? (programBank >> 1) : programBank;
                    int flataddress = selectedBank * bankSize + bankOffset;
                    return Cartridge.ProgramRom[flataddress];
                }
                else
                {
                    return base[address]; // default - returns open bus
                }
            }

            set
            {
                if (address >= 0x8000)
                {
                    // $8000 - FFFF:  A~[.... .... MOCC CPPP]
                    // P = PRG page select
                    // C = CHR page select (8k @ $0000)
                    // O = PRG Mode
                    // M = Mirroring(0 = Vert, 1 = Horz)
                    programBank = address & Bin.B00000111;
                    characterBank = (address >> 3) & Bin.B00000111;
                    programMode = (address >> 6) & Bin.Bit0;
                    MirrorMode = (address & Bin.Bit7) != 0 ? MirrorMode.Horizontal : MirrorMode.Vertical;

                    Debug.WriteLine(" ........MOCCCPPP");
                    Debug.WriteLine(Bin.Format(address));
                }
                else
                {
                    base[address] = value; // default - do nothing
                }
            }
        }


Note: Bin.B00000111 is just a byte constant of value 0x07 - they are convenient mask values that I find handy. Similarly Bin.Bit0, Bin.Bit1, bin.Bit2 etc. correspond to values 0x01, 0x02, 0x04 etc.
Re: Mapper 58 and Game Star 68-in-1
by on (#178837)
Since I don't see anything obviously wrong with your code, and Galaxian usually shares a bank with the menu, I have a hunch that whatever problem you're having, it's not in your mapper implementation.


Tangential unasked-for not-so-humble-opinion: I'm not clear that thinking in terms of "remainder" and "multiplication" is the best design decision. In late-80s electronics, bit shifts, multiplexers, and boolean logic are cheap and it might be more useful to represent it that way, rather than thinking in terms of ordinary math on a file offset.