DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦58a262d35⟧ Ada Source

    Length: 24576 (0x6000)
    Types: Ada Source
    Notes: 03_class, FILE, R1k_Segment, e3_tag, package Krn_Defs, seg_04cdf4

Derivation

└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
    └─ ⟦cfc2e13cd⟧ »Space Info Vol 2« 
        └─⟦this⟧ 

E3 Source Code



-- Copyright 1991,1992,1993 Verdix Corporation

with System;
use System;
with Krn_Cpu_Defs;
with Link_Block;
with V_I_Types;
with Unchecked_Conversion;
package Krn_Defs is
    pragma Suppress (All_Checks);
    pragma Suppress (Exception_Tables);
    pragma Not_Elaborated;
    pragma Local_Access;


    -- The Kernel's type definitions

    type A_Boolean is access Boolean;
    function To_A_Boolean is new Unchecked_Conversion (Address, A_Boolean);

    -- Forward references
    type Krn_Tcb_T;
    type A_Krn_Tcb_T is access Krn_Tcb_T;
    type Krn_Pcb_T;
    type A_Krn_Pcb_T is access Krn_Pcb_T;
-- SPORADIC_TASK
    type Krn_Sporadic_T;
    type A_Krn_Sporadic_T is access Krn_Sporadic_T;
