Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 10:45 23 Apr 2026 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : PicoMite 6.03.00 betas

Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11224
Posted: 10:30am 22 Apr 2026
Copy link to clipboard 
Print this post

As recommended I'm updating the release to a full point recognising the amount of changes.

V6.03.00B0
PicoMiteRP2040V6.03.00B0.zip
PicoMiteRP2350V6.03.00B0.zip

Compared to version 6.02.02B8 the changes are as follows:

Various bug fixes and tweaks to the editor and filemanager in response to comments on this thread

Performance optimisation tools are now enabled on the PICO, PICORP2350, VGA, VGARP2350, HDMI and HDMIUSB builds
NB: Performance profiling is available on all builds
option-profiling-cache.pdf
 
USB versions have a new tweak. Plug in and remove a device like a keyboard with audio enabled and speakers connected.
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1853
Posted: 02:14pm 22 Apr 2026
Copy link to clipboard 
Print this post

Hmm, bit of a performance hit for me.

Just a bunch of:

cntr=cntr+1


In a do loop to see what was happening in the main code while running four PIDs.

Old firmware: ~162,000
New firmware: ~158,000
With new performance feature: ~126,000

This is the count value over a period of two seconds.
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 8773
Posted: 03:15pm 22 Apr 2026
Copy link to clipboard 
Print this post

Is it quicker than INC cntr [,increment] ?
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
javavi

Guru

Joined: 01/10/2023
Location: Ukraine
Posts: 548
Posted: 03:41pm 22 Apr 2026
Copy link to clipboard 
Print this post

@matherp
Testing the new PicoMiteRP2350VGAUSBV6.03.00B0
I again tested the ability to load firmware into a Pico connected via USB in boot mode.
When connected in boot mode, Pico is read as drive C:
I tried copying the Clear_Flash_RP2350.uf2 firmware there and it loaded and worked, clearing the connected Pico2.
Next, I tried to download other firmware using FM in the same way, and firmware up to 1 MB downloaded normally, but those that were larger did not download, which is strange.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11224
Posted: 04:03pm 22 Apr 2026
Copy link to clipboard 
Print this post

  Quote  Old firmware: ~162,000
New firmware: ~158,000


That is within the normal range for the effect of a different compilation on the cpu cache hit ratio.

  Quote  With new performance feature: ~126,000

Have you run with CACHE DEBUG ON and PROFILING ON? If it is a large program you need to tune which subroutines are included and make sure the number of cache slots specified aren't all used. This functionality isn't so easy to use. Simple programs like the bubble universe can see huge gains. I'm testing on the solar eclipse calculation. Normal run time 13.5 seconds, set cache on with no tuning 17.8 seconds and default no. of cache slots. Identify and cache key subroutines 10.9 seconds
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1853
Posted: 04:30pm 22 Apr 2026
Copy link to clipboard 
Print this post

  Mixtel90 said  Is it quicker than INC cntr [,increment] ?


Hi Mick. I always use Inc but in this case, I have four PID loops running @2ms with related code running in the interrupt callbacks.

I am only using the inefficient increment to deliberately load up what is happening outside of the interrupt. Pretty darned impressive. The Picomite is competitive with the TRIO MC308 and they don't have an onboard editor nor video  

Footnote added 2026-04-23 02:36 by PhenixRising
MC308 should have read MC403
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1853
Posted: 04:33pm 22 Apr 2026
Copy link to clipboard 
Print this post

  matherp said  
  Quote  Old firmware: ~162,000
New firmware: ~158,000


That is within the normal range for the effect of a different compilation on the cpu cache hit ratio.

  Quote  With new performance feature: ~126,000

Have you run with CACHE DEBUG ON and PROFILING ON? If it is a large program you need to tune which subroutines are included and make sure the number of cache slots specified aren't all used. This functionality isn't so easy to use. Simple programs like the bubble universe can see huge gains. I'm testing on the solar eclipse calculation. Normal run time 13.5 seconds, set cache on with no tuning 17.8 seconds and default no. of cache slots. Identify and cache key subroutines 10.9 seconds


One of those things where I quickly checked TBS before I drove off. I ran back inside for a quick test. Will be back there in an hour or so  
 
Bleep
Guru

Joined: 09/01/2022
Location: United Kingdom
Posts: 789
Posted: 04:45pm 22 Apr 2026
Copy link to clipboard 
Print this post

Hi Peter,
I think I've found a bug.
If I use
'Option Tracecache on 16
Dim Integer maxst=1000:c=42
c=c*(c<=maxst)    'If c>maxst Then c=0
Print c
End

c is printed as 42, if I remove the comment for Option Trace Cache, c is printed as -42? If I set c to 1001, then in both cases c is printed as 0, which is fine.
Kevin.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11224
Posted: 05:10pm 22 Apr 2026
Copy link to clipboard 
Print this post

