summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m68000/m68kmake.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m68000/m68kmake.cpp')
-rw-r--r--src/devices/cpu/m68000/m68kmake.cpp1414
1 files changed, 0 insertions, 1414 deletions
diff --git a/src/devices/cpu/m68000/m68kmake.cpp b/src/devices/cpu/m68000/m68kmake.cpp
deleted file mode 100644
index 9be6ca437af..00000000000
--- a/src/devices/cpu/m68000/m68kmake.cpp
+++ /dev/null
@@ -1,1414 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Karl Stenerud
-/* ======================================================================== */
-/* ========================= LICENSING & COPYRIGHT ======================== */
-/* ======================================================================== */
-/*
- * MUSASHI
- * Version 4.90
- *
- * A portable Motorola M680x0 processor emulation engine.
- * Copyright Karl Stenerud. All rights reserved.
- *
- */
-
-/*
- * 68030 and PMMU by R. Belmont and Hans Ostermeyer
- * 68040 and FPU by Ville Linde, R. Belmont, and Hans Ostermeyer
- * CPU32 by David Haywood. ColdFire by R. Belmont.
- *
- */
-
-
-/* ======================================================================== */
-/* ============================ CODE GENERATOR ============================ */
-/* ======================================================================== */
-/*
- * This is the code generator program which will generate the opcode table
- * and the final opcode handlers.
- *
- * It requires an input file to function (default m68k_in.c), but you can
- * specify your own like so:
- *
- * m68kmake <output path> <input file>
- *
- * where output path is the path where the output files should be placed, and
- * input file is the file to use for input.
- *
- * If you modify the input file greatly from its released form, you may have
- * to tweak the configuration section a bit since I'm using static allocation
- * to keep things simple.
- *
- *
- * TODO: - build a better code generator for the move instruction.
- * - Add callm and rtm instructions
- * - Fix RTE to handle other format words
- * - Add address error (and bus error?) handling
- */
-
-
-static const char g_version[] = "4.90";
-
-/* ======================================================================== */
-/* =============================== INCLUDES =============================== */
-/* ======================================================================== */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
-
-
-
-/* ======================================================================== */
-/* ============================= CONFIGURATION ============================ */
-/* ======================================================================== */
-
-#if defined(__GNUC__) && (__GNUC__ >= 3)
-#define ATTR_PRINTF(x,y) __attribute__((format(printf, x, y)))
-#else
-#define ATTR_PRINTF(x,y)
-#endif
-
-#define M68K_MAX_PATH 1024
-#define M68K_MAX_DIR 1024
-
-#define MAX_LINE_LENGTH 200 /* length of 1 line */
-#define MAX_BODY_LENGTH 300 /* Number of lines in 1 function */
-#define MAX_REPLACE_LENGTH 30 /* Max number of replace strings */
-#define MAX_INSERT_LENGTH 5000 /* Max size of insert piece */
-#define MAX_NAME_LENGTH 96 /* Max length of ophandler name */
-#define MAX_SPEC_PROC_LENGTH 4 /* Max length of special processing str */
-#define MAX_SPEC_EA_LENGTH 5 /* Max length of specified EA str */
-#define EA_ALLOWED_LENGTH 11 /* Max length of ea allowed str */
-#define MAX_OPCODE_INPUT_TABLE_LENGTH 1000 /* Max length of opcode handler tbl */
-#define MAX_OPCODE_OUTPUT_TABLE_LENGTH 3000 /* Max length of opcode handler tbl */
-
-/* Default filenames */
-#define FILENAME_INPUT "m68k_in.cpp"
-#define FILENAME_PROTOTYPE "m68kops.h"
-#define FILENAME_TABLE "m68kops.cpp"
-
-
-/* Identifier sequences recognized by this program */
-
-#define ID_INPUT_SEPARATOR "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
-
-#define ID_BASE "M68KMAKE"
-#define ID_PROTOTYPE_HEADER ID_BASE "_PROTOTYPE_HEADER"
-#define ID_PROTOTYPE_FOOTER ID_BASE "_PROTOTYPE_FOOTER"
-#define ID_TABLE_HEADER ID_BASE "_TABLE_HEADER"
-#define ID_TABLE_FOOTER ID_BASE "_TABLE_FOOTER"
-#define ID_TABLE_BODY ID_BASE "_TABLE_BODY"
-#define ID_TABLE_START ID_BASE "_TABLE_START"
-#define ID_OPHANDLER_HEADER ID_BASE "_OPCODE_HANDLER_HEADER"
-#define ID_OPHANDLER_FOOTER ID_BASE "_OPCODE_HANDLER_FOOTER"
-#define ID_OPHANDLER_BODY ID_BASE "_OPCODE_HANDLER_BODY"
-#define ID_END ID_BASE "_END"
-
-#define ID_OPHANDLER_NAME ID_BASE "_OP"
-#define ID_OPHANDLER_EA_AY_8 ID_BASE "_GET_EA_AY_8"
-#define ID_OPHANDLER_EA_AY_16 ID_BASE "_GET_EA_AY_16"
-#define ID_OPHANDLER_EA_AY_32 ID_BASE "_GET_EA_AY_32"
-#define ID_OPHANDLER_OPER_AY_8 ID_BASE "_GET_OPER_AY_8"
-#define ID_OPHANDLER_OPER_AY_16 ID_BASE "_GET_OPER_AY_16"
-#define ID_OPHANDLER_OPER_AY_32 ID_BASE "_GET_OPER_AY_32"
-#define ID_OPHANDLER_CC ID_BASE "_CC"
-#define ID_OPHANDLER_NOT_CC ID_BASE "_NOT_CC"
-
-
-#ifndef DECL_SPEC
-#define DECL_SPEC
-#endif /* DECL_SPEC */
-
-
-
-/* ======================================================================== */
-/* ============================== PROTOTYPES ============================== */
-/* ======================================================================== */
-
-enum
-{
- CPU_TYPE_000 = 0, // 0
- CPU_TYPE_010, // 1
- CPU_TYPE_020, // 2
- CPU_TYPE_030, // 3
- CPU_TYPE_040, // 4
- CPU_TYPE_FSCPU32, // 5
- CPU_TYPE_COLDFIRE, // 6
- NUM_CPUS
-};
-
-#define UNSPECIFIED "."
-#define UNSPECIFIED_CH '.'
-
-#define HAS_NO_EA_MODE(A) (strcmp(A, "..........") == 0)
-#define HAS_EA_AI(A) ((A)[0] == 'A')
-#define HAS_EA_PI(A) ((A)[1] == '+')
-#define HAS_EA_PD(A) ((A)[2] == '-')
-#define HAS_EA_DI(A) ((A)[3] == 'D')
-#define HAS_EA_IX(A) ((A)[4] == 'X')
-#define HAS_EA_AW(A) ((A)[5] == 'W')
-#define HAS_EA_AL(A) ((A)[6] == 'L')
-#define HAS_EA_PCDI(A) ((A)[7] == 'd')
-#define HAS_EA_PCIX(A) ((A)[8] == 'x')
-#define HAS_EA_I(A) ((A)[9] == 'I')
-
-enum
-{
- EA_MODE_NONE, /* No special addressing mode */
- EA_MODE_AI, /* Address register indirect */
- EA_MODE_PI, /* Address register indirect with postincrement */
- EA_MODE_PI7, /* Address register 7 indirect with postincrement */
- EA_MODE_PD, /* Address register indirect with predecrement */
- EA_MODE_PD7, /* Address register 7 indirect with predecrement */
- EA_MODE_DI, /* Address register indirect with displacement */
- EA_MODE_IX, /* Address register indirect with index */
- EA_MODE_AW, /* Absolute word */
- EA_MODE_AL, /* Absolute long */
- EA_MODE_PCDI, /* Program counter indirect with displacement */
- EA_MODE_PCIX, /* Program counter indirect with index */
- EA_MODE_I /* Immediate */
-};
-
-
-/* Everything we need to know about an opcode */
-struct opcode_struct
-{
- char name[MAX_NAME_LENGTH]; /* opcode handler name */
- unsigned char size; /* Size of operation */
- char spec_proc[MAX_SPEC_PROC_LENGTH]; /* Special processing mode */
- char spec_ea[MAX_SPEC_EA_LENGTH]; /* Specified effective addressing mode */
- unsigned char bits; /* Number of significant bits (used for sorting the table) */
- unsigned short op_mask; /* Mask to apply for matching an opcode to a handler */
- unsigned short op_match; /* Value to match after masking */
- char ea_allowed[EA_ALLOWED_LENGTH]; /* Effective addressing modes allowed */
- char cpu_mode[NUM_CPUS]; /* User or supervisor mode */
- char cpus[NUM_CPUS+1]; /* Allowed CPUs */
- unsigned char cycles[NUM_CPUS]; /* cycles for 000, 010, 020, 030, 040 */
-};
-
-
-/* All modifications necessary for a specific EA mode of an instruction */
-struct ea_info_struct
-{
- const char* fname_add;
- const char* ea_add;
- unsigned int mask_add;
- unsigned int match_add;
-};
-
-
-/* Holds the body of a function */
-struct body_struct
-{
- char body[MAX_BODY_LENGTH][MAX_LINE_LENGTH+1];
- int length;
-};
-
-
-/* Holds a sequence of search / replace strings */
-struct replace_struct
-{
- char replace[MAX_REPLACE_LENGTH][2][MAX_LINE_LENGTH+1];
- int length;
-};
-
-
-/* Function Prototypes */
-[[noreturn]] static void error_exit(const char* fmt, ...) ATTR_PRINTF(1,2);
-[[noreturn]] static void perror_exit(const char* fmt, ...) ATTR_PRINTF(1,2);
-static int check_strsncpy(char* dst, char* src, int maxlength);
-static int check_atoi(char* str, int *result);
-static int skip_spaces(char* str);
-static int num_bits(int value);
-//int atoh(char* buff);
-static int fgetline(char* buff, int nchars, FILE* file);
-static int get_oper_cycles(opcode_struct* op, int ea_mode, int cpu_type);
-static opcode_struct* find_opcode(char* name, int size, char* spec_proc, char* spec_ea);
-//opcode_struct* find_illegal_opcode(void);
-static int extract_opcode_info(char* src, char* name, int* size, char* spec_proc, char* spec_ea);
-static void add_replace_string(replace_struct* replace, const char* search_str, const char* replace_str);
-static void write_body(FILE* filep, body_struct* body, replace_struct* replace);
-static void get_base_name(char* base_name, opcode_struct* op);
-static void write_function_name(FILE* filep, char* base_name);
-static void add_opcode_output_table_entry(opcode_struct* op, char* name);
-static int DECL_SPEC compare_nof_true_bits(const void* aptr, const void* bptr);
-static void print_opcode_output_table(FILE* filep);
-static void write_table_entry(FILE* filep, opcode_struct* op);
-static void set_opcode_struct(opcode_struct* src, opcode_struct* dst, int ea_mode);
-static void generate_opcode_handler(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* opinfo, int ea_mode);
-static void generate_opcode_ea_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op);
-static void generate_opcode_cc_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op_in, int offset);
-static void process_opcode_handlers(FILE* filep);
-static void populate_table(void);
-static void read_insert(char* insert);
-
-
-
-/* ======================================================================== */
-/* ================================= DATA ================================= */
-/* ======================================================================== */
-
-/* Name of the input file */
-static char g_input_filename[M68K_MAX_PATH];
-
-/* File handles */
-static FILE* g_input_file = nullptr;
-static FILE* g_prototype_file = nullptr;
-static FILE* g_table_file = nullptr;
-
-static int g_num_functions = 0; /* Number of functions processed */
-static int g_num_primitives = 0; /* Number of function primitives read */
-static int g_line_number = 1; /* Current line number */
-
-/* Opcode handler table */
-static opcode_struct g_opcode_input_table[MAX_OPCODE_INPUT_TABLE_LENGTH];
-
-static opcode_struct g_opcode_output_table[MAX_OPCODE_OUTPUT_TABLE_LENGTH];
-static int g_opcode_output_table_length = 0;
-
-static const ea_info_struct g_ea_info_table[13] =
-{/* fname ea mask match */
- {"", "", 0x00, 0x00}, /* EA_MODE_NONE */
- {"ai", "AY_AI", 0x38, 0x10}, /* EA_MODE_AI */
- {"pi", "AY_PI", 0x38, 0x18}, /* EA_MODE_PI */
- {"pi7", "A7_PI", 0x3f, 0x1f}, /* EA_MODE_PI7 */
- {"pd", "AY_PD", 0x38, 0x20}, /* EA_MODE_PD */
- {"pd7", "A7_PD", 0x3f, 0x27}, /* EA_MODE_PD7 */
- {"di", "AY_DI", 0x38, 0x28}, /* EA_MODE_DI */
- {"ix", "AY_IX", 0x38, 0x30}, /* EA_MODE_IX */
- {"aw", "AW", 0x3f, 0x38}, /* EA_MODE_AW */
- {"al", "AL", 0x3f, 0x39}, /* EA_MODE_AL */
- {"pcdi", "PCDI", 0x3f, 0x3a}, /* EA_MODE_PCDI */
- {"pcix", "PCIX", 0x3f, 0x3b}, /* EA_MODE_PCIX */
- {"i", "I", 0x3f, 0x3c}, /* EA_MODE_I */
-};
-
-
-static const char *const g_cc_table[16][2] =
-{
- { "t", "T"}, /* 0000 */
- { "f", "F"}, /* 0001 */
- {"hi", "HI"}, /* 0010 */
- {"ls", "LS"}, /* 0011 */
- {"cc", "CC"}, /* 0100 */
- {"cs", "CS"}, /* 0101 */
- {"ne", "NE"}, /* 0110 */
- {"eq", "EQ"}, /* 0111 */
- {"vc", "VC"}, /* 1000 */
- {"vs", "VS"}, /* 1001 */
- {"pl", "PL"}, /* 1010 */
- {"mi", "MI"}, /* 1011 */
- {"ge", "GE"}, /* 1100 */
- {"lt", "LT"}, /* 1101 */
- {"gt", "GT"}, /* 1110 */
- {"le", "LE"}, /* 1111 */
-};
-
-/* size to index translator (0 -> 0, 8 and 16 -> 1, 32 -> 2) */
-static const int g_size_select_table[33] =
-{
- 0, /* unsized */
- 0, 0, 0, 0, 0, 0, 0, 1, /* 8 */
- 0, 0, 0, 0, 0, 0, 0, 1, /* 16 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 /* 32 */
-};
-
-/* Extra cycles required for certain EA modes */
-/* TODO: correct timings for 030, 040 */
-static const int g_ea_cycle_table[13][NUM_CPUS][3] =
-{/* 000 010 020 030 040 CPU*/
- {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}}, /* EA_MODE_NONE */
- {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AI */
- {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_PI */
- {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_PI7 */
- {{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PD */
- {{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PD7 */
- {{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_DI */
- {{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}, { 0, 7, 7}, { 0, 7, 7}, { 0, 7, 7}}, /* EA_MODE_IX */
- {{ 0, 8, 12}, { 0, 8, 12}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AW */
- {{ 0, 12, 16}, { 0, 12, 16}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}, { 0, 4, 4}}, /* EA_MODE_AL */
- {{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}, { 0, 5, 5}}, /* EA_MODE_PCDI */
- {{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}, { 0, 7, 7}, { 0, 7, 7}, { 0, 7, 7}}, /* EA_MODE_PCIX */
- {{ 0, 4, 8}, { 0, 4, 8}, { 0, 2, 4}, { 0, 2, 4}, { 0, 2, 4}, { 0, 2, 4}}, /* EA_MODE_I */
-};
-
-/* Extra cycles for JMP instruction (000, 010) */
-static const int g_jmp_cycle_table[13] =
-{
- 0, /* EA_MODE_NONE */
- 4, /* EA_MODE_AI */
- 0, /* EA_MODE_PI */
- 0, /* EA_MODE_PI7 */
- 0, /* EA_MODE_PD */
- 0, /* EA_MODE_PD7 */
- 6, /* EA_MODE_DI */
- 10, /* EA_MODE_IX */
- 6, /* EA_MODE_AW */
- 8, /* EA_MODE_AL */
- 6, /* EA_MODE_PCDI */
- 10, /* EA_MODE_PCIX */
- 0, /* EA_MODE_I */
-};
-
-/* Extra cycles for JSR instruction (000, 010) */
-static const int g_jsr_cycle_table[13] =
-{
- 0, /* EA_MODE_NONE */
- 4, /* EA_MODE_AI */
- 0, /* EA_MODE_PI */
- 0, /* EA_MODE_PI7 */
- 0, /* EA_MODE_PD */
- 0, /* EA_MODE_PD7 */
- 6, /* EA_MODE_DI */
- 10, /* EA_MODE_IX */
- 6, /* EA_MODE_AW */
- 8, /* EA_MODE_AL */
- 6, /* EA_MODE_PCDI */
- 10, /* EA_MODE_PCIX */
- 0, /* EA_MODE_I */
-};
-
-/* Extra cycles for LEA instruction (000, 010) */
-static const int g_lea_cycle_table[13] =
-{
- 0, /* EA_MODE_NONE */
- 4, /* EA_MODE_AI */
- 0, /* EA_MODE_PI */
- 0, /* EA_MODE_PI7 */
- 0, /* EA_MODE_PD */
- 0, /* EA_MODE_PD7 */
- 8, /* EA_MODE_DI */
- 12, /* EA_MODE_IX */
- 8, /* EA_MODE_AW */
- 12, /* EA_MODE_AL */
- 8, /* EA_MODE_PCDI */
- 12, /* EA_MODE_PCIX */
- 0, /* EA_MODE_I */
-};
-
-/* Extra cycles for PEA instruction (000, 010) */
-static const int g_pea_cycle_table[13] =
-{
- 0, /* EA_MODE_NONE */
- 6, /* EA_MODE_AI */
- 0, /* EA_MODE_PI */
- 0, /* EA_MODE_PI7 */
- 0, /* EA_MODE_PD */
- 0, /* EA_MODE_PD7 */
- 10, /* EA_MODE_DI */
- 14, /* EA_MODE_IX */
- 10, /* EA_MODE_AW */
- 14, /* EA_MODE_AL */
- 10, /* EA_MODE_PCDI */
- 14, /* EA_MODE_PCIX */
- 0, /* EA_MODE_I */
-};
-
-/* Extra cycles for MOVEM instruction (000, 010) */
-static const int g_movem_cycle_table[13] =
-{
- 0, /* EA_MODE_NONE */
- 0, /* EA_MODE_AI */
- 0, /* EA_MODE_PI */
- 0, /* EA_MODE_PI7 */
- 0, /* EA_MODE_PD */
- 0, /* EA_MODE_PD7 */
- 4, /* EA_MODE_DI */
- 6, /* EA_MODE_IX */
- 4, /* EA_MODE_AW */
- 8, /* EA_MODE_AL */
- 0, /* EA_MODE_PCDI */
- 0, /* EA_MODE_PCIX */
- 0, /* EA_MODE_I */
-};
-
-/* Extra cycles for MOVES instruction (010) */
-static const int g_moves_cycle_table[13][3] =
-{
- { 0, 0, 0}, /* EA_MODE_NONE */
- { 0, 4, 6}, /* EA_MODE_AI */
- { 0, 4, 6}, /* EA_MODE_PI */
- { 0, 4, 6}, /* EA_MODE_PI7 */
- { 0, 6, 12}, /* EA_MODE_PD */
- { 0, 6, 12}, /* EA_MODE_PD7 */
- { 0, 12, 16}, /* EA_MODE_DI */
- { 0, 16, 20}, /* EA_MODE_IX */
- { 0, 12, 16}, /* EA_MODE_AW */
- { 0, 16, 20}, /* EA_MODE_AL */
- { 0, 0, 0}, /* EA_MODE_PCDI */
- { 0, 0, 0}, /* EA_MODE_PCIX */
- { 0, 0, 0}, /* EA_MODE_I */
-};
-
-/* Extra cycles for CLR instruction (010) */
-static const int g_clr_cycle_table[13][3] =
-{
- { 0, 0, 0}, /* EA_MODE_NONE */
- { 0, 4, 6}, /* EA_MODE_AI */
- { 0, 4, 6}, /* EA_MODE_PI */
- { 0, 4, 6}, /* EA_MODE_PI7 */
- { 0, 6, 8}, /* EA_MODE_PD */
- { 0, 6, 8}, /* EA_MODE_PD7 */
- { 0, 8, 10}, /* EA_MODE_DI */
- { 0, 10, 14}, /* EA_MODE_IX */
- { 0, 8, 10}, /* EA_MODE_AW */
- { 0, 10, 14}, /* EA_MODE_AL */
- { 0, 0, 0}, /* EA_MODE_PCDI */
- { 0, 0, 0}, /* EA_MODE_PCIX */
- { 0, 0, 0}, /* EA_MODE_I */
-};
-
-
-
-/* ======================================================================== */
-/* =========================== UTILITY FUNCTIONS ========================== */
-/* ======================================================================== */
-
-/* Print an error message and exit with status error */
-static void error_exit(const char* fmt, ...)
-{
- va_list args;
- fprintf(stderr, "In %s, near or on line %d:\n\t", g_input_filename, g_line_number);
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
- fprintf(stderr, "\n");
-
- if(g_prototype_file) fclose(g_prototype_file);
- if(g_table_file) fclose(g_table_file);
- if(g_input_file) fclose(g_input_file);
-
- exit(EXIT_FAILURE);
-}
-
-/* Print an error message, call perror(), and exit with status error */
-static void perror_exit(const char* fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
- perror("");
-
- if(g_prototype_file) fclose(g_prototype_file);
- if(g_table_file) fclose(g_table_file);
- if(g_input_file) fclose(g_input_file);
-
- exit(EXIT_FAILURE);
-}
-
-
-/* copy until 0 or space and exit with error if we read too far */
-static int check_strsncpy(char* dst, char* src, int maxlength)
-{
- char* p = dst;
- while(*src && *src != ' ')
- {
- *p++ = *src++;
- if(p - dst > maxlength)
- error_exit("Field too long");
- }
- *p = 0;
- return p - dst;
-}
-
-/* copy until 0 or specified character and exit with error if we read too far */
-static int check_strcncpy(char* dst, char* src, char delim, int maxlength)
-{
- char* p = dst;
- while(*src && *src != delim)
- {
- *p++ = *src++;
- if(p - dst > maxlength)
- error_exit("Field too long");
- }
- *p = 0;
- return p - dst;
-}
-
-/* convert ascii to integer and exit with error if we find invalid data */
-static int check_atoi(char* str, int *result)
-{
- int accum = 0;
- char* p = str;
- while(*p >= '0' && *p <= '9')
- {
- accum *= 10;
- accum += *p++ - '0';
- }
- if(*p != ' ' && *p != 0)
- error_exit("Malformed integer value (%c)", *p);
- *result = accum;
- return p - str;
-}
-
-/* Skip past spaces in a string */
-static int skip_spaces(char* str)
-{
- char* p = str;
-
- while(*p == ' ')
- p++;
-
- return p - str;
-}
-
-/* Count the number of set bits in a value */
-static int num_bits(int value)
-{
- value = ((value & 0xaaaa) >> 1) + (value & 0x5555);
- value = ((value & 0xcccc) >> 2) + (value & 0x3333);
- value = ((value & 0xf0f0) >> 4) + (value & 0x0f0f);
- value = ((value & 0xff00) >> 8) + (value & 0x00ff);
- return value;
-}
-
-#ifdef UNUSED_FUNCTION
-/* Convert a hex value written in ASCII */
-int atoh(char* buff)
-{
- int accum = 0;
-
- for(;;buff++)
- {
- if(*buff >= '0' && *buff <= '9')
- {
- accum <<= 4;
- accum += *buff - '0';
- }
- else if(*buff >= 'a' && *buff <= 'f')
- {
- accum <<= 4;
- accum += *buff - 'a' + 10;
- }
- else break;
- }
- return accum;
-}
-#endif
-
-/* Get a line of text from a file, discarding any end-of-line characters */
-static int fgetline(char* buff, int nchars, FILE* file)
-{
- int length;
-
- if(fgets(buff, nchars, file) == nullptr)
- return -1;
- if(buff[0] == '\r')
- memmove(buff, buff + 1, nchars - 1);
-
- length = strlen(buff);
- while(length && (buff[length-1] == '\r' || buff[length-1] == '\n'))
- length--;
- buff[length] = 0;
- g_line_number++;
-
- return length;
-}
-
-
-
-/* ======================================================================== */
-/* =========================== HELPER FUNCTIONS =========================== */
-/* ======================================================================== */
-
-/* Calculate the number of cycles an opcode requires */
-static int get_oper_cycles(opcode_struct* op, int ea_mode, int cpu_type)
-{
- int size = g_size_select_table[op->size];
-
- if(op->cpus[cpu_type] == '.')
- return 255;
-
- if(cpu_type < CPU_TYPE_020)
- {
- if(cpu_type == CPU_TYPE_010)
- {
- if(strcmp(op->name, "moves") == 0)
- return op->cycles[cpu_type] + g_moves_cycle_table[ea_mode][size];
- if(strcmp(op->name, "clr") == 0)
- return op->cycles[cpu_type] + g_clr_cycle_table[ea_mode][size];
- }
-
- /* ASG: added these cases -- immediate modes take 2 extra cycles here */
- /* SV: but only when operating on long, and also on register direct mode */
- if(cpu_type == CPU_TYPE_000 && (ea_mode == EA_MODE_I || ea_mode == EA_MODE_NONE) && op->size == 32 &&
- ((strcmp(op->name, "add") == 0 && strcmp(op->spec_proc, "er") == 0) ||
- strcmp(op->name, "adda") == 0 ||
- (strcmp(op->name, "and") == 0 && strcmp(op->spec_proc, "er") == 0) ||
- (strcmp(op->name, "or") == 0 && strcmp(op->spec_proc, "er") == 0) ||
- (strcmp(op->name, "sub") == 0 && strcmp(op->spec_proc, "er") == 0) ||
- strcmp(op->name, "suba") == 0))
- return op->cycles[cpu_type] + g_ea_cycle_table[ea_mode][cpu_type][size] + 2;
-
- if(strcmp(op->name, "jmp") == 0)
- return op->cycles[cpu_type] + g_jmp_cycle_table[ea_mode];
- if(strcmp(op->name, "jsr") == 0)
- return op->cycles[cpu_type] + g_jsr_cycle_table[ea_mode];
- if(strcmp(op->name, "lea") == 0)
- return op->cycles[cpu_type] + g_lea_cycle_table[ea_mode];
- if(strcmp(op->name, "pea") == 0)
- return op->cycles[cpu_type] + g_pea_cycle_table[ea_mode];
- if(strcmp(op->name, "movem") == 0)
- return op->cycles[cpu_type] + g_movem_cycle_table[ea_mode];
- }
- return op->cycles[cpu_type] + g_ea_cycle_table[ea_mode][cpu_type][size];
-}
-
-/* Find an opcode in the opcode handler list */
-static opcode_struct* find_opcode(char* name, int size, char* spec_proc, char* spec_ea)
-{
- opcode_struct* op;
-
-
- for(op = g_opcode_input_table;op->name[0] != 0;op++)
- {
- if( strcmp(name, op->name) == 0 &&
- (size == op->size) &&
- strcmp(spec_proc, op->spec_proc) == 0 &&
- strcmp(spec_ea, op->spec_ea) == 0)
- return op;
- }
- return nullptr;
-}
-
-#ifdef UNUSED_FUNCTION
-/* Specifically find the illegal opcode in the list */
-opcode_struct* find_illegal_opcode(void)
-{
- opcode_struct* op;
-
- for(op = g_opcode_input_table;op->name != nullptr;op++)
- {
- if(strcmp(op->name, "illegal") == 0)
- return op;
- }
- return nullptr;
-}
-#endif
-
-/* Parse an opcode handler name */
-static int extract_opcode_info(char* src, char* name, int* size, char* spec_proc, char* spec_ea)
-{
- char* ptr = strstr(src, ID_OPHANDLER_NAME);
-
- if(ptr == nullptr)
- return 0;
-
- ptr += strlen(ID_OPHANDLER_NAME) + 1;
-
- ptr += check_strcncpy(name, ptr, ',', MAX_NAME_LENGTH);
- if(*ptr != ',') return 0;
- ptr++;
- ptr += skip_spaces(ptr);
-
- *size = atoi(ptr);
- ptr = strstr(ptr, ",");
- if(ptr == nullptr) return 0;
- ptr++;
- ptr += skip_spaces(ptr);
-
- ptr += check_strcncpy(spec_proc, ptr, ',', MAX_SPEC_PROC_LENGTH);
- if(*ptr != ',') return 0;
- ptr++;
- ptr += skip_spaces(ptr);
-
- ptr += check_strcncpy(spec_ea, ptr, ')', MAX_SPEC_EA_LENGTH);
- if(*ptr != ')') return 0;
- ptr++;
- ptr += skip_spaces(ptr);
-
- return 1;
-}
-
-
-/* Add a search/replace pair to a replace structure */
-static void add_replace_string(replace_struct* replace, const char* search_str, const char* replace_str)
-{
- if(replace->length >= MAX_REPLACE_LENGTH)
- error_exit("overflow in replace structure");
-
- strcpy(replace->replace[replace->length][0], search_str);
- strcpy(replace->replace[replace->length++][1], replace_str);
-}
-
-/* Write a function body while replacing any selected strings */
-static void write_body(FILE* filep, body_struct* body, replace_struct* replace)
-{
- int i;
- int j;
- char* ptr;
- char output[MAX_LINE_LENGTH+1];
- char temp_buff[MAX_LINE_LENGTH+1];
- int found;
-
- for(i=0;i<body->length;i++)
- {
- strcpy(output, body->body[i]);
- /* Check for the base directive header */
- if(strstr(output, ID_BASE) != nullptr)
- {
- /* Search for any text we need to replace */
- found = 0;
- for(j=0;j<replace->length;j++)
- {
- ptr = strstr(output, replace->replace[j][0]);
- if(ptr)
- {
- /* We found something to replace */
- found = 1;
- strcpy(temp_buff, ptr+strlen(replace->replace[j][0]));
- strcpy(ptr, replace->replace[j][1]);
- strcat(ptr, temp_buff);
- }
- }
- /* Found a directive with no matching replace string */
- if(!found)
- error_exit("Unknown " ID_BASE " directive [%s]", output);
- }
- fprintf(filep, "%s\n", output);
- }
- fprintf(filep, "\n\n");
-}
-
-/* Generate a base function name from an opcode struct */
-static void get_base_name(char* base_name, opcode_struct* op)
-{
- sprintf(base_name, "m68k_op_%s", op->name);
- if(op->size > 0)
- sprintf(base_name+strlen(base_name), "_%d", op->size);
- if(strcmp(op->spec_proc, UNSPECIFIED) != 0)
- sprintf(base_name+strlen(base_name), "_%s", op->spec_proc);
- if(strcmp(op->spec_ea, UNSPECIFIED) != 0)
- sprintf(base_name+strlen(base_name), "_%s", op->spec_ea);
-}
-
-/* Write the name of an opcode handler function */
-static void write_function_name(FILE* filep, char* base_name)
-{
- fprintf(filep, "void m68000_base_device::%s()\n", base_name);
- fprintf(g_prototype_file, "void %s();\n", base_name);
-}
-
-static void add_opcode_output_table_entry(opcode_struct* op, char* name)
-{
- opcode_struct* ptr;
- if(g_opcode_output_table_length > MAX_OPCODE_OUTPUT_TABLE_LENGTH)
- error_exit("Opcode output table overflow");
-
- ptr = g_opcode_output_table + g_opcode_output_table_length++;
-
- *ptr = *op;
-
- sprintf( ptr->name, "&m68000_base_device::%s", name);
- ptr->bits = num_bits(ptr->op_mask);
-}
-
-/*
- * Comparison function for qsort()
- * For entries with an equal number of set bits in
- * the mask compare the match values
- */
-static int DECL_SPEC compare_nof_true_bits(const void* aptr, const void* bptr)
-{
- const opcode_struct *a = (const opcode_struct *)aptr, *b = (const opcode_struct *)bptr;
- if(a->bits != b->bits)
- return a->bits - b->bits;
- if(a->op_mask != b->op_mask)
- return a->op_mask - b->op_mask;
- return a->op_match - b->op_match;
-}
-
-static void print_opcode_output_table(FILE* filep)
-{
- int i;
- qsort((void *)g_opcode_output_table, g_opcode_output_table_length, sizeof(g_opcode_output_table[0]), compare_nof_true_bits);
-
- for(i=0;i<g_opcode_output_table_length;i++)
- write_table_entry(filep, g_opcode_output_table+i);
-}
-
-/* Write an entry in the opcode handler table */
-static void write_table_entry(FILE* filep, opcode_struct* op)
-{
- int i;
-
- fprintf(filep, "\t{%-28s, 0x%04x, 0x%04x, {",
- op->name, op->op_mask, op->op_match);
-
- for(i=0;i<NUM_CPUS;i++)
- {
- fprintf(filep, "%3d", op->cycles[i]);
- if(i < NUM_CPUS-1)
- fprintf(filep, ", ");
- }
-
- fprintf(filep, "}},\n");
-}
-
-/* Fill out an opcode struct with a specific addressing mode of the source opcode struct */
-static void set_opcode_struct(opcode_struct* src, opcode_struct* dst, int ea_mode)
-{
- int i;
-
- *dst = *src;
-
- for(i=0;i<NUM_CPUS;i++)
- dst->cycles[i] = get_oper_cycles(dst, ea_mode, i);
- if(strcmp(dst->spec_ea, UNSPECIFIED) == 0 && ea_mode != EA_MODE_NONE)
- sprintf(dst->spec_ea, "%s", g_ea_info_table[ea_mode].fname_add);
- dst->op_mask |= g_ea_info_table[ea_mode].mask_add;
- dst->op_match |= g_ea_info_table[ea_mode].match_add;
-}
-
-
-/* Generate a final opcode handler from the provided data */
-static void generate_opcode_handler(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* opinfo, int ea_mode)
-{
- char str[MAX_LINE_LENGTH+1];
- opcode_struct* op = (opcode_struct *)malloc(sizeof(opcode_struct));
-
- /* Set the opcode structure and write the tables, prototypes, etc */
- set_opcode_struct(opinfo, op, ea_mode);
- get_base_name(str, op);
- add_opcode_output_table_entry(op, str);
- write_function_name(filep, str);
-
- /* Add any replace strings needed */
- if(ea_mode != EA_MODE_NONE)
- {
- sprintf(str, "EA_%s_8()", g_ea_info_table[ea_mode].ea_add);
- add_replace_string(replace, ID_OPHANDLER_EA_AY_8, str);
- sprintf(str, "EA_%s_16()", g_ea_info_table[ea_mode].ea_add);
- add_replace_string(replace, ID_OPHANDLER_EA_AY_16, str);
- sprintf(str, "EA_%s_32()", g_ea_info_table[ea_mode].ea_add);
- add_replace_string(replace, ID_OPHANDLER_EA_AY_32, str);
- sprintf(str, "OPER_%s_8()", g_ea_info_table[ea_mode].ea_add);
- add_replace_string(replace, ID_OPHANDLER_OPER_AY_8, str);
- sprintf(str, "OPER_%s_16()", g_ea_info_table[ea_mode].ea_add);
- add_replace_string(replace, ID_OPHANDLER_OPER_AY_16, str);
- sprintf(str, "OPER_%s_32()", g_ea_info_table[ea_mode].ea_add);
- add_replace_string(replace, ID_OPHANDLER_OPER_AY_32, str);
- }
-
- /* Now write the function body with the selected replace strings */
- write_body(filep, body, replace);
- g_num_functions++;
- free(op);
-}
-
-/* Generate opcode variants based on available addressing modes */
-static void generate_opcode_ea_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op)
-{
- int old_length = replace->length;
-
- /* No ea modes available for this opcode */
- if(HAS_NO_EA_MODE(op->ea_allowed))
- {
- generate_opcode_handler(filep, body, replace, op, EA_MODE_NONE);
- return;
- }
-
- /* Check for and create specific opcodes for each available addressing mode */
- if(HAS_EA_AI(op->ea_allowed))
- generate_opcode_handler(filep, body, replace, op, EA_MODE_AI);
- replace->length = old_length;
- if(HAS_EA_PI(op->ea_allowed))
- {
- generate_opcode_handler(filep, body, replace, op, EA_MODE_PI);
- replace->length = old_length;
- if(op->size == 8)
- generate_opcode_handler(filep, body, replace, op, EA_MODE_PI7);
- }
- replace->length = old_length;
- if(HAS_EA_PD(op->ea_allowed))
- {
- generate_opcode_handler(filep, body, replace, op, EA_MODE_PD);
- replace->length = old_length;
- if(op->size == 8)
- generate_opcode_handler(filep, body, replace, op, EA_MODE_PD7);
- }
- replace->length = old_length;
- if(HAS_EA_DI(op->ea_allowed))
- generate_opcode_handler(filep, body, replace, op, EA_MODE_DI);
- replace->length = old_length;
- if(HAS_EA_IX(op->ea_allowed))
- generate_opcode_handler(filep, body, replace, op, EA_MODE_IX);
- replace->length = old_length;
- if(HAS_EA_AW(op->ea_allowed))
- generate_opcode_handler(filep, body, replace, op, EA_MODE_AW);
- replace->length = old_length;
- if(HAS_EA_AL(op->ea_allowed))
- generate_opcode_handler(filep, body, replace, op, EA_MODE_AL);
- replace->length = old_length;
- if(HAS_EA_PCDI(op->ea_allowed))
- generate_opcode_handler(filep, body, replace, op, EA_MODE_PCDI);
- replace->length = old_length;
- if(HAS_EA_PCIX(op->ea_allowed))
- generate_opcode_handler(filep, body, replace, op, EA_MODE_PCIX);
- replace->length = old_length;
- if(HAS_EA_I(op->ea_allowed))
- generate_opcode_handler(filep, body, replace, op, EA_MODE_I);
- replace->length = old_length;
-}
-
-/* Generate variants of condition code opcodes */
-static void generate_opcode_cc_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op_in, int offset)
-{
- char repl[32];
- char replnot[32];
- int i;
- int old_length = replace->length;
- opcode_struct* op = (opcode_struct *)malloc(sizeof(opcode_struct));
-
- *op = *op_in;
-
- op->op_mask |= 0x0f00;
-
- /* Do all condition codes except t and f */
- for(i=2;i<16;i++)
- {
- /* Add replace strings for this condition code */
- sprintf(repl, "COND_%s()", g_cc_table[i][1]);
- sprintf(replnot, "COND_NOT_%s()", g_cc_table[i][1]);
-
- add_replace_string(replace, ID_OPHANDLER_CC, repl);
- add_replace_string(replace, ID_OPHANDLER_NOT_CC, replnot);
-
- /* Set the new opcode info */
- strcpy(op->name+offset, g_cc_table[i][0]);
-
- op->op_match = (op->op_match & 0xf0ff) | (i<<8);
-
- /* Generate all opcode variants for this modified opcode */
- generate_opcode_ea_variants(filep, body, replace, op);
- /* Remove the above replace strings */
- replace->length = old_length;
- }
- free(op);
-}
-
-/* Process the opcode handlers section of the input file */
-static void process_opcode_handlers(FILE* filep)
-{
- FILE* input_file = g_input_file;
- char func_name[MAX_LINE_LENGTH+1];
- char oper_name[MAX_LINE_LENGTH+1];
- int oper_size = 0;
- char oper_spec_proc[MAX_LINE_LENGTH+1];
- char oper_spec_ea[MAX_LINE_LENGTH+1];
- opcode_struct* opinfo;
- replace_struct* replace = (replace_struct*)malloc(sizeof(replace_struct));
- body_struct* body = (body_struct*)malloc(sizeof(body_struct));
-
- for(;;)
- {
- /* Find the first line of the function */
- func_name[0] = 0;
- while(strstr(func_name, ID_OPHANDLER_NAME) == nullptr)
- {
- if(strcmp(func_name, ID_INPUT_SEPARATOR) == 0)
- {
- free(replace);
- free(body);
- return; /* all done */
- }
- if(fgetline(func_name, MAX_LINE_LENGTH, input_file) < 0)
- error_exit("Premature end of file when getting function name");
- }
- /* Get the rest of the function */
- for(body->length=0;;body->length++)
- {
- if(body->length > MAX_BODY_LENGTH)
- error_exit("Function too long");
-
- if(fgetline(body->body[body->length], MAX_LINE_LENGTH, input_file) < 0)
- error_exit("Premature end of file when getting function body");
-
- if(body->body[body->length][0] == '}')
- {
- body->length++;
- break;
- }
- }
-
- g_num_primitives++;
-
- /* Extract the function name information */
- if(!extract_opcode_info(func_name, oper_name, &oper_size, oper_spec_proc, oper_spec_ea))
- error_exit("Invalid " ID_OPHANDLER_NAME " format");
-
- /* Find the corresponding table entry */
- opinfo = find_opcode(oper_name, oper_size, oper_spec_proc, oper_spec_ea);
- if(opinfo == nullptr)
- error_exit("Unable to find matching table entry for %s", func_name);
-
- replace->length = 0;
-
- /* Generate opcode variants */
- if(strcmp(opinfo->name, "bcc") == 0 || strcmp(opinfo->name, "scc") == 0)
- generate_opcode_cc_variants(filep, body, replace, opinfo, 1);
- else if(strcmp(opinfo->name, "dbcc") == 0)
- generate_opcode_cc_variants(filep, body, replace, opinfo, 2);
- else if(strcmp(opinfo->name, "trapcc") == 0)
- generate_opcode_cc_variants(filep, body, replace, opinfo, 4);
- else
- generate_opcode_ea_variants(filep, body, replace, opinfo);
- }
-
- free(replace);
- free(body);
-}
-
-
-/* Populate the opcode handler table from the input file */
-static void populate_table(void)
-{
- char* ptr;
- char bitpattern[17];
- opcode_struct* op;
- char buff[MAX_LINE_LENGTH];
- int i;
- int temp;
-
- buff[0] = 0;
-
- /* Find the start of the table */
- while (strncmp(buff, ID_TABLE_START, strlen(ID_TABLE_START)) != 0)
- {
- if(fgetline(buff, MAX_LINE_LENGTH, g_input_file) < 0)
- error_exit("(table_start) Premature EOF while reading table");
- }
-
- /* Process the entire table */
- for(op = g_opcode_input_table;;op++)
- {
- if(fgetline(buff, MAX_LINE_LENGTH, g_input_file) < 0)
- error_exit("(inline) Premature EOF while reading table");
- if(strlen(buff) == 0)
- continue;
- /* We finish when we find an input separator */
- if(strcmp(buff, ID_INPUT_SEPARATOR) == 0)
- break;
-
- /* Extract the info from the table */
- ptr = buff;
-
-
- /* Name */
- ptr += skip_spaces(ptr);
- ptr += check_strsncpy(op->name, ptr, MAX_NAME_LENGTH);
-
- /* Size */
- ptr += skip_spaces(ptr);
- ptr += check_atoi(ptr, &temp);
- op->size = (unsigned char)temp;
-
- /* Special processing */
- ptr += skip_spaces(ptr);
- ptr += check_strsncpy(op->spec_proc, ptr, MAX_SPEC_PROC_LENGTH);
-
- /* Specified EA Mode */
- ptr += skip_spaces(ptr);
- ptr += check_strsncpy(op->spec_ea, ptr, MAX_SPEC_EA_LENGTH);
-
- /* Bit Pattern (more processing later) */
- ptr += skip_spaces(ptr);
- ptr += check_strsncpy(bitpattern, ptr, 17);
-
- /* Allowed Addressing Mode List */
- ptr += skip_spaces(ptr);
- ptr += check_strsncpy(op->ea_allowed, ptr, EA_ALLOWED_LENGTH);
-
- /* CPU operating mode (U = user or supervisor, S = supervisor only */
- ptr += skip_spaces(ptr);
- for(i=0;i<NUM_CPUS;i++)
- {
- op->cpu_mode[i] = *ptr++;
- ptr += skip_spaces(ptr);
- }
-
- /* Allowed CPUs for this instruction */
- for(i=0;i<NUM_CPUS;i++)
- {
- ptr += skip_spaces(ptr);
- if(*ptr == UNSPECIFIED_CH)
- {
- op->cpus[i] = UNSPECIFIED_CH;
- op->cycles[i] = 0;
- ptr++;
- }
- else
- {
- op->cpus[i] = '0' + i;
- ptr += check_atoi(ptr, &temp);
- op->cycles[i] = (unsigned char)temp;
- }
- }
-
- /* generate mask and match from bitpattern */
- op->op_mask = 0;
- op->op_match = 0;
- for(i=0;i<16;i++)
- {
- op->op_mask |= (bitpattern[i] != '.') << (15-i);
- op->op_match |= (bitpattern[i] == '1') << (15-i);
- }
- }
- /* Terminate the list */
- op->name[0] = 0;
-}
-
-/* Read a header or footer insert from the input file */
-static void read_insert(char* insert)
-{
- char* ptr = insert;
- char* overflow = insert + MAX_INSERT_LENGTH - MAX_LINE_LENGTH;
- int length;
- char* first_blank = nullptr;
-
- first_blank = nullptr;
-
- /* Skip any leading blank lines */
- for(length = 0;length == 0;length = fgetline(ptr, MAX_LINE_LENGTH, g_input_file))
- if(ptr >= overflow)
- error_exit("Buffer overflow reading inserts");
- if(length < 0)
- error_exit("Premature EOF while reading inserts");
-
- /* Advance and append newline */
- ptr += length;
- strcpy(ptr++, "\n");
-
- /* Read until next separator */
- for(;;)
- {
- /* Read a new line */
- if(ptr >= overflow)
- error_exit("Buffer overflow reading inserts");
- if((length = fgetline(ptr, MAX_LINE_LENGTH, g_input_file)) < 0)
- error_exit("Premature EOF while reading inserts");
-
- /* Stop if we read a separator */
- if(strcmp(ptr, ID_INPUT_SEPARATOR) == 0)
- break;
-
- /* keep track in case there are trailing blanks */
- if(length == 0)
- {
- if(first_blank == nullptr)
- first_blank = ptr;
- }
- else
- first_blank = nullptr;
-
- /* Advance and append newline */
- ptr += length;
- strcpy(ptr++, "\n");
- }
-
- /* kill any trailing blank lines */
- if(first_blank)
- ptr = first_blank;
- *ptr++ = 0;
-}
-
-
-
-/* ======================================================================== */
-/* ============================= MAIN FUNCTION ============================ */
-/* ======================================================================== */
-
-int main(int argc, char *argv[])
-{
- /* File stuff */
- char output_path[M68K_MAX_DIR] = "";
- char filename[M68K_MAX_PATH];
- /* Section identifier */
- char section_id[MAX_LINE_LENGTH+1];
- /* Inserts */
- char temp_insert[MAX_INSERT_LENGTH+1];
- char prototype_footer_insert[MAX_INSERT_LENGTH+1];
- char table_header_insert[MAX_INSERT_LENGTH+1];
- char table_footer_insert[MAX_INSERT_LENGTH+1];
- char ophandler_header_insert[MAX_INSERT_LENGTH+1];
- char ophandler_footer_insert[MAX_INSERT_LENGTH+1];
- /* Flags if we've processed certain parts already */
- int prototype_header_read = 0;
- int prototype_footer_read = 0;
- int table_header_read = 0;
- int table_footer_read = 0;
- int ophandler_header_read = 0;
- int ophandler_footer_read = 0;
- int table_body_read = 0;
- int ophandler_body_read = 0;
-
- printf("\n\tMusashi v%s 680x0, CPU32, and ColdFire emulator\n", g_version);
- printf("\tCopyright Karl Stenerud and the MAME team.\n\n");
-
- /* Check if output path and source for the input file are given */
- if(argc > 1)
- {
- char *ptr;
- strcpy(output_path, argv[1]);
-
- for(ptr = strchr(output_path, '\\'); ptr; ptr = strchr(ptr, '\\'))
- *ptr = '/';
- }
-
- strcpy(g_input_filename, (argc > 2) ? argv[2] : FILENAME_INPUT);
-
- /* Open the files we need */
- sprintf(filename, "%s/%s", output_path, FILENAME_PROTOTYPE);
- if((g_prototype_file = fopen(filename, "wt")) == nullptr)
- perror_exit("Unable to create prototype file (%s)\n", filename);
-
- sprintf(filename, "%s/%s", output_path, FILENAME_TABLE);
- if((g_table_file = fopen(filename, "wt")) == nullptr)
- perror_exit("Unable to create table file (%s)\n", filename);
-
- if((g_input_file=fopen(g_input_filename, "rt")) == nullptr)
- perror_exit("can't open %s for input", g_input_filename);
-
-
- /* Get to the first section of the input file */
- section_id[0] = 0;
- while(strcmp(section_id, ID_INPUT_SEPARATOR) != 0)
- if(fgetline(section_id, MAX_LINE_LENGTH, g_input_file) < 0)
- error_exit("Premature EOF while reading input file");
-
- /* Now process all sections */
- for(;;)
- {
- if(fgetline(section_id, MAX_LINE_LENGTH, g_input_file) < 0)
- error_exit("Premature EOF while reading input file");
- if(strcmp(section_id, ID_PROTOTYPE_HEADER) == 0)
- {
- if(prototype_header_read)
- error_exit("Duplicate prototype header");
- read_insert(temp_insert);
- fprintf(g_prototype_file, "%s\n\n", temp_insert);
- prototype_header_read = 1;
- }
- else if(strcmp(section_id, ID_TABLE_HEADER) == 0)
- {
- if(table_header_read)
- error_exit("Duplicate table header");
- read_insert(table_header_insert);
- table_header_read = 1;
- }
- else if(strcmp(section_id, ID_OPHANDLER_HEADER) == 0)
- {
- if(ophandler_header_read)
- error_exit("Duplicate opcode handler header");
- read_insert(ophandler_header_insert);
- ophandler_header_read = 1;
- }
- else if(strcmp(section_id, ID_PROTOTYPE_FOOTER) == 0)
- {
- if(prototype_footer_read)
- error_exit("Duplicate prototype footer");
- read_insert(prototype_footer_insert);
- prototype_footer_read = 1;
- }
- else if(strcmp(section_id, ID_TABLE_FOOTER) == 0)
- {
- if(table_footer_read)
- error_exit("Duplicate table footer");
- read_insert(table_footer_insert);
- table_footer_read = 1;
- }
- else if(strcmp(section_id, ID_OPHANDLER_FOOTER) == 0)
- {
- if(ophandler_footer_read)
- error_exit("Duplicate opcode handler footer");
- read_insert(ophandler_footer_insert);
- ophandler_footer_read = 1;
- }
- else if(strcmp(section_id, ID_TABLE_BODY) == 0)
- {
- if(!prototype_header_read)
- error_exit("Table body encountered before prototype header");
- if(!table_header_read)
- error_exit("Table body encountered before table header");
- if(!ophandler_header_read)
- error_exit("Table body encountered before opcode handler header");
-
- if(table_body_read)
- error_exit("Duplicate table body");
-
- populate_table();
- table_body_read = 1;
- }
- else if(strcmp(section_id, ID_OPHANDLER_BODY) == 0)
- {
- if(!prototype_header_read)
- error_exit("Opcode handlers encountered before prototype header");
- if(!table_header_read)
- error_exit("Opcode handlers encountered before table header");
- if(!ophandler_header_read)
- error_exit("Opcode handlers encountered before opcode handler header");
- if(!table_body_read)
- error_exit("Opcode handlers encountered before table body");
-
- if(ophandler_body_read)
- error_exit("Duplicate opcode handler section");
-
- fprintf(g_table_file, "%s\n\n", ophandler_header_insert);
- process_opcode_handlers(g_table_file);
- fprintf(g_table_file, "%s\n\n", ophandler_footer_insert);
-
- ophandler_body_read = 1;
- }
- else if(strcmp(section_id, ID_END) == 0)
- {
- /* End of input file. Do a sanity check and then write footers */
- if(!prototype_header_read)
- error_exit("Missing prototype header");
- if(!prototype_footer_read)
- error_exit("Missing prototype footer");
- if(!table_header_read)
- error_exit("Missing table header");
- if(!table_footer_read)
- error_exit("Missing table footer");
- if(!table_body_read)
- error_exit("Missing table body");
- if(!ophandler_header_read)
- error_exit("Missing opcode handler header");
- if(!ophandler_footer_read)
- error_exit("Missing opcode handler footer");
- if(!ophandler_body_read)
- error_exit("Missing opcode handler body");
-
- fprintf(g_table_file, "%s\n\n", table_header_insert);
- print_opcode_output_table(g_table_file);
- fprintf(g_table_file, "%s\n\n", table_footer_insert);
-
- fprintf(g_prototype_file, "%s\n\n", prototype_footer_insert);
-
- break;
- }
- else
- {
- error_exit("Unknown section identifier: %s", section_id);
- }
- }
-
- /* Close all files and exit */
- fclose(g_prototype_file);
- fclose(g_table_file);
- fclose(g_input_file);
-
- printf("Generated %d opcode handlers from %d primitives\n", g_num_functions, g_num_primitives);
-
- return 0;
-}
-
-
-
-/* ======================================================================== */
-/* ============================== END OF FILE ============================= */
-/* ======================================================================== */