REV A P2 Edge booting from flash possible?
rogloh
Posts: 6,410
Hi,
First time I've tried it on this board but am having problems booting an old REV-A P2-Edge board from flash. I can see the flash from my app when loaded and running from a RAM download and I can also write to it with loadp2 but it refuses to boot from flash for some reason.
I've got the pull up and down icon dip switches both set off, and flash enabled (serial + flash boot). Won't boot my app from flash. Also tried with the up dip switch disabled and down enabled (flash only boot), with the same result.
I measured P59 resistance to ground (out of circuit) being 10k when the down dip switch is enabled and 14Meg when disabled so I think the DIP switch is working. Measured P61 (flash CS) to be 300k to ground and 10k to the V56 IO pad.
I'm now wondering if there was some known issue in the early boards? Or perhaps there is a problem with my app - but it seems fine when loaded to RAM. I'll pare it down to just toggling a LED and try that too but I suspect it'll be the same. My current binary app image size is about 330kB so I know it fits.
I'm using loadp2 rev 0.77 to flash the P2-Edge with these settings.
loadp2 -t -flash xxx.binary
I know loadp can write to the flash as I also share the upper flash with data and I can see that data in flash if the app is run from RAM.
My RAM load works when I flashed the upper filesystem data at 1MB offset, but the boot from flash seems to fail. Also tried this out...
loadp2 -t -HIMEM=flash @0=z80.binary,@80000000=z80.binary,@80100000=/Users/roger/z80fs.bin
For testing I wrote a simple flash sector dump app which I loaded to RAM and can see my app in FLASH sitting at sector 2 onwards - sector 0 and 1 seem to have a small initial 1kB bootloader written to it which reads in the remaining app code starting from the 1kB offset in flash:
Sector 0 08 00 90 FD FC C2 47 EA 9C 43 05 00 3C 94 0C FC ......G..C..<... 50 78 64 FD 3C 02 1C FC 58 78 64 FD 1D 32 60 FD Pxd.<...Xxd..2`. 00 00 8C FC 0A 00 CC F9 02 00 20 F3 00 04 80 F1 ................ 05 00 64 F0 00 34 20 F9 01 00 64 F0 3C 00 24 FC ..d..4....d.<.$. 1F 06 64 FD 00 34 A4 FC 24 36 60 FD F5 05 9C FB ..d..4..$6`..... 50 F4 65 FD 3C 00 0C FC 42 0F 80 FF 1F 00 65 FD P.e.<...B.....e. 00 00 EC FC 00 00 00 40 00 00 F5 C0 00 00 00 00 .......@........ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ... Sector 2 00 00 00 00 01 EC 63 FD 02 00 00 FF 04 EC E7 FC ......c......... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
What am I missing? It has been a while since I tried flashing something on a P2 so perhaps I have forgotten something simple and I'm just doing something dumb, or maybe REV A flash booting is problematic...?
Could it be some initial clock setting that is normally patched by loadp2 or something like that? My flexspin based app does have _clkfreq set to 270000000, but no explicit CLKMODE setup otherwise. Although I didn't think it really patched the settings unless -PATCH option was applied anyway.

