Example #1
0
        public static int rb(int addr)
        {
            switch (addr & 0xF000)
            {
            // ROM bank 0
            case 0x0000:
                if (MMU._inbios)
                {
                    if (addr < 0x0100)
                    {
                        return(MMU._bios[addr]);
                    }
                    else if (Z80._r.pc == 0x0100)
                    {
                        MMU._inbios = false;
                        LOG.@out("MMU", "Leaving BIOS.");
                        return(rb(addr));
                    }
                }
                else
                {
                    return(MMU._rom[addr]);
                }
                break;

            case 0x1000:
            case 0x2000:
            case 0x3000:
                return(MMU._rom[addr]);

            // ROM bank 1
            case 0x4000:
            case 0x5000:
            case 0x6000:
            case 0x7000:
                return(MMU._rom[MMU._romoffs + (addr & 0x3FFF)]);

            // VRAM
            case 0x8000:
            case 0x9000:
                return(GPU._vram[addr & 0x1FFF]);

            // External RAM
            case 0xA000:
            case 0xB000:
                return(MMU._eram[MMU._ramoffs + (addr & 0x1FFF)]);

            // Work RAM and echo
            case 0xC000:
            case 0xD000:
            case 0xE000:
                return(MMU._wram[addr & 0x1FFF]);

            // Everything else
            case 0xF000:
                switch (addr & 0x0F00)
                {
                // Echo RAM
                case 0x000:
                case 0x100:
                case 0x200:
                case 0x300:
                case 0x400:
                case 0x500:
                case 0x600:
                case 0x700:
                case 0x800:
                case 0x900:
                case 0xA00:
                case 0xB00:
                case 0xC00:
                case 0xD00:
                    return(MMU._wram[addr & 0x1FFF]);

                // OAM
                case 0xE00:
                    return(((addr & 0xFF) < 0xA0) ? GPU._oam[addr & 0xFF] : 0);

                // Zeropage RAM, I/O, interrupts
                case 0xF00:
                    if (addr == 0xFFFF)
                    {
                        return(MMU._ie);
                    }
                    else if (addr > 0xFF7F)
                    {
                        return(MMU._zram[addr & 0x7F]);
                    }
                    else
                    {
                        switch (addr & 0xF0)
                        {
                        case 0x00:
                            switch (addr & 0xF)
                            {
                            case 0: return(KEY.rb());                   // JOYP

                            case 4:
                            case 5:
                            case 6:
                            case 7:
                                return(TIMER.rb(addr));

                            case 15: return(MMU._if);                   // Interrupt flags

                            default: return(0);
                            }

                        case 0x10:
                        case 0x20:
                        case 0x30:
                            return(0);

                        case 0x40:
                        case 0x50:
                        case 0x60:
                        case 0x70:
                            return(GPU.rb(addr));
                        }
                    }

                    break;
                }

                break;
            }
            throw new InvalidOperationException($"Unable to read address {addr}: Out of range.");
        }
Example #2
0
 public static void Reset()
 {
     LOG.reset(); GPU.reset(); MMU.reset(); Z80.reset(); KEY.reset(); TIMER.reset();
     Z80._r.pc = 0x100; MMU._inbios = true; Z80._r.sp = 0xFFFE; Z80._r.h = 0x01; Z80._r.l = 0x4D;
     Z80._r.c  = 0x13; Z80._r.e = 0xD8; Z80._r.a = 1;
 }
Example #3
0
        public static void reset()
        {
            GPU._vram = new int[8192];
            GPU._oam  = new int[160];

            for (int i = 0; i < 4; i++)
            {
                GPU._palette.bg[i]   = 255;
                GPU._palette.obj0[i] = 255;
                GPU._palette.obj1[i] = 255;
            }

            GPU._tilemap = new int[512, 8, 8];

            LOG.@out("GPU", "Initialising screen.");

            GPU._canvas = new int[160, 144];
            for (int i = 0; i < GPU._scrn.data.Length; i++)
            {
                GPU._scrn.data[i] = 255;
            }

            CopyScrnToCanvas();

            GPU._curline    = 0;
            GPU._curscan    = 0;
            GPU._linemode   = 2;
            GPU._modeclocks = 0;
            GPU._yscrl      = 0;
            GPU._xscrl      = 0;
            GPU._raster     = 0;
            GPU._ints       = 0;

            GPU._lcdon = 0;
            GPU._bgon  = 0;
            GPU._objon = 0;
            GPU._winon = 0;

            GPU._objsize = 0;
            GPU._scanrow = new int[160];

            for (int i = 0; i < 40; i++)
            {
                GPU._objdata[i] = new ObjData
                {
                    y       = -16,
                    x       = -8,
                    tile    = 0,
                    palette = 0,
                    yflip   = 0,
                    xflip   = 0,
                    prio    = 0,
                    num     = i
                };
            }

            // Set to values expected by BIOS, to start
            GPU._bgtilebase  = 0x0000;
            GPU._bgmapbase   = 0x1800;
            GPU._wintilebase = 0x1800; // TODO: doesn't seem to be used anywhere?

            LOG.@out("GPU", "Reset.");
        }