/*
 * ACME - a crossassembler for producing 6502/65c02/65816 code.
 * Copyright (C) 1998 Marco Baye
 * Have a look at "acme.c" for further info
 */

/*
 * Constants for data tables
 */

#ifndef data_H
#define data_H

#include "item.h"

/*
 * Flags for characters
 */

/* Byte is illegal in a keyword */
#define MBYTEILLEGAL    (1u << 7)
/* Byte is uppercase */
#define MBYTEUPPERCASE  (1u << 6)

/*
 * List item types
 */
enum {            /* List item type handles */
 HTYPE_LABEL     ,/* Labels defined during assembly  */
 HTYPE_MACRO     ,/* Macros defined during assembly  */
 HTYPE_PSEUDO    ,/* Pseudo opcodes                  */
 HTYPE_OPERATOR  ,/* Strings of arithmetic operators */
 HTYPE_CPU       ,/* Names of processors             */
 HTYPE_DOLOOP    ,/* Keywords "until" and "while"    */
 HTYPE_ELSE      ,/* Keyword "else"                  */
 HTYPE_6502MNEMO ,/* Mnemonics of standard 6502 instruction set         */
 HTYPE_65C02MNEMO,/* Mnemonics of 65c02 extensions to instruction set   */
 HTYPE_65816MNEMO,/* Mnemonics of 65816 extensions to instruction set   */
 HTYPE_6510MNEMO ,/* Mnemonics of some illegal instructions of the 6510 */
 HTYPE_Z80        /* Mnemonics of the z80 instruction set               */
};

/*
 * Processor handles
 *
 * "1 << (this value)" has to match the flag bit position in the flag table !
 */
#define HCPU_6502       0
#define HCPU_6510       1
#define HCPU_65C02      2
#define HCPU_65816      3
#define HCPU_Z80        4

/*
 * Internal data tables
 */

/*
 * Flag table:
 *
 * This table contains flags for all the 256 possible byte values. The
 * assembler reads the table whenever it needs to know whether a byte is
 * allowed to be in a label name, for example.
 *
 * $00-$1f   control characters
 * $20-$2f   " !"#$%&'()*+,-./"
 * $30-$3f   digits and ":;<=>?"
 * $40-$5f   uppercase characters
 * $60-$7f   lowercase characters
 * $80-$ff   upper half of codes
 *
 * Format:
 *
 * Bit         Meaning when set
 *
 * 7.......    Byte is forbidden in keyword names
 * .6......    Byte is uppercase, can be converted to lowercase by "OR 32"
 * ..5.....    (reserved, currently zero)
 * ...4....    Byte is legal instruction of Z80    (unimplemented)
 * ....3...    Byte is legal instruction of 65816
 * .....2..    Byte is legal instruction of 65c02
 * ......1.    Byte is illegal instruction of 6510 (unimplemented)
 * .......0    Byte is legal instruction of 6502
 */