Comments
Ok, so it turns out that this LED test did boot from flash when I flashed it using this command:
loadp2 -FLASH ledflash.binaryso perhaps my 330kB is too big for reliable serial downloading, or perhaps there is a bad sector somewhere in the flash...hope not. I guess I'll try to add a CRC check or read back all the sectors and manually compare the source binary.
CON _clkfreq = 100000000 PUB main() repeat waitms(1000) pintoggle(56)I should also mention: I tried the app boot test after first removing the PropPlug (in case that was holding down reset) and then re-powering the P2-Edge, but always get the same problem with my main app not starting up.
I've never used the multipart bundling let alone also burning it to flash. EDIT: Oh, oops, that was an alternate.
Ah-ha! The -FLASH option has to be all caps! I guess all of Loadp2's options are case sensitive then.
Verbose without -FLASH option:
Verbose with -FLASH option:
I get this output with verbose enabled:
Just ran this simple total byte sum test on the binary stored in flash. Doesn't look like there is a problem with the flash contents itself unless the initial loader is getting rejected by the P2 boot process.
CON _clkfreq = 100000000 OBJ f:"ers_fmt" uart:"SmartSerial" flash:"SpiFlash" PUB main() uart.start(115200) send:=@uart.tx send("checksum=",f.dec(checksum()),13,10) repeat PUB checksum() :sum | i sum:=0 repeat i from 1024 to $54567+1024 if (i//512 == 0) flash.read(@buffer, i,512) sum+=buffer[(i & $1ff)] DAT buffer byte 0[512]Result was this:
❯ loadp2 -t reader.binary
( Entering terminal mode. Press Ctrl-] or Ctrl-Z to exit. )
checksum=40231575
Did the same computation over binary file with this same result
od -v -An -tu1 z80.binary | awk '{for(i=1;i<=NF;i++) sum+=$i} END {print sum}'40231575Doesn't the first 1kB loaded need to sum to the 32 bit value of "Prop" or something like that for the P2 to boot from flash? I guess I can check that too...
Something very weird about loadp2 and the -FLASH option. I see some of this code sitting in the first sector but it doesn't seem to contain the "app_longs" value which is meant to be set by the programmer. Why is this value missing? What am I doing wrong on the command line ? @ersmith do you know? None of the longs after the "wmode" value seem to be present there. Isn't loadp2 meant to fill this in for us? EDIT: Ok I found this sector code is actually from flash_stub.spin2 and not flash_loader.spin2.
Here's the loader code from what I can tell...EDIT: no this is the loader code from the programmer (see post below).
' On entry, both spi_cs and spi_ck are low outputs and the flash is outputting bit 7 of the ' byte at address $400 on spi_do. By cycling spi_ck, any additional application data can be ' received from spi_do. ' ' Once all application data is in the hub, an application checksum is verified, after which ' cog 0 is restarted by a 'COGINIT #0,#$00000' to execute the application. If that checksum ' fails, due to some data corruption, the SPI pins will be floated and the clock stopped ' until the next reset. As well, a checksum is verified upon initial download of all data, ' before programming the flash. This all ensures that no errant application code will boot. ' org ' ' ' First, move application data in cog app_start..$0FF into hub $00000+ ' loader setq #$100-app_start-1 'move code from cog app_start..$0FF to hub $00000+ wrlong app_start,#0 sub app_longs,#$100-app_start wcz 'if app longs met or exceeded, run application if_be coginit #0,#$00000 '(small applications verified by 'Prop' checksum) ' ' ' Read in remaining application longs ' wrpin #%01_00101_0,#spi_ck 'set spi_ck smart pin for transitions, drives low fltl #spi_ck 'reset smart pin wxpin #1,#spi_ck 'set transition timebase to clk/1 drvl #spi_ck 'enable smart pin setxfrq clk2 'set streamer rate to clk/2 wrfast #0,##$400-app_start*4 'ready to write to hub at application continuation .block bmask x,#10 'try max streamer block size for longs ($7FF) fle x,app_longs 'limit to number of longs left sub app_longs,x 'update number of longs left shl x,#5 'get number of bits setword wmode,x,#0 'insert into streamer command shl x,#1 'double for number of spi_ck transitions wypin x,#spi_ck '2 start spi_ck transitions waitx #3 '2+3 align spi_ck transitions with spi_do sampling xinit wmode,#0 '2 start inputting spi_do bits to hub, bytes-msb-first waitxfi '? wait for streamer to finish tjnz app_longs,#.block 'if more longs left, read another block wrpin #0,#spi_ck 'clear spi_ck smart pin mode ' ' ' Verify application checksum ' rdfast #0,#0 'sum all application longs rep #2,app_longs2 rflong x add app_sum,x wz 'z=1 if verified stop if_nz fltl #spi_di addpins 2 'if checksum failed, float spi_cs/spi_ck/spi_di pins if_nz hubset #%0010 '..and stop clock until next reset coginit #0,#$00000 'checksum verified, run application ' ' ' Data ' clk2 long $4000_0000 'clk/2 nco value for streamer wmode long $C081_0000 + spi_do<<17 'streamer mode, 1-pin input, bytes-msb-first, bytes to hub zeroa '(used by programmer as long 0) app_longs long 0 'number of longs in application (set by programmer) zerob '(used by programmer as long 0) app_longs2 long 0 'number of longs in application (set by programmer) zeroc '(used by programmer as long 0) app_sum long 0 '-sum of application longs (set by programmer) x '(used by loader as variable) loader_sum byte -"P",!"r",!"o",!"p" '"Prop" - sum of $100 loader longs (set by programmer) ' ' ' Application start ' app_start 'append application bytes after this label@evanh is your loadp2 flash_stub.h file in the loadp2 root folder area the same as this? I wonder if mine is somehow corrupted? This file is generated when I build loadp2 source.
unsigned char flash_stub_bin[] = {
0x08, 0x00, 0x90, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x94, 0x0c, 0xfc, 0x50, 0x78, 0x64, 0xfd, 0x3c, 0x02, 0x1c, 0xfc,
0x58, 0x78, 0x64, 0xfd, 0x1d, 0x32, 0x60, 0xfd, 0x00, 0x00, 0x8c, 0xfc,
0x0a, 0x00, 0xcc, 0xf9, 0x02, 0x00, 0x20, 0xf3, 0x00, 0x04, 0x80, 0xf1,
0x05, 0x00, 0x64, 0xf0, 0x00, 0x34, 0x20, 0xf9, 0x01, 0x00, 0x64, 0xf0,
0x3c, 0x00, 0x24, 0xfc, 0x1f, 0x06, 0x64, 0xfd, 0x00, 0x34, 0xa4, 0xfc,
0x24, 0x36, 0x60, 0xfd, 0xf5, 0x05, 0x9c, 0xfb, 0x50, 0xf4, 0x65, 0xfd,
0x3c, 0x00, 0x0c, 0xfc, 0x42, 0x0f, 0x80, 0xff, 0x1f, 0x00, 0x65, 0xfd,
0x00, 0x00, 0xec, 0xfc, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf5, 0xc0
};
unsigned int flash_stub_bin_len = 108;
Update:
Okay now I'm more confused than before. There seems to be two different flash loaders. One seems to be bundled with some programming code (flash_loader.spin2), and the other is standalone (flash_stub.spin2). The latter is what is in my flash by the looks of it.
Update2: I checked the total 32 bit sum of the first 1kB in flash. Results in
checksum=706F7250which is "Prop" so it look like the P2 should boot this. Starting to wonder if maybe my own app is somehow locking up if flash is already enabled after boot or something like that since it also uses flash. I'm going to try modifying it to not read flash and just blink a LED instead like that other short test app I wrote.Update3: Nope, disabling flash in my app doesn't help. Still no boot. I'm at a loss now. Power draw from flash boot perhaps...?
After it is built I manually copy the resulting binary "loadp2" into a stand-alone directory in my exec path. Nothing else is copied from the build and the build directory is ignored after. I only look at again when updating with
git pull. Last build was August 2025, v0.077.Content of flash_stub.h
unsigned char flash_stub_bin[] = { 0x08, 0x00, 0x90, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x94, 0x0c, 0xfc, 0x50, 0x78, 0x64, 0xfd, 0x3c, 0x02, 0x1c, 0xfc, 0x58, 0x78, 0x64, 0xfd, 0x1d, 0x32, 0x60, 0xfd, 0x00, 0x00, 0x8c, 0xfc, 0x0a, 0x00, 0xcc, 0xf9, 0x02, 0x00, 0x20, 0xf3, 0x00, 0x04, 0x80, 0xf1, 0x05, 0x00, 0x64, 0xf0, 0x00, 0x34, 0x20, 0xf9, 0x01, 0x00, 0x64, 0xf0, 0x3c, 0x00, 0x24, 0xfc, 0x1f, 0x06, 0x64, 0xfd, 0x00, 0x34, 0xa4, 0xfc, 0x24, 0x36, 0x60, 0xfd, 0xf5, 0x05, 0x9c, 0xfb, 0x50, 0xf4, 0x65, 0xfd, 0x3c, 0x00, 0x0c, 0xfc, 0x42, 0x0f, 0x80, 0xff, 0x1f, 0x00, 0x65, 0xfd, 0x00, 0x00, 0xec, 0xfc, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xf5, 0xc0 }; unsigned int flash_stub_bin_len = 108;I think you've already figured this out, but for reference in case someone stumbles across this thread: the boot ROM will only boot the first $400 bytes of the flash, so in most cases that needs to contain a second stage boot loader. In loadp2 we have two variants of this second stage bootloader:
flash_loader.spin2is used to write the data if-FLASHand-SINGLEare both given, and it contains its own second stage boot stub confusingly also calledLoader(it's near the end offlash_loader.spin2). IIRC it's the old flash loader and was kept as a backup. For regular-FLASHwe prepend the stub inflash_stub.spin2to the binary and write it to flash usinghimem_flash.spin2, which is the new mechanism for writing stuff and is intended to be compatible with things like the hyperflash (although as yet there is nohimem_hyper.spin2). The himem mechanism is also used for loading ELF files to flash (or potentially to other kinds of external memory) for execute in place. At the moment AFAIK only the riscvp2 toolchain supports producing such ELF files.Thanks Eric. Good to know about -SINGLE selection.
Still having this issue. Decided to scope the flash clock pin to see what it is doing. Seeing some strange behavior.
Firstly I do see an initial burst of 8 bit transfers which would look like what the P2 is doing in its initial 1kB boot.
Then theres a short gap.
Then it transfers faster and continuously without byte gaps which appears to be the streamer clocking in the rest of the data according to the code in the loop in this snippet below from flash_stub.spin2. However the duration doesn't seem to make sense. When I zoom in on the individual clocks I see it doing one period in about 80ns (12.5MHz). The application is around 337kB or $54568 longs which was observed above in the 3rd long of the boot loader in sector 0.
EDIT: Ok, that's the issue then. $54568 is the long count being used, but this is a byte count of the application size, the long count should be 4x smaller! Bug in the flash loader/loadp2!
It should stop after 2763584 clocks or around 221msec. But I see it take a lot longer than that at over 800ms to complete according to the capture below. Why so slow/long? I know there'll be some other small gap per each $7ff longs, but it'll very very small and not contribute much. It's as if the loader thinks the application is 4 x larger than it is for some reason. (Confusing byte counts with longs perhaps?). If it keeps streaming maybe it overwraps the address in HUB and corrupts the application...? Pin transition mode should stop once it completes its transition count so that shouldn't be issue. There's also meant to be a small gap of 2M clocks or around 80ms before it starts the application so even if my application started using the flash itself soon after starting up, we should see a pause in the clock activity before then which was not observed.
wrpin #%01_00101_0,#spi_ck 'set spi_ck smart pin for transitions, drives low fltl #spi_ck 'reset smart pin wxpin #1,#spi_ck 'set transition timebase to clk/1 drvl #spi_ck 'enable smart pin setxfrq clk2 'set streamer rate to clk/2 wrfast #0,#0 'ready to write to hub at application start .block bmask x,#10 'try max streamer block size for longs ($7FF) fle x,app_longs 'limit to number of longs left sub app_longs,x 'update number of longs left shl x,#5 'get number of bits setword wmode,x,#0 'insert into streamer command shl x,#1 'double for number of spi_ck transitions wypin x,#spi_ck '2 start spi_ck transitions waitx #3 '2+3 align spi_ck transitions with spi_do sampling xinit wmode,#0 '2 start inputting spi_do bits to hub, bytes-msb-first waitxfi '? wait for streamer to finish tjnz app_longs,#.block 'if more longs left, read another block fltl #spi_do addpins 3 'float all pins wrpin #0,#spi_ck 'clear spi_ck smart pin mode waitx ##2_000_000 'pause a bit coginit #0,#$00000 'run applicationHuh, what a bug. No one else has had large binaries I guess. Ada may have at some stage but she ended up putting most of the binary onto the SD card and just had the FAT filesystem in EEPROM. EDIT: Err, no, the emulators are serial booted I believe.
I typically just use serial boot, yes. You can do whatever with them, they're just normal binaries.
I did notice an issue with large binaries not correctly flashing, but I was able to just sidestep it by using the --compress flag on the compiler, which naturally makes the binary smaller.
I imagine it's only going to be an issue if the code size is >256kB, that way it will wrap around at the 1MB point and start corrupting at zero (assuming the streamer reading into memory from 512k to 1MB is thrown away. I'll need to try to work on the boot flash code again to see if I can fix it. Early today I already tried changing the spin2 file by adding
shr app_longs, #2to divide by 4 and then recompiled loadp2 but that didn't seem to be enough as the sector 0 still had the same data in it and didn't contain the new instruction I added. This is what got built:❯ make
flexspin -2 -o flash_stub.bin flash_stub.spin2
Propeller Spin/PASM Compiler 'FlexSpin' (c) 2011-2026 Total Spectrum Software Inc. and contributors
Version 7.6.2 Compiled on: Mar 16 2026
flash_stub.spin2
flash_stub.spin2
Done.
Program size is 112 bytes
xxd -i flash_stub.bin flash_stub.h
gcc -Wall -Og -g -DMACOSX -o build/loadp2 loadp2.c loadelf.c osint_linux.c u9fs/u9fs.c u9fs/authnone.c u9fs/print.c u9fs/doprint.c u9fs/rune.c u9fs/fcallconv.c u9fs/dirmodeconv.c u9fs/convM2D.c u9fs/convS2M.c u9fs/convD2M.c u9fs/convM2S.c u9fs/readn.c
rm flash_stub.bin
Here's my change:
diff --git a/flash_stub.spin2 b/flash_stub.spin2 index a7d8991..78f0779 100644 --- a/flash_stub.spin2 +++ b/flash_stub.spin2 @@ -52,6 +52,7 @@ real_start wxpin #1,#spi_ck 'set transition timebase to clk/1 drvl #spi_ck 'enable smart pin + shr app_longs, #2 setxfrq clk2 'set streamer rate to clk/2 wrfast #0,#0 'ready to write to hub at application startbefore change flash content at sector 0 is:
after code change and re-flashing seems to be the same size and no new instruction got added. Weird.
Why not leave the bootloader alone and just fix it in the PC-side code?
(also, I think it'd have to be
(x+3)>>2so up to 3 trail bytes aren't eaten)UPDATE: Just retried this and it does seem to let me flash my image now. Must have missed a step earlier today. The fix is just the one line to divide by 4. Probably better to round up rather than shift right although I suspect most images will be aligned to longs. We could test the bottom two bits and add one long if either were set. RCZR is probably our friend here.
Yeah another way to go. @ersmith you may want to fix loadp2 according to this finding.
Now that flash is working I can finally boot my P2 application standalone! It's a Z80 emulator to play my old Microbee games (cycle accurate). Fits in the original case with same I/O ports as the original device had plus now includes the extra HDMI and USB port for a mouse if needed, or a USB keyboard or joystick, but my custom keyboard matrix with modern glorious keyswitches is also working
No more dodgy original switches. Flash contains a bootable CP/M filesystem, currently just read only but I might try Chip's filesystem to make it writeable (or have one read only drive so I don't lose anything and a separate writeable one).


Scambler, cool game!
I wonder what it'd take to add a filesystem to Flexspin.
I thought flexspin already has some support for one via FAT32 etc, maybe not from flash I guess. If you took Chip's code and merged to existing read/write/erase APIs, perhaps it's doable.
There is stuff there, including a copy of Chip's Flash FS. I just don't know how to use any of it. But I was mainly thinking about adding a CP/M FS on top of the plug-in block driver mechanism that FAT FS uses.
I didn't use it yet either. Seemed mostly complete though when I looked at it initially so hopefully it "just works". My application just reads/writes raw 512 byte sectors to/from HUB so it doesn't have to go through flexspin, it could probably talk directly through to Chip's object API and deal with erase as needed.
PRI readsector() | diskparams, block diskparams := long[@portdata][1] ' holds sector, track, disk block:= (diskparams & $1f) | ((diskparams >> 3) & $7fe0) 'r:=sd.readblock(block, @sdsector) flash.Read(@sdsector, FLASH_OFFSET+(block<<9), 512) DEBUG("read sector number ", UDEC_LONG(block)) byte[@portdata]:= 0 PRI writesector() | diskparams, block diskparams := long[@portdata][1] ' holds sector, track, disk block:= (diskparams & $1f) | ((diskparams >> 3) & $7fe0) DEBUG("write sector number ", UDEC_LONG(block)) ' r:=sd.writeblock(block, @sdsector) r:=0 byte[@portdata]:=r & $7fFlexspin is mainly about C Lib. If you're using Z80 assembly with incorporated FS then that doesn't really fit.
loadp2 was already rounding up the download size to a long word boundary, so we don't need to worry about trailing bytes. Nice catch, @rogloh. I've updated my loadp2 repository on github.
Thanks for that Eric. I grabbed your latest.
I also had a look at himem_flash.spin2 and I can see the intent of your initial framework that could eventually be used for different types of memory, such as HyperFlash. I was considering what else would be needed to make it work and found there is a small limitation in the setup API used today that would prevent a generic loader to work with that memory. We have no pin numbers being passed which is a problem as the HyperFlash devices could be connected on different pins, unlike the normal boot flash. We also may need some timing parameters passed for latency etc but given we run at ~24MHz at boot time we may be okay hard coding that.
We can probably also support HyperRAM and PSRAM loads this way also. 24MHz is a little slow for efficient transfers given the 4 or 8us maximum chip select window for the RAM variants but it should still be possible to get some data transfer done in each window. HyperFlash doesn't have this limitation IIRC. Main issue is still the pin allocation, which also varies slightly per memory type. It needs some sort of extra setup config file read in containing that information, or extra pin parameter passing from command line...? It'd be nice to not have to recompile loadp2 each time this changed so perhaps the command line method is easier for the user.