Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > USB Freezer/Downloader
2012-11-10 09:20
logikstate
Account closed

Registered: Jan 2011
Posts: 21
USB Freezer/Downloader

Posting this to gauge interest.

Here is a hacked Action Replay ROM running inside an Easy Flash 3 cartridge. I've modified the cartridge CPLD core to allow freezing via USB. I can 'freeze' the machine via USB at any point, download new code, 'unfreeze' and then run.

I've modified Tom-Cat's ef3usb tools to achieve this, no point re-inventing the wheel :)

Next I hope to be able to modify the CPLD core further by adding true hardware breakpoints. The CPLD would 'freeze' when a read/write at a certain address is reached, allowing USB comms, further memory/register modification would then be possible over USB, as well as 'unfreeze' to resume.

Here's a video of me running a few random one-file demos...

http://www.youtube.com/watch?v=00kYghjobfU
 
... 14 posts hidden. Click here to view all posts....
 
2012-11-16 20:48
logikstate
Account closed

Registered: Jan 2011
Posts: 21
OK, hardware breakpoints (or actually, in reality, hardware Action Replay FreezePoints) are working now...

However, the freeze occurs after the instruction has been fetched and executed via the CPU. i.e if I set a breakpoint to softpress the freeze button of the AR at 0xc000, when I freeze and look in the AR monitor I am at 0xc003 with a 3 byte instruction at 0xc000.

Reading up a little on CodeBase64 I find this :
http://codebase64.org/doku.php?id=base:6510_instruction_timing

"The processor will usually wait for the current instruction to complete before executing the interrupt sequence. To process the interrupt before the next instruction, the interrupt must occur before the last cycle of the current instruction."

I am currently freezing when the address is on the bus and the clock is on rising edge... So at that point the instruction fetch has been started...

So, freezing after the current instruction is read. Is this the best I am going to get? Or is there a better way?

<edit>
I've just realised that I can alter the CPLD to put a NOP on the bus at the address of the breakpoint... This should do what I need! :)
2012-11-25 20:12
Karoshier
Account closed

Registered: May 2010
Posts: 15
Wow, I would really love to have such an advanced development environment. Please keep up the good work. I would be more than happy to buy an EF3 for that purpose.
One question though: you are talking about "freezepoint" and if I remember correctly, the AR freezepoint is actually modifying your code to make a call to $DFD3. Now this involves having in memory the bytes $20 $D3 $DF. The 6510 will fetch all three bytes and make a call to that address, at which point you will sense that the 6510 requests a read at $DFD3 and freeze the machine. If you put a NOP on the bus at this point, then the next instruction will execute at $DFD4. Shouldn't you rather put $60 (RTS) on the bus? In this case, doing an LDA $DFD3 would also freeze the machine, and you don't actually have to care about what you put on the bus in that case. Or maybe have I misunderstood the way you have implemented the thing?
2012-11-26 10:43
logikstate
Account closed

Registered: Jan 2011
Posts: 21
You misunderstand. I've created a new register that watches for the CPU accessing a certain address... This can be any address which is normally seen on the cartridge port expansion bus... When this address is reached the cartridge soft-presses the freeze button and enters freeze mode.

However, because the instruction fetch has already started the freeze doesnt happen until after that instruction has been executed.

So, for example... a 3 byte instruction at 0xc000 will leave the pc at 0xc003 once the soft freeze has happened.

I do not want to insert code to freeze, I am sniffing the bus and freezing without modifiying any instructions.

What I would like to achieve is swapping out the byte at 0xc000 with a nop, so the instruction isnt executed and then rewinding the PC counter by 1 from 0xc001 in the freezer.

However, my hardware knowledge is fairly limited... As far as I can tell this is possible using the same trick that Skoe uses to switch in the external kernal imagine.

Alas, so far my tinkering has failed to achieve this... Maybe Skoe could shed some light on this?
2012-11-27 10:35
Karoshier
Account closed

Registered: May 2010
Posts: 15
I see. Now I get it. Sorry.

I find your idea great for stepping through the code and update watches in the debugger at the same time, which is IMHO one of the most useful features ever. In that case personally I wouldn't have a problem knowing that the instruction shown on screen has already been executed.

But we're talking about not having that instruction executed.
The only way I see to be able to do this is to switch Ultimax mode in, on the fly, so that the RAM/ROM where the CPU is executing code will not be chip-selected. And I guess this is the trick that is used to swap in the replacement kernel and basic, as you can legally provide them both from the cart in this case.
Since most RAM blocks are also "open" in this case, you can talk on the bus in place of the RAM as well to say $EA. But this has limitations.
* Accesses from $0000 to $0FFF will still be directed to motherboard RAM
* Accesses from $D000 to $DFFF will still be directed to the I/O block
In the above two cases therefore you cannot talk onto the bus.
Unless, that is, there exists some trick to overcome these two limitations. Personally I don't know any.

