예제 #1
0
        public static void reset()
        {
            cycles = 0;

            if (coldreset)
            {
                GBRegs.reset();
                Flash.reset();
                EEProm.reset();
                GPU.reset();
                Memory.reset(filename);
            }

            CPU.reset();
            GPU_Timing.reset();
            Sound.reset();
            Joypad.set_reg();
            Timer.reset();
            DMA.reset();
            SoundDMA.reset();
            BusTiming.reset();
            gpio.reset();

            //Serial.reset();

            loading_state = false;
            coldreset     = false;

            on = true;
        }
예제 #2
0
        public static void write_dword(UInt32 address, UInt32 data)
        {
#if DEBUG
            writecnt32[(address >> 24) & 0xF]++;
            if (enable_debugout && address >= 0x04FFF600 & address < 0x04FFF700)
            {
                debug_out.Add((char)(data & 0xFF));
                debug_out.Add((char)((data >> 8) & 0xFF));
                debug_out.Add((char)((data >> 16) & 0xFF));
                debug_out.Add((char)((data >> 24) & 0xFF));
            }
            if (enable_debugout && address == 0x04FFF700)
            {
                int a = 5;
            }
#endif
            byte offset = (byte)(address & 3);
            address = address & 0xFFFFFFFC;
            uint adr;

            byte select = (byte)(address >> 24);
            switch (select)
            {
            case 2:
                adr                 = address & 0x03FFFF;
                WRAM_Large[adr]     = (byte)(data & 0xFF);
                WRAM_Large[adr + 1] = (byte)((data >> 8) & 0xFF);
                WRAM_Large[adr + 2] = (byte)((data >> 16) & 0xFF);
                WRAM_Large[adr + 3] = (byte)((data >> 24) & 0xFF);
                return;

            case 3:
                adr                 = address & 0x7FFF;
                WRAM_Small[adr]     = (byte)(data & 0xFF);
                WRAM_Small[adr + 1] = (byte)((data >> 8) & 0xFF);
                WRAM_Small[adr + 2] = (byte)((data >> 16) & 0xFF);
                WRAM_Small[adr + 3] = (byte)((data >> 24) & 0xFF);
                return;

            case 4:
                if (address < 0x04000400)
                {
                    adr = address & 0x3FF;

                    GBRegs.data[adr]     = (byte)(data & 0xFF);
                    GBRegs.data[adr + 1] = (byte)((data >> 8) & 0xFF);
                    GBRegs.data[adr + 2] = (byte)((data >> 16) & 0xFF);
                    GBRegs.data[adr + 3] = (byte)((data >> 24) & 0xFF);

                    write_gbreg(adr, data, true);
                    write_gbreg(adr + 2, data, true);
                }
                return;

            case 5:
                adr                 = address & 0x3FF;
                PaletteRAM[adr]     = (byte)(data & 0xFF);
                PaletteRAM[adr + 1] = (byte)((data >> 8) & 0xFF);
                PaletteRAM[adr + 2] = (byte)((data >> 16) & 0xFF);
                PaletteRAM[adr + 3] = (byte)((data >> 24) & 0xFF);
                return;

            case 6:
                adr = address & 0x1FFFF;
                if (GPU.videomode < 3 || ((address & 0x1C000) != 0x18000))
                {
                    if (adr > 0x17FFF)
                    {
                        adr -= 0x8000;
                    }
                    VRAM[adr]     = (byte)(data & 0xFF);
                    VRAM[adr + 1] = (byte)((data >> 8) & 0xFF);
                    VRAM[adr + 2] = (byte)((data >> 16) & 0xFF);
                    VRAM[adr + 3] = (byte)((data >> 24) & 0xFF);
                }
                return;

            case 7:
                adr             = address & 0x3FF;
                OAMRAM[adr]     = (byte)(data & 0xFF);
                OAMRAM[adr + 1] = (byte)((data >> 8) & 0xFF);
                OAMRAM[adr + 2] = (byte)((data >> 16) & 0xFF);
                OAMRAM[adr + 3] = (byte)((data >> 24) & 0xFF);
                return;

            case 0x8:
                if (gpio_enable)
                {
                    if (address >= 0x80000c4 && address <= 0x80000c8)
                    {
                        gpio_used = true;
                        gpio.gpioWrite(address, (ushort)data);
                    }
                }
                return;

            case 0xD:
                if (EEPROMEnabled)
                {
                    EEProm.write((byte)data);
                }
                return;

            case 0xE:
            case 0xF:
                if (!EEPROMEnabled | FlashEnabled | SramEnabled)
                {
                    SaveGameFunc(address + offset + blockcmd_lowerbits, (byte)data);
                }
                return;
            }
        }
