Files
ProSystem-Core/core/Sally.cpp
T
clobber 6d1f51397e Initial port
Still needs sound. Note: won't run with optimizations so release build
is -O0
2013-07-30 02:31:40 -05:00

1737 lines
41 KiB
C++
Executable File

// ----------------------------------------------------------------------------
// ___ ___ ___ ___ ___ ____ ___ _ _
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
//
// ----------------------------------------------------------------------------
// Copyright 2005 Greg Stanton
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// ----------------------------------------------------------------------------
// Sally.cpp
// ----------------------------------------------------------------------------
#include "Sally.h"
byte sally_a = 0;
byte sally_x = 0;
byte sally_y = 0;
byte sally_p = 0;
byte sally_s = 0;
pair sally_pc = {0};
static byte sally_opcode;
static pair sally_address;
static uint sally_cycles;
struct Flag {
byte C;
byte Z;
byte I;
byte D;
byte B;
byte R;
byte V;
byte N;
};
static const Flag SALLY_FLAG = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
struct Vector {
word H;
word L;
};
static const Vector SALLY_RES = {65533, 65532};
static const Vector SALLY_NMI = {65531, 65530};
static const Vector SALLY_IRQ = {65535, 65534};
static const byte SALLY_CYCLES[256] = {
7,6,0,0,0,3,5,0,3,2,2,0,0,4,6,0,
2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,
6,6,0,0,3,3,5,0,4,2,2,0,4,4,6,0,
2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,
6,6,0,0,0,3,5,0,3,2,2,0,3,4,6,0,
2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,
6,6,0,0,0,3,5,0,4,2,2,0,5,4,6,0,
2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,
0,6,0,0,3,3,3,0,2,0,2,0,4,4,4,0,
2,6,0,0,4,4,4,0,2,5,2,0,0,5,0,0,
2,6,2,0,3,3,3,0,2,2,2,0,4,4,4,0,
2,5,0,0,4,4,4,0,2,4,2,0,4,4,4,0,
2,6,0,0,3,3,5,0,2,2,2,0,4,4,6,0,
2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,
2,6,0,0,3,3,5,0,2,2,2,0,4,4,6,0,
2,5,0,0,0,4,6,0,2,4,0,0,0,4,7,0,
};
// ----------------------------------------------------------------------------
// Push
// ----------------------------------------------------------------------------
static void sally_Push(byte data) {
memory_Write(sally_s + 256, data);
sally_s--;
}
// ----------------------------------------------------------------------------
// Pop
// ----------------------------------------------------------------------------
static byte sally_Pop( ) {
sally_s++;
return memory_Read(sally_s + 256);
}
// ----------------------------------------------------------------------------
// Flags
// ----------------------------------------------------------------------------
static void sally_Flags(byte data) {
if(!data) {
sally_p |= SALLY_FLAG.Z;
}
else {
sally_p &= ~SALLY_FLAG.Z;
}
if(data & 128) {
sally_p |= SALLY_FLAG.N;
}
else {
sally_p &= ~SALLY_FLAG.N;
}
}
// ----------------------------------------------------------------------------
// Branch
// ----------------------------------------------------------------------------
static void sally_Branch(byte branch) {
if(branch) {
pair temp = sally_pc;
sally_pc.w += (char)sally_address.b.l;
if(temp.b.h != sally_pc.b.h) {
sally_cycles += 2;
}
else {
sally_cycles++;
}
}
}
// ----------------------------------------------------------------------------
// Delay
// ----------------------------------------------------------------------------
static void sally_Delay(byte delta) {
pair address1 = sally_address;
pair address2 = sally_address;
address1.w -= delta;
if(address1.b.h != address2.b.h) {
sally_cycles++;
}
}
// ----------------------------------------------------------------------------
// Absolute
// ----------------------------------------------------------------------------
static void sally_Absolute( ) {
sally_address.b.l = memory_Read(sally_pc.w++);
sally_address.b.h = memory_Read(sally_pc.w++);
}
// ----------------------------------------------------------------------------
// AbsoluteX
// ----------------------------------------------------------------------------
static void sally_AbsoluteX( ) {
sally_address.b.l = memory_Read(sally_pc.w++);
sally_address.b.h = memory_Read(sally_pc.w++);
sally_address.w += sally_x;
}
// ----------------------------------------------------------------------------
// AbsoluteY
// ----------------------------------------------------------------------------
static void sally_AbsoluteY( ) {
sally_address.b.l = memory_Read(sally_pc.w++);
sally_address.b.h = memory_Read(sally_pc.w++);
sally_address.w += sally_y;
}
// ----------------------------------------------------------------------------
// Immediate
// ----------------------------------------------------------------------------
static void sally_Immediate( ) {
sally_address.w = sally_pc.w++;
}
// ----------------------------------------------------------------------------
// Indirect
// ----------------------------------------------------------------------------
static void sally_Indirect( ) {
pair base;
base.b.l = memory_Read(sally_pc.w++);
base.b.h = memory_Read(sally_pc.w++);
sally_address.b.l = memory_Read(base.w);
sally_address.b.h = memory_Read(base.w + 1);
}
// ----------------------------------------------------------------------------
// IndirectX
// ----------------------------------------------------------------------------
static void sally_IndirectX( ) {
sally_address.b.l = memory_Read(sally_pc.w++) + sally_x;
sally_address.b.h = memory_Read(sally_address.b.l + 1);
sally_address.b.l = memory_Read(sally_address.b.l);
}
// ----------------------------------------------------------------------------
// IndirectY
// ----------------------------------------------------------------------------
static void sally_IndirectY( ) {
sally_address.b.l = memory_Read(sally_pc.w++);
sally_address.b.h = memory_Read(sally_address.b.l + 1);
sally_address.b.l = memory_Read(sally_address.b.l);
sally_address.w += sally_y;
}
// ----------------------------------------------------------------------------
// Relative
// ----------------------------------------------------------------------------
static void sally_Relative( ) {
sally_address.w = memory_Read(sally_pc.w++);
}
// ----------------------------------------------------------------------------
// Zero Page
// ----------------------------------------------------------------------------
static void sally_ZeroPage( ) {
sally_address.w = memory_Read(sally_pc.w++);
}
// ----------------------------------------------------------------------------
// ZeroPageX
// ----------------------------------------------------------------------------
static void sally_ZeroPageX( ) {
sally_address.w = memory_Read(sally_pc.w++);
sally_address.b.l += sally_x;
}
// ----------------------------------------------------------------------------
// ZeroPageY
// ----------------------------------------------------------------------------
static void sally_ZeroPageY( ) {
sally_address.w = memory_Read(sally_pc.w++);
sally_address.b.l += sally_y;
}
// ----------------------------------------------------------------------------
// ADC
// ----------------------------------------------------------------------------
static void sally_ADC( ) {
byte data = memory_Read(sally_address.w);
if(sally_p & SALLY_FLAG.D) {
word al = (sally_a & 15) + (data & 15) + (sally_p & SALLY_FLAG.C);
word ah = (sally_a >> 4) + (data >> 4);
if(al > 9) {
al += 6;
ah++;
}
if(!(sally_a + data + (sally_p & SALLY_FLAG.C))) {
sally_p |= SALLY_FLAG.Z;
}
else {
sally_p &= ~SALLY_FLAG.Z;
}
if((ah & 8) != 0) {
sally_p |= SALLY_FLAG.N;
}
else {
sally_p &= ~SALLY_FLAG.N;
}
if(~(sally_a ^ data) & ((ah << 4) ^ sally_a) & 128) {
sally_p |= SALLY_FLAG.V;
}
else {
sally_p &= ~SALLY_FLAG.V;
}
if(ah > 9) {
ah += 6;
}
if(ah > 15) {
sally_p |= SALLY_FLAG.C;
}
else {
sally_p &= ~SALLY_FLAG.C;
}
sally_a = (ah << 4) | (al & 15);
}
else {
pair temp;
temp.w = sally_a + data + (sally_p & SALLY_FLAG.C);
if(temp.b.h) {
sally_p |= SALLY_FLAG.C;
}
else {
sally_p &= ~SALLY_FLAG.C;
}
if(~(sally_a ^ data) & (sally_a ^ temp.b.l) & 128) {
sally_p |= SALLY_FLAG.V;
}
else {
sally_p &= ~SALLY_FLAG.V;
}
sally_Flags(temp.b.l);
sally_a = temp.b.l;
}
}
// ----------------------------------------------------------------------------
// AND
// ----------------------------------------------------------------------------
static void sally_AND( ) {
sally_a &= memory_Read(sally_address.w);
sally_Flags(sally_a);
}
// ----------------------------------------------------------------------------
// ASLA
// ----------------------------------------------------------------------------
static void sally_ASLA( ) {
if(sally_a & 128) {
sally_p |= SALLY_FLAG.C;
}
else {
sally_p &= ~SALLY_FLAG.C;
}
sally_a <<= 1;
sally_Flags(sally_a);
}
// ----------------------------------------------------------------------------
// ASL
// ----------------------------------------------------------------------------
static void sally_ASL( ) {
byte data = memory_Read(sally_address.w);
if(data & 128) {
sally_p |= SALLY_FLAG.C;
}
else {
sally_p &= ~SALLY_FLAG.C;
}
data <<= 1;
memory_Write(sally_address.w, data);
sally_Flags(data);
}
// ----------------------------------------------------------------------------
// BCC
// ----------------------------------------------------------------------------
static void sally_BCC( ) {
sally_Branch(!(sally_p & SALLY_FLAG.C));
}
// ----------------------------------------------------------------------------
// BCS
// ----------------------------------------------------------------------------
static void sally_BCS( ) {
sally_Branch(sally_p & SALLY_FLAG.C);
}
// ----------------------------------------------------------------------------
// BEQ
// ----------------------------------------------------------------------------
static void sally_BEQ( ) {
sally_Branch(sally_p & SALLY_FLAG.Z);
}
// ----------------------------------------------------------------------------
// BIT
// ----------------------------------------------------------------------------
static void sally_BIT( ) {
byte data = memory_Read(sally_address.w);
if(!(data & sally_a)) {
sally_p |= SALLY_FLAG.Z;
}
else {
sally_p &= ~SALLY_FLAG.Z;
}
sally_p &= ~SALLY_FLAG.V;
sally_p &= ~SALLY_FLAG.N;
sally_p |= data & 64;
sally_p |= data & 128;
}
// ----------------------------------------------------------------------------
// BMI
// ----------------------------------------------------------------------------
static void sally_BMI( ) {
sally_Branch(sally_p & SALLY_FLAG.N);
}
// ----------------------------------------------------------------------------
// BNE
// ----------------------------------------------------------------------------
static void sally_BNE( ) {
sally_Branch(!(sally_p & SALLY_FLAG.Z));
}
// ----------------------------------------------------------------------------
// BPL
// ----------------------------------------------------------------------------
static void sally_BPL( ) {
sally_Branch(!(sally_p & SALLY_FLAG.N));
}
// ----------------------------------------------------------------------------
// BRK
// ----------------------------------------------------------------------------
static void sally_BRK( ) {
sally_pc.w++;
sally_p |= SALLY_FLAG.B;
sally_Push(sally_pc.b.h);
sally_Push(sally_pc.b.l);
sally_Push(sally_p);
sally_p |= SALLY_FLAG.I;
sally_pc.b.l = memory_ram[SALLY_IRQ.L];
sally_pc.b.h = memory_ram[SALLY_IRQ.H];
}
// ----------------------------------------------------------------------------
// BVC
// ----------------------------------------------------------------------------
static void sally_BVC( ) {
sally_Branch(!(sally_p & SALLY_FLAG.V));
}
// ----------------------------------------------------------------------------
// BVS
// ----------------------------------------------------------------------------
static void sally_BVS( ) {
sally_Branch(sally_p & SALLY_FLAG.V);
}
// ----------------------------------------------------------------------------
// CLC
// ----------------------------------------------------------------------------
static void sally_CLC( ) {
sally_p &= ~SALLY_FLAG.C;
}
// ----------------------------------------------------------------------------
// CLD
// ----------------------------------------------------------------------------
static void sally_CLD( ) {
sally_p &= ~SALLY_FLAG.D;
}
// ----------------------------------------------------------------------------
// CLI
// ----------------------------------------------------------------------------
static void sally_CLI( ) {
sally_p &= ~SALLY_FLAG.I;
}
// ----------------------------------------------------------------------------
// CLV
// ----------------------------------------------------------------------------
static void sally_CLV( ) {
sally_p &= ~SALLY_FLAG.V;
}
// ----------------------------------------------------------------------------
// CMP
// ----------------------------------------------------------------------------
static void sally_CMP( ) {
byte data = memory_Read(sally_address.w);
if(sally_a >= data) {
sally_p |= SALLY_FLAG.C;
}
else {
sally_p &= ~SALLY_FLAG.C;
}
sally_Flags(sally_a - data);
}
// ----------------------------------------------------------------------------
// CPX
// ----------------------------------------------------------------------------
static void sally_CPX( ) {
byte data = memory_Read(sally_address.w);
if(sally_x >= data) {
sally_p |= SALLY_FLAG.C;
}
else {
sally_p &= ~SALLY_FLAG.C;
}
sally_Flags(sally_x - data);
}
// ----------------------------------------------------------------------------
// CPY
// ----------------------------------------------------------------------------
static void sally_CPY( ) {
byte data = memory_Read(sally_address.w);
if(sally_y >= data) {
sally_p |= SALLY_FLAG.C;
}
else {
sally_p &= ~SALLY_FLAG.C;
}
sally_Flags(sally_y - data);
}
// ----------------------------------------------------------------------------
// DEC
// ----------------------------------------------------------------------------
static void sally_DEC( ) {
byte data = memory_Read(sally_address.w);
memory_Write(sally_address.w, --data);
sally_Flags(data);
}
// ----------------------------------------------------------------------------
// DEX
// ----------------------------------------------------------------------------
static void sally_DEX( ) {
sally_Flags(--sally_x);
}
// ----------------------------------------------------------------------------
// DEY
// ----------------------------------------------------------------------------
static void sally_DEY( ) {
sally_Flags(--sally_y);
}
// ----------------------------------------------------------------------------
// EOR
// ----------------------------------------------------------------------------
static void sally_EOR( ) {
sally_a ^= memory_Read(sally_address.w);
sally_Flags(sally_a);
}
// ----------------------------------------------------------------------------
// INC
// ----------------------------------------------------------------------------
static void sally_INC( ) {
byte data = memory_Read(sally_address.w);
memory_Write(sally_address.w, ++data);
sally_Flags(data);
}
// ----------------------------------------------------------------------------
// INX
// ----------------------------------------------------------------------------
static void sally_INX( ) {
sally_Flags(++sally_x);
}
// ----------------------------------------------------------------------------
// INY
// ----------------------------------------------------------------------------
static void sally_INY( ) {
sally_Flags(++sally_y);
}
// ----------------------------------------------------------------------------
// JMP
// ----------------------------------------------------------------------------
static void sally_JMP( ) {
sally_pc = sally_address;
}
// ----------------------------------------------------------------------------
// JSR
// ----------------------------------------------------------------------------
static void sally_JSR( ) {
sally_pc.w--;
sally_Push(sally_pc.b.h);
sally_Push(sally_pc.b.l);
sally_pc = sally_address;
}
// ----------------------------------------------------------------------------
// LDA
// ----------------------------------------------------------------------------
static void sally_LDA( ) {
sally_a = memory_Read(sally_address.w);
sally_Flags(sally_a);
}
// ----------------------------------------------------------------------------
// LDX
// ----------------------------------------------------------------------------
static void sally_LDX( ) {
sally_x = memory_Read(sally_address.w);
sally_Flags(sally_x);
}
// ----------------------------------------------------------------------------
// LDY
// ----------------------------------------------------------------------------
static void sally_LDY( ) {
sally_y = memory_Read(sally_address.w);
sally_Flags(sally_y);
}
// ----------------------------------------------------------------------------
// LSRA
// ----------------------------------------------------------------------------
static void sally_LSRA( ) {
sally_p &= ~SALLY_FLAG.C;
sally_p |= sally_a & 1;
sally_a >>= 1;
sally_Flags(sally_a);
}
// ----------------------------------------------------------------------------
// LSR
// ----------------------------------------------------------------------------
static void sally_LSR( ) {
byte data = memory_Read(sally_address.w);
sally_p &= ~SALLY_FLAG.C;
sally_p |= data & 1;
data >>= 1;
memory_Write(sally_address.w, data);
sally_Flags(data);
}
// ----------------------------------------------------------------------------
// NOP
// ----------------------------------------------------------------------------
static void sally_NOP( ) {
}
// ----------------------------------------------------------------------------
// ORA
// ----------------------------------------------------------------------------
static void sally_ORA( ) {
sally_a |= memory_Read(sally_address.w);
sally_Flags(sally_a);
}
// ----------------------------------------------------------------------------
// PHA
// ----------------------------------------------------------------------------
static void sally_PHA( ) {
sally_Push(sally_a);
}
// ----------------------------------------------------------------------------
// PHP
// ----------------------------------------------------------------------------
static void sally_PHP( ) {
sally_Push(sally_p);
}
// ----------------------------------------------------------------------------
// PLA
// ----------------------------------------------------------------------------
static void sally_PLA( ) {
sally_a = sally_Pop( );
sally_Flags(sally_a);
}
// ----------------------------------------------------------------------------
// PLP
// ----------------------------------------------------------------------------
static void sally_PLP( ) {
sally_p = sally_Pop( );
}
// ----------------------------------------------------------------------------
// ROLA
// ----------------------------------------------------------------------------
static void sally_ROLA( ) {
byte temp = sally_p;
if(sally_a & 128) {
sally_p |= SALLY_FLAG.C;
}
else {
sally_p &= ~SALLY_FLAG.C;
}
sally_a <<= 1;
sally_a |= temp & SALLY_FLAG.C;
sally_Flags(sally_a);
}
// ----------------------------------------------------------------------------
// ROL
// ----------------------------------------------------------------------------
static void sally_ROL( ) {
byte data = memory_Read(sally_address.w);
byte temp = sally_p;
if(data & 128) {
sally_p |= SALLY_FLAG.C;
}
else {
sally_p &= ~SALLY_FLAG.C;
}
data <<= 1;
data |= temp & 1;
memory_Write(sally_address.w, data);
sally_Flags(data);
}
// ----------------------------------------------------------------------------
// RORA
// ----------------------------------------------------------------------------
static void sally_RORA( ) {
byte temp = sally_p;
sally_p &= ~SALLY_FLAG.C;
sally_p |= sally_a & 1;
sally_a >>= 1;
if(temp & SALLY_FLAG.C) {
sally_a |= 128;
}
sally_Flags(sally_a);
}
// ----------------------------------------------------------------------------
// ROR
// ----------------------------------------------------------------------------
static void sally_ROR( ) {
byte data = memory_Read(sally_address.w);
byte temp = sally_p;
sally_p &= ~SALLY_FLAG.C;
sally_p |= data & 1;
data >>= 1;
if(temp & 1) {
data |= 128;
}
memory_Write(sally_address.w, data);
sally_Flags(data);
}
// ----------------------------------------------------------------------------
// RTI
// ----------------------------------------------------------------------------
static void sally_RTI( ) {
sally_p = sally_Pop( );
sally_pc.b.l = sally_Pop( );
sally_pc.b.h = sally_Pop( );
}
// ----------------------------------------------------------------------------
// RTS
// ----------------------------------------------------------------------------
static void sally_RTS( ) {
sally_pc.b.l = sally_Pop( );
sally_pc.b.h = sally_Pop( );
sally_pc.w++;
}
// ----------------------------------------------------------------------------
// SBC
// ----------------------------------------------------------------------------
static void sally_SBC( ) {
byte data = memory_Read(sally_address.w);
if(sally_p & SALLY_FLAG.D) {
word al = (sally_a & 15) - (data & 15) - !(sally_p & SALLY_FLAG.C);
word ah = (sally_a >> 4) - (data >> 4);
if(al > 9) {
al -= 6;
ah--;
}
if(ah > 9) {
ah -= 6;
}
pair temp;
temp.w = sally_a - data - !(sally_p & SALLY_FLAG.C);
if(!temp.b.h) {
sally_p |= SALLY_FLAG.C;
}
else {
sally_p &= ~SALLY_FLAG.C;
}
if((sally_a ^ data) & (sally_a ^ temp.b.l) & 128) {
sally_p |= SALLY_FLAG.V;
}
else {
sally_p &= ~SALLY_FLAG.V;
}
sally_Flags(temp.b.l);
sally_a = (ah << 4) | (al & 15);
}
else {
pair temp;
temp.w = sally_a - data - !(sally_p & SALLY_FLAG.C);
if(!temp.b.h) {
sally_p |= SALLY_FLAG.C;
}
else {
sally_p &= ~SALLY_FLAG.C;
}
if((sally_a ^ data) & (sally_a ^ temp.b.l) & 128) {
sally_p |= SALLY_FLAG.V;
}
else {
sally_p &= ~SALLY_FLAG.V;
}
sally_Flags(temp.b.l);
sally_a = temp.b.l;
}
}
// ----------------------------------------------------------------------------
// SEC
// ----------------------------------------------------------------------------
static void sally_SEC( ) {
sally_p |= SALLY_FLAG.C;
}
// ----------------------------------------------------------------------------
// SED
// ----------------------------------------------------------------------------
static void sally_SED( ) {
sally_p |= SALLY_FLAG.D;
}
// ----------------------------------------------------------------------------
// SEI
// ----------------------------------------------------------------------------
static void sally_SEI( ) {
sally_p |= SALLY_FLAG.I;
}
// ----------------------------------------------------------------------------
// STA
// ----------------------------------------------------------------------------
static void sally_STA( ) {
memory_Write(sally_address.w, sally_a);
}
// ----------------------------------------------------------------------------
// STX
// ----------------------------------------------------------------------------
static void sally_stx( ) {
memory_Write(sally_address.w, sally_x);
}
// ----------------------------------------------------------------------------
// STY
// ----------------------------------------------------------------------------
static void sally_STY( ) {
memory_Write(sally_address.w, sally_y);
}
// ----------------------------------------------------------------------------
// TAX
// ----------------------------------------------------------------------------
static void sally_TAX( ) {
sally_x = sally_a;
sally_Flags(sally_x);
}
// ----------------------------------------------------------------------------
// TAY
// ----------------------------------------------------------------------------
static void sally_TAY( ) {
sally_y = sally_a;
sally_Flags(sally_y);
}
// ----------------------------------------------------------------------------
// TSX
// ----------------------------------------------------------------------------
static void sally_TSX( ) {
sally_x = sally_s;
sally_Flags(sally_x);
}
// ----------------------------------------------------------------------------
// TXA
// ----------------------------------------------------------------------------
static void sally_TXA( ) {
sally_a = sally_x;
sally_Flags(sally_a);
}
// ----------------------------------------------------------------------------
// TXS
// ----------------------------------------------------------------------------
static void sally_TXS( ) {
sally_s = sally_x;
}
// ----------------------------------------------------------------------------
// TYA
// ----------------------------------------------------------------------------
static void sally_TYA( ) {
sally_a = sally_y;
sally_Flags(sally_a);
}
// ----------------------------------------------------------------------------
// Reset
// ----------------------------------------------------------------------------
void sally_Reset( ) {
sally_a = 0;
sally_x = 0;
sally_y = 0;
sally_p = SALLY_FLAG.R;
sally_s = 0;
sally_pc.w = 0;
}
// ----------------------------------------------------------------------------
// ExecuteInstruction
// ----------------------------------------------------------------------------
uint sally_ExecuteInstruction( ) {
sally_opcode = memory_Read(sally_pc.w++);
sally_cycles = SALLY_CYCLES[sally_opcode];
switch(sally_opcode) {
case 0x00:
sally_BRK( );
break;
case 0x01:
sally_IndirectX( );
sally_ORA( );
break;
case 0x05:
sally_ZeroPage( );
sally_ORA( );
break;
case 0x06:
sally_ZeroPage( );
sally_ASL( );
break;
case 0x08:
sally_PHP( );
break;
case 0x09:
sally_Immediate( );
sally_ORA( );
break;
case 0x0a:
sally_ASLA( );
break;
case 0x0d:
sally_Absolute( );
sally_ORA( );
break;
case 0x0e:
sally_Absolute( );
sally_ASL( );
break;
case 0x10:
sally_Relative( );
sally_BPL( );
break;
case 0x11:
sally_IndirectY( );
sally_ORA( );
sally_Delay(sally_y);
break;
case 0x15:
sally_ZeroPageX( );
sally_ORA( );
break;
case 0x16:
sally_ZeroPageX( );
sally_ASL( );
break;
case 0x18:
sally_CLC( );
break;
case 0x19:
sally_AbsoluteY( );
sally_ORA( );
sally_Delay(sally_y);
break;
case 0x1d:
sally_AbsoluteX( );
sally_ORA( );
sally_Delay(sally_x);
break;
case 0x1e:
sally_AbsoluteX( );
sally_ASL( );
break;
case 0x20:
sally_Absolute( );
sally_JSR( );
break;
case 0x21:
sally_IndirectX( );
sally_AND( );
break;
case 0x24:
sally_ZeroPage( );
sally_BIT( );
break;
case 0x25:
sally_ZeroPage( );
sally_AND( );
break;
case 0x26:
sally_ZeroPage( );
sally_ROL( );
break;
case 0x28:
sally_PLP( );
break;
case 0x29:
sally_Immediate( );
sally_AND( );
break;
case 0x2a:
sally_ROLA( );
break;
case 0x2c:
sally_Absolute( );
sally_BIT( );
break;
case 0x2d:
sally_Absolute( );
sally_AND( );
break;
case 0x2e:
sally_Absolute( );
sally_ROL( );
break;
case 0x30:
sally_Relative( );
sally_BMI( );
break;
case 0x31:
sally_IndirectY( );
sally_AND( );
sally_Delay(sally_y);
break;
case 0x35:
sally_ZeroPageX( );
sally_AND( );
break;
case 0x36:
sally_ZeroPageX( );
sally_ROL( );
break;
case 0x38:
sally_SEC( );
break;
case 0x39:
sally_AbsoluteY( );
sally_AND( );
sally_Delay(sally_y);
break;
case 0x3d:
sally_AbsoluteX( );
sally_AND( );
sally_Delay(sally_x);
break;
case 0x3e:
sally_AbsoluteX( );
sally_ROL( );
break;
case 0x40:
sally_RTI( );
break;
case 0x41:
sally_IndirectX( );
sally_EOR( );
break;
case 0x45:
sally_ZeroPage( );
sally_EOR( );
break;
case 0x46:
sally_ZeroPage( );
sally_LSR( );
break;
case 0x48:
sally_PHA( );
break;
case 0x49:
sally_Immediate( );
sally_EOR( );
break;
case 0x4a:
sally_LSRA( );
break;
case 0x4c:
sally_Absolute( );
sally_JMP( );
break;
case 0x4d:
sally_Absolute( );
sally_EOR( );
break;
case 0x4e:
sally_Absolute( );
sally_LSR( );
break;
case 0x50:
sally_Relative( );
sally_BVC( );
break;
case 0x51:
sally_IndirectY( );
sally_EOR( );
sally_Delay(sally_y);
break;
case 0x55:
sally_ZeroPageX( );
sally_EOR( );
break;
case 0x56:
sally_ZeroPageX( );
sally_LSR( );
break;
case 0x58:
sally_CLI( );
break;
case 0x59:
sally_AbsoluteY( );
sally_EOR( );
sally_Delay(sally_y);
break;
case 0x5d:
sally_AbsoluteX( );
sally_EOR( );
sally_Delay(sally_x);
break;
case 0x5e:
sally_AbsoluteX( );
sally_LSR( );
break;
case 0x60:
sally_RTS( );
break;
case 0x61:
sally_IndirectX( );
sally_ADC( );
break;
case 0x65:
sally_ZeroPage( );
sally_ADC( );
break;
case 0x66:
sally_ZeroPage( );
sally_ROR( );
break;
case 0x68:
sally_PLA( );
break;
case 0x69:
sally_Immediate( );
sally_ADC( );
break;
case 0x6a:
sally_RORA( );
break;
case 0x6c:
sally_Indirect( );
sally_JMP( );
break;
case 0x6d:
sally_Absolute( );
sally_ADC( );
break;
case 0x6e:
sally_Absolute( );
sally_ROR( );
break;
case 0x70:
sally_Relative( );
sally_BVS( );
break;
case 0x71:
sally_IndirectY( );
sally_ADC( );
sally_Delay(sally_y);
break;
case 0x75:
sally_ZeroPageX( );
sally_ADC( );
break;
case 0x76:
sally_ZeroPageX( );
sally_ROR( );
break;
case 0x78:
sally_SEI( );
break;
case 0x79:
sally_AbsoluteY( );
sally_ADC( );
sally_Delay(sally_y);
break;
case 0x7d:
sally_AbsoluteX( );
sally_ADC( );
sally_Delay(sally_x);
break;
case 0x7e:
sally_AbsoluteX( );
sally_ROR( );
break;
case 0x81:
sally_IndirectX( );
sally_STA( );
break;
case 0x84:
sally_ZeroPage( );
sally_STY( );
break;
case 0x85:
sally_ZeroPage( );
sally_STA( );
break;
case 0x86:
sally_ZeroPage( );
sally_stx( );
break;
case 0x88:
sally_DEY( );
break;
case 0x8a:
sally_TXA( );
break;
case 0x8c:
sally_Absolute( );
sally_STY( );
break;
case 0x8d:
sally_Absolute( );
sally_STA( );
break;
case 0x8e:
sally_Absolute( );
sally_stx( );
break;
case 0x90:
sally_Relative( );
sally_BCC( );
break;
case 0x91:
sally_IndirectY( );
sally_STA( );
break;
case 0x94:
sally_ZeroPageX( );
sally_STY( );
break;
case 0x95:
sally_ZeroPageX( );
sally_STA( );
break;
case 0x96:
sally_ZeroPageY( );
sally_stx( );
break;
case 0x98:
sally_TYA( );
break;
case 0x99:
sally_AbsoluteY( );
sally_STA( );
break;
case 0x9a:
sally_TXS( );
break;
case 0x9d:
sally_AbsoluteX( );
sally_STA( );
break;
case 0xa0:
sally_Immediate( );
sally_LDY( );
break;
case 0xa1:
sally_IndirectX( );
sally_LDA( );
break;
case 0xa2:
sally_Immediate( );
sally_LDX( );
break;
case 0xa4:
sally_ZeroPage( );
sally_LDY( );
break;
case 0xa5:
sally_ZeroPage( );
sally_LDA( );
break;
case 0xa6:
sally_ZeroPage( );
sally_LDX( );
break;
case 0xa8:
sally_TAY( );
break;
case 0xa9:
sally_Immediate( );
sally_LDA( );
break;
case 0xaa:
sally_TAX( );
break;
case 0xac:
sally_Absolute( );
sally_LDY( );
break;
case 0xad:
sally_Absolute( );
sally_LDA( );
break;
case 0xae:
sally_Absolute( );
sally_LDX( );
break;
case 0xb0:
sally_Relative( );
sally_BCS( );
break;
case 0xb1:
sally_IndirectY( );
sally_LDA( );
sally_Delay(sally_y);
break;
case 0xb4:
sally_ZeroPageX( );
sally_LDY( );
break;
case 0xb5:
sally_ZeroPageX( );
sally_LDA( );
break;
case 0xb6:
sally_ZeroPageY( );
sally_LDX( );
break;
case 0xb8:
sally_CLV( );
break;
case 0xb9:
sally_AbsoluteY( );
sally_LDA( );
sally_Delay(sally_y);
break;
case 0xba:
sally_TSX( );
break;
case 0xbc:
sally_AbsoluteX( );
sally_LDY( );
sally_Delay(sally_x);
break;
case 0xbd:
sally_AbsoluteX( );
sally_LDA( );
sally_Delay(sally_x);
break;
case 0xbe:
sally_AbsoluteY( );
sally_LDX( );
sally_Delay(sally_y);
break;
case 0xc0:
sally_Immediate( );
sally_CPY( );
break;
case 0xc1:
sally_IndirectX( );
sally_CMP( );
break;
case 0xc4:
sally_ZeroPage( );
sally_CPY( );
break;
case 0xc5:
sally_ZeroPage( );
sally_CMP( );
break;
case 0xc6:
sally_ZeroPage( );
sally_DEC( );
break;
case 0xc8:
sally_INY( );
break;
case 0xc9:
sally_Immediate( );
sally_CMP( );
break;
case 0xca:
sally_DEX( );
break;
case 0xcc:
sally_Absolute( );
sally_CPY( );
break;
case 0xcd:
sally_Absolute( );
sally_CMP( );
break;
case 0xce:
sally_Absolute( );
sally_DEC( );
break;
case 0xd0:
sally_Relative( );
sally_BNE( );
break;
case 0xd1:
sally_IndirectY( );
sally_CMP( );
sally_Delay(sally_y);
break;
case 0xd5:
sally_ZeroPageX( );
sally_CMP( );
break;
case 0xd6:
sally_ZeroPageX( );
sally_DEC( );
break;
case 0xd8:
sally_CLD( );
break;
case 0xd9:
sally_AbsoluteY( );
sally_CMP( );
sally_Delay(sally_y);
break;
case 0xdd:
sally_AbsoluteX( );
sally_CMP( );
sally_Delay(sally_x);
break;
case 0xde:
sally_AbsoluteX( );
sally_DEC( );
break;
case 0xe0:
sally_Immediate( );
sally_CPX( );
break;
case 0xe1:
sally_IndirectX( );
sally_SBC( );
break;
case 0xe4:
sally_ZeroPage( );
sally_CPX( );
break;
case 0xe5:
sally_ZeroPage( );
sally_SBC( );
break;
case 0xe6:
sally_ZeroPage( );
sally_INC( );
break;
case 0xe8:
sally_INX( );
break;
case 0xe9:
sally_Immediate( );
sally_SBC( );
break;
case 0xea:
sally_NOP( );
break;
case 0xec:
sally_Absolute( );
sally_CPX( );
break;
case 0xed:
sally_Absolute( );
sally_SBC( );
break;
case 0xee:
sally_Absolute( );
sally_INC( );
break;
case 0xf0:
sally_Relative( );
sally_BEQ( );
break;
case 0xf1:
sally_IndirectY( );
sally_SBC( );
sally_Delay(sally_y);
break;
case 0xf5:
sally_ZeroPageX( );
sally_SBC( );
break;
case 0xf6:
sally_ZeroPageX( );
sally_INC( );
break;
case 0xf8:
sally_SED( );
break;
case 0xf9:
sally_AbsoluteY( );
sally_SBC( );
sally_Delay(sally_y);
break;
case 0xfd:
sally_AbsoluteX( );
sally_SBC( );
sally_Delay(sally_x);
break;
case 0xfe:
sally_AbsoluteX( );
sally_INC( );
break;
default:
break;
}
return sally_cycles;
}
// ----------------------------------------------------------------------------
// ExecuteRES
// ----------------------------------------------------------------------------
uint sally_ExecuteRES( ) {
sally_p = SALLY_FLAG.I | SALLY_FLAG.R | SALLY_FLAG.Z;
sally_pc.b.l = memory_ram[SALLY_RES.L];
sally_pc.b.h = memory_ram[SALLY_RES.H];
return 6;
}
// ----------------------------------------------------------------------------
// ExecuteNMI
// ----------------------------------------------------------------------------
uint sally_ExecuteNMI( ) {
sally_Push(sally_pc.b.h);
sally_Push(sally_pc.b.l);
sally_p &= ~SALLY_FLAG.B;
sally_Push(sally_p);
sally_p |= SALLY_FLAG.I;
sally_pc.b.l = memory_ram[SALLY_NMI.L];
sally_pc.b.h = memory_ram[SALLY_NMI.H];
return 7;
}
// ----------------------------------------------------------------------------
// Execute IRQ
// ----------------------------------------------------------------------------
uint sally_ExecuteIRQ( ) {
if(!(sally_p & SALLY_FLAG.I)) {
sally_Push(sally_pc.b.h);
sally_Push(sally_pc.b.l);
sally_p &= ~SALLY_FLAG.B;
sally_Push(sally_p);
sally_p |= SALLY_FLAG.I;
sally_pc.b.l = memory_ram[SALLY_IRQ.L];
sally_pc.b.h = memory_ram[SALLY_IRQ.H];
}
return 7;
}