public void GenerateInstructionTypesTable() { string tableName = "InstructionTables/z80_instructions.csv"; StringWriter writer = new StringWriter(); writer.WriteLine("using System;"); writer.WriteLine(""); writer.WriteLine("namespace Z80Simulator.Instructions"); writer.WriteLine("{"); writer.WriteLine(" public static class Z80InstructionTypes"); writer.WriteLine(" {"); writer.WriteLine(" /// <summary>"); writer.WriteLine(" /// Z80 Instruction Types tables."); writer.WriteLine(" /// To be user friendly in the documentation, the first instruction type is found at index 1."); writer.WriteLine(" /// </summary>"); writer.WriteLine(" public static InstructionType[] Table = new InstructionType[163];"); writer.WriteLine(""); writer.WriteLine(" static Z80InstructionTypes()"); writer.WriteLine(" {"); IList <InstructionParamVariantLine> paramVariants = new List <InstructionParamVariantLine>(); InstructionParamVariantLine previousVariant = null; Stream stream = PlatformSpecific.GetStreamForProjectFile(tableName); using (StreamReader reader = new StreamReader(stream)) { reader.ReadLine(); string line = null; string nextLine = null; int lineCount = 0; while (true) { if (lineCount == 0) { line = reader.ReadLine(); lineCount++; } else { line = nextLine; } if (line == null) { break; } while (true) { nextLine = reader.ReadLine(); lineCount++; if (nextLine == null) { break; } else if (nextLine.StartsWith("instr;") || nextLine.StartsWith("execvar;")) { break; } else { line += "\\n" + nextLine; } } InstructionParamVariantLine instrLine = new InstructionParamVariantLine(); string[] columns = line.Split(';'); instrLine.lineType = columns[0]; instrLine.instructionIndex = columns[1]; instrLine.paramVariant = columns[2]; instrLine.numberOfInstructionCodes = columns[3]; instrLine.isInternal = columns[4] == "1" ? "true" : "false"; instrLine.mnemonic = columns[5]; instrLine.param1List = columns[6]; instrLine.param2List = columns[7]; instrLine.param3List = columns[8]; instrLine.param1AddressingMode = columns[10]; instrLine.param2AddressingMode = columns[11]; instrLine.param3AddressingMode = columns[12]; instrLine.instructionCodeSizeInBytes = columns[15]; instrLine.execVariant = columns[16]; instrLine.MCycles = columns[17]; instrLine.TStates = columns[18]; instrLine.execCondition = columns[19]; instrLine.M1 = columns[20].Trim(); instrLine.M2 = columns[21].Trim(); instrLine.M3 = columns[22].Trim(); instrLine.M4 = columns[23].Trim(); instrLine.M5 = columns[24].Trim(); instrLine.M6 = columns[25].Trim(); instrLine.stackComment = columns[26]; instrLine.M1comment = columns[27]; instrLine.instructionGroup = columns[29]; instrLine.undocumented = columns[30] == "1" ? "true" : "false"; instrLine.userManualPage = columns[31]; instrLine.operationSchema = columns[32]; instrLine.description = columns[33]; instrLine.conditionBitsAffected = columns[34]; instrLine.example = columns[35]; // Instruction / param variant if (instrLine.lineType == "instr") { if (previousVariant != null && instrLine.instructionIndex != previousVariant.instructionIndex) { GenerateInstructionType(writer, paramVariants); paramVariants = new List <InstructionParamVariantLine>(); } paramVariants.Add(instrLine); } // Exec variant else if (instrLine.lineType == "execvar") { previousVariant.ExecutionVariant = instrLine; } previousVariant = instrLine; } } GenerateInstructionType(writer, paramVariants); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine("}"); string Z80InstructionTypes_cs = writer.ToString(); }
public void GenerateOpCodesTable() { string[] tableNames = new string[] { "InstructionTables/z80_opcodes_table_1byte.csv", "InstructionTables/z80_opcodes_table_2bytes_CB.csv", "InstructionTables/z80_opcodes_table_2bytes_DD.csv", "InstructionTables/z80_opcodes_table_2bytes_ED.csv", "InstructionTables/z80_opcodes_table_2bytes_FD.csv", "InstructionTables/z80_opcodes_table_4bytes_DDCB.csv", "InstructionTables/z80_opcodes_table_4bytes_FDCB.csv" }; StringWriter writer = new StringWriter(); writer.WriteLine("using System;"); writer.WriteLine("using System.Collections.Generic;"); writer.WriteLine(""); writer.WriteLine("namespace Z80Simulator.Instructions"); writer.WriteLine("{"); writer.WriteLine(" public static class Z80OpCodes"); writer.WriteLine(" {"); writer.WriteLine(" /// <summary>"); writer.WriteLine(" /// Z80 OpCodes tables."); writer.WriteLine(" /// "); writer.WriteLine(" /// [0,] : 1 byte opcodes table."); writer.WriteLine(" /// [1,] : 2 bytes CB prefix opcodes table."); writer.WriteLine(" /// [2,] : 2 bytes DD prefix opcodes table."); writer.WriteLine(" /// [3,] : 2 bytes ED prefix opcodes table."); writer.WriteLine(" /// [4,] : 2 bytes FB prefix opcodes table."); writer.WriteLine(" /// [5,] : 4 bytes DDCB prefix opcodes table."); writer.WriteLine(" /// [6,] : 4 bytes FDCB prefix opcodes table."); writer.WriteLine(" /// </summary>"); writer.WriteLine(" public static InstructionCode[,] Tables = new InstructionCode[7, 256];"); writer.WriteLine(""); writer.WriteLine(" /// <summary>"); writer.WriteLine(" /// Lookup table used to find an InstructionCode by its InstructionText"); writer.WriteLine(" /// </summary>"); writer.WriteLine(" public static IDictionary<string, InstructionCode> Dictionary = new Dictionary<string, InstructionCode>(1792);"); writer.WriteLine(""); writer.WriteLine(" static Z80OpCodes()"); writer.WriteLine(" {"); for (int tableIndex = 0; tableIndex < 7; tableIndex++) { Stream stream = PlatformSpecific.GetStreamForProjectFile(tableNames[tableIndex]); using (StreamReader reader = new StreamReader(stream)) { string line = reader.ReadLine(); int opcodeIndex = 0; while ((line = reader.ReadLine()) != null) { string[] columns = line.Split(';'); //param 1;param 2;param 3;duplicate string prefix = columns[0]; string opcode = columns[1]; string opCodeBytes = columns[2].Length == 0 ? "0" : columns[2]; string operandBytes = columns[3].Length == 0 ? "0" : columns[3]; string undocumented = columns[4] == "1" ? "true" : "false"; string fetchMoreBytes = columns[5]; string switchToTable = columns[6].Length == 0 ? "null" : columns[6]; string text = columns[7]; string instrTypeIndex = columns[8].Length == 0 ? "0" : columns[8]; string instrParamVariant = columns[9].Length == 0 ? "0" : columns[9]; int instructionIndex = Int32.Parse(instrTypeIndex); Z80Simulator.Instructions.InstructionType instruction = Z80Simulator.Instructions.Z80InstructionTypes.Table[instructionIndex]; string param1 = columns[10].Length == 0 ? null : GetEnumFromParam(columns[10], instruction.Param1Type, instruction.Index); string param2 = columns[11].Length == 0 ? null : GetEnumFromParam(columns[11], instruction.Param2Type, instruction.Index); string param3 = columns[12].Length == 0 ? null : GetEnumFromParam(columns[12], instruction.Param3Type, instruction.Index); string duplicate = columns[13] == "1" ? "true" : "false"; writer.WriteLine(String.Format(" Tables[{0}, {1}] = new InstructionCode()", tableIndex, opcodeIndex)); writer.WriteLine(" {"); byte[] prefixBytes = null; if (prefix.Length == 4) { prefixBytes = new byte[] { Convert.ToByte(prefix.Substring(2, 2), 16) }; writer.WriteLine(String.Format(" Prefix = new byte[] {{ {0} }},", prefix)); } else if (prefix.Length == 6) { prefixBytes = new byte[] { Convert.ToByte(prefix.Substring(2, 2), 16), Convert.ToByte(prefix.Substring(4, 2), 16) }; writer.WriteLine(String.Format(" Prefix = new byte[] {{ {0}, 0x{1} }},", prefix.Substring(0, 4), prefix.Substring(4))); } writer.WriteLine(String.Format(" OpCode = {0},", opcode)); if (duplicate == "true") { string instrCodeBytes = "["; foreach (byte b in prefixBytes) { instrCodeBytes += b.ToString("X2") + "H "; } instrCodeBytes += opcode.Substring(2, 2) + "H]"; int insertIndex = text.IndexOf(' '); if (insertIndex < 0) { text += instrCodeBytes; } else { text = text.Insert(insertIndex, instrCodeBytes); } } writer.WriteLine(String.Format(" InstructionText = \"{0}\",", text)); if (param1 != null) { writer.WriteLine(String.Format(" Param1 = {0},", param1)); } if (param2 != null) { writer.WriteLine(String.Format(" Param2 = {0},", param2)); } if (param3 != null) { writer.WriteLine(String.Format(" Param3 = {0},", param3)); } writer.WriteLine(String.Format(" InstructionTypeIndex = {0},", instrTypeIndex)); writer.WriteLine(String.Format(" InstructionTypeParamVariant = {0},", instrParamVariant)); writer.WriteLine(String.Format(" IsUndocumented = {0},", undocumented)); writer.WriteLine(String.Format(" IsDuplicate = {0},", duplicate)); writer.WriteLine(String.Format(" OpCodeByteCount = {0},", opCodeBytes)); writer.WriteLine(String.Format(" OperandsByteCount = {0},", operandBytes)); writer.WriteLine(String.Format(" FetchMoreBytes = {0},", fetchMoreBytes)); writer.WriteLine(String.Format(" SwitchToTableNumber = {0}", switchToTable)); writer.WriteLine(" };"); writer.WriteLine(" "); opcodeIndex++; if (opcodeIndex == 256) { break; } } } } writer.WriteLine(" for (int i = 0; i < 7; i++)"); writer.WriteLine(" {"); writer.WriteLine(" for (int j = 0; j < 256; j++)"); writer.WriteLine(" {"); writer.WriteLine(" InstructionCode opcode = Tables[i, j];"); writer.WriteLine(" if (opcode.FetchMoreBytes == 0 && opcode.SwitchToTableNumber == null && !opcode.IsDuplicate)"); writer.WriteLine(" {"); writer.WriteLine(" string text = opcode.InstructionText.Replace(\"nn\", \"n\").Replace(\"e\", \"n\");"); writer.WriteLine(" if (!Dictionary.ContainsKey(text))"); writer.WriteLine(" {"); writer.WriteLine(" Dictionary.Add(text, opcode);"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine(" }"); writer.WriteLine("}"); string Z80OpCodes_cs = writer.ToString(); }