-
Notifications
You must be signed in to change notification settings - Fork 0
/
registers.h
130 lines (117 loc) · 3.35 KB
/
registers.h
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once
#include <stddef.h>
#include <stdint.h>
/* macro for getting pointer of low/high byte of a 16-bit register given its pointer */
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define LB_PTR(p) ((uint8_t*)((uintptr_t)(p) + 0))
#define HB_PTR(p) ((uint8_t*)((uintptr_t)(p) + 1))
#else
#define LB_PTR(p) ((uint8_t*)((uintptr_t)(p) + 1))
#define HB_PTR(p) ((uint8_t*)((uintptr_t)(p) + 0))
#endif
namespace llz80emu {
/* 8-bit register pair */
#pragma pack(push, 1)
typedef union {
struct {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
uint8_t lo;
uint8_t hi;
#else
uint8_t hi;
uint8_t lo;
#endif
} bytes;
uint16_t word;
} z80_regpair_t;
#pragma pack(pop)
typedef struct {
/* main registers */
#define REG_AF AF.word
#define REG_A AF.bytes.hi
#define REG_F AF.bytes.lo
z80_regpair_t AF;
#define REG_BC BC.word
#define REG_B BC.bytes.hi
#define REG_C BC.bytes.lo
z80_regpair_t BC;
#define REG_DE DE.word
#define REG_D DE.bytes.hi
#define REG_E DE.bytes.lo
z80_regpair_t DE;
#define REG_HL HL.word
#define REG_H HL.bytes.hi
#define REG_L HL.bytes.lo
z80_regpair_t HL;
/* shadow registers */
#define REG_AF_S AF_s.word
#define REG_A_S AF_s.bytes.hi
#define REG_F_S AF_s.bytes.lo
z80_regpair_t AF_s;
#define REG_BC_S BC_s.word
#define REG_B_S BC_s.bytes.hi
#define REG_C_S BC_s.bytes.lo
z80_regpair_t BC_s;
#define REG_DE_S DE_s.word
#define REG_D_S DE_s.bytes.hi
#define REG_E_S DE_s.bytes.lo
z80_regpair_t DE_s;
#define REG_HL_S HL_s.word
#define REG_H_S HL_s.bytes.hi
#define REG_L_S HL_s.bytes.lo
z80_regpair_t HL_s;
/* index registers */
#define REG_IX IX.word
#define REG_IXH IX.bytes.hi
#define REG_IXL IX.bytes.lo
z80_regpair_t IX;
#define REG_IY IY.word
#define REG_IYH IY.bytes.hi
#define REG_IYL IY.bytes.lo
z80_regpair_t IY;
/* stack pointer */
#define REG_SP SP.word
#define REG_SPH SP.bytes.hi
#define REG_SPL SP.bytes.lo
z80_regpair_t SP;
/* program counter */
#define REG_PC PC.word
#define REG_PCH PC.bytes.hi
#define REG_PCL PC.bytes.lo
z80_regpair_t PC;
/* other registers */
#define REG_IR IR.word
#define REG_I IR.bytes.hi
#define REG_R IR.bytes.lo
z80_regpair_t IR;
#define REG_WZ WZ.word
#define REG_W WZ.bytes.hi
#define REG_Z WZ.bytes.lo
z80_regpair_t WZ;
uint8_t Q; // undocumented - contains assembled flags register value
uint16_t MEMPTR; // undocumented - WZ should've been used but that would complicate things
/* instruction fetch */
uint8_t instr; // last instruction byte
/* maskable interrupt */
bool iff1, iff2; // interrupt flip-flops
uint8_t int_mode; // interrupt mode (0-2)
} z80_registers_t;
/* flag bits */
#define Z80_FLAGBIT_S 7
#define Z80_FLAGBIT_Z 6
#define Z80_FLAGBIT_F5 5
#define Z80_FLAGBIT_H 4
#define Z80_FLAGBIT_F3 3
#define Z80_FLAGBIT_PV 2
#define Z80_FLAGBIT_N 1
#define Z80_FLAGBIT_C 0
/* flag bitmasks */
#define Z80_FLAG_S (1 << Z80_FLAGBIT_S)
#define Z80_FLAG_Z (1 << Z80_FLAGBIT_Z)
#define Z80_FLAG_F5 (1 << Z80_FLAGBIT_F5)
#define Z80_FLAG_H (1 << Z80_FLAGBIT_H)
#define Z80_FLAG_F3 (1 << Z80_FLAGBIT_F3)
#define Z80_FLAG_PV (1 << Z80_FLAGBIT_PV)
#define Z80_FLAG_N (1 << Z80_FLAGBIT_N)
#define Z80_FLAG_C (1 << Z80_FLAGBIT_C)
}