Good catch, Conditionals in LET statements aren't currently implemented so either, it should be, or the line should fail compilation and run normally. Will fix one way or the other in the next beta
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11224
Posted: 05:37pm 22 Apr 2026
Copy link to clipboard 
Print this post

For javavi

ME:
  Quote  A user is using the HDMIUSB variant of the firmware. He has connected a second Pico in USB boot mode where it appears as a C: drive. He can copy uf2 files to the second Pico successfully as long as they are less than 1MB (1024x1024) and the second pico then reboots and appears as a cdc device as expected. Above 1MB the uf2 files do not copy successfully. Can you identify any reason for this.

CLAUDE:
  Quote  The root cause is in the interaction between FatFS's FAT window mechanism and the RP2040 bootrom's virtual FAT disk.

Root cause: FatFS FAT-window vs. RP2040 bootrom's non-persistent FAT
How the RP2040 bootrom handles writes
The RP2040 in BOOTSEL mode presents a virtual FAT16 disk. When it receives USB MSC sector writes:

If the sector contains a valid UF2 magic (0x0A324655 / 0x9E5D5157): the payload is extracted and programmed to flash.
Any other sector write (including FAT, directory, BPB): silently discarded — the bootrom has no backing store for them.
The bootrom always returns the original, read-only FAT when those sectors are read back.

FatFS uses a single-sector FAT window
In ff.c, move_window() keeps exactly one 512-byte sector of the FAT in fs->win[]:


static FRESULT move_window(FATFS* fs, LBA_t sect)
{
   if (sect != fs->winsect) {
       res = sync_window(fs);          // flush current window → WRITTEN TO DISK
       disk_read(fs->pdrv, fs->win, sect, 1);  // load new sector ← READ FROM DISK
       fs->winsect = sect;
   }
}
Each FAT sector holds 256 FAT16 entries (512 bytes ÷ 2 bytes/entry).

The 1 MB boundary
The RP2040 bootrom's 128 MB virtual disk uses 4 KB clusters (8 sectors/cluster — the only cluster size that fits ≤65524 clusters into a 128 MB FAT16 volume). One FAT sector therefore covers:


256 clusters × 4096 bytes/cluster = 1,048,576 bytes = 1 MB exactly
For files ≤ 1 MB (≤ 256 clusters): all cluster-chain entries live in FAT sector 1. FatFS keeps it in win[] throughout the write and never needs to swap the window. The FAT flush happens only at f_close(), by which time every UF2 block has already been written to the data area and processed by the bootrom. Result: success.

For files > 1 MB (> 256 clusters): FatFS needs FAT sector 2 for clusters 256+. move_window() flushes FAT sector 1 to disk (bootrom discards it) and reads FAT sector 2. Later, when it needs to write the cluster 255→256 chain link (which straddles the sector boundary), it swaps back to FAT sector 1 — and reads the original all-free data. FatFS now believes clusters 2-255 are free and tries to re-allocate them, overwriting data sectors or corrupting the chain. Result: failure.

Secondary confirmation
You can verify the cluster size yourself. Sector 0 of the C: drive is the BPB. Byte offset 13 (0x0D) is BPB_SecPerClus. If it reads 8, cluster size = 4096 bytes and the analysis above is exact.

Fix
The FatFS layer is the wrong tool for writing to an RP2040 boot drive: the bootrom ignores FAT structure entirely. The correct approach is to bypass FatFS for this transfer:

Read the UF2 source file from SD card normally with f_read.
Write each 512-byte UF2 block directly to the USB drive using disk_write(pdrv=1, buff, start_lba + block_idx, 1), starting at an LBA inside the data area (well past the FAT sectors — any LBA ≥ ~300 is safe for the 128 MB layout).
The bootrom processes each write as it arrives, regardless of which LBA it lands on.
This completely sidesteps the FAT chain management and would remove the 1 MB limit. It would need a dedicated MMBasic command (e.g., FLASH PICO C: B:/firmware.uf2) rather than reusing COPY, since COPY always goes through FatFS on the destination.

ME:
  Quote  This is interesting, how does W11 and Linux deal with this?

CLAUDE:
  Quote  Both Windows 11 and Linux are immune to this problem, for the same fundamental reason: they never read FAT data back from disk once they've written it.

The page cache difference
When a PC OS writes a file to any FAT volume, it maintains the entire FAT in its page cache (Windows calls this the system cache / FastFAT cache; Linux uses the kernel buffer cache). The flow is:

