+
    lijj                    r    R t ^ RIHt ^ RIHt  ! R R]4      t] ! R R4      4       tRR R lltR	 R
 lt	R# )a  Intel HEX encode/decode.

Intel HEX itself is a public, well-documented format (unlike the Roboteq
bytecode it will eventually carry -- see docs/reverse_engineering.md), so
this module is implemented for real rather than stubbed. It's also useful
right now for reverse-engineering work: `read_intel_hex` can load .hex
files exported from RoborunPlus so they can be diffed byte-for-byte.

Only record types 00 (Data) and 01 (End Of File) are handled -- Roboteq
scripts are small enough that extended segment/linear address records
(02/03/04/05) are not expected to be needed, but that assumption should be
verified against real exported files during reverse engineering.
)annotations)	dataclassc                      ] tR t^tRtR# )HexFormatError N)__name__
__module____qualname____firstlineno____static_attributes__r       m\\thalassa.shore.mbari.org\ProjectLibrary\ESP\FIDO\PumpController\compiler\src\microbasic_compiler\hexfile.pyr   r      s    r   r   c                  X    ] tR t^t$ R]R&   R]R&   R]R&   R]R&   R R ltR	 R
 ltRtR# )	HexRecordint
byte_countaddressrecord_typebytesdatac                   V ^8  d   QhRR/# )   returnr   r   )formats   "r   __annotate__HexRecord.__annotate__   s      # r   c                	    V P                   V P                  ^,	          ,           V P                  ^,          ,           V P                  ,           \        V P                  4      ,           pV) ^,          # )   )r   r   r   sumr   )selftotals   & r   checksumHexRecord.checksum   s`    OO||q "||d"$  $))n	 	 $r   c                   V ^8  d   QhRR/# )r   r   strr   )r   s   "r   r   r   )   s     C C Cr   c                	&   \        V P                  V P                  ^,	          V P                  ^,          V P                  .4      V P                  ,           pRVP                  4       P                  4       ,           V P                  4       R ,           # )r   :02X)r   r   r   r   r   hexupperr!   )r   bodys   & r   to_lineHexRecord.to_line)   sg    doot||q'8$,,:MtO_O_`adhdmdmmTXXZ%%''T]]_S,ABBr   r   N)r   r   r	   r
   __annotations__r!   r+   r   r   r   r   r   r      s(    OL
KC Cr   r   c               (    V ^8  d   QhRRRRRRRR/# )r   r   r   start_addressr   bytes_per_liner   r$   r   )r   s   "r   r   r   .   s)     # #% # # #VY #r   c                   V^8  g   V^8  d   \        R4      h\        V 4      V,          pV'       d   V RW#,
          ,          ,           p . pTp\        ^ \        V 4      V4       F]  pWWb,            p\        \        V4      VR,          ^ VR7      pVP	                  VP                  4       4       V\        V4      ,          pK_  	  \        ^ ^ ^RR7      p	VP	                  V	P                  4       4       RP                  V4      R,           # )a   Encode `data` as Intel HEX text (data records + trailing EOF record).

CONFIRMED (gosub_distance corpus, 2026-07-28): real RoborunPlus-exported
.hex always pads the final line out to a full `bytes_per_line` (16)
bytes with 0xFF, rather than emitting a short last record for whatever
remainder doesn't divide evenly. Every one of the 6 distance test cases
(12/212/262/267/512/962 raw bytes) came back from RoborunPlus padded up
to the next 16-byte boundary (16/224/272/272/... bytes) with the
difference being solely trailing 0xFF -- 0 differing bytes in the shared
range in all 6 cases, confirming GoSub codegen itself is correct
(including across the 256-byte 1-vs-2-byte-address boundary). Padding
here so our .hex output matches real compiler output byte-for-byte.
z(bytes_per_line must be between 1 and 255   i  r   r   r   r   r   
)
ValueErrorlenranger   appendr+   join)
r   r/   r0   	remainderlinesaddroffsetchunkrecordeofs
   &&&       r   write_intel_hexrA   .   s     ^c1CDDD	N*Ig!;<<ED3t9n5f56c%j$-UY`efV^^%&E
	 6 q!C
HC	LL99Ud""r   c                    V ^8  d   QhRRRR/# )r   textr$   r   r   r   )r   s   "r   r   r   P   s     " " " "r   c                   \        4       p\        V P                  4       ^R7       EF5  w  r#VP                  4       pV'       g   K   VP	                  R4      '       g   \        RV R24      h \        P                  VR,          4      p\        T4      ^8  d   \        RT R24      hT^ ,          T^,          T^,          T^,          3w  rxrT^^T,            pT^T,           ,          p\        Yx^,          T	,          YR	7      pTP                  4       T8w  d   \        RT R
24      hT
^ 8X  d   TP                  T4       EK  T
^8X  d    M\        RT RT
R 24      h	  \        V4      #   \         d   p\        RT R24      ThRp?ii ; i)zDecode Intel HEX text back into a flat byte string (data records only,
concatenated in file order -- does not attempt to place bytes at their
absolute addresses since that's not needed for diffing bytecode dumps).
)startr&   zline z: missing ':' start code:   NNz: invalid hex dataNz: record too shortr3   z: checksum mismatchz: unsupported record type 0xr'   )	bytearray	enumerate
splitlinesstrip
startswithr   r   fromhexr5   r6   r   r!   extend)rC   outlinenoraw_lineliner*   excr   addr_hiaddr_lor   payloadr!   r?   s   &             r   read_intel_hexrV   P   s   
 +C%doo&7qAA~~s## 50H!IJJ	N==b*D t9q= 50B!CDD48GT!Wd1gtTUw4V1
Wq1z>*J'ja<7:R`kz??( 50C!DEE$JJwD  50L[Y\L]!^__5 B8 :)  	N 50B!CD#M	Ns   -E++F6FFN)       )
__doc__
__future__r   dataclassesr   	Exceptionr   r   rA   rV   r   r   r   <module>r]      sE    # !	Y 	 C C C*#D"r   