Modern Mode Explained

 visits
Parent Previous Next

What changes from Legacy mode?


Modern mode adds a file table to a RAW SD card. Each entry tells the application and your firmware where one picture or movie is stored and how to identify it. An alias such as BeetleL can therefore travel with the media itself.

This is the application's own RAW format. It is not FAT16 or FAT32, and Windows Explorer cannot browse it as a normal collection of files. Use Verify Card to inspect the contents.


Detail

Legacy

Modern

Index space

8 sectors (4096 bytes)

4096 sectors (2 MiB)

Maximum table entries

1024

16,384, including freed entries

First data sector

8

4096

File identification

Sector addresses; names are in the PC report

Alias and original name are stored on the card

Stored measurements

Compact end-sector index

Dimensions, exact byte length, video frames and frame rate

Checking

No per-file CRC32

CRC32 stored with each live file

Replacing individual files

No reusable-slot mechanism

Free a slot and reuse its existing allocation

Numeric fields

Little-endian end-sector entries

Big-endian multibyte fields; inclusive stop sectors


The mode changes the index, not the RGB565 pixel format or the conversion controls. Choose the same mode when writing, appending or verifying a card. Changing an existing card to another mode requires a rebuild, which replaces its contents.

Where the information lives

The beginning of the card is reserved for the table. Each slot is 128 bytes, so four slots fit in one 512-byte sector.

16384 slots x 128 bytes = 2097152 bytes = 2 MiB

2097152 bytes / 512 bytes per sector = 4096 sectors


Sectors 0 to 4095: header table

Sector 4096 onward: file data


For zero-based slot N:

    tableSector = N / 4          (integer division)

    byteOffset  = (N mod 4) * 128


A live slot records the file's starting sector, its last data sector and the last sector reserved for that slot. BMP files retain their BMP structure. A movie is a sequence of RGB565 frames; its table entry supplies the dimensions and frame-rate information that the raw stream does not carry.

Aliases select a file without fixed sector numbers

The Alias is the name your program can request with TftBmpFromSdRawAlias() or TftRgbFromSdRawAlias(). It is different from a Positron $define: the quoted alias is looked up on the card, while a $define expands to fixed values during compilation.

TftBmpFromSdRawAlias("BeetleL",136,96)

TftRgbFromSdRawAlias("OldFilmCountdown",40,40,0)

Image dimensions come from the BMP; movie dimensions come from its table entry. The coordinates identify the lower-left corner on the TFT. The examples assume the display and library are already configured.

Alias and Original Name each have a 40-byte field: up to 39 ASCII characters followed by a zero terminator. Long or repeated values receive a four-digit suffix. For example, a second Bird can become Bird0001; an overlong name keeps its first 35 characters followed by a suffix. Alias and Original Name are handled independently. Use the stored name shown by Verify Card or the generated report.

What happens when you free a file?

In Verify Card, select the × button and confirm. The application changes the slot's Media Type to 64 (free). Its data is not erased at that point, and the slot retains its original allocated range. It remains in the table and counts towards the 16,384-slot limit.


The confirmation identifies the slot that will be made available for reuse.


The confirmation identifies the slot that will be made available for reuse.


The free slot remains visible between live files; it is not the end of the table.


The free slot remains visible between live files; it is not the end of the table.


When Convert & Append runs, each file is converted to determine its size. The application chooses the lowest-numbered free slot with enough allocated space. If none fits, it adds a new slot and places the data after the highest allocated stop sector.

A smaller replacement changes the Stop Sector, but keeps the Start Sector and Allocated Stop. This preserves the slot's capacity for a later replacement.

A worked example

Suppose a free slot owns sectors 4096 through 4195. That is 100 sectors, or 51,200 bytes. A new 20,000-byte file needs 40 sectors after rounding up.


Field

Before reuse

After writing the smaller file

Start Sector

4096

4096

Stop Sector

End of the previous file

4135

Allocated Stop

4195

4195

Data Length

Previous exact length

20,000 bytes

Reusable capacity after freeing again

51,200 bytes

51,200 bytes


requiredSectors = ceil(dataLength / 512)

stopSector      = startSector + requiredSectors - 1

capacityBytes   = (allocatedStop - startSector + 1) * 512


Separate free slots are not combined into one larger allocation. A new file must fit a single free slot or use enough unused space after the last allocation. Existing sector-based $define values may point at different media after a slot is reused; update them or use the intended stored alias.


The completion message confirms that the new file reused an existing slot.


The completion message confirms that the new file reused an existing slot.


How file checking works

The writer stores a CRC32 over exactly Data Length bytes. Padding at the end of the last sector is excluded. Double-clicking a live file in Verify Card downloads those bytes and compares their CRC32 with the stored value.