static unsigned char pFlagTable[256] = {

  0x8f, 0x8f, 0x88, 0x88, 0x8c, 0x8f, 0x8f, 0x88,
  0x8f, 0x8f, 0x8f, 0x88, 0x8c, 0x8f, 0x8f, 0x88,

  0x8f, 0x8f, 0x8c, 0x88, 0x8c, 0x8f, 0x8f, 0x88,
  0x8f, 0x8f, 0x8c, 0x88, 0x8c, 0x8f, 0x8f, 0x88,

  0x8f, 0x8f, 0x88, 0x88, 0x8f, 0x8f, 0x8f, 0x88,
  0x8f, 0x8f, 0x8f, 0x88, 0x8f, 0x8f, 0x8f, 0x88,

  0x0f, 0x0f, 0x0c, 0x08, 0x0c, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x8c, 0x88, 0x8c, 0x8f, 0x8f, 0x88,
  0x8f, 0x4f, 0x48, 0x48, 0x48, 0x4f, 0x4f, 0x48,
  0x4f, 0x4f, 0x4f, 0x48, 0x4f, 0x4f, 0x4f, 0x48,

  0x4f, 0x4f, 0x4c, 0x48, 0x48, 0x4f, 0x4f, 0x48,
  0x4f, 0x4f, 0x4c, 0x88, 0x88, 0x8f, 0x8f, 0x08,

  0x8f, 0x0f, 0x08, 0x08, 0x0c, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0f, 0x08, 0x0f, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0c, 0x08, 0x0c, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0c, 0x88, 0x8c, 0x8f, 0x8f, 0x88,

  0x0c, 0x0f, 0x08, 0x08, 0x0f, 0x0f, 0x0f, 0x08,
  0x0f, 0x0c, 0x0f, 0x08, 0x0f, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0c, 0x08, 0x0f, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0f, 0x08, 0x0c, 0x0f, 0x0c, 0x08,
  0x0f, 0x0f, 0x0f, 0x08, 0x0f, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0f, 0x08, 0x0f, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0c, 0x08, 0x0f, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0f, 0x08, 0x0f, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x08, 0x08, 0x0f, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0f, 0x08, 0x0f, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0c, 0x08, 0x08, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0c, 0x08, 0x08, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x08, 0x08, 0x0f, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0f, 0x08, 0x0f, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0c, 0x08, 0x08, 0x0f, 0x0f, 0x08,
  0x0f, 0x0f, 0x0c, 0x08, 0x08, 0x0f, 0x0f, 0x08
};

/*
 * Code table for groups 5, 6 and 7:
 *
 * This table is needed for finding out the correct code in cases when
 * there are no general rules. By reading the mnemonic's byte value (from the
 * mnemotable), the assembler finds out the row to use here. The column
 * depends on the used addressing mode. A zero entry in these tables means
 * that the combination of mnemonic and addressing mode is illegal.
 *
 * Format:
 *
 *  implicit/accu     16bit
 *  |     #8bit       |     8bit,x
 *  |     |     8bit  |     |     16bit,x
 *  |     |     |     |     |     |     8bit,y
 *  |     |     |     |     |     |     |     16bit,y
 *  |     |     |     |     |     |     |     |
 */

static unsigned char pGroup5Table[160] = {
  0x0a,    0, 0x06, 0x0e, 0x16, 0x1e,    0,    0, /* asl */
  0x2c, 0x89, 0x24, 0x2c, 0x34, 0x3c,    0,    0, /* bit */
     0, 0xe0, 0xe4, 0xec,    0,    0,    0,    0, /* cpx */
     0, 0xc0, 0xc4, 0xcc,    0,    0,    0,    0, /* cpy */
  0x3a,    0, 0xc6, 0xce, 0xd6, 0xde,    0,    0, /* dec */
  0x1a,    0, 0xe6, 0xee, 0xf6, 0xfe,    0,    0, /* inc */
     0, 0xa2, 0xa6, 0xae,    0,    0, 0xb6, 0xbe, /* ldx */
     0, 0xa0, 0xa4, 0xac, 0xb4, 0xbc,    0,    0, /* ldy */
  0x4a,    0, 0x46, 0x4e, 0x56, 0x5e,    0,    0, /* lsr */
  0x2a,    0, 0x26, 0x2e, 0x36, 0x3e,    0,    0, /* rol */
  0x6a,    0, 0x66, 0x6e, 0x76, 0x7e,    0,    0, /* ror */
     0,    0, 0x86, 0x8e,    0,    0, 0x96,    0, /* stx */
     0,    0, 0x84, 0x8c, 0x94,    0,    0,    0, /* sty */
     0,    0, 0x64, 0x9c, 0x74, 0x9e,    0,    0, /* stz */
     0,    0, 0x14, 0x1c,    0,    0,    0,    0, /* trb */
     0,    0, 0x04, 0x0c,    0,    0,    0,    0, /* tsb */
     0,    0, 0x02,    0,    0,    0,    0,    0, /* cop */
     0,    0,    0, 0xf4,    0,    0,    0,    0, /* pea */
     0, 0xc2,    0,    0,    0,    0,    0,    0, /* rep */
     0, 0xe2,    0,    0,    0,    0,    0,    0  /* sep */
};

