Nghĩ rằng tôi sẽ đi trước và đăng thực hiện của riêng tôi. Đó là HOÀN TOÀN vô căn cứ, nhưng đó là một thực hiện đầy đủ.
- 668 dòng của C. (không tính các dòng trống hoặc dòng chỉ có ý kiến)
- Hỗ trợ (tôi nghĩ) tất cả các hướng dẫn không có giấy tờ.
- Hỗ trợ BCD.
- Đồng hồ CPU chu kỳ thời gian. (bao gồm các điều chỉnh trên các kết thúc giới hạn trang nhất định)
- Có thể thực hiện các hướng dẫn bằng một bước hoặc bằng cách chỉ định số lượng bọ ve.
- Hỗ trợ hook một chức năng bên ngoài được gọi sau khi mọi lệnh được thực hiện. Điều này là do ban đầu nó là cho một trình giả lập NES và tôi đã sử dụng nó cho thời gian âm thanh.
/ * Lõi giả lập CPU Fake6502 v1.1 ****** / TÌM HIỂU
* (c) 2011-2013 Mike Chambers *
****** / TÌM KIẾM *** /
#inc loại <stdio.h>
#inc loại <stdint.h>
// các hàm được cung cấp bên ngoài
extern uint8_t read6502 (địa chỉ uint16_t);
extern void write6502 (địa chỉ uint16_t, giá trị uint8_t);
// 6502 định nghĩa
#define UNDOCUMENTED // khi điều này được xác định, các opcodes không có giấy tờ được xử lý.
// nếu không, chúng chỉ đơn giản được coi là NOP.
// # xác định NES_CPU // khi điều này được xác định, số thập phân được mã hóa nhị phân (BCD)
// cờ trạng thái không được vinh danh bởi ADC và SBC. 2A03
// CPU trong Hệ thống giải trí Nintendo không
// hỗ trợ hoạt động BCD.
#define FLAG_CARRY 0x01
#define FLAG_ZERO 0x02
#define FLAG_INTERRUPT 0x04
#define FLAG_DECIMAL 0x08
#define FLAG_BREAK 0x10
#define FLAG_CONSTANT 0x20
#define FLAG_OVERFLOW 0x40
#define FLAG_SIGN 0x80
#define BASE_STACK 0x100
#define saveaccum (n) a = (uint8_t) ((n) & 0x00FF)
// macro sửa đổi cờ
#define setcarry () trạng thái | = FLAG_CARRY
#define trạng thái Clearcarry () & = (~ FLAG_CARRY)
#define setzero () trạng thái | = FLAG_ZERO
#define Clearzero () trạng thái & = (~ FLAG_ZERO)
#define setinterrupt () status | = FLAG_INTERRUPT
#define trạng thái Clearinterrupt () & = (~ FLAG_INTERRUPT)
#define setdecimal () status | = FLAG_DECIMAL
#define trạng thái Cleardecimal () & = (~ FLAG_DECIMAL)
#define setoverflow () status | = FLAG_OVERFLOW
#define trạng thái clearoverflow () & = (~ FLAG_OVERFLOW)
#define setsign () trạng thái | = FLAG_SIGN
#define xóa trạng thái () & = (~ FLAG_SIGN)
// macro tính toán cờ
#define zerocalc (n) {\
if ((n) & 0x00FF) Clearzero (); \
khác setzero (); \
}
#define đăng nhập (n) {\
if ((n) & 0x0080) setign (); \
other Clearsign (); \
}
#define carrycalc (n) {\
if ((n) & 0xFF00) setcarry (); \
khác Clearcarry (); \
}
#define overflowcalc (n, m, o) {/ * n = result, m = ắc quy, o = bộ nhớ * / \
if (((n) ^ (uint16_t) (m)) & ((n) ^ (o)) & 0x0080) setoverflow (); \
khác clearoverflow (); \
}
// 6502 thanh ghi CPU
máy tính uint16_t;
uint8_t sp, a, x, y, status = FLAG_CONSTANT;
// biến trợ giúp
hướng dẫn uint64_t = 0; // theo dõi tổng số lệnh được thực hiện
uint32_t clockticks6502 = 0, clockgoal6502 = 0;
uint16_t oldpc, ea, reladdr, giá trị, kết quả;
opint uint8_t, oldstatus;
// một vài hàm chung được sử dụng bởi các hàm khác
void đẩy16 (uint16_t đẩy) {
write6502 (BASE_STACK + sp, (giá trị >> 8) & 0xFF);
write6502 (BASE_STACK + ((sp - 1) & 0xFF), giá trị đẩy & 0xFF);
sp - = 2;
}
void đẩy8 (uint8_t đẩy) {
write6502 (BASE_STACK + sp--, đẩy);
}
uint16_t pull16 () {
uint16_t temp16;
temp16 = read6502 (BASE_STACK + ((sp + 1) & 0xFF)) | ((uint16_t) đọc6502 (BASE_STACK + ((sp + 2) & 0xFF)) << 8);
sp + = 2;
trở về (temp16);
}
uint8_t pull8 () {
trả về (read6502 (BASE_STACK + ++ sp));
}
void reset6502 () {
pc = (uint16_t) đọc6502 (0xFFFC) | ((uint16_t) đọc6502 (0xFFFD) << 8);
a = 0;
x = 0;
y = 0;
sp = 0xFD;
trạng thái | = FLAG_CONSTANT;
}
khoảng trống tĩnh (* addrtable [256]) ();
khoảng trống tĩnh (* có thể chọn [256]) ();
uint8_t hình phạt, hình phạt;
// chức năng chế độ địa chỉ, tính toán địa chỉ hiệu quả
static void imp () {// ngụ ý
}
static void acc () {// ắc quy
}
static void imm () {// ngay lập tức
e = pc ++;
}
void void zp () {// zero-page
e = (uint16_t) đọc6502 ((uint16_t) pc ++);
}
void void zpx () {// zero-page, X
e = ((uint16_t) read6502 ((uint16_t) pc ++) + (uint16_t) x) & 0xFF; // không có trang
}
static void zpy () {// zero-page, Y
e = ((uint16_t) read6502 ((uint16_t) pc ++) + (uint16_t) y) & 0xFF; // không có trang
}
static void rel () {// tương đối cho ops nhánh (giá trị tức thời 8 bit, mở rộng đăng nhập)
reladdr = (uint16_t) read6502 (pc ++);
if (reladdr & 0x80) reladdr | = 0xFF00;
}
void void abso () {// tuyệt đối
e = (uint16_t) đọc6502 (pc) | ((uint16_t) đọc6502 (pc + 1) << 8);
pc + = 2;
}
void void absx () {// tuyệt đối, X
trang bắt đầu uint16_t;
e = ((uint16_t) read6502 (pc) | ((uint16_t) read6502 (pc + 1) << 8));
startpage = e & 0xFF00;
e + = (uint16_t) x;
if (startpage! = (ea & 0xFF00)) {// một chu kỳ penlty để vượt trang trên một số opcodes
hình phạt = 1;
}
pc + = 2;
}
static void absy () {// tuyệt đối, Y
trang bắt đầu uint16_t;
e = ((uint16_t) read6502 (pc) | ((uint16_t) read6502 (pc + 1) << 8));
startpage = e & 0xFF00;
e + = (uint16_t) y;
if (startpage! = (ea & 0xFF00)) {// một chu kỳ penlty để vượt trang trên một số opcodes
hình phạt = 1;
}
pc + = 2;
}
static void ind () {// gián tiếp
uint16_t eahelp, eahelp2;
eahelp = (uint16_t) read6502 (pc) | (uint16_t) ((uint16_t) đọc6502 (pc + 1) << 8);
eahelp2 = (eahelp & 0xFF00) | ((trợ giúp + 1) & 0x00FF); // sao chép 6502 lỗi bao quanh ranh giới trang
e = (uint16_t) read6502 (eahelp) | ((uint16_t) đọc6502 (eahelp2) << 8);
pc + = 2;
}
static void indx () {// (gián tiếp, X)
uint16_t eahelp;
eahelp = (uint16_t) (((uint16_t) đọc6502 (pc ++) + (uint16_t) x) & 0xFF); // bao quanh trang zero cho con trỏ bảng
e = (uint16_t) đọc6502 (eahelp & 0x00FF) | ((uint16_t) đọc6502 ((eahelp + 1) & 0x00FF) << 8);
}
static void indy () {// (gián tiếp), Y
uint16_t eahelp, eahelp2, startpage;
eahelp = (uint16_t) đọc6502 (pc ++);
eahelp2 = (eahelp & 0xFF00) | ((trợ giúp + 1) & 0x00FF); // không có trang
e = (uint16_t) read6502 (eahelp) | ((uint16_t) đọc6502 (eahelp2) << 8);
startpage = e & 0xFF00;
e + = (uint16_t) y;
if (startpage! = (ea & 0xFF00)) {// một chu kỳ penlty để vượt trang trên một số opcodes
hình phạt = 1;
}
}
tĩnh uint16_t getvalue () {
if (addrtable [opcode] == acc) return ((uint16_t) a);
trả về khác ((uint16_t) read6502 (e));
}
void void putvalue (uint16_t saveval) {
if (addrtable [opcode] == acc) a = (uint8_t) (saveval & 0x00FF);
khác write6502 (ee, (saveval & 0x00FF));
}
// hàm xử lý lệnh
khoảng trống tĩnh adc () {
hình phạt = 1;
giá trị = getvalue ();
result = (uint16_t) a + value + (uint16_t) (trạng thái & FLAG_CARRY);
carrycalc (kết quả);
zerocalc (kết quả);
tràn (kết quả, a, giá trị);
dấu hiệu (kết quả);
#ifndef NES_CPU
if (trạng thái & FLAG_DECIMAL) {
Clearcarry ();
if ((a & 0x0F)> 0x09) {
a + = 0x06;
}
if ((a & 0xF0)> 0x90) {
a + = 0x60;
setcarry ();
}
clockticks6502 ++;
}
#endif
saveaccum (kết quả);
}
khoảng trống tĩnh và () {
hình phạt = 1;
giá trị = getvalue ();
kết quả = (uint16_t) a & value;
zerocalc (kết quả);
dấu hiệu (kết quả);
saveaccum (kết quả);
}
void void asl () {
giá trị = getvalue ();
kết quả = giá trị << 1;
carrycalc (kết quả);
zerocalc (kết quả);
dấu hiệu (kết quả);
putvalue (kết quả);
}
khoảng trống tĩnh bcc () {
if ((trạng thái & FLAG_CARRY) == 0) {
oldpc = pc;
pc + = reladdr;
if ((oldpc & 0xFF00)! = (pc & 0xFF00)) clockticks6502 + = 2; // kiểm tra xem bước nhảy có vượt qua ranh giới trang không
khác clockticks6502 ++;
}
}
void void bcs () {
if ((trạng thái & FLAG_CARRY) == FLAG_CARRY) {
oldpc = pc;
pc + = reladdr;
if ((oldpc & 0xFF00)! = (pc & 0xFF00)) clockticks6502 + = 2; // kiểm tra xem bước nhảy có vượt qua ranh giới trang không
khác clockticks6502 ++;
}
}
void void beq () {
if ((trạng thái & FLAG_ZERO) == FLAG_ZERO) {
oldpc = pc;
pc + = reladdr;
if ((oldpc & 0xFF00)! = (pc & 0xFF00)) clockticks6502 + = 2; // kiểm tra xem bước nhảy có vượt qua ranh giới trang không
khác clockticks6502 ++;
}
}
bit void void () {
giá trị = getvalue ();
kết quả = (uint16_t) a & value;
zerocalc (kết quả);
trạng thái = (trạng thái & 0x3F) | (uint8_t) (giá trị & 0xC0);
}
void void bmi () {
if ((trạng thái & FLAG_SIGN) == FLAG_SIGN) {
oldpc = pc;
pc + = reladdr;
if ((oldpc & 0xFF00)! = (pc & 0xFF00)) clockticks6502 + = 2; // kiểm tra xem bước nhảy có vượt qua ranh giới trang không
khác clockticks6502 ++;
}
}
void void bne () {
if ((trạng thái & FLAG_ZERO) == 0) {
oldpc = pc;
pc + = reladdr;
if ((oldpc & 0xFF00)! = (pc & 0xFF00)) clockticks6502 + = 2; // kiểm tra xem bước nhảy có vượt qua ranh giới trang không
khác clockticks6502 ++;
}
}
void void bpl () {
if ((trạng thái & FLAG_SIGN) == 0) {
oldpc = pc;
pc + = reladdr;
if ((oldpc & 0xFF00)! = (pc & 0xFF00)) clockticks6502 + = 2; // kiểm tra xem bước nhảy có vượt qua ranh giới trang không
khác clockticks6502 ++;
}
}
void void brk () {
pc ++;
đẩy 16 (pc); // đẩy địa chỉ lệnh tiếp theo lên ngăn xếp
đẩy8 (trạng thái | FLAG_BREAK); // đẩy trạng thái CPU lên ngăn xếp
setinterrupt (); // đặt cờ ngắt
pc = (uint16_t) đọc6502 (0xFFFE) | ((uint16_t) đọc6502 (0xFFFF) << 8);
}
void void bvc () {
if ((trạng thái & FLAG_OVERFLOW) == 0) {
oldpc = pc;
pc + = reladdr;
if ((oldpc & 0xFF00)! = (pc & 0xFF00)) clockticks6502 + = 2; // kiểm tra xem bước nhảy có vượt qua ranh giới trang không
khác clockticks6502 ++;
}
}
void bvs () {
if ((trạng thái & FLAG_OVERFLOW) == FLAG_OVERFLOW) {
oldpc = pc;
pc + = reladdr;
if ((oldpc & 0xFF00)! = (pc & 0xFF00)) clockticks6502 + = 2; // kiểm tra xem bước nhảy có vượt qua ranh giới trang không
khác clockticks6502 ++;
}
}
void void clc () {
Clearcarry ();
}
void void cld () {
rõ ràng ();
}
void void cli () {
rõ ràng ngắt ();
}
void void clv () {
dòng phân tách ();
}
khoảng trống tĩnh cmp () {
hình phạt = 1;
giá trị = getvalue ();
kết quả = (uint16_t) a - giá trị;
if (a> = (uint8_t) (giá trị & 0x00FF)) setcarry ();
khác Clearcarry ();
if (a == (uint8_t) (giá trị & 0x00FF)) setzero ();
khác Clearzero ();
dấu hiệu (kết quả);
}
void void cpx () {
giá trị = getvalue ();
kết quả = (uint16_t) x - giá trị;
if (x> = (uint8_t) (giá trị & 0x00FF)) setcarry ();
khác Clearcarry ();
if (x == (uint8_t) (giá trị & 0x00FF)) setzero ();
khác Clearzero ();
dấu hiệu (kết quả);
}
void void cpy () {
giá trị = getvalue ();
kết quả = (uint16_t) y - giá trị;
if (y> = (uint8_t) (giá trị & 0x00FF)) setcarry ();
khác Clearcarry ();
if (y == (uint8_t) (giá trị & 0x00FF)) setzero ();
khác Clearzero ();
dấu hiệu (kết quả);
}
void void dec () {
giá trị = getvalue ();
kết quả = giá trị - 1;
zerocalc (kết quả);
dấu hiệu (kết quả);
putvalue (kết quả);
}
void void dex () {
x--;
zerocalc (x);
ký hiệu (x);
}
void void dey () {
y--;
zerocalc (y);
dấu hiệu (y);
}
void void eor () {
hình phạt = 1;
giá trị = getvalue ();
kết quả = (uint16_t) a ^ giá trị;
zerocalc (kết quả);
dấu hiệu (kết quả);
saveaccum (kết quả);
}
void void inc () {
giá trị = getvalue ();
kết quả = giá trị + 1;
zerocalc (kết quả);
dấu hiệu (kết quả);
putvalue (kết quả);
}
void void inx () {
x ++;
zerocalc (x);
ký hiệu (x);
}
void void iny () {
y ++;
zerocalc (y);
dấu hiệu (y);
}
void void jmp () {
pc = e;
}
khoảng trống tĩnh jsr () {
đẩy 16 (pc - 1);
pc = e;
}
khoảng trống tĩnh lda () {
hình phạt = 1;
giá trị = getvalue ();
a = (uint8_t) (giá trị & 0x00FF);
zerocalc (a);
ký hiệu (a);
}
khoảng trống tĩnh ldx () {
hình phạt = 1;
giá trị = getvalue ();
x = (uint8_t) (giá trị & 0x00FF);
zerocalc (x);
ký hiệu (x);
}
void void ldy () {
hình phạt = 1;
giá trị = getvalue ();
y = (uint8_t) (giá trị & 0x00FF);
zerocalc (y);
dấu hiệu (y);
}
khoảng trống tĩnh lsr () {
giá trị = getvalue ();
kết quả = giá trị >> 1;
if (value & 1) setcarry ();
khác Clearcarry ();
zerocalc (kết quả);
dấu hiệu (kết quả);
putvalue (kết quả);
}
void void nop () {
chuyển đổi (opcode) {
trường hợp 0x1C:
trường hợp 0x3C:
trường hợp 0x5C:
trường hợp 0x7C:
trường hợp 0xDC:
trường hợp 0xFC:
hình phạt = 1;
phá vỡ;
}
}
khoảng trống tĩnh ora () {
hình phạt = 1;
giá trị = getvalue ();
kết quả = (uint16_t) a | giá trị;
zerocalc (kết quả);
dấu hiệu (kết quả);
saveaccum (kết quả);
}
tĩnh void pha () {
đẩy8 (a);
}
void void php () {
đẩy8 (trạng thái | FLAG_BREAK);
}
void void pla () {
a = pull8 ();
zerocalc (a);
ký hiệu (a);
}
void void plp () {
trạng thái = pull8 () | FLAG_CONSTANT;
}
void void rol () {
giá trị = getvalue ();
kết quả = (giá trị << 1) | (trạng thái & FLAG_CARRY);
carrycalc (kết quả);
zerocalc (kết quả);
dấu hiệu (kết quả);
putvalue (kết quả);
}
static void ror () {
giá trị = getvalue ();
kết quả = (giá trị >> 1) | ((trạng thái & FLAG_CARRY) << 7);
if (value & 1) setcarry ();
khác Clearcarry ();
zerocalc (kết quả);
dấu hiệu (kết quả);
putvalue (kết quả);
}
void void rti () {
trạng thái = pull8 ();
giá trị = pull16 ();
pc = giá trị;
}
void void rts () {
giá trị = pull16 ();
pc = giá trị + 1;
}
void void sbc () {
hình phạt = 1;
giá trị = getvalue () ^ 0x00FF;
result = (uint16_t) a + value + (uint16_t) (trạng thái & FLAG_CARRY);
carrycalc (kết quả);
zerocalc (kết quả);
tràn (kết quả, a, giá trị);
dấu hiệu (kết quả);
#ifndef NES_CPU
if (trạng thái & FLAG_DECIMAL) {
Clearcarry ();
a - = 0x66;
if ((a & 0x0F)> 0x09) {
a + = 0x06;
}
if ((a & 0xF0)> 0x90) {
a + = 0x60;
setcarry ();
}
clockticks6502 ++;
}
#endif
saveaccum (kết quả);
}
void void sec () {
setcarry ();
}
void void sed () {
setdecimal ();
}
void void sei () {
setinterrupt ();
}
void void sta () {
giá trị (a);
}
void void stx () {
giá trị (x);
}
static void sty () {
putvalue (y);
}
thuế void void () {
x = a;
zerocalc (x);
ký hiệu (x);
}
static void tay () {
y = a;
zerocalc (y);
dấu hiệu (y);
}
void void tsx () {
x = sp;
zerocalc (x);
ký hiệu (x);
}
khoảng trống tĩnh txa () {
a = x;
zerocalc (a);
ký hiệu (a);
}
void void txs () {
sp = x;
}
void void tya () {
a = y;
zerocalc (a);
ký hiệu (a);
}
// hướng dẫn không có giấy tờ
#ifdef HIỂU
void void lax () {
lda ();
ldx ();
}
tĩnh void sax () {
sta ();
stx ();
giá trị (a & x);
if (penaltyop && penaltyaddr) clockticks6502--;
}
static void dcp() {
dec();
cmp();
if (penaltyop && penaltyaddr) clockticks6502--;
}
static void isb() {
inc();
sbc();
if (penaltyop && penaltyaddr) clockticks6502--;
}
static void slo() {
asl();
ora();
if (penaltyop && penaltyaddr) clockticks6502--;
}
static void rla() {
rol();
and();
if (penaltyop && penaltyaddr) clockticks6502--;
}
static void sre() {
lsr();
eor();
if (penaltyop && penaltyaddr) clockticks6502--;
}
static void rra() {
ror();
adc();
if (penaltyop && penaltyaddr) clockticks6502--;
}
#else
#define lax nop
#define sax nop
#define dcp nop
#define isb nop
#define slo nop
#define rla nop
#define sre nop
#define rra nop
#endif
static void (*addrtable[256])() = {
/* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */
/* 0 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, abso, /* 0 */
/* 1 */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx, /* 1 */
/* 2 */ abso, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, abso, /* 2 */
/* 3 */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx, /* 3 */
/* 4 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, abso, /* 4 */
/* 5 */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx, /* 5 */
/* 6 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, ind, abso, abso, abso, /* 6 */
/* 7 */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx, /* 7 */
/* 8 */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, abso, /* 8 */
/* 9 */ rel, indy, imp, indy, zpx, zpx, zpy, zpy, imp, absy, imp, absy, absx, absx, absy, absy, /* 9 */
/* A */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, abso, /* A */
/* B */ rel, indy, imp, indy, zpx, zpx, zpy, zpy, imp, absy, imp, absy, absx, absx, absy, absy, /* B */
/* C */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, abso, /* C */
/* D */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx, /* D */
/* E */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, abso, /* E */
/* F */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx /* F */
};
static void (*optable[256])() = {
/* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */
/* 0 */ brk, ora, nop, slo, nop, ora, asl, slo, php, ora, asl, nop, nop, ora, asl, slo, /* 0 */
/* 1 */ bpl, ora, nop, slo, nop, ora, asl, slo, clc, ora, nop, slo, nop, ora, asl, slo, /* 1 */
/* 2 */ jsr, and, nop, rla, bit, and, rol, rla, plp, and, rol, nop, bit, and, rol, rla, /* 2 */
/* 3 */ bmi, and, nop, rla, nop, and, rol, rla, sec, and, nop, rla, nop, and, rol, rla, /* 3 */
/* 4 */ rti, eor, nop, sre, nop, eor, lsr, sre, pha, eor, lsr, nop, jmp, eor, lsr, sre, /* 4 */
/* 5 */ bvc, eor, nop, sre, nop, eor, lsr, sre, cli, eor, nop, sre, nop, eor, lsr, sre, /* 5 */
/* 6 */ rts, adc, nop, rra, nop, adc, ror, rra, pla, adc, ror, nop, jmp, adc, ror, rra, /* 6 */
/* 7 */ bvs, adc, nop, rra, nop, adc, ror, rra, sei, adc, nop, rra, nop, adc, ror, rra, /* 7 */
/* 8 */ nop, sta, nop, sax, sty, sta, stx, sax, dey, nop, txa, nop, sty, sta, stx, sax, /* 8 */
/* 9 */ bcc, sta, nop, nop, sty, sta, stx, sax, tya, sta, txs, nop, nop, sta, nop, nop, /* 9 */
/* A */ ldy, lda, ldx, lax, ldy, lda, ldx, lax, tay, lda, tax, nop, ldy, lda, ldx, lax, /* A */
/* B */ bcs, lda, nop, lax, ldy, lda, ldx, lax, clv, lda, tsx, lax, ldy, lda, ldx, lax, /* B */
/* C */ cpy, cmp, nop, dcp, cpy, cmp, dec, dcp, iny, cmp, dex, nop, cpy, cmp, dec, dcp, /* C */
/* D */ bne, cmp, nop, dcp, nop, cmp, dec, dcp, cld, cmp, nop, dcp, nop, cmp, dec, dcp, /* D */
/* E */ cpx, sbc, nop, isb, cpx, sbc, inc, isb, inx, sbc, nop, sbc, cpx, sbc, inc, isb, /* E */
/* F */ beq, sbc, nop, isb, nop, sbc, inc, isb, sed, sbc, nop, isb, nop, sbc, inc, isb /* F */
};
static const uint32_t ticktable[256] = {
/* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */
/* 0 */ 7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, /* 0 */
/* 1 */ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 1 */
/* 2 */ 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 4, 4, 6, 6, /* 2 */
/* 3 */ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 3 */
/* 4 */ 6, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 3, 4, 6, 6, /* 4 */
/* 5 */ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 5 */
/* 6 */ 6, 6, 2, 8, 3, 3, 5, 5, 4, 2, 2, 2, 5, 4, 6, 6, /* 6 */
/* 7 */ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* 7 */
/* 8 */ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, /* 8 */
/* 9 */ 2, 6, 2, 6, 4, 4, 4, 4, 2, 5, 2, 5, 5, 5, 5, 5, /* 9 */
/* A */ 2, 6, 2, 6, 3, 3, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, /* A */
/* B */ 2, 5, 2, 5, 4, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 4, /* B */
/* C */ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, /* C */
/* D */ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, /* D */
/* E */ 2, 6, 2, 8, 3, 3, 5, 5, 2, 2, 2, 2, 4, 4, 6, 6, /* E */
/* F */ 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7 /* F */
};
void nmi6502() {
push16(pc);
push8(status);
status |= FLAG_INTERRUPT;
pc = (uint16_t)read6502(0xFFFA) | ((uint16_t)read6502(0xFFFB) << 8);
}
void irq6502() {
push16(pc);
push8(status);
status |= FLAG_INTERRUPT;
pc = (uint16_t)read6502(0xFFFE) | ((uint16_t)read6502(0xFFFF) << 8);
}
uint8_t callexternal = 0;
void (*loopexternal)();
void exec6502(uint32_t tickcount) {
clockgoal6502 += tickcount;
while (clockticks6502 < clockgoal6502) {
opcode = read6502(pc++);
penaltyop = 0;
penaltyaddr = 0;
(*addrtable[opcode])();
(*optable[opcode])();
clockticks6502 += ticktable[opcode];
if (penaltyop && penaltyaddr) clockticks6502++;
instructions++;
if (callexternal) (*loopexternal)();
}
}
void step6502() {
opcode = read6502(pc++);
penaltyop = 0;
penaltyaddr = 0;
(*addrtable[opcode])();
(*optable[opcode])();
clockticks6502 += ticktable[opcode];
if (penaltyop && penaltyaddr) clockticks6502++;
clockgoal6502 = clockticks6502;
instructions++;
if (callexternal) (*loopexternal)();
}
void hookexternal(void *funcptr) {
if (funcptr != (void *)NULL) {
loopexternal = funcptr;
callexternal = 1;
} else callexternal = 0;
}