OK means the two checksums match. FAIL means they differ; it does not, by itself, identify the card, reader or write operation as the cause. A failed file can still be previewed for inspection.


Verify Card checks a downloaded file before displaying the preview.


Verify Card checks a downloaded file before displaying the preview.


The CRC uses reflected polynomial 0xEDB88320, initial value 0xFFFFFFFF and final XOR 0xFFFFFFFF. The check value for the ASCII text 123456789 is 0xCBF43926.

Header reference: one 128-byte slot

All fields are packed without gaps. Multibyte numbers are unsigned and big-endian. The two stop values are inclusive; Legacy's compact index instead stores the sector after a file.


Bytes

Field

Notes

0

Media Type

0 = BMP, 1 = RGB, 64 = free (deleted, reusable), 128 = empty (never used)

1–4

Start Sector

32-bit unsigned - first sector of the file

5–8

Stop Sector

32-bit unsigned, inclusive - last sector holding the file's actual data (not one past the end, the way Legacy's index works)

9–12

Allocated Stop

32-bit unsigned, inclusive - last sector the slot owns. Set once when the slot is created and never lowered; see Freeing and reusing slots

13–14

Width

16-bit unsigned, pixels

15–16

Height

16-bit unsigned, pixels

17–20

Data Length

32-bit unsigned - exact file size in bytes, without the zero padding up to the next sector boundary

21–24

Frame Count

32-bit unsigned - RGB: number of frames (Data Length ÷ (Width × Height × 2)); BMP: 0

25–26

Frame Rate ×100

16-bit unsigned - RGB: frames per second × 100, e.g. 2500 = 25.00 fps, 2997 = 29.97 fps; BMP or unknown: 0

27–30

CRC32

32-bit unsigned - checksum of the Data Length bytes (see CRC32 below)

31

Day

1–31

32

Month

1–12

33–34

Year

16-bit unsigned, e.g. 2026

35

Hour

0–23

36

Minute

0–59

37

Second

0–59 - the date and time are the PC's local time when the file was written

38–77

Alias

40 bytes: up to 39 ASCII characters, then a 0 terminator

78–117

Original Name

40 bytes: up to 39 ASCII characters, then a 0 terminator

118–127

Reserved

Always 0 - 10 bytes free for future use


Unused bytes after each text terminator are zero. Original Name omits the source extension. The date and time describe when the PC wrote the file, using the PC's local time.

Reading the table on a small microcontroller

The desktop application can keep a copy of the table in memory, but firmware can scan one 512-byte sector at a time. Process its four slots, then read the next sector. The following is a format-reading outline, not Positron source code:

for each slot from 0 through 16383:

    read Media Type and Start Sector

    if Media Type = 128 or Start Sector = 0:

        stop: no more initialized slots

    if Media Type = 64:

        continue: this slot is free

    if Media Type is neither 0 nor 1:

        reject this unsupported entry

    read the remaining fields as big-endian numbers

    use Data Length bytes beginning at Start Sector


Do not stop at a free slot: later live files may follow it. A zero-filled card without a Modern index has no valid live file merely because the Media Type byte is zero. The Start Sector check prevents that misinterpretation.

Stored frame rate and actual playback

For a movie, Frame Rate ×100 stores values such as 2500 for 25.00 fps or 2997 for 29.97 fps. The target period between the starts of consecutive frames is:

framePeriodUs = 100000000 / storedRate100


2500 -> 40000 microseconds per frame (25 fps)

This is a complete frame period, not a delay that can simply be added after a full frame has already been drawn. A timed renderer accounts for reading and drawing time. The alias procedure's bDelayUs is only an additional Byte-sized delay from 0 to 255 microseconds; the stored rate does not establish that the library automatically paces playback. A stored rate of zero means unknown and must not be used as a divisor.

The application's TFT Preview uses a fixed 25 fps. Treat it as a preview of the converted content, not a measurement of your PIC's achievable playback rate.

Practical workflow

  1. For a new build, select the correct card and run Format System (FAT32), then Format RAW.
  2. Choose Modern, prepare the batch, and use Convert & Write to create the table and files.
  3. Open Verify Card to inspect the aliases and preview files from the card.
  4. Use Convert & Append in the same mode for additions. Free a suitable slot first if you want to reuse its allocation.

Rebuilding erases existing contents. Appending to a valid Modern card does not require formatting again. Switching modes or replacing an incompatible development format requires the full rebuild sequence.

See also

Positron Media Foundry · User Manual · RAW / No file system · TftBmpFromSdRaw() · TftRgbFromSdRaw()

Created with the Personal Edition of HelpNDoc: Full-featured EPub generator