/*
 * Code table for group 10:
 *
 * This table is needed for finding out the correct code when the mnemonic is
 * "jmp" or "jsr" (or the long versions "jml" and "jsl").
 * By reading the mnemonic's byte value (from the mnemotable), the assembler
 * finds out the column to use here. The row depends on the used addressing
 * mode. A zero entry in these tables means that the combination of mnemonic
 * and addressing mode is illegal.
 *
 * Format:
 *
 * jmp   jsr   jml    jsl
 */

static unsigned char pGroup0Table[20] = {
  0x4c, 0x20,    0,     0, /*  16bit    */
  0x6c,    0,    0,     0, /* (16bit)   */
  0x7c, 0xfc,    0,     0, /* (16bit,x) */
  0x5c, 0x22, 0x5c,  0x22, /*  24bit    */
  0xdc,    0, 0xdc,     0  /* [16bit]   */
};

/*
 * Keyword tables:
 *
 * These tables hold the name and a byte value for several special keywords
 * the assembler must know about, e.g. the pseudo opcodes, the arithmetic
 * and logic operators, the processor names and the assembler mnemonics.
 * After finding the table entry that matches the current string, the assembler
 * loads the entry's byte value(s) and acts upon it.
 *
 * Format:
 *
 *   Pointer to next list item with the same small hash value
 *   Big hash value
 *   Pointer to body (macro) or pointer to handler function (pseudo opcode)
 *     or four data bytes (anything else)
 *   Type of keyword (Pseudo opcode, operator, processor name,
           6502-, 6510-, 65c02-, 65816- or Z80-mnemonic)
 *   Name string, must be at least two characters without terminator
 *   Terminator
 *
 * The mnemonics are split up into groups, each group has its own routine to be
 * dealt with:
 *
 * Group 0: Mnemonics using only implicit addressing. Byte value = opcode.
 * Group 1: The short branch instructions.            Byte value = opcode.
 * Group 2: Mnemonics with 16bit relative addressing. Byte value = opcode.
 * Group 3: The main accumulator stuff. Byte value = "base" opcode; there has
 *     to be an offset added to it according to the used addressing mode.
 * Group 4: As Group 3, but without immediate addressing mode. This only
 *     applies to STA and some illegal instructions of the 6510.
 * Groups 5, 6, 7: Various mnemonics with different addressing modes. Byte
 *     value = row to use when reading the code table.
 *     Group 5 isn't affected by different immediate addressing,
 *     Group 6 means accumulator-related,
 *     Group 7 means index-register-related.
 * Group 8: The "move" commands.                      Byte value = opcode.
 * Group 9: "pei", it only has one addressing mode.   Byte value = opcode.
 * Group 10: The jump instructions. Byte value = column to use when reading
 *     the code table.
 */


/* Two-character strings using byte values */

#define KEY2COUNT_B 1

static KeyStruct2_B pKeyTable2_B[KEY2COUNT_B] = {
  {0, 0, {{HOP_OR}}, HTYPE_OPERATOR, "OR"},
};


/* Three-character strings using byte values */

#define KEY3COUNT_B 100

