30#pragma GCC optimize ("O2")
37#define COMPOSE_STATUS (0x20 | ((int)m_carry) | ((int)m_zero << 1) | ((int)m_intDisable << 2) | ((int)m_decimal << 3) | ((int)m_overflow << 6) | ((int) m_negative << 7))
41#define DECOMPOSE_STATUS(status) { \
45 m_intDisable = s & 0x04; \
46 m_decimal = s & 0x08; \
47 m_overflow = s & 0x40; \
48 m_negative = s & 0x80; \
53#define BUSREAD(addr) (m_readByte(m_context, (addr)))
54#define BUSWRITE(addr, value) (m_writeByte(m_context, (addr), (value)))
55#define PAGE0READ(addr) (m_page0ReadByte(m_context, (addr)))
56#define PAGE0WRITE(addr, value) (m_page0WriteByte(m_context, (addr), (value)))
57#define PAGE1READ(addr) (m_page1ReadByte(m_context, (addr)))
58#define PAGE1WRITE(addr, value) (m_page1WriteByte(m_context, (addr), (value)))
61#define STACKPUSHBYTE(v) PAGE1WRITE(m_SP--, (v))
63#define STACKPUSHWORD(v) { PAGE1WRITE(m_SP--, (v) >> 8); PAGE1WRITE(m_SP--, (v) & 0xff); }
65#define STACKPOPBYTE() PAGE1READ(++m_SP)
67#define STACKPOPWORD() (m_SP += 2, (PAGE1READ(m_SP - 1) | (PAGE1READ(m_SP) << 8)))
74 m_PC = (BUSREAD(0xfffd) << 8) + BUSREAD(0xfffc);
85 STACKPUSHBYTE(COMPOSE_STATUS);
86 m_PC = (BUSREAD(0xffff) << 8) + BUSREAD(0xfffe);
97 STACKPUSHBYTE(COMPOSE_STATUS);
98 m_PC = (BUSREAD(0xfffb) << 8) + BUSREAD(0xfffa);
104void MOS6502::setADCSBC()
107 m_OP_ADC = &MOS6502::OP_BCDADC;
108 m_OP_SBC = &MOS6502::OP_BCDSBC;
110 m_OP_ADC = &MOS6502::OP_BINADC;
111 m_OP_SBC = &MOS6502::OP_BINSBC;
116void MOS6502::OP_BINADC(uint8_t m)
118 uint32_t t = m + m_A + (int)m_carry;
119 m_zero = !(t & 0xff);
120 m_negative = t & 0x80;
121 m_overflow = !((m_A ^ m) & 0x80) && ((m_A ^ t) & 0x80);
127void MOS6502::OP_BINSBC(uint8_t m)
129 uint32_t t = m_A - m - (int)(!m_carry);
130 m_zero = !(t & 0xff);
131 m_negative = t & 0x80;
132 m_overflow = ((m_A ^ t) & 0x80) && ((m_A ^ m) & 0x80);
133 m_carry = !(t & 0x100);
138void MOS6502::OP_BCDADC(uint8_t m)
140 uint32_t t = m + m_A + (int)m_carry;
141 m_zero = !(t & 0xff);
142 if (((m_A & 0x0f) + (m & 0x0f) + (
int)m_carry) > 9)
144 m_negative = t & 0x80;
145 m_overflow = !((m_A ^ m) & 0x80) && ((m_A ^ t) & 0x80);
153void MOS6502::OP_BCDSBC(uint8_t m)
155 uint32_t t = m_A - m - (int)(!m_carry);
156 m_zero = !(t & 0xff);
157 m_negative = t & 0x80;
158 m_overflow = ((m_A ^ t) & 0x80) && ((m_A ^ m) & 0x80);
159 if (((m_A & 0x0f) - (int)(!m_carry)) < (m & 0x0f))
171 m_negative = m_A & 0x80; \
176 m_carry = m & 0x80; \
177 m = (m << 1) & 0xff; \
179 m_negative = m & 0x80; \
184 m_zero = !(m & m_A); \
185 m_overflow = m & 0x40; \
186 m_negative = m & 0x80; \
191 uint32_t t = m_A - m; \
192 m_zero = !(t & 0xff); \
193 m_carry = !(t & 0x100); \
194 m_negative = t & 0x80; \
199 uint32_t t = m_X - m; \
200 m_zero = !(t & 0xff); \
201 m_carry = !(t & 0x100); \
202 m_negative = t & 0x80; \
207 uint32_t t = m_Y - m; \
208 m_zero = !(t & 0xff); \
209 m_carry = !(t & 0x100); \
210 m_negative = t & 0x80; \
215 m = (m - 1) & 0xff; \
217 m_negative = m & 0x80; \
224 m_negative = m_A & 0x80; \
229 m = (m + 1) & 0xff; \
230 m_negative = m & 0x80; \
237 m_negative = m & 0x80; \
244 m_negative = m & 0x80; \
251 m_negative = m & 0x80; \
257 m_negative = false; \
258 m_carry = m & 0x01; \
266 m_negative = m_A & 0x80; \
272 m = (m << 1) | (int)m_carry; \
273 m_carry = m & 0x100; \
275 m_negative = m & 0x80; \
281 m |= (int)m_carry << 8; \
282 m_carry = m & 0x01; \
283 m = (m >> 1) & 0xff; \
284 m_negative = m & 0x80; \
289#define PAGECROSS() (al >> 8)
294 m = BUSREAD(m_PC++); \
299#define ADR_ZABS_GETADDR { \
300 a = BUSREAD(m_PC++); \
309#define ADR_ZABSX_GETADDR { \
310 a = (BUSREAD(m_PC++) + m_X) & 0xff; \
319#define ADR_ZABSY_GETADDR { \
320 a = (BUSREAD(m_PC++) + m_Y) & 0xff; \
329#define ADR_ABS_GETADDR { \
330 a = BUSREAD(m_PC) | (BUSREAD(m_PC + 1) << 8); \
340#define ADR_ABSX_GETADDR { \
341 al = BUSREAD(m_PC++) + m_X; \
342 a = al + (BUSREAD(m_PC++) << 8); \
351#define ADR_ABSY_GETADDR { \
352 al = BUSREAD(m_PC++) + m_Y; \
353 a = al + (BUSREAD(m_PC++) << 8); \
362#define ADR_IIND_GETADDR { \
363 int l = (BUSREAD(m_PC++) + m_X) & 0xff; \
364 int h = (l + 1) & 0xff; \
365 a = PAGE0READ(l) | (PAGE0READ(h) << 8); \
374#define ADR_INDI_GETADDR { \
375 int l = BUSREAD(m_PC++); \
376 int h = (l + 1) & 0xff; \
377 al = PAGE0READ(l) + m_Y; \
378 a = al + (PAGE0READ(h) << 8); \
388 m = (int8_t)BUSREAD(m_PC++); \
390 al = (m_PC & 0xff) + m; \
396 int l = BUSREAD(m_PC++); \
397 int h = BUSREAD(m_PC++); \
400 h = BUSREAD((a & 0xff00) | ((a + 1) & 0xff)); \
411 switch (BUSREAD(m_PC++)) {
418 (this->*m_OP_ADC)(m);
424 (this->*m_OP_ADC)(m);
430 (this->*m_OP_ADC)(m);
436 (this->*m_OP_ADC)(m);
442 (this->*m_OP_ADC)(m);
443 return 4 + PAGECROSS();
448 (this->*m_OP_ADC)(m);
449 return 4 + PAGECROSS();
454 (this->*m_OP_ADC)(m);
460 (this->*m_OP_ADC)(m);
461 return 5 + PAGECROSS();
493 return 4 + PAGECROSS();
499 return 4 + PAGECROSS();
511 return 5 + PAGECROSS();
560 return 3 + PAGECROSS();
570 return 3 + PAGECROSS();
583 return 3 + PAGECROSS();
610 return 3 + PAGECROSS();
626 return 3 + PAGECROSS();
639 return 3 + PAGECROSS();
648 STACKPUSHBYTE(COMPOSE_STATUS | 0x10);
650 m_PC = (BUSREAD(0xffff) << 8) + BUSREAD(0xfffe);
663 return 3 + PAGECROSS();
673 return 3 + PAGECROSS();
695 m_intDisable =
false;
734 return 4 + PAGECROSS();
740 return 4 + PAGECROSS();
752 return 5 + PAGECROSS();
827 m_X = (m_X - 1) & 0xff;
828 m_negative = m_X & 0x80;
835 m_Y = (m_Y - 1) & 0xff;
836 m_negative = m_Y & 0x80;
870 return 4 + PAGECROSS();
876 return 4 + PAGECROSS();
888 return 5 + PAGECROSS();
923 m_X = (m_X + 1) & 0xff;
924 m_negative = m_X & 0x80;
931 m_Y = (m_Y + 1) & 0xff;
932 m_negative = m_Y & 0x80;
954 a = (m_PC + 1) & 0xffff;
990 return 4 + PAGECROSS();
996 return 4 + PAGECROSS();
1008 return 5 + PAGECROSS();
1040 return 4 + PAGECROSS();
1072 return 4 + PAGECROSS();
1146 return 4 + PAGECROSS();
1152 return 4 + PAGECROSS();
1164 return 5 + PAGECROSS();
1175 STACKPUSHBYTE(COMPOSE_STATUS | 0x10);
1181 m_A = STACKPOPBYTE();
1183 m_negative = m_A & 0x80;
1189 DECOMPOSE_STATUS(STACKPOPBYTE());
1270 DECOMPOSE_STATUS(STACKPOPBYTE());
1271 m_PC = STACKPOPWORD();
1279 m_PC = STACKPOPWORD() + 1;
1288 (this->*m_OP_SBC)(m);
1294 (this->*m_OP_SBC)(m);
1300 (this->*m_OP_SBC)(m);
1306 (this->*m_OP_SBC)(m);
1312 (this->*m_OP_SBC)(m);
1313 return 4 + PAGECROSS();
1318 (this->*m_OP_SBC)(m);
1319 return 4 + PAGECROSS();
1324 (this->*m_OP_SBC)(m);
1330 (this->*m_OP_SBC)(m);
1331 return 5 + PAGECROSS();
1349 m_intDisable =
true;
1441 m_negative = m_X & 0x80;
1449 m_negative = m_Y & 0x80;
1457 m_negative = m_X & 0x80;
1465 m_negative = m_A & 0x80;
1479 m_negative = m_A & 0x80;
1526 (this->*m_OP_SBC)(m);
1533 (this->*m_OP_SBC)(m);
1540 (this->*m_OP_SBC)(m);
1547 (this->*m_OP_SBC)(m);
1554 (this->*m_OP_SBC)(m);
1561 (this->*m_OP_SBC)(m);
1568 (this->*m_OP_SBC)(m);
This file contains fabgl::MOS6502 definition.