diff --git a/stella/src/build/makefile b/stella/src/build/makefile index 08b7ae97d..337b2ed5a 100644 --- a/stella/src/build/makefile +++ b/stella/src/build/makefile @@ -13,7 +13,7 @@ ## See the file "license" for information on usage and redistribution of ## this file, and for a DISCLAIMER OF ALL WARRANTIES. ## -## $Id: makefile,v 1.104 2005-06-21 18:46:32 stephena Exp $ +## $Id: makefile,v 1.105 2005-06-23 01:10:25 urchlay Exp $ ##============================================================================ ##============================================================================ @@ -153,7 +153,7 @@ win32-gl: ############################################################################### ## List of "core" object files ############################################################################### -M6502_OBJS = D6502.o Device.o M6502.o M6502Low.o M6502Hi.o NullDev.o System.o +M6502_OBJS = D6502.o Device.o M6502.o M6502Hi.o NullDev.o System.o GUI_OBJS = Font.o Menu.o Launcher.o \ Widget.o PopUpWidget.o ScrollBarWidget.o ListWidget.o TabWidget.o \ @@ -180,15 +180,9 @@ CORE_OBJS = Booster.o Cart.o Cart2K.o Cart3F.o Cart4K.o CartAR.o CartDPC.o \ stella: $(CORE_OBJS) $(OBJS) $(LD) -o $(EXE_NAME) $(CORE_OBJS) $(OBJS) $(LDFLAGS) $(LDLIBS) -M6502Low.ins: $(CORE)/m6502/src/M6502Low.m4 $(CORE)/m6502/src/M6502.m4 - m4 $(CORE)/m6502/src/M6502Low.m4 $(CORE)/m6502/src/M6502.m4 > $(CORE)/m6502/src/M6502Low.ins - M6502Hi.ins: $(CORE)/m6502/src/M6502Hi.m4 $(CORE)/m6502/src/M6502.m4 m4 $(CORE)/m6502/src/M6502Hi.m4 $(CORE)/m6502/src/M6502.m4 > $(CORE)/m6502/src/M6502Hi.ins -#M6502Low.o: M6502Low.ins -#M6502Hi.o: M6502Hi.ins - clean: rm -f *.o stella stella.exe core @@ -372,9 +366,6 @@ Device.o: $(CORE)/m6502/src/Device.cxx M6502.o: $(CORE)/m6502/src/M6502.cxx $(CXX) -c $(FLAGS) $(OPTIONS) $(CORE)/m6502/src/M6502.cxx -M6502Low.o: $(CORE)/m6502/src/M6502Low.cxx - $(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(CORE)/m6502/src/M6502Low.cxx - M6502Hi.o: $(CORE)/m6502/src/M6502Hi.cxx $(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(CORE)/m6502/src/M6502Hi.cxx diff --git a/stella/src/debugger/Debugger.hxx b/stella/src/debugger/Debugger.hxx index 940a95ea3..4b6359266 100644 --- a/stella/src/debugger/Debugger.hxx +++ b/stella/src/debugger/Debugger.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Debugger.hxx,v 1.25 2005-06-22 20:25:19 urchlay Exp $ +// $Id: Debugger.hxx,v 1.26 2005-06-23 01:10:25 urchlay Exp $ //============================================================================ #ifndef DEBUGGER_HXX @@ -51,7 +51,7 @@ enum { for all debugging operations in Stella (parser, 6502 debugger, etc). @author Stephen Anthony - @version $Id: Debugger.hxx,v 1.25 2005-06-22 20:25:19 urchlay Exp $ + @version $Id: Debugger.hxx,v 1.26 2005-06-23 01:10:25 urchlay Exp $ */ class Debugger : public DialogContainer { @@ -199,7 +199,7 @@ class Debugger : public DialogContainer void formatFlags(int f, char *out); EquateList *equates(); - PromptWidget *prompt(); + PromptWidget *prompt() { return myPrompt; } string showWatches(); void addLabel(string label, int address); diff --git a/stella/src/debugger/DebuggerParser.cxx b/stella/src/debugger/DebuggerParser.cxx index 2c9a32ab5..976d16084 100644 --- a/stella/src/debugger/DebuggerParser.cxx +++ b/stella/src/debugger/DebuggerParser.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: DebuggerParser.cxx,v 1.26 2005-06-22 20:25:19 urchlay Exp $ +// $Id: DebuggerParser.cxx,v 1.27 2005-06-23 01:10:25 urchlay Exp $ //============================================================================ #include "bspf.hxx" @@ -247,6 +247,24 @@ string DebuggerParser::listBreaks() { return "no breakpoints set"; } +string DebuggerParser::listTraps() { + int count = 0; + string ret; + + for(unsigned int i=0; i<0x10000; i++) { + if(debugger->readTrap(i) || debugger->writeTrap(i)) { + ret += trapStatus(i); + ret += "\n"; + count++; + } + } + + if(count) + return ret; + else + return "no traps set"; +} + string DebuggerParser::disasm() { int start, lines = 20; @@ -359,10 +377,22 @@ string DebuggerParser::trapStatus(int addr) { string result; result += debugger->valueToString(addr); result += ": "; - if(debugger->readTrap(addr)) - result += "read "; - if(debugger->writeTrap(addr)) - result += "write "; + bool r = debugger->readTrap(addr); + bool w = debugger->writeTrap(addr); + if(r && w) + result += "read|write"; + else if(r) + result += "read"; + else if(w) + result += " write"; + else result += " none "; + + char *l = debugger->equateList->getLabel(addr); + if(l != NULL) { + result += " ("; + result += l; + result += ")"; + } return result; } @@ -375,9 +405,23 @@ string DebuggerParser::run(const string& command) { if(subStringMatch(verb, "loadsym")) { result = debugger->equateList->loadFile(argStrings[0]); return result; - } else if(subStringMatch(verb, "label")) { - debugger->addLabel(argStrings[0], decipher_arg(argStrings[1])); - return ""; + } else if(subStringMatch(verb, "savesym")) { + if(debugger->equateList->saveFile(argStrings[0])) + return "saved symbols to file " + argStrings[0]; + else + return "I/O error"; + } else if(subStringMatch(verb, "define")) { + int arg = decipher_arg(argStrings[1]); + if(arg < 0) + return "invalid argument"; + + debugger->addLabel(argStrings[0], arg); + return "label " + argStrings[0] + " defined as " + debugger->valueToString(arg); + } else if(subStringMatch(verb, "saveses")) { + if(debugger->prompt()->saveBuffer(argStrings[0])) + return "saved session to file " + argStrings[0]; + else + return "I/O error"; } else { return "invalid label or address"; } @@ -508,6 +552,8 @@ string DebuggerParser::run(const string& command) { return "Cleared breakpoint"; } else if(subStringMatch(verb, "listbreaks")) { return listBreaks(); + } else if(subStringMatch(verb, "listtraps")) { + return listTraps(); } else if(subStringMatch(verb, "disasm")) { return disasm(); } else if(subStringMatch(verb, "frame")) { @@ -535,6 +581,13 @@ string DebuggerParser::run(const string& command) { return delWatch(args[0]); else return "one argument required"; + } else if(subStringMatch(verb, "define")) { + return argStrings[0] + " already defined"; + } else if(subStringMatch(verb, "undef")) { + if(debugger->equateList->undefine(argStrings[0])) + return argStrings[0] + " now undefined"; + else + return "no such label"; } else if(subStringMatch(verb, "height")) { if(argCount != 1) return "one argument required"; @@ -580,6 +633,8 @@ string DebuggerParser::run(const string& command) { result += "Set base "; result += buf; return result; + } else if(subStringMatch(verb, "listsym")) { + return debugger->equateList->dumpAll(); } else if(subStringMatch(verb, "quit") || subStringMatch(verb, "run")) { debugger->quit(); return ""; @@ -600,14 +655,16 @@ string DebuggerParser::run(const string& command) { "cleartraps - Clear all traps\n" "clearwatches - Clear all watches\n" "d - Toggle Decimal Flag\n" - "dump xx - Dump 128 bytes of memory starting at xx (may be ROM, TIA, RAM)\n" + "define ll xx - Define label ll with value xx\n" "delwatch xx - Delete watch xx\n" "disasm - Disassemble (from current PC)\n" "disasm xx - Disassemble (from address xx)\n" + "dump xx - Dump 128 bytes of memory starting at xx (may be ROM, TIA, RAM)\n" "frame - Advance to next TIA frame, then break\n" - "height xx - Set height of debugger window in pixels\n" + "height xx - Set height of debugger window in pixels (NOT WORKING)\n" "listbreaks - List all breakpoints\n" - "*listtraps - List all traps\n" + "listtraps - List all traps\n" + "listsym - List all currently defined symbols\n" "loadsym f - Load DASM symbols from file f\n" "n - Toggle Negative Flag\n" "pc xx - Set Program Counter to xx\n" @@ -618,15 +675,17 @@ string DebuggerParser::run(const string& command) { "reset - Jump to 6502 init vector (does not reset TIA/RIOT)\n" "run - Exit debugger (back to emulator)\n" "s xx - Set Stack Pointer to xx\n" - "*save f - Save console session to file f\n" + "saveses f - Save console session to file f\n" + "savesym f - Save symbols to file f\n" "step - Single-step\n" "tia - Show TIA register contents\n" "trace - Single-step treating subroutine calls as 1 instruction\n" "trap xx - Trap any access to location xx (enter debugger on access)\n" "trapread xx - Trap any read access from location xx\n" "trapwrite xx - Trap any write access to location xx\n" + "undef ll - Undefine label ll (if defined)\n" "v - Toggle Overflow Flag\n" - "watch xx - Print contents of location xx before every prompt\n" + "watch xx - Print contents of location xx before every prompt\n" "x xx - Set X register to xx\n" "y xx - Set Y register to xx\n" "z - Toggle Zero Flag\n" diff --git a/stella/src/debugger/DebuggerParser.hxx b/stella/src/debugger/DebuggerParser.hxx index c9174a3c9..b68a24297 100644 --- a/stella/src/debugger/DebuggerParser.hxx +++ b/stella/src/debugger/DebuggerParser.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: DebuggerParser.hxx,v 1.15 2005-06-21 23:01:25 stephena Exp $ +// $Id: DebuggerParser.hxx,v 1.16 2005-06-23 01:10:25 urchlay Exp $ //============================================================================ #ifndef DEBUGGER_PARSER_HXX @@ -58,6 +58,7 @@ class DebuggerParser bool subStringMatch(const string& needle, const string& haystack); string disasm(); string listBreaks(); + string listTraps(); string eval(); string dump(); string trapStatus(int addr); diff --git a/stella/src/debugger/EquateList.cxx b/stella/src/debugger/EquateList.cxx index eb018c819..5b0f5cd1a 100644 --- a/stella/src/debugger/EquateList.cxx +++ b/stella/src/debugger/EquateList.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: EquateList.cxx,v 1.13 2005-06-22 20:25:20 urchlay Exp $ +// $Id: EquateList.cxx,v 1.14 2005-06-23 01:10:25 urchlay Exp $ //============================================================================ #include @@ -23,6 +23,7 @@ #include "bspf.hxx" #include "Equate.hxx" #include "EquateList.hxx" +#include "Debugger.hxx" // built in labels static Equate hardCodedEquates[] = { @@ -150,12 +151,51 @@ int EquateList::getAddress(const char *lbl) { for(int i=0; i= 0) + return ourVcsEquates[i].address; } return -1; } +bool EquateList::undefine(string& label) { + return undefine(label.c_str()); +} + +bool EquateList::undefine(const char *lbl) { + for(int i=0; i= 0) { + sprintf(buf, "%-24s %04x \n", ourVcsEquates[i].label, a); + out << buf; + } + } + + out << "--- End of Symbol List." << endl; + return true; +} + string EquateList::loadFile(string file) { int lines = 0; string curLabel; @@ -215,6 +255,7 @@ void EquateList::addEquate(string label, int address) { } int EquateList::parse4hex(char *c) { + //cerr << c << endl; int ret = 0; for(int i=0; i<4; i++) { if(*c >= '0' && *c <= '9') @@ -253,7 +294,16 @@ string EquateList::extractLabel(char *c) { return l; } -void EquateList::dumpAll() { - for(int i=0; i @@ -30,7 +30,6 @@ #include "EventHandler.hxx" #include "Joystick.hxx" #include "Keyboard.hxx" -#include "M6502Low.hxx" #include "M6502Hi.hxx" #include "M6532.hxx" #include "MD5.hxx" @@ -137,14 +136,7 @@ Console::Console(const uInt8* image, uInt32 size, OSystem* osystem) mySystem = new System(13, 6); M6502* m6502; - if(myProperties.get("Emulation.CPU") == "Low") - { - m6502 = new M6502Low(1); - } - else - { - m6502 = new M6502High(1); - } + m6502 = new M6502High(1); m6502->attach(myOSystem->debugger()); M6532* m6532 = new M6532(*this); diff --git a/stella/src/emucore/m6502/src/M6502Low.cxx b/stella/src/emucore/m6502/src/M6502Low.cxx deleted file mode 100644 index 13f2debea..000000000 --- a/stella/src/emucore/m6502/src/M6502Low.cxx +++ /dev/null @@ -1,255 +0,0 @@ -//============================================================================ -// -// MM MM 6666 555555 0000 2222 -// MMMM MMMM 66 66 55 00 00 22 22 -// MM MMM MM 66 55 00 00 22 -// MM M MM 66666 55555 00 00 22222 -- "A 6502 Microprocessor Emulator" -// MM MM 66 66 55 00 00 22 -// MM MM 66 66 55 55 00 00 22 -// MM MM 6666 5555 0000 222222 -// -// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: M6502Low.cxx,v 1.6 2005-06-17 03:49:10 urchlay Exp $ -//============================================================================ - -#include "M6502Low.hxx" -#include "Serializer.hxx" -#include "Deserializer.hxx" -#include "Debugger.hxx" - -#define debugStream cout - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -M6502Low::M6502Low(uInt32 systemCyclesPerProcessorCycle) - : M6502(systemCyclesPerProcessorCycle) -{ -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -M6502Low::~M6502Low() -{ -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -inline uInt8 M6502Low::peek(uInt16 address) -{ - return mySystem->peek(address); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -inline void M6502Low::poke(uInt16 address, uInt8 value) -{ - mySystem->poke(address, value); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool M6502Low::execute(uInt32 number) -{ - // Clear all of the execution status bits except for the fatal error bit - myExecutionStatus &= FatalErrorBit; - - // Loop until execution is stopped or a fatal error occurs - for(;;) - { - for(; !myExecutionStatus && (number != 0); --number) - { - uInt16 operandAddress = 0; - uInt8 operand = 0; - - if(breakPoints != NULL) - { - if(breakPoints->isSet(PC)) - if(myDebugger->start()) - return true; - } - -#ifdef DEBUG - debugStream << "PC=" << hex << setw(4) << PC << " "; -#endif - - // Fetch instruction at the program counter - IR = peek(PC++); - -#ifdef DEBUG - debugStream << "IR=" << hex << setw(2) << (int)IR << " "; - debugStream << "<" << ourAddressingModeTable[IR] << " "; -#endif - - // Update system cycles - mySystem->incrementCycles(myInstructionSystemCycleTable[IR]); - - // Call code to execute the instruction - switch(IR) - { - // 6502 instruction emulation is generated by an M4 macro file - #include "M6502Low.ins" - - default: - // Oops, illegal instruction executed so set fatal error flag - myExecutionStatus |= FatalErrorBit; - cerr << "Illegal Instruction! " << hex << (int) IR << endl; - } - -#ifdef DEBUG - debugStream << hex << setw(4) << operandAddress << " "; - debugStream << setw(4) << ourInstructionMnemonicTable[IR]; - debugStream << "> "; - debugStream << "A=" << ::hex << setw(2) << (int)A << " "; - debugStream << "X=" << ::hex << setw(2) << (int)X << " "; - debugStream << "Y=" << ::hex << setw(2) << (int)Y << " "; - debugStream << "PS=" << ::hex << setw(2) << (int)PS() << " "; - debugStream << "SP=" << ::hex << setw(2) << (int)SP << " "; - debugStream << "Cyc=" << dec << mySystem->cycles(); - debugStream << endl; -#endif - } - - // See if we need to handle an interrupt - if((myExecutionStatus & MaskableInterruptBit) || - (myExecutionStatus & NonmaskableInterruptBit)) - { - // Yes, so handle the interrupt - interruptHandler(); - } - - // See if execution has been stopped - if(myExecutionStatus & StopExecutionBit) - { - // Yes, so answer that everything finished fine - return true; - } - - // See if a fatal error has occured - if(myExecutionStatus & FatalErrorBit) - { - // Yes, so answer that something when wrong - return false; - } - - // See if we've executed the specified number of instructions - if(number == 0) - { - // Yes, so answer that everything finished fine - return true; - } - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void M6502Low::interruptHandler() -{ - // Handle the interrupt - if((myExecutionStatus & MaskableInterruptBit) && !I) - { - mySystem->incrementCycles(7 * mySystemCyclesPerProcessorCycle); - mySystem->poke(0x0100 + SP--, (PC - 1) >> 8); - mySystem->poke(0x0100 + SP--, (PC - 1) & 0x00ff); - mySystem->poke(0x0100 + SP--, PS() & (~0x10)); - D = false; - I = true; - PC = (uInt16)mySystem->peek(0xFFFE) | ((uInt16)mySystem->peek(0xFFFF) << 8); - } - else if(myExecutionStatus & NonmaskableInterruptBit) - { - mySystem->incrementCycles(7 * mySystemCyclesPerProcessorCycle); - mySystem->poke(0x0100 + SP--, (PC - 1) >> 8); - mySystem->poke(0x0100 + SP--, (PC - 1) & 0x00ff); - mySystem->poke(0x0100 + SP--, PS() & (~0x10)); - D = false; - PC = (uInt16)mySystem->peek(0xFFFA) | ((uInt16)mySystem->peek(0xFFFB) << 8); - } - - // Clear the interrupt bits in myExecutionStatus - myExecutionStatus &= ~(MaskableInterruptBit | NonmaskableInterruptBit); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool M6502Low::save(Serializer& out) -{ - string CPU = name(); - - try - { - out.putString(CPU); - - out.putLong(A); // Accumulator - out.putLong(X); // X index register - out.putLong(Y); // Y index register - out.putLong(SP); // Stack Pointer - out.putLong(IR); // Instruction register - out.putLong(PC); // Program Counter - - out.putBool(N); // N flag for processor status register - out.putBool(V); // V flag for processor status register - out.putBool(B); // B flag for processor status register - out.putBool(D); // D flag for processor status register - out.putBool(I); // I flag for processor status register - out.putBool(notZ); // Z flag complement for processor status register - out.putBool(C); // C flag for processor status register - - out.putLong(myExecutionStatus); - } - catch(char *msg) - { - cerr << msg << endl; - return false; - } - catch(...) - { - cerr << "Unknown error in save state for " << CPU << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool M6502Low::load(Deserializer& in) -{ - string CPU = name(); - - try - { - if(in.getString() != CPU) - return false; - - A = (uInt8) in.getLong(); // Accumulator - X = (uInt8) in.getLong(); // X index register - Y = (uInt8) in.getLong(); // Y index register - SP = (uInt8) in.getLong(); // Stack Pointer - IR = (uInt8) in.getLong(); // Instruction register - PC = (uInt16) in.getLong(); // Program Counter - - N = in.getBool(); // N flag for processor status register - V = in.getBool(); // V flag for processor status register - B = in.getBool(); // B flag for processor status register - D = in.getBool(); // D flag for processor status register - I = in.getBool(); // I flag for processor status register - notZ = in.getBool(); // Z flag complement for processor status register - C = in.getBool(); // C flag for processor status register - - myExecutionStatus = (uInt8) in.getLong(); - } - catch(char *msg) - { - cerr << msg << endl; - return false; - } - catch(...) - { - cerr << "Unknown error in load state for " << CPU << endl; - return false; - } - - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const char* M6502Low::name() const -{ - return "M6502Low"; -} diff --git a/stella/src/emucore/m6502/src/M6502Low.hxx b/stella/src/emucore/m6502/src/M6502Low.hxx deleted file mode 100644 index b3577fbb6..000000000 --- a/stella/src/emucore/m6502/src/M6502Low.hxx +++ /dev/null @@ -1,119 +0,0 @@ -//============================================================================ -// -// MM MM 6666 555555 0000 2222 -// MMMM MMMM 66 66 55 00 00 22 22 -// MM MMM MM 66 55 00 00 22 -// MM M MM 66666 55555 00 00 22222 -- "A 6502 Microprocessor Emulator" -// MM MM 66 66 55 00 00 22 -// MM MM 66 66 55 55 00 00 22 -// MM MM 6666 5555 0000 222222 -// -// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: M6502Low.hxx,v 1.3 2005-06-16 01:11:29 stephena Exp $ -//============================================================================ - -#ifndef M6507LOW_HXX -#define M6507LOW_HXX - -class M6507Low; -class Serializer; -class Deserializer; - -#include "bspf.hxx" -#include "M6502.hxx" - -/** - This class provides a low compatibility 6502 microprocessor emulator. - The memory accesses and cycle updates of this emulator are not 100% - accurate as shown below: - - 1. Only memory accesses which are actually needed are done - (i.e. no "false" reads and writes are performed) - - 2. Cycle counts are updated at the beginning of the instruction - execution and not valid at the sub-instruction level - - If speed is the most important issue then use this class, however, if - better compatibility is neccessary use one of the other 6502 classes. - - @author Bradford W. Mott - @version $Id: M6502Low.hxx,v 1.3 2005-06-16 01:11:29 stephena Exp $ -*/ -class M6502Low : public M6502 -{ - public: - /** - Create a new low compatibility 6502 microprocessor with the specified - cycle multiplier. - - @param systemCyclesPerProcessorCycle The cycle multiplier - */ - M6502Low(uInt32 systemCyclesPerProcessorCycle); - - /** - Destructor - */ - virtual ~M6502Low(); - - public: - /** - Execute instructions until the specified number of instructions - is executed, someone stops execution, or an error occurs. Answers - true iff execution stops normally. - - @param number Indicates the number of instructions to execute - @return true iff execution stops normally - */ - virtual bool execute(uInt32 number); - - /** - Saves the current state of this device to the given Serializer. - - @param out The serializer device to save to. - @return The result of the save. True on success, false on failure. - */ - virtual bool save(Serializer& out); - - /** - Loads the current state of this device from the given Deserializer. - - @param in The deserializer device to load from. - @return The result of the load. True on success, false on failure. - */ - virtual bool load(Deserializer& in); - - /** - Get a null terminated string which is the processors's name (i.e. "M6532") - - @return The name of the device - */ - virtual const char* name() const; - - protected: - /** - Called after an interrupt has be requested using irq() or nmi() - */ - void interruptHandler(); - - protected: - /* - Get the byte at the specified address - - @return The byte at the specified address - */ - inline uInt8 peek(uInt16 address); - - /** - Change the byte at the specified address to the given value - - @param address The address where the value should be stored - @param value The value to be stored at the address - */ - inline void poke(uInt16 address, uInt8 value); -}; -#endif - diff --git a/stella/src/emucore/m6502/src/M6502Low.ins b/stella/src/emucore/m6502/src/M6502Low.ins deleted file mode 100644 index 295e2d325..000000000 --- a/stella/src/emucore/m6502/src/M6502Low.ins +++ /dev/null @@ -1,4374 +0,0 @@ -//============================================================================ -// -// MM MM 6666 555555 0000 2222 -// MMMM MMMM 66 66 55 00 00 22 22 -// MM MMM MM 66 55 00 00 22 -// MM M MM 66666 55555 00 00 22222 -- "A 6502 Microprocessor Emulator" -// MM MM 66 66 55 00 00 22 -// MM MM 66 66 55 55 00 00 22 -// MM MM 6666 5555 0000 222222 -// -// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: M6502Low.ins,v 1.2 2005-06-16 01:11:29 stephena Exp $ -//============================================================================ - -/** - Code to handle addressing modes and branch instructions for - low compatibility emulation - - @author Bradford W. Mott - @version $Id: M6502Low.ins,v 1.2 2005-06-16 01:11:29 stephena Exp $ -*/ - -#ifndef NOTSAMEPAGE - #define NOTSAMEPAGE(_addr1, _addr2) (((_addr1) ^ (_addr2)) & 0xff00) -#endif - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//============================================================================ -// -// MM MM 6666 555555 0000 2222 -// MMMM MMMM 66 66 55 00 00 22 22 -// MM MMM MM 66 55 00 00 22 -// MM M MM 66666 55555 00 00 22222 -- "A 6502 Microprocessor Emulator" -// MM MM 66 66 55 00 00 22 -// MM MM 66 66 55 55 00 00 22 -// MM MM 6666 5555 0000 222222 -// -// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: M6502Low.ins,v 1.2 2005-06-16 01:11:29 stephena Exp $ -//============================================================================ - -/** - Code and cases to emulate each of the 6502 instruction - - @author Bradford W. Mott - @version $Id: M6502Low.ins,v 1.2 2005-06-16 01:11:29 stephena Exp $ -*/ - -#ifndef NOTSAMEPAGE - #define NOTSAMEPAGE(_addr1, _addr2) (((_addr1) ^ (_addr2)) & 0xff00) -#endif - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -case 0x69: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x65: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x75: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x6d: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x7d: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + X)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += X; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x79: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x61: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x71: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - - -case 0x4b: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - A &= operand; - - // Set carry flag according to the right-most bit - C = A & 0x01; - - A = (A >> 1) & 0x7f; - - notZ = A; - N = A & 0x80; -} -break; - - -case 0x0b: -case 0x2b: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - A &= operand; - notZ = A; - N = A & 0x80; - C = N; -} -break; - - -case 0x29: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - A &= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x25: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - A &= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x35: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - A &= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x2d: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - A &= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x3d: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + X)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += X; - operand = peek(operandAddress); -} -{ - A &= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x39: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - A &= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x21: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - A &= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x31: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - A &= operand; - notZ = A; - N = A & 0x80; -} -break; - - -case 0x8b: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - // NOTE: The implementation of this instruction is based on - // information from the 64doc.txt file. This instruction is - // reported to be unstable! - A = (A | 0xee) & X & operand; - notZ = A; - N = A & 0x80; -} -break; - - -case 0x6b: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - // NOTE: The implementation of this instruction is based on - // information from the 64doc.txt file. There are mixed - // reports on its operation! - if(!D) - { - A &= operand; - A = ((A >> 1) & 0x7f) | (C ? 0x80 : 0x00); - - C = A & 0x40; - V = (A & 0x40) ^ ((A & 0x20) << 1); - - notZ = A; - N = A & 0x80; - } - else - { - uInt8 value = A & operand; - - A = ((value >> 1) & 0x7f) | (C ? 0x80 : 0x00); - N = C; - notZ = A; - V = (value ^ A) & 0x40; - - if(((value & 0x0f) + (value & 0x01)) > 0x05) - { - A = (A & 0xf0) | ((A + 0x06) & 0x0f); - } - - if(((value & 0xf0) + (value & 0x10)) > 0x50) - { - A = (A + 0x60) & 0xff; - C = 1; - } - else - { - C = 0; - } - } -} -break; - - -case 0x0a: -{ -} -{ - // Set carry flag according to the left-most bit in A - C = A & 0x80; - - A <<= 1; - - notZ = A; - N = A & 0x80; -} -break; - -case 0x06: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - // Set carry flag according to the left-most bit in value - C = operand & 0x80; - - operand <<= 1; - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - -case 0x16: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - // Set carry flag according to the left-most bit in value - C = operand & 0x80; - - operand <<= 1; - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - -case 0x0e: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - // Set carry flag according to the left-most bit in value - C = operand & 0x80; - - operand <<= 1; - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - -case 0x1e: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -} -{ - // Set carry flag according to the left-most bit in value - C = operand & 0x80; - - operand <<= 1; - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - - -case 0x90: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - if(!C) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -} -break; - - -case 0xb0: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - if(C) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -} -break; - - -case 0xf0: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - if(!notZ) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -} -break; - - -case 0x24: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - notZ = (A & operand); - N = operand & 0x80; - V = operand & 0x40; -} -break; - -case 0x2C: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - notZ = (A & operand); - N = operand & 0x80; - V = operand & 0x40; -} -break; - - -case 0x30: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - if(N) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -} -break; - - -case 0xD0: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - if(notZ) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -} -break; - - -case 0x10: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - if(!N) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -} -break; - - -case 0x00: -{ - peek(PC++); - - B = true; - - poke(0x0100 + SP--, PC >> 8); - poke(0x0100 + SP--, PC & 0x00ff); - poke(0x0100 + SP--, PS()); - - I = true; - - PC = peek(0xfffe); - PC |= ((uInt16)peek(0xffff) << 8); -} -break; - - -case 0x50: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - if(!V) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -} -break; - - -case 0x70: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - if(V) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -} -break; - - -case 0x18: -{ -} -{ - C = false; -} -break; - - -case 0xd8: -{ -} -{ - D = false; -} -break; - - -case 0x58: -{ -} -{ - I = false; -} -break; - - -case 0xb8: -{ -} -{ - V = false; -} -break; - - -case 0xc9: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)A - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - -case 0xc5: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)A - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - -case 0xd5: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)A - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - -case 0xcd: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)A - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - -case 0xdd: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + X)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += X; - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)A - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - -case 0xd9: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)A - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - -case 0xc1: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)A - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - -case 0xd1: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)A - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - - -case 0xe0: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)X - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - -case 0xe4: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)X - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - -case 0xec: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)X - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - - -case 0xc0: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)Y - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - -case 0xc4: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)Y - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - -case 0xcc: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)Y - (uInt16)operand; - - notZ = value; - N = value & 0x0080; - C = !(value & 0x0100); -} -break; - - -case 0xcf: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - uInt8 value = operand - 1; - poke(operandAddress, value); - - uInt16 value2 = (uInt16)A - (uInt16)value; - notZ = value2; - N = value2 & 0x0080; - C = !(value2 & 0x0100); -} -break; - -case 0xdf: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -} -{ - uInt8 value = operand - 1; - poke(operandAddress, value); - - uInt16 value2 = (uInt16)A - (uInt16)value; - notZ = value2; - N = value2 & 0x0080; - C = !(value2 & 0x0100); -} -break; - -case 0xdb: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += Y; - operand = peek(operandAddress); -} -{ - uInt8 value = operand - 1; - poke(operandAddress, value); - - uInt16 value2 = (uInt16)A - (uInt16)value; - notZ = value2; - N = value2 & 0x0080; - C = !(value2 & 0x0100); -} -break; - -case 0xc7: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - uInt8 value = operand - 1; - poke(operandAddress, value); - - uInt16 value2 = (uInt16)A - (uInt16)value; - notZ = value2; - N = value2 & 0x0080; - C = !(value2 & 0x0100); -} -break; - -case 0xd7: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - uInt8 value = operand - 1; - poke(operandAddress, value); - - uInt16 value2 = (uInt16)A - (uInt16)value; - notZ = value2; - N = value2 & 0x0080; - C = !(value2 & 0x0100); -} -break; - -case 0xc3: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - uInt8 value = operand - 1; - poke(operandAddress, value); - - uInt16 value2 = (uInt16)A - (uInt16)value; - notZ = value2; - N = value2 & 0x0080; - C = !(value2 & 0x0100); -} -break; - -case 0xd3: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operandAddress += Y; - operand = peek(operandAddress); -} -{ - uInt8 value = operand - 1; - poke(operandAddress, value); - - uInt16 value2 = (uInt16)A - (uInt16)value; - notZ = value2; - N = value2 & 0x0080; - C = !(value2 & 0x0100); -} -break; - - -case 0xc6: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - uInt8 value = operand - 1; - poke(operandAddress, value); - - notZ = value; - N = value & 0x80; -} -break; - -case 0xd6: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - uInt8 value = operand - 1; - poke(operandAddress, value); - - notZ = value; - N = value & 0x80; -} -break; - -case 0xce: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - uInt8 value = operand - 1; - poke(operandAddress, value); - - notZ = value; - N = value & 0x80; -} -break; - -case 0xde: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -} -{ - uInt8 value = operand - 1; - poke(operandAddress, value); - - notZ = value; - N = value & 0x80; -} -break; - - -case 0xca: -{ -} -{ - X--; - - notZ = X; - N = X & 0x80; -} -break; - - -case 0x88: -{ -} -{ - Y--; - - notZ = Y; - N = Y & 0x80; -} -break; - - -case 0x49: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x45: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x55: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x4d: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x5d: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + X)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += X; - operand = peek(operandAddress); -} -{ - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x59: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x41: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x51: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - - -case 0xe6: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - uInt8 value = operand + 1; - poke(operandAddress, value); - - notZ = value; - N = value & 0x80; -} -break; - -case 0xf6: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - uInt8 value = operand + 1; - poke(operandAddress, value); - - notZ = value; - N = value & 0x80; -} -break; - -case 0xee: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - uInt8 value = operand + 1; - poke(operandAddress, value); - - notZ = value; - N = value & 0x80; -} -break; - -case 0xfe: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -} -{ - uInt8 value = operand + 1; - poke(operandAddress, value); - - notZ = value; - N = value & 0x80; -} -break; - - -case 0xe8: -{ -} -{ - X++; - notZ = X; - N = X & 0x80; -} -break; - - -case 0xc8: -{ -} -{ - Y++; - notZ = Y; - N = Y & 0x80; -} -break; - - -case 0xef: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - operand = operand + 1; - poke(operandAddress, operand); - - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xff: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -} -{ - operand = operand + 1; - poke(operandAddress, operand); - - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xfb: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += Y; - operand = peek(operandAddress); -} -{ - operand = operand + 1; - poke(operandAddress, operand); - - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xe7: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - operand = operand + 1; - poke(operandAddress, operand); - - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xf7: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - operand = operand + 1; - poke(operandAddress, operand); - - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xe3: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - operand = operand + 1; - poke(operandAddress, operand); - - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xf3: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operandAddress += Y; - operand = peek(operandAddress); -} -{ - operand = operand + 1; - poke(operandAddress, operand); - - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - - -case 0x4c: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; -} -{ - PC = operandAddress; -} -break; - -case 0x6c: -{ - uInt16 addr = peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // Simulate the error in the indirect addressing mode! - uInt16 high = NOTSAMEPAGE(addr, addr + 1) ? (addr & 0xff00) : (addr + 1); - - operandAddress = peek(addr) | ((uInt16)peek(high) << 8); -} -{ - PC = operandAddress; -} -break; - - -case 0x20: -{ - uInt8 low = peek(PC++); - peek(0x0100 + SP); - - // It seems that the 650x does not push the address of the next instruction - // on the stack it actually pushes the address of the next instruction - // minus one. This is compensated for in the RTS instruction - poke(0x0100 + SP--, PC >> 8); - poke(0x0100 + SP--, PC & 0xff); - - PC = low | ((uInt16)peek(PC++) << 8); -} -break; - - -case 0xbb: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - A = X = SP = SP & operand; - notZ = A; - N = A & 0x80; -} -break; - - -case 0xaf: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - A = operand; - X = operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0xbf: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - A = operand; - X = operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0xa7: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - A = operand; - X = operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0xb7: -{ - operandAddress = (uInt8)(peek(PC++) + Y); - operand = peek(operandAddress); -} -{ - A = operand; - X = operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0xa3: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - A = operand; - X = operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0xb3: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - A = operand; - X = operand; - notZ = A; - N = A & 0x80; -} -break; - - -case 0xa9: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - A = operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0xa5: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - A = operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0xb5: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - A = operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0xad: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - A = operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0xbd: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + X)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += X; - operand = peek(operandAddress); -} -{ - A = operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0xb9: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - A = operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0xa1: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - A = operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0xb1: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - A = operand; - notZ = A; - N = A & 0x80; -} -break; - - -case 0xa2: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - X = operand; - notZ = X; - N = X & 0x80; -} -break; - -case 0xa6: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - X = operand; - notZ = X; - N = X & 0x80; -} -break; - -case 0xb6: -{ - operandAddress = (uInt8)(peek(PC++) + Y); - operand = peek(operandAddress); -} -{ - X = operand; - notZ = X; - N = X & 0x80; -} -break; - -case 0xae: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - X = operand; - notZ = X; - N = X & 0x80; -} -break; - -case 0xbe: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - X = operand; - notZ = X; - N = X & 0x80; -} -break; - - -case 0xa0: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - Y = operand; - notZ = Y; - N = Y & 0x80; -} -break; - -case 0xa4: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - Y = operand; - notZ = Y; - N = Y & 0x80; -} -break; - -case 0xb4: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - Y = operand; - notZ = Y; - N = Y & 0x80; -} -break; - -case 0xac: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - Y = operand; - notZ = Y; - N = Y & 0x80; -} -break; - -case 0xbc: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + X)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += X; - operand = peek(operandAddress); -} -{ - Y = operand; - notZ = Y; - N = Y & 0x80; -} -break; - - -case 0x4a: -{ -} -{ - // Set carry flag according to the right-most bit - C = A & 0x01; - - A = (A >> 1) & 0x7f; - - notZ = A; - N = A & 0x80; -} -break; - - -case 0x46: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - // Set carry flag according to the right-most bit in value - C = operand & 0x01; - - operand = (operand >> 1) & 0x7f; - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - -case 0x56: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - // Set carry flag according to the right-most bit in value - C = operand & 0x01; - - operand = (operand >> 1) & 0x7f; - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - -case 0x4e: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - // Set carry flag according to the right-most bit in value - C = operand & 0x01; - - operand = (operand >> 1) & 0x7f; - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - -case 0x5e: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -} -{ - // Set carry flag according to the right-most bit in value - C = operand & 0x01; - - operand = (operand >> 1) & 0x7f; - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - - -case 0xab: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - // NOTE: The implementation of this instruction is based on - // information from the 64doc.txt file. This instruction is - // reported to be very unstable! - A = X = (A | 0xee) & operand; - notZ = A; - N = A & 0x80; -} -break; - - -case 0x1a: -case 0x3a: -case 0x5a: -case 0x7a: -case 0xda: -case 0xea: -case 0xfa: -{ -} -{ -} -break; - -case 0x80: -case 0x82: -case 0x89: -case 0xc2: -case 0xe2: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ -} -break; - -case 0x04: -case 0x44: -case 0x64: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ -} -break; - -case 0x14: -case 0x34: -case 0x54: -case 0x74: -case 0xd4: -case 0xf4: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ -} -break; - -case 0x0c: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ -} -break; - -case 0x1c: -case 0x3c: -case 0x5c: -case 0x7c: -case 0xdc: -case 0xfc: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + X)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += X; - operand = peek(operandAddress); -} -{ -} -break; - - -case 0x09: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x05: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x15: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x0d: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x1d: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + X)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += X; - operand = peek(operandAddress); -} -{ - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x19: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x01: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x11: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - - -case 0x48: -{ -} -{ - poke(0x0100 + SP--, A); -} -break; - - -case 0x08: -{ -} -{ - poke(0x0100 + SP--, PS()); -} -break; - - -case 0x68: -{ -} -{ - peek(0x0100 + SP++); - A = peek(0x0100 + SP); - notZ = A; - N = A & 0x80; -} -break; - - -case 0x28: -{ -} -{ - peek(0x0100 + SP++); - PS(peek(0x0100 + SP)); -} -break; - - -case 0x2f: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - uInt8 value = (operand << 1) | (C ? 1 : 0); - poke(operandAddress, value); - - A &= value; - C = operand & 0x80; - notZ = A; - N = A & 0x80; -} -break; - -case 0x3f: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -} -{ - uInt8 value = (operand << 1) | (C ? 1 : 0); - poke(operandAddress, value); - - A &= value; - C = operand & 0x80; - notZ = A; - N = A & 0x80; -} -break; - -case 0x3b: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += Y; - operand = peek(operandAddress); -} -{ - uInt8 value = (operand << 1) | (C ? 1 : 0); - poke(operandAddress, value); - - A &= value; - C = operand & 0x80; - notZ = A; - N = A & 0x80; -} -break; - -case 0x27: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - uInt8 value = (operand << 1) | (C ? 1 : 0); - poke(operandAddress, value); - - A &= value; - C = operand & 0x80; - notZ = A; - N = A & 0x80; -} -break; - -case 0x37: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - uInt8 value = (operand << 1) | (C ? 1 : 0); - poke(operandAddress, value); - - A &= value; - C = operand & 0x80; - notZ = A; - N = A & 0x80; -} -break; - -case 0x23: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - uInt8 value = (operand << 1) | (C ? 1 : 0); - poke(operandAddress, value); - - A &= value; - C = operand & 0x80; - notZ = A; - N = A & 0x80; -} -break; - -case 0x33: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operandAddress += Y; - operand = peek(operandAddress); -} -{ - uInt8 value = (operand << 1) | (C ? 1 : 0); - poke(operandAddress, value); - - A &= value; - C = operand & 0x80; - notZ = A; - N = A & 0x80; -} -break; - - -case 0x2a: -{ -} -{ - bool oldC = C; - - // Set carry flag according to the left-most bit - C = A & 0x80; - - A = (A << 1) | (oldC ? 1 : 0); - - notZ = A; - N = A & 0x80; -} -break; - - -case 0x26: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - bool oldC = C; - - // Set carry flag according to the left-most bit in operand - C = operand & 0x80; - - operand = (operand << 1) | (oldC ? 1 : 0); - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - -case 0x36: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - bool oldC = C; - - // Set carry flag according to the left-most bit in operand - C = operand & 0x80; - - operand = (operand << 1) | (oldC ? 1 : 0); - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - -case 0x2e: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - bool oldC = C; - - // Set carry flag according to the left-most bit in operand - C = operand & 0x80; - - operand = (operand << 1) | (oldC ? 1 : 0); - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - -case 0x3e: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -} -{ - bool oldC = C; - - // Set carry flag according to the left-most bit in operand - C = operand & 0x80; - - operand = (operand << 1) | (oldC ? 1 : 0); - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - - -case 0x6a: -{ -} -{ - bool oldC = C; - - // Set carry flag according to the right-most bit - C = A & 0x01; - - A = ((A >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); - - notZ = A; - N = A & 0x80; -} -break; - -case 0x66: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - bool oldC = C; - - // Set carry flag according to the right-most bit - C = operand & 0x01; - - operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - -case 0x76: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - bool oldC = C; - - // Set carry flag according to the right-most bit - C = operand & 0x01; - - operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - -case 0x6e: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - bool oldC = C; - - // Set carry flag according to the right-most bit - C = operand & 0x01; - - operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - -case 0x7e: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -} -{ - bool oldC = C; - - // Set carry flag according to the right-most bit - C = operand & 0x01; - - operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); - poke(operandAddress, operand); - - notZ = operand; - N = operand & 0x80; -} -break; - - -case 0x6f: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - bool oldC = C; - - // Set carry flag according to the right-most bit - C = operand & 0x01; - - operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); - poke(operandAddress, operand); - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x7f: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - bool oldC = C; - - // Set carry flag according to the right-most bit - C = operand & 0x01; - - operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); - poke(operandAddress, operand); - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x7b: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += Y; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - bool oldC = C; - - // Set carry flag according to the right-most bit - C = operand & 0x01; - - operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); - poke(operandAddress, operand); - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x67: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - bool oldC = C; - - // Set carry flag according to the right-most bit - C = operand & 0x01; - - operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); - poke(operandAddress, operand); - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x77: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - bool oldC = C; - - // Set carry flag according to the right-most bit - C = operand & 0x01; - - operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); - poke(operandAddress, operand); - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x63: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - bool oldC = C; - - // Set carry flag according to the right-most bit - C = operand & 0x01; - - operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); - poke(operandAddress, operand); - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0x73: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operandAddress += Y; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - bool oldC = C; - - // Set carry flag according to the right-most bit - C = operand & 0x01; - - operand = ((operand >> 1) & 0x7f) | (oldC ? 0x80 : 0x00); - poke(operandAddress, operand); - - if(!D) - { - Int16 sum = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((sum > 127) || (sum < -128)); - - sum = (Int16)A + (Int16)operand + (C ? 1 : 0); - A = sum; - C = (sum > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 sum = ourBCDTable[0][A] + ourBCDTable[0][operand] + (C ? 1 : 0); - - C = (sum > 99); - A = ourBCDTable[1][sum & 0xff]; - notZ = A; - N = A & 0x80; - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - - -case 0x40: -{ -} -{ - peek(0x0100 + SP++); - PS(peek(0x0100 + SP++)); - PC = peek(0x0100 + SP++); - PC |= ((uInt16)peek(0x0100 + SP) << 8); -} -break; - - -case 0x60: -{ -} -{ - peek(0x0100 + SP++); - PC = peek(0x0100 + SP++); - PC |= ((uInt16)peek(0x0100 + SP) << 8); - peek(PC++); -} -break; - - -case 0x8f: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; -} -{ - poke(operandAddress, A & X); -} -break; - -case 0x87: -{ - operandAddress = peek(PC++); -} -{ - poke(operandAddress, A & X); -} -break; - -case 0x97: -{ - operandAddress = (uInt8)(peek(PC++) + Y); -} -{ - poke(operandAddress, A & X); -} -break; - -case 0x83: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); -} -{ - poke(operandAddress, A & X); -} -break; - - -case 0xe9: -case 0xeb: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xe5: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xf5: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xed: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xfd: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + X)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += X; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xf9: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xe1: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - -case 0xf1: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -} -{ - uInt8 oldA = A; - - if(!D) - { - operand = ~operand; - Int16 difference = (Int16)((Int8)A) + (Int16)((Int8)operand) + (C ? 1 : 0); - V = ((difference > 127) || (difference < -128)); - - difference = ((Int16)A) + ((Int16)operand) + (C ? 1 : 0); - A = difference; - C = (difference > 0xff); - notZ = A; - N = A & 0x80; - } - else - { - Int16 difference = ourBCDTable[0][A] - ourBCDTable[0][operand] - - (C ? 0 : 1); - - if(difference < 0) - difference += 100; - - A = ourBCDTable[1][difference]; - notZ = A; - N = A & 0x80; - - C = (oldA >= (operand + (C ? 0 : 1))); - V = ((oldA ^ A) & 0x80) && ((A ^ operand) & 0x80); - } -} -break; - - -case 0xcb: -{ - operandAddress = PC++; - operand = peek(operandAddress); -} -{ - uInt16 value = (uInt16)(X & A) - (uInt16)operand; - X = (value & 0xff); - - notZ = X; - N = X & 0x80; - C = !(value & 0x0100); -} -break; - - -case 0x38: -{ -} -{ - C = true; -} -break; - - -case 0xf8: -{ -} -{ - D = true; -} -break; - - -case 0x78: -{ -} -{ - I = true; -} -break; - - -case 0x9f: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += Y; -} -{ - // NOTE: There are mixed reports on the actual operation - // of this instruction! - poke(operandAddress, A & X & (((operandAddress >> 8) & 0xff) + 1)); -} -break; - -case 0x93: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operandAddress += Y; -} -{ - // NOTE: There are mixed reports on the actual operation - // of this instruction! - poke(operandAddress, A & X & (((operandAddress >> 8) & 0xff) + 1)); -} -break; - - -case 0x9b: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += Y; -} -{ - // NOTE: There are mixed reports on the actual operation - // of this instruction! - SP = A & X; - poke(operandAddress, A & X & (((operandAddress >> 8) & 0xff) + 1)); -} -break; - - -case 0x9e: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += Y; -} -{ - // NOTE: There are mixed reports on the actual operation - // of this instruction! - poke(operandAddress, X & (((operandAddress >> 8) & 0xff) + 1)); -} -break; - - -case 0x9c: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; -} -{ - // NOTE: There are mixed reports on the actual operation - // of this instruction! - poke(operandAddress, Y & (((operandAddress >> 8) & 0xff) + 1)); -} -break; - - -case 0x0f: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - // Set carry flag according to the left-most bit in value - C = operand & 0x80; - - operand <<= 1; - poke(operandAddress, operand); - - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x1f: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -} -{ - // Set carry flag according to the left-most bit in value - C = operand & 0x80; - - operand <<= 1; - poke(operandAddress, operand); - - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x1b: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += Y; - operand = peek(operandAddress); -} -{ - // Set carry flag according to the left-most bit in value - C = operand & 0x80; - - operand <<= 1; - poke(operandAddress, operand); - - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x07: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - // Set carry flag according to the left-most bit in value - C = operand & 0x80; - - operand <<= 1; - poke(operandAddress, operand); - - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x17: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - // Set carry flag according to the left-most bit in value - C = operand & 0x80; - - operand <<= 1; - poke(operandAddress, operand); - - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x03: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - // Set carry flag according to the left-most bit in value - C = operand & 0x80; - - operand <<= 1; - poke(operandAddress, operand); - - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x13: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operandAddress += Y; - operand = peek(operandAddress); -} -{ - // Set carry flag according to the left-most bit in value - C = operand & 0x80; - - operand <<= 1; - poke(operandAddress, operand); - - A |= operand; - notZ = A; - N = A & 0x80; -} -break; - - -case 0x4f: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -} -{ - // Set carry flag according to the right-most bit in value - C = operand & 0x01; - - operand = (operand >> 1) & 0x7f; - poke(operandAddress, operand); - - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x5f: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -} -{ - // Set carry flag according to the right-most bit in value - C = operand & 0x01; - - operand = (operand >> 1) & 0x7f; - poke(operandAddress, operand); - - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x5b: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += Y; - operand = peek(operandAddress); -} -{ - // Set carry flag according to the right-most bit in value - C = operand & 0x01; - - operand = (operand >> 1) & 0x7f; - poke(operandAddress, operand); - - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x47: -{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -} -{ - // Set carry flag according to the right-most bit in value - C = operand & 0x01; - - operand = (operand >> 1) & 0x7f; - poke(operandAddress, operand); - - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x57: -{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -} -{ - // Set carry flag according to the right-most bit in value - C = operand & 0x01; - - operand = (operand >> 1) & 0x7f; - poke(operandAddress, operand); - - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x43: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -} -{ - // Set carry flag according to the right-most bit in value - C = operand & 0x01; - - operand = (operand >> 1) & 0x7f; - poke(operandAddress, operand); - - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - -case 0x53: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operandAddress += Y; - operand = peek(operandAddress); -} -{ - // Set carry flag according to the right-most bit in value - C = operand & 0x01; - - operand = (operand >> 1) & 0x7f; - poke(operandAddress, operand); - - A ^= operand; - notZ = A; - N = A & 0x80; -} -break; - - -case 0x85: -{ - operandAddress = peek(PC++); -} -{ - poke(operandAddress, A); -} -break; - -case 0x95: -{ - operandAddress = (uInt8)(peek(PC++) + X); -} -{ - poke(operandAddress, A); -} -break; - -case 0x8d: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; -} -{ - poke(operandAddress, A); -} -break; - -case 0x9d: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; -} -{ - poke(operandAddress, A); -} -break; - -case 0x99: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += Y; -} -{ - poke(operandAddress, A); -} -break; - -case 0x81: -{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); -} -{ - poke(operandAddress, A); -} -break; - -case 0x91: -{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operandAddress += Y; -} -{ - poke(operandAddress, A); -} -break; - - -case 0x86: -{ - operandAddress = peek(PC++); -} -{ - poke(operandAddress, X); -} -break; - -case 0x96: -{ - operandAddress = (uInt8)(peek(PC++) + Y); -} -{ - poke(operandAddress, X); -} -break; - -case 0x8e: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; -} -{ - poke(operandAddress, X); -} -break; - - -case 0x84: -{ - operandAddress = peek(PC++); -} -{ - poke(operandAddress, Y); -} -break; - -case 0x94: -{ - operandAddress = (uInt8)(peek(PC++) + X); -} -{ - poke(operandAddress, Y); -} -break; - -case 0x8c: -{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; -} -{ - poke(operandAddress, Y); -} -break; - - -case 0xaa: -{ -} -{ - X = A; - notZ = X; - N = X & 0x80; -} -break; - - -case 0xa8: -{ -} -{ - Y = A; - notZ = Y; - N = Y & 0x80; -} -break; - - -case 0xba: -{ -} -{ - X = SP; - notZ = X; - N = X & 0x80; -} -break; - - -case 0x8a: -{ -} -{ - A = X; - notZ = A; - N = A & 0x80; -} -break; - - -case 0x9a: -{ -} -{ - SP = X; -} -break; - - -case 0x98: -{ -} -{ - A = Y; - notZ = A; - N = A & 0x80; -} -break; - - diff --git a/stella/src/emucore/m6502/src/M6502Low.m4 b/stella/src/emucore/m6502/src/M6502Low.m4 deleted file mode 100644 index cc2929536..000000000 --- a/stella/src/emucore/m6502/src/M6502Low.m4 +++ /dev/null @@ -1,286 +0,0 @@ -//============================================================================ -// -// MM MM 6666 555555 0000 2222 -// MMMM MMMM 66 66 55 00 00 22 22 -// MM MMM MM 66 55 00 00 22 -// MM M MM 66666 55555 00 00 22222 -- "A 6502 Microprocessor Emulator" -// MM MM 66 66 55 00 00 22 -// MM MM 66 66 55 55 00 00 22 -// MM MM 6666 5555 0000 222222 -// -// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: M6502Low.m4,v 1.2 2005-06-16 01:11:29 stephena Exp $ -//============================================================================ - -/** - Code to handle addressing modes and branch instructions for - low compatibility emulation - - @author Bradford W. Mott - @version $Id: M6502Low.m4,v 1.2 2005-06-16 01:11:29 stephena Exp $ -*/ - -#ifndef NOTSAMEPAGE - #define NOTSAMEPAGE(_addr1, _addr2) (((_addr1) ^ (_addr2)) & 0xff00) -#endif - -define(M6502_IMPLIED, `{ -}') - -define(M6502_IMMEDIATE_READ, `{ - operandAddress = PC++; - operand = peek(operandAddress); -}') - -define(M6502_ABSOLUTE_READ, `{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -}') - -define(M6502_ABSOLUTE_WRITE, `{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; -}') - -define(M6502_ABSOLUTE_READMODIFYWRITE, `{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operand = peek(operandAddress); -}') - -define(M6502_ABSOLUTEX_READ, `{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + X)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += X; - operand = peek(operandAddress); -}') - -define(M6502_ABSOLUTEX_WRITE, `{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; -}') - -define(M6502_ABSOLUTEX_READMODIFYWRITE, `{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += X; - operand = peek(operandAddress); -}') - -define(M6502_ABSOLUTEY_READ, `{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // See if we need to add one cycle for indexing across a page boundary - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -}') - -define(M6502_ABSOLUTEY_WRITE, `{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += Y; -}') - -define(M6502_ABSOLUTEY_READMODIFYWRITE, `{ - operandAddress = (uInt16)peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - operandAddress += Y; - operand = peek(operandAddress); -}') - -define(M6502_ZERO_READ, `{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -}') - -define(M6502_ZERO_WRITE, `{ - operandAddress = peek(PC++); -}') - -define(M6502_ZERO_READMODIFYWRITE, `{ - operandAddress = peek(PC++); - operand = peek(operandAddress); -}') - -define(M6502_ZEROX_READ, `{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -}') - -define(M6502_ZEROX_WRITE, `{ - operandAddress = (uInt8)(peek(PC++) + X); -}') - -define(M6502_ZEROX_READMODIFYWRITE, `{ - operandAddress = (uInt8)(peek(PC++) + X); - operand = peek(operandAddress); -}') - -define(M6502_ZEROY_READ, `{ - operandAddress = (uInt8)(peek(PC++) + Y); - operand = peek(operandAddress); -}') - -define(M6502_ZEROY_WRITE, `{ - operandAddress = (uInt8)(peek(PC++) + Y); -}') - -define(M6502_ZEROY_READMODIFYWRITE, `{ - operandAddress = (uInt8)(peek(PC++) + Y); - operand = peek(operandAddress); -}') - -define(M6502_INDIRECT, `{ - uInt16 addr = peek(PC) | ((uInt16)peek(PC + 1) << 8); - PC += 2; - - // Simulate the error in the indirect addressing mode! - uInt16 high = NOTSAMEPAGE(addr, addr + 1) ? (addr & 0xff00) : (addr + 1); - - operandAddress = peek(addr) | ((uInt16)peek(high) << 8); -}') - -define(M6502_INDIRECTX_READ, `{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -}') - -define(M6502_INDIRECTX_WRITE, `{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); -}') - -define(M6502_INDIRECTX_READMODIFYWRITE, `{ - uInt8 pointer = peek(PC++) + X; - operandAddress = peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operand = peek(operandAddress); -}') - -define(M6502_INDIRECTY_READ, `{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - - if(NOTSAMEPAGE(operandAddress, operandAddress + Y)) - { - mySystem->incrementCycles(mySystemCyclesPerProcessorCycle); - } - - operandAddress += Y; - operand = peek(operandAddress); -}') - -define(M6502_INDIRECTY_WRITE, `{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operandAddress += Y; -}') - -define(M6502_INDIRECTY_READMODIFYWRITE, `{ - uInt8 pointer = peek(PC++); - operandAddress = (uInt16)peek(pointer) | ((uInt16)peek(pointer + 1) << 8); - operandAddress += Y; - operand = peek(operandAddress); -}') - - -define(M6502_BCC, `{ - if(!C) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -}') - -define(M6502_BCS, `{ - if(C) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -}') - -define(M6502_BEQ, `{ - if(!notZ) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -}') - -define(M6502_BMI, `{ - if(N) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -}') - -define(M6502_BNE, `{ - if(notZ) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -}') - -define(M6502_BPL, `{ - if(!N) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -}') - -define(M6502_BVC, `{ - if(!V) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -}') - -define(M6502_BVS, `{ - if(V) - { - uInt16 address = PC + (Int8)operand; - mySystem->incrementCycles(NOTSAMEPAGE(PC, address) ? - mySystemCyclesPerProcessorCycle << 1 : mySystemCyclesPerProcessorCycle); - PC = address; - } -}') - - diff --git a/stella/src/gui/PromptWidget.cxx b/stella/src/gui/PromptWidget.cxx index 257b57894..8b917d2fe 100644 --- a/stella/src/gui/PromptWidget.cxx +++ b/stella/src/gui/PromptWidget.cxx @@ -13,12 +13,15 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: PromptWidget.cxx,v 1.11 2005-06-21 00:13:49 urchlay Exp $ +// $Id: PromptWidget.cxx,v 1.12 2005-06-23 01:10:26 urchlay Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project //============================================================================ +#include +#include + #include "ScrollBarWidget.hxx" #include "FrameBuffer.hxx" #include "EventHandler.hxx" @@ -683,3 +686,29 @@ void PromptWidget::scrollToCurrent() updateScrollBuffer(); } } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool PromptWidget::saveBuffer(string& filename) +{ + ofstream out(filename.c_str()); + if(!out.is_open()) + return false; + + for(int start=0; start<_promptStartPos; start+=_lineWidth) { + int end = start+_lineWidth-1; + + // look for first non-space char from end of line + while(_buffer[end] == ' ' && end >= start) + end--; + + // spit out the line minus its trailing spaces + for(int j=start; j<=end; j++) + out << _buffer[j]; + + // add a \n + out << endl; + } + + out.close(); + return true; +} diff --git a/stella/src/gui/PromptWidget.hxx b/stella/src/gui/PromptWidget.hxx index e9adbba0f..3d78965ad 100644 --- a/stella/src/gui/PromptWidget.hxx +++ b/stella/src/gui/PromptWidget.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: PromptWidget.hxx,v 1.3 2005-06-17 03:49:10 urchlay Exp $ +// $Id: PromptWidget.hxx,v 1.4 2005-06-23 01:10:26 urchlay Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -52,6 +52,7 @@ class PromptWidget : public Widget, public CommandSender void print(const char *str); void print(string str); void printPrompt(); + bool saveBuffer(string& filename); protected: inline char &buffer(int idx) { return _buffer[idx % kBufferSize]; }