static KeyStruct3_B pKeyTable3_B[KEY3COUNT_B] = {
/*  {0, 0, {HCPU_Z80  }, HTYPE_CPU       , "z80"},*/
  {0, 0, {{HOP_AND   }}, HTYPE_OPERATOR  , "AND"},
  {0, 0, {{HOP_SL    }}, HTYPE_OPERATOR  , "ASL"},
  {0, 0, {{HOP_DIVIDE}}, HTYPE_OPERATOR  , "DIV"},
  {0, 0, {{HOP_EXOR  }}, HTYPE_OPERATOR  , "EOR"},
  {0, 0, {{HOP_SL    }}, HTYPE_OPERATOR  , "LSL"},
  {0, 0, {{HOP_LSR   }}, HTYPE_OPERATOR  , "LSR"},
  {0, 0, {{HOP_MODULO}}, HTYPE_OPERATOR  , "MOD"},
  {0, 0, {{HOP_EXOR  }}, HTYPE_OPERATOR  , "XOR"},
  {0, 0, {{   96,   3}}, HTYPE_6502MNEMO , "adc"},
  {0, 0, {{   32,   3}}, HTYPE_6502MNEMO , "and"},
  {0, 0, {{    0,   5}}, HTYPE_6502MNEMO , "asl"},
  {0, 0, {{  144,   1}}, HTYPE_6502MNEMO , "bcc"},
  {0, 0, {{  176,   1}}, HTYPE_6502MNEMO , "bcs"},
  {0, 0, {{  240,   1}}, HTYPE_6502MNEMO , "beq"},
  {0, 0, {{    1,   6}}, HTYPE_6502MNEMO , "bit"},
  {0, 0, {{   48,   1}}, HTYPE_6502MNEMO , "bmi"},
  {0, 0, {{  208,   1}}, HTYPE_6502MNEMO , "bne"},
  {0, 0, {{   16,   1}}, HTYPE_6502MNEMO , "bpl"},
  {0, 0, {{    0,   0}}, HTYPE_6502MNEMO , "brk"},
  {0, 0, {{   80,   1}}, HTYPE_6502MNEMO , "bvc"},
  {0, 0, {{  112,   1}}, HTYPE_6502MNEMO , "bvs"},
  {0, 0, {{   24,   0}}, HTYPE_6502MNEMO , "clc"},
  {0, 0, {{  216,   0}}, HTYPE_6502MNEMO , "cld"},
  {0, 0, {{   88,   0}}, HTYPE_6502MNEMO , "cli"},
  {0, 0, {{  184,   0}}, HTYPE_6502MNEMO , "clv"},
  {0, 0, {{  192,   3}}, HTYPE_6502MNEMO , "cmp"},
  {0, 0, {{    2,   7}}, HTYPE_6502MNEMO , "cpx"},
  {0, 0, {{    3,   7}}, HTYPE_6502MNEMO , "cpy"},
  {0, 0, {{    4,   5}}, HTYPE_6502MNEMO , "dec"},
  {0, 0, {{  202,   0}}, HTYPE_6502MNEMO , "dex"},
  {0, 0, {{  136,   0}}, HTYPE_6502MNEMO , "dey"},
  {0, 0, {{   64,   3}}, HTYPE_6502MNEMO , "eor"},
  {0, 0, {{    5,   5}}, HTYPE_6502MNEMO , "inc"},
  {0, 0, {{  232,   0}}, HTYPE_6502MNEMO , "inx"},
  {0, 0, {{  200,   0}}, HTYPE_6502MNEMO , "iny"},
  {0, 0, {{    0,  10}}, HTYPE_6502MNEMO , "jmp"},
  {0, 0, {{    1,  10}}, HTYPE_6502MNEMO , "jsr"},
  {0, 0, {{  160,   3}}, HTYPE_6502MNEMO , "lda"},
  {0, 0, {{    6,   7}}, HTYPE_6502MNEMO , "ldx"},
  {0, 0, {{    7,   7}}, HTYPE_6502MNEMO , "ldy"},
  {0, 0, {{    8,   5}}, HTYPE_6502MNEMO , "lsr"},
  {0, 0, {{  234,   0}}, HTYPE_6502MNEMO , "nop"},
  {0, 0, {{    0,   3}}, HTYPE_6502MNEMO , "ora"},
  {0, 0, {{   72,   0}}, HTYPE_6502MNEMO , "pha"},
  {0, 0, {{    8,   0}}, HTYPE_6502MNEMO , "php"},
  {0, 0, {{  104,   0}}, HTYPE_6502MNEMO , "pla"},
  {0, 0, {{   40,   0}}, HTYPE_6502MNEMO , "plp"},
  {0, 0, {{    9,   5}}, HTYPE_6502MNEMO , "rol"},
  {0, 0, {{   10,   5}}, HTYPE_6502MNEMO , "ror"},
  {0, 0, {{   64,   0}}, HTYPE_6502MNEMO , "rti"},
  {0, 0, {{   96,   0}}, HTYPE_6502MNEMO , "rts"},
  {0, 0, {{  224,   3}}, HTYPE_6502MNEMO , "sbc"},
  {0, 0, {{   56,   0}}, HTYPE_6502MNEMO , "sec"},
  {0, 0, {{  248,   0}}, HTYPE_6502MNEMO , "sed"},
  {0, 0, {{  120,   0}}, HTYPE_6502MNEMO , "sei"},
  {0, 0, {{  128,   4}}, HTYPE_6502MNEMO , "sta"},
  {0, 0, {{   11,   5}}, HTYPE_6502MNEMO , "stx"},
  {0, 0, {{   12,   5}}, HTYPE_6502MNEMO , "sty"},
  {0, 0, {{  170,   0}}, HTYPE_6502MNEMO , "tax"},
  {0, 0, {{  168,   0}}, HTYPE_6502MNEMO , "tay"},
  {0, 0, {{  186,   0}}, HTYPE_6502MNEMO , "tsx"},
  {0, 0, {{  138,   0}}, HTYPE_6502MNEMO , "txa"},
  {0, 0, {{  154,   0}}, HTYPE_6502MNEMO , "txs"},
  {0, 0, {{  152,   0}}, HTYPE_6502MNEMO , "tya"},
  {0, 0, {{  130,   2}}, HTYPE_65816MNEMO, "brl"},
  {0, 0, {{   16,   5}}, HTYPE_65816MNEMO, "cop"},
  {0, 0, {{    2,  10}}, HTYPE_65816MNEMO, "jml"},
  {0, 0, {{    3,  10}}, HTYPE_65816MNEMO, "jsl"},
  {0, 0, {{ 0x54,   8}}, HTYPE_65816MNEMO, "mvn"},
  {0, 0, {{ 0x44,   8}}, HTYPE_65816MNEMO, "mvp"},
  {0, 0, {{   17,   5}}, HTYPE_65816MNEMO, "pea"},
  {0, 0, {{ 0xd4,   9}}, HTYPE_65816MNEMO, "pei"},
  {0, 0, {{   98,   2}}, HTYPE_65816MNEMO, "per"},
  {0, 0, {{  139,   0}}, HTYPE_65816MNEMO, "phb"},
  {0, 0, {{   11,   0}}, HTYPE_65816MNEMO, "phd"},
  {0, 0, {{   75,   0}}, HTYPE_65816MNEMO, "phk"},
  {0, 0, {{  171,   0}}, HTYPE_65816MNEMO, "plb"},
  {0, 0, {{   43,   0}}, HTYPE_65816MNEMO, "pld"},
  {0, 0, {{   18,   5}}, HTYPE_65816MNEMO, "rep"},
  {0, 0, {{  107,   0}}, HTYPE_65816MNEMO, "rtl"},
  {0, 0, {{   19,   5}}, HTYPE_65816MNEMO, "sep"},
  {0, 0, {{  219,   0}}, HTYPE_65816MNEMO, "stp"},
  {0, 0, {{   91,   0}}, HTYPE_65816MNEMO, "tcd"},
  {0, 0, {{   27,   0}}, HTYPE_65816MNEMO, "tcs"},
  {0, 0, {{  123,   0}}, HTYPE_65816MNEMO, "tdc"},
  {0, 0, {{   59,   0}}, HTYPE_65816MNEMO, "tsc"},
  {0, 0, {{  155,   0}}, HTYPE_65816MNEMO, "txy"},
  {0, 0, {{  187,   0}}, HTYPE_65816MNEMO, "tyx"},
  {0, 0, {{  203,   0}}, HTYPE_65816MNEMO, "wai"},
  {0, 0, {{   66,   0}}, HTYPE_65816MNEMO, "wdm"},
  {0, 0, {{  235,   0}}, HTYPE_65816MNEMO, "xba"},
  {0, 0, {{  251,   0}}, HTYPE_65816MNEMO, "xce"},
  {0, 0, {{  128,   1}}, HTYPE_65C02MNEMO, "bra"},
  {0, 0, {{  218,   0}}, HTYPE_65C02MNEMO, "phx"},
  {0, 0, {{   90,   0}}, HTYPE_65C02MNEMO, "phy"},
  {0, 0, {{  250,   0}}, HTYPE_65C02MNEMO, "plx"},
  {0, 0, {{  122,   0}}, HTYPE_65C02MNEMO, "ply"},
  {0, 0, {{   13,   5}}, HTYPE_65C02MNEMO, "stz"},
  {0, 0, {{   14,   5}}, HTYPE_65C02MNEMO, "trb"},
  {0, 0, {{   15,   5}}, HTYPE_65C02MNEMO, "tsb"},
};


