Loading...
Searching...
No Matches
lisa_tag.c File Reference

Parsing, conversion and serialization helpers for Lisa (Apple Lisa / Profile / Priam / Sony) disk block tags. More...

`#include <stdint.h>`
`#include "aaruformat/structs/lisa_tag.h"`
`#include <stdlib.h>`

Go to the source code of this file.

## Macros

#define | SONY_BLOCK_NUMBER_MASK 0x07FFU
#define | SONY_BLOCK_VALID_FLAG 0x8000U
#define | SONY_BLOCK_ALLOWED_MASK (SONY_BLOCK_VALID_FLAG | SONY_BLOCK_NUMBER_MASK)
| Preserve valid bit + 11-bit index.

## Functions

sony_tag | bytes_to_sony_tag (const uint8_t *bytes)
| Parse a 12-byte Sony tag record into a sony_tag structure.
priam_tag | bytes_to_priam_tag (const uint8_t *bytes)
| Parse a 24-byte Priam tag record into a priam_tag structure.
profile_tag | bytes_to_profile_tag (const uint8_t *bytes)
| Parse a 20-byte Profile tag record into a profile_tag structure.
profile_tag | sony_tag_to_profile (const sony_tag tag)
| Convert a sony_tag to a profile_tag representation.
priam_tag | sony_tag_to_priam (const sony_tag tag)
| Convert a sony_tag to a priam_tag representation.
priam_tag | profile_tag_to_priam (const profile_tag tag)
| Convert a profile_tag to a priam_tag.
sony_tag | profile_tag_to_sony (const profile_tag tag)
| Convert a profile_tag to a sony_tag.
sony_tag | priam_tag_to_sony (const priam_tag tag)
| Convert a priam_tag to a sony_tag.
profile_tag | priam_tag_to_profile (const priam_tag tag)
| Convert a priam_tag to a profile_tag.
uint8_t * | profile_tag_to_bytes (const profile_tag tag)
| Serialize a profile_tag into a newly allocated 20-byte big-endian on-disk representation.
uint8_t * | priam_tag_to_bytes (const priam_tag tag)
| Serialize a priam_tag into a newly allocated 24-byte big-endian on-disk representation.
uint8_t * | sony_tag_to_bytes (sony_tag tag)
| Serialize a sony_tag into a newly allocated 12-byte big-endian on-disk representation.

## Detailed Description

Parsing, conversion and serialization helpers for Lisa (Apple Lisa / Profile / Priam / Sony) disk block tags.

