public override void BusWrite(object sender, ushort address, byte value) { int linearAddress = 0; bool isRam = false; switch (address & 0xC000) { case 0x0000: if (BootMode) { return; } linearAddress = address & 0x3FFF; isRam = false; break; case 0x4000: linearAddress = (address & 0x3FFF) | bank4000; isRam = Bank4000IsRam; break; case 0x8000: if (address < lowerPageAlwaysPresentLimit && memoryMapMode == 0) { isRam = true; linearAddress = (address & 0x3FFF) | 0x4000; break; } linearAddress = (address & 0x3FFF) | bank8000; isRam = Bank8000IsRam; break; case 0xC000: if (address >= upperPageAlawayPresentLimit && memoryMapMode == 0) { isRam = true; linearAddress = (address & 0x3FFF); break; } linearAddress = (address & 0x3FFF) | bankC000; isRam = BankC000IsRam; break; } Breakpoint bp = new Breakpoint() { Address = (ushort)(linearAddress & 0x3FFF), IsRam = isRam, Page = linearAddress >> 14, Type = MemoryBreakpointType.Write }; if (haveWriteBps && IsWriteBreakpoint(bp)) { Cpu.BreakExecution(); } if (isRam) { Ram.WriteByte(sender, linearAddress & 0x3FFFF, value); } else { if (!FlashWriteEnable) { return; } int highBits = ((1 << flashType) - 1) << 20; if ((linearAddress & 0xF00000) == highBits) { highBits = linearAddress & 0xFFFFF; if (highBits >= 0xB0000 && highBits < 0xC000 || highBits >= 0xFC000) { return; } } Flash.WriteByte(sender, linearAddress, value); } }
/* * 20.02 * */ // Value Boot Cert. Privileged Immutable // 0 3F 3E 2C-2F, 3C-3F 2C-2F, 3F // 1 7F 7E 6C-6F, 7C-7F 6C-6F, 7F // 2 FF FE EC-EF, FC-FF EC-EF, FF public override byte BusRead(object sender, ushort address) { int linearAddress = 0; bool isRam = false; // Compute linear address in RAM or flash switch (address & 0xC000) { case 0x0000: /* * if (BootMode) * return Flash.ReadByte(sender, address | 0xFFC000); * else * return Flash.ReadByte(sender, address);*/ isRam = false; if (BootMode) { linearAddress = address | Flash.BootSector; } else { linearAddress = address; } break; case 0x4000: BootMode = false; linearAddress = (address & 0x3FFF) | bank4000; isRam = Bank4000IsRam; break; case 0x8000: if (address < lowerPageAlwaysPresentLimit && memoryMapMode == 0) { isRam = true; linearAddress = (address & 0x3FFF) | 0x4000; break; } if (memoryMapMode == 1) { BootMode = false; } linearAddress = (address & 0x3FFF) | bank8000; isRam = Bank8000IsRam; break; case 0xC000: if (address >= upperPageAlawayPresentLimit && memoryMapMode == 0) { isRam = true; linearAddress = (address & 0x3FFF); break; } linearAddress = (address & 0x3FFF) | bankC000; isRam = BankC000IsRam; break; } Breakpoint bp = new Breakpoint() { Address = (ushort)(linearAddress & 0x3FFF), IsRam = isRam, Page = linearAddress >> 14, Type = Cpu.M1 ? MemoryBreakpointType.Execution : MemoryBreakpointType.Read }; if (Cpu.M1 && IsExecutionBreakpoint(bp)) { Cpu.BreakExecution(); } else if (haveReadBps && IsReadBreakpoint(bp)) { Cpu.BreakExecution(); } if (isRam) { // Check execution permissions: address must be within allowed limits, masked by RAM chip size if (Cpu.M1 && sender is Z80Cpu) { if ((linearAddress & ramTypeMask) < ramLowerLimit || (linearAddress & ramTypeMask) >= ramUpperLimit) { Master.Reset(); } } return(Ram.ReadByte(sender, linearAddress & 0x3FFFF)); } else { // Check execution permissions: address must be within allowed limits if (Cpu.M1 && sender is Z80Cpu) { if ((linearAddress & flashTypeMask) >= flashLowerLimit && (linearAddress & flashTypeMask) < flashUpperLimit) { // . . . unless it's on a privileged page, in which case, execution is always allowed if (!((((linearAddress >> 14) & 0xF) >= 0xC) && (((linearAddress >> 18) & 0x2) >= 2) && ((linearAddress >> 20) == (1 << flashType) - 1))) { Master.Reset(); } } } // Check for censorship int highBits = ((1 << flashType) - 1) << 20; if ((linearAddress & 0xF00000) == highBits && !FlashWriteEnable) { highBits = linearAddress & 0xFFFFF; if (highBits >= 0xF8000 && highBits < 0xFC000) { return(0xFF); } } return(Flash.ReadByte(sender, linearAddress)); } }