/*
 *      Z80 - Assembler
 *      Copyright (C) 1987-1992 by Udo Munk
 *
 *	History:
 *	17-SEP-1987 Development under Digital Research CP/M 2.2
 *      28-JUN-1988 Switched to Unix System V.3
 */

/*
 *      Diese Modul enthaelt die Op-Code-Tabelle. In ihr
 *      sind fuer jeden Z80 Op-Code und alle Pseudo-Op-Codes
 *      ausser END Eintraege vorhanden. Die Tabelle muss
 *      aufsteigend nach den Op-Code-Namen sortiert sein !
 *
 *      Die zweite Tabelle im Modul enthaelt die Namen aller
 *      reservierten Operanden (Register, Registerpaare und Flags.
 *      Sie muss ebenfalls nach den Namen sortiert sein !
 */

#include <stdio.h>
#include "z80a.h"

/*
 *      Die Funktionen zur Codegenerierung der einzelnen
 *      Op-Codes muessen forward deklariert werden:
 */
extern int op_1b(), op_2b(), op_pupo(), op_ex(), op_ld();
extern int op_call(), op_ret(), op_jp(), op_jr(), op_djnz(), op_rst();
extern int op_add(), op_adc(), op_sub(), op_sbc(), op_cp();
extern int op_inc(), op_dec(), op_or(), op_xor(), op_and();
extern int op_rl(), op_rr(), op_sla(), op_sra(), op_srl(), op_rlc(), op_rrc();
extern int op_out(), op_in(), op_im();
extern int op_set(), op_res(), op_bit();
extern int op_org(), op_dl(), op_equ();
extern int op_ds(), op_db(), op_dw(), op_dm();
extern int op_misc();
extern int op_cond();
extern int op_glob();

