2005-06-29 13:11:03 +00:00
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
// SSSS tt lll lll
|
|
|
|
// SS SS tt ll ll
|
|
|
|
// SS tttttt eeee ll ll aaaa
|
|
|
|
// SSSS tt ee ee ll ll aa
|
|
|
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
|
|
// SS SS tt ee ll ll aa aa
|
|
|
|
// SSSS ttt eeeee llll llll aaaaa
|
|
|
|
//
|
2011-01-01 16:04:32 +00:00
|
|
|
// Copyright (c) 1995-2011 by Bradford W. Mott, Stephen Anthony
|
2010-04-10 21:37:23 +00:00
|
|
|
// and the Stella Team
|
2005-06-29 13:11:03 +00:00
|
|
|
//
|
2010-01-10 03:23:32 +00:00
|
|
|
// See the file "License.txt" for information on usage and redistribution of
|
2005-06-29 13:11:03 +00:00
|
|
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
|
|
//
|
2009-05-13 13:55:40 +00:00
|
|
|
// $Id$
|
2005-06-29 13:11:03 +00:00
|
|
|
//============================================================================
|
Added initial trap support. It doesn't quite work yet: when I hit a
trap, the PC keeps getting reset to the start of the frame. FYI,
traps are like breakpoints, only they trigger on any access of the
trap location (e.g. loading data from it, rather than executing it
as a breakpoint).
Fixed two nasty bugs:
1. Debugger::disassemble() was printing hex bytes from the wrong address.
This is because I used readRAM(), which wants a parameter of 0-127, and
reads only from RAM. I *should* have been using peek(), which takes a
16-bit address. In fact, readRAM() is only for the GUI.
2. D6502::disassemble() was printing wrong operands in zero,x and
zero,y addressing modes, due to me passing a wrong number of places
(and thus creating a wrong format string).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@537 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2005-06-21 04:30:49 +00:00
|
|
|
|
2005-07-08 17:22:41 +00:00
|
|
|
#ifndef TIA_DEBUG_HXX
|
|
|
|
#define TIA_DEBUG_HXX
|
Added initial trap support. It doesn't quite work yet: when I hit a
trap, the PC keeps getting reset to the start of the frame. FYI,
traps are like breakpoints, only they trigger on any access of the
trap location (e.g. loading data from it, rather than executing it
as a breakpoint).
Fixed two nasty bugs:
1. Debugger::disassemble() was printing hex bytes from the wrong address.
This is because I used readRAM(), which wants a parameter of 0-127, and
reads only from RAM. I *should* have been using peek(), which takes a
16-bit address. In fact, readRAM() is only for the GUI.
2. D6502::disassemble() was printing wrong operands in zero,x and
zero,y addressing modes, due to me passing a wrong number of places
(and thus creating a wrong format string).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@537 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2005-06-21 04:30:49 +00:00
|
|
|
|
2005-07-08 17:22:41 +00:00
|
|
|
class Debugger;
|
2005-07-19 00:05:23 +00:00
|
|
|
class TiaDebug;
|
2010-10-18 18:39:57 +00:00
|
|
|
class TIA;
|
Added initial trap support. It doesn't quite work yet: when I hit a
trap, the PC keeps getting reset to the start of the frame. FYI,
traps are like breakpoints, only they trigger on any access of the
trap location (e.g. loading data from it, rather than executing it
as a breakpoint).
Fixed two nasty bugs:
1. Debugger::disassemble() was printing hex bytes from the wrong address.
This is because I used readRAM(), which wants a parameter of 0-127, and
reads only from RAM. I *should* have been using peek(), which takes a
16-bit address. In fact, readRAM() is only for the GUI.
2. D6502::disassemble() was printing wrong operands in zero,x and
zero,y addressing modes, due to me passing a wrong number of places
(and thus creating a wrong format string).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@537 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2005-06-21 04:30:49 +00:00
|
|
|
|
2005-07-08 17:22:41 +00:00
|
|
|
#include "Array.hxx"
|
|
|
|
#include "DebuggerSystem.hxx"
|
Added initial trap support. It doesn't quite work yet: when I hit a
trap, the PC keeps getting reset to the start of the frame. FYI,
traps are like breakpoints, only they trigger on any access of the
trap location (e.g. loading data from it, rather than executing it
as a breakpoint).
Fixed two nasty bugs:
1. Debugger::disassemble() was printing hex bytes from the wrong address.
This is because I used readRAM(), which wants a parameter of 0-127, and
reads only from RAM. I *should* have been using peek(), which takes a
16-bit address. In fact, readRAM() is only for the GUI.
2. D6502::disassemble() was printing wrong operands in zero,x and
zero,y addressing modes, due to me passing a wrong number of places
(and thus creating a wrong format string).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@537 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2005-06-21 04:30:49 +00:00
|
|
|
|
2005-07-18 16:10:52 +00:00
|
|
|
// pointer types for TIADebug instance methods
|
2005-07-19 00:05:23 +00:00
|
|
|
// (used by TiaMethodExpression)
|
2010-10-18 18:39:57 +00:00
|
|
|
class TIADebug;
|
2005-07-19 00:05:23 +00:00
|
|
|
typedef int (TIADebug::*TIADEBUG_INT_METHOD)();
|
2005-07-18 16:10:52 +00:00
|
|
|
|
2005-07-19 00:05:23 +00:00
|
|
|
// call the pointed-to method on the (global) debugger object.
|
2005-07-18 16:10:52 +00:00
|
|
|
#define CALL_TIADEBUG_METHOD(method) ( ( Debugger::debugger().tiaDebug().*method)() )
|
|
|
|
|
2005-08-15 18:52:15 +00:00
|
|
|
// Indices for various IntArray in TiaState
|
|
|
|
enum {
|
|
|
|
P0, P1, M0, M1, BL
|
|
|
|
};
|
|
|
|
|
2005-07-08 17:22:41 +00:00
|
|
|
class TiaState : public DebuggerState
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IntArray ram;
|
2005-07-14 18:28:36 +00:00
|
|
|
IntArray coluRegs;
|
2005-08-15 18:52:15 +00:00
|
|
|
IntArray gr;
|
|
|
|
IntArray pos;
|
|
|
|
IntArray hm;
|
|
|
|
IntArray pf;
|
2005-08-17 21:38:34 +00:00
|
|
|
IntArray size;
|
2005-10-13 18:53:07 +00:00
|
|
|
IntArray aud;
|
2005-07-08 17:22:41 +00:00
|
|
|
};
|
2005-07-03 01:36:40 +00:00
|
|
|
|
2005-07-08 17:22:41 +00:00
|
|
|
class TIADebug : public DebuggerSystem
|
|
|
|
{
|
|
|
|
public:
|
Added RiotDebug class, which for now only duplicates the previous
functionality of the Debugger::riotState() method. It will become
more useful when I add a RIOT tab to the debugger. Also, added
change tracking infrastructure.
Fixed long-standing bug with viewing the contents of TIM{1, 8, 64, 1024}T
registers. Apparently, the output generated by the 'riot' debugger
command showed either INTIM or TIMINT for those registers, and not the
actual value written to those registers.
Added INTIM, TIMINT, and TIMCLKS to the riot output, which show the
current values of the timer, the timer interrupt, and the number of
'timer clocks' resulting from writing to a timer register.
Cleaned up some of the debugger API, removing pointers and using
references instead.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1479 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2008-04-19 21:11:52 +00:00
|
|
|
TIADebug(Debugger& dbg, Console& console);
|
Added initial trap support. It doesn't quite work yet: when I hit a
trap, the PC keeps getting reset to the start of the frame. FYI,
traps are like breakpoints, only they trigger on any access of the
trap location (e.g. loading data from it, rather than executing it
as a breakpoint).
Fixed two nasty bugs:
1. Debugger::disassemble() was printing hex bytes from the wrong address.
This is because I used readRAM(), which wants a parameter of 0-127, and
reads only from RAM. I *should* have been using peek(), which takes a
16-bit address. In fact, readRAM() is only for the GUI.
2. D6502::disassemble() was printing wrong operands in zero,x and
zero,y addressing modes, due to me passing a wrong number of places
(and thus creating a wrong format string).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@537 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2005-06-21 04:30:49 +00:00
|
|
|
|
Added RiotDebug class, which for now only duplicates the previous
functionality of the Debugger::riotState() method. It will become
more useful when I add a RIOT tab to the debugger. Also, added
change tracking infrastructure.
Fixed long-standing bug with viewing the contents of TIM{1, 8, 64, 1024}T
registers. Apparently, the output generated by the 'riot' debugger
command showed either INTIM or TIMINT for those registers, and not the
actual value written to those registers.
Added INTIM, TIMINT, and TIMCLKS to the riot output, which show the
current values of the timer, the timer interrupt, and the number of
'timer clocks' resulting from writing to a timer register.
Cleaned up some of the debugger API, removing pointers and using
references instead.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1479 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2008-04-19 21:11:52 +00:00
|
|
|
const DebuggerState& getState();
|
|
|
|
const DebuggerState& getOldState() { return myOldState; }
|
2005-07-03 01:36:40 +00:00
|
|
|
|
2005-07-08 17:22:41 +00:00
|
|
|
void saveOldState();
|
Added RiotDebug class, which for now only duplicates the previous
functionality of the Debugger::riotState() method. It will become
more useful when I add a RIOT tab to the debugger. Also, added
change tracking infrastructure.
Fixed long-standing bug with viewing the contents of TIM{1, 8, 64, 1024}T
registers. Apparently, the output generated by the 'riot' debugger
command showed either INTIM or TIMINT for those registers, and not the
actual value written to those registers.
Added INTIM, TIMINT, and TIMCLKS to the riot output, which show the
current values of the timer, the timer interrupt, and the number of
'timer clocks' resulting from writing to a timer register.
Cleaned up some of the debugger API, removing pointers and using
references instead.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1479 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2008-04-19 21:11:52 +00:00
|
|
|
string toString();
|
2005-07-03 01:36:40 +00:00
|
|
|
|
2005-07-23 15:55:21 +00:00
|
|
|
/* TIA byte (or part of a byte) registers */
|
|
|
|
uInt8 nusiz0(int newVal = -1);
|
|
|
|
uInt8 nusiz1(int newVal = -1);
|
2005-08-17 21:38:34 +00:00
|
|
|
uInt8 nusizP0(int newVal = -1);
|
|
|
|
uInt8 nusizP1(int newVal = -1);
|
|
|
|
uInt8 nusizM0(int newVal = -1);
|
|
|
|
uInt8 nusizM1(int newVal = -1);
|
|
|
|
const string& nusizP0String() { return nusizStrings[nusizP0()]; }
|
|
|
|
const string& nusizP1String() { return nusizStrings[nusizP1()]; }
|
2005-07-23 15:55:21 +00:00
|
|
|
|
2005-07-14 18:28:36 +00:00
|
|
|
uInt8 coluP0(int newVal = -1);
|
|
|
|
uInt8 coluP1(int newVal = -1);
|
|
|
|
uInt8 coluPF(int newVal = -1);
|
|
|
|
uInt8 coluBK(int newVal = -1);
|
2005-07-08 17:22:41 +00:00
|
|
|
|
2005-08-17 21:38:34 +00:00
|
|
|
uInt8 sizeBL(int newVal = -1);
|
2005-07-23 15:55:21 +00:00
|
|
|
uInt8 ctrlPF(int newVal = -1);
|
|
|
|
|
|
|
|
uInt8 pf0(int newVal = -1);
|
|
|
|
uInt8 pf1(int newVal = -1);
|
|
|
|
uInt8 pf2(int newVal = -1);
|
|
|
|
|
|
|
|
uInt8 grP0(int newVal = -1);
|
|
|
|
uInt8 grP1(int newVal = -1);
|
2005-08-15 18:52:15 +00:00
|
|
|
uInt8 posP0(int newVal = -1);
|
|
|
|
uInt8 posP1(int newVal = -1);
|
|
|
|
uInt8 posM0(int newVal = -1);
|
|
|
|
uInt8 posM1(int newVal = -1);
|
|
|
|
uInt8 posBL(int newVal = -1);
|
2005-07-23 15:55:21 +00:00
|
|
|
uInt8 hmP0(int newVal = -1);
|
|
|
|
uInt8 hmP1(int newVal = -1);
|
|
|
|
uInt8 hmM0(int newVal = -1);
|
|
|
|
uInt8 hmM1(int newVal = -1);
|
|
|
|
uInt8 hmBL(int newVal = -1);
|
|
|
|
|
|
|
|
uInt8 audC0(int newVal = -1);
|
|
|
|
uInt8 audC1(int newVal = -1);
|
|
|
|
uInt8 audF0(int newVal = -1);
|
|
|
|
uInt8 audF1(int newVal = -1);
|
|
|
|
uInt8 audV0(int newVal = -1);
|
|
|
|
uInt8 audV1(int newVal = -1);
|
|
|
|
|
2005-08-18 16:19:07 +00:00
|
|
|
/* TIA bool registers */
|
2005-07-23 15:55:21 +00:00
|
|
|
bool refP0(int newVal = -1);
|
|
|
|
bool refP1(int newVal = -1);
|
|
|
|
bool enaM0(int newVal = -1);
|
|
|
|
bool enaM1(int newVal = -1);
|
|
|
|
bool enaBL(int newVal = -1);
|
|
|
|
|
2005-08-15 18:52:15 +00:00
|
|
|
bool vdelP0(int newVal = -1);
|
|
|
|
bool vdelP1(int newVal = -1);
|
|
|
|
bool vdelBL(int newVal = -1);
|
|
|
|
|
|
|
|
bool resMP0(int newVal = -1);
|
|
|
|
bool resMP1(int newVal = -1);
|
|
|
|
|
2005-08-18 16:19:07 +00:00
|
|
|
bool refPF(int newVal = -1);
|
|
|
|
bool scorePF(int newVal = -1);
|
|
|
|
bool priorityPF(int newVal = -1);
|
|
|
|
|
|
|
|
/* Collision registers */
|
|
|
|
bool collM0_P1(int newVal = -1) { return collision(0, newVal); }
|
|
|
|
bool collM0_P0(int newVal = -1) { return collision(1, newVal); }
|
|
|
|
bool collM1_P0(int newVal = -1) { return collision(2, newVal); }
|
|
|
|
bool collM1_P1(int newVal = -1) { return collision(3, newVal); }
|
|
|
|
bool collP0_PF(int newVal = -1) { return collision(4, newVal); }
|
|
|
|
bool collP0_BL(int newVal = -1) { return collision(5, newVal); }
|
|
|
|
bool collP1_PF(int newVal = -1) { return collision(6, newVal); }
|
|
|
|
bool collP1_BL(int newVal = -1) { return collision(7, newVal); }
|
|
|
|
bool collM0_PF(int newVal = -1) { return collision(8, newVal); }
|
|
|
|
bool collM0_BL(int newVal = -1) { return collision(9, newVal); }
|
|
|
|
bool collM1_PF(int newVal = -1) { return collision(10, newVal); }
|
|
|
|
bool collM1_BL(int newVal = -1) { return collision(11, newVal); }
|
|
|
|
bool collBL_PF(int newVal = -1) { return collision(12, newVal); }
|
|
|
|
bool collP0_P1(int newVal = -1) { return collision(13, newVal); }
|
|
|
|
bool collM0_M1(int newVal = -1) { return collision(14, newVal); }
|
2005-08-17 21:38:34 +00:00
|
|
|
|
2005-08-15 18:52:15 +00:00
|
|
|
/* TIA strobe registers */
|
Added RiotDebug class, which for now only duplicates the previous
functionality of the Debugger::riotState() method. It will become
more useful when I add a RIOT tab to the debugger. Also, added
change tracking infrastructure.
Fixed long-standing bug with viewing the contents of TIM{1, 8, 64, 1024}T
registers. Apparently, the output generated by the 'riot' debugger
command showed either INTIM or TIMINT for those registers, and not the
actual value written to those registers.
Added INTIM, TIMINT, and TIMCLKS to the riot output, which show the
current values of the timer, the timer interrupt, and the number of
'timer clocks' resulting from writing to a timer register.
Cleaned up some of the debugger API, removing pointers and using
references instead.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1479 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2008-04-19 21:11:52 +00:00
|
|
|
void strobeWsync() { mySystem.poke(WSYNC, 0); }
|
|
|
|
void strobeRsync() { mySystem.poke(RSYNC, 0); } // not emulated!
|
|
|
|
void strobeResP0() { mySystem.poke(RESP0, 0); }
|
|
|
|
void strobeResP1() { mySystem.poke(RESP1, 0); }
|
|
|
|
void strobeResM0() { mySystem.poke(RESM0, 0); }
|
|
|
|
void strobeResM1() { mySystem.poke(RESM1, 0); }
|
|
|
|
void strobeResBL() { mySystem.poke(RESBL, 0); }
|
|
|
|
void strobeHmove() { mySystem.poke(HMOVE, 0); }
|
|
|
|
void strobeHmclr() { mySystem.poke(HMCLR, 0); }
|
|
|
|
void strobeCxclr() { mySystem.poke(CXCLR, 0); }
|
2005-07-23 15:55:21 +00:00
|
|
|
|
|
|
|
/* read-only internal TIA state */
|
2005-07-08 17:22:41 +00:00
|
|
|
int scanlines();
|
|
|
|
int frameCount();
|
2005-07-21 04:10:16 +00:00
|
|
|
int clocksThisLine();
|
2005-07-08 17:22:41 +00:00
|
|
|
bool vsync();
|
|
|
|
bool vblank();
|
2009-01-12 15:11:55 +00:00
|
|
|
int vsyncAsInt() { return int(vsync()); } // so we can use _vsync pseudo-register
|
|
|
|
int vblankAsInt() { return int(vblank()); } // so we can use _vblank pseudo-register
|
2005-07-08 17:22:41 +00:00
|
|
|
|
|
|
|
private:
|
2005-08-18 16:19:07 +00:00
|
|
|
/** Display a color patch for color at given index in the palette */
|
2005-07-08 17:22:41 +00:00
|
|
|
string colorSwatch(uInt8 c);
|
Added initial trap support. It doesn't quite work yet: when I hit a
trap, the PC keeps getting reset to the start of the frame. FYI,
traps are like breakpoints, only they trigger on any access of the
trap location (e.g. loading data from it, rather than executing it
as a breakpoint).
Fixed two nasty bugs:
1. Debugger::disassemble() was printing hex bytes from the wrong address.
This is because I used readRAM(), which wants a parameter of 0-127, and
reads only from RAM. I *should* have been using peek(), which takes a
16-bit address. In fact, readRAM() is only for the GUI.
2. D6502::disassemble() was printing wrong operands in zero,x and
zero,y addressing modes, due to me passing a wrong number of places
(and thus creating a wrong format string).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@537 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2005-06-21 04:30:49 +00:00
|
|
|
|
2005-08-18 16:19:07 +00:00
|
|
|
/** Get/set specific bits in the collision register (used by collXX_XX) */
|
|
|
|
bool collision(int collID, int newVal);
|
|
|
|
|
2011-07-13 14:13:49 +00:00
|
|
|
string audFreq(uInt8 div);
|
Added RiotDebug class, which for now only duplicates the previous
functionality of the Debugger::riotState() method. It will become
more useful when I add a RIOT tab to the debugger. Also, added
change tracking infrastructure.
Fixed long-standing bug with viewing the contents of TIM{1, 8, 64, 1024}T
registers. Apparently, the output generated by the 'riot' debugger
command showed either INTIM or TIMINT for those registers, and not the
actual value written to those registers.
Added INTIM, TIMINT, and TIMCLKS to the riot output, which show the
current values of the timer, the timer interrupt, and the number of
'timer clocks' resulting from writing to a timer register.
Cleaned up some of the debugger API, removing pointers and using
references instead.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1479 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2008-04-19 21:11:52 +00:00
|
|
|
string booleanWithLabel(string label, bool value);
|
|
|
|
|
2005-07-08 17:22:41 +00:00
|
|
|
private:
|
|
|
|
TiaState myState;
|
|
|
|
TiaState myOldState;
|
|
|
|
|
Added RiotDebug class, which for now only duplicates the previous
functionality of the Debugger::riotState() method. It will become
more useful when I add a RIOT tab to the debugger. Also, added
change tracking infrastructure.
Fixed long-standing bug with viewing the contents of TIM{1, 8, 64, 1024}T
registers. Apparently, the output generated by the 'riot' debugger
command showed either INTIM or TIMINT for those registers, and not the
actual value written to those registers.
Added INTIM, TIMINT, and TIMCLKS to the riot output, which show the
current values of the timer, the timer interrupt, and the number of
'timer clocks' resulting from writing to a timer register.
Cleaned up some of the debugger API, removing pointers and using
references instead.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1479 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2008-04-19 21:11:52 +00:00
|
|
|
TIA& myTIA;
|
2005-07-08 17:22:41 +00:00
|
|
|
|
|
|
|
string nusizStrings[8];
|
|
|
|
};
|
Added initial trap support. It doesn't quite work yet: when I hit a
trap, the PC keeps getting reset to the start of the frame. FYI,
traps are like breakpoints, only they trigger on any access of the
trap location (e.g. loading data from it, rather than executing it
as a breakpoint).
Fixed two nasty bugs:
1. Debugger::disassemble() was printing hex bytes from the wrong address.
This is because I used readRAM(), which wants a parameter of 0-127, and
reads only from RAM. I *should* have been using peek(), which takes a
16-bit address. In fact, readRAM() is only for the GUI.
2. D6502::disassemble() was printing wrong operands in zero,x and
zero,y addressing modes, due to me passing a wrong number of places
(and thus creating a wrong format string).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@537 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2005-06-21 04:30:49 +00:00
|
|
|
|
|
|
|
#endif
|