Stack Watching in VICE

You need an actual VIC.

Moderator: Moderators

User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Stack Watching in VICE

Post by chysn »

All right, this might involve some major VICE-mojo, I'm not sure.

I'm familiar with the VICE monitor's "watch" command, to set up memory locations to be watched, and conditions under which events stop execution and open the monitor.

What I'd like to do is open the monitor when a specific value is pulled from the stack. For example:

Code: Select all

lda #$55
pha
lda #$20
pha
pla
pla
My scenario would be "break when #$55 is pulled from the stack," so execution would continue until the second PLA, at which point the monitor would open and show the PC.

Is this kind of thing possible with VICE's watch conditions?
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
groepaz
Vic 20 Scientist
Posts: 1187
Joined: Wed Aug 25, 2010 5:30 pm

Re: Stack Watching in VICE

Post by groepaz »

I don't think this can be done directly (please correct me if i am missing something) - you can only compare registers and memory locations, there is no way to tell "was pulled from stack".

Perhaps you can do something like ($100+SP)=$55 && A=$55 (which is obviously not really what you want, but might do the trick anyway)
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
furroy
Vic 20 Drifter
Posts: 20
Joined: Sun Aug 27, 2023 5:03 am

Re: Stack Watching in VICE

Post by furroy »

i don't think vice can help. you could use mame and set up a registerpoint on A=55 which would get you close. you can add some extra checks for
&& pc != addr to your expression to skip over places you've checked until you eventually find the one after the pla.

Oh actually Vice supports conditions too, so on each pla you can add break addr if (A==55)
Last edited by furroy on Fri Oct 06, 2023 7:53 am, edited 2 times in total.
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Stack Watching in VICE

Post by chysn »

groepaz wrote: Fri Oct 06, 2023 7:28 am I don't think this can be done directly (please correct me if i am missing something) - you can only compare registers and memory locations, there is no way to tell "was pulled from stack".

Perhaps you can do something like ($100+SP)=$55 && A=$55 (which is obviously not really what you want, but might do the trick anyway)
It looks like it might get a superset of what I want, then I can sift through them. How would that watch command be formatted? I haven't spent too much time on conditions. I tried:

Code: Select all

watch load if ($100+SP)=$55 && A=$55
watch load ($100+SP) if A=$55
It seems to want an address for the second parameter, and I'm not sure what to tell it....
furroy
Vic 20 Drifter
Posts: 20
Joined: Sun Aug 27, 2023 5:03 am

Re: Stack Watching in VICE

Post by furroy »

You want == not =

Each time the specified checkpoint is examined, the condition is evaluated. If it evalutes to true, the checkpoint is activated. Otherwise, it is ignored. If registers are specified in the expression, the values used are those at the time the checkpoint is examined, not when the condition is set. The condition can use registers (A, X, Y, PC, SP, FL and other cpu specific registers (see manual)) and compare them (==, !=, <, >, <=, >=) against other registers or constants. RL can be used to refer to the current rasterline, and CY refers to the current cycle in the line. Full expressions are also supported (+, -, *, /, &, |, &&, ||). This lets you for example check specific bits in the FL register using the bitwise boolean operators (& and |). Parentheses are also supported in the expression. Registers can be the registers of other devices; this is denoted by a memspace prefix (i.e., c:, 8:, 9:, 10:, 11: Examples: A == $0, X == Y, 8:X == X) You can also compare against the value of a memory location in a specific bank, i.e you can break only if the vic register $d020 is $f0. use the form @[bankname]:[$<address>] | [.label]. Note this is for the C : memspace only. Examples : if @io:$d020 == $f0, if @io:.vicBorder == $f0
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Stack Watching in VICE

Post by Mike »

Here's my suggestion, provided source code is available: you could instrument all PLAs with:

Code: Select all

PLA -> PLA
       JSR --+
             |
             V

            PHP
            CMP #$55
            BNE --+
            BRK   |
            NOP   |
            PLP <-+
            RTS
This would even work on real hardware. :)

When the condition is met, the BRK instruction is executed ... a native monitor then leaves you with the pushed copy of the status register and the JSR return address on stack, and from the latter you can derive which PLA did pop $55:

Image

The example at $02A1 just pushes A and pulls A again, calls the instrumentation at $02F7 and ends with BRK for a planned return to the monitor prompt.

Image

The first call with G 02A1 has A=$00 from the initial register dump and returns normally.