/* Four-character strings using byte values */

#define KEY4COUNT_B 3

static KeyStruct4_B pKeyTable4_B[KEY4COUNT_B] = {
  {0, 0, {{HCPU_6502}}, HTYPE_CPU , "6502"},
  {0, 0, {{HCPU_6510}}, HTYPE_CPU , "6510"},
  {0, 0, {{ID_ELSE  }}, HTYPE_ELSE, "else"},
};


/* Five-character strings using byte values */

#define KEY5COUNT_B 4

static KeyStruct5_B pKeyTable5_B[KEY5COUNT_B] = {
  {0, 0, {{HCPU_65816}}, HTYPE_CPU   , "65816"},
  {0, 0, {{HCPU_65C02}}, HTYPE_CPU   , "65c02"},
  {0, 0, {{ID_UNTIL  }}, HTYPE_DOLOOP, "until"},
  {0, 0, {{ID_WHILE  }}, HTYPE_DOLOOP, "while"},
};


/* Two-character strings with a pointer */

#define KEY2COUNT_P 17

static KeyStruct2_P pKeyTable2_P[KEY2COUNT_P] = {
  {0, 0, {(void *) FN_FlowPO_do     }, HTYPE_PSEUDO, "do"},
  {0, 0, {(void *) FN_FlowPO_if     }, HTYPE_PSEUDO, "if"},
  {0, 0, {(void *) FN_FlowPO_zone   }, HTYPE_PSEUDO, "zn"},
  {0, 0, {(void *) FN_FlowPO_subzone}, HTYPE_PSEUDO, "sz"},
  {0, 0, {(void *) FN_PO_al         }, HTYPE_PSEUDO, "al"},
  {0, 0, {(void *) FN_PO_as         }, HTYPE_PSEUDO, "as"},
  {0, 0, {(void *) FN_PO_rl         }, HTYPE_PSEUDO, "rl"},
  {0, 0, {(void *) FN_PO_rs         }, HTYPE_PSEUDO, "rs"},
  {0, 0, {(void *) FN_PO_08         }, HTYPE_PSEUDO, "by"},
  {0, 0, {(void *) FN_PO_16         }, HTYPE_PSEUDO, "wo"},
  {0, 0, {(void *) FN_PO_08         }, HTYPE_PSEUDO, "08"},
  {0, 0, {(void *) FN_PO_16         }, HTYPE_PSEUDO, "16"},
  {0, 0, {(void *) FN_PO_24         }, HTYPE_PSEUDO, "24"},
  {0, 0, {(void *) FN_PO_fill       }, HTYPE_PSEUDO, "fi"},
  {0, 0, {(void *) FN_PO_savelabels }, HTYPE_PSEUDO, "sl"},
  {0, 0, {(void *) FN_PO_text       }, HTYPE_PSEUDO, "tx"},
  {0, 0, {(void *) FN_PO_to         }, HTYPE_PSEUDO, "to"},
};
/*
 * Possible future pseudo opcodes:
 *   "char"
 *   "od", "objectDef" ?
 *   "oe", "objectEnd" ?
 */


