Comments

Cluso and I have an extension of about another 12-15 hours from now to finalize the ROM code since Monday is a holiday in the US. If you are able to test ROM code using the loadable ROM FPGA version on the 123-A9 or CVA9 then this is perhaps the last chance to give this code a good bash. I will be checking timing this morning and working out with Ray how to improve the boot and load speed. I will also be adding a few extras to TAQOZ to do with file handling as it is easy enough to have a simple file renaming word as well as generalize some of the other words to be SD virtual memory aware. Even now, if I want to list a file after it is opened all I need to do is type "0 SD PRINT$" and so it uses address 0 in SD virtual memory offset from the opened file as 4GB of virtual memory and prints the file as if it were one giant string, even up to 4GB.

We all are deeply interested in P2 so even if you can't test the ROM perhaps you could load the latest taqoz32k.spin2 into any current P2 FPGA and try it out as it only needs 32k and 1 cog, no cordic (but I do need to update it so let me know). The latest P2 rom code is built from includes files as p2rom.spin2 in the P2 BOOT folder so you can use that if you test it. There's even the new PNut v32J in there too which does not have the 1024 DAT symbol limit and even though I am using p2asm as part of my build I do use PNut every so often and as a final check just in case although I may do some binary comparisons of the output to provide feedback to @Dave Hein on his excellent work on p2gcc tools.p2rom.spin2P2 BOOT folder

Ray is testing improved timings to speed up not only SD boot fail detection but also loading memory. I'm just doing overall testing and checking the timings on the scope and LA. There are a couple more features that I will put into TAQOZ but we only have about another 5 hours or so before Chip gets up again and calls us as he needs the ROM ready to send to onsemi.

Would somebody like to do a useful program to put into Flash that we can test? It needs a two-stage loader and if I have time I will load taqoz32k up with the first stage loader and make sure it boots. Chip will develop the tools later on that will allow the Flash to be loaded transparently with the 1st stage loader and user code, but at the moment they don't exist.

Here is a scope capture (a bit easier to see than the detailed LA capture) of the boot pins with an SPI Flash present which is loaded but has no boot code, which then causes the SD to be checked and loaded. The boot image is actually the 32K binary for the TAQOZ32k RAM version.
You can see the CS being clocked initially because this is the clock for the SPI Flash but after Chip's booter determines that it doesn't actually have a valid boot image it then passes over to Cluso's code which senses the card's internal pull-up on the SD chip select (=SPI Flash clock) and proceeds to initialize the card and towards the last 200ms or so you can see MISO being quite active as the image is read in to hub RAM.

BTW, for these tests I made sure that the card came up in a power-up state by powering the SD from an LDO with its active low shutdown pin connected to my reset switch. This simulates power-up since the FPGA is already powered up and has its P2 configuration active, ready to go.

For reference here is the first 200ms or so of the LA capture which shows the reset which also corresponds to the SD Vdd which simulates power-up. There's about 6ms before things start to happen after reset.

For those who are curious, here is my test setup with a breakout mounted onto a BeMicroCV-A9. The SPI Flash is mounted on a module above the SD that I can unplug for testing and the boot pins are buffered by a HC245 since the LA probes appear as a pull-down during P2's boot. The reset switch is debounced but also fed into the shutdown pin of a tiny TC1184 SOT-23 LDO regulator that feeds the SD power. The socket that connects to the FPGA has long pins that can be probed on the top of the breakout as well as 4 LEDs that can be jumpered across to anywhere. The SD pin headers where the probes and other modules are plugged in were initially uncommitted and jumpered to different pins for early testing but later on they were soldered directly to P58..P61.

If you want to be able to test SD cards on your board but don't have an SD socket or breakout, be mindful that the most microSD cards come with an adapter that you can solder to directly. All you need are 6 wires, gently solder the cable from your board to the back of the adapter but keep the cable short (<6") and solder a 1 to 10uF cap across the middle supply pins.

Alternatively you can glue the adapter upside down onto your board or somewhere with the contacts facing out (and card accessible) and run your wires from this. I've never had to do this but that is exactly what I would do if I had to but I can do one just for the exercise I suppose.

More alternatives:
0.1" Card edge connector socket - I have plugged cards directly into these before - it works.
0.1" Header pins or socket - solder directly to the adapter and you can plug it into your board.

EDIT:
Even though I'm going out I took 3 minutes to solder a socket to a microSD card adapter so that it will plug into a pin header. I will try it out later on when I get back. Hint - I squirted a little flux onto each contact to help the solder flow.

If you want to be able to test SD cards on your board but don't have an SD socket or breakout, be mindful that the most microSD cards come with an adapter that you can solder to directly. All you need are 6 wires, gently solder the cable from your board to the back of the adapter but keep the cable short (<6") and solder a 1 to 10uF cap across the middle supply pins.