예제 #3
0
        public static void write_byte(UInt32 address, byte data)
        {
#if DEBUG
            writecnt8[(address >> 24) & 0xF]++;
            if (enable_debugout && address >= 0x04FFF600 & address < 0x04FFF700)
            {
                debug_out.Add((char)data);
            }
            if (enable_debugout && address == 0x04FFF700)
            {
                int a = 5;
            }
#endif
            uint adr;
            byte select = (byte)(address >> 24);
            switch (select)
            {
            case 2: WRAM_Large[address & 0x03FFFF] = (byte)(data & 0xFF); return;

            case 3: WRAM_Small[address & 0x7FFF] = (byte)(data & 0xFF); return;

            case 4:
                if (address < 0x04000400)
                {
                    adr = address & 0x3FF;
                    GBRegs.data[adr] = data;
                    write_gbreg(adr & 0xFFFFFFFE, data, false);
                }
                return;

            // Writing 8bit Data to Video Memory
            // Video Memory(BG, OBJ, OAM, Palette) can be written to in 16bit and 32bit units only.Attempts to write 8bit data(by STRB opcode) won't work:
            // Writes to OBJ(6010000h - 6017FFFh)(or 6014000h - 6017FFFh in Bitmap mode) and to OAM(7000000h - 70003FFh) are ignored, the memory content remains unchanged.
            // Writes to BG(6000000h - 600FFFFh)(or 6000000h - 6013FFFh in Bitmap mode) and to Palette(5000000h - 50003FFh) are writing the new 8bit value to BOTH upper and lower 8bits of the addressed halfword, ie. "[addr AND NOT 1]=data*101h".

            case 5: PaletteRAM[address & 0x3FE] = data; PaletteRAM[(address & 0x3FE) + 1] = data; return;

            case 6:
                adr = address & 0x1FFFE;
                if ((GPU.videomode <= 2 && adr <= 0xFFFF) || GPU.videomode >= 3 && adr <= 0x013FFF)
                {
                    if (adr > 0x17FFF)
                    {
                        adr -= 0x8000;
                    }
                    VRAM[adr]     = data;
                    VRAM[adr + 1] = data;
                }
                return;

            case 7: return;     // no saving here!

            case 0xD:
                if (EEPROMEnabled)
                {
                    EEProm.write(data);
                }
                return;

            case 0xE:
            case 0xF:
                if (!EEPROMEnabled | FlashEnabled | SramEnabled)
                {
                    SaveGameFunc(address, data);
                }
                return;
            }
        }