struct opc opctab[] = {
	{ "ADC",        op_adc,         0,    0    },
	{ "ADD",        op_add,         0,    0    },
	{ "AND",        op_and,         0,    0    },
	{ "BIT",        op_bit,         0,    0    },
	{ "CALL",       op_call,        0,    0    },
	{ "CCF",        op_1b,          0x3f, 0    },
	{ "CP",         op_cp,          0,    0    },
	{ "CPD",        op_2b,          0xed, 0xa9 },
	{ "CPDR",       op_2b,          0xed, 0xb9 },
	{ "CPI",        op_2b,          0xed, 0xa1 },
	{ "CPIR",       op_2b,          0xed, 0xb1 },
	{ "CPL",        op_1b,          0x2f, 0    },
	{ "DAA",        op_1b,          0x27, 0    },
	{ "DEC",        op_dec,         0,    0    },
	{ "DEFB",       op_db,          0,    0    },
	{ "DEFL",       op_dl,          0,    0    },
	{ "DEFM",       op_dm,          0,    0    },
	{ "DEFS",       op_ds,          0,    0    },
	{ "DEFW",       op_dw,          0,    0    },
	{ "DI",         op_1b,          0xf3, 0    },
	{ "DJNZ",       op_djnz,        0,    0    },
	{ "EI",         op_1b,          0xfb, 0    },
	{ "EJECT",      op_misc,        1,    0    },
	{ "ELSE",       op_cond,        98,   0    },
	{ "ENDIF",      op_cond,        99,   0    },
	{ "EQU",        op_equ,         0,    0    },
	{ "EX",         op_ex,          0,    0    },
	{ "EXTRN",      op_glob,        1,    0    },
	{ "EXX",        op_1b,          0xd9, 0    },
	{ "HALT",       op_1b,          0x76, 0    },
	{ "IFDEF",      op_cond,        1,    0    },
	{ "IFEQ",       op_cond,        3,    0    },
	{ "IFNDEF",     op_cond,        2,    0    },
	{ "IFNEQ",      op_cond,        4,    0    },
	{ "IM",         op_im,          0,    0    },
	{ "IN",         op_in,          0,    0    },
	{ "INC",        op_inc,         0,    0    },
	{ "INCLUDE",    op_misc,        6,    0    },
	{ "IND",        op_2b,          0xed, 0xaa },
	{ "INDR",       op_2b,          0xed, 0xba },
	{ "INI",        op_2b,          0xed, 0xa2 },
	{ "INIR",       op_2b,          0xed, 0xb2 },
	{ "JP",         op_jp,          0,    0    },
	{ "JR",         op_jr,          0,    0    },
	{ "LD",         op_ld,          0,    0    },
	{ "LDD",        op_2b,          0xed, 0xa8 },
	{ "LDDR",       op_2b,          0xed, 0xb8 },
	{ "LDI",        op_2b,          0xed, 0xa0 },
	{ "LDIR",       op_2b,          0xed, 0xb0 },
	{ "LIST",       op_misc,        2,    0    },
	{ "NEG",        op_2b,          0xed, 0x44 },
	{ "NOLIST",     op_misc,        3,    0    },
	{ "NOP",        op_1b,          0,    0    },
	{ "OR",         op_or,          0,    0    },
	{ "ORG",        op_org,         0,    0    },
	{ "OTDR",       op_2b,          0xed, 0xbb },
	{ "OTIR",       op_2b,          0xed, 0xb3 },
	{ "OUT",        op_out,         0,    0    },
	{ "OUTD",       op_2b,          0xed, 0xab },
	{ "OUTI",       op_2b,          0xed, 0xa3 },
	{ "PAGE",       op_misc,        4,    0    },
	{ "POP",        op_pupo,        1,    0    },
	{ "PRINT",      op_misc,        5,    0    },
	{ "PUBLIC",     op_glob,        2,    0    },
	{ "PUSH",       op_pupo,        2,    0    },
	{ "RES",        op_res,         0,    0    },
	{ "RET",        op_ret,         0,    0    },
	{ "RETI",       op_2b,          0xed, 0x4d },
	{ "RETN",       op_2b,          0xed, 0x45 },
	{ "RL",         op_rl,          0,    0    },
	{ "RLA",        op_1b,          0x17, 0    },
	{ "RLC",        op_rlc,         0,    0    },
	{ "RLCA",       op_1b,          0x07, 0    },
	{ "RLD",        op_2b,          0xed, 0x6f },
	{ "RR",         op_rr,          0,    0    },
	{ "RRA",        op_1b,          0x1f, 0    },
	{ "RRC",        op_rrc,         0,    0    },
	{ "RRCA",       op_1b,          0x0f, 0    },
	{ "RRD",        op_2b,          0xed, 0x67 },
	{ "RST",        op_rst,         0,    0    },
	{ "SBC",        op_sbc,         0,    0    },
	{ "SCF",        op_1b,          0x37, 0    },
	{ "SET",        op_set,         0,    0    },
	{ "SLA",        op_sla,         0,    0    },
	{ "SRA",        op_sra,         0,    0    },
	{ "SRL",        op_srl,         0,    0    },
	{ "SUB",        op_sub,         0,    0    },
	{ "TITLE",      op_misc,        7,    0    },
	{ "XOR",        op_xor,         0,    0    }
};

/*
 *	Die Anzahl der Eintraege in der Op-Code Tabelle wird fuer die
 *	Suchfunktion search_op() in der Variablen no_opcodes abgelegt.
 */
int no_opcodes = sizeof(opctab) / sizeof(struct opc);

struct ope opetab[] = {
	{ "(BC)",       REGIBC },
	{ "(DE)",       REGIDE },
	{ "(HL)",       REGIHL },
	{ "(IX)",       REGIIX },
	{ "(IY)",       REGIIY },
	{ "(SP)",       REGISP },
	{ "A",          REGA   },
	{ "AF",         REGAF  },
	{ "B",          REGB   },
	{ "BC",         REGBC  },
	{ "C",          REGC   },
	{ "D",          REGD   },
	{ "DE",         REGDE  },
	{ "E",          REGE   },
	{ "H",          REGH   },
	{ "HL",         REGHL  },
	{ "I",          REGI   },
	{ "IX",         REGIX  },
	{ "IY",         REGIY  },
	{ "L",          REGL   },
	{ "M",          FLGM   },
	{ "NC",         FLGNC  },
	{ "NZ",         FLGNZ  },
	{ "P",          FLGP   },
	{ "PE",         FLGPE  },
	{ "PO",         FLGPO  },
	{ "R",          REGR   },
	{ "SP",         REGSP  },
	{ "Z",          FLGZ   }
};

/*
 *      Hier wird ebenfalls die Anzahl der Tabelleneintraege
 *      bekannt gemacht.
 */
int no_operands = sizeof(opetab) / sizeof(struct ope);
