#ifndef __DEC_H__
#define __DEC_H__ 1

#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif

#define uint8_t unsigned char
#define uint16_t unsigned short
#define uint32_t unsigned int
#define uint64_t unsigned long long

typedef uint32_t CODE_ADDR;
typedef uint64_t FLAGS;

// retargetable framework for 8-bit machine disassembly.
// Actual disassembly done by external call, and disassembles only 1 opcode at a time.
// Machine-specific disassembler support:

// Was hoping I could have kept all flags in 32 bits, but couldn't quite manage it...

#define F_present               1LL // something was loaded at this address. not a gap.
#define F_invalid_memory        2LL // not in the used address space, so can help to eliminate invalid address operands 
#define F_leads_to_bad_code     4LL // may look like code but a treewalk that passes through here
                                    // eventually leads to an illegal instruction or otherwise implausible code sequence.
#define F_Visited               8LL
#define F_EntryPoint           16LL
#define F_unconditional_jump   32LL // This code does not drop through to the following instruction.
#define F_explicit_jump        64LL // eg BRA BCS JSR etc - there is a target address associated with this
                                    // that is different from the following instruction.
#define F_OPCODE              128LL // The byte at this address is definitely the first byte of an instruction.
#define F_OPERAND             256LL // This is either a byte in a multi-byte opcode, or an operand.  We don't
                                    // really care which, just that it is not the first byte of an instruction
                                    // and therefore not someplace that you would want to be jumping into.
#define F_data                512LL // data byte. May also have one of the following attributes:

#define F_char               1024LL
#define F_decimal            2048LL
#define F_hex                4096LL
#define F_word_hi            8192LL // 16-bit quantity - output both bytes as a unit.  Or in certain cases, as "label DIV 256" vs "label MOD 256"
#define F_word_lo           16384LL
#define F_addr_hi           32768LL // jump table entry, or pointer to data etc - show using a laabel if possible
#define F_addr_lo           65536LL
#define F_start_of_table   131072LL // array of data, usually from indexed load.

#define F_Label            262144LL // Requires a label or a case label in the SBT. Optionally qualified by:

#define F_ProcedureEntry   524288LL
#define F_JumpTarget      1048576LL
#define F_ReturnTo        2097152LL // Immediately follows a JSR/BSR etc.  Only returned to, never explicitly jumped to or called
                                    // unless also flagged with F_ProcedureEntry or F_JumpTarget.  I.e. this is not a label that
                                    // is required for a disassembly listing, only for a SBT translation jump target.
#define F_READONLY        4194304LL // any instruction that writes to a readonly address is probably illegal
#define F_may_be_valid_OPCODE   8388608LL // used to tentatively mark while pre-scanning
#define F_may_be_valid_OPERAND 16777216LL // used to tentatively mark while pre-scanning
#define F_enqueued             33554432LL
#define F_may_be_jump_target   67108864LL
#define F_Definite            134217728LL
#define F_diffy               268435456LL
#define F_ascii_string        536870912LL
#define F_V_string           1073741824LL
#define F_packet             2147483648LL
#define F_duffy              4294967296LL
#define F_diffduff (F_diffy|F_duffy)
#define MAX_DISASM  256 // max length of disassembled string for one instruction

// Separate rom areas.  Usually only one.  But a file of S records can have gaps...
#define MAX_SEGMENTS 64
extern int next_free_segment;
extern CODE_ADDR segstart[MAX_SEGMENTS];
extern CODE_ADDR seglen[MAX_SEGMENTS];

// These could be made sparse at the expense of complexity
extern uint8_t    mem[0x10000];
extern uint8_t    DP[0x10000];
extern FLAGS      F[0x10000];
extern FLAGS      TempF[0x10000];
extern CODE_ADDR  branch[0x10000];

#endif // __DEC_H__