/* Three-character strings with a pointer */

#define KEY3COUNT_P 9

static KeyStruct3_P pKeyTable3_P[KEY3COUNT_P] = {
  {0, 0, {(void *) FN_FlowPO_end   }, HTYPE_PSEUDO, "end"},
  {0, 0, {(void *) FN_FlowPO_source}, HTYPE_PSEUDO, "src"},
  {0, 0, {(void *) FN_PO_binary    }, HTYPE_PSEUDO, "bin"},
  {0, 0, {(void *) FN_PO_cbm       }, HTYPE_PSEUDO, "cbm"},
  {0, 0, {(void *) FN_PO_cpu       }, HTYPE_PSEUDO, "cpu"},
  {0, 0, {(void *) FN_PO_petscii   }, HTYPE_PSEUDO, "pet"},
  {0, 0, {(void *) FN_PO_raw       }, HTYPE_PSEUDO, "raw"},
  {0, 0, {(void *) FN_PO_screencode}, HTYPE_PSEUDO, "scr"},
  {0, 0, {(void *) FN_PO_set       }, HTYPE_PSEUDO, "set"},
};


/* Four-character strings with a pointer */

#define KEY4COUNT_P 5

static KeyStruct4_P pKeyTable4_P[KEY4COUNT_P] = {
  {0, 0, {(void *) FN_FlowPO_zone}, HTYPE_PSEUDO, "zone"},
  {0, 0, {(void *) FN_PO_08      }, HTYPE_PSEUDO, "byte"},
  {0, 0, {(void *) FN_PO_16      }, HTYPE_PSEUDO, "word"},
  {0, 0, {(void *) FN_PO_fill    }, HTYPE_PSEUDO, "fill"},
  {0, 0, {(void *) FN_PO_text    }, HTYPE_PSEUDO, "text"},
};