OS reads the BPB, FAT sectors, and root directory — all go into the page cache.
OS allocates clusters — updates are made in the page-cached copy of the FAT, never flushed to disk yet.
OS writes data sectors to disk — the bootrom receives each sector, sees UF2 magic, programs flash.
OS marks the FAT pages dirty — eventually flushed to disk, but that's just metadata cleanup.
By the time the FAT is flushed (if at all), all UF2 blocks have already been received and programmed.
When the OS needs to find the next free cluster for step 2, it scans its in-memory page-cached FAT, which correctly reflects every allocation it just made. It never does a disk round-trip to ask "is cluster 257 free?" — it already knows, from its own cache.

FatFS has no page cache. Its win[] buffer is exactly 512 bytes. The instant it needs to switch from FAT sector 1 to FAT sector 2, it must disk_read() sector 1 when it comes back — and the bootrom hands back the original all-free data.

Write ordering also helps
Windows and Linux typically write data sectors first, then update the FAT and directory entry afterwards (or asynchronously). This means the bootrom has received and programmed every UF2 block before the FAT is even touched. The FAT flush is essentially a no-op as far as the bootrom is concerned — it's just tidying up a virtual disk that's about to disappear anyway (the Pico reboots and unmounts).

Why the RP2040 bootrom was designed this way
Raspberry Pi designed the bootrom specifically assuming a host with a page cache. The design relies on two properties:

UF2 blocks carry their own address (target flash address is in the block itself), so they can arrive at any LBA in any order — no FAT traversal is needed by the bootrom.
The virtual FAT is read-only from the bootrom's perspective — it exists only to make the device mountable and to let Windows/macOS/Linux discover free space and allocate sectors. The FAT write-back is always ignored.
This design works perfectly for all mainstream OS FAT drivers but breaks FatFS because FatFS is the only common FAT implementation with a single-sector window that forces disk round-trips on every window switch.

Summary table
Windows 11 / Linux FatFS (PicoMite)
FAT backing store Page cache (entire FAT in RAM) Single 512-byte win[]
Re-reads own FAT writes? Never — reads from cache Yes — disk_read() on window switch
Immune to bootrom's non-persistent FAT? Yes No, breaks at 256 clusters
Large UF2 files Always work Fail above 1 cluster-sector boundary
The fix for PicoMite is to bypass FatFS for the write direction on the boot drive, writing raw UF2 sectors directly via disk_write() so there's no FAT chain management at all.

ME:
  Quote  Implement a Flash Pico command. The C: isn't necessary as the flash drive will always be C:. The uf2 filename will be on the A: or B: drive and will need normal filename parsing and path determination

CLAUDE:
  Quote  Syntax:
FLASH PICO B:/firmware.uf2     ' explicit drive + path
FLASH PICO firmware             ' current drive, adds .uf2 automatically
FLASH PICO A:/stored.uf2        ' from internal flash filesystem

PicoMiteHDMIUSB.zip
 
Bleep
Guru

Joined: 09/01/2022
Location: United Kingdom
Posts: 789
Posted: 05:54pm 22 Apr 2026
Copy link to clipboard 
Print this post

