42#pragma GCC optimize ("O2")
48#define RD_BYTE(addr) m_readByte(m_context, addr)
49#define RD_WORD(addr) m_readWord(m_context, addr)
51#define WR_BYTE(addr, value) m_writeByte(m_context, addr, value)
52#define WR_WORD(addr, value) m_writeWord(m_context, addr, value)
88#define C_FLAG FLAGS.carry_flag
89#define P_FLAG FLAGS.parity_flag
90#define H_FLAG FLAGS.half_carry_flag
91#define Z_FLAG FLAGS.zero_flag
92#define S_FLAG FLAGS.sign_flag
93#define UN1_FLAG FLAGS.unused1
94#define UN3_FLAG FLAGS.unused3
95#define UN5_FLAG FLAGS.unused5
97#define SET(flag) (flag = 1)
98#define CLR(flag) (flag = 0)
99#define TST(flag) (flag)
100#define CPL(flag) (flag = !flag)
102#define POP(reg) { (reg) = RD_WORD(SP); SP += 2; }
103#define PUSH(reg) { SP -= 2; WR_WORD(SP, (reg)); }
104#define RET() { POP(PC); }
105#define STC() { SET(C_FLAG); }
106#define CMC() { CPL(C_FLAG); }
111 S_FLAG = (((reg) & 0x80) != 0); \
112 Z_FLAG = ((reg) == 0); \
113 H_FLAG = (((reg) & 0x0f) == 0); \
114 P_FLAG = PARITY(reg); \
120 S_FLAG = (((reg) & 0x80) != 0); \
121 Z_FLAG = ((reg) == 0); \
122 H_FLAG = !(((reg) & 0x0f) == 0x0f); \
123 P_FLAG = PARITY(reg); \
128 work16 = (uint16_t)A + (val); \
129 index = ((A & 0x88) >> 1) | \
130 (((val) & 0x88) >> 2) | \
131 ((work16 & 0x88) >> 3); \
133 S_FLAG = ((A & 0x80) != 0); \
135 H_FLAG = half_carry_table[index & 0x7]; \
136 P_FLAG = PARITY(A); \
137 C_FLAG = ((work16 & 0x0100) != 0); \
142 work16 = (uint16_t)A + (val) + C_FLAG; \
143 index = ((A & 0x88) >> 1) | \
144 (((val) & 0x88) >> 2) | \
145 ((work16 & 0x88) >> 3); \
147 S_FLAG = ((A & 0x80) != 0); \
149 H_FLAG = half_carry_table[index & 0x7]; \
150 P_FLAG = PARITY(A); \
151 C_FLAG = ((work16 & 0x0100) != 0); \
156 work16 = (uint16_t)A - (val); \
157 index = ((A & 0x88) >> 1) | \
158 (((val) & 0x88) >> 2) | \
159 ((work16 & 0x88) >> 3); \
161 S_FLAG = ((A & 0x80) != 0); \
163 H_FLAG = !sub_half_carry_table[index & 0x7]; \
164 P_FLAG = PARITY(A); \
165 C_FLAG = ((work16 & 0x0100) != 0); \
170 work16 = (uint16_t)A - (val) - C_FLAG; \
171 index = ((A & 0x88) >> 1) | \
172 (((val) & 0x88) >> 2) | \
173 ((work16 & 0x88) >> 3); \
175 S_FLAG = ((A & 0x80) != 0); \
177 H_FLAG = !sub_half_carry_table[index & 0x7]; \
178 P_FLAG = PARITY(A); \
179 C_FLAG = ((work16 & 0x0100) != 0); \
184 work16 = (uint16_t)A - (val); \
185 index = ((A & 0x88) >> 1) | \
186 (((val) & 0x88) >> 2) | \
187 ((work16 & 0x88) >> 3); \
188 S_FLAG = ((work16 & 0x80) != 0); \
189 Z_FLAG = ((work16 & 0xff) == 0); \
190 H_FLAG = !sub_half_carry_table[index & 0x7]; \
191 C_FLAG = ((work16 & 0x0100) != 0); \
192 P_FLAG = PARITY(work16 & 0xff); \
197 H_FLAG = ((A | val) & 0x08) != 0; \
199 S_FLAG = ((A & 0x80) != 0); \
201 P_FLAG = PARITY(A); \
208 S_FLAG = ((A & 0x80) != 0); \
211 P_FLAG = PARITY(A); \
218 S_FLAG = ((A & 0x80) != 0); \
221 P_FLAG = PARITY(A); \
227 work32 = (uint32_t)HL + (reg); \
228 HL = work32 & 0xffff; \
229 C_FLAG = ((work32 & 0x10000L) != 0); \
244#define PARITY(reg) getParity(reg)
247int getParity(
int val)
251 return !((0x6996 >> val) & 1);
255static const int half_carry_table[] = { 0, 0, 1, 0, 1, 0, 1, 1 };
256static const int sub_half_carry_table[] = { 0, 1, 1, 1, 0, 0, 0, 1 };
274void i8080::store_flags()
276 if (S_FLAG) F |= F_NEG;
else F &= ~F_NEG;
277 if (Z_FLAG) F |= F_ZERO;
else F &= ~F_ZERO;
278 if (H_FLAG) F |= F_HCARRY;
else F &= ~F_HCARRY;
279 if (P_FLAG) F |= F_PARITY;
else F &= ~F_PARITY;
280 if (C_FLAG) F |= F_CARRY;
else F &= ~F_CARRY;
287void i8080::retrieve_flags()
289 S_FLAG = F & F_NEG ? 1 : 0;
290 Z_FLAG = F & F_ZERO ? 1 : 0;
291 H_FLAG = F & F_HCARRY ? 1 : 0;
292 P_FLAG = F & F_PARITY ? 1 : 0;
293 C_FLAG = F & F_CARRY ? 1 : 0;
299 int opcode = RD_BYTE(PC++);
349 C_FLAG = ((A & 0x80) != 0);
350 A = (A << 1) | C_FLAG;
386 A = (A >> 1) | (C_FLAG << 7);
422 work8 = (uint8_t)C_FLAG;
423 C_FLAG = ((A & 0x80) != 0);
424 A = (A << 1) | work8;
459 work8 = (uint8_t)C_FLAG;
461 A = (A >> 1) | (work8 << 7);
472 WR_WORD(RD_WORD(PC), HL);
498 carry = (uint8_t)C_FLAG;
500 if (H_FLAG || (A & 0x0f) > 9) {
503 if (C_FLAG || (A >> 4) > 9 || ((A >> 4) >= 9 && (A & 0x0f) > 9)) {
519 HL = RD_WORD(RD_WORD(PC));
556 WR_BYTE(RD_WORD(PC), A);
581 WR_BYTE(HL, RD_BYTE(PC++));
596 A = RD_BYTE(RD_WORD(PC));
1011 work8 = RD_BYTE(HL);
1052 work8 = RD_BYTE(HL);
1093 work8 = RD_BYTE(HL);
1134 work8 = RD_BYTE(HL);
1175 work8 = RD_BYTE(HL);
1216 work8 = RD_BYTE(HL);
1257 work8 = RD_BYTE(HL);
1312 work8 = RD_BYTE(PC++);
1364 work8 = RD_BYTE(PC++);
1397 m_writeIO(m_context, RD_BYTE(PC++), A);
1417 work8 = RD_BYTE(PC++);
1445 A = m_readIO(m_context, RD_BYTE(PC++));
1460 work8 = RD_BYTE(PC++);
1494 work16 = RD_WORD(SP);
1516 work8 = RD_BYTE(PC++);
1566 work8 = RD_BYTE(PC++);
1621 work8 = RD_BYTE(PC++);
1669 work8 = RD_BYTE(PC++);
This file contains fabgl::i8080 definition.