-- SPORADIC_TASK

    -- Returned kernel service status
    No_Memory : constant := -1;
    Success : constant := 0;


    Delta_Time : constant Day_T := -1;

    -- Record types
    type Record_Type_T is (R_Invalid, R_Fifo_Cond, R_Prio_Cond,
                           R_Fifo_Cond_Attr, R_Prio_Cond_Attr, R_Fifo_Mutex,
                           R_Prio_Mutex, R_Prio_Inherit_Mutex,
                           R_Prio_Ceiling_Mutex, R_Intr_Mutex,
                           R_Fifo_Mutex_Attr, R_Prio_Mutex_Attr,
                           R_Prio_Inherit_Mutex_Attr, R_Prio_Ceiling_Mutex_Attr,
                           R_Intr_Mutex_Attr, R_Semaphore,
                           R_Semaphore_Attr, R_Count_Semaphore, R_Mailbox);

    -- Values corresponding to a zero/non-zero for the CPU specific
    -- test-and-set instruction
    type Test_And_Set_T is new V_I_Types.Test_And_Set_T;
    Test_And_Set_False : constant Test_And_Set_T :=
       Test_And_Set_T (V_I_Types.Test_And_Set_False);
    Test_And_Set_True : constant Test_And_Set_T :=
       Test_And_Set_T (V_I_Types.Test_And_Set_True);

    --------------------------------------------------------------------------
    -- Interrupt types (OS DEPENDENT)
    --------------------------------------------------------------------------

    -- Exception vector table ID's
    subtype Intr_Vector_Id_T is Natural;

    -- Interrupt enable/disable status: Interrupt Priority Level (IPL)
    -- mask stored in Status Register
    subtype Intr_Status_T is Integer;

    Disable_Intr_Status : constant Intr_Status_T := 16#0700#;
    Enable_Intr_Status : constant Intr_Status_T := 16#0000#;
    Level_0_Intr_Status : constant Intr_Status_T := 16#0000#;
    Level_1_Intr_Status : constant Intr_Status_T := 16#0100#;
    Level_2_Intr_Status : constant Intr_Status_T := 16#0200#;
    Level_3_Intr_Status : constant Intr_Status_T := 16#0300#;
    Level_4_Intr_Status : constant Intr_Status_T := 16#0400#;
    Level_5_Intr_Status : constant Intr_Status_T := 16#0500#;
    Level_6_Intr_Status : constant Intr_Status_T := 16#0600#;
    Level_7_Intr_Status : constant Intr_Status_T := 16#0700#;


    -- Value return for a bad intr_vector passed to the interrupt
    -- service routines
    Bad_Intr_Vector : constant Address := Memory_Address (16#FFFF_FFFF#);


    --------------------------------------------------------------------------
    -- Condition variable and mutex types
    --------------------------------------------------------------------------
    type Cond_Attr_T is
        record
            Rec_Type : Record_Type_T;
            -- valid rec_type are: R_FIFO_COND_ATTR | R_PRIO_COND_ATTR
        end record;
    type A_Cond_Attr_T is access Cond_Attr_T;
    function To_A_Cond_Attr_T is
       new Unchecked_Conversion (Address, A_Cond_Attr_T);
    function To_Address is new Unchecked_Conversion (A_Cond_Attr_T, Address);

--    DEFAULT_COND_ATTR: constant a_cond_attr_t := null;
    function Default_Cond_Attr return A_Cond_Attr_T;
    pragma Inline_Only (Default_Cond_Attr);

    type Cond_T is
        record
            Rec_Type : Record_Type_T;
            -- valid rec_type are: R_FIFO_COND | R_PRIO_COND
            T_Head : A_Krn_Tcb_T;
            T_Tail : A_Krn_Tcb_T;
        end record;
    type A_Cond_T is access Cond_T;
    function To_A_Cond_T is new Unchecked_Conversion (Address, A_Cond_T);
    function To_Address is new Unchecked_Conversion (A_Cond_T, Address);

    type Mutex_Attr_T is
        record
            Rec_Type : Record_Type_T;
            -- valid rec_type are: R_FIFO_MUTEX_ATTR | R_PRIO_MUTEX_ATTR
            -- also for PRIORITY_INHERITANCE: R_PRIO_INHERIT_MUTEX_ATTR
            Pad : Intr_Status_T;  -- must be large enough
                                  -- to accommodate space needed
                                  -- by other mutex attribute
            -- record types
        end record;
    type A_Mutex_Attr_T is access Mutex_Attr_T;
    function To_A_Mutex_Attr_T is
       new Unchecked_Conversion (Address, A_Mutex_Attr_T);
    function To_Address is new Unchecked_Conversion (A_Mutex_Attr_T, Address);

--    DEFAULT_MUTEX_ATTR: constant a_mutex_attr_t := null;
    function Default_Mutex_Attr return A_Mutex_Attr_T;
    pragma Inline_Only (Default_Mutex_Attr);

    type Intr_Attr_T is
        record
            Rec_Type : Record_Type_T;
            -- only valid rec_type is: R_INTR_MUTEX_ATTR
            Disable_Status : Intr_Status_T;
        end record;
    type A_Intr_Attr_T is access Intr_Attr_T;
    function To_A_Intr_Attr_T is
       new Unchecked_Conversion (Address, A_Intr_Attr_T);
    function To_A_Intr_Attr_T is new Unchecked_Conversion
                                        (A_Mutex_Attr_T, A_Intr_Attr_T);
    function To_A_Mutex_Attr_T is new Unchecked_Conversion
                                         (A_Intr_Attr_T, A_Mutex_Attr_T);
    function To_Address is new Unchecked_Conversion (A_Intr_Attr_T, Address);

--    DEFAULT_INTR_ATTR: constant a_mutex_attr_t :=
--\x09\x09to_a_mutex_attr_t(memory_address(1));
    function Default_Intr_Attr return A_Mutex_Attr_T;
    pragma Inline_Only (Default_Intr_Attr);

    type Prio_Ceiling_Attr_T is
        record
            Rec_Type : Record_Type_T;
            -- only valid rec_type is: R_PRIO_CEILING_MUTEX_ATTR
            Ceiling_Prio : Priority;
        end record;
    type A_Prio_Ceiling_Attr_T is access Prio_Ceiling_Attr_T;
    function To_A_Prio_Ceiling_Attr_T is
       new Unchecked_Conversion (Address, A_Prio_Ceiling_Attr_T);
    function To_A_Prio_Ceiling_Attr_T is
       new Unchecked_Conversion (A_Mutex_Attr_T, A_Prio_Ceiling_Attr_T);
    function To_A_Mutex_Attr_T is
       new Unchecked_Conversion (A_Prio_Ceiling_Attr_T, A_Mutex_Attr_T);
    function To_Address is new Unchecked_Conversion
                                  (A_Prio_Ceiling_Attr_T, Address);

    type Mutex_Pad_T is array (1 .. 2) of Intr_Status_T;
    type Mutex_T;
    type A_Mutex_T is access Mutex_T;
    type Mutex_T is
        record
            Rec_Type : Record_Type_T;
            -- valid rec_type are: R_FIFO_MUTEX | R_PRIO_MUTEX
            -- also for PRIORITY_INHERITANCE: R_PRIO_INHERIT_MUTEX
            -- also for PRIORITY_CEILING: R_PRIO_CEILING_MUTEX
            T_Head : A_Krn_Tcb_T;
            T_Tail : A_Krn_Tcb_T;
            Flag : Test_And_Set_T;
            Others_Waiting : Boolean;
            Owner : A_Krn_Tcb_T;  -- for INHERITANCE or CEILING
            Q_Next : A_Mutex_T;  --  "          "
            Ceiling_Prio : Integer;   -- for R_PRIO_CEILING_MUTEX
            Pad : Mutex_Pad_T;      -- must be large enough
                                    -- to accommodate space needed
                                    -- by other mutex record types
        end record;
    function To_A_Mutex_T is new Unchecked_Conversion (Address, A_Mutex_T);
    function To_Address is new Unchecked_Conversion (A_Mutex_T, Address);

    type Intr_Mutex_T is
        record
            Rec_Type : Record_Type_T;
            -- only valid rec_type is: R_INTR_MUTEX
            Disable_Status : Intr_Status_T;
            Restore_Status : Intr_Status_T;
        end record;
    type A_Intr_Mutex_T is access Intr_Mutex_T;
    function To_A_Intr_Mutex_T is
       new Unchecked_Conversion (A_Mutex_T, A_Intr_Mutex_T);
    function To_A_Mutex_T is new Unchecked_Conversion
                                    (A_Intr_Mutex_T, A_Mutex_T);
    function To_Address is new Unchecked_Conversion (A_Intr_Mutex_T, Address);

    --------------------------------------------------------------------------
    -- Semaphore types (Only FIFO queuing)
    --------------------------------------------------------------------------
    type Semaphore_T is
        record
            Rec_Type : Record_Type_T;
            -- only valid rec_type is: R_SEMAPHORE
            T_Head : A_Krn_Tcb_T;
            T_Tail : A_Krn_Tcb_T;
            Flag : Test_And_Set_T;
            Others_Waiting : Boolean;
        end record;
    type A_Semaphore_T is access Semaphore_T;
    function To_A_Semaphore_T is
       new Unchecked_Conversion (Address, A_Semaphore_T);
    function To_Address is new Unchecked_Conversion (A_Semaphore_T, Address);

    type Semaphore_Attr_T is
        record
            Rec_Type : Record_Type_T := R_Semaphore_Attr;
            -- only valid rec_type is: R_SEMAPHORE_ATTR
        end record;
    type A_Semaphore_Attr_T is access Semaphore_Attr_T;
    function To_A_Semaphore_Attr_T is
       new Unchecked_Conversion (Address, A_Semaphore_Attr_T);
    function To_Address is new Unchecked_Conversion
                                  (A_Semaphore_Attr_T, Address);
--    DEFAULT_SEMAPHORE_ATTR: constant a_semaphore_attr_t := null;
    function Default_Semaphore_Attr return A_Semaphore_Attr_T;
    pragma Inline_Only (Default_Semaphore_Attr);

    --------------------------------------------------------------------------
    -- Counting semaphore types
    --------------------------------------------------------------------------
    type Count_Semaphore_T is
        record
            Rec_Type : Record_Type_T;
            -- only valid rec_type is: R_COUNT_SEMAPHORE
            Mutex : Mutex_T;
            Cond : Cond_T;
            Count : Integer;
        end record;
    type A_Count_Semaphore_T is access Count_Semaphore_T;
    function To_A_Count_Semaphore_T is
       new Unchecked_Conversion (Address, A_Count_Semaphore_T);
    function To_Address is new Unchecked_Conversion
                                  (A_Count_Semaphore_T, Address);

    subtype Count_Semaphore_Attr_T is Mutex_Attr_T;
    subtype A_Count_Semaphore_Attr_T is A_Mutex_Attr_T;
    function To_A_Count_Semaphore_Attr_T is
       new Unchecked_Conversion (Address, A_Count_Semaphore_Attr_T);
--    DEFAULT_COUNT_SEMAPHORE_ATTR: constant a_count_semaphore_attr_t := null;
    function Default_Count_Semaphore_Attr return A_Count_Semaphore_Attr_T;
    pragma Inline_Only (Default_Count_Semaphore_Attr);

    subtype Count_Intr_Attr_T is Intr_Attr_T;
    subtype A_Count_Intr_Attr_T is A_Intr_Attr_T;
    function To_A_Count_Intr_Attr_T is
       new Unchecked_Conversion (Address, A_Count_Intr_Attr_T);
    function To_A_Count_Semaphore_Attr_T is
       new Unchecked_Conversion (A_Count_Intr_Attr_T, A_Count_Semaphore_Attr_T);

--    DEFAULT_COUNT_INTR_ATTR: constant a_count_semaphore_attr_t :=
--\x09\x09to_a_count_semaphore_attr_t(memory_address(1));
    function Default_Count_Intr_Attr return A_Count_Semaphore_Attr_T;
    pragma Inline_Only (Default_Count_Intr_Attr);

    --------------------------------------------------------------------------
    -- Mailbox types
    --------------------------------------------------------------------------
    type Unit_T is range -2 ** (Storage_Unit - 1) ..
                            2 ** (Storage_Unit - 1) - 1;
    for Unit_T'Size use Storage_Unit;
    type Slots_T is array (Positive range <>, Positive range <>) of Unit_T;
    type A_Slots_T is access Slots_T;
    function To_A_Slots_T is new Unchecked_Conversion (Address, A_Slots_T);
    function To_Address is new Unchecked_Conversion (A_Slots_T, Address);

    type Mailbox_T is
        record
            Rec_Type : Record_Type_T;
            -- only valid rec_type is: R_MAILBOX
            Mutex : Mutex_T;
            Read_Cond : Cond_T;
            Slots_Cnt : Natural;
            Slot_Len : Natural;
            Msg_Cnt : Natural;
            Bottom : Address;
            Top : Address;
            Read_Addr : Address;
            Write_Addr : Address;
        end record;
    type A_Mailbox_T is access Mailbox_T;
    function To_A_Mailbox_T is new Unchecked_Conversion (Address, A_Mailbox_T);
    function To_Address is new Unchecked_Conversion (A_Mailbox_T, Address);

    subtype Mailbox_Attr_T is Mutex_Attr_T;
    subtype A_Mailbox_Attr_T is A_Mutex_Attr_T;
    function To_A_Mailbox_Attr_T is      new Unchecked_Conversion (Address, A_Mailbox_Attr_T);
--    DEFAULT_MAILBOX_ATTR: constant a_mailbox_attr_t := null;
    function Default_Mailbox_Attr return A_Mailbox_Attr_T;
    pragma Inline_Only (Default_Mailbox_Attr);

    subtype Mailbox_Intr_Attr_T is Intr_Attr_T;
    subtype A_Mailbox_Intr_Attr_T is A_Intr_Attr_T;
    function To_A_Mailbox_Intr_Attr_T is
       new Unchecked_Conversion (Address, A_Mailbox_Intr_Attr_T);
    function To_A_Mailbox_Attr_T is
       new Unchecked_Conversion (A_Mailbox_Intr_Attr_T, A_Mailbox_Attr_T);

--    DEFAULT_MAILBOX_INTR_ATTR: constant a_mailbox_attr_t :=
--\x09\x09to_a_mailbox_attr_t(memory_address(1));
    function Default_Mailbox_Intr_Attr return A_Mailbox_Attr_T;
    pragma Inline_Only (Default_Mailbox_Intr_Attr);

    --------------------------------------------------------------------------
    -- Callout and task storage types
    --------------------------------------------------------------------------
    -- Callout events
    type Callout_Event_T is
       (Exit_Event, Unexpected_Exit_Event, Idle_Event,
        Program_Switch_Event,  -- stack limit checking must be suppressed
        Task_Create_Event, Task_Switch_Event, Task_Complete_Event);
    --[ Integer'size ne focntionne pas ]
    -- for Callout_Event_T'Size use Integer'Size;
    for Callout_Event_T'Size use 32;

    -- Id for accessing user defined storage in the task control block
    type Task_Storage_Id is new Integer;
    No_Task_Storage_Id : constant Task_Storage_Id := Task_Storage_Id (0);

    -- Callout Control Block
    type Callout_T;
    type A_Callout_T is access Callout_T;
    type A_A_Callout_T is access A_Callout_T;
    type Callout_T is
        record
            Q_Next : A_Callout_T;
            Proc : Address;
            Parent_Program : A_Krn_Pcb_T;  -- needed for program switch callout
        end record;
    function To_A_Callout_T is new Unchecked_Conversion (Address, A_Callout_T);
    function To_A_A_Callout_T is
       new Unchecked_Conversion (Address, A_A_Callout_T);

    type Calloutq_Heads_T is array (Callout_Event_T) of A_Callout_T;


    --------------------------------------------------------------------------
    -- Time event types
    --------------------------------------------------------------------------
    type Time_State_T is (Time_Stopped, Time_Counting,
                          Time_Overrun, Time_Canceled);

    type Time_Event_T;
    type A_Time_Event_T is access Time_Event_T;
    type Time_Event_T is
        record
            Q_Next : A_Time_Event_T;
            Q_Prev : A_Time_Event_T;
            Time_State : Time_State_T;
            Delay_Until_Flag : Boolean;
            Day : Day_T;
            Sec : Duration;
            Proc : Address;
            Arg : Address;
        end record;
    function To_A_Time_Event_T is
       new Unchecked_Conversion (Address, A_Time_Event_T);


    -- Program Control Block
    type Krn_Pcb_T is
        record
            Q_Next : A_Krn_Pcb_T;
            T_Head : A_Krn_Tcb_T;
            User_Link_Block : Link_Block.A_Link_Block_T;
            Terminated : Boolean;   -- program is terminated,
            -- but, waiting to be freed
            Prio_Inherit_Support : Boolean;   -- TRUE if kernel supports
            -- PRIORITY_INHERITANCE
            Prio_Ceiling_Support : Boolean;   -- TRUE if kernel supports
            -- PRIORITY_CEILING
            Sporadic_Task_Support : Boolean;   -- TRUE if kernel supports
            -- SPORADIC_TASK
            Is_Server : Boolean;   -- set via
            -- program_is_server()
            -- when program contains
            -- procedures called from
            -- other programs. Inhibits
            -- program termination.
            -- Allows kernel exit
            -- when no other programs
            -- are still active.
            My_Creator : A_Krn_Pcb_T;  -- parent program
            Terminate_Callout : Address;    -- defined at
            -- program create
            Exit_Status : Integer;   -- passed at program_exit
            Alloc_Head : Address;   -- krn_alloc.prog_new
            -- allocations
            Key : Address;   -- user defined at
            -- program create, main
            -- is predefined as NO_ADDR
            Sequence_Num : Integer;   -- eventhough newly created
            -- programs may share the
            -- same program control
            -- block, they have a
            -- unique sequence number
            Task_Storage_Avail : Integer;   -- index into next avail
            -- user storage in tcb
            Calloutq_Heads : Calloutq_Heads_T;
            Ada_Program_Id : Program_Id;
            Exception_Stack_Size : Natural;
        end record;
    function To_A_Krn_Pcb_T is new Unchecked_Conversion (Address, A_Krn_Pcb_T);

    type A_A_Krn_Pcb_T is access A_Krn_Pcb_T;
    function To_A_A_Krn_Pcb_T is
       new Unchecked_Conversion (Address, A_A_Krn_Pcb_T);

    type Tstate_T is (T_Created, T_Ready, T_Executing, T_Waiting,
                      T_Suspended_At_Cond, T_Suspended_At_Mutex,
                      T_Suspended_At_Semaphore, T_Suspended_At_Delay,
                      T_Suspended_At_Name_Resolve, T_Suspended_Idle_Task,
                      T_In_Transition, T_Terminated);

    Cpu_Number_Dont_Care : constant := -1;
    Cpu_Number_This_Cpu : constant := -2;

    -- Task control block
    type Krn_Tcb_T is
        record
            Cpu_State : Krn_Cpu_Defs.Cpu_State_T;
            Tstate : Tstate_T;
            Task_Suspended_Flag : Boolean; -- when set, a READY task isn't
            -- on the runq
            Q_Next : A_Krn_Tcb_T;
            Q_Prev : A_Krn_Tcb_T;
            T_Link : A_Krn_Tcb_T;

            Parent_Program : A_Krn_Pcb_T;

            -- The following changes during a usr_prog.program_inter_call().
            -- Otherwise, current_program = parent_program and
            -- current_stack_limit_p =
            -- parent_program.user_link_block.stack_limit_p.
            Current_Program : A_Krn_Pcb_T;
            Current_Stack_Limit_P : Address;

            Cond_Mutex : A_Mutex_T;
            Suspended_Queue : Address;
            Preemption_Depth : Natural;
            Signaled : Boolean;
            Cur_Prio : Integer;
            Delay_Event : Time_Event_T;
            Time_Slice : Duration;
            Start_Address : Address;
            Stack_Size : Natural;
            Stack_Area : Address;
            Ada_Task_Id : Task_Id;
-- PRIORITY_INHERITANCE or PRIORITY_CEILING or SPORADIC_TASK
            Mutex_Head : A_Mutex_T;
            Static_Prio : Integer;
-- PRIORITY_INHERITANCE or PRIORITY_CEILING or SPORADIC_TASK
-- SPORADIC_TASK
            Sporadic : A_Krn_Sporadic_T;
-- SPORADIC_TASK
            Sequence_Num : Integer; -- task's unique sequence number

            -- Storage available for the user follows the last field in the
            -- krn_tcb_t record. The size is specified by the configuration
            -- parameter, TASK_STORAGE_SIZE. The task's
            -- parent_program.task_storage_avail points to the next avail slot.
        end record;

    type A_A_Krn_Tcb_T is access A_Krn_Tcb_T;
    function To_A_A_Krn_Tcb_T is
       new Unchecked_Conversion (Address, A_A_Krn_Tcb_T);

-- SPORADIC_TASK begin
    type Krn_Replenishment_T;
    type A_Krn_Replenishment_T is access Krn_Replenishment_T;

    -- Sporadic task control block
    type Krn_Sporadic_T is
        record
            My_Tcb : A_Krn_Tcb_T;
            Low_Prio : Priority;
            Replenish_Period : Duration;
            Initial_Budget : Duration;
            Min_Replenishment : Duration;
            Replenishment_Count : Natural;
            S_Link : A_Krn_Sporadic_T;

            Avail_Exec_Time : Duration;
            Rep_Addr : Address;
            Rep_Head : A_Krn_Replenishment_T;
            Rep_Tail : A_Krn_Replenishment_T;
            Free_Rep_Head : A_Krn_Replenishment_T;
            Rep_Event : Time_Event_T;

            Force_High_Prio : Boolean;

-- SPORADIC_TASK_STATISTICS_ENABLED
            -- Statistics
            Exec_Cnt : Natural;
            Background_Exec_Cnt : Natural;
            Exec_Timeout_Cnt : Natural;
            Rep_Timeout_Cnt : Natural;
-- SPORADIC_TASK_STATISTICS_ENABLED
        end record;

    Zero_Avail_Exec_Time : constant Duration := 0.0;

    -- Sporadic task replenishment
    type Krn_Replenishment_T is
        record
            Next : A_Krn_Replenishment_T;
            Rep_Day : Day_T;
            Rep_Sec : Duration;
            Rep_Amount : Duration;
        end record;
-- SPORADIC_TASK end

    -- Ring for pending interrupt queue.
    type Ring_Entry_T is
        record
            Proc : Address;
            Arg : Address;
        end record;
    type A_Ring_Entry_T is access Ring_Entry_T;

    -- Name services entry
    type Name_Entry_T;
    type A_Name_Entry_T is access Name_Entry_T;
    type Name_Entry_T is
        record
            Next : A_Name_Entry_T;
            Name_Len : Natural;
            Name_Addr : Address;
            Prg : A_Krn_Pcb_T;
            Addr : Address;
        end record;
    function To_A_Name_Entry_T is
       new Unchecked_Conversion (Address, A_Name_Entry_T);



end Krn_Defs;

E3 Meta Data

    nblk1=17
    nid=0
    hdr6=2e
        [0x00] rec0=28 rec1=00 rec2=01 rec3=07c
        [0x01] rec0=13 rec1=00 rec2=02 rec3=00e
        [0x02] rec0=15 rec1=00 rec2=03 rec3=070
        [0x03] rec0=19 rec1=00 rec2=04 rec3=05c
        [0x04] rec0=17 rec1=00 rec2=05 rec3=00e
        [0x05] rec0=15 rec1=00 rec2=06 rec3=064
        [0x06] rec0=19 rec1=00 rec2=07 rec3=01c
        [0x07] rec0=14 rec1=00 rec2=08 rec3=044
        [0x08] rec0=17 rec1=00 rec2=09 rec3=01a
        [0x09] rec0=15 rec1=00 rec2=0a rec3=03a
        [0x0a] rec0=15 rec1=00 rec2=0b rec3=032
        [0x0b] rec0=14 rec1=00 rec2=0c rec3=06a
        [0x0c] rec0=1a rec1=00 rec2=0d rec3=002
        [0x0d] rec0=14 rec1=00 rec2=0e rec3=012
        [0x0e] rec0=17 rec1=00 rec2=0f rec3=09c
        [0x0f] rec0=1e rec1=00 rec2=10 rec3=016
        [0x10] rec0=17 rec1=00 rec2=11 rec3=046
        [0x11] rec0=16 rec1=00 rec2=12 rec3=054
        [0x12] rec0=1a rec1=00 rec2=13 rec3=07a
        [0x13] rec0=19 rec1=00 rec2=14 rec3=04a
        [0x14] rec0=1b rec1=00 rec2=15 rec3=024
        [0x15] rec0=21 rec1=00 rec2=16 rec3=00a
        [0x16] rec0=16 rec1=00 rec2=17 rec3=000
    tail 0x2175420be874f7bd1415b 0x42a00088462060003