Bootloader API library with SDHC and FAT32

Topics related to the API, programming discussions & questions, coding tips, bugs, etc. should go here.
User avatar
Artcfox
Posts: 1382
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Re: Bootloader API library with SDHC and FAT32

Post by Artcfox »

FS_Next_Sector doesn't read the data in the sector, it just reads the FAT and updates the sd_struct to point to the next sector regardless of whether or not the file is contiguous (it doesn't have to be contiguous). You would still need to use FS_Read_Sector to read the sector data that the sd_struct points to. If your file might not be contiguous use this way.


If you know your file will be contiguous (and/or you want raw speed) you can use direct sector reads. If you need raw speed, let me know, and I can post my modifications to SD_Read_Sector_Nr_Nc that allow for separate cueing and reading.
User avatar
nicksen782
Posts: 714
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: Bootloader API library with SDHC and FAT32

Post by nicksen782 »

bootlib_hasloader is in bootlib.s. It is called at the start of each ASM API. How could I call it from C?

Could this be made into an extern?
User avatar
Jubatian
Posts: 1561
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Bootloader API library with SDHC and FAT32

Post by Jubatian »

nicksen782 wrote: Fri Aug 10, 2018 6:57 pmbootlib_hasloader is in bootlib.s. It is called at the start of each ASM API. How could I call it from C?

Could this be made into an extern?
What exactly do you need it for? The intent was that it should be hidden from the user which code is serving his SD accesses, making the presence or absence of the new bootloader completely transparent. Using this from user code would defeat this. Possibly you need a feature which should be part of the library then.
User avatar
nicksen782
Posts: 714
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: Bootloader API library with SDHC and FAT32

Post by nicksen782 »

A simple example would be to warn about potential file fragmentation when using the old bootloader.

Also, I would just like to know. Right now I can run CUzeBox with either the bootloader hex or the game.uze. If only one .uze file exists then the bootloader just loads that. However, it takes a few more seconds to do so. My interface lets me start the game via either file. Other than the initial delay with the bootloader I do not see a difference. This is likely different on the actual hardware.
User avatar
Jubatian
Posts: 1561
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Bootloader API library with SDHC and FAT32

Post by Jubatian »

nicksen782 wrote: Sun Aug 12, 2018 5:13 pmA simple example would be to warn about potential file fragmentation when using the old bootloader.
If you have the old bootloader, you need to have the whole card defragmented anyway, otherwise all the games could fail to load (the bootloader will mess up loading a fragmented game) including yours (so it may not even get to display the warning). It would only be a nuisance to someone using it right. Basically you would implement a nag screen with this, urging people with the old loader to upgrade. I don't think this being a good idea (those still using the old bootloader might not have a tool to upgrade it).
nicksen782 wrote: Sun Aug 12, 2018 5:13 pmAlso, I would just like to know. Right now I can run CUzeBox with either the bootloader hex or the game.uze. If only one .uze file exists then the bootloader just loads that. However, it takes a few more seconds to do so. My interface lets me start the game via either file. Other than the initial delay with the bootloader I do not see a difference. This is likely different on the actual hardware.
It would do the same on the real hardware. The new bootloader has this behavior in it: If the SD card has a single .uze on it, it programs it, so the Uzebox works like a normal game console (insert the cart, turn it on, the game runs). It works just the same way in the emulator if you start the bootloader's .hex on a directory with a single .uze. Just to note: The behavior doesn't cause extra wear on the ATmega as the new bootloader only programs sectors which actually need programming (so if the Uzebox already has the game burned in, the bootloader just skims over it checking that it is indeed the same).

If you need a specific tool to query the bootloader's version, use its interface directly:

https://github.com/Uzebox/uzebox/blob/m ... ore.s#L158

This area is at 0xF000 (the interrupt vector table of the bootloader), the bytes 0xF002 - 0xF007 are those which you need to check whether the signature is present, and which version of the bootloader is there. If there is no valid signature there, then you may check for jump instructions: if they are present, a version of the old bootloader is there. If they are not, likely the Uzebox (or emulator) has no bootloader at all, the program was burned on it directly from .hex (real hardware, the emulator of course can load the .uze without the bootloader).

I don't think there was a reliable way to tell apart old bootloader versions as there may be results of multiple compiles out in the "wild". If you still would like to approximate it, the old bootloader's topic could be used: those binaries are the most likely to occur, so you may attempt to match some bytes from them to tell them apart.
User avatar
nicksen782
Posts: 714
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: Bootloader API library with SDHC and FAT32

Post by nicksen782 »

Code: Select all

