| |
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.... |
| |
logikstate Account closed
Registered: Jan 2011 Posts: 21 |
Quote: Ah, nice idea :)
Erm. Are you the one who wrote a mail to me a few months ago which I missed to respond to?
Yes indeed.. that was me :)
As you didn't reply I took it upon myself to experiment... I have no background in electronics or VHDL... After a few false starts I figured out the logic needed to do the freeze as I imagined it to be possible. So this can be considered a 'proof of concept'
As far as VHDL HW breakpoints (or I guess Action Replay freezepoints) This is something that is a little beyond my knowledge at the moment... I had to remove the SS5 logic in order to make this fit, even though it was just a few changes.
Any help or advice on this would be appreciated :) |
| |
Skoe Account closed
Registered: Jan 2008 Posts: 34 |
Arrgh! I actually had something to write to you. As I was quite busy (and lazy...) I deferred the response. And a while later I didn't find the mail again and couldn't remember the sender. Shame on me!
Could you resend it please? :)
Because last year I started something you could be interested in. And I'm interested in your ideas. |
| |
logikstate Account closed
Registered: Jan 2011 Posts: 21 |
Quote: Arrgh! I actually had something to write to you. As I was quite busy (and lazy...) I deferred the response. And a while later I didn't find the mail again and couldn't remember the sender. Shame on me!
Could you resend it please? :)
Because last year I started something you could be interested in. And I'm interested in your ideas.
I've resent the original email and also PM'd you my personal email address, thanks!
|
| |
logikstate Account closed
Registered: Jan 2011 Posts: 21 |
Gah! Have made some progress with HW breakpoints but there isn't enough space on the CPLD... Some rethinking is needed... |
| |
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! :) |
| |
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? |
| |
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?
|
| |
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.
|
| |
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. |
| |
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? |
Previous - 1 | 2 | 3 - Next |