summaryrefslogtreecommitdiff
path: root/plugins/ao/eng_ssf/m68kmake.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/ao/eng_ssf/m68kmake.c')
-rw-r--r--plugins/ao/eng_ssf/m68kmake.c1421
1 files changed, 0 insertions, 1421 deletions
diff --git a/plugins/ao/eng_ssf/m68kmake.c b/plugins/ao/eng_ssf/m68kmake.c
deleted file mode 100644
index 00e244b9..00000000
--- a/plugins/ao/eng_ssf/m68kmake.c
+++ /dev/null
@@ -1,1421 +0,0 @@
-/* ======================================================================== */
-/* ========================= LICENSING & COPYRIGHT ======================== */
-/* ======================================================================== */
-/*
- * MUSASHI
- * Version 3.3
- *
- * A portable Motorola M680x0 processor emulation engine.
- * Copyright 1998-2001 Karl Stenerud. All rights reserved.
- *
- * This code may be freely used for non-commercial purposes as long as this
- * copyright notice remains unaltered in the source code and any binary files
- * containing this code in compiled form.
- *
- * All other lisencing terms must be negotiated with the author
- * (Karl Stenerud).
- *
- * The latest version of this code can be obtained at:
- * http://kstenerud.cjb.net
- */
-
-
-
-/* ======================================================================== */
-/* ============================ 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
- */
-
-
-char* g_version = "3.3";
-
-/* ======================================================================== */
-/* =============================== INCLUDES =============================== */
-/* ======================================================================== */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
-
-
-
-/* ======================================================================== */
-/* ============================= CONFIGURATION ============================ */
-/* ======================================================================== */
-
-#define M68K_MAX_PATH 1024
-#define M68K_MAX_DIR 1024
-
-#define NUM_CPUS 3 /* 000, 010, 020 */
-#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 30 /* 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.c"
-#define FILENAME_PROTOTYPE "m68kops.h"
-#define FILENAME_TABLE "m68kops.c"
-#define FILENAME_OPS_AC "m68kopac.c"
-#define FILENAME_OPS_DM "m68kopdm.c"
-#define FILENAME_OPS_NZ "m68kopnz.c"
-
-
-/* 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 ============================== */
-/* ======================================================================== */
-
-#define CPU_TYPE_000 0
-#define CPU_TYPE_010 1
-#define CPU_TYPE_020 2
-
-#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 */
-typedef 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 */
-} opcode_struct;
-
-
-/* All modifications necessary for a specific EA mode of an instruction */
-typedef struct
-{
- char* fname_add;
- char* ea_add;
- unsigned int mask_add;
- unsigned int match_add;
-} ea_info_struct;
-
-
-/* Holds the body of a function */
-typedef struct
-{
- char body[MAX_BODY_LENGTH][MAX_LINE_LENGTH+1];
- int length;
-} body_struct;
-
-
-/* Holds a sequence of search / replace strings */
-typedef struct
-{
- char replace[MAX_REPLACE_LENGTH][2][MAX_LINE_LENGTH+1];
- int length;
-} replace_struct;
-
-
-/* Function Prototypes */
-void error_exit(char* fmt, ...);
-void perror_exit(char* fmt, ...);
-int check_strsncpy(char* dst, char* src, int maxlength);
-int check_atoi(char* str, int *result);
-int skip_spaces(char* str);
-int num_bits(int value);
-int atoh(char* buff);
-int fgetline(char* buff, int nchars, FILE* file);
-int get_oper_cycles(opcode_struct* op, int ea_mode, int cpu_type);
-opcode_struct* find_opcode(char* name, int size, char* spec_proc, char* spec_ea);
-opcode_struct* find_illegal_opcode(void);
-int extract_opcode_info(char* src, char* name, int* size, char* spec_proc, char* spec_ea);
-void add_replace_string(replace_struct* replace, char* search_str, char* replace_str);
-void write_body(FILE* filep, body_struct* body, replace_struct* replace);
-void get_base_name(char* base_name, opcode_struct* op);
-void write_prototype(FILE* filep, char* base_name);
-void write_function_name(FILE* filep, char* base_name);
-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);
-void print_opcode_output_table(FILE* filep);
-void write_table_entry(FILE* filep, opcode_struct* op);
-void set_opcode_struct(opcode_struct* src, opcode_struct* dst, int ea_mode);
-void generate_opcode_handler(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* opinfo, int ea_mode);
-void generate_opcode_ea_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op);
-void generate_opcode_cc_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op_in, int offset);
-void process_opcode_handlers(void);
-void populate_table(void);
-void read_insert(char* insert);
-
-
-
-/* ======================================================================== */
-/* ================================= DATA ================================= */
-/* ======================================================================== */
-
-/* Name of the input file */
-char g_input_filename[M68K_MAX_PATH] = FILENAME_INPUT;
-
-/* File handles */
-FILE* g_input_file = NULL;
-FILE* g_prototype_file = NULL;
-FILE* g_table_file = NULL;
-FILE* g_ops_ac_file = NULL;
-FILE* g_ops_dm_file = NULL;
-FILE* g_ops_nz_file = NULL;
-
-int g_num_functions = 0; /* Number of functions processed */
-int g_num_primitives = 0; /* Number of function primitives read */
-int g_line_number = 1; /* Current line number */
-
-/* Opcode handler table */
-opcode_struct g_opcode_input_table[MAX_OPCODE_INPUT_TABLE_LENGTH];
-
-opcode_struct g_opcode_output_table[MAX_OPCODE_OUTPUT_TABLE_LENGTH];
-int g_opcode_output_table_length = 0;
-
-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 */
-};
-
-
-char* 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) */
-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 */
-int g_ea_cycle_table[13][NUM_CPUS][3] =
-{/* 000 010 020 */
- {{ 0, 0, 0}, { 0, 0, 0}, { 0, 0, 0}}, /* EA_MODE_NONE */
- {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}}, /* EA_MODE_AI */
- {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}}, /* EA_MODE_PI */
- {{ 0, 4, 8}, { 0, 4, 8}, { 0, 4, 4}}, /* EA_MODE_PI7 */
- {{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}}, /* EA_MODE_PD */
- {{ 0, 6, 10}, { 0, 6, 10}, { 0, 5, 5}}, /* EA_MODE_PD7 */
- {{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}}, /* EA_MODE_DI */
- {{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}}, /* EA_MODE_IX */
- {{ 0, 8, 12}, { 0, 8, 12}, { 0, 4, 4}}, /* EA_MODE_AW */
- {{ 0, 12, 16}, { 0, 12, 16}, { 0, 4, 4}}, /* EA_MODE_AL */
- {{ 0, 8, 12}, { 0, 8, 12}, { 0, 5, 5}}, /* EA_MODE_PCDI */
- {{ 0, 10, 14}, { 0, 10, 14}, { 0, 7, 7}}, /* EA_MODE_PCIX */
- {{ 0, 4, 8}, { 0, 4, 8}, { 0, 2, 4}}, /* EA_MODE_I */
-};
-
-/* Extra cycles for JMP instruction (000, 010) */
-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 */
- 8, /* 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) */
-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) */
-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) */
-int g_pea_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 */
- 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 MOVES instruction (010) */
-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) */
-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 */
-void error_exit(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_ops_ac_file) fclose(g_ops_ac_file);
- if(g_ops_dm_file) fclose(g_ops_dm_file);
- if(g_ops_nz_file) fclose(g_ops_nz_file);
- if(g_input_file) fclose(g_input_file);
-
- exit(EXIT_FAILURE);
-}
-
-/* Print an error message, call perror(), and exit with status error */
-void perror_exit(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_ops_ac_file) fclose(g_ops_ac_file);
- if(g_ops_dm_file) fclose(g_ops_dm_file);
- if(g_ops_nz_file) fclose(g_ops_nz_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 */
-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 */
-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 */
-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 */
-int skip_spaces(char* str)
-{
- char* p = str;
-
- while(*p == ' ')
- p++;
-
- return p - str;
-}
-
-/* Count the number of set bits in a value */
-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;
-}
-
-/* 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;
-}
-
-/* Get a line of text from a file, discarding any end-of-line characters */
-int fgetline(char* buff, int nchars, FILE* file)
-{
- int length;
-
- if(fgets(buff, nchars, file) == NULL)
- return -1;
- if(buff[0] == '\r')
- memcpy(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 */
-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 0;
-
- 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 */
- if(cpu_type == CPU_TYPE_000 && ea_mode == EA_MODE_I &&
- ((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];
- }
- return op->cycles[cpu_type] + g_ea_cycle_table[ea_mode][cpu_type][size];
-}
-
-/* Find an opcode in the opcode handler list */
-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 != NULL;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 NULL;
-}
-
-/* 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 != NULL;op++)
- {
- if(strcmp(op->name, "illegal") == 0)
- return op;
- }
- return NULL;
-}
-
-/* Parse an opcode handler name */
-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 == NULL)
- 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 == NULL) 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 */
-void add_replace_string(replace_struct* replace, char* search_str, 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 */
-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) != NULL)
- {
- /* 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");
- }
- fprintf(filep, "%s\n", output);
- }
- fprintf(filep, "\n\n");
-}
-
-/* Generate a base function name from an opcode struct */
-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 prototype of an opcode handler function */
-void write_prototype(FILE* filep, char* base_name)
-{
- fprintf(filep, "void %s(void);\n", base_name);
-}
-
-/* Write the name of an opcode handler function */
-void write_function_name(FILE* filep, char* base_name)
-{
- fprintf(filep, "void %s(void)\n", base_name);
-}
-
-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;
- strcpy(ptr->name, 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 = aptr, *b = 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;
-}
-
-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 */
-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 */
-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 */
-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 = 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);
- write_prototype(g_prototype_file, str);
- 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 */
-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 */
-void generate_opcode_cc_variants(FILE* filep, body_struct* body, replace_struct* replace, opcode_struct* op_in, int offset)
-{
- char repl[20];
- char replnot[20];
- int i;
- int old_length = replace->length;
- opcode_struct* op = 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 */
-void process_opcode_handlers(void)
-{
- FILE* input_file = g_input_file;
- FILE* output_file;
- char func_name[MAX_LINE_LENGTH+1];
- char oper_name[MAX_LINE_LENGTH+1];
- int oper_size;
- char oper_spec_proc[MAX_LINE_LENGTH+1];
- char oper_spec_ea[MAX_LINE_LENGTH+1];
- opcode_struct* opinfo;
- replace_struct* replace = malloc(sizeof(replace_struct));
- body_struct* body = malloc(sizeof(body_struct));
-
-
- output_file = g_ops_ac_file;
-
- for(;;)
- {
- /* Find the first line of the function */
- func_name[0] = 0;
- while(strstr(func_name, ID_OPHANDLER_NAME) == NULL)
- {
- 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 == NULL)
- error_exit("Unable to find matching table entry for %s", func_name);
-
- /* Change output files if we pass 'c' or 'n' */
- if(output_file == g_ops_ac_file && oper_name[0] > 'c')
- output_file = g_ops_dm_file;
- else if(output_file == g_ops_dm_file && oper_name[0] > 'm')
- output_file = g_ops_nz_file;
-
- replace->length = 0;
-
- /* Generate opcode variants */
- if(strcmp(opinfo->name, "bcc") == 0 || strcmp(opinfo->name, "scc") == 0)
- generate_opcode_cc_variants(output_file, body, replace, opinfo, 1);
- else if(strcmp(opinfo->name, "dbcc") == 0)
- generate_opcode_cc_variants(output_file, body, replace, opinfo, 2);
- else if(strcmp(opinfo->name, "trapcc") == 0)
- generate_opcode_cc_variants(output_file, body, replace, opinfo, 4);
- else
- generate_opcode_ea_variants(output_file, body, replace, opinfo);
- }
-
- free(replace);
- free(body);
-}
-
-
-/* Populate the opcode handler table from the input file */
-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(strcmp(buff, ID_TABLE_START) != 0)
- if(fgetline(buff, MAX_LINE_LENGTH, g_input_file) < 0)
- error_exit("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("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 */
-void read_insert(char* insert)
-{
- char* ptr = insert;
- char* overflow = insert + MAX_INSERT_LENGTH - MAX_LINE_LENGTH;
- int length;
- char* first_blank = NULL;
-
- first_blank = NULL;
-
- /* 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 == NULL)
- first_blank = ptr;
- }
- else
- first_blank = NULL;
-
- /* 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_footer_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\t\tMusashi v%s 68000, 68010, 68EC020, 68020 emulator\n", g_version);
- printf("\t\tCopyright 1998-2000 Karl Stenerud (karl@mame.net)\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 = '/';
- if(output_path[strlen(output_path)-1] != '/')
- strcat(output_path, "/");
- if(argc > 2)
- strcpy(g_input_filename, argv[2]);
- }
-
-
- /* Open the files we need */
- sprintf(filename, "%s%s", output_path, FILENAME_PROTOTYPE);
- if((g_prototype_file = fopen(filename, "wt")) == NULL)
- 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")) == NULL)
- perror_exit("Unable to create table file (%s)\n", filename);
-
- sprintf(filename, "%s%s", output_path, FILENAME_OPS_AC);
- if((g_ops_ac_file = fopen(filename, "wt")) == NULL)
- perror_exit("Unable to create ops ac file (%s)\n", filename);
-
- sprintf(filename, "%s%s", output_path, FILENAME_OPS_DM);
- if((g_ops_dm_file = fopen(filename, "wt")) == NULL)
- perror_exit("Unable to create ops dm file (%s)\n", filename);
-
- sprintf(filename, "%s%s", output_path, FILENAME_OPS_NZ);
- if((g_ops_nz_file = fopen(filename, "wt")) == NULL)
- perror_exit("Unable to create ops nz file (%s)\n", filename);
-
- if((g_input_file=fopen(g_input_filename, "rt")) == NULL)
- 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(temp_insert);
- fprintf(g_table_file, "%s", temp_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(temp_insert);
- fprintf(g_ops_ac_file, "%s\n\n", temp_insert);
- fprintf(g_ops_dm_file, "%s\n\n", temp_insert);
- fprintf(g_ops_nz_file, "%s\n\n", temp_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");
-
- process_opcode_handlers();
-
- 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");
-
- print_opcode_output_table(g_table_file);
-
- fprintf(g_prototype_file, "%s\n\n", prototype_footer_insert);
- fprintf(g_table_file, "%s\n\n", table_footer_insert);
- fprintf(g_ops_ac_file, "%s\n\n", ophandler_footer_insert);
- fprintf(g_ops_dm_file, "%s\n\n", ophandler_footer_insert);
- fprintf(g_ops_nz_file, "%s\n\n", ophandler_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_ops_ac_file);
- fclose(g_ops_dm_file);
- fclose(g_ops_nz_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 ============================= */
-/* ======================================================================== */