I've almost got the RPC library ready for release. It's all fit together so well. The first version won't have live interaction, merely "recording" of routine calls into a file that you then send to the NES to "replay" them. You can read things back from the NES though. The next version will have full interaction, where you can make calls and get data back interactively. The nice thing about the recording approach is that it gives more flexibility in how you get it to the NES, and is simpler to code for.
Memblers wrote:
EDIT - Sorry, nevermind what I said about the block size, I wasn't considering that it's only one block, heheh. Still seems a little odd, but any arbitrary amount is fine in that case.
Yeah, I guess the term "block" implies there's more than one. I guess I should avoid using that word.
See the
Design Rationale section of the specification for more about each decision. I've tried to examine every aspect of this and choose a design that's a best fit for them all.
Quote:
I've been thinking about this lately, about hooking this up on the expansion port version of my Squeedo board. Given the choice between synchronous SPI and async UART, I'm definitely going to try synchronous. What I'm hoping would work, is on MCU it could do an async bit-bang to be compatible with just the initial loader. After it gets the proper comms code loaded from that, then it should be OK to use any kind of hardware whatsoever, right?
Yeah. Once your code starts executing at address $0007, it's free to do whatever it wants. Of course if there's not the standard serial connection, the code won't be able to do that much.
I'm thinking a second level of loader is really needed, one that hides how serial transfer is done, etc. This boot loader is mainly meant to reduce the amount of code needed in ROM on a system with the D0-based serial connection. It's not suited for other connections to the PC.
Quote:
I guess my biggest concern (with my hardware as I imagine it), is wondering wtf happens if a controller is in port 2 at the same time the MCU (or anything for that matter) is bit-banging the same lines on the expansion port.. On the expansion port though it would be really easy to move to the other bits. I kind of wish the "standard" serial adapter didn't use D0. So I'll have to look for a work-around, probably.
One reason to use D0 is that every controller cable connects it. It's also easier to use for optimized serial code where it just does LSR $4017 to move the bit into carry. I'll have to think more about this, as you raise a good issue.
Quote:
Despite whatever issues I may or may not run into, a standard bootloader like this is a really great idea. I figured XMODEM would just be the standard
I had realized that XMODEM is meant for unreliable connections. At least here, 57600 has been very reliable, so error checking merely needs to catch that rare error (or bad cabling), rather than automatically retry.
The main goal of this boot loader was being really small yet still (optionally) robust. There could be a second level of loader that sits on this one, or is implemented directly by for example Squeedo, where you don't even have the first-level loader because you've got the space/easy reprogrammability. As long as you can bootstrap to a common environment, then it doesn't matter.
kyuusaku, heh, that's sort of like one of the send routines I have in the upcoming remote procedure call library. There's also an equivalent one that CRC-16s a byte as it's receiving another. Doing those in parallel is definitely the way to go.
EDIT: OK, I figured out how this fits in with Memblers' points about other hardware. I'll be adding this to the specification:
This boot loader is meant to allow control of a NES connected to the host via serial on the second controller port's D0 input. It isn't suitable for other host connection schemes, for example serial connected to a different input on the expansion connector.
Serial over D0 is very easy to wire up, since standard controller cables connect that pin, and the circuitry is just a few resistors and a transistor. The standard boot loader protocol allows it to be put on a cartridge easily, and it doesn't need to be updated, so the user doesn't need the ability to re-burn it. It could for example be included on homebrew cartridges as an extra feature. Anyone can build the serial cable, but getting the boot loader burned on a ROM is the biggest hurdle.
In normal use, a secondary loader will be sent, which then loads the actual program to be executed. The user doesn't directly write programs to send to the boot loader. This secondary loader can be implemented for other host connection cable types, so that the user has the same host tools regardless of the connection. This boot laoder thus is only used for those connected with the simple serial cable described here.
[the further loading might be handled by something like the upcoming RPC library, or perhaps something simpler]