/* Five-character strings with a pointer */

#define KEY5COUNT_P 2

static KeyStruct5_P pKeyTable5_P[KEY5COUNT_P] = {
  {0, 0, {(void *) FN_FlowPO_macro}, HTYPE_PSEUDO, "macro"},
  {0, 0, {(void *) FN_PO_align    }, HTYPE_PSEUDO, "align"},
};


/* Six-character strings with a pointer */

#define KEY6COUNT_P 4

static KeyStruct6_P pKeyTable6_P[KEY6COUNT_P] = {
  {0, 0, {(void *) FN_FlowPO_offset}, HTYPE_PSEUDO, "offset"},
  {0, 0, {(void *) FN_FlowPO_source}, HTYPE_PSEUDO, "source"},
  {0, 0, {(void *) FN_PO_binary    }, HTYPE_PSEUDO, "binary"},
  {0, 0, {(void *) FN_PO_scrxor    }, HTYPE_PSEUDO, "scrxor"},
};


/* Seven-character strings with a pointer */

#define KEY7COUNT_P 1

static KeyStruct7_P pKeyTable7_P[KEY7COUNT_P] = {
  {0, 0, {(void *) FN_FlowPO_subzone}, HTYPE_PSEUDO, "subzone"},
};

/*
 * Prototypes
 */
static void FN_DataTables_Init(void);
static void FN_DataTables_Next(ListItem *, int);

#endif