예제 #4
0
        public static UInt32 read_dword(UInt32 address)
        {
#if DEBUG
            readcnt32[(address >> 24) & 0xF]++;
#endif
            unreadable = false;

            UInt32 value  = 0;
            byte   rotate = (byte)(address & 3);
            address = address & 0xFFFFFFFC;

            byte select = (byte)(address >> 24);
            switch (select)
            {
            case 0:
                if ((CPU.regs[15] >> 24) > 0)
                {
                    if (address < 0x4000)
                    {
                        value = BitConverter.ToUInt32(biosProtected, 0);
                    }
                    else
                    {
                        value = read_unreadable_dword();
                    }
                }
                else
                {
                    for (int i = 0; i < 4; i++)
                    {
                        biosProtected[i] = GBRom[((address + 8) & 0x3FFC) + i];
                    }
                    value = BitConverter.ToUInt32(GBRom, (int)address & 0x3FFC);
                }
                break;

            case 1: value = read_unreadable_dword(); break;

            case 2: value = BitConverter.ToUInt32(WRAM_Large, (int)address & 0x03FFFF); break;

            case 3: value = BitConverter.ToUInt32(WRAM_Small, (int)address & 0x7FFF); break;

            case 4:
                if (address < 0x04000400)
                {
                    value = (UInt16)read_word(address) | (read_word(address + 2) << 16);
                }
                else
                {
                    value = read_unreadable_dword();
                }
                break;

            case 5: value = BitConverter.ToUInt32(PaletteRAM, (int)address & 0x3FF); break;

            case 6:
                uint adr = address & 0x1FFFF;
                if (adr > 0x17FFF)
                {
                    adr -= 0x8000;
                }
                value = BitConverter.ToUInt32(VRAM, (int)adr);
                break;

            case 7: value = BitConverter.ToUInt32(OAMRAM, (int)address & 0x3FF); break;

            case 8:
            case 9:
            case 0xA:
            case 0xB:
            case 0xC:
                if (gpio_enable && gpio_used && address >= 0x80000c4 && address <= 0x80000c8)
                {
                    value = gpio.gpioRead(address);
                }
                else
                {
                    if ((address & 0x01FFFFFF) < GameRom_max)
                    {
                        value = BitConverter.ToUInt32(GameRom, (int)address & 0x01FFFFFF);
                    }
                    else
                    {
                        value = ((address / 2) & 0xFFFF) + ((((address / 2) + 1) & 0xFFFF) << 16);
                    }
                }
                break;

            case 0xD:
                if (EEPROMEnabled)
                {
                    value = (UInt32)EEProm.read();
                }
                break;

            case 0xE:
            case 0xF:
                if (FlashEnabled | SramEnabled)
                {
                    value = Flash.flashRead(address + rotate + blockcmd_lowerbits) * (UInt32)0x01010101;
                }
                else
                {
                    value = read_unreadable_dword();
                }
                break;

            default: value = read_unreadable_dword(); break;
            }

            lastreadvalue = value;

            if (rotate == 0)
            {
                return(value);
            }
            else
            {
                value = CPU.RotateRight(value, 8 * rotate);
            }

            return(value);
        }
예제 #5
0
        public static UInt32 read_word(UInt32 address)
        {
#if DEBUG
            readcnt16[(address >> 24) & 0xF]++;
#endif

            unreadable = false;

            UInt32 value  = 0;
            byte   rotate = (byte)(address & 1);
            address = address & 0xFFFFFFFE;
            uint adr;

            byte select = (byte)(address >> 24);
            switch (select)
            {
            case 0:
                if ((CPU.regs[15] >> 24) > 0)
                {
                    if (address < 0x4000)
                    {
                        value = BitConverter.ToUInt16(biosProtected, (int)address & 2);
                    }
                    else
                    {
                        value = read_unreadable_word();
                    }
                }
                else
                {
                    for (int i = 0; i < 4; i++)
                    {
                        biosProtected[i] = GBRom[((address + 8) & 0x3FFC) + i];
                    }
                    value = BitConverter.ToUInt16(GBRom, (int)address & 0x3FFE);
                }
                break;

            case 1: value = read_unreadable_word(); break;

            case 2: value = BitConverter.ToUInt16(WRAM_Large, (int)address & 0x03FFFF); break;

            case 3: value = BitConverter.ToUInt16(WRAM_Small, (int)address & 0x7FFF); break;

            case 4:
                if (address < 0x04000400)
                {
                    adr = address & 0x3FF;

                    if (adr == GBRegs.Sect_dma.DMA0CNT_L.address ||
                        adr == GBRegs.Sect_dma.DMA1CNT_L.address ||
                        adr == GBRegs.Sect_dma.DMA2CNT_L.address ||
                        adr == GBRegs.Sect_dma.DMA3CNT_L.address)
                    {
                        return(0);
                    }
                    else
                    {
                        UInt16 rwmask = BitConverter.ToUInt16(GBRegs.rwmask, (int)adr & 0x3FFE);

                        if (rwmask == 0)
                        {
                            value = read_unreadable_word();
                        }
                        else
                        {
                            prepare_read_gbreg(adr);
                            value  = BitConverter.ToUInt16(GBRegs.data, (int)adr);
                            value &= rwmask;
                        }
                    }
                }
                else
                {
                    value = read_unreadable_word();
                }
                break;

            case 5: value = BitConverter.ToUInt16(PaletteRAM, (int)address & 0x3FF); break;

            case 6:
                adr = address & 0x1FFFF;
                if (adr > 0x17FFF)
                {
                    adr -= 0x8000;
                }
                value = BitConverter.ToUInt16(VRAM, (int)adr);
                break;

            case 7: value = BitConverter.ToUInt16(OAMRAM, (int)address & 0x3FF); break;

            case 8:
            case 9:
            case 0xA:
            case 0xB:
            case 0xC:
                if (gpio_enable && gpio_used && address >= 0x80000c4 && address <= 0x80000c8)
                {
                    value = gpio.gpioRead(address);
                }
                else
                {
                    if ((address & 0x01FFFFFF) < GameRom_max)
                    {
                        value = BitConverter.ToUInt16(GameRom, (int)address & 0x01FFFFFF);
                    }
                    else
                    {
                        value = (address / 2) & 0xFFFF;
                    }
                }
                break;

            case 0xD:
                if (EEPROMEnabled)
                {
                    value = (UInt32)EEProm.read();
                }
                break;

            case 0xE:
            case 0xF:
                if (FlashEnabled | SramEnabled)
                {
                    value = Flash.flashRead(address + rotate) * (UInt32)0x0101;
                }
                else
                {
                    value = read_unreadable_word();
                }
                break;

            default: value = read_unreadable_word(); break;
            }

            lastreadvalue = value;

            if (rotate == 0)
            {
                return(value);
            }
            else
            {
                value = ((value & 0xFF) << 24) | (value >> 8);
            }

            return(value);
        }
