Ejemplo n.º 1
0
        public void ExecCycle()
        {
            byte cmd = 0;

            if (XFX == CpuModeEx.None && FX == CpuModeIndex.None)
            {
                if (ProcessSignals())
                {
                    return;
                }
                LPC = regs.PC;
                cmd = RDMEM_M1(LPC);
            }
            else
            {
                if (ProcessSignals())
                {
                    return;
                }
                cmd = RDMEM(regs.PC);
            }
            Tact += 3;
            regs.PC++;
            if (XFX == CpuModeEx.Cb)
            {
                BINT = false;
                if (FX != CpuModeIndex.None)
                {
                    // elapsed T: 4, 4, 3
                    // will be T: 4, 4, 3, 5
                    int drel = (sbyte)cmd;

                    regs.MW = FX == CpuModeIndex.Ix ? (ushort)(regs.IX + drel) : (ushort)(regs.IY + drel);
                    cmd     = RDMEM(regs.PC); Tact += 3;
                    RDNOMREQ(regs.PC); Tact++;
                    RDNOMREQ(regs.PC); Tact++;

                    regs.PC++;
                    _opcodesFxCb[cmd](cmd, regs.MW);
                }
                else
                {
                    //Refresh();
                    regs.R = (byte)(((regs.R + 1) & 0x7F) | (regs.R & 0x80));
                    Tact  += 1;
                    RzxCounter++;

                    _opcodesCb[cmd](cmd);
                }
                XFX = CpuModeEx.None;
                FX  = CpuModeIndex.None;
            }
            else if (XFX == CpuModeEx.Ed)
            {
                //Refresh();
                regs.R = (byte)(((regs.R + 1) & 0x7F) | (regs.R & 0x80));
                Tact  += 1;
                RzxCounter++;

                BINT = false;
                var edop = _opcodesEd[cmd];
                if (edop != null)
                {
                    edop(cmd);
                }
                XFX = CpuModeEx.None;
                FX  = CpuModeIndex.None;
            }
            else if (cmd == 0xDD)
            {
                //Refresh();
                regs.R = (byte)(((regs.R + 1) & 0x7F) | (regs.R & 0x80));
                Tact  += 1;
                RzxCounter++;

                FX   = CpuModeIndex.Ix;
                BINT = true;
            }
            else if (cmd == 0xFD)
            {
                //Refresh();
                regs.R = (byte)(((regs.R + 1) & 0x7F) | (regs.R & 0x80));
                Tact  += 1;
                RzxCounter++;

                FX   = CpuModeIndex.Iy;
                BINT = true;
            }
            else if (cmd == 0xCB)
            {
                //Refresh();
                regs.R = (byte)(((regs.R + 1) & 0x7F) | (regs.R & 0x80));
                Tact  += 1;
                RzxCounter++;

                XFX  = CpuModeEx.Cb;
                BINT = true;
            }
            else if (cmd == 0xED)
            {
                //Refresh();
                regs.R = (byte)(((regs.R + 1) & 0x7F) | (regs.R & 0x80));
                Tact  += 1;
                RzxCounter++;

                XFX  = CpuModeEx.Ed;
                BINT = true;
            }
            else
            {
                //Refresh();
                regs.R = (byte)(((regs.R + 1) & 0x7F) | (regs.R & 0x80));
                Tact  += 1;
                RzxCounter++;

                BINT = false;
                var opdo = FX == CpuModeIndex.None ? _opcodes[cmd] : _opcodesFx[cmd];
                if (opdo != null)
                {
                    opdo(cmd);
                }
                FX = CpuModeIndex.None;
            }
        }
Ejemplo n.º 2
0
        private bool ProcessSignals()
        {
            if (RST)    // RESET
            {
                // 3T
                RESET();
                //Refresh();      //+1T
                regs.R = (byte)(((regs.R + 1) & 0x7F) | (regs.R & 0x80));
                Tact  += 1;
                RzxCounter++;


                FX     = CpuModeIndex.None;
                XFX    = CpuModeEx.None;
                HALTED = false;

                IFF1    = false;
                IFF2    = false;
                regs.PC = 0;
                regs.IR = 0;
                IM      = 0;
                //regs.SP = 0xFFFF;
                //regs.AF = 0xFFFF;

                Tact += 2;      // total should be 3T?
                return(true);
            }
            else if (NMI)
            {
                // 11T (5, 3, 3)

                if (HALTED) // workaround for Z80 snapshot halt issue + comfortable debugging
                {
                    regs.PC++;
                }

                // M1
                NMIACK_M1();
                Tact += 4;
                //Refresh();
                regs.R = (byte)(((regs.R + 1) & 0x7F) | (regs.R & 0x80));
                Tact  += 1;
                RzxCounter++;


                IFF2   = IFF1;
                IFF1   = false;
                HALTED = false;
                regs.SP--;

                // M2
                WRMEM(regs.SP, (byte)(regs.PC >> 8));
                Tact += 3;
                regs.SP--;

                // M3
                WRMEM(regs.SP, (byte)regs.PC);
                regs.PC = 0x0066;
                Tact   += 3;

                return(true);
            }
            else if (INT && (!BINT) && IFF1)
            {
                // http://www.z80.info/interrup.htm
                // IM0: 13T (7,3,3) [RST]
                // IM1: 13T (7,3,3)
                // IM2: 19T (7,3,3,3,3)

                if (HALTED) // workaround for Z80 snapshot halt issue + comfortable debugging
                {
                    regs.PC++;
                }


                INTACK_M1();
                // M1: 7T = interrupt acknowledgement; SP--
                regs.SP--;
                //if (HALTED) ??
                //    Tact += 2;
                Tact += 4 + 2;
                //Refresh();
                //RzxCounter--;	// fix because INTAK should not be calculated
                regs.R = (byte)(((regs.R + 1) & 0x7F) | (regs.R & 0x80));
                Tact  += 1;


                IFF1   = false;
                IFF2   = false; // proof?
                HALTED = false;

                // M2
                WRMEM(regs.SP, (byte)(regs.PC >> 8));   // M2: 3T write PCH; SP--
                regs.SP--;
                Tact += 3;

                // M3
                WRMEM(regs.SP, (byte)regs.PC); // M3: 3T write PCL
                Tact += 3;

                if (IM == 0)          // IM 0: execute instruction taken from BUS with timing T+2???
                {
                    regs.MW = 0x0038; // workaround: just execute #FF
                }
                else if (IM == 1)     // IM 1: execute #FF with timing T+2 (11+2=13T)
                {
                    regs.MW = 0x0038;
                }
                else                // IM 2: VH=reg.I; VL=BUS; PC=[V]
                {
                    // M4
                    ushort adr = (ushort)((regs.IR & 0xFF00) | BUS);
                    regs.MW = RDMEM(adr);               // M4: 3T read VL
                    Tact   += 3;

                    // M5
                    regs.MW += (ushort)(RDMEM(++adr) * 0x100);   // M5: 3T read VH, PC=V
                    Tact    += 3;
                }
                regs.PC = regs.MW;

                return(true);
            }
            return(false);
        }