using System; namespace BizHawk.Emulation.Consoles.Sega { public partial class Genesis { private byte ReadByte(uint address) { return (byte) ReadB((int)address); } private ushort ReadWord(uint address) { return (ushort) ReadW((int)address); } private uint ReadLong(uint address) { return (uint) ReadL((int)address); } private void WriteByte(uint address, byte value) { WriteB((int)address, (sbyte)value); } private void WriteWord(uint address, ushort value) { WriteW((int)address, (short)value); } private void WriteLong(uint address, uint value) { WriteL((int)address, (int) value); } public sbyte ReadB(int address) { address &= 0x00FFFFFF; if (address < 0x400000) return (sbyte) RomData[address]; if (address >= 0xA10000 && address < 0xA1001F) return (sbyte) ReadIO((address >> 1) & 0x0F); if (address >= 0xE00000) return (sbyte) Ram[address & 0xFFFF]; if (address == 0xA11100) // Z80 BUS status { Console.WriteLine("QUERY z80 bus status. 68000 can access? " + (M68000HasZ80Bus && Z80Reset == false)); return (sbyte) (M68000HasZ80Bus && Z80Reset == false ? 0 : 1); } if ((address & 0xFF0000) == 0xA00000) { return (sbyte) ReadMemoryZ80((ushort) (address & 0x7FFF)); } if (address >= 0xC00004 && address < 0xC00008) { ushort value = VDP.ReadVdpControl(); if ((address & 1) == 0) // read MSB return (sbyte) (value >> 8); return (sbyte) value; // read LSB } Console.WriteLine("UNHANDLED READB {0:X6}", address); return 0x7D; } public short ReadW(int address) { address &= 0x00FFFFFF; int maskedAddr; if (address < 0x400000) return (short)((RomData[address] << 8) | RomData[address + 1]); if (address >= 0xE00000) // Work RAM { maskedAddr = address & 0xFFFF; return (short)((Ram[maskedAddr] << 8) | Ram[maskedAddr + 1]); } if (address >= 0xC00004 && address < 0xC00008) return (short) VDP.ReadVdpControl(); Console.WriteLine("UNHANDLED READW {0:X6}", address); return 0x7DCD; } public int ReadL(int address) { address &= 0x00FFFFFF; int maskedAddr; if (address < 0x400000) // Cartridge ROM return (RomData[address] << 24) | (RomData[address + 1] << 16) | (RomData[address + 2] << 8) | RomData[address + 3]; if (address >= 0xE00000) // Work RAM { maskedAddr = address & 0xFFFF; return (Ram[maskedAddr] << 24) | (Ram[maskedAddr + 1] << 16) | (Ram[maskedAddr + 2] << 8) | Ram[maskedAddr + 3]; } Console.WriteLine("UNHANDLED READL {0:X6}", address); return 0x7DCDCDCD; } public void WriteB(int address, sbyte value) { address &= 0x00FFFFFF; if (address >= 0xE00000) // Work RAM { Console.WriteLine("MEM[{0:X4}] change from {1:X2} to {2:X2}", address & 0xFFFF, Ram[address & 0xFFFF], value); Ram[address & 0xFFFF] = (byte)value; return; } if ((address & 0xFF0000) == 0xA00000) { WriteMemoryZ80((ushort)(address & 0x7FFF), (byte)value); return; } if (address == 0xA11100) { M68000HasZ80Bus = (value & 1) != 0; Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus); return; } if (address == 0xA11200) // Z80 RESET { Z80Reset = (value & 1) == 0; if (Z80Reset) SoundCPU.Reset(); Console.WriteLine("z80 reset: " + Z80Reset); return; } if (address >= 0xC00000) { // when writing to VDP in byte mode, the LSB is duplicated into the MSB switch (address & 0x1F) { case 0x00: case 0x02: VDP.WriteVdpData((ushort) (value | (value << 8))); return; case 0x04: case 0x06: VDP.WriteVdpControl((ushort) (value | (value << 8))); return; case 0x11: case 0x13: case 0x15: case 0x17: Console.WriteLine("!+!+!+ PSG WRITE => {0:X2}",value); PSG.WritePsgData((byte) value, SoundCPU.TotalExecutedCycles); return; } } Console.WriteLine("UNHANDLED WRITEB {0:X6}:{1:X2}", address, value); } public void WriteW(int address, short value) { address &= 0x00FFFFFF; if (address >= 0xE00000) // Work RAM { //Console.WriteLine("MEM[{0:X4}] change to {1:X4}", address & 0xFFFF, value); Ram[(address & 0xFFFF) + 0] = (byte)(value >> 8); Ram[(address & 0xFFFF) + 1] = (byte)value; return; } if (address >= 0xC00000) { switch (address & 0x1F) { case 0x00: case 0x02: VDP.WriteVdpData((ushort)value); return; case 0x04: case 0x06: VDP.WriteVdpControl((ushort)value); return; } } if (address == 0xA11100) // Z80 BUSREQ { M68000HasZ80Bus = (value & 0x100) != 0; Console.WriteLine("68000 has the z80 bus: " + M68000HasZ80Bus); return; } if (address == 0xA11200) // Z80 RESET { Z80Reset = (value & 0x100) == 0; if (Z80Reset) SoundCPU.Reset(); Console.WriteLine("z80 reset: " + Z80Reset); return; } Console.WriteLine("UNHANDLED WRITEW {0:X6}:{1:X4}", address, value); } public void WriteL(int address, int value) { address &= 0x00FFFFFF; if (address >= 0xE00000) // Work RAM { //Console.WriteLine("MEM[{0:X4}] change to {1:X8}", address & 0xFFFF, value); Ram[(address & 0xFFFF) + 0] = (byte)(value >> 24); Ram[(address & 0xFFFF) + 1] = (byte)(value >> 16); Ram[(address & 0xFFFF) + 2] = (byte)(value >> 8); Ram[(address & 0xFFFF) + 3] = (byte)value; return; } if (address >= 0xC00000) { WriteW(address, (short)(value >> 16)); WriteW(address, (short)value); return; } Console.WriteLine("UNHANDLED WRITEL {0:X6}:{1:X8}", address, value); } } }