The Frob: Ongoing analysis: Why is FMON hanging?

6 posts / 0 new
Last post
Offline
Last seen: 2 hours 24 min ago
Joined: Jan 22 2022 - 07:50
Posts: 10
The Frob: Ongoing analysis: Why is FMON hanging?

The Frob was an Atari VCS #GameDev system card for the #Apple2.

It had an interactive debugger called FMON which I am trying to debug. And an apple2 side called AMON, these run in tandem.

The Frob was unique because it had a pair of bi-directional registers for status and sending one byte of data. This can be used by the VCS and the Apple2 to send information to each other.

Chapter 2 of the Frob manual describes the operation of these registers. 

These bi-directional registers were exposed as two addresses (e.g. $C0A0, $C0A1 for slot 2) on the apple2, and as three addresses ($FFF0, $FFF1, and $FFF2) on the VCS.

The status register only comprises the two uppermost bits. Bit 7 is Write OK, Bit 6 is Read OK. They are set once their complementary operation is performed.

So basically, I am seeing a situation where both sides are waiting for an OK, in a dead-lock, because the VCS isn't completing its read.

I've added bits of debug statements to the Apple2 side to see when FMON transactions are happening, and am trying to work through where the deadlock happens.

THIS DEADLOCK DOES NOT HAPPEN WITH THE CONTROL CODE THAT YOU CAN EMBED E.G. USING THE FROB EXPLORER. MY PLAYER TOOL USES THIS CODE TOO, AND IT WORKS WITHOUT FAIL.

Rebecca Heineman had offered some advice on a debugging procedure which involved embedding FMON. This approach does not work, however, because FMON is intended to be isolated in the VCS address space at a known address. It's intended to just sit and spin with nothing else bothering it, right at the end of the address space. This is in stark contrast to EXPLORER, which embeds a routine to interpret commands in-line with the game code.

FMON is a bit unique in that it uses some clever tricks.

AMON injects a bit of code into VCS RAM which loops and sleeps, then jumping to the IRQ (BRK) vector, which is used to support breakpoints.

Meanwhile FMON preserves and restores state when Go is entered and exited.

Another peculiarity, is that reading/writing to ROM addresses cause a corresponding operation to shadow area in the Apple2 at $8000, which is then transferred to the FROB memory area via PMOVE. This means that I can use FMON to alter ROM code just fine, but when I attempt a RAM or register read or write, it hangs while sending parameters.

Sigh. :) 

S.Elliott's picture
Offline
Last seen: 3 hours 23 min ago
Joined: Jun 23 2022 - 16:26
Posts: 278
Missing clues

If BREAK is the address of the IRQ (BRK) vector, then line 133 will cause the VCS to crash.  Indeed, the encoding for "JMP IRQ" or "JMP BREAK" will fail on every 65xx processor.

 

 

To interpret your ASM code any deeper, I need to know the values of the labels BREAK, PSTAT, WDATA, and RDATA...or to see the bytes of machine code at the left of the line numbers.  But I've got to run to a 10:30AM Zoom call, so I will come back for another look later.

 

But it looks plausible that BJUMP might have been assembled into the bytes 4C FE FF.  If so, then that's definitely a fatal error...regardless of whether the rest of the code is right.

Offline
Last seen: 2 hours 24 min ago
Joined: Jan 22 2022 - 07:50
Posts: 10
S.Elliott wrote:If BREAK is
S.Elliott wrote:

If BREAK is the address of the IRQ (BRK) vector, then line 133 will cause the VCS to crash.  Indeed, the encoding for "JMP IRQ" or "JMP BREAK" will fail on every 65xx processor.

 

[[{"fid":"41143","view_mode":"default","fields":{"format":"default","alignment":"","field_file_image_alt_text[und][0][value]":false,"field_file_image_title_text[und][0]

 

so no, the break is a jump to $FF00.

 

Source code is here: https://drive.google.com/file/d/14A8TfdMZD0wrZUw7D-EZzEGqCdSjf7ui/view?usp=sharing

 

 

 

 

 

Offline
Last seen: 2 hours 24 min ago
Joined: Jan 22 2022 - 07:50
Posts: 10
I know that Apple2 -> VCS bi

I know that Apple2 -> VCS bi-di register works:

https://drive.google.com/file/d/1VXFpCPxxG30FmO_QBdAdHpU7N4vGjSZu/view?usp=sharing

 

and I know that VCS -> Apple2 bi-di register works:

https://drive.google.com/file/d/1VZA19hYqqvMouV4Me-vC0DH_Z2iBlBVU/view?usp=sharing

 

 

S.Elliott's picture
Offline
Last seen: 3 hours 23 min ago
Joined: Jun 23 2022 - 16:26
Posts: 278
Thomas Cherryhomes wrote:I
Thomas Cherryhomes wrote:

I know that Apple2 -> VCS bi-di register works:

https://drive.google.com/file/d/1VXFpCPxxG30FmO_QBdAdHpU7N4vGjSZu/view?usp=sharing

 

and I know that VCS -> Apple2 bi-di register works:

https://drive.google.com/file/d/1VZA19hYqqvMouV4Me-vC0DH_Z2iBlBVU/view?usp=sharing

 

Ooo...those are excellent demonstrations, each showing that information is being forwarded from one device to the other.  One video for each direction.  Nice.

In order to get in sync with your intentions, here's a list of interesting details I perceive in the FMON source code.  If my observations don't match your intentions, then we will try to determine whether my interpretation is wrong or if I stumbled across a bug...

  • Apparently this is still experimental, so there are contradictory-looking details because it's not-yet-finished code.  For instance, lines 41-58 partially-preserve the N and Z flags in order to so that the code does not need to use the stack.  But at lines 79-81 it does use the stack to read the processor status register (except N and Z) and make a function call.
  • The BREAK function saves only three of the four valid combinations of the N and Z flags.  It won't correctly preserve the combination N=1 Z=1, the saved state will incorrectly be restored as N=0 Z=1.  The combination N=1 Z=1 is quite uncommon because the 6502's arithmetic unit will never evaluate a result as being both negative and zero at the same time, but it is a valid combination that can arise from using the PLP instruction or BIT instruction.  (See this blogpost for a code sample that uses BIT to select all 8 combinations of the N, Z, and V flags.)  Was this an intentional choice to conserve code?
  • Lines 69-75 transmit exactly 32 bytes of the VCS's memory to the Apple, although the VCS has 128 bytes of memory.  (It saves locations $E0-$FF, not $80-$FF.)  Is the Apple expecting only 32 bytes?
  • Only 16 cycles after sending the last byte of saved status to WDATA, line 90 reads one byte from RDATA and discards it before awaiting command-input from RDATA at line 97.  If the Apple had already sent a command byte, then it looks like line 90 would discard it -- then become stalled at line 97 awaiting the command it had just discarded.  After the Apple receives the saved processor state, does it wait at least 16 cycles before sending a command byte?
Offline
Last seen: 2 hours 24 min ago
Joined: Jan 22 2022 - 07:50
Posts: 10
 The invalid N Z processor

 The invalid N Z processor flags combo is explicitly caught by its Apple2 counterpart, AMON, and is not allowed.

 

As AMON is running in AppleSoft BASIC, it is very slow, so I would safely assume more than 16 processor cycles are elapsed between command bytes and parameters.

 

I'm going to see if I can test the status register function between the two systems.

 

 

Log in or register to post comments