Let's also not forget that Peddle has implemented a rudimentary "pipelining": the CPU starts fetching the next instruction before the previous one has completed execution! I don't have enough knowledge on this, so this might have a good or bad effect on your results which I cannot predict. Michael Steil and the guys at visual6502.org know better on this.

The Chameleon guys do have their own soft 6510 (the one on the motherboard is permanently disabled), which should be much easier to stop and inspect at will, but as far as I understand their FPGA code is not public except for a basic framework with its test application.

If you DMA a JSR$DFD3 to RAM instead (using the RAM FREE mode), you can freeze anywhere you wish as long as the I/O area is enabled (where you have two open pages from $DE00 to $DFFF where you can provide your own code freely). One of the things the original AR does when a freezepoint is hit, is to restore the original data that the JSR$DFD3 has overwritten and then alter the stack so that an RTS will resume execution as if nothing happened. And this is easy to do with the 6510 code placed at $DFD3. The kernel and basic ROMs can be freezepointed in the same way using the ultimax mode.
2012-11-27 11:23
logikstate
Account closed

Registered: Jan 2011
Posts: 21
Actually, re-reading this doc I see that Skoe also mentions that the cartridge is using Ultimax mode to switch the external kernal in : http://skoe.de/kernal/kernal-cartridge.pdf

This must be what I am missing... I will look over the VHDL code again and see if I can now get the $EA byte on the bus.

Not being able to manipulate the bus from $0000->$0fff is not *too* much of a limitation I guess... A small price to pay for being able to otherwise have full control over the machine. The freezepoint would still work, just one instruction later than intended.

I also have a Chameleon cartridge. Once I had made enough progress with this I was aiming to talk to those guys. It would be fairly easy for them to add the needed functionality to talk over the USB cable that comes with the cartridge.

The Chameleon USB cable can already read/write memory to/from the C64 so the base functionality is there already.
2012-11-27 12:10
logikstate
Account closed

Registered: Jan 2011
Posts: 21
I'm no expert, but reading over that doc again, it seems to suggest that there is a trick with using the DMA line to then alter whatever is on the bus before the data is read?
2012-11-27 19:06
Karoshier
Account closed

Registered: May 2010
Posts: 15
Thanks for the link to the document! It contains information I missed.
As far as I undestand, the document describes a neat way to get around the problem of not knowing from the cartridge side when the kernal is read, instead of the RAM, by the CPU, thereby being able to switch to ultimax mode at the right time to replace just the kernel (whose replacement is only possible in ultimax mode).
As you already said, $0000-$0FFF and $D000-$DFFF areas can still be breakpointed, but one instruction later. I agree that this is already better than nothing, but wouldn't all this address checking add to the footprint you need in the FPGA? Plus, wouldn't this discrepancy be confusing to the user?
2012-11-27 19:27
logikstate
Account closed

Registered: Jan 2011
Posts: 21
The footprint is already full to overflowing and I've had to remove some functionality... At the moment, just support for nordic power cartridge... and the button press logic.

Consider a "developer" edition of the CPLD and a "consumer" edition.

As it stands, I have this working, including the soft freeze but there isnt enough logic to make the buttons function... However, I believe its possible to simplify some other logic and also remove C128 support to simplify this down a little.

First things first though, I would like to get this NOP byte on the bus. At that point I think it could be considered proof of concept and we can look at how this might move forwards.

There are probably ways to simplify getting the NOP on the bus too once that is working.
2012-11-27 20:05
Karoshier
Account closed

Registered: May 2010
Posts: 15
WOW! Cool. Keep us posted on the progress, please.
Unfortunately I don't have an EF3 (yet), but if there's any 6510 code or hardware thing I can help with...
2012-11-28 14:01
logikstate
Account closed

Registered: Jan 2011
Posts: 21
Hang on.

I think I've been trying to be far too clever with this. There is no need for me to put a NOP on the bus at all.

All I need to do is set the freezepoint register... physically alter the byte in RAM at that address to be NOP and then restore it again when the freeze is hit and rewind the PC counter by 1 byte.

This then allows for HW freezepoints at any address in RAM with a 1 byte instruction (NOP) and doesnt rely on any jump vectors or even the kernal to be present.

Problem solved!
Previous - 1 | 2 | 3 - Next
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
Darkflight
LordCrass
Freeze/Blazon
Didi/Laxity
Guests online: 76
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 Edge of Disgrace  (9.6)
6 What Is The Matrix 2  (9.6)
7 The Demo Coder  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 No Listen  (9.6)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 Dawnfall V1.1  (9.5)
7 Rainbow Connection  (9.5)
8 Onscreen 5k  (9.5)
9 Morph  (9.5)
10 Libertongo  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Triad  (9.3)
5 Censor Design  (9.3)
Top Diskmag Editors
1 Magic  (9.8)
2 hedning  (9.6)
3 Jazzcat  (9.5)
4 Elwix  (9.1)
5 Remix  (9.1)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.039 sec.