Re: [stella] Stella conditional breakpoint support RFC

Subject: Re: [stella] Stella conditional breakpoint support RFC
From: "B. Watson" <atari@xxxxxxxxxxxxxx>
Date: Mon, 11 Jul 2005 23:18:03 -0400
On Mon, 11 Jul 2005, Jeremy Penner wrote:

>> 1. Re-parse the conditional(s) before each 6502 instruction
>> executes, or..
> What are you doing, man!  Don't ever parse more than once!  Put it
> into a data structure!

It's this that I don't fully know how to do... I know about enough yacc
to write a simple interpreted language, and I understand the concept of
using yacc building a tree (or something), but I don't understand how to
glue the two together: have yacc build a tree that I can evaluate without
actually re-calling yyparse() and letting it re-lex and parse the input...

>> 2. Write a compiler for the conditionals (a "bytecode" type of
> You really don't need bytecode to evaluate simple expressions; all
> you need is an executable parse tree, which is pretty trivial to do
> and probably much more efficient.

I was thinking "three-address code"... mostly because I have a book that
extols its virtues :)

If it's overkill, I'm glad to hear it: it makes my head spin...

Part of my confusion is that yacc's stated purpose is to generate a
parse tree... but I don't think there's any way to save this tree and
evaluate it later, is there?

> Stella's C++, right?  You could pretty trivially write a virtual
> "expression" class, with an overridable "evaluate" method, and
> subclass your operations: EqualityExpression, PCExpression, etc.
> EqualityExpression's constructor takes two expressions as arguments,
> PCExpression's evaluate method grabs the PC from the CPU state, etc.
> Build up this tree in yacc, and just call evaluate after every
> instruction to figure out whether or not to break.  (Make your ANDs
> and ORs shortcut; it'll save you from having to do anything else on
> those PC==myLabel checks.)

This is more like something I could actually learn to do in a reasonable
amount of time.

So each Expression subclass is a tree node with left/right pointers,
which will be null for a leaf node...? At evaluate time, we call the
root node's evaluate(), which calls the left node's evaluate(), which
calls its left node's evaluate(), etc...?

I'm going to have to spend some quality time with the dragon book,
I guess. I recall a whole section on parse trees, but can't remember
much about them now.

> In any case, you should absolutely be building a simple data
> structure and interpreting that, rather than re-parsing every time.

Agreed. I just didn't have any idea on how to do so... I was stuck on
the "save the yacc parse tree and re-use it" idea... but after a week
of trying to figure it out, have given up on it.

>> Of course, there's no reason I couldn't do both: arbitrary
>> conditions that
>> come at the cost of slowing down the emulator (maybe a lot), or
>> conditions
>> tied to an address that let the emulator run at (99% of) full speed.
> Arbitrary conditional breakpoints are really useful in certain
> annoying situations.  ("Just when does that value get overwritten?!
> Argh!")

The only places a value can live are RAM (or I/O on the same bus) or
registers. Stella currently has breakpoints on memory (or I/O) access or
the program counter, so you could trap the address if you're talking about
a value in RAM... how about if I add traps for other registers too? Along
with conditionals, I mean: "trapwrite y" catches any change to Y, and
"trapwrite y if y==$ff" catches a specific value being loaded into Y.
(Could shorten the syntax to "trapwrite y $ff" maybe).

> They are also slow; it's a fact and has always been one.
> Thankfully, in the case of emulation, timing-sensitive things don't
> break when things slow down.  When you're tracking down that kind of
> problem, emulation speed is probably last thing on your mind.  If it
> helps you find the bug, who cares if the sound cuts out?

True. Tying conditionals to the existing break/trap mechanism is just
an optimization, and maybe this doesn't need to be optimized...

Thanks, you've given me some direction...

Archives (includes files) at
Unsub & more at

Current Thread