Sorry another one :-(
Because the TraceCache works with If statments, I converted the Case statment in the below code to a If, ElseIf.... type structure, when I run it without the TraceCache it works fine, stars of various colours, when I enable the TraceCache, 'Almost' all the stars are Blue, as though it is defaulting to the Else statment at the end, strangely there are a few yellow stars?
I did try making the Else a ElseIf stz(st) >= 0.8 but then almost all the stars were white, no Blue or Cyan
PS, it was considerably faster with the If, ElseIf, than the Case, so that bit works, assuming it's not faster because it's always defaulting to the Else statment?
Kevin.
'set mode here if appropriate
'Option TraceCache On 32
MODE 3
'change maxst for more or fewer stars
Dim Integer maxst=1250,h=MM.VRES,w=MM.HRES,x,y,st,c
Dim Float f,stx(maxst),stxx(maxst),sty(maxst),styy(maxst),stz(maxst)
Dim Integer ox(maxst),oy(maxst),oxl(maxst),oyl(maxst),cl(maxst),s(maxst)
'FRAMEBUFFER create
'FRAMEBUFFER write f
CLS
'initialise the stars
For st=0 To maxst
 stxx(st)=(Rnd*w>>1)-(w>>2):styy(st)=(Rnd*h>>1)-(h>>2)
 stz(st)=Int(Rnd*5+5)/10
 cl(st)=RGB(White)
Next
'initialise array for box size
Math Set 2,s()

Do
'move stars forward
Math Add stz(),-0.025,stz()
'do the calculation (stx/stz)+half width
Math C_div stxx(),stz(),stx():Math Add stx(),w>>1,stx()
'do the calculation (sty/stz)+half height
Math C_div styy(),stz(),sty():Math Add sty(),h>>1,sty()
'reset rouge stars
'Inc c:c=c*(c<=maxst)
Inc c:If c>maxst Then c=0
'stx(c)=stx(c)*(stz(c)>0.1)
If stz(c)<0 Then stx(c)=0
'loop for all stars
'set star colour and check for star off screen
For st=0 To maxst
x=stx(st):y=sty(st)
' Select Case stz(st)
' Case < 0.2
'  cl(st)=&HFFFF00'RGB(Yellow)
' Case < 0.6
'  cl(st)=&HFFFFFF'RGB(White)
' Case < 0.8
'  cl(st)=&HFFFF'RGB(Cyan)
' Case Else
'  cl(st)=&HFF'RGB(Blue)
' End Select
If stz(st) < 0.2 Then
 cl(st)=&HFFFF00'RGB(Yellow)
ElseIf stz(st) < 0.6 Then
 cl(st)=&HFFFFFF'RGB(White)
ElseIf stz(st) < 0.8 Then
 cl(st)=&HFFFF'RGB(Cyan)
Else
 cl(st)=&HFF'RGB(Blue)
EndIf

If (x>0 And x<w And y>0 And y<h)Then
 ox(st)=x:oy(st)=y
Else
 Inc f,0.025:If f>0.09 Then f=0
 stxx(st)=(Rnd*w>>1)-(w>>2)
 styy(st)=(Rnd*h>>1)-(h>>2)
 stz(st)=Int(Rnd*5+5)/10+f
EndIf
Next
'blank out last times stars, replace with new stars
' Pixel oxl(),oyl(),0:Pixel ox(),oy(),cl()
Box oxl(),oyl(),s(),s(),0,,0:Box ox(),oy(),s(),s(),0,,cl()
'copy this times stars, to last times stars array
Math Add ox(),0,oxl():Math add oy(),0,oyl()
' FRAMEBUFFER copy f,n,b
Print Timer:Timer =0
Loop

Edited 2026-04-23 04:00 by Bleep
 
toml_12953
Guru

Joined: 13/02/2015
Location: United States
Posts: 603
Posted: 06:18pm 22 Apr 2026
Copy link to clipboard 
Print this post

  Bleep said  Hi Peter,
I think I've found a bug.
If I use
'Option Tracecache on 16
Dim Integer maxst=1000:c=42
c=c*(c<=maxst)    'If c>maxst Then c=0
Print c
End

c is printed as 42, if I remove the comment for Option Trace Cache, c is printed as -42? If I set c to 1001, then in both cases c is printed as 0, which is fine.
Kevin.


To be consistent with other conditionals, a true comparison should return 1

? 5 > 2
1


so c=c*(c<=maxst) should set c to 42.

Option Trace Cache should, of course, have nothing to do with the outcome.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11224
Posted: 06:19pm 22 Apr 2026
Copy link to clipboard 
Print this post

Bleep
Try this - should fix both bugs

PicoMiteHDMIUSB.zip
 
Bleep
Guru

Joined: 09/01/2022
Location: United Kingdom
Posts: 789
Posted: 06:31pm 22 Apr 2026
Copy link to clipboard 
Print this post

Hi Peter,
Not sure what happened there, but this is significantly faster, even before I change the Case to a If,ElseIf?
But yes both the above problems are fixed. :-)
Kevin.
 
javavi

Guru

Joined: 01/10/2023
Location: Ukraine
Posts: 548
Posted: 06:45pm 22 Apr 2026
Copy link to clipboard 
Print this post

  matherp said  For javavi

Syntax:
FLASH PICO B:/firmware.uf2     ' explicit drive + path
FLASH PICO firmware             ' current drive, adds .uf2 automatically
FLASH PICO A:/stored.uf2        ' from internal flash filesystem


Yes, it worked!  
A miracle happened, Pico flashes Pico!
Thanks to Peter and his friend Claude  

I think the name Pico is a special case, and it would be better to specify it in the command something else, for example, like this

Syntax:
FLASH UF2 B:/firmware.uf2     ' explicit drive + path
FLASH UF2 firmware            ' current drive, adds .uf2 automatically
FLASH UF2 A:/stored.uf2       ' from internal flash filesystem
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11224
Posted: 06:51pm 22 Apr 2026
Copy link to clipboard 
Print this post

FLASH UF2 it will be
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1853
Posted: 07:17pm 22 Apr 2026
Copy link to clipboard 
Print this post

That Claude thing...I am loving this stuff. What a time to be MCU-ing  
 
ville56
Guru

Joined: 08/06/2022
Location: Austria
Posts: 451
Posted: 08:01pm 22 Apr 2026
Copy link to clipboard 
Print this post

Peter,

in FM, if listing a file (with "L"), the first character in the first non-empty line is not displayed in the list output.

e.g.

"option explicit" becomes "ption explicit" in the output. This is only true for the first non-empty line. Leading empty lines do not change the behaviour.

Issue found on PicoMite MMBasic RP2350B V6.03.00B0
                                                                 
73 de OE1HGA, Gerald
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2026