Devam edip kendi uygulamamı göndereceğimi düşündüm. Tamamen ungolfed, ama tam bir uygulama.
- 668 C. satır (boş satırları saymaz veya yalnızca yorumlu satırları)
- Belgelenmemiş tüm talimatları (sanırım) destekler.
- BCD'yi destekler.
- CPU saat döngüsü zamanlaması. (belirli sayfa sınırındaki sargılardaki ayarlamalar dahil)
- Talimatları tek adım adım ya da tik sayısını belirterek çalıştırabilir.
- Her komuttan çıkarıldıktan sonra çağrılacak harici bir fonksiyonun bağlanmasını destekler. Bunun nedeni aslen bir NES emülatörü içindi ve bunu ses zamanlaması için kullandım.
/ * Fake6502 CPU emülatörü çekirdek v1.1 ********************
* (c) 2011-2013 Mike Chambers *
************************************************** *** /
#include <stdio.h>
#include <stdint.h>
// harici olarak sağlanan fonksiyonlar
dış uint8_t read6502 (uint16_t adresi);
dış boşluk yazma6502 (uint16_t adresi, uint8_t değeri);
// 6502 tanımlar
#define UNDOCUMENTED // bu tanımlandığında belgesiz kodlar işlenir.
// aksi takdirde, NOP olarak kabul edilirler.
// # tanımlandığında NES_CPU // tanımlandığında, ikili kodlanmış ondalık (BCD)
// durum bayrağı ADC ve SBC tarafından onurlandırılmaz. 2A03
// Nintendo Eğlence Sistemindeki CPU çalışmıyor
// BCD işlemini destekle.
#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) ve 0x00FF)
// bayrak değiştirici makroları
#define setcarry () status | = FLAG_CARRY
#define clearcarry () durumu & = (~ FLAG_CARRY)
#define setzero () status | = FLAG_ZERO
#define clearzero () durumu & = (~ FLAG_ZERO)
#define setinterrupt () status | = FLAG_INTERRUPT
#define clearinterrupt () status & = (~ FLAG_INTERRUPT)
#define setdecimal () status | = FLAG_DECIMAL
#define cleardecimal () status & = (~ FLAG_DECIMAL)
#define setoverflow () status | = FLAG_OVERFLOW
#define clearoverflow () durumu & = (~ FLAG_OVERFLOW)
#define setsign () status | = FLAG_SIGN
#define clearsign () status & = (~ FLAG_SIGN)
// bayrak hesaplama makroları
#define zerocalc (n) {\
if ((n) & 0x00FF) clearzero (); \
else setzero (); \
}
#define signcalc (n) {\
if ((n) & 0x0080) setsign (); \
else clearsign (); \
}
#define carrycalc (n) {\
if ((n) & 0xFF00) setcarry (); \
başka clearcarry (); \
}
#define taşması (n, m, o) {/ * n = sonuç, m = akümülatör, o = bellek * / \
if (((n) ^ (uint16_t) (m)) & ((n) ^ (o)) & 0x0080) setoverflow (); \
else clearoverflow (); \
}
// 6502 CPU kaydı
uint16_t pc;
uint8_t sp, a, x, y, durum = FLAG_CONSTANT;
// yardımcı değişkenler
uint64_t talimatları = 0; // yürütülen toplam talimatları takip et
uint32_t clockticks6502 = 0, clockgoal6502 = 0;
uint16_t oldpc, ea, reladdr, değer, sonuç;
uint8_t opcode, oldstatus;
// çeşitli diğer fonksiyonlar tarafından kullanılan birkaç genel fonksiyon
geçersiz push16 (uint16_t pushval) {
write6502 (BASE_STACK + sp, (pushval >> 8) & 0xFF);
write6502 (BASE_STACK + ((sp - 1) & 0xFF), pushval ve 0xFF);
sp - = 2;
}
void push8 (uint8_t pushval) {
write6502 (BASE_STACK + sp--, pushval);
}
uint16_t pull16 () {
uint16_t temp16;
temp16 = read6502 (BASE_STACK + ((sp + 1) ve 0xFF)) | ((uint16_t) read6502 (BASE_STACK + ((sp + 2) & 0xFF)) << 8);
sp + = 2;
(Temp16) döndürür;
}
uint8_t pull8 () {
dönüş (read6502 (BASE_STACK + ++ sp));
}
geçersiz sıfırlama6502 () {
pc = (uint16_t) okuma6502 (0xFFFC) | ((uint16_t) okuma6502 (0xFFFD) << 8);
a = 0;
x = 0;
y = 0;
sp = 0xFD;
status | = FLAG_CONSTANT;
}
statik boşluk (* adres [256]) ();
statik boşluk (* optable [256]) ();
uint8_t penaltı, penaltyaddr;
// adresleme modu fonksiyonları, etkili adresleri hesaplar
statik boşluk imp () {// ima edildi
}
statik boşluk acc () {// akümülatör
}
statik boşluk imm () {// hemen
ea = pc ++;
}
statik boşluk zp () {// sıfır sayfa
ea = (uint16_t) okuma6502 ((uint16_t) pc ++);
}
statik boşluk zpx () {// sıfır sayfa, X
ea = ((uint16_t) okuma6502 ((uint16_t) pc ++) + (uint16_t) x) & 0xFF; // sıfır sayfa sarma
}
statik boşluk zpy () {// sıfır sayfa, Y
ea = ((uint16_t) read6502 ((uint16_t) bilgisayar ++) + (uint16_t) y) & 0xFF; // sıfır sayfa sarma
}
statik boşluk rel () {// şube işlemleri için göreceli (8 bitlik anında değer, genişletilmiş işaret)
reladdr = (uint16_t) 6602 (pc ++);
if (reladdr ve 0x80) reladdr | = 0xFF00;
}
statik boşluk abso () {// mutlak
ea = (uint16_t) okuma6502 (pc) | ((uint16_t) read6502 (pc + 1) << 8);
pc + = 2;
}
statik boşluk absx () {// mutlak, X
uint16_t başlangıç sayfası;
ea = ((uint16_t) okuma6502 (pc) | ((uint16_t) okuma6502 (pc + 1) << 8));
startpage = ea & 0xFF00;
ea + = (uint16_t) x;
if (startpage! = (ea & 0xFF00)) {// bazı kodlarda sayfa geçişi için bir döngü ceza
penaltyaddr = 1;
}
pc + = 2;
}
statik boşluk absy () {// mutlak, Y
uint16_t başlangıç sayfası;
ea = ((uint16_t) okuma6502 (pc) | ((uint16_t) okuma6502 (pc + 1) << 8));
startpage = ea & 0xFF00;
ea + = (uint16_t) y;
if (startpage! = (ea & 0xFF00)) {// bazı kodlarda sayfa geçişi için bir döngü ceza
penaltyaddr = 1;
}
pc + = 2;
}
statik boşluk ind () {// dolaylı
uint16_t eahelp, eahelp2;
eahelp = (uint16_t) okuma6502 (pc) | (uint16_t) ((uint16_t) okuma6502 (pc + 1) << 8);
eahelp2 = (eahelp ve 0xFF00) | ((eahelp + 1) & 0x00FF); // 6502 sayfa sınırında sarmalama hatası
ea = (uint16_t) okuma6502 (eahelp) | ((uint16_t) okuma6502 (eahelp2) << 8);
pc + = 2;
}
statik boşluk indx () {// (dolaylı, X)
uint16_t eahelp;
eahelp = (uint16_t) ((((uint16_t)) 6502 (pc ++) + (uint16_t) x) & 0xFF); // tablo işaretçisi için sıfır sayfalı sarma
ea = (uint16_t) okuma6502 (eahelp ve 0x00FF) | ((uint16_t) read6502 ((eahelp + 1) & 0x00FF) << 8);
}
statik boşluk indy () {// (dolaylı), Y
uint16_t eahelp, eahelp2, başlangıç sayfası;
eahelp = (uint16_t) okuma6502 (pc ++);
eahelp2 = (eahelp ve 0xFF00) | ((eahelp + 1) & 0x00FF); // sıfır sayfa sarma
ea = (uint16_t) okuma6502 (eahelp) | ((uint16_t) okuma6502 (eahelp2) << 8);
startpage = ea & 0xFF00;
ea + = (uint16_t) y;
if (startpage! = (ea & 0xFF00)) {// bazı kodlarda sayfa geçişi için bir döngü ceza
penaltyaddr = 1;
}
}
statik uint16_t getvalue () {
if (addrtable [opcode] == acc) return ((uint16_t) a);
aksi halde geri dönüş ((uint16_t) read6502 (ea));
}
statik geçersiz değer (uint16_t saveval) {
if (addrtable [opcode] == acc) a = (uint8_t) (saveval & 0x00FF);
başka yazma6502 (ea, (saveval & 0x00FF));
}
// öğretim işleyicisi işlevleri
statik boşluk adc () {
ceza türü = 1;
değer = getvalue ();
sonuç = (uint16_t) a + değeri + (uint16_t) (durum & FLAG_CARRY);
carrycalc (sonuç);
zerocalc (sonuç);
taşma hesabı (sonuç, a, değer);
signcalc (sonuç);
#ifndef NES_CPU
eğer (durum ve FLAG_DECIMAL) {
clearcarry ();
if ((a & 0x0F)> 0x09) {
a + = 0x06;
}
if ((a & 0xF0)> 0x90) {
a + = 0x60;
) (Setcarry;
}
clockticks6502 ++;
}
#endif
saveaccum (sonuç);
}
statik boşluk ve () {
ceza türü = 1;
değer = getvalue ();
sonuç = (uint16_t) a & değer;
zerocalc (sonuç);
signcalc (sonuç);
saveaccum (sonuç);
}
statik boşluk asl () {
değer = getvalue ();
sonuç = değer << 1;
carrycalc (sonuç);
zerocalc (sonuç);
signcalc (sonuç);
putvalue (sonuç);
}
statik boşluk bcc () {
eğer ((durum & FLAG_CARRY) == 0) {
oldpc = bilgisayar;
pc + = reladdr;
eğer ((oldpc & 0xFF00)! = ((pc & 0xFF00)) clockticks6502 + = 2; // atlamanın bir sayfa sınırı geçip geçmediğini kontrol et
başka clockticks6502 ++;
}
}
statik boşluk bcs () {
if ((status & FLAG_CARRY) == FLAG_CARRY) {
oldpc = bilgisayar;
pc + = reladdr;
eğer ((oldpc & 0xFF00)! = ((pc & 0xFF00)) clockticks6502 + = 2; // atlamanın bir sayfa sınırı geçip geçmediğini kontrol et
başka clockticks6502 ++;
}
}
statik boşluk beq () {
if ((status & FLAG_ZERO) == FLAG_ZERO) {
oldpc = bilgisayar;
pc + = reladdr;
eğer ((oldpc & 0xFF00)! = ((pc & 0xFF00)) clockticks6502 + = 2; // atlamanın bir sayfa sınırı geçip geçmediğini kontrol et
başka clockticks6502 ++;
}
}
statik boşluk bit () {
değer = getvalue ();
sonuç = (uint16_t) a & değer;
zerocalc (sonuç);
status = (durum & 0x3F) | (uint8_t) (değer & 0xC0);
}
statik boşluk bmi () {
if ((status & FLAG_SIGN) == FLAG_SIGN) {
oldpc = bilgisayar;
pc + = reladdr;
eğer ((oldpc & 0xFF00)! = ((pc & 0xFF00)) clockticks6502 + = 2; // atlamanın bir sayfa sınırı geçip geçmediğini kontrol et
başka clockticks6502 ++;
}
}
statik boşluk bne () {
eğer (((& FLAG_ZERO durumu) == 0) {
oldpc = bilgisayar;
pc + = reladdr;
eğer ((oldpc & 0xFF00)! = ((pc & 0xFF00)) clockticks6502 + = 2; // atlamanın bir sayfa sınırı geçip geçmediğini kontrol et
başka clockticks6502 ++;
}
}
statik boşluk bpl () {
eğer ((durum & FLAG_SIGN) == 0) {
oldpc = bilgisayar;
pc + = reladdr;
eğer ((oldpc & 0xFF00)! = ((pc & 0xFF00)) clockticks6502 + = 2; // atlamanın bir sayfa sınırı geçip geçmediğini kontrol et
başka clockticks6502 ++;
}
}
statik boşluk brk () {
pc ++;
push16 (PC); // bir sonraki komut adresini yığının üstüne it
push8 (durum | FLAG_BREAK); // yığmak için CPU durumunu zorla
setinterrupt (); // kesme bayrağını ayarla
pc = (uint16_t) okuma6502 (0xFFFE) | ((uint16_t) read6502 (0xFFFF) << 8);
}
statik boşluk bvc () {
if ((status & FLAG_OVERFLOW) == 0) {
oldpc = bilgisayar;
pc + = reladdr;
eğer ((oldpc & 0xFF00)! = ((pc & 0xFF00)) clockticks6502 + = 2; // atlamanın bir sayfa sınırı geçip geçmediğini kontrol et
başka clockticks6502 ++;
}
}
statik boşluk bvs () {
if ((status & FLAG_OVERFLOW) == FLAG_OVERFLOW) {
oldpc = bilgisayar;
pc + = reladdr;
eğer ((oldpc & 0xFF00)! = ((pc & 0xFF00)) clockticks6502 + = 2; // atlamanın bir sayfa sınırı geçip geçmediğini kontrol et
başka clockticks6502 ++;
}
}
statik boşluk clc () {
clearcarry ();
}
statik boşluk cld () {
cleardecimal ();
}
statik boşluk cli () {
clearinterrupt ();
}
statik boşluk clv () {
) (Clearoverflow;
}
statik boşluk cmp () {
ceza türü = 1;
değer = getvalue ();
sonuç = (uint16_t) a - değer;
if (a> = (uint8_t) (değer & 0x00FF)) setcarry ();
başka bir clearcarry ();
if (a == (uint8_t) (değer & 0x00FF)) setzero ();
başka clearzero ();
signcalc (sonuç);
}
statik boşluk cpx () {
değer = getvalue ();
sonuç = (uint16_t) x - değer;
if (x> = (uint8_t) (değer & 0x00FF)) setcarry ();
başka bir clearcarry ();
if (x == (uint8_t) (değer & 0x00FF)) setzero ();
başka clearzero ();
signcalc (sonuç);
}
statik boşluk cpy () {
değer = getvalue ();
sonuç = (uint16_t) y - değer;
if (y> = (uint8_t) (değer & 0x00FF)) setcarry ();
başka bir clearcarry ();
if (y == (uint8_t) (değer & 0x00FF)) setzero ();
başka clearzero ();
signcalc (sonuç);
}
statik boşluk dec () {
değer = getvalue ();
sonuç = değer - 1;
zerocalc (sonuç);
signcalc (sonuç);
putvalue (sonuç);
}
statik boşluk dex () {
X-'i;
zerocalc (x);
signcalc (x);
}
statik boşluk dey () {
Y-;
zerocalc (y);
signcalc (y);
}
statik boşluk eor () {
ceza türü = 1;
değer = getvalue ();
sonuç = (uint16_t) bir ^ değer;
zerocalc (sonuç);
signcalc (sonuç);
saveaccum (sonuç);
}
statik boşluk inc () {
değer = getvalue ();
sonuç = değer + 1;
zerocalc (sonuç);
signcalc (sonuç);
putvalue (sonuç);
}
statik boşluk inx () {
x ++;
zerocalc (x);
signcalc (x);
}
statik boşluk iny () {
y ++;
zerocalc (y);
signcalc (y);
}
statik boşluk jmp () {
pc = ea;
}
statik boşluk jsr () {
push16 (pc - 1);
pc = ea;
}
statik boşluk lda () {
ceza türü = 1;
değer = getvalue ();
a = (uint8_t) (değer & 0x00FF);
zerocalc (a) '
signcalc (a) '
}
statik boşluk ldx () {
ceza türü = 1;
değer = getvalue ();
x = (uint8_t) (değer & 0x00FF);
zerocalc (x);
signcalc (x);
}
statik boşluk ldy () {
ceza türü = 1;
değer = getvalue ();
y = (uint8_t) (değer & 0x00FF);
zerocalc (y);
signcalc (y);
}
statik boşluk lsr () {
değer = getvalue ();
sonuç = değer >> 1;
if (değer & 1) setcarry ();
başka bir clearcarry ();
zerocalc (sonuç);
signcalc (sonuç);
putvalue (sonuç);
}
statik boşluk nop () {
anahtar (opcode) {
durum 0x1C:
durum 0x3C:
durum 0x5C:
durum 0x7C:
durum 0xDC:
durum 0xFC:
ceza türü = 1;
break;
}
}
statik boşluk ora () {
ceza türü = 1;
değer = getvalue ();
sonuç = (uint16_t) a | değeri;
zerocalc (sonuç);
signcalc (sonuç);
saveaccum (sonuç);
}
statik boşluk pha () {
push8 (a) '
}
statik boşluk php () {
push8 (durum | FLAG_BREAK);
}
statik boşluk pla () {
a = pull8 ();
zerocalc (a) '
signcalc (a) '
}
statik boşluk plp () {
durum = pull8 () | FLAG_CONSTANT;
}
statik boşluk rol () {
değer = getvalue ();
sonuç = (değer << 1) | (durum & FLAG_CARRY);
carrycalc (sonuç);
zerocalc (sonuç);
signcalc (sonuç);
putvalue (sonuç);
}
statik boşluk ror () {
değer = getvalue ();
sonuç = (değer >> 1) | ((durum & FLAG_CARRY) << 7);
if (değer & 1) setcarry ();
başka bir clearcarry ();
zerocalc (sonuç);
signcalc (sonuç);
putvalue (sonuç);
}
statik boşluk rti () {
status = pull8 ();
değer = pull16 ();
pc = değer;
}
statik boşluk rts () {
değer = pull16 ();
pc = değer + 1;
}
statik boşluk sbc () {
ceza türü = 1;
değer = getvalue () ^ 0x00FF;
sonuç = (uint16_t) a + değeri + (uint16_t) (durum & FLAG_CARRY);
carrycalc (sonuç);
zerocalc (sonuç);
taşma hesabı (sonuç, a, değer);
signcalc (sonuç);
#ifndef NES_CPU
eğer (durum ve FLAG_DECIMAL) {
clearcarry ();
a - = 0x66;
if ((a & 0x0F)> 0x09) {
a + = 0x06;
}
if ((a & 0xF0)> 0x90) {
a + = 0x60;
) (Setcarry;
}
clockticks6502 ++;
}
#endif
saveaccum (sonuç);
}
statik boşluk sn () {
) (Setcarry;
}
statik boşluk sed () {
setdecimal ();
}
statik boşluk sei () {
setinterrupt ();
}
statik boşluk sta () {
putvalue (a) '
}
statik boşluk stx () {
putvalue (x);
}
statik boşluk sty () {
putvalue (y);
}
statik boşluk vergisi () {
x = a;
zerocalc (x);
signcalc (x);
}
statik boşluk tay () {
y = a;
zerocalc (y);
signcalc (y);
}
statik boşluk tsx () {
x = sp;
zerocalc (x);
signcalc (x);
}
statik boşluk txa () {
a = x;
zerocalc (a) '
signcalc (a) '
}
statik boşluk txs () {
sp = x;
}
statik boşluk tya () {
a = y;
zerocalc (a) '
signcalc (a) '
}
// belgelenmemiş talimatlar
#ifdef BELGESİZ
statik boşluk lax () {
LDA ();
ldx ();
}
statik boşluk sax () {
sta ();
STX ();
değer (a & x);
if (penaltyop && penaltyaddr) clockticks6502 -;
}
statik boşluk dcp () {
dec ();
cmp ();
if (penaltyop && penaltyaddr) clockticks6502 -;
}
statik boşluk isb () {
Inc ();
SBC ();
if (penaltyop && penaltyaddr) clockticks6502 -;
}
statik boşluk slo () {
asl ();
ora ();
if (penaltyop && penaltyaddr) clockticks6502 -;
}
statik boşluk rla () {
rol ();
ve();
if (penaltyop && penaltyaddr) clockticks6502 -;
}
statik boşluk sre () {
LSR ();
EOR ();
if (penaltyop && penaltyaddr) clockticks6502 -;
}
statik boşluk rra () {
ror ();
ADC ();
if (penaltyop && penaltyaddr) clockticks6502 -;
}
#Başka
#define lax nop
#define sax nop
#define dcp nop
#define isb nop
#define slo nop
#define rop nop
#define sre nop
#define rop nop
#endif
statik boşluk (* adres [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, abm, 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, abm, abso, abso, abso, / * E * /
/ * F * / rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx / * F * /
};
statik boşluk (* optable [256]) () = {
/ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | * /
/ * 0 * / brk, ora, no, slo, no, ora, asl, slo, php, ora, asl, no, no, nop, ora, asl, slo, / * 0 * /
/ * 1 * / bpl, ora, no, slo, no, no, o, asl, slo, clc, ora, no, slo, no, o, asl, slo, / * 1 * /
/ * 2 * / jsr, ve, nop, rla, bit, ve, rol, rla, plp, ve, nop, bit, ve, rol, rla, / * 2 * /
/ * 3 * / bmi ve nop, rla, nop, ve, rol, rla, sn ve nop, rla, nop, ve, rol, rla, / * 3 * /
/ * 4 * / rti, eor, hayır, sre, nop, eor, lsr, sre, pha, eor, lsr, nop, jmp, eor, lsr, sre, / * 4 * /
/ * 5 * / bvc, eor, hayır, 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, no, rra, nop, adc, ror, rra, sei, adc, nop, rra, nop, adc, ror, rra, / * 7 * /
/ * 8 * / noop, sta, no, sax, arpacık, sta, stx, sax, dey, no, txa, no, arpacık, sta, stx, sax, / * 8 * /
/ * 9 * / bcc, sta, no, nop, arpacık, sta, stx, sax, tya, sta, txs, no, no, nop, sta, no, nop, / * 9 * /
/ * A * / ldy, lda, ldx, lax, ldy, lda, ldx, lax, tay, lda, vergi, yok, 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, no, dcp, cpy, cmp, dec, dcp, iny, cmp, dex, nop, cpy, cmp, dec, dcp, / * C * /
/ * D * / bne, cmp, no, dcp, no, cmp, dec, dcp, cld, cmp, no, dcp, no, 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 * /
};
statik const uint32_t gıdıklanabilir [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, 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, 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, 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, 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, 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, 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, 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, 6, 2, 4, 2, 7, 4, 4, 7, 7 / * F * /
};
void nmi6502 () {
push16 (PC);
push8 (durum);
status | = FLAG_INTERRUPT;
pc = (uint16_t) okuma6502 (0xFFFA) | ((uint16_t) read6502 (0xFFFB) << 8);
}
geçersiz irq6502 () {
push16 (PC);
push8 (durum);
status | = FLAG_INTERRUPT;
pc = (uint16_t) okuma6502 (0xFFFE) | ((uint16_t) read6502 (0xFFFF) << 8);
}
uint8_t callexternal = 0;
void (* loopexternal) ();
void exec6502 (uint32_t tickcount) {
clockgoal6502 + = tickcount;
while (clockticks6502 <clockgoal6502) {
opcode = read6502 (bilgisayar ++);
ceza türü = 0;
penaltyaddr = 0;
(* Addrtable [işlem kodu]) ();
(* Optable [işlem kodu]) ();
clockticks6502 + = işaretlenebilir [opcode];
if (penaltyop && penaltyaddr) clockticks6502 ++;
talimatları ++;
if (callexternal) (* loopexternal) ();
}
}
boşluk step6502 () {
opcode = read6502 (bilgisayar ++);
ceza türü = 0;
penaltyaddr = 0;
(* Addrtable [işlem kodu]) ();
(* Optable [işlem kodu]) ();
clockticks6502 + = işaretlenebilir [opcode];
if (penaltyop && penaltyaddr) clockticks6502 ++;
clockgoal6502 = clockticks6502;
talimatları ++;
if (callexternal) (* loopexternal) ();
}
geçersiz hookexternal (void * funcptr) {
if (funcptr! = (geçersiz *) NULL) {
loopexternal = funcptr;
callexternal = 1;
} başka bir eksenli = 0;
}