static void _getBlSig(){
	u8 volatile * const _bl_0 = (u8 *) 0xF000;
	u8 volatile * const _bl_1 = (u8 *) 0xF001;
	u8 volatile * const _bl_2 = (u8 *) 0xF002;
	u8 volatile * const _bl_3 = (u8 *) 0xF003;
	u8 volatile * const _bl_4 = (u8 *) 0xF004;
	u8 volatile * const _bl_5 = (u8 *) 0xF005;
	u8 volatile * const _bl_6 = (u8 *) 0xF006;
	u8 volatile * const _bl_7 = (u8 *) 0xF007;

	u8 y=2;
	Print(0 , y, PSTR("0XF000:")); PrintInt(27 , y, *_bl_0, false); y++;
	Print(0 , y, PSTR("0XF001:")); PrintInt(27 , y, *_bl_1, false); y++;
	Print(0 , y, PSTR("0XF002:")); PrintInt(27 , y, *_bl_2, false); y++;
	Print(0 , y, PSTR("0XF003:")); PrintInt(27 , y, *_bl_3, false); y++;
	Print(0 , y, PSTR("0XF004:")); PrintInt(27 , y, *_bl_4, false); y++;
	Print(0 , y, PSTR("0XF005:")); PrintInt(27 , y, *_bl_5, false); y++;
	Print(0 , y, PSTR("0XF006:")); PrintInt(27 , y, *_bl_6, false); y++;
	Print(0 , y, PSTR("0XF007:")); PrintInt(27 , y, *_bl_7, false); y++;
}
With this, the emulator returns 0 for each. I was basing it on this which is how I operate the "whisper port".

Code: Select all


static void _emu_whisper(int port, unsigned char val){
	if(port == 0){ u8 volatile * const _whisper_pointer1 = (u8 *) 0x39; *_whisper_pointer1 = val; }
	if(port == 1){ u8 volatile * const _whisper_pointer2 = (u8 *) 0x3A; *_whisper_pointer2 = val; }
}
Perhaps it doesn't work the same way. Could you provide an example on how to read those bytes?

I'm not interested in versions of the old bootloader. Only if the bootloader is the new one or not and maybe the version of it too.

Thanks!
User avatar
Jubatian
Posts: 1561
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Bootloader API library with SDHC and FAT32

Post by Jubatian »

Remember, these locations are in ROM! So use:

Code: Select all

PrintInt(27 , y, pgm_read_byte(_bl_0), false);
It should work then!
User avatar
nicksen782
Posts: 714
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: Bootloader API library with SDHC and FAT32

Post by nicksen782 »

It was in ROM. Of course! Thank you.

Here is what I came up with in case someone else is interested:

Code: Select all

static void _getBlSig(){
	u16 val0 = ( pgm_read_byte( (u8 *) 0xF000) << 8 ) + ( pgm_read_byte( (u8 *) 0xF001) & 0xFF );
	u16 val1 = ( pgm_read_byte( (u8 *) 0xF002) << 8 ) + ( pgm_read_byte( (u8 *) 0xF003) & 0xFF );
	u16 val2 = ( pgm_read_byte( (u8 *) 0xF004) << 8 ) + ( pgm_read_byte( (u8 *) 0xF005) & 0xFF );
	u16 val3 = ( pgm_read_byte( (u8 *) 0xF006) << 8 ) + ( pgm_read_byte( (u8 *) 0xF007) & 0xFF );

	u8 y=2;
	Print( 0 , y, PSTR("VAL0:") ); PrintHexInt( 20 , y, val0 ); y++; // New bootloader shows: 0x64C1
	Print( 0 , y, PSTR("VAL1:") ); PrintHexInt( 20 , y, val1 ); y++; // New bootloader shows: 0xB007
	Print( 0 , y, PSTR("VAL2:") ); PrintHexInt( 20 , y, val2 ); y++; // New bootloader shows: 0x10AD
	Print( 0 , y, PSTR("VAL3:") ); PrintHexInt( 20 , y, val3 ); y++; // New bootloader shows: 0x5010
}
If there is not a bootloader then all these values are 0. I don't have a .hex of the old bootloader at the moment.

Which of those four values will I need to determine if it is the new bootloader and also the version?
User avatar
Jubatian
Posts: 1561
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Bootloader API library with SDHC and FAT32

Post by Jubatian »

nicksen782 wrote: Mon Aug 13, 2018 6:31 amWhich of those four values will I need to determine if it is the new bootloader and also the version?
0xF002 - 0xF005 are a signature (0xB007 0x10AD for "BOOTLOAD") indicating that a >= 5.0.00 bootloader is present. 0xF006 - 0xF007 encode the version number (0x5010 for 5.0.10). In the practice versions prior to 5.0.08 should be lost by now (I could recover them, but they have no real significance), the significance of this is that all the existing versions of this new bootloader support the bootloader API properly.
Post Reply