static public void OptReset() { Z80.Reset(); CRTC.Reset(); PPI.Reset(); UPD.Reset(); VGA.Reset(); }
public Form1() { InitializeComponent(); Show(); desasm.Init(); VGA.DecodeurAdresse = 0; // VGA.ROMSUP_OFF; Z80.Init(); pictureBox1.Image = VGA.Init(pictureBox1.Width, pictureBox1.Height); PPI.Init(); UPD.Init(); CRTC.Init(); Keyboard.OptReset(); int nbCycles = 0; while (!finMain) { int cycle = Z80.ExecInstr(); bool DoResync = CRTC.CycleCRTC(cycle); UPD.Cycle(cycle); nbCycles += cycle; if (debugMode.Checked) { while (!doExec && debugMode.Checked) { DoRefresh(); } doExec = false; } else { if ((DoResync && nbCycles > 1000) || nbCycles > 100000) { DoRefresh(); nbCycles = 0; } } } }
static public void Load(string fileName) { BinaryReader br = new BinaryReader(new FileStream(fileName, FileMode.Open)); string id = System.Text.Encoding.UTF8.GetString(br.ReadBytes(0x10)); byte Version = br.ReadByte(); if (id.Substring(0, 8) == "MV - SNA") { Z80.AF.Word = br.ReadUInt16(); Z80.BC.Word = br.ReadUInt16(); Z80.DE.Word = br.ReadUInt16(); Z80.HL.Word = br.ReadUInt16(); Z80.IR.Word = br.ReadUInt16(); Z80.IFF1 = br.ReadByte(); Z80.IFF2 = br.ReadByte(); Z80.IX.Word = br.ReadUInt16(); Z80.IY.Word = br.ReadUInt16(); Z80.SP.Word = br.ReadUInt16(); Z80.PC.Word = br.ReadUInt16(); Z80.InterruptMode = br.ReadByte(); Z80._AF.Word = br.ReadUInt16(); Z80._BC.Word = br.ReadUInt16(); Z80._DE.Word = br.ReadUInt16(); Z80._HL.Word = br.ReadUInt16(); byte InkReg = br.ReadByte(); for (int i = 0; i < 17; i++) { byte val = br.ReadByte(); VGA.Write(i); VGA.Write(0x40 | (val & 0x1F)); VGA.SyncColor(); } VGA.Write(InkReg); VGA.Write(0x80 | br.ReadByte()); VGA.Write(0xC0 | (br.ReadByte() & 7)); byte CrtcIndex = br.ReadByte(); for (int i = 0; i < 18; i++) { byte val = br.ReadByte(); CRTC.Write(0, i); CRTC.Write(0x100, val); } CRTC.Write(0, CrtcIndex); VGA.NumRomExt = br.ReadByte(); PPI.RegsPPI = br.ReadBytes(4); byte PsgIndex = br.ReadByte(); byte[] PsgData = br.ReadBytes(16); ushort MemSize = br.ReadUInt16(); byte CpcType = br.ReadByte(); byte LastInt = br.ReadByte(); byte[] ScrMode = br.ReadBytes(6); byte[] DrvAName = br.ReadBytes(13); byte[] DrvBName = br.ReadBytes(13); byte[] CartName = br.ReadBytes(13); UPD.Moteur = br.ReadByte(); UPD.CurrTrack = br.ReadBytes(4); byte PrinterData = br.ReadByte(); byte EnvStep = br.ReadByte(); byte EnvDir = br.ReadByte(); byte CrtcType = br.ReadByte(); int Unused3 = br.ReadInt32(); byte HCC = br.ReadByte(); byte Unused4 = br.ReadByte(); CRTC.VCC = br.ReadByte(); CRTC.VLC = br.ReadByte(); CRTC.VtAdj = br.ReadByte(); CRTC.TailleHBL = br.ReadByte(); CRTC.TailleVBL = br.ReadByte(); ushort CrtcFlag = br.ReadUInt16(); CRTC.SyncCount = br.ReadByte(); CRTC.CntHSync = br.ReadByte(); Z80.IRQ = br.ReadByte(); byte[] Unused5 = br.ReadBytes(0x4B); tmpRam = br.ReadBytes(1024 * MemSize); System.Buffer.BlockCopy(tmpRam, 0, VGA.ram, 0, tmpRam.Length); } br.Close(); }
// Exécution de "cycles" crtc (1 cycle = 1µs) // Retourne un indicateur disant si il faut rafraichir l'écran (une "frame" terminée) static public bool CycleCRTC(int NbCycles) { bool CalcMa = false, DoResync = false; for (; NbCycles-- > 0;) { VCharCount++; if (HCC++ >= RegsCRTC[0]) { HCC = 0; VLC = (byte)((VLC + 1) & 0x1F); if (VSync != 0 && ++TailleVBL >= ((RegsCRTC[3] & 0xF0) != 0 ? RegsCRTC[3] >> 4 : 16)) { OldVSync = true; VSync = 0; } if (MR) { MR = false; VLC = 0; if (!HDT) { MaCRTC += RegsCRTC[1]; } VCC = (byte)((VCC + 1) & 0x7F); } if (VtAdj != 0) { CalcMa = --VtAdj == 0; } if (VT) { VT = false; if ((RegsCRTC[5] & 0x1F) != 0) { VtAdj = (byte)(RegsCRTC[5] & 0x1F); // #### } else { CalcMa = true; } //VtAdj = RegsCRTC[ 5 ] & 0x1F; //CalcMa = ! VtAdj; } if (CalcMa) { CalcMa = false; OldVSync = false; VLC = VCC = 0; VDT = true; MaCRTC = RegsCRTC[13] + MaHi; } if (VLC == RegsCRTC[9]) { MR = true; if (VtAdj == 0 && VCC == RegsCRTC[4]) { VT = true; } } if (VCC == RegsCRTC[6]) { VDT = false; } if (VCC == RegsCRTC[7] && VSync == 0 && !OldVSync) { TailleVBL = 0; SyncCount = 2; VSync = 1; VDelay = 2; VswCount = 4; } HDT = true; } if (HCC == RegsCRTC[1]) { HDT = false; } if (HS) { if (HDelay == 2) { if (--VHCount == 0) { LigneCRTC++; VCharCount = 0; HDelay++; } } else { HDelay++; } } if (TailleHBL != 0 && --TailleHBL == 0) { HS = false; if (VDelay != 0) { VDelay--; } if (VDelay == 0 && VswCount != 0 && --VswCount == 0) { LigneCRTC = 0; DoResync = true; // #### } CntHSync++; if ((SyncCount != 0 && --SyncCount == 0) || CntHSync == 52) { Z80.IRQ = CntHSync & 32; // Si 52 lignes comptée -> Génération d'une interruption CntHSync = 0; } LastMode = VGA.MemoMode; // Prise en compte nouveau mode écran } if (HCC == RegsCRTC[2]) { HDelay = 0; HS = true; TailleHBL = (byte)((RegsCRTC[3] & 0x0F) != 0 ? RegsCRTC[3] & 0x0F : 16); VHCount = (byte)Math.Max(0, Math.Min((TailleHBL - 2), 4)); } if (x < TAILLE_X_ECR && LigneCRTC >= TAILLE_VBL) { VGA.TraceMot(x, y - 1, HDT && VDT ? ((((HCC + MaCRTC) << 1) + (((HCC + MaCRTC) & 0x1000) << 2)) & 0xC7FF) | (VLC << 11) : -1); x += 8; } else { VGA.SyncColor(); if (VCharCount == 7) { if (y < TAILLE_Y_ECR) { x = 0; y++; } else if (LigneCRTC == TAILLE_VBL) { y = 0; } } if (LigneCRTC == TAILLE_Y_CRTC) { LigneCRTC = 0; DoResync = true; } } } return(DoResync); }