public void StartLogging(CPUStateElements stateElements, Z80CPU.LifecycleEventType[] eventTypes)
        {
            stateElementsToLog = stateElements;
            // Write header line : title for each column
            log.Append("event type");
            log.Append(';');
            // Internal state : instruction, machine cycle, TStates
            if(stateElementsToLog.HasFlag(CPUStateElements.InternalState))
            {
                log.Append("instruction count");
                log.Append(';');
                log.Append("instruction address");
                log.Append(';');
                log.Append("instruction text");
                log.Append(';');
                log.Append("machine cycle index");
                log.Append(';');
                log.Append("machine cycle type");
                log.Append(';');
                log.Append("half Tstate index");
                log.Append(';');
                log.Append("Tstate count");
                log.Append(';');
            }
            // Micro instructions
            if (stateElementsToLog.HasFlag(CPUStateElements.MicroInstructions))
            {
                log.Append("micro instructions");
                log.Append(';');
            }
            // CPU registers
            if (stateElementsToLog.HasFlag(CPUStateElements.Registers))
            {
                log.Append("A");
                log.Append(';');
                log.Append("SZYHXPNC");
                log.Append(';');
                log.Append("B");
                log.Append(';');
                log.Append("C");
                log.Append(';');
                log.Append("D");
                log.Append(';');
                log.Append("E");
                log.Append(';');
                log.Append("H");
                log.Append(';');
                log.Append("L");
                log.Append(';');
                log.Append("PC");
                log.Append(';');
                log.Append("SP");
                log.Append(';');
                log.Append("IX");
                log.Append(';');
                log.Append("IY");
                log.Append(';');
                log.Append("IFF1");
                log.Append(';');
                log.Append("IFF2");
                log.Append(';');
                log.Append("IM");
                log.Append(';');
                log.Append("I");
                log.Append(';');
                log.Append("R");
                log.Append(';');
            }
            // Address and Data bus
            if (stateElementsToLog.HasFlag(CPUStateElements.Buses))
            {
                log.Append("address bus");
                log.Append(';');
                log.Append("data bus");
                log.Append(';');
            }
            // Control pins
            if (stateElementsToLog.HasFlag(CPUStateElements.ControlPins))
            {
                log.Append("M1");
                log.Append(';');
                log.Append("MREQ");
                log.Append(';');
                log.Append("IORQ");
                log.Append(';');
                log.Append("RD");
                log.Append(';');
                log.Append("WR");
                log.Append(';');
                log.Append("RFSH");
                log.Append(';');

                log.Append("HALT");
                log.Append(';');
                log.Append("WAIT");
                log.Append(';');
                log.Append("INT");
                log.Append(';');
                log.Append("NMI");
                log.Append(';');
                log.Append("RESET");
                log.Append(';');

                log.Append("BUSACK");
                log.Append(';');
                log.Append("BUSREQ");
                log.Append(';');

                log.Append("CLK");
                log.Append(';');
            }
            log.AppendLine();

            eventTypesToLog = eventTypes;
            foreach (Z80CPU.LifecycleEventType eventType in eventTypesToLog)
            {
                switch (eventType)
                {
                    case Z80CPU.LifecycleEventType.HalfTState:
                        cpu.HalfTState += LogCPUState;
                        break;
                    case Z80CPU.LifecycleEventType.InstructionEnd:
                        cpu.InstructionEnd += LogCPUState;
                        break;
                    case Z80CPU.LifecycleEventType.InstructionStart:
                        cpu.InstructionStart += LogCPUState;
                        break;
                    case Z80CPU.LifecycleEventType.MachineCycleEnd:
                        cpu.MachineCycleEnd += LogCPUState;
                        break;
                    case Z80CPU.LifecycleEventType.MachineCycleStart:
                        cpu.MachineCycleStart += LogCPUState;
                        break;
                }
            }
            if (stateElementsToLog.HasFlag(CPUStateElements.MicroInstructions))
            {
                cpu.TraceMicroInstructions = true;
                cpu.MicroInstructions = new List<Z80Simulator.Instructions.MicroInstruction>();
            }
        }
        public void StartLogging(CPUStateElements stateElements, Z80CPU.LifecycleEventType[] eventTypes)
        {
            stateElementsToLog = stateElements;
            // Write header line : title for each column
            log.Append("event type");
            log.Append(';');
            // Internal state : instruction, machine cycle, TStates
            if (stateElementsToLog.HasFlag(CPUStateElements.InternalState))
            {
                log.Append("instruction count");
                log.Append(';');
                log.Append("instruction address");
                log.Append(';');
                log.Append("instruction text");
                log.Append(';');
                log.Append("machine cycle index");
                log.Append(';');
                log.Append("machine cycle type");
                log.Append(';');
                log.Append("half Tstate index");
                log.Append(';');
                log.Append("Tstate count");
                log.Append(';');
            }
            // Micro instructions
            if (stateElementsToLog.HasFlag(CPUStateElements.MicroInstructions))
            {
                log.Append("micro instructions");
                log.Append(';');
            }
            // CPU registers
            if (stateElementsToLog.HasFlag(CPUStateElements.Registers))
            {
                log.Append("A");
                log.Append(';');
                log.Append("SZYHXPNC");
                log.Append(';');
                log.Append("B");
                log.Append(';');
                log.Append("C");
                log.Append(';');
                log.Append("D");
                log.Append(';');
                log.Append("E");
                log.Append(';');
                log.Append("H");
                log.Append(';');
                log.Append("L");
                log.Append(';');
                log.Append("PC");
                log.Append(';');
                log.Append("SP");
                log.Append(';');
                log.Append("IX");
                log.Append(';');
                log.Append("IY");
                log.Append(';');
                log.Append("IFF1");
                log.Append(';');
                log.Append("IFF2");
                log.Append(';');
                log.Append("IM");
                log.Append(';');
                log.Append("I");
                log.Append(';');
                log.Append("R");
                log.Append(';');
            }
            // Address and Data bus
            if (stateElementsToLog.HasFlag(CPUStateElements.Buses))
            {
                log.Append("address bus");
                log.Append(';');
                log.Append("data bus");
                log.Append(';');
            }
            // Control pins
            if (stateElementsToLog.HasFlag(CPUStateElements.ControlPins))
            {
                log.Append("M1");
                log.Append(';');
                log.Append("MREQ");
                log.Append(';');
                log.Append("IORQ");
                log.Append(';');
                log.Append("RD");
                log.Append(';');
                log.Append("WR");
                log.Append(';');
                log.Append("RFSH");
                log.Append(';');

                log.Append("HALT");
                log.Append(';');
                log.Append("WAIT");
                log.Append(';');
                log.Append("INT");
                log.Append(';');
                log.Append("NMI");
                log.Append(';');
                log.Append("RESET");
                log.Append(';');

                log.Append("BUSACK");
                log.Append(';');
                log.Append("BUSREQ");
                log.Append(';');

                log.Append("CLK");
                log.Append(';');
            }
            log.AppendLine();

            eventTypesToLog = eventTypes;
            foreach (Z80CPU.LifecycleEventType eventType in eventTypesToLog)
            {
                switch (eventType)
                {
                case Z80CPU.LifecycleEventType.HalfTState:
                    cpu.HalfTState += LogCPUState;
                    break;

                case Z80CPU.LifecycleEventType.InstructionEnd:
                    cpu.InstructionEnd += LogCPUState;
                    break;

                case Z80CPU.LifecycleEventType.InstructionStart:
                    cpu.InstructionStart += LogCPUState;
                    break;

                case Z80CPU.LifecycleEventType.MachineCycleEnd:
                    cpu.MachineCycleEnd += LogCPUState;
                    break;

                case Z80CPU.LifecycleEventType.MachineCycleStart:
                    cpu.MachineCycleStart += LogCPUState;
                    break;
                }
            }
            if (stateElementsToLog.HasFlag(CPUStateElements.MicroInstructions))
            {
                cpu.TraceMicroInstructions = true;
                cpu.MicroInstructions      = new List <Z80Simulator.Instructions.MicroInstruction>();
            }
        }