The Lisa operating system and related peripheral disk formats (Sony 3.5" diskettes, ProFile hard disks, Priam drives) store per-block (or per-page) metadata in compact on-disk "tag" records. These records use mixed-size big-endian integer fields and bit fields to describe allocation chains, relative/absolute page numbering, volume numbers, versions, and (for some variants) checksums and disk sizing.

This module provides:

- Parsing raw big-endian on-disk tag byte sequences into the in-memory structures: sony_tag, profile_tag, priam_tag.
- Lossless (within each format's limits) conversion between the different tag structure variants, mapping sentinel values (e.g. 0x7FF <-> 0xFFFFFF for end-of-chain markers) appropriately.
- Serialization of the in-memory structures back into their canonical on-disk packed byte layouts.

Endianness: All multi-byte numeric fields in the on-disk tag formats are stored big-endian. The helper routines perform the necessary byte shifting and masking; the resulting structure fields are in host endianness.

Memory management: The serialization functions ( *_tag_to_bytes ) allocate new byte buffers using calloc(). The caller owns the returned pointer and must free() it when no longer needed. Parsing functions do not allocate dynamic memory; they return structures by value.

Validation: For performance and low-level usage reasons, the parsing routines do not perform NULL pointer checks nor length validation on the input byte arrays. Supplying a NULL pointer or insufficient bytes is undefined behavior. If such safety is required, perform validation before calling these functions.

Sentinel mapping: Sony tag next/prev block fields are 11-bit values (masked with 0x7FF) with the value 0x7FF meaning end-of-chain (or no previous). In the wider Profile/Priam formats these become 24-bit fields, with 0xFFFFFF used for the same semantic meaning. Conversion helpers transparently translate between these sentinel values.

Bit fields: The structures define C bit fields for compact representation (e.g., kind, reserved, valid_chk, used_bytes). The parsing and serialization routines reconstruct / pack these manually through masking and shifting because on-disk layout may not match compiler bit-field packing. This provides portability irrespective of platform-specific bit-field ordering.

Definition in file lisa_tag.c.

## Macro Definition Documentation

## SONY_BLOCK_ALLOWED_MASK

#define SONY_BLOCK_ALLOWED_MASK (SONY_BLOCK_VALID_FLAG | SONY_BLOCK_NUMBER_MASK)

Preserve valid bit + 11-bit index.

Definition at line 68 of file lisa_tag.c.

Referenced by bytes_to_sony_tag(), and sony_tag_to_bytes().

## SONY_BLOCK_NUMBER_MASK

#define SONY_BLOCK_NUMBER_MASK 0x07FFU

Definition at line 66 of file lisa_tag.c.

Referenced by priam_tag_to_sony(), profile_tag_to_sony(), sony_tag_to_priam(), and sony_tag_to_profile().

## SONY_BLOCK_VALID_FLAG

#define SONY_BLOCK_VALID_FLAG 0x8000U

Definition at line 67 of file lisa_tag.c.

## Function Documentation

## bytes_to_priam_tag()

priam_tag bytes_to_priam_tag | ( | const uint8_t * | bytes | ) |

Parse a 24-byte Priam tag record into a priam_tag structure.

Priam tags extend the Profile tag with an additional 4-byte disk_size field. This routine decodes all bit fields, separating the valid checksum flag (bit 7 of byte 6) from the 15-bit used_bytes value.

Parameters

  bytes | Pointer to at least 24 consecutive bytes containing a raw Priam tag.

Returns
  A populated priam_tag structure.

Warning
  Undefined behavior if bytes is NULL or shorter than 24 bytes.

Note
  The abs_page, next_block and prev_block 24-bit values are expanded into 32-bit integers in host memory.

Definition at line 112 of file lisa_tag.c.

References priam_tag::abs_page, priam_tag::checksum, priam_tag::disk_size, priam_tag::file_id, priam_tag::kind, priam_tag::next_block, priam_tag::prev_block, priam_tag::rel_page, priam_tag::reserved, priam_tag::used_bytes, priam_tag::valid_chk, priam_tag::version, and priam_tag::volume.

Referenced by aaruf_write_sector_long().

## bytes_to_profile_tag()

profile_tag bytes_to_profile_tag | ( | const uint8_t * | bytes | ) |

Parse a 20-byte Profile tag record into a profile_tag structure.

A Profile tag is similar to Priam but without the trailing disk_size field. Multi-byte numeric values are big-endian.

Parameters

  bytes | Pointer to at least 20 consecutive bytes containing a raw Profile tag.

Returns
  A populated profile_tag structure.

Warning
  Undefined behavior if bytes is NULL or shorter than 20 bytes.

Definition at line 142 of file lisa_tag.c.

References profile_tag::abs_page, profile_tag::checksum, profile_tag::file_id, profile_tag::kind, profile_tag::next_block, profile_tag::prev_block, profile_tag::rel_page, profile_tag::reserved, profile_tag::used_bytes, profile_tag::valid_chk, profile_tag::version, and profile_tag::volume.

Referenced by aaruf_write_sector_long().

## bytes_to_sony_tag()

sony_tag bytes_to_sony_tag | ( | const uint8_t * | bytes | ) |

Parse a 12-byte Sony tag record into a sony_tag structure.

Field extraction follows the documented on-disk layout (big-endian). The next/prev block numbers are masked to 11 bits (0x7FF) since only those bits are defined in the Sony tag format. The reserved bits are preserved in the structure's reserved member for round-tripping if needed.

Parameters

  bytes | Pointer to at least 12 consecutive bytes containing a raw Sony tag as read from disk.

Returns
  A populated sony_tag structure with host-endian integer fields.

Warning
  Behavior is undefined if bytes is NULL or does not point to at least 12 readable bytes.

Note
  No validation of version, kind, or chain linkage consistency is performed.

Definition at line 82 of file lisa_tag.c.

References sony_tag::file_id, sony_tag::kind, sony_tag::next_block, sony_tag::prev_block, sony_tag::rel_page, sony_tag::reserved, SONY_BLOCK_ALLOWED_MASK, sony_tag::version, and sony_tag::volume.

Referenced by aaruf_write_sector_long().

## priam_tag_to_bytes()

uint8_t * priam_tag_to_bytes | ( | const priam_tag | tag | ) |

Serialize a priam_tag into a newly allocated 24-byte big-endian on-disk representation.

Layout matches bytes_to_priam_tag(). Includes the final 4-byte disk_size field. Packing rules for used_bytes and valid_chk mirror those used in profile_tag_to_bytes().

Parameters

  tag | Priam tag to serialize.

Returns
  Pointer to a 24-byte buffer, or NULL on allocation failure.

Return values

  NULL | Allocation failure.

Note
  Caller must free() the returned buffer.

Definition at line 409 of file lisa_tag.c.

References priam_tag::abs_page, priam_tag::checksum, priam_tag::disk_size, priam_tag::file_id, priam_tag::kind, priam_tag::next_block, priam_tag::prev_block, priam_tag::rel_page, priam_tag::reserved, priam_tag::used_bytes, priam_tag::valid_chk, priam_tag::version, and priam_tag::volume.

Referenced by aaruf_write_sector_long().

## priam_tag_to_profile()

profile_tag priam_tag_to_profile | ( | const priam_tag | tag | ) |

Convert a priam_tag to a profile_tag.

Copies overlapping fields, omitting the Priam-specific disk_size. Useful when reusing Priam metadata in a context that expects Profile tag semantics.

Parameters

  tag | Source Priam tag.

Returns
  Profile tag with copied values.

Definition at line 325 of file lisa_tag.c.

References priam_tag::abs_page, profile_tag::abs_page, priam_tag::checksum, profile_tag::checksum, priam_tag::file_id, profile_tag::file_id, priam_tag::kind, profile_tag::kind, priam_tag::next_block, profile_tag::next_block, priam_tag::prev_block, profile_tag::prev_block, priam_tag::rel_page, profile_tag::rel_page, priam_tag::reserved, profile_tag::reserved, priam_tag::used_bytes, profile_tag::used_bytes, priam_tag::valid_chk, profile_tag::valid_chk, priam_tag::version, profile_tag::version, priam_tag::volume, and profile_tag::volume.

Referenced by aaruf_write_sector_long().

## priam_tag_to_sony()

sony_tag priam_tag_to_sony | ( | const priam_tag | tag | ) |

Convert a priam_tag to a sony_tag.

See profile_tag_to_sony(); Priam-only fields (abs_page, checksum, used_bytes, valid_chk, disk_size) are discarded. 0xFFFFFF chain terminators become 0x7FF; other values are truncated to 11 bits.

Parameters

  tag | Source Priam tag.

Returns
  Sony tag with mapped values.

Definition at line 291 of file lisa_tag.c.

References priam_tag::file_id, sony_tag::file_id, priam_tag::kind, sony_tag::kind, priam_tag::next_block, sony_tag::next_block, priam_tag::prev_block, sony_tag::prev_block, priam_tag::rel_page, sony_tag::rel_page, priam_tag::reserved, sony_tag::reserved, SONY_BLOCK_NUMBER_MASK, priam_tag::version, sony_tag::version, priam_tag::volume, and sony_tag::volume.

Referenced by aaruf_write_sector_long().

## profile_tag_to_bytes()

uint8_t * profile_tag_to_bytes | ( | const profile_tag | tag | ) |

Serialize a profile_tag into a newly allocated 20-byte big-endian on-disk representation.

Bit/byte packing mirrors bytes_to_profile_tag(). The 24-bit next_block, prev_block and abs_page values are written most-significant byte first. The used_bytes high 7 bits and valid_chk flag are packed into the first byte of the 16-bit used_bytes field as per on-disk layout.

Parameters

  tag | Profile tag to serialize.

Returns
  Pointer to a 20-byte buffer containing the serialized tag, or NULL on allocation failure.

Return values

  NULL | Allocation failure (caller should check before use).

Note
  Caller must free() the returned buffer.

Definition at line 357 of file lisa_tag.c.

References profile_tag::abs_page, profile_tag::checksum, profile_tag::file_id, profile_tag::kind, profile_tag::next_block, profile_tag::prev_block, profile_tag::rel_page, profile_tag::reserved, profile_tag::used_bytes, profile_tag::valid_chk, profile_tag::version, and profile_tag::volume.

Referenced by aaruf_write_sector_long().

## profile_tag_to_priam()

priam_tag profile_tag_to_priam | ( | const profile_tag | tag | ) |

Convert a profile_tag to a priam_tag.

Copies all overlapping fields directly. The Priam-only disk_size field remains zero unless modified later.

Parameters

  tag | Source Profile tag.

Returns
  Priam tag with copied values.

Definition at line 228 of file lisa_tag.c.

References priam_tag::abs_page, profile_tag::abs_page, priam_tag::checksum, profile_tag::checksum, priam_tag::file_id, profile_tag::file_id, priam_tag::kind, profile_tag::kind, priam_tag::next_block, profile_tag::next_block, priam_tag::prev_block, profile_tag::prev_block, priam_tag::rel_page, profile_tag::rel_page, priam_tag::reserved, profile_tag::reserved, priam_tag::used_bytes, profile_tag::used_bytes, priam_tag::valid_chk, profile_tag::valid_chk, priam_tag::version, profile_tag::version, priam_tag::volume, and profile_tag::volume.

Referenced by aaruf_write_sector_long().

## profile_tag_to_sony()

sony_tag profile_tag_to_sony | ( | const profile_tag | tag | ) |

Convert a profile_tag to a sony_tag.

Narrows 24-bit next/prev block numbers to 11 bits. A value of 0xFFFFFF (end-of-chain sentinel) is mapped back to 0x7FF. Any non-sentinel value is truncated to its lower 11 bits. Fields without Sony equivalents are dropped.

Parameters

  tag | Source Profile tag.

Returns
  Sony tag with mapped/narrowed values.

Definition at line 257 of file lisa_tag.c.

References profile_tag::file_id, sony_tag::file_id, profile_tag::kind, sony_tag::kind, profile_tag::next_block, sony_tag::next_block, profile_tag::prev_block, sony_tag::prev_block, profile_tag::rel_page, sony_tag::rel_page, profile_tag::reserved, sony_tag::reserved, SONY_BLOCK_NUMBER_MASK, profile_tag::version, sony_tag::version, profile_tag::volume, and sony_tag::volume.

Referenced by aaruf_write_sector_long().

## sony_tag_to_bytes()

uint8_t * sony_tag_to_bytes | ( | sony_tag | tag | ) |

Serialize a sony_tag into a newly allocated 12-byte big-endian on-disk representation.

The next_block and prev_block fields are masked to 11 bits (0x7FF) during packing. Caller should ensure sentinel semantics are already encoded (i.e., use 0x7FF for end-of-chain) prior to calling.

Parameters

  tag | Sony tag to serialize.

Returns
  Pointer to a 12-byte buffer, or NULL on allocation failure.

Return values

  NULL | Allocation failure.

Note
  Caller must free() the returned buffer.

Definition at line 466 of file lisa_tag.c.

References sony_tag::file_id, sony_tag::kind, sony_tag::next_block, sony_tag::prev_block, sony_tag::rel_page, sony_tag::reserved, SONY_BLOCK_ALLOWED_MASK, sony_tag::version, and sony_tag::volume.

Referenced by aaruf_write_sector_long().

## sony_tag_to_priam()

priam_tag sony_tag_to_priam | ( | const sony_tag | tag | ) |

Convert a sony_tag to a priam_tag representation.

Similar to sony_tag_to_profile() but returns a Priam tag. Priam-specific fields (abs_page, checksum, used_bytes, valid_chk, disk_size, reserved) are zero-initialized. 0x7FF next/prev sentinels expand to 0xFFFFFF.

Parameters

  tag | Source Sony tag.

Returns
  Priam tag with mapped values.

Definition at line 201 of file lisa_tag.c.

References priam_tag::file_id, sony_tag::file_id, priam_tag::kind, sony_tag::kind, priam_tag::next_block, sony_tag::next_block, priam_tag::prev_block, sony_tag::prev_block, priam_tag::rel_page, sony_tag::rel_page, priam_tag::reserved, sony_tag::reserved, SONY_BLOCK_NUMBER_MASK, priam_tag::version, sony_tag::version, priam_tag::volume, and sony_tag::volume.

Referenced by aaruf_write_sector_long().

## sony_tag_to_profile()

profile_tag sony_tag_to_profile | ( | const sony_tag | tag | ) |

Convert a sony_tag to a profile_tag representation.

Sony tags contain a reduced-width (11-bit) next/prev block. To preserve chain termination semantics, values of 0x7FF are translated to 0xFFFFFF (24-bit "no next/prev" sentinel). Other values are copied verbatim into the wider fields. Only fields common to both formats are populated; Profile-specific fields (abs_page, checksum, used_bytes, valid_chk, reserved) remain zero-initialized.

Parameters

  tag | Source Sony tag.

Returns
  Profile tag with mapped values.

Definition at line 173 of file lisa_tag.c.

References profile_tag::file_id, sony_tag::file_id, profile_tag::kind, sony_tag::kind, profile_tag::next_block, sony_tag::next_block, profile_tag::prev_block, sony_tag::prev_block, profile_tag::rel_page, sony_tag::rel_page, profile_tag::reserved, sony_tag::reserved, SONY_BLOCK_NUMBER_MASK, profile_tag::version, sony_tag::version, profile_tag::volume, and sony_tag::volume.

Referenced by aaruf_write_sector_long().