예제 #6
0
        public static byte read_byte(UInt32 address)
        {
#if DEBUG
            readcnt8[(address >> 24) & 0xF]++;
#endif
            unreadable = false;
            uint adr;

            byte select = (byte)(address >> 24);
            switch (select)
            {
            case 0:
                if ((CPU.regs[15] >> 24) > 0)
                {
                    if (address < 0x4000)
                    {
                        return(biosProtected[address & 3]);
                    }
                    else
                    {
                        return(read_unreadable_byte(address & 1));
                    }
                }
                else
                {
                    for (int i = 0; i < 4; i++)
                    {
                        biosProtected[i] = GBRom[((address + 8) & 0x3FFC) + i];
                    }
                    return(GBRom[address & 0x3FFF]);
                }

            case 1: return(read_unreadable_byte(address & 1));

            case 2: return(WRAM_Large[address & 0x03FFFF]);

            case 3: return(WRAM_Small[address & 0x7FFF]);

            case 4:
                if (address < 0x04000400)
                {
                    adr = address & 0x3FF;
                    byte rwmask = GBRegs.rwmask[adr];

                    if (rwmask == 0)
                    {
                        return(read_unreadable_byte(address & 1));
                    }
                    else
                    {
                        prepare_read_gbreg(adr);
                        byte value = GBRegs.data[adr];
                        value &= rwmask;
                        return(value);
                    }
                }
                else
                {
                    return(read_unreadable_byte(address & 1));
                }

            case 5: return(PaletteRAM[address & 0x3FF]);

            case 6:
                adr = address & 0x1FFFF;
                if (adr > 0x17FFF)
                {
                    adr -= 0x8000;
                }
                return(VRAM[adr & 0x1FFFF]);

            case 7: return(OAMRAM[address & 0x3FF]);

            case 8:
            case 9:
            case 0xA:
            case 0xB:
            case 0xC:
                if ((address & 0x01FFFFFF) < GameRom_max)
                {
                    return(GameRom[address & 0x01FFFFFF]);
                }
                else
                {
                    if ((address & 1) == 0)
                    {
                        return((byte)(address / 2));
                    }
                    else
                    {
                        return((byte)((address >> 8) / 2));
                    }
                }

            case 0xD:
                if (EEPROMEnabled)
                {
                    return((byte)EEProm.read());
                }
                else
                {
                    return(read_unreadable_byte(address & 1));
                }

            case 0xE:
            case 0xF:
                if (has_tilt && address == 0x0E008200)
                {
                    return((byte)tiltx);
                }
                if (has_tilt && address == 0x0E008300)
                {
                    return((byte)(0x80 | ((tiltx >> 8) & 0xF)));
                }
                if (has_tilt && address == 0x0E008400)
                {
                    return((byte)tilty);
                }
                if (has_tilt && address == 0x0E008500)
                {
                    return((byte)((tilty >> 8) & 0xF));
                }

                if (FlashEnabled | SramEnabled)
                {
                    return(Flash.flashRead(address));
                }
                else
                {
                    return(read_unreadable_byte(address));
                }

            default: return(read_unreadable_byte(address & 1));
            }
        }