In a copy of the register dump, I change A to $55 and do a second G 02A1. This one promptly gets intercepted by the instrumentation. I use the current value of SP=$F4 in the register dump to do a stack dump with M 01F4 01FF, which shows the return address - 1 of JSR in the 3rd and 4th byte, $02A5. I then count 3 bytes backwards and arrive at the "offending" PLA at $02A2.

Another G (without address) continues from the breakpoint in the instrumentation and the example terminates normally at $02A6.
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Stack Watching in VICE

Post by chysn »

I think I'm getting pretty close:

Code: Select all

watch load 0100 01ff if A==$55
To narrow it down a bit, I'd like to see if the byte at the PC == $68 (PLA). But I can probably use something like the above if I'm willing to spend time weeding out results.

I know that PC can be used in a condition. Can the value of the memory at PC be used?
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Stack Watching in VICE

Post by chysn »

Mike wrote: Fri Oct 06, 2023 7:59 am Here's my suggestion, provided source code is available: you could instrument all PLAs
That's some real brute force there! But it would work, provided the PLA isn't in ROM. I'm trying to track down a stack issue that doesn't seem like it should even be happening, and it could be anywhere.
furroy
Vic 20 Drifter
Posts: 20
Joined: Sun Aug 27, 2023 5:03 am

Re: Stack Watching in VICE

Post by furroy »

is it causing a crash or what? if you can get any breakpoint to trigger afterwards, you could use chis and scroll back to see what caused it.
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Stack Watching in VICE

Post by Mike »

chysn wrote:I'm trying to track down a stack issue that doesn't seem like it should even be happening, and it could be anywhere.
In such a case, all stack pulling instructions could face that issue, not just PLA.

At the risk of stating the obvious: nothing in the stack area at or below $0100+SP should be of any value for the executing program, especially not in the presence of interrupts.

Is $55 some kind of guard value you want to use to detect excess pulls from stack?
groepaz
Vic 20 Scientist
Posts: 1187
Joined: Wed Aug 25, 2010 5:30 pm

Re: Stack Watching in VICE

Post by groepaz »

Can the value of the memory at PC be used?
Unfortunately not
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Stack Watching in VICE

Post by chysn »

furroy wrote: Fri Oct 06, 2023 8:20 am is it causing a crash or what? if you can get any breakpoint to trigger afterwards, you could use chis and scroll back to see what caused it.
Not crashing, just returning an unexpected value. The expected value is one address below on the stack so something's already pulled it.
Mike wrote: Fri Oct 06, 2023 8:31 am
chysn wrote:I'm trying to track down a stack issue that doesn't seem like it should even be happening, and it could be anywhere.
In such a case, all stack pulling instructions could face that issue, not just PLA.
Yes, including RTS. Although that seems like it'd cause obvious problems. That's why I was hoping I could examine stack activity as opposed to just watching the accumulator.
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Stack Watching in VICE

Post by chysn »

Well, if I haven't solved my problem, at least I understand what's happening. My big error was thinking that I was off by one. Actually, there are three return addresses added to the stack between PHA and PLA, and that PLA is getting the low byte of the most recent of those. Since I'm working with a BRK handler, corrupting a return address isn't causing a crash.

VICE's watch conditions were very informative while figuring this out. Even though the condition was broad by necessity, I could easily see what I needed to see, and I was able to make marginal improvements to my code.

Thanks, all!
groepaz
Vic 20 Scientist
Posts: 1187
Joined: Wed Aug 25, 2010 5:30 pm

Re: Stack Watching in VICE

Post by groepaz »

BTW, i am offering a crate of beer to whoever implements a "dereference" operator for the conditions (so you can use the content of the memory whatever expression points to) - that would be super useful indeed :)
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
User avatar
thegg
Vic 20 Amateur
Posts: 69
Joined: Mon Aug 30, 2021 4:49 am
Location: England
Occupation: retired

Re: Stack Watching in VICE

Post by thegg »

Can't test this as I'm away from my computer at the moment. But as a matter of interest you could try:
Trace load m1 m2 with the condition A==value. To see if it would have helped with your debugging.

I'm not sure Vice treats the stack as memory, but I suspect it does. This would log all reads of 'value' along with the address where the accumulator is loaded.

You could of course replace trace with watch. However, whatever 'value' is, there are likely more than one instance of it on the stack.
Post Reply