program-format: AND-record u16s are BE on disk (verified empirically)
Authored AND IF ZONE 5 SECURE in PC Access and diffed against AND IF NEVER. The zone number 5 lands at byte 4 (high-offset of the u16), confirming that Arg1_IX / Arg2_IX / CompConst in AND records use big-endian byte order on disk. This is the opposite of compact-form cond / cond2 / pr2 which are LE. Different record families use different byte orders. Convert the earlier "open question" caution to a confirmation note, and add a separate caution for the remaining open question about byte 1's semantic role (OP vs family code).
This commit is contained in:
parent
7a766d69ba
commit
7d53992841
@ -426,16 +426,37 @@ AND record's condition is rendered from the **`Cond` u16 at bytes
|
|||||||
`OP > 0`. So the same byte positions serve double duty: as `Cond`
|
`OP > 0`. So the same byte positions serve double duty: as `Cond`
|
||||||
(traditional) or as `OP` + `Arg1_ArgType` (structured).
|
(traditional) or as `OP` + `Arg1_ArgType` (structured).
|
||||||
|
|
||||||
:::caution[Open: disk byte order for `Arg1_IX` / `Arg2_IX` / `CompConst`]
|
:::note[Disk byte order: BE for AND records (verified)]
|
||||||
The C# `clsProgram.Read` reads u16 fields **little-endian** via
|
Authored an `AND IF ZONE 5 SECURE` capture and diffed it against an
|
||||||
`clsPcaCryptFileStream.ReadUInt16`, but the `Arg1_IX` /
|
`AND IF NEVER`:
|
||||||
`Arg2_IX` / `CompConst` accessors index `Data[]` as **big-endian**.
|
|
||||||
This implies an implicit byte swap somewhere we haven't fully traced.
|
```
|
||||||
Our one captured `AND IF NEVER` record (`08 00 00 00 01 00 00 00 00
|
NEVER: 08 00 00 00 01 ...
|
||||||
00 00 00 00 00`) is byte-symmetric (all zero except byte 4 = `0x01`)
|
ZONE 5 SECURE: 08 04 00 00 05 ...
|
||||||
so it doesn't disambiguate. Resolving the disk byte order needs a
|
↑ ↑
|
||||||
controlled capture of `AND IF ZONE 5 SECURE` or `AND IF UNIT 7 ON` —
|
byte 1 byte 4
|
||||||
the first non-symmetric example will pin it down.
|
```
|
||||||
|
|
||||||
|
The zone number `5` lands in **byte 4** (high-offset byte of the
|
||||||
|
positions 3-4 u16). If disk were LE the `5` would be in byte 3. So
|
||||||
|
**`Arg1_IX` / `Arg2_IX` / `CompConst` are big-endian on disk for
|
||||||
|
AND records** — opposite of compact-form `cond` / `cond2` / `pr2`
|
||||||
|
which are LE. The two record families use different byte orders;
|
||||||
|
the C# encoder writes AND records' u16s directly in BE matching
|
||||||
|
the in-memory `Data[]` layout. Compact-form fields go through
|
||||||
|
`Cond`/`Cond2`/`Pr2` setters that swap to LE on the wire.
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::caution[Still open: byte 1's semantic role]
|
||||||
|
For `AND IF ZONE 5 SECURE`, byte 1 = `0x04`. The C# accessor at
|
||||||
|
`clsProgram.cs:326` says `OP = Data[1]` and `0x04 = Arg1_GT_Arg2` —
|
||||||
|
which makes no sense for a zone-state check. But `0x04` *also* matches
|
||||||
|
the compact-form `ProgramCond.ZONE` family code. So byte 1 is
|
||||||
|
probably the **condition family code** (re-using compact-form
|
||||||
|
semantics) when `OP == Arg1_Traditional` (the implicit case), and
|
||||||
|
only acts as the structured `OP` when the user has actually picked
|
||||||
|
a comparison operator. Resolving this needs a capture of an
|
||||||
|
explicitly-structured AND like `AND IF TEMPERATURE > 70`.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
A 5-record block from our test fixture (one WHEN, three ANDs, one
|
A 5-record block from our test fixture (one WHEN, three ANDs, one
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user