Added 65c02 Instructions NEEDS TESTING!
This commit is contained in:
parent
caba72b134
commit
5cc21f3a6f
195
src/cpu.c
195
src/cpu.c
@ -1,7 +1,7 @@
|
|||||||
/* Fake6502 CPU emulator core v1.1 *******************
|
/* Fake6502 CPU emulator core v1.1 *******************
|
||||||
* (c)2011-2013 Mike Chambers *
|
* (c)2011-2013 Mike Chambers *
|
||||||
* *
|
* *
|
||||||
* Modified by Gabriel Weingardt *
|
* Modified for 65c02 by Gabriel Weingardt *
|
||||||
*****************************************************/
|
*****************************************************/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -130,6 +130,10 @@ static void zp() { //zero-page
|
|||||||
ea = (uint16_t)read6502((uint16_t)pc++);
|
ea = (uint16_t)read6502((uint16_t)pc++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void izp() { // zero-page indirect (new 65c02 instruction)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void zpx() { //zero-page,X
|
static void zpx() { //zero-page,X
|
||||||
ea = ((uint16_t)read6502((uint16_t)pc++) + (uint16_t)x) & 0xFF; //zero-page wraparound
|
ea = ((uint16_t)read6502((uint16_t)pc++) + (uint16_t)x) & 0xFF; //zero-page wraparound
|
||||||
}
|
}
|
||||||
@ -201,6 +205,16 @@ static void indy() { // (indirect),Y
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// new 65c02 address mode
|
||||||
|
static void aii() { // absolute indexed indirect
|
||||||
|
uint16_t eahelp, eahelp2;
|
||||||
|
eahelp = ((uint16_t)read6502(pc) | ((uint16_t)read6502(pc+1) << 8)) + x;
|
||||||
|
eahelp2 = (eahelp & 0xFF00) | ((eahelp + 1) & 0x00FF); //replicate 6502 page-boundary wraparound bug
|
||||||
|
ea = (uint16_t)read6502(eahelp) | ((uint16_t)read6502(eahelp2) << 8);
|
||||||
|
pc += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint16_t getvalue() {
|
static uint16_t getvalue() {
|
||||||
if (addrtable[opcode] == acc) return((uint16_t)a);
|
if (addrtable[opcode] == acc) return((uint16_t)a);
|
||||||
else return((uint16_t)read6502(ea));
|
else return((uint16_t)read6502(ea));
|
||||||
@ -336,6 +350,37 @@ static void bvs() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bra() { // new 65c02 instruction
|
||||||
|
oldpc = pc;
|
||||||
|
pc += reladdr;
|
||||||
|
if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary
|
||||||
|
else clockticks6502++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bbr() { // new 65c02 instruction
|
||||||
|
uint8_t testval = 1;
|
||||||
|
for (int i = 0; i < ((opcode & 0b01110000) >> 4); i++) testval = testval << 1;
|
||||||
|
|
||||||
|
if (!(a & testval)) {
|
||||||
|
oldpc = pc;
|
||||||
|
pc += reladdr;
|
||||||
|
if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary
|
||||||
|
else clockticks6502++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bbs() { // new 65c02 instruction
|
||||||
|
uint8_t testval = 1;
|
||||||
|
for (int i = 0; i < ((opcode & 0b01110000) >> 4); i++) testval = testval << 1;
|
||||||
|
|
||||||
|
if (a & testval) {
|
||||||
|
oldpc = pc;
|
||||||
|
pc += reladdr;
|
||||||
|
if ((oldpc & 0xFF00) != (pc & 0xFF00)) clockticks6502 += 2; //check if jump crossed a page boundary
|
||||||
|
else clockticks6502++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void clc() {
|
static void clc() {
|
||||||
clearcarry();
|
clearcarry();
|
||||||
}
|
}
|
||||||
@ -522,9 +567,18 @@ static void pha() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void php() {
|
static void php() {
|
||||||
push8(status | FLAG_BREAK);
|
push8(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void phy() { // new 65c02 instruction
|
||||||
|
push8(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void phx() { // new 65c02 instruction
|
||||||
|
push8(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void pla() {
|
static void pla() {
|
||||||
a = pull8();
|
a = pull8();
|
||||||
|
|
||||||
@ -536,6 +590,21 @@ static void plp() {
|
|||||||
status = pull8() | FLAG_CONSTANT;
|
status = pull8() | FLAG_CONSTANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ply() { // new 65c02 instruction
|
||||||
|
y = pull8();
|
||||||
|
|
||||||
|
zerocalc(y);
|
||||||
|
signcalc(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plx() { // new 65c02 instruction
|
||||||
|
a = pull8();
|
||||||
|
|
||||||
|
zerocalc(x);
|
||||||
|
signcalc(x);
|
||||||
|
}
|
||||||
|
|
||||||
static void rol() {
|
static void rol() {
|
||||||
value = getvalue();
|
value = getvalue();
|
||||||
result = (value << 1) | (status & FLAG_CARRY);
|
result = (value << 1) | (status & FLAG_CARRY);
|
||||||
@ -608,6 +677,10 @@ static void sty() {
|
|||||||
putvalue(y);
|
putvalue(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void stz() { // new 65c02 instruction
|
||||||
|
putvalue(0);
|
||||||
|
}
|
||||||
|
|
||||||
static void tax() {
|
static void tax() {
|
||||||
x = a;
|
x = a;
|
||||||
|
|
||||||
@ -647,44 +720,88 @@ static void tya() {
|
|||||||
signcalc(a);
|
signcalc(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void (*addrtable[256])() = {
|
static void trb() { // new 65c02 instruction
|
||||||
/* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */
|
value = getvalue();
|
||||||
/* 0 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, abso, /* 0 */
|
result = value & ~a;
|
||||||
/* 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 */
|
zerocalc(result);
|
||||||
/* 3 */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx, /* 3 */
|
putvalue(result);
|
||||||
/* 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 */
|
static void tsb() { // new 65c02 instruction
|
||||||
/* 7 */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx, /* 7 */
|
value = getvalue();
|
||||||
/* 8 */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, abso, /* 8 */
|
result = value | a;
|
||||||
/* 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 */
|
zerocalc(result);
|
||||||
/* B */ rel, indy, imp, indy, zpx, zpx, zpy, zpy, imp, absy, imp, absy, absx, absx, absy, absy, /* B */
|
putvalue(result);
|
||||||
/* 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 */
|
static void rmb() { // new 65c02 instruction
|
||||||
/* F */ rel, indy, imp, indy, zpx, zpx, zpx, zpx, imp, absy, imp, absy, absx, absx, absx, absx /* F */
|
uint8_t testval = 1;
|
||||||
};
|
for (int i = 0; i < ((opcode & 0b01110000) >> 4); i++) testval = testval << 1;
|
||||||
|
|
||||||
|
value = getvalue();
|
||||||
|
result = value & ~testval;
|
||||||
|
|
||||||
|
putvalue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void smb() { // new 65c02 instruction
|
||||||
|
uint8_t testval = 1;
|
||||||
|
for (int i = 0; i < ((opcode & 0b01110000) >> 4); i++) testval = testval << 1;
|
||||||
|
|
||||||
|
value = getvalue();
|
||||||
|
result = value | testval;
|
||||||
|
|
||||||
|
putvalue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wai() { // new 65c02 instruction
|
||||||
|
// implement later
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stp() { // new 65c02 instruction
|
||||||
|
// implement later
|
||||||
|
}
|
||||||
|
|
||||||
static void (*optable[256])() = {
|
static void (*optable[256])() = {
|
||||||
/* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */
|
/* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | */
|
||||||
/* 0 */ brk, ora, nop, nop, nop, ora, asl, nop, php, ora, asl, nop, nop, ora, asl, nop, /* 0 */
|
/* 0 */ brk, ora, nop, nop, tsb, ora, asl, rmb, php, ora, asl, nop, tsb, ora, asl, bbr, /* 0 */
|
||||||
/* 1 */ bpl, ora, nop, nop, nop, ora, asl, nop, clc, ora, nop, nop, nop, ora, asl, nop, /* 1 */
|
/* 1 */ bpl, ora, ora, nop, trb, ora, asl, rmb, clc, ora, inc, nop, trb, ora, asl, bbr, /* 1 */
|
||||||
/* 2 */ jsr, and, nop, nop, bit, and, rol, nop, plp, and, rol, nop, bit, and, rol, nop, /* 2 */
|
/* 2 */ jsr, and, nop, nop, bit, and, rol, rmb, plp, and, rol, nop, bit, and, rol, bbr, /* 2 */
|
||||||
/* 3 */ bmi, and, nop, nop, nop, and, rol, nop, sec, and, nop, nop, nop, and, rol, nop, /* 3 */
|
/* 3 */ bmi, and, and, nop, bit, and, rol, rmb, sec, and, dec, nop, bit, and, rol, bbr, /* 3 */
|
||||||
/* 4 */ rti, eor, nop, nop, nop, eor, lsr, nop, pha, eor, lsr, nop, jmp, eor, lsr, nop, /* 4 */
|
/* 4 */ rti, eor, nop, nop, nop, eor, lsr, rmb, pha, eor, lsr, nop, jmp, eor, lsr, bbr, /* 4 */
|
||||||
/* 5 */ bvc, eor, nop, nop, nop, eor, lsr, nop, cli, eor, nop, nop, nop, eor, lsr, nop, /* 5 */
|
/* 5 */ bvc, eor, eor, nop, nop, eor, lsr, rmb, cli, eor, phy, nop, nop, eor, lsr, bbr, /* 5 */
|
||||||
/* 6 */ rts, adc, nop, nop, nop, adc, ror, nop, pla, adc, ror, nop, jmp, adc, ror, nop, /* 6 */
|
/* 6 */ rts, adc, nop, nop, stz, adc, ror, rmb, pla, adc, ror, nop, jmp, adc, ror, bbr, /* 6 */
|
||||||
/* 7 */ bvs, adc, nop, nop, nop, adc, ror, nop, sei, adc, nop, nop, nop, adc, ror, nop, /* 7 */
|
/* 7 */ bvs, adc, adc, nop, stz, adc, ror, rmb, sei, adc, ply, nop, jmp, adc, ror, bbr, /* 7 */
|
||||||
/* 8 */ nop, sta, nop, nop, sty, sta, stx, nop, dey, nop, txa, nop, sty, sta, stx, nop, /* 8 */
|
/* 8 */ bra, sta, nop, nop, sty, sta, stx, smb, dey, bit, txa, nop, sty, sta, stx, bbs, /* 8 */
|
||||||
/* 9 */ bcc, sta, nop, nop, sty, sta, stx, nop, tya, sta, txs, nop, nop, sta, nop, nop, /* 9 */
|
/* 9 */ bcc, sta, sta, nop, sty, sta, stx, smb, tya, sta, txs, nop, stz, sta, stz, bbs, /* 9 */
|
||||||
/* A */ ldy, lda, ldx, nop, ldy, lda, ldx, nop, tay, lda, tax, nop, ldy, lda, ldx, nop, /* A */
|
/* A */ ldy, lda, ldx, nop, ldy, lda, ldx, smb, tay, lda, tax, nop, ldy, lda, ldx, bbs, /* A */
|
||||||
/* B */ bcs, lda, nop, nop, ldy, lda, ldx, nop, clv, lda, tsx, nop, ldy, lda, ldx, nop, /* B */
|
/* B */ bcs, lda, lda, nop, ldy, lda, ldx, smb, clv, lda, tsx, nop, ldy, lda, ldx, bbs, /* B */
|
||||||
/* C */ cpy, cmp, nop, nop, cpy, cmp, dec, nop, iny, cmp, dex, nop, cpy, cmp, dec, nop, /* C */
|
/* C */ cpy, cmp, nop, nop, cpy, cmp, dec, smb, iny, cmp, dex, wai, cpy, cmp, dec, bbs, /* C */
|
||||||
/* D */ bne, cmp, nop, nop, nop, cmp, dec, nop, cld, cmp, nop, nop, nop, cmp, dec, nop, /* D */
|
/* D */ bne, cmp, cmp, nop, nop, cmp, dec, smb, cld, cmp, phx, stp, nop, cmp, dec, bbs, /* D */
|
||||||
/* E */ cpx, sbc, nop, nop, cpx, sbc, inc, nop, inx, sbc, nop, sbc, cpx, sbc, inc, nop, /* E */
|
/* E */ cpx, sbc, nop, nop, cpx, sbc, inc, smb, inx, sbc, nop, sbc, cpx, sbc, inc, bbs, /* E */
|
||||||
/* F */ beq, sbc, nop, nop, nop, sbc, inc, nop, sed, sbc, nop, nop, nop, sbc, inc, nop /* F */
|
/* F */ beq, sbc, sbc, nop, nop, sbc, inc, smb, sed, sbc, plx, nop, nop, sbc, inc, bbs /* F */
|
||||||
|
};
|
||||||
|
|
||||||
|
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, rel, /* 0 */
|
||||||
|
/* 1 */ rel, indy, izp, indy, zp, zpx, zpx, zp, imp, absy, acc, absy, abso, absx, absx, rel, /* 1 */
|
||||||
|
/* 2 */ abso, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, rel, /* 2 */
|
||||||
|
/* 3 */ rel, indy, izp, indy, zpx, zpx, zpx, zp, imp, absy, acc, absy, absx, absx, absx, rel, /* 3 */
|
||||||
|
/* 4 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, abso, abso, abso, rel, /* 4 */
|
||||||
|
/* 5 */ rel, indy, izp, indy, zpx, zpx, zpx, zp, imp, absy, imp, absy, absx, absx, absx, rel, /* 5 */
|
||||||
|
/* 6 */ imp, indx, imp, indx, zp, zp, zp, zp, imp, imm, acc, imm, ind, abso, abso, rel, /* 6 */
|
||||||
|
/* 7 */ rel, indy, izp, indy, zpx, zpx, zpx, zp, imp, absy, imp, absy, aii, absx, absx, rel, /* 7 */
|
||||||
|
/* 8 */ rel, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, rel, /* 8 */
|
||||||
|
/* 9 */ rel, indy, izp, indy, zpx, zpx, zpy, zp, imp, absy, imp, absy, abso, absx, absx, rel, /* 9 */
|
||||||
|
/* A */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, rel, /* A */
|
||||||
|
/* B */ rel, indy, izp, indy, zpx, zpx, zpy, zp, imp, absy, imp, absy, absx, absx, absy, rel, /* B */
|
||||||
|
/* C */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imp, abso, abso, abso, rel, /* C */
|
||||||
|
/* D */ rel, indy, izp, indy, zpx, zpx, zpx, zp, imp, absy, imp, imp, absx, absx, absx, rel, /* D */
|
||||||
|
/* E */ imm, indx, imm, indx, zp, zp, zp, zp, imp, imm, imp, imm, abso, abso, abso, rel, /* E */
|
||||||
|
/* F */ rel, indy, izp, indy, zpx, zpx, zpx, zp, imp, absy, imp, absy, absx, absx, absx, rel /* F */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint32_t ticktable[256] = {
|
static const uint32_t ticktable[256] = {
|
||||||
@ -716,11 +833,15 @@ void nmi6502() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void irq6502() {
|
void irq6502() {
|
||||||
|
// only initiate interrupts when interrupt flag is cleared
|
||||||
|
|
||||||
|
if (!(status & FLAG_INTERRUPT)){
|
||||||
push16(pc);
|
push16(pc);
|
||||||
push8(status);
|
push8(status);
|
||||||
status |= FLAG_INTERRUPT;
|
status |= FLAG_INTERRUPT;
|
||||||
pc = (uint16_t)read6502(0xFFFE) | ((uint16_t)read6502(0xFFFF) << 8);
|
pc = (uint16_t)read6502(0xFFFE) | ((uint16_t)read6502(0xFFFF) << 8);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void step6502() {
|
void step6502() {
|
||||||
opcode = read6502(pc++);
|
opcode = read6502(pc++);
|
||||||
|
Loading…
Reference in New Issue
Block a user