summaryrefslogtreecommitdiff
path: root/opcode.h
blob: e5fde3d4967a79c06f3446028f1131cde9a1be15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "tables.h"

#define keypoll 0

#define OPNUM 74
#define EXT_OPNUM 49
#define ORTHO_OPNUM 16

#define C (1 << 0)	/* Carry flag. */
#define Z (1 << 1)	/* Zero flag. */
#define I (1 << 2)	/* Interrupt flag. */
#define V (1 << 6)	/* oVerflow flag. */
#define N (1 << 7)	/* Negative flag. */

/*extern uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode);*/
extern char *showbits(uint64_t value, uint8_t bitnum, uint8_t dbg);

/* reg_expr, and val_expr are the arithmetic expressions
 * that will be used for either the value, or register, such as '+', or '-'.
 */
#define setreg(reg, reg_expr, reg_idx, val, val_expr, val_idx, size) {\
	switch (size) {\
		case 7: reg[(reg_idx) reg_expr 7] = val[(val_idx) val_expr 7];\
		case 6: reg[(reg_idx) reg_expr 6] = val[(val_idx) val_expr 6];\
		case 5: reg[(reg_idx) reg_expr 5] = val[(val_idx) val_expr 5];\
		case 4: reg[(reg_idx) reg_expr 4] = val[(val_idx) val_expr 4];\
		case 3: reg[(reg_idx) reg_expr 3] = val[(val_idx) val_expr 3];\
		case 2: reg[(reg_idx) reg_expr 2] = val[(val_idx) val_expr 2];\
		case 1: reg[(reg_idx) reg_expr 1] = val[(val_idx) val_expr 1];\
		case 0: reg[(reg_idx) reg_expr 0] = val[(val_idx) val_expr 0];\
	}\
}

#define setreg_sw(reg, reg_idx, val, val_idx, prefix, addrmode, type) {\
	switch (type) {\
		case RS: setreg(reg, +, reg_idx, val, +, val_idx, (1 << ((prefix >> 4) & 3))-1); break;\
		case AM: setreg(reg, +, reg_idx, val, +, val_idx, get_addrsize(prefix, addrmode)); break;\
	}\
}

extern uint8_t *addr; /* Address Space. */

union reg {
	uint8_t u8[8];
	uint16_t u16[4];
	uint32_t u32[2];
	uint64_t u64;
};

struct sux {
	union reg ps; /* The processor status register. */
	uint64_t a, b, y, x; /* Registers A, B, X, and Y. */
	uint64_t e; /* Effective address register. */
	uint64_t c, d, s, f; /* Registers C, D, S, and F. */;
	uint64_t pc; /* Program counter. */
	uint64_t sp; /* Stack pointer. */
	uint64_t bp; /* Base pointer. */
	uint64_t r11, r12, r13, r14, r15; /* Registers R11-R15. */;
	uint64_t clk; /* Number of clock cycles.  */
	int nmi : 1; /* NMI flag. */
	int reset : 1; /* Reset flag. */
	int irq : 1; /* IRQ flag. */
};

typedef struct op operand;

struct op {
	uint8_t type;		/* Operand Type. 0 = register, 1 = memory. */
	uint8_t id;		/* Operand Type ID 1. 4 bits. */
	uint8_t rind[2];	/* Register(s) used for register indirect. */
	uint8_t scale;		/* Scale used for SIB. */
	int is_ind : 1;		/* Flag used to determine if this operand is an indirect mode. */
	uint8_t cc;		/* Condition code. 3 bits. */
	uint64_t value;		/* Value of operand (used only by memory operands). */
};

extern int asmmon();

enum sw_type {RS, AM, BYTE};