For older people who have some 5 1/4 floppy ribbons from the past they can just use one of them. The SD (or microSD with SD adaptor) just fits fine into the card edge connector.

The addresses in the CON blocks are from an old revision now. They need to be updated.

Maybe it would be better to have an array of relative JMP instructions at the base of the monitor source so the addresses don't change every time the code is updated?

That's a more usual approach, tho it does cost a little bit more code.
The ROM itself is unlikely to move about, but it is quite possible 'ROM patches' are released, to fix bugs/updates in the ROM itself, and I believe a larger TAQOZ was also planned.

The addresses in the CON blocks are from an old revision now. They need to be updated.

Maybe it would be better to have an array of relative JMP instructions at the base of the monitor source so the addresses don't change every time the code is updated?

That's a more usual approach, tho it does cost a little bit more code.
The ROM itself is unlikely to move about, but it is quite possible 'ROM patches' are released, to fix bugs/updates in the ROM itself, and I believe a larger TAQOZ was also planned.

It's also possible that later versions of the chip could have updated ROMs. Seems like a better approach to have a jump table so the entry points are fixed.

The addresses in the CON blocks are from an old revision now. They need to be updated.

Maybe it would be better to have an array of relative JMP instructions at the base of the monitor source so the addresses don't change every time the code is updated?

Well, if you looked some years ago when I first did the Monitor, that's precisely what I had.
Alas, there was no spare space, and so the jump table was removed, along with the help command, and some other features too. It was only at the end that we achieved ~40 bytes. I know 60 was mentioned but I am fairly sure I saw about up to $FFFD6 was used.

I have been pretty busy catching up on everything I didn't do while working on the ROM code.

re Baud

The Monitor/Serial/TAQOZ when initially called from the booter, will use whatever autobaud has been sensed. If the clock has been changed by a "Prop-Clk" command, that will be honoured too.

For using my Serial at another baud, it's just a matter of presetting the parameter before calling the Initialisation routine's secondary entry point. That can be done for most parameters, including where the hub buffer is for reading sectors or loading files.

The addresses in the CON blocks are from an old revision now. They need to be updated.

Maybe it would be better to have an array of relative JMP instructions at the base of the monitor source so the addresses don't change every time the code is updated?

Well, if you looked some years ago when I first did the Monitor, that's precisely what I had.
Alas, there was no spare space, and so the jump table was removed, along with the help command, and some other features too. It was only at the end that we achieved ~40 bytes. I know 60 was mentioned but I am fairly sure I saw about up to $FFFD6 was used.

I guess it's better to have the added functionality than the JMP table.

In this case, since it's copied the ram, the table would be nice for adding hooks into things, but that can still be done, it's just a little harder. No big loss.

Really, you don't need the ROM code after boot anyway. You can always link in code that does the same thing. It would have been nice to have a standard set of functions for things like serial, SPI, and SD access but it's not a huge loss.

That's going to get done with an overlay after boot. What we've got here is, basic exploration why didn't it boot, and a few other tools one might need early on. The moment that has passed, a standard thing can be loaded and probably will be.

In my P1 OS I have to load them into upper HUB RAM first. They stay resident between OS programs that use them. Programs like DIR, LS, COPY, PROGRAM (eeprom), etc. However, user programs are not aware of the OS routines and so need to be reloaded again when the user program terminates. The user can write OS aware programs, and of course use the routines.

The mains part of the Monitor is the Serial support routines. Calls such as sending characters, printing a byte/long/word in HEX, with optional number of digits, reversal, and byte spacing, printing zero-terminates strings, the basic things such as printing a CR+LF, plus LIST/DUMP of COG/LUT/HUB. Reading includes reading a character, and reading a string which converts the CR into a zero-terminated string and includes backspace correction, plus downloading/storing to COG/LUT/HUB.
The Monitor just adds a layer on top of these routines to make them interactive, and includes access to the higher level SD routines such as LOAD and RUN FILE.
Access to the other lower level SD routines are also available, but require setting things such as sector addresses, lengths, and calling the routine(s) using the GOSUB command.

All the Serial and all SD routines, plus the Monitor, can all be called from the user program, without the need to compile or load them.

So, basically we have an almost complete FullDuplexSerial object in ROM and able to be called by the user program. Provided half-duplex is ok (there is no read buffering until the program calls the read routines), then it's all done for you in the same COG.

TAQOZ, SD, the Monitor and Serial are not afterthoughts. We have used them on the P1 for years. They just had to be squeezed into the ROM space, and we basically only had a few weeks to get it done properly.