DataMuseum.dk

Presents historical artifacts from the history of:

Bogika Butler

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

See our Wiki for more about Bogika Butler

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦8ca895bba⟧ TextFile

    Length: 114816 (0x1c080)
    Types: TextFile
    Names: »KERNEL.PRN«

Derivation

└─⟦08e5746f0⟧ Bits:30009789/_.ft.Ibm2.50007359.imd Mogens Pelles Zilog 80,000 / EOS projekt
    └─⟦this⟧ »KERNEL.PRN« 

TextFile

Pro Pascal Compiler - Version zz 2.1

Compilation of: B:KERNEL.PAS

Options:    LNIAG

    1   0000    (*
    2   0000    ***********************************************************************
    3   0000    *                       Copyright 1984 by                             *
    4   0000    *                       NCR Corporation                               *
    5   0000    *                       Dayton, Ohio  U.S.A.                          *
    6   0000    *                       All Rights Reserved                           *
    7   0000    ***********************************************************************
    8   0000    *                       EOS Software produced by:                     *
    9   0000    *                       NCR Systems Engineering - Copenhagen          *
   10   0000    *                       Copenhagen                                    *
   11   0000    *                       DENMARK                                       *
   12   0000    ***********************************************************************
   13   0000    *                       EOS Software rewritten by:                    *
   14   0000    *                       Metanic Aps.                                  *
   15   0000    *                       DK-3660 Stenloese                             *
   16   0000    *                       DENMARK                                       *
   17   0000    *                                                                     *
   18   0000    *                       Copyright 1986 by Metanic Aps.                *
   19   0000    ***********************************************************************
   20   0000    *)
   21   0000    PROGRAM EosKernel;
   22   0000    
   23   0000    (*$I B:COMDEF.PAS *)
   24   0000    (*
   25   0000    ***********************************************************************
   26   0000    *                       Copyright 1984 by                             *
   27   0000    *                       NCR Corporation                               *
   28   0000    *                       Dayton, Ohio  U.S.A.                          *
   29   0000    *                       All Rights Reserved                           *
   30   0000    ***********************************************************************
   31   0000    *                       EOS Software produced by:                     *
   32   0000    *                       NCR Systems Engineering - Copenhagen          *
   33   0000    *                       Copenhagen                                    *
   34   0000    *                       DENMARK                                       *
   35   0000    ***********************************************************************
   36   0000    *                       EOS Software rewritten by:                    *
   37   0000    *                       Lars G. Jakobsen                              *
   38   0000    *                       Metanic Aps.                                  *
   39   0000    *                       DK-3660 Stenloese                             *
   40   0000    *                       DENMARK                                       *
   41   0000    *                                                                     *
   42   0000    *                       Copyright 1986 by Metanic Aps.                *
   43   0000    ***********************************************************************
   44   0000    *)
   45   0000    (*
   46   0000    
   47   0000    This file defines constants, data types and primitive operations
   48   0000    on abstract datatypes.
   49   0000         Names of constants and fields of structures complies with the
   50   0000    names used by NCR secp in the Motorola EXORmacs 680000 implementation
   51   0000    of the kernel.
   52   0000    
   53   0000    *)
   54   0000    
   55   0000       TYPE
   56   0000          long = integer;
   57   0000          word = 0..65535;
   58   0000          byte = 0..255;
   59   0000          AddressType = integer; (* Used to represent assembler chaining
   60   0000                                    fields instead of ordinary pascal
   61   0000                                    pointers *)
   62   0000          PhysicalAddressType = integer;
   63   0000    
   64   0000    (*---------------------------------------------------------------------
   65   0000      CHAIN AND MEMBER   *)
   66   0000    
   67   0000       TYPE
   68   0000          ChainPointerType = ^ChainType;
   69   0000    
   70   0000          ChainType = RECORD
   71   0000             Next: ChainPointerType; (* next element, always meaningful *)
   72   0000             Prev: ChainPointerType; (* previous element, always meaningful *)
   73   0000            END;
   74   0000    
   75   0000          MemberType = RECORD
   76   0000             Chain: ChainType;
   77   0000             Ch_hold: AddressType;      (* Addr of structure holding chain head *)
   78   0000            END;
   79   0000    
   80   0000       CONST
   81   0000          Ch_siz = 4;            (* Number of word in chain *)
   82   0000          Member = 6;            (* Number of word in member element *)
   83   0000    
   84   0000    (*---------------------------------------------------------------------
   85   0000      SIZE TYPE  *)
   86   0000    
   87   0000       TYPE
   88   0000          SizeType = RECORD
   89   0000             UserPart: long;     (* no. of bytes in user part *)
   90   0000             KnelPart: word;     (* no. of bytes in kernel part *)
   91   0000            END;
   92   0000    
   93   0000       CONST
   94   0000          Sz_siz = 6;            (* size of size type *)
   95   0000          Sz_typ = 3;            (* number of words in size type *)
   96   0000    
   97   0000    (*--------------------------------------------------------------------
   98   0000      POINTER AND FORMAL POINTER  *)
   99   0000    
  100   0000       TYPE
  101   0000          PointerKindType =
  102   0000             (pt_nil   (* nil   often set with clear instruction *)
  103   0000             ,pt_obj   (* refObj                                 *)
  104   0000             ,pt_env   (* refEnv  ( <= pt_env means simple ref)  *)
  105   0000             ,pt_own   (* ownSet                                 *)
  106   0000             ,pt_man   (* manSet                                 *)
  107   0000             ,pt_int   (* interrupt pointer, always local (refers to a code segment)*)
  108   0000             ,pt_mmu   (* mmuDescription ref to object (not a real pointer)         *)
  109   0000             ,pt_seg   (* segmentDescription ref to object (not a real pointer)     *)
  110   0000             );
  111   0000          (* VOID argument encoded as 6 = pt_mmu. Used for argument check *)
  112   0000             pt_voi = (.pt_int..pt_seg.); (* *** ??? *** *)
  113   0000    
  114   0000          PointerInfoKindType = (interrupt_pointer, non_interrupt_pointer);
  115   0000    
  116   0000          PointerInfoBaseType =
  117   0000             (* Comments describe the meaning of the elements belonging to the set *)
  118   0000             (.pt_lsc     (* 0 local scope pointer *)
  119   0000              ,pt_tsc     (* 1 temp scope pointer  *)
  120   0000              ,pt_fsc     (* 2 formal scope pointer *)
  121   0000              ,pt_cc      (* 3 simple pointer with call capability (0 if nil) *)
  122   0000              ,pt_con     (* 4 manager enforces copy control (0 if nil) *)
  123   0000              ,pt_io      (* 5 simple pointer with io-lock (0 if nil) *)
  124   0000              ,pt_res     (* 6 simple pointer with resident lock (0 if nil ) *)
  125   0000              ,pt_ret     (* 7 formal return pointer (also=1 for dummy actual) *)
  126   0000             .)
  127   0000    
  128   0000          PointerInfoSetType = SET of PointerInfoBaseType;
  129   0000    
  130   0000          PointerInfoType = RECORD
  131   0000    
  132   0000             (* The Pascal interpretation of PointerInfoType is based on
  133   0000                the declarations in kernel.comdef.sa page 2 and the usage
  134   0000                shown at entry simplpt of kernel.mmprocs.sa page 41. *)
  135   0000    
  136   0000          CASE PointerInfoKindType OF
  137   0000          interrupt_pointer:        (* For interrupt pointers all bits of pt_inf
  138   0000                                       represent the interrupt vector number *)
  139   0000             (pt_inf: byte
  140   0000             );
  141   0000          non_interrupt_pointer:
  142   0000             (pt_inf: PointerInfoSetType
  143   0000             )
  144   0000            END;
  145   0000    
  146   0000    
  147   0000          PointerCommonPartType = RECORD
  148   0000             Pointer: memberType;
  149   0000                       (* ownset and manset: pointer -> obj or env
  150   0000                          refobj and refenv: obj or env -> pointer
  151   0000                          nil: empty chain.
  152   0000                          ch_hold (named pt_ref):
  153   0000                          ownset, manset, nil: not used.
  154   0000                          refobj and refenv: addr of obj or env.
  155   0000                       *)
  156   0000             pt_kin: PointerKindType;
  157   0000                      (* pointer kind. See above *)
  158   0000             pt_inf: PointerInfoType;
  159   0000                     (* pointer inf. See above. pt_kin+pt_inf=word *)
  160   0000            END;
  161   0000    
  162   0000          PointerFormalPartType = RECORD
  163   0000             (* part only present for formal pointers *)
  164   0000             fp_act: memberType; (* actual: env or ctx -> formal pointer
  165   0000                                    ch_hold (named fp_str):
  166   0000                                    addr of env or ctx structure, 0 if dummy
  167   0000                                 *)
  168   0000             fp_off: word;       (* actual pointer offset within env or ctx *)
  169   0000            END;
  170   0000    
  171   0000          PointerType = RECORD
  172   0000             Common: PointerCommonPartType
  173   0000            END;
  174   0000    
  175   0000          FormalPointerType = RECORD
  176   0000             Common: PointerCommonPartType;
  177   0000             Formal: PointerFormalPartType
  178   0000            END;
  179   0000    
  180   0000       CONST
  181   0000          pt_siz = sizeof(PointerCommonPartType);
  182   0000                                 (* size of non-formal pointer *)
  183   0000          fp_siz = sizeof(FormalPointerType);
  184   0000                                 (* size of formal pointer *)
  185   0000             (* fp_siz must be less than or equal to fp_pow2 = 32 *)
  186   0000          fp_pow2 = 32;
  187   0000          pt_mask = (2**15)/fp_pow2 - 1;
  188   0000                                 (* mask for pointer index <= 2**15/fp_siz *)
  189   0000    
  190   0000    (*--------------------------------------------------------------------
  191   0000      OBJECT COMMON PART  *)
  192   0000    
  193   0000       TYPE
  194   0000          ObjectKindType =
  195   0000             (OB_GEOB  (* 0 General object *)
  196   0000             ,OB_GAOB  (* 1 Gate object *)
  197   0000             ,OB_COOB  (* 2 Condition object *)
  198   0000             ,OB_OPOB  (* 3 Open object *)
  199   0000             ,OB_DOOB  (* 4 Dormant object *)
  200   0000             ,OB_PROB  (* 5 Process object *)
  201   0000             ,OB_EXOB  (* 6 Extension object (Kind not visible to user) *)
  202   0000             ,OB_SEOB  (* 7 Segment object (emb or non-emb, subsegm or root segm) *)
  203   0000             ,OB_ALLO  (* 8 Allocate *)
  204   0000             ,OB_SCHE  (* 9 Internal scheduler *)
  205   0000             );
  206   0000    
  207   0000          ObjectStateBaseType =
  208   0000             (OB_REEN  (* 0 Reentrant object (only general objects) *)
  209   0000             ,OB_EMB   (* 1 Embedded object  (only general objects) *)
  210   0000             ,OB_SUB   (* 2 Subsegment object *)
  211   0000             ,OB_OCC   (* 3 Owner has call capability (only general objects) *)
  212   0000             ,OB_READ  (* 4 Read allowed (only segment objects) *)
  213   0000             ,OB_WRIT  (* 5 Write allowed (only segment objects) *)
  214   0000             ,OB_EXEC  (* 6 Execute allowed (only segment objects) *)
  215   0000             ,OB_ABOR  (* 7 Aborted object (General and segment objects) *)
  216   0000             );
  217   0000    
  218   0000          ObjectStateType = SET OF ObjectStateBaseType;
  219   0000    
  220   0000       CONST
  221   0000          OB_SEGM: ObjectStateType = (. OB_READ, OB_WRIT, OB_EXEC .);
  222   0000          OB_SUBS: ObjectStateType = (. OB_SUB, OB_SEGM .);
  223   0000    
  224   0000       TYPE
  225   0000          ObjectCommonPartType = RECORD
  226   0000             Owner: MemberType;
  227   0000                       (* Ownset -> Object
  228   0000                          OB_Own = Ch_hold: addr. of owner env or ctx *)
  229   0000             OB_Off: word;
  230   0000                       (* Owner pointer offset in env or ctx
  231   0000                          (0 for initial owner pointer) *)
  232   0000             OB_Ref: ChainType;
  233   0000                       (* Referred by: Object -> RefObj, SebSegm, MMUdescr *)
  234   0000             OB_Res: word;
  235   0000                       (* Resident Count: Non segment object = #res_pt
  236   0000                          to object *)
  237   0000             OB_SizK: word;
  238   0000                       (* Size of kernel part (used also for emb obj) *)
  239   0000             OB_Kin: ObjectKindType;
  240   0000                       (* See above *)
  241   0000             OB_Sta: ObjectStateType;
  242   0000                       (* See above *)
  243   0000             OB_Spa: AddressType;
  244   0000    (* *** ??? *** *)
  245   0000                       (* Space descr: Top Object, abs. ddr.
  246   0000                          Disagrees with size of object during
  247   0000                          relocation (not used for embedded objects) *)
  248   0000            END;
  249   0000    
  250   0000    
  251   0000       CONST
  252   0000          OB_Siz = sizeof(ObjectCommonPartType);
  253   0000    
  254   0000    (*--------------------------------------------------------------------
  255   0000      SPACE DESCRIPTION, PRESENT ONLY FOR NON-EMBEDDED OBJECTS
  256   0000      ADDRESSES RELATIVE TO TOP OF KERNEL PART  See kernel.comdef.sa p 3. *)
  257   0000    
  258   0000       TYPE
  259   0000          SpaceDescriptionType = RECORD
  260   0000             Sp_env: ChainType;  (* Envelope stack: Object -> env *)
  261   0000             Sp_fre: SizeType;   (* Free bytes. User and kernel part *)
  262   0000             Sp_FirU: long;      (* First free. User part *)
  263   0000             Sp_Firk: long;      (* First free. Kernel part *)
  264   0000             Sp_SizU: long;      (* Total size. User part *)
  265   0000            END;
  266   0000    
  267   0000    (*--------------------------------------------------------------------
  268   0000      GATE OBJECT  *)
  269   0000    
  270   0000       TYPE
  271   0000          GateChainArrayIndexType =
  272   0000             (GA_lok   (* Locking: Gate -> processes waiting on gate.lock *)
  273   0000             ,GA_relok (* Relocking: Gate -> Processes relocking after being
  274   0000                          signalled *)
  275   0000             ,GA_splok (* Speed reloking: Gate -> Processes relocking after
  276   0000                          speed up or time out *)
  277   0000             );
  278   0000    
  279   0000          GateStateType =
  280   0000             (open
  281   0000             ,locked
  282   0000             );
  283   0000    
  284   0000          GateLevelType =
  285   0000             (Normal
  286   0000             ,device1
  287   0000             ,device2
  288   0000             ,device3
  289   0000             ,device4
  290   0000             ,device5
  291   0000             ,device6
  292   0000             ,device7
  293   0000             );
  294   0000    
  295   0000    
  296   0000          ObjectGatePartType = RECORD
  297   0000             GA_sch: PointerCommonPartType;
  298   0000                       (* ObjRef to Scheduler obj or nil *)
  299   0000             GA_set: ChainType;
  300   0000                       (* ManSet: Gate -> Cond *)
  301   0000             GA_array: ARRAY (. GateChainArrayIndexType .) OF ChainType;
  302   0000             GA_sta: GateStateType; (* open = 0,  locked = 2**7=128 *)
  303   0000    (* *** ??? *** could it be boolean ??? *)
  304   0000             GA_lev: GateLevelType
  305   0000            END;
  306   0000    
  307   0000          GateObjectType = RECORD
  308   0000             ObjectCommonPart: ObjectCommonPartType;
  309   0000             ObjectGatePart: ObjectGatePartType
  310   0000            END;
  311   0000    
  312   0000       CONST
  313   0000          GA_siz = sizeof(GateObjectType);
  314   0000    
  315   0000    (*--------------------------------------------------------------------
  316   0000      CONDITION OBJECT  *)
  317   0000    
  318   0000       TYPE
  319   0000          ObjectConditionPartType = RECORD
  320   0000             CO_man: MemberType; (* Manager: manset in gate -> condition
  321   0000                                    CO_GA = ch_hold: addr. of managing
  322   0000                                    gate object. 0 when cond is aborted *)
  323   0000             CO_wait: ChainType; (* Waiting: condition -> processes
  324   0000                                    waiting on cond.wait *)
  325   0000            END;
  326   0000    
  327   0000          ConditionObjectType = RECORD
  328   0000             CommonPart: ObjectCommonPartType;
  329   0000             ConditionPart: ObjectConditionPartType
  330   0000            END;
  331   0000    
  332   0000       CONST
  333   0000          CO_Siz = sizeof(ConditionObjectType);
  334   0000    
  335   0000    (*--------------------------------------------------------------------
  336   0000      EXTENSION AND PROCESS OBJECT *)
  337   0000    
  338   0000       TYPE
  339   0000          ObjectExtensionPartType = RECORD
  340   0000             EX_ctx: ChainType;  (* Contexts: Extension obj-> ctx *)
  341   0000             EX_ext: MemberType; (* Extension: Process obj -> ext
  342   0000                                    EX_pr = CH_hold = address of process obj *)
  343   0000            END;
  344   0000    
  345   0000          RegisterType = long;
  346   0000    
  347   0000          RegisterSaveAreaIndexType = 1..12;
  348   0000          RegisterSaveAreaType = ARRAY (. RegisterSaveAreaIndexType .) OF
  349   0000             RegisterType;
  350   0000    
  351   0000          TimeType = RECORD
  352   0000             MSL: long;
  353   0000             LSL: long
  354   0000            END;
  355   0000    
  356   0000          ProcessPriorityType = byte;
  357   0000    (* *** ??? *** *)
  358   0000    
  359   0000          ProcessStateType = (run      (* 0 *)
  360   0000                             ,wait     (* 2 *)
  361   0000                             ,d_wait   (* 4 *)
  362   0000                             ,lock     (* 6 *)
  363   0000                             ,signld   (* 8 *)
  364   0000                             );
  365   0000    
  366   0000          SynchronizationResultType = byte;
  367   0000    (* *** ??? *** *)
  368   0000    
  369   0000          ObjectProcessPartType = RECORD
  370   0000             PR_main: ChainType; (* Main queue: Gate locking, gate relocking,
  371   0000                                                gate speed lock, timer or
  372   0000                                                driving -> process *)
  373   0000             PR_aux: MemberType; (* Aux queue: Condition, running, se_wait,
  374   0000                                               pr_term, mm_queue -> process
  375   0000                                               PR_con = CH_hold = address of
  376   0000                                               condition object or undef *)
  377   0000             PR_term: ChainType; (* Proc. waiting for terminate: proc->proc *)
  378   0000             PR_d0.a3: RegisterSaveAreaType;
  379   0000                                 (* Register save area: Used between time slices.
  380   0000                                    Alloc saves part of stack, not gers. *)
  381   0000             PR_timo: TimeType;  (* Time out: 64 bit point in time for
  382   0000                                              reschedule *)
  383   0000             PR_cpu: TimeType;   (* Cpu time: No of usec used by the process
  384   0000                                              (64bits) *)
  385   0000             PR_pri: ProcessPriorityType;
  386   0000                                 (* Priority: Used for interrupt level and
  387   0000                                              lock control *)
  388   0000             PR_sta: ProcessStateType;
  389   0000                                 (* Used when a "process" is speeded up *)
  390   0000             PR_syn: SynchonizationResultType;
  391   0000                                 (* Result of a sync_func. (e.g. wait) *)
  392   0000            END;
  393   0000    
  394   0000          ExtensionObjectType = RECORD
  395   0000             CommonPart: ObjectCommonPartType;
  396   0000             ExtensionPart: ObjectExtensionPartType
  397   0000            END;
  398   0000    
  399   0000          ProcessObjectType = RECORD
  400   0000             CommonPart: ObjectCommonPartType;
  401   0000             ExtensionPart: ObjectExtensionPartType;
  402   0000             ProcessPart: ObjectProcessPartType
  403   0000            END;
  404   0000    
  405   0000       CONST
  406   0000          EX_siz = sizeof(ExtensionObjectType);
  407   0000          PR_siz = sizeof(ProcessObjectType);
  408   0000    
  409   0000    (*--------------------------------------------------------------------
  410   0000      SEGMENT AND SUBSEGMENT OBJECT  *)
  411   0000    
  412   0000       TYPE
  413   0000          ObjectSegmentPartType = RECORD
  414   0000             SE_io: word;        (* IO_count: #io_refs to segment and to
  415   0000                                              sub segments *)
  416   0000             SE_fir: PhysicalAddressType;
  417   0000                                 (* First physical address of user segment
  418   0000                                    (even). Undefined when segment is aborted *)
  419   0000             SE_len: long;       (* Length of user segment (even). Undefined
  420   0000                                    when segment is aborted *)
  421   0000             SE_wait: ChainType; (* IO_count_wait: segm -> proc waiting for
  422   0000                                                   io_count to become 0 *)
  423   0000           END;
  424   0000    
  425   0000          ObjectSubSegmentPartType = RECORD
  426   0000             SU_p: PointerType;  (* Points to base segment or subsegment.
  427   0000                                    SU_ref = PT_ref = address of base segment
  428   0000                                                      or sub segment (0 if
  429   0000                                                      base segment removed)
  430   0000                                    SU_kin = PT_kin = Kind (=subsegment(=PT_seg))
  431   0000                                    SU_inf = PT_inf   Not used. *)
  432   0000            END;
  433   0000    
  434   0000          SegmentObjectType = RECORD
  435   0000             CommonPart: ObjectCommonPartType;
  436   0000             SegmentPart: ObjectSegmentPartType
  437   0000            END;
  438   0000    
  439   0000          SubSegmentObjectType = RECORD
  440   0000             CommonPart: ObjectCommonPartType;
  441   0000             SegmentPart: ObjectSegmentPartType;
  442   0000             SubSegmentPart: ObjectSubSegmentPartType
  443   0000            END;
  444   0000    
  445   0000          NonEmbeddedSegmentObjectType = RECORD
  446   0000             SpacePart: SpaceDescriptionType;
  447   0000             CommonPart: ObjectCommonPartType;
  448   0000             SegmentPart: ObjectSegmentPartType
  449   0000            END;
  450   0000    
  451   0000       CONST
  452   0000          SE_siz = sizeof(SegmentObjectType);
  453   0000          SU_siz = sizeof(SubSegmentObjectType);
  454   0000          NEmb_Siz = sizeof(NonEmbeddedSegmentObjectType);
  455   0000    
  456   0000    (*$I B:COMDEF2.PAS *)
  457   0000    (*--------------------------------------------------------------------
  458   0000      MMU DESCRIPTOR (ONLY USED AS PART OF CONTEXT)  *)
  459   0000    
  460   0000       TYPE
  461   0000          MMU_RegisterIndexType = (First_logical (* first log. // 256 *)
  462   0000                                  ,Last_logical  (* last log. // 256 *)
  463   0000                                  ,Offset        (* offset //256
  464   0000                                                    (logical + offset =
  465   0000                                                     physical) *)
  466   0000                                  ,Flags         (* bit0=1: ENABLE
  467   0000                                                    bit1=1: READ ONLY *)
  468   0000                                  );
  469   0000    
  470   0000          MMU_RegisterType = ARRAY (. MMU_RegisterIndexType .) OF word;
  471   0000    
  472   0000          MMU_SaveAreaKindType = (MMU_RegKind, D67_RegKind);
  473   0000    
  474   0000          MMU_saveAreaType = RECORD
  475   0000    
  476   0000          (* The pascal interpretation is based on the comment in line
  477   0000             253 in file comdef.sa page 6. *)
  478   0000    
  479   0000          CASE MMU_SaveAreaKindType OF
  480   0000          MMU_RegKind:
  481   0000             (MMU_Regs: MMU_RegisterType
  482   0000             );
  483   0000          D67_RegKind:
  484   0000             (d6
  485   0000             ,d7: RegisterType
  486   0000             )
  487   0000            END;
  488   0000    
  489   0000          MMU_DescriptorType = RECORD
  490   0000             MM_map: PointerType;
  491   0000                       (* Points to segment or sub segment mapped
  492   0000                          MM_ref = PT_ref = address of segment or sub
  493   0000                                   segment object. 0 if unmapped or
  494   0000                                   base segment removed.
  495   0000                          MM_kin = PT_kin = MMU_descriptor (=PT_MMU) *)
  496   0000             MM_reg: MMU_SaveAreaType;
  497   0000                       (* MMU register contents. Also used to save d6/d7
  498   0000                          (=result) during delete context (del_ctx) in
  499   0000                          knelop. *)
  500   0000            END;
  501   0000    
  502   0000       CONST
  503   0000          MM_siz = sizeof(MMU_DescriptorType);
  504   0000    
  505   0000    (*--------------------------------------------------------------------
  506   0000      GENERAL OBJECT  *)
  507   0000    
  508   0000       TYPE
  509   0000          ObjectGeneralPartType = RECORD
  510   0000             GE_ex: ChainType;   (* Executed by: General obj -> ctx *)
  511   0000             GE_con: word;       (* Control procedure <= 0 *)
  512   0000             GE_temp: word;      (* No of temp pointers in contexts
  513   0000                                    (incl T(0)) *)
  514   0000             GE_temd: long;      (* No of bytes in temp stack, > 0,
  515   0000                                    < MAX-AR_MAXVAL  *)
  516   0000             GE_stk: SizeType;   (* Size of required free call stack *)
  517   0000             GE_stkm: AddressType;
  518   0000                                 (* Logical address for mapping temp stack:
  519   0000                                    FL_tempd = $200000 for normal objects *)
  520   0000             GE_ent: AddressType;
  521   0000                                (* Logical address for entry *)
  522   0000            END;
  523   0000    
  524   0000          GeneralObjectType = RECORD
  525   0000             CommonPart: ObjectCommonPartType;
  526   0000             GeneralPart: ObjectGeneralPartType
  527   0000            END;
  528   0000    
  529   0000       CONST
  530   0000          GE_siz = sizeof(GeneralObjectType);
  531   0000    
  532   0000    (*--------------------------------------------------------------------
  533   0000      STACK ELEMENT: COMMON PART OF ENVELOPES AND CONTEXTS  *)
  534   0000    
  535   0000          (* Embedded segments and subsegments allocated here *)
  536   0000       TYPE
  537   0000          StackCommonPartType = RECORD
  538   0000             ST_mem: MemberType; (* Various usage: Head -> stack element
  539   0000                                    ST_ref = CH_hold = address of entity
  540   0000                                    holding head *)
  541   0000             ST_word: word;      (* Various usage *)
  542   0000             ST_stk: MemberType; (* Stack: Head -> stack element
  543   0000                                    ST_hold = CH_hold = addrass of object
  544   0000                                    holding stack element *)
  545   0000             ST_act: ChainType;  (* Actual: Stack element -> formal pointer *)
  546   0000             ST_top: word;       (* Top pointers, relative to stack element *)
  547   0000             ST_fir: word;       (* First embedded, relative to stack element *)
  548   0000             ST_res: word;       (* Resident count: <> 0 when stack
  549   0000                                    element is resident *)
  550   0000             ST_io: word;        (* io_count: #simple pointers with io_cap
  551   0000                                    in element *)
  552   0000            END;
  553   0000          (* Pointers allocated here *)
  554   0000    
  555   0000          (* NOTE: Size of envelope/contextincluding pointers and embedded
  556   0000             structures is always:
  557   0000                       TOP POINTERS - FIRST EMBEDDED
  558   0000                            (ST_top - ST_fir)                           *)
  559   0000    
  560   0000       CONST
  561   0000          ST_siz = sizeof(StackCommonPartType);
  562   0000    
  563   0000    (*--------------------------------------------------------------------
  564   0000      STACK ELEMENTS: ENVELOPE AND CONTEXT *)
  565   0000    
  566   0000    
  567   0000       TYPE
  568   0000          StackElementKindType = (EnvelopeKind, ContextKind);
  569   0000    
  570   0000          StackElementType = RECORD
  571   0000    
  572   0000          (* Although the first parts of both variants are structurally
  573   0000             almost identical they have not been united in a fixed part
  574   0000             because of the differences in semantics. The interpretation
  575   0000             of each field is explained (as usual) in the accompanying
  576   0000             comment *)
  577   0000    
  578   0000          CASE StackElementKindType OF
  579   0000          EnvelopeKind:
  580   0000             (
  581   0000             EN_mst: MemberType; (* Manager: Manset -> envelope
  582   0000                                    EN_man = CH_hold = address of manager
  583   0000                                    envelope (0 if dummy manager) (also
  584   0000                                    term_proc = 0 for dummy manager)  *)
  585   0000             EN_off: word;       (* Manset pointer offset in manager envelope *)
  586   0000             EN_stk: MemberType; (* Envelope stack: object -> envelope
  587   0000                                    EN_obj = CH_hold = addrass of object
  588   0000                                     holding envelope *)
  589   0000             EN_act: ChainType;  (* Actual: Envelope -> formal pointer *)
  590   0000             EN_topl: word;      (* Top local pointers, relative to envelope *)
  591   0000             EN_fir: word;       (* First embedded, relative to envelope *)
  592   0000             EN_res: word;       (* Resident count: #res_pt to env + #driv_pt
  593   0000                                       in env + #res_ctx in the obj having
  594   0000                                       env as primary env. <> 0 when envelope
  595   0000                                       is resident *)
  596   0000             EN_io: word;        (* io_count: #simple pointers with io_cap
  597   0000                                    in envelope *)
  598   0000    
  599   0000             (*  END OF COMMON PART *)
  600   0000    
  601   0000             EN_ref: ChainType;  (* Referred by: Env -> refEnv pointers *)
  602   0000             EN_term: word;      (* Termination procedure:
  603   0000                                       < 0: Normal
  604   0000                                       = 0: Dummy or dummy manager
  605   0000                                       = 1: Term procedure called *)
  606   0000             EN_termr: SizeType; (* Termination requirement: Free stack needed
  607   0000                                       to enter term procedure, use call stack
  608   0000                                       or dealloc stack+delete locals and older
  609   0000                                       envelopes *)
  610   0000             EN_fix: SizeType;   (* Fixed term requirement: Fixed stack needed
  611   0000                                       to enter term procedure and use dealloc
  612   0000                                       stack *)
  613   0000             EN_max: SizeType;   (* Max stack: Free stack sufficient to delete
  614   0000                                       all locals in envelope *)
  615   0000             EN_cou: word;       (* Number of "locals" with term req = max for
  616   0000                                       both components. "Locals" are logically
  617   0000                                       owned objects and older envelopes.
  618   0000                                       EN_cou may be zero in case max components
  619   0000                                       are from different "locals" *)
  620   0000             );
  621   0000          ContextKind:
  622   0000             (
  623   0000             CT_exe: MemberType; (* Executes: Gen obj -> ctx (self-ref if
  624   0000                                    aborted)
  625   0000                                    CT_obj = CH_hold = address of general obj.
  626   0000                                    (0 if aborted) *)
  627   0000             CT_mode: byte;      (* Exc_mode << 2 + propagation mode:
  628   0000                                    Exc_mode: 0=No_exc,1=undef_exec,
  629   0000                                    3=undef/reject_exc
  630   0000                                    Propagation_mode: 0=stop,1=reject,3=same *)
  631   0000             CT_spe: byte;       (* Speedexc << 7 + speed_up.
  632   0000                                    Speedexc=1 ==> exception.
  633   0000                                    Speed_up: 0=normal, 1=reject, 3=undef *)
  634   0000             CT_stk: MemberType; (* Context stack: Process or
  635   0000                                    extension obj -> ctx.
  636   0000                                    CT_hold = CH_hold = addrass of process
  637   0000                                    or extension object *)
  638   0000             CT_act: ChainType;  (* Actual: ctx -> formal pointers *)
  639   0000             CT_topf: word;      (* Top formal pointers, relative to ctx *)
  640   0000             CT_fir: word;       (* First embedded, relative to ctx *)
  641   0000             CT_res: word;       (* Resident count: 0 for normal, 1 for
  642   0000                                    resident ctx *)
  643   0000             CT_io: word;        (* io_count: #simple pointers with io_cap
  644   0000                                    in ctx *)
  645   0000    
  646   0000             (* END OF COMMON PART *)
  647   0000    
  648   0000             CT_topt: word;      (* Top temp pointers, relative to context
  649   0000                                       = first formal pointer, relative to ctx.
  650   0000                                    CT_topt must be placed on offset ST_siz *)
  651   0000             CT_stkuk: SizeType; (* Size of free call stack in context (used
  652   0000                                    when temp/formal in old ctx grows *)
  653   0000             CT_mm: ARRAY (.0..3.) OF MMU_DescriptorType;
  654   0000                                 (* CT_mm(.0.) is used as save area in del_ctx *)
  655   0000             CT_con: AddressType;
  656   0000                                 (* Continue address in kernel when user returns *)
  657   0000             CT_usp: long;       (* Saved user stack pointer *)
  658   0000             CT_sava: ARRAY (.0..11.) OF long;
  659   0000                                 (* Supervisor stack: saved in old context
  660   0000                                    when new context is created *)
  661   0000             CT_count: word;     (* - #supervisor stack words saved in addition
  662   0000                                      to "A4,A5,A6,SR,PC" which are always saved.
  663   0000                                      Kernel return is also always saved (count=-2)
  664   0000                                      Used by procedures save_stk and rsto_stk *)
  665   0000                                 (* Val data description: *)
  666   0000             CT_val: word;       (* Pointer offset in prev ctx for val base segm *)
  667   0000             CT_frel: long;      (* First rel address of val in val base segm *)
  668   0000             CT_trel: long       (* Top rel address of val in val base segm *)
  669   0000             )
  670   0000            END; (* StackElementType *)
  671   0000    
  672   0000             (* temp pointers allocated here. T(0) is aux pointer for dealloc *)
  673   0000             (* formal pointers allocated here *)
  674   0000    
  675   0000       CONST
  676   0000          EN_siz = sizeof(StackElementType);
  677   0000                       (* Size of envelope excluding local pointers *)
  678   0000          CT_siz = sizeof(StackElementType);
  679   0000                       (* Size of context excluding pointers *)
  680   0000    
  681   0000    (*--------------------------------------------------------------------
  682   0000      RESULT ARGUMENT, ERROR CODES.  *)
  683   0000    
  684   0000    (* RESULT:   MAIN   = D7, BIT  7: 0
  685   0000                 FAMILY = D7, BIT 15: 8
  686   0000                 ORGNO  = D7, BIT 31:16  ALWAYS ZERO FOR KERNEL
  687   0000                 ARGNO  = D6, BIT  7: 0  ARGUMENT NUMBER WHERE ERROR FOUND
  688   0000                 AUXCAU = D6, BIT 15: 8
  689   0000                 ORGSYS = D6, BIT 31:16  ALWAYS ZERO FOR KERNEL *)
  690   0000    
  691   0000       CONST
  692   0000          EC_OK = 0;             (* MAIN: OK  (set by CLR d7) *)
  693   0000    
  694   0000          (* ERROR CODES page 10 in comdef.sa.  Should these be declared
  695   0000             as numeric constants or as an enumeration type? *)
  696   0000    
  697   0000    (* *** ??? *** *)
  698   0000    
  699   0000    (*--------------------------------------------------------------------
  700   0000      ARGUMENT LIST  *)
  701   0000    
  702   0000    (* ARGUMENT TYPES. HOW TO DECLARE ?  PAGE 11 F IN COMDEF.SA *)
  703   0000    
  704   0000    (*--------------------------------------------------------------------
  705   0000      INS ELEM MACRO  *)
  706   0000    
  707   0000       PROCEDURE InsElem((*UNIV*) VAR Old, New, Prev: ChainPointerType);
  708   0000    
  709   0000       (* Insert the new element in the chain between prev and old.
  710   0000    
  711   0000       The macro is substituted by a procedure to conform with pascal
  712   0000       programming facilities. Parameter number 4 (OLD/PREV) which is
  713   0000       redundant and only used to provide performance optimization is
  714   0000       omitted. Parameter number 3 (PREV) is redundant too, but the
  715   0000       exact usage is not known and consequently it is retained.
  716   0000    
  717   0000          Old:  Points to a chain element (often the chain head)
  718   0000          New:  Points to the new element
  719   0000          Prev: At call: Any value
  720   0000                At return: = New^.Pred; Points to the chain element
  721   0000                           previously next to old, which has now
  722   0000                           been moved one position down the chain
  723   0000                           to make room for the new element. Same
  724   0000                           value as Old^.Prev *)
  725   0000    
  726   0000         BEGIN
  727   0000          Prev := Old^.Prev;
  728   0000          New^.Next := Old;
  729   0000          New^.Prev := Prev;
  730   0000          Prev^.Next := New;
  731   0000          Old^.Prev := New
  732   0000         END;
  733   0000    
  734   0000    (*--------------------------------------------------------------------
  735   0000      REM_ELEM MACRO  *)
  736   0000    
  737   0000       PROCEDURE RemElem((*UNIV*) VAR Elem, Next, Prev: ChainPointerType);
  738   0000    
  739   0000       (* Removes element Elem from the chain but does NOT make Elem
  740   0000          self-referencing
  741   0000    
  742   0000       The macro is substituted by a procedure to conform with pascal
  743   0000       programming facilities. Parameter #4 (OLD/PREV) which is
  744   0000       redundant and only used to provide performance optimization is
  745   0000       omitted. Parameters #3 (PREV) and #2 (NEXT) are redundant too,
  746   0000       but their exact usage is not known and consequently they are retained.
  747   0000    
  748   0000          Elem: Points to chain element to be removed.
  749   0000          Next: At call: Any value.
  750   0000                At return: = Elem^.Next; Points to the neighbour chain
  751   0000                           element towards the chain head along the line
  752   0000                           of next-pointers.
  753   0000          Prev: At call: Any value.
  754   0000                At return: = Elem^.Prev; Points to the neighbour chain
  755   0000                           element towards then chain head along the
  756   0000                           line of prev-pointers. *)
  757   0000    
  758   0000         BEGIN
  759   0000    
  760   0000          (* Obvious performance improvements can be obtained if the
  761   0000            redundant parameters are omitted *)
  762   0000    
  763   0000          Next := Elem^.Next;
  764   0000          Prev := Elem^.Prev;
  765   0000          Prev^.Next := Next;
  766   0000          Next^.Prev := Prev;
  767   0000         END;
  768   0000    
  769   0000    (*--------------------------------------------------------------------
  770   0000      INIT_HEAD MACRO  *)
  771   0000    
  772   0000       PROCEDURE InitHead((*UNIV*)     Elem: ChainType;
  773   0000                         ,     VAR AbsElem: AddressType
  774   0000                         );
  775   0000    
  776   0000       (* Makes chain element self-referencing
  777   0000    
  778   0000          Elem: Points to chain element to be made self-referencing.
  779   0000          AbsElem: At call: Any value.
  780   0000                   At return: The effective (virtual) address of Elem. *)
  781   0000    
  782   0000         BEGIN
  783   0000          AbsElem := addr(Elem);
  784   0000          WITH Elem DO
  785   0000            BEGIN
  786   0000             Next := AbsElem;
  787   0000             Prev := AbsElem;
  788   0000            END
  789   0000         END;
  790   0000    
  791   0000    (*--------------------------------------------------------------------
  792   0000      CASEJMP AND CASELAB MACROES *)
  793   0000    
  794   0000       (* BOTH CASEJMP AND CASELAB MACROES ARE OMITTED AS THEY ONLY SERVE
  795   0000          TO IMPLEMENT AN EQUIVALENT TO THE PASCAL CASE STATEMENT *)
  796   0000    
  797   0000    (*--------------------------------------------------------------------
  798   0000      ENTRYSAV AND RETURN MACRO  *)
  799   0000    
  800   0000       (* ARE these nessesary ??? *)
  801   0000    
  802   0000    (*--------------------------------------------------------------------
  803   0000      PRT_REG, PRT_MEM, ERROR MACRO  *)
  804   0000    
  805   0000      (* TO APPEAR *)
  806   0000    
  807   0000    (*--------------------------------------------------------------------
  808   0000      OTHER CONSTANTS USED IN MORE THAN ONE MODULE
  809   0000      (TO BE REMOVED FROM THIS SOURCE)
  810   0000      Moved to file kernel.pas *)
  811   0000    
  812   0000    
  813   0000    (*$I B:KNELVAR.PAS *)
  814   0000       CONST (* Comdef *)
  815   0000          SchTemP = 3; (* #Temp pointers in ctx in general scheduler
  816   0000                          objects (incl T(0) ) *)
  817   0000          SchTemD = 200;
  818   0000                       (* #Temp data bytes in context in general
  819   0000                          scheduler objects *)
  820   0000          KV_StkSiz = 16#800;
  821   0000                       (* Initial size of the supervisor stack (in bytes) *)
  822   0000          Trp7Stak = 16#100;
  823   0000                       (* Stack space (#bytes) required by normal kernel
  824   0000                          operations i.e. operations called from normal
  825   0000                          contexts only *)
  826   0000          Trp7Resi = 16#80 + 16#FF;
  827   0000                       (* 16#FF is a "round up" value. The rest is the
  828   0000                          stack space (#bytes) needed by the kernel on
  829   0000                          each of the interrrupt levels to execute the
  830   0000                          kernel operations called by resident contexts
  831   0000                          and by the interrupt procedures. *)
  832   0000          (* KV_StkSiz - Trp7Stak - (Trp7Resi - 16#FF)*8
  833   0000             must be positive. The value gives number of bytes in the
  834   0000             supervisor stack that can be used by the interrupt
  835   0000             procedures.
  836   0000    
  837   0000             Trp8Stack = 16#FE ? Stack space required to save the processor
  838   0000             state when trap #8 is called. It is not significant because
  839   0000             it is less than one page. (One page is ensured by Trp7Resi).
  840   0000          *)
  841   0000    
  842   0000          TimeSlic = 10000000;
  843   0000                       (* 10 seconds is used for test
  844   0000                          25,6 millisecods is a reasonable value *)
  845   0000          Dont_Use = 0;
  846   0000                       (* #bytes.
  847   0000                          The last <dont_use> bytes of the memory will
  848   0000                          never be used. If all available mamory can be
  849   0000                          requested by the users, compression will often
  850   0000                          take place when the system is heavily loaded
  851   0000                          (slow alloc). If memory is divided in several
  852   0000                          ram areas the memory exchange guarantee cannot
  853   0000                          be fulfilled due to memory fragmentation. This
  854   0000                          problem disappears if
  855   0000                          largest_segment*no_of_ram_areas < dont_use.
  856   0000                          (I think this is ok ???) *)
  857   0000    (* *** ??? *** *)
  858   0000          PTM_VEC = 16#8C;
  859   0000                       (* Interrupt vector index for timer device.
  860   0000                          Address of vector is index multiplied by 4 *)
  861   0000    
  862   0000       CONST (* Preface *)
  863   0000          I_Config = -1;
  864   0000                       (* address of the first ROM-OS-module to be
  865   0000                          booted by the stub. -1 ignals that the
  866   0000                          first module is in the boot owner set *)
  867   0000          RAM_TOP = 16#C000;
  868   0000                       (* upper available ram address
  869   0000                          384K = 16#6 * 64K
  870   0000                          512K = 16#8 * 64K
  871   0000                          640K = 16#A * 64K
  872   0000                          768K = 16#C * 64K *)
  873   0000          Init_SSP = RAM_TOP;
  874   0000                       (* use top RAM as initial stack pointer
  875   0000          Mem_ListLength = 1;
  876   0000                       (* Only one record in the Mem_List *)
  877   0000    
  878   0000       CONST (* MMProcs *)
  879   0000          AllocSiz = Se_Siz + Sp_Siz; (* *** ??? *** *)
  880   0000          (* NEmb_Siz now defined in file comdef.pas *)
  881   0000    
  882   0000       TYPE (* Preface *)
  883   0000          ExceptionVectorAreaIndexType = 0..255;
  884   0000          ExceptionVectorAreaType = ARRAY (.ExceptionVectorAreaIndexType.) OF
  885   0000             AddressType;
  886   0000          MemListRecordType = RECORD
  887   0000             Start,              (* lower memory address *)
  888   0000             End: AddressType;   (* upper memory address *)
  889   0000          Mem_ListType = RECORD
  890   0000             Length: integer;
  891   0000             List: ARRAY (.1..Mem_ListLength.) OF MemListRecordType
  892   0000            END;
  893   0000    
  894   0000          MmuChipType = byte;
  895   0000    (* *** ??? *** *) (* byte??? *)
  896   0000    
  897   0000          TimerRegisterType = RECORD (* Interpretation based on M68000      *)
  898   0000             Filler1: byte;          (* instruction MOVEP used in ENTER.SA  *)
  899   0000             MSB: byte;              (* page 4                              *)
  900   0000             Filler2: byte;
  901   0000             LSB: byte;
  902   0000            END;
  903   0000    
  904   0000          PtmChipType = RECORD
  905   0000             Filler1: byte;
  906   0000             Contrl13: byte;     (* Control register 1 or 3 *)
  907   0000             Filler2: byte;
  908   0000             StatCon2: byte;     (* Control register2 and Status *)
  909   0000             Filler3: TimerRegisterType;
  910   0000                                 (* Probably used for timer1 *)
  911   0000             Timer2,
  912   0000             Timer3: TimerRegisterType
  913   0000            END;
  914   0000    
  915   0000    
  916   0000       (*IMPORTED*) VAR (* Comdef *) (* Test panel status word *)
  917   0000          TstPanel: byte;  (* based at 16#FE0000 *)
  918   0000    
  919   0000       (*IMPORTED*) VAR (* Comdef *) (* Printer device control and data registers *)
  920   0000          PrtContA: byte;  (* based at 16#FEE00B *)
  921   0000          PrtContB: byte;  (*             FEE00F *)
  922   0000          PrtStatu: byte;  (*             FEE00D *)
  923   0000          PrtBuf:   byte;  (*             FEE009 *)
  924   0000    
  925   0000       (*IMPORTED*) VAR (* Preface *)  (* MMU device *)
  926   0000          KV_MMU: MmuChipType;
  927   0000                           (* based at 16#FE2000 *)
  928   0000    
  929   0000       (*IMPORTED*) VAR (* Comdef *) (* Timer device *)
  930   0000          PtmChip: PtmChipType;
  931   0000                           (* based at 16#FEE040 *)
  932   0000    
  933   0000       (*IMPORTED*) VAR (* Preface *)
  934   0000          KV_InVec: ExceptionVectorAreaType;
  935   0000                       (* Interrupt vector (normally = 0), contains addresses
  936   0000                          of the interrupt procedures. The addresses are
  937   0000                          adjusted when the segments holding the procedures
  938   0000                          are moved *)
  939   0000                       (* KV_InVec(.0.) is assumed to be initialized to
  940   0000                          the initial value of the SSP (System stack pointer)
  941   0000                          = Init_SSP prior to boot loading.
  942   0000                          KV_InVec(.1.) is assumed to be initialized to
  943   0000                          the initial value of the PC prior to boot
  944   0000                          loading *)
  945   0000          KV_FrMem: AddressType;
  946   0000                       (* Initially: points to Mem_List;
  947   0000                          Later: Number of free bytes for allocation of objects.
  948   0000                          KV_FrMem is assumed to be initialized prior to
  949   0000                          boot loading *)
  950   0000          KV_BotLd: AddressType;
  951   0000                       (* Lower starting address of bootloaded OS-modules
  952   0000                          (RAM-boot) or the value -1 (ROM-boot).
  953   0000                          Initially states absolute minimum address
  954   0000                          (First_OS) but is upward page aligned.
  955   0000                          KV_BotLd is assumed to be initialized prior to
  956   0000                          boot loading. *)
  957   0000          KV_Stub: long;
  958   0000                       (* Contains the address of a ROM-stub or -1
  959   0000                          when the stub is the first module of the
  960   0000                          RAM-boot. *)
  961   0000                       (* KV_Stub is assumed to be initialized to
  962   0000                          the value -1 indicating that the stub is
  963   0000                          booted in RAM *)
  964   0000          Mem_List: Mem_ListType;
  965   0000                       (* Mem_List(.1.).Start is assumed to be initialized
  966   0000                          to TOP_KNEL prior to boot loading.
  967   0000                          Mem_List(.1.).End is assumed to be initialized
  968   0000                          to RAM_TOP prior to boot loading *)
  969   0000    
  970   0000    
  971   0000       VAR  (* Preface *) (* Variables used by test print procedures *)
  972   0000          TstCount: word;
  973   0000                       (* Counts down from 50 the number of output lines *)
  974   0000          TstStatus: word;
  975   0000                       (* State of test output *)
  976   0000                       (* Test output from alloc/dealloc is generated
  977   0000                          when bit zero of this variable equals one *)
  978   0000    
  979   0000       TYPE (* MMPROCS *)
  980   0000          MR_FixType = (Dynamic, Initial);
  981   0000          MR_TypType = (Free, Kernel, User);
  982   0000          MemRecPointerType = ^MemRecType;
  983   0000          MemRecType = RECORD
  984   0000             MR_Nxt: MemRecPointerType; (* Addr. of next mem rec *)
  985   0000             MR_Prv: MemRecPointerType; (* Addr. of prior mem rec *)
  986   0000             MR_Fst: AddressType;  (* Addr. of first free byte *)
  987   0000             MR_Fre: Integer; (* Number of bytes in the free part *)
  988   0000             MR_Fix: MR_FixType;
  989   0000             MR_Typ: MR_TypType;
  990   0000            END;
  991   0000    
  992   0000          LoadModuleHeaderPointerType = ^LoadModuleHaeaderType;
  993   0000          LoadModuleHeaderType = RECORD
  994   0000             MOD_Hsiz: word; (* The size of the module header segment *)
  995   0000             MOD_Size: integer;
  996   0000                             (* The size of the whole module
  997   0000                                0 means dummy top module *)
  998   0000             MOD_Kind: word; (* Module kind. Should be 0=program module *)
  999   0000             MOD_Prog: word; (* The address of the program description
 1000   0000                                relative to MOD_HSiz *)
 1001   0000            END;
 1002   0000    
 1003   0000          LdMdObjectDescriptionType = RECORD
 1004   0000             MOD_FDSD: word; (* Address of first data segment description
 1005   0000                                relative to MOD_Fdsd *)
 1006   0000             MOD_Locs: word; (* No of local pointers in object *)
 1007   0000             MOD_Temp: word; (* NO of temp pointers in contexts *)
 1008   0000             MOD_TemD: integer;
 1009   0000                             (* No of temp bytes in contexts *)
 1010   0000             MOD_Stk: SizeType;
 1011   0000                             (* Call stack requirement = Size of boot proc *)
 1012   0000             MOD_Ent: AddressType;
 1013   0000                             (* Entry address to program *)
 1014   0000             MOD_Nul1: word; (* Unused field *)
 1015   0000             MOD_LDSS: word; (* No of local data segment descriptions *)
 1016   0000            END;
 1017   0000    
 1018   0000          LdMDLocalDataSegmentDescriptionType = RECORD
 1019   0000             MOD_DSiz: word; (* Size of description *)
 1020   0000             MOD_Nul2: ARRAY (.1..24.) OF byte;
 1021   0000                             (* Unused fields *)
 1022   0000             MOD_LSDs: word; (* No of local section descriptions *)
 1023   0000             MOD_LdSz: word; (* Size of fixed part of data segment description *)
 1024   0000            END;
 1025   0000    
 1026   0000          LdMdLoadSectionDescriptionType = RECORD
 1027   0000             MOD_Nul3: ARRAY (.1..4.) OF byte;
 1028   0000                             (* Unused fields *)
 1029   0000             MOD_SLen: integer;
 1030   0000                             (* Length of the load section segment *)
 1031   0000             MOD_Nul4: ARRAY (.1..4.) OF byte;
 1032   0000                             (* Unused fields *)
 1033   0000             MOD_LSDZ: word; (* Size of one load section description *)
 1034   0000            END;
 1035   0000    
 1036   0000       CONST (* MMPROCS *)
 1037   0000          MR_Siz = sizeof(MemRecType);
 1038   0000    
 1039   0000       VAR (* MMProcs *)
 1040   0000          F_Alloc: AddressType;   (* Address of the first mem_rec *)
 1041   0000          L_Alloc: AddressType;   (* Address of the last mem_rec *)
 1042   0000          F_Supvs: AddressType;   (* Address of the supervisor stack (first byte) *)
 1043   0000          Page_Tab: AddressType;  (* Address of the page table (addr of entry zero) *)
 1044   0000          Supv_Stk: AddressType;  (* "Last + 1" address of the supervisor stack *)
 1045   0000          MM_Queue: ChainType;
 1046   0000                    (* chain of processes waiting to create/remove an object *)
 1047   0000          MM_Lock: MM_LockType;
 1048   0000    (* *** ??? *** *)
 1049   0000          (**** Initial pointers *)
 1050   0000          KV_IOwnP: PointerType;
 1051   0000                    (* Owns objects that are never deleted. Stub object
 1052   0000                       is first in set *)
 1053   0000          KV_IManP: PointerType;
 1054   0000                    (* Manages envelopes that are never demanaged. Stub
 1055   0000                       envelope is first in set *)
 1056   0000          KV_DummyOwn: PointerType;
 1057   0000                    (* Owns a kernel part while the user part is being
 1058   0000                       allocated. (Is not initialized) *)
 1059   0000          (**** Initial objects *)
 1060   0000          AllocObj: NonEmbeddedSegmentObjectType;
 1061   0000                    (* AllocObj holds the kernel part of the kernel
 1062   0000                       defined alloc object. During MM_initialization
 1063   0000                       the kernel part is used as the kernel part of
 1064   0000                       a non-embedded segmnet describing the boot
 1065   0000                       loaded modules *)
 1066   0000          FulSpace: NonEmbeddedSegmentObjectType;
 1067   0000                    (* FulSpace is a segment object describing the whole
 1068   0000                       address space of the MC68000. Subsegments of
 1069   0000                       FulSpace is used by driver objects. The Stub
 1070   0000                       object gets a reference to FulSpace *)
 1071   0000    
 1072   0000    
 1073   0000          (**** Global temporary variables used during calls to mm-procs *)
 1074   0000    
 1075   0000          CurKMove: AddressType;
 1076   0000                    (* Current kernel move candidate *)
 1077   0000                    (* Also used as CurUMove = Current User move candidate *)
 1078   0000                    (* Holds the address of the next item (envelope,
 1079   0000                       context or segment) to be moved by the mm-procs. The
 1080   0000                       item will be moved when mm-procs reenters the
 1081   0000                       sub mm-monitor.
 1082   0000                       The item may be destroyed by a call to an mm-pop
 1083   0000                       procedure. In this case the mm-pop procedure will
 1084   0000                       update the variable *)
 1085   0000          CurKHead: AddressType;
 1086   0000                    (* = Cur_Head. Holds the address of the head of a
 1087   0000                       context chain or of an envelope chain *)
 1088   0000          CurObOb: AddressType;
 1089   0000                   (* Holds the address of an object *)
 1090   0000          CurDist: integer;
 1091   0000                   (* Holds the distance that items should be moved *)
 1092   0000          Cur_Stak: AddressType;
 1093   0000                   (* Holds the address of a context or an envelope *)
 1094   0000          Cur_Embs: AddressType;
 1095   0000                   (* Holds the address of an embedded segment object *)
 1096   0000          UserDest: AddressType;
 1097   0000                   (* Holds the fututre address of a user part being moved.
 1098   0000                      If the current user move candidate is destroyed,
 1099   0000                      the move is actually finished, and future allocation
 1100   0000                      of user segments should be allocated according to
 1101   0000                      the new position of the user part. This is ensured
 1102   0000                      by the MM-popu, by moving userdest to SP_FirU of
 1103   0000                      the space_Description, in case CurUMove is popped *)
 1104   0000          SaveNeed: integer;
 1105   0000                   (* Holds the >>bytes needed<< during alloc.new_obj *)
 1106   0000          Save_RPA: integer;
 1107   0000                   (* Holds the pointer argument during alloc.new_obj *)
 1108   0000          KSavPrt: ARRAY (.1..15.) OF integer;
 1109   0000                   (* = USavPrt. Used by C_UParts and C_KParts *)
 1110   0000          KSavCrs: ARRAY (.1..15.) OF integer;
 1111   0000                   (* = USavCrs. Used by M_Uacroes and M_Kacroes *)
 1112   0000          KSavMov: ARRAY (.1..15.) OF integer;
 1113   0000                   (* = USavMov. Used by MoveUser and MoveKnel *)
 1114   0000          Sav_Chk: ARRAY (.1..2.) OF integer;
 1115   0000                   (* Used by Check_Tir *)
 1116   0000    
 1117   0000       (**** NewHead macro *)
 1118   0000    
 1119   0000       PROCEDURE NewHead(
 1120   0000          Curr: AddressType; (* Addr. of new MemRec head *)
 1121   0000          Fix: MR_FixType;   (* Value for MR_Fix field *)
 1122   0000          Typ: MR_TypeType;  (* Value for MR_Typ field *)
 1123   0000          Prev: AddressType; (* Addr. of previous MemRec head *)
 1124   0000          Next: AddressType  (* Addr. of next MemRec head *)
 1125   0000                        );
 1126   0000    
 1127   0000          (* The NewHead procedure creates a head for a new MemRec and
 1128   0000             adjusts the chain to the next and prior MemRecs
 1129   0000    
 1130   0000             OBS: MR_Fre Free Bytes are not assigned. The fields are
 1131   0000                  often reassigned by caller
 1132   0000          *)
 1133   0000    
 1134   0000          VAR
 1135   0000             CurPtr: MemRecPointerType;
 1136   0000    
 1137   0000         BEGIN
 1138   0000          CurPtr := MemRecPtr(Curr);
 1139   0000          WITH CurPtr^ DO
 1140   0000            BEGIN
 1141   0000             MR_Fst := Curr;
 1142   0000             MR_Fix := Fix;
 1143   0000             MR_Typ := Typ;
 1144   0000             MR_Prv := MemRecPtr(Prev);
 1145   0000             MR_Nxt := MemRecPtr(Next);
 1146   0000            END;
 1147   0000          WITH CurPtr^.Prv^ DO
 1148   0000             MR_Nxt := MemRecPtr(Curr);
 1149   0000          WITH CurPtr^.Nxt^ DO
 1150   0000             MR_Prv := MemRecPtr(Curr);
 1151   0000         END;
 1152   0000    
 1153   0000       (**** MovLm Macro *)
 1154   0000    
 1155   0000       PROCEDURE MovLm(
 1156   0000          VAR AS: AddressType; (* Address of source *)
 1157   0000          VAR AD: AddressType; (* Addres of destination *)
 1158   0000                      );
 1159   0000    
 1160   0000          (* References to the element to be moved are changed to
 1161   0000             reflct the new position of the element. The element is
 1162   0000             moved. AS and AD are increased by the size of element (=8) *)
 1163   0000    
 1164   0000          (* It might be considerably easier to have parameters of
 1165   0000             chainpointertype depending on how the procedure is used *)
 1166   0000    
 1167   0000          VAR
 1168   0000             SrcPtr: ChainPointerType;
 1169   0000             DstPtr: ChainPointerType;
 1170   0000    
 1171   0000         BEGIN
 1172   0000          SrcPtr := ChainPtr(AS);
 1173   0000          DstPtr := ChainPtr(AD);
 1174   0000          WITH SrcPtr^ DO
 1175   0000            BEGIN
 1176   0000             Next^.Prev := DstPtr;
 1177   0000             Prev^.Next := DstPtr;
 1178   0000    
 1179   0000             DstPtr^.Next := Next;
 1180   0000             DstPtr^.Prev := Prev;
 1181   0000            END;
 1182   0000    
 1183   0000          AS := AS + Ch_Siz*2;
 1184   0000          AD := AD + Ch_Siz*2;
 1185   0000         END;
 1186   0000    
 1187   0000       (**** MovHd macro *)
 1188   0000    
 1189   0000       PROCEDURE MovHd(
 1190   0000          AS: AddressType; (* Address of source *9
 1191   0000          AD: AddressType; (* Address of destination *)
 1192   0000          NR: AddressType  (* New reference for the Ch_hold field *)
 1193   0000                      );
 1194   0000    
 1195   0000          (* All references (CH_Hold) in elements in chain are set to NR.
 1196   0000             References to the chain head are changed to reflect the
 1197   0000             new position of the chain head. The element is moved.
 1198   0000             AS and AD are increased by the size of the head (= 8)  *)
 1199   0000    
 1200   0000          (* It might be considerably easier to have parameters of
 1201   0000             chainpointertype depending on how the procedure is used *)
 1202   0000    
 1203   0000          VAR
 1204   0000             SrcPtr: ChainPointerType;
 1205   0000             DstPtr: ChainPointerType;
 1206   0000    
 1207   0000         BEGIN
 1208   0000          SrcPtr := ChainPtr(AS);
 1209   0000          DstPtr := ChainPtr(AD);
 1210   0000          WITH SrcPtr^ DO
 1211   0000            BEGIN
 1212   0000             Next^.Prev := DstPtr;
 1213   0000             Prev^.Next := DstPtr;
 1214   0000    
 1215   0000             CurPtr := Next;
 1216   0000             WHILE CurPtr <> DstPtr DO
 1217   0000    
 1218   0000    (* *** ??? *** Why is SrcPtr^.Prev^.CH_Hold not updated with NR ??? *** *)
 1219   0000    
 1220   0000                WITH CurPtr^ DO
 1221   0000                  BEGIN
 1222   0000                   CH_Hold := NR;
 1223   0000    (*
 1224   0000                   PrtMem('MovHd_NewRef', CurPtr^, PT_Siz);
 1225   0000    *)
 1226   0000                   CurPtr := CurPtr^.Next
 1227   0000                  END;
 1228   0000    
 1229   0000             DstPtr^.Next := Next;
 1230   0000             DstPtr^.Prev := Prev;
 1231   0000            END;
 1232   0000    
 1233   0000          AS := AS + Ch_Siz*2;
 1234   0000          AD := AD + Ch_Siz*2;
 1235   0000         END;
 1236   0000    
 1237   0000       (**** TstPage macro *)
 1238   0000    
 1239   0000       PROCEDURE TstPage(
 1240   0000          A: AddressType; (* Address to test *)
 1241   0000          E: ErrorNo      (* Error number
 1242   0000                        );
 1243   0000    
 1244   0000          (* Tests that a value is a multiple of 256. Generate an address
 1245   0000             exception if it is not the case. The Test is used in the
 1246   0000             initialization (WIR says) *)
 1247   0000    
 1248   0000         BEGIN
 1249   0000          IF A mod 256 <> 0 THEN
 1250   0000             Error(E)
 1251   0000         END;
 1252   0000    
 1253   0000    
 1254   0000       CONST (* SC *)
 1255   0000          A_Formal = 0;       (* Direct address of formal pointer *)
 1256   0000          A_Local  = 16#8000; (* Direct address of local pointer *)
 1257   0000          A_Temp   = 16#4000; (* Direct address of temporary pointer *)
 1258   0000          Act_Siz = AR_Siz;   (* Size of actual arg/subsegm arg/void value arg *)
 1259   0000    
 1260   0000       TYPE (* SC *)
 1261   0000          ChannelIndexType = 0..255;
 1262   0000          StakTabRecordType = RECORD
 1263   0000             IntStk: word;
 1264   0000             level: word
 1265   0000            END;
 1266   0000          DrivTabType = ARRAY (. ChannelIndexType .) OF AddressType;
 1267   0000          StakTabType = ARRAY (. ChannelIndexType .) OF StakTabRecordType;
 1268   0000    
 1269   0000          (* Both entries are zero for an unused channel and -1 for a
 1270   0000             permanently reserved channel.
 1271   0000             After a driver for a cahnnel is installed DrivTab(Channel)
 1272   0000             contains the address of the field "Env.Enstk" of the driver
 1273   0000             envelope (<> 0) and StakTab(Channel) contains int_stk and
 1274   0000             level (<> 0).
 1275   0000             Int_Stk tells the max number of bytes used uring processing
 1276   0000             of a channel interrupt. Level gives the interrupt level of
 1277   0000             the associated interrupt procedure of the channel. *)
 1278   0000    
 1279   0000          RtCntType = RECORD
 1280   0000             msl,             (*  most significant long word *)
 1281   0000             lsl: integer     (* least significant long word *)
 1282   0000            END;
 1283   0000    
 1284   0000       SchedulerType = byte;
 1285   0000       DDivSchType = byte;
 1286   0000       SegmentObjectType = byte;
 1287   0000       InterruptContextType = byte;
 1288   0000       SchdArgType = byte;
 1289   0000    
 1290   0000       VAR (* SC *)
 1291   0000          DrivTab: DrivTabType;
 1292   0000          StakTab: StakTabType;
 1293   0000    
 1294   0000          Timer: ChainType;       (* Processes waiting for time out.
 1295   0000                                     Proc= running_current or
 1296   0000                                     proc.state= wait=2 or =D_wait=4 *)
 1297   0000          Running: ChainType;     (* Processes executing normal contexts.
 1298   0000                                     Proc.state=run=0 *)
 1299   0000          Driving: ChainType;     (* Processes executing resident contexts.
 1300   0000                                     Proc.state=run=0 or =D_wait=4 *)
 1301   0000          KV_Ctx: AddressType;    (* Top context of current process.
 1302   0000                                     zero when dummy process is running *)
 1303   0000          KV_Proc: AddressType;   (* Current process. Used to identify the
 1304   0000                                     process that called the kernel.
 1305   0000                                     Undef when dummy process is running *)
 1306   0000          KV_SPSave: AddressType; (* Current supervisor stack pointer.
 1307   0000                                     Changes when a recursion of the
 1308   0000                                     scheduler is created or removed
 1309   0000                                     (see tr_tr8 ff). Points to saved
 1310   0000                                     A4,A5,A6,SR,PC in the stack *)
 1311   0000          SAVE_PC: AddressType;
 1312   0000          SAVE_SR: word;
 1313   0000                               (* Used by scheduler to save PC and SR
 1314   0000                                  of current process *)
 1315   0000          RTCNT: RtCntType;    (* 64 bit real time counter. Initially
 1316   0000                                  zero. Counts the elapsed time in micro
 1317   0000                                  seconds *)
 1318   0000    
 1319   0000          (**** Initial objects *)
 1320   0000    
 1321   0000          Init_Sch: SchedulerType; (* Initial scheduler object *)
 1322   0000          Norm_Sch: SchedulerType; (* Normal  scheduler object *)
 1323   0000          Intr_Sch: SchedulerType; (* Interrupt scheduler object *)
 1324   0000          DDiv_Sch: DDivSchType;   (* Decl_Div object *)
 1325   0000          Sch_Code: SegmentObjectType; (* Segment object holding code of Sched *)
 1326   0000    
 1327   0000          Int_Ctx: InterruptContextType; (* ST_fields + CT_Topt are present
 1328   0000                                            in the interrupt_Ctx.  The
 1329   0000                                            context is "Current context"
 1330   0000                                            when an interrupt procedure calls
 1331   0000                                            the kernel *)
 1332   0000          Schd_Arg: SchdArgType; (* Used when a gate creates a cond by calling
 1333   0000                                    scheduler object *)
 1334   0000    
 1335   0000    
 1336   0000    
 1337   0000       (* Miscellaneous procedures *)
 1338   0000    
 1339   0000          FUNCTION PtrVal(
 1340   0000             (*UNIV*) x: AddressType): AddressType;
 1341   0000    
 1342   0000            BEGIN
 1343   0000             PtrVal := x
 1344   0000            END;
 1345   0000    
 1346   0000          FUNCTION MemRecPtr(
 1347   0000             (*UNIV*) x: MemRecPointerType): MemRecPointerType;
 1348   0000    
 1349   0000            BEGIN
 1350   0000             MemRecPtr := x
 1351   0000            END;
 1352   0000    
 1353   0000          FUNCTION LdMdPtr(
 1354   0000             (*UNIV*) x: LoadModuleHeaderPointerType): LoadModuleHeaderPointerType;
 1355   0000    
 1356   0000            BEGIN
 1357   0000             LdMdPtr := x
 1358   0000            END;
 1359   0000    
 1360   0000          FUNCTION ChainPtr(
 1361   0000             (*UNIV*) x: ChainPointerType): ChainPointerType;
 1362   0000    
 1363   0000            BEGIN
 1364   0000             ChainPtr := x
 1365   0000            END;
 1366   0000    
 1367   0000          FUNCTION LdMdObjDscPtr(
 1368   0000             (*UNIV*) x: LdMdObjDscType): LdMdObjDscType;
 1369   0000    
 1370   0000            BEGIN
 1371   0000             LdMdObjDscPtr := x
 1372   0000            END;
 1373   0000    
 1374   0000          FUNCTION LdMdHdrPtr(
 1375   0000             (*UNIV*) x: LdMdHdrPtrType): LdMdHdrPtrType;
 1376   0000    
 1377   0000            BEGIN
 1378   0000             LdMdHdrPtr := x
 1379   0000            END;
 1380   0000    
 1381   0000          FUNCTION LdMdLDSDPtr(
 1382   0000             (*UNIV*) x: LdMdLDSDPtrType): LdMdLDSDPtrType;
 1383   0000    
 1384   0000            BEGIN
 1385   0000             LdMdLDSDPtr := x
 1386   0000            END;
 1387   0000    
 1388   0000          FUNCTION LdMdLSDPtr(
 1389   0000             (*UNIV*) x: LdMdLSDPtrType): LdMdLSDPtrType;
 1390   0000    
 1391   0000            BEGIN
 1392   0000             LdMdLSDPtr := x
 1393   0000            END;
 1394   0000    
 1395   0000          FUNCTION GePtr(
 1396   0000             (*UNIV*) x: GePtrType): GePtrType;
 1397   0000    
 1398   0000            BEGIN
 1399   0000             GePtr := x
 1400   0000            END;
 1401   0000    
 1402   0000          FUNCTION SuPtr(
 1403   0000             (*UNIV*) x: SuPtrType): SuPtrType;
 1404   0000    
 1405   0000            BEGIN
 1406   0000             SuPtr := x
 1407   0000            END;
 1408   0000    
 1409   0000          FUNCTION PointerPtr(
 1410   0000             (*UNIV*) x: PointerPtrType ): PointerPtrType;
 1411   0000    
 1412   0000            BEGIN
 1413   0000             PointerPtr := x
 1414   0000            END;
 1415   0000    
 1416   0000       PROCEDURE Error(ErrorCode: integer); (* comdef *)
 1417   0000    
 1418   0000         BEGIN
 1419   0000          REPEAT
 1420   0000             (* *** Enable system mode and set interrrupt level to 7 *** *)
 1421   0000          UNTIL false;
 1422   0000         END;
 1423   0000    
 1424   0000       (* Memory management procedures *)
 1425   0000       (* Scheduling procedures *)
 1426   0000       (* Kernel Operations procedures *)
 1427   0000    
 1428   0000       (*EXPORTED*) PROCEDURE SystemCall;
 1429   0000    
 1430   0000         BEGIN (* SystemCall *)
 1431   0000          (* Do this and that and call knelop *)
 1432   0000         END;  (* SystemCall *)
 1433   0000    
 1434   0000    (*$I B:IPREFACE.PAS *)
 1435   0000       PROCEDURE InitPreface;
 1436   0000    
 1437   0000          VAR
 1438   0000             d0: ExceptionVectorAreaIndexType;
 1439   0000                       (* working register D0 *)
 1440   0000    
 1441   0000         BEGIN (* InitPreface *)
 1442   0000    
 1443   0000          (*** Round up First_OS in KV_BotLd to align with next page *)
 1444   0000    
 1445   0000          KV_BotLd := ((KV_BotLd + 255) div 256) * 256;
 1446   0000    
 1447   0000          (*** Set up vector table etc. Does this match the initialization
 1448   0000               in knelop ??? *)
 1449   0000          (*** ??? *** Both tables initialized here are defined in Sc.sa.
 1450   0000               Why are they not initialized there ??? They do not appear to
 1451   0000               used in any way whatever by the intervening MMPROCS
 1452   0000               initialization section. Is the stack space computation
 1453   0000               algorithm involved? *)
 1454   0000    
 1455   0000          FOR d0 := 2 TO 255 DO
 1456   0000            BEGIN (* entry 0 and 1 initialized prior to boot loading *)
 1457   0000             Driv_Tab(.d0.) := 0; (* channel := free *)
 1458   0000             KV_InVec(.d0.) := addr(RteDummy);
 1459   0000                       (* interrupt address := dummy interrupt *)
 1460   0000             Stak_Tab(.d0.) := 0; (* channel := free *)
 1461   0000            END;
 1462   0000          Driv_Tab(.32+9.) := -1;
 1463   0000                       (* channel 32+9 (trap #9) := reserved *)
 1464   0000          KV_InVec(.32+9.) := addr(Test_Prt);
 1465   0000                       (* assign testprint procedure to trap #9 *)
 1466   0000          Stack_Tab(.32+9.) := -1;
 1467   0000                       (* channel 32+9 (trap #9) := reserved *)
 1468   0000    
 1469   0000          (**** Initialize test print *)
 1470   0000    
 1471   0000          TstCount := 0;
 1472   0000          TstStatus := 0;
 1473   0000    
 1474   0000          (**** Initialize printer *)
 1475   0000    
 1476   0000          PrtContA := 16#00;
 1477   0000                       (* select data direction register for a-part *)
 1478   0000          PrtBuf := 16#FF;
 1479   0000                       (* all lines used for output *)
 1480   0000          PrtContA := 16#3C;
 1481   0000                       (* assign control bits to output part *)
 1482   0000          PrtContB := 16#00;
 1483   0000                       (* select data direction register for b-part *)
 1484   0000          PrtStatu := 16#08;
 1485   0000                       (* all lines used for input but bit 3 ??? *)
 1486   0000          PrtContB := 16#3C;
 1487   0000                       (* assign control bits to input part *)
 1488   0000    
 1489   0000          NewLine;
 1490   0000          PrtChar('E');
 1491   0000          PrtChar('O');
 1492   0000          PrtChar('S');
 1493   0000          NewLine;
 1494   0000    
 1495   0000          (**** Prepare the stack space computation algorithm *)
 1496   0000    
 1497   0000          Stak_Tab(.0.) := Trp7Stak * 2**16 + 0; (* 0 is interrupt priority *)
 1498   0000          Driv_Tab(.0.) := Stak_Tab(.0.); (* := used := dummy value > 0 *)
 1499   0000          Stak_Tab(.1.) := -1;   (* reserved. Entry 1 cannot be used *)
 1500   0000          Driv_Tab(.1.) := -1;   (* channel(1) := reserved *)
 1501   0000    
 1502   0000    (*
 1503   0000          Prt_Mem('End of preface', KV_InVec, KV_InVec - TstStatus);
 1504   0000    *)
 1505   0000    
 1506   0000         END;  (* InitPreface *)
 1507   0000    
 1508   0000    
 1509   0000    (*$I B:IMMUPROC.PAS *)
 1510   0000       PROCEDURE InitMMU;
 1511   0000    
 1512   0000          (* The MM_Proc initialization gets control right after the preface
 1513   0000    
 1514   0000             The following steps are carried out:
 1515   0000    
 1516   0000             (1) Allocate page table
 1517   0000             (2) Set up initial mem-rec structure
 1518   0000             (3) Boot loaded modules (in ram) are described as one segment object
 1519   0000             (4) Create the fulspace segment object and initial pointers
 1520   0000             (5) Allocate and initialize the stub object, except local pointers
 1521   0000             (6) Create the boot owner set, describing the boot loaded modules
 1522   0000                 in local-2 of the stub object
 1523   0000             (7) Initialize local-1: Ref to the code of the stub
 1524   0000                            local-6: ref to the fulspace segment object
 1525   0000             (8) Create the alloc object
 1526   0000    
 1527   0000          *)
 1528   0000    
 1529   0000    
 1530   0000          PROCEDURE MMBusErr;
 1531   0000    
 1532   0000             (* Bus_error_exception may be generated by illegal address
 1533   0000                specifications in the ram area list *)
 1534   0000    
 1535   0000            BEGIN (* MMBusErr *)
 1536   0000             Error(0);
 1537   0000            END;  (* MMBusErr *)
 1538   0000    
 1539   0000          FUNCTION Get_LdMd: AddressType;
 1540   0000    
 1541   0000             (* Return address of boot loaded modules *)
 1542   0000    
 1543   0000            BEGIN (* Get_LdMd *)
 1544   0000             Get_LdMd := AllocObj.Se_fir
 1545   0000            END;  (* Get_LdMd *)
 1546   0000    
 1547   0000          FUNCTION Get_StMd: AddressType;
 1548   0000    
 1549   0000             (* Return the stub module address *)
 1550   0000    
 1551   0000            BEGIN (* Get_StMd *)
 1552   0000             IF KV_Stub = -1 THEN
 1553   0000                Get_StMd := Get_LdMd
 1554   0000             ELSE
 1555   0000                Get_StMd := KVStub
 1556   0000            END;  (* Get_StMd *)
 1557   0000    
 1558   0000          FUNCTION GetStubE: AddressType;
 1559   0000    
 1560   0000             (* Get address of the stub envelope *)
 1561   0000    
 1562   0000            BEGIN (* GetStubE *)
 1563   0000             GetStubE := KV_IManP.Common.Pointer.Next (* First env. in list *)
 1564   0000            END;  (* GetStubE *)
 1565   0000    
 1566   0000          FUNCTION GetStubO: AddressType;
 1567   0000    
 1568   0000             (* Get address of the stub object *)
 1569   0000    
 1570   0000            BEGIN (* GetStubO *)
 1571   0000             GetStubO := KV_IOwnP.Common.Pointer.Next (* First obj. in list *)
 1572   0000            END;  (* GetStubO *)
 1573   0000    
 1574   0000          PROCEDURE MakeSegm(
 1575   0000             UserSize: LongInteger;    (* Length of user part (D1) *)
 1576   0000             UserAddress: AddressType; (* Address of user part (A1) *)
 1577   0000             SegmentObject: NonEmbeddedSegmentObjectType
 1578   0000                                       (* Address of kernell part (A0) *)
 1579   0000                            );
 1580   0000    
 1581   0000             (* Make a non embedded segment object *)
 1582   0000    
 1583   0000             VAR
 1584   0000                d0: AddressType;      (* Top address of user part =
 1585   0000                                         UserAddress + UserSize *)
 1586   0000                Dummy: AddressType;
 1587   0000    
 1588   0000            BEGIN (* MakeSegm *)
 1589   0000             (* prt_reg(parameters) *)
 1590   0000    
 1591   0000             d0 := UserAddress + UserSize;
 1592   0000             IF d0 IN (. F_Alloc..L_Alloc .) THEN
 1593   0000                PgTabSet(d0, KernelAddress);   (* PageTable(d0):=KernelAddress *)
 1594   0000             WITH SegmentObject DO
 1595   0000               BEGIN
 1596   0000                WITH CommonPart DO
 1597   0000                  BEGIN
 1598   0000                   OB_Kin := OB_SEOB;  (* Kind := segment object *)
 1599   0000                   OB_Sta := OB_SEGM;  (* State := segment *)
 1600   0000                  END;
 1601   0000                WITH SegmentPart DO
 1602   0000                  BEGIN
 1603   0000                   SE_io := 0;         (* io_count := 0 *)
 1604   0000                   SE_Fir := UserAddress;
 1605   0000                   SE_Len := UserSize;
 1606   0000                   InitHead(SE_Wait, Dummy);
 1607   0000                  END;
 1608   0000                WITH SpacePart DO
 1609   0000                (* Possibly this should be handled dynamically so that SpacePart
 1610   0000                   could be positioned anywhere. See line 1260 in MMPROCS.SA
 1611   0000                   Something like WITH CommonPart.OB_Spa^ DO *)
 1612   0000                  BEGIN
 1613   0000                   SP_FirU := UserAddress;
 1614   0000                   SP_FreU := 0;
 1615   0000                   SP_SizU := UserSize;
 1616   0000                   SP_FirK := SP_FirK + (SE_Siz - OB_Siz); (* Add size of SegmentPart *)
 1617   0000                   SP_FreK := SP_FreK - (SE_Siz - OB_Siz);
 1618   0000                  END;
 1619   0000               END;
 1620   0000    (*
 1621   0000              prt_mem('Makesegm', SegmentObject, AllocSiz);
 1622   0000    *)
 1623   0000            END;  (* MakeSegm *)
 1624   0000    
 1625   0000          VAR
 1626   0000             d1: integer; (* Allocation Space *)
 1627   0000             d2: integer; (* Page Table Size *)
 1628   0000    
 1629   0000             Inx: integer; (* MemList index *)
 1630   0000             Curr: integer; (* Current mem rec *)
 1631   0000             Prev: integer; (* Previous mem rec *)
 1632   0000             Next: integer; (* Next mem rec *)
 1633   0000             FFre: integer; (* First free byte *)
 1634   0000             TFre: integer; (* Top free byte *)
 1635   0000    
 1636   0000             Holder: MemRecPointerType; (* ^Holder mem rec of loaded modules *)
 1637   0000             CMRPtr: MemRecPointerType; (* ^Current mem rec *)
 1638   0000             CLMPtr: LdMdHeaderPtrType; (* ^Current load module *)
 1639   0000             TopModuleAddress: AddressType; (* Highest addr. in modules *)
 1640   0000             TopModuleSize: Integer; (* Size of loaded modules *)
 1641   0000    
 1642   0000             ObjDscPtr: LdMdObjectDescriptionPtrType;
 1643   0000                (* ^Program object descriptor *)
 1644   0000             KernelPart: AddressType; (* Address of kernel part of object *)
 1645   0000             UserPart: AddressType;   (* Address of user part of object *)
 1646   0000             Size: integer;           (* Size of primary envelope *)
 1647   0000             Envelope: AddressType;   (* Address of envelope *)
 1648   0000             SpaceDsc: AddressType;   (* Address of space descriptor *)
 1649   0000    
 1650   0000             LDSD_Inx: word;  (* Local data segment descriptor index *)
 1651   0000             LSD_Inx: word;   (* Load section descriptor index *)
 1652   0000             SegmentSize: integer; (* Size of segment *)
 1653   0000             Rest: integer;   (* Remaining size of protected modules *)
 1654   0000             ObjDscAddr: AddressType; (* Addr. of program object descriptor *)
 1655   0000             LDSDAddr: AddressType; (* Addr. of local data segment descriptor *)
 1656   0000             LSDAddr: AddressType; (* Addr. of load section descriptor *)
 1657   0000    
 1658   0000    
 1659   0000         BEGIN (* InitMMU *)
 1660   0000    
 1661   0000          (**** The bus error exception handler gets control if a non
 1662   0000                existing address or uneven address is referenced by the
 1663   0000                MMproc initialization phase *)
 1664   0000    
 1665   0000          KV_InVec(.2.) := addr(MMBusErr); (* Bus error vector*)
 1666   0000          KV_InVec(.3.) := addr(MMBusErr); (* Address error vector*)
 1667   0000    
 1668   0000          (**** Format the last part of the last ram area:
 1669   0000                Compute the addresses of:
 1670   0000                Page_Tab, L_Alloc, F_Alloc, F_Supvs, SupvStk *)
 1671   0000    
 1672   0000          WITH Mem_List (* pointed to by KV_FrMem *) DO
 1673   0000            BEGIN
 1674   0000             d1 := List(.Length.).End - List(.1.).Start;
 1675   0000             IF d1 <= 0 THEN
 1676   0000                Error(3)
 1677   0000            END;
 1678   0000    
 1679   0000          (**** The page table need not describe the memory holding
 1680   0000                the page table. The table contains 4 bytes for each
 1681   0000                page of 256 bytes, consequently:
 1682   0000    
 1683   0000                TABSIZE * 64 + TABSIZE = ALLOCSPACE
 1684   0000    
 1685   0000                <=>
 1686   0000    
 1687   0000                TABSIZE = ALLOCSPACE DIV 65
 1688   0000    
 1689   0000                Divide allocspace with 65;
 1690   0000                Tabsize may be larger than 2*16, hence simple
 1691   0000                division is insufficient *)
 1692   0000    
 1693   0000           d2 := 0;                    (* tabsize *)
 1694   0000           WHILE d1 > 65*65000 DO
 1695   0000             BEGIN
 1696   0000              d1 := d1 - 65*65000;
 1697   0000              d2 := d2 + 65000;
 1698   0000             END;
 1699   0000          d2 := (d2 + d1 DIV 65) + 7; (* round up by 7 *)
 1700   0000          IF odd(d2) THEN
 1701   0000             d2 := d2 - 1;            (* tabsize must be even *)
 1702   0000    
 1703   0000          WITH Mem_List DO
 1704   0000             d1 := (List(.Length.).End - d2) DIV 256 * 256;
 1705   0000          (* d1 = ( top of last ram area - tabsize ) truncated to page boundary *)
 1706   0000    
 1707   0000          L_Alloc := d1;  (* L_Alloc := last mem_rec *)
 1708   0000          Supv_Stk := d1; (* Top byte of Supv_Stk := L_Alloc *)
 1709   0000    
 1710   0000          (**** Set up the supervisor stack. Subroutines may now be called *)
 1711   0000    
 1712   0000          (*
 1713   0000             Subroutines called so far (this is a subroutine) have been using
 1714   0000             the initial supervisor stack pointer Init_SSP based at RAM_TOP.
 1715   0000             Init_SSP is boot loaded into the exception vector area.
 1716   0000             Will this stack be overwritten during initialization??
 1717   0000    
 1718   0000          *)
 1719   0000    
 1720   0000          (* stack pointer register "a7" := d1; *)
 1721   0000          F_Supvs := (d1 - KV_StkSiz) DIV 256 * 256;
 1722   0000    
 1723   0000          (**** The variable called page_tab should contain the address of
 1724   0000                entry # 0 of the page table and not the address of entry # 1 *)
 1725   0000    
 1726   0000           WITH Mem_List DO
 1727   0000             BEGIN
 1728   0000              Page_Tab := List(.Length.).End - d2 - List(.1.).Start DIV 256 * 4;
 1729   0000              F_Alloc :=  List(.1.).Start;
 1730   0000             END;
 1731   0000    (*
 1732   0000          Prt_Mem('F_Alloc_etc', F_alloc, MM_Queue-F_Alloc);
 1733   0000    *)
 1734   0000    
 1735   0000          (**** Set up initial mem_recs *)
 1736   0000    
 1737   0000          FOR Inx := 1 TO Mem_List.Length DO
 1738   0000             WITH Mem_List.List(.Inx.) DO
 1739   0000               BEGIN
 1740   0000                FFre := Start;
 1741   0000                IF Inx = 1 THEN
 1742   0000                  BEGIN
 1743   0000                   FFre := Start + MR_Siz;
 1744   0000                   Curr := Start;
 1745   0000                   Prev := FFre; (* Bad trick WIR says *)
 1746   0000                  END;
 1747   0000                TFre := (End - MR_Siz) div 256 * 256;
 1748   0000                Next := TFre;
 1749   0000                IF Inx = Mem_List.Length THEN
 1750   0000                  BEGIN
 1751   0000                   TFre := F_Supvs;
 1752   0000                   Next := L_Alloc;
 1753   0000                  END;
 1754   0000                IF Curr >= TFre THEN
 1755   0000                   Error(4);
 1756   0000                NewHead(Curr, User, Prev, Next);
 1757   0000                WITH MemRecPtr(Curr)^ DO
 1758   0000                  BEGIN
 1759   0000                   MR_Fst := FFre;
 1760   0000                   MR_Fre := TFre - FFre;
 1761   0000                  END;
 1762   0000    (*
 1763   0000                Prt_Mem('NewHead', Curr, MR_Siz);
 1764   0000    *)
 1765   0000                Prev := Curr;
 1766   0000                Curr := Next;
 1767   0000               END;
 1768   0000    
 1769   0000          (**** Curr = Last mem rec. Prev = mem rec holding supervisor stack
 1770   0000                adjust these mem rec.
 1771   0000                Assign known but illegal addresses to undefined chain fields *)
 1772   0000    
 1773   0000          WITH MemRecPtr(Curr)^ DO
 1774   0000            BEGIN
 1775   0000             MR_Prv := MemRecPtr(Prev);    (* last mem rec.prev := prior mem rec *)
 1776   0000             MR_Nxt := MemRecPtr(10#4711); (* next to last := odd address *)
 1777   0000             MR_Fix := Initial;  (* L_Alloc.fix := initial *)
 1778   0000             MR_Fre := 0;       (* L_Alloc.Free_Bytes := 0 *)
 1779   0000    (*
 1780   0000             Prt_Mem('LastHead', Curr, MR_Siz);
 1781   0000    *)
 1782   0000            END;
 1783   0000    
 1784   0000          MemRecPtr(Prev)^.MR_Typ := User;
 1785   0000    
 1786   0000          MemRecPtr(F_Alloc)^.MR_Prv :=
 1787   0000             MemRecPtr(10#7913) ; (* prior to first := uneven address *)
 1788   0000    (*
 1789   0000          Prt_Mem('FirstHead', F_Alloc, MR_Siz);
 1790   0000    *)
 1791   0000    
 1792   0000          (**** Create one segment object that has the boot loaded modules as
 1793   0000                segment data. This will protect the modules during the
 1794   0000                initialization. The AllocObj is used as the kernel part of this
 1795   0000                segment object *)
 1796   0000    
 1797   0000          IF KV_BotLd <> -1 THEN (* Modules have been boot loaded *)
 1798   0000            BEGIN
 1799   0000             (**** Find the mem rec that holds the boot loaded modules. This
 1800   0000                   mem rec is called holder. The modules must be present in one
 1801   0000                   of the mem recs. The modules may have been damaged by the
 1802   0000                   previous initialization if they were located too near to the
 1803   0000                   end (or beginning) of the ram area that holds the modules *)
 1804   0000    
 1805   0000             CMRPtr := MemRecPtr(F_Alloc); (* First mem rec *)
 1806   0000             REPEAT
 1807   0000                Holder := CMMRPtr;
 1808   0000                CMRPtr := CMRPtr^.MR_Nxt
 1809   0000             UNTIL PtrVal(CurrPtr) > KV_BotLd;
 1810   0000    
 1811   0000             (****  Find length of boot loaded modules *)
 1812   0000             TopModuleAddress := KV_BotLd + 256; (* including the zero module *)
 1813   0000             CLMPtr := LdMdPtr(KV_BotLd);
 1814   0000             REPEAT
 1815   0000                TopModuleAddress := TopModuleAddress + CLMPtr^.MOD_Size
 1816   0000             UNTIL CLMPtr^.MOD_Size = 0; (* Size of dummy top module = 0 *)
 1817   0000    
 1818   0000             (**** Restructure holder^. Create MemRec at TopModuleAddress *)
 1819   0000    (*
 1820   0000             Prt_reg('BootModule', **local variables ** *);
 1821   0000    *)
 1822   0000             IF TopModuleAddress mod 256 <> 0 THEN
 1823   0000                Error(1);
 1824   0000             ModuleSize := TopModuleAddress - KV_BotLd;
 1825   0000             IF ModuleSize mod 256 <> 0 THEN
 1826   0000                Error(2);
 1827   0000             IF ModuleSize > 256 THEN
 1828   0000                ReChainC(Holder^, KV_BotLd, ModuleSize, User)
 1829   0000            END
 1830   0000          ELSE  (* No boot loaded modules *)
 1831   0000             ModuleSize := 0;
 1832   0000          InitKnel(AllocObj, AllocSiz);
 1833   0000          IF ModuleSize > 256 THEN
 1834   0000             MakeSegm(ModuleSize, KV_BotLd, AllocObj);
 1835   0000    
 1836   0000          (**** Create Fulspace Object *)
 1837   0000          InitKnel(FulSpace, NEmb_Siz);
 1838   0000          MakeSegm(16#1000000, 0, FulSpace);
 1839   0000    
 1840   0000          (**** Initial Pointer Init *)
 1841   0000          WITH KV_IOwnP.Common DO
 1842   0000            BEGIN
 1843   0000             WITH Pointer.Chain DO
 1844   0000               BEGIN
 1845   0000                Next := ChainPtr(addr(KV_IOwnP));
 1846   0000                Prev := ChainPtr(addr(KV_IOwnP))
 1847   0000               END;
 1848   0000             PT_Inf := PT_lsc;
 1849   0000            END;
 1850   0000    
 1851   0000          WITH KV_IManP.Common DO
 1852   0000            BEGIN
 1853   0000             WITH Pointer.Chain DO
 1854   0000               BEGIN
 1855   0000                Next := ChainPtr(addr(KV_IManP));
 1856   0000                Prev := ChainPtr(addr(KV_IManP))
 1857   0000               END;
 1858   0000             PT_Inf := PT_lsc;
 1859   0000            END;
 1860   0000    
 1861   0000          (**** Various global variables *)
 1862   0000          MM_Lock := open;
 1863   0000          WITH MM_queue DO  (* := empty *)
 1864   0000            BEGIN
 1865   0000             Next := ChainPtr(addr(MM_queue));
 1866   0000             PRev := ChainPtr(addr(MM_queue))
 1867   0000            END;
 1868   0000    
 1869   0000          CurKMove := 0;  (* Clear move candidate *)
 1870   0000    
 1871   0000          (**** Allocate Stub Object. The Stub module can be found in KV_Stub
 1872   0000                (Stub in ROM) or (when KV_Stub = -1) in allocObj.SE_fir
 1873   0000                (Stub in RAM). *)
 1874   0000    
 1875   0000          ObjDscPtr: = LdMdObjDscPtr(Get_StMd +
 1876   0000                                           LdMdHdrPtr(Get_StMd)^.MOD_Prog
 1877   0000                                          );
 1878   0000          WITH ObjDscPtr DO
 1879   0000            BEGIN
 1880   0000             IF MOD_Locs < 10 THEN  (* If #local pointers < 10 then error *)
 1881   0000                Error(8);
 1882   0000             Size := (MOD_Locs*Pt_Siz)+SP_Siz+GE_Siz+EN_Siz;
 1883   0000             MM_Cre(Size, 0, KernelPart, UserPart);
 1884   0000             IF false THEN  (* Compare with line 2190 of mmprocs.sa *)
 1885   0000                Error(5);
 1886   0000            END;
 1887   0000    
 1888   0000          (**** Initial owner pointer holds the stub as the first member *)
 1889   0000          ChainOwn( KernelPart, KV_IOwnP, 0 (*, omitting a2 *) );
 1890   0000    
 1891   0000          (**** Create primary envelope *)
 1892   0000          Size := Size - SP_Siz - GE_Siz;
 1893   0000          MM_PushK(KernelPart, Envelope, Size, SpaceDsc);
 1894   0000          Init_Env(Size, Envelope, SpaceDsc);
 1895   0000    
 1896   0000          (**** Initial manager pointer holds the stub envelope as first member *)
 1897   0000          ChainMan( Envelope, KV_IManP, 0 (*, omitting a2 *) );
 1898   0000    
 1899   0000          (**** Initialize general part of stub object *)
 1900   0000          InitGein(PtrVal(Get_StubO), ObjDscPtr^.MOD_Ent);
 1901   0000    
 1902   0000          (**** Modify the stub object according to the description *)
 1903   0000          WITH GePtr(Get_StubO)^.GeneralPart, ObjDscPtr^ DO
 1904   0000            BEGIN
 1905   0000             GE_Temp := MOD_Temp + 1; (* including T(0) *)
 1906   0000             GE_Stk := MOD_Stk;  (* Sizetype *)
 1907   0000    
 1908   0000             (* Push MOD_Stk on stack to be picked up when boot process is
 1909   0000                created *)
 1910   0000    (* *** ??? *** *)
 1911   0000             GE_TemD := MOD_TemD
 1912   0000            END;
 1913   0000    
 1914   0000       (**** Create a set of non embedded segment objects.
 1915   0000             Each segment object contains a header segment or a load section
 1916   0000             from the boot loaded modules currently protected by the alloc
 1917   0000             object.The segment data of the alloc object shrinks as the new
 1918   0000             set grows. The set is owned by local-2 oof the stub object.
 1919   0000             The header sections as well as the load sections must be an integral
 1920   0000             number of pages *)
 1921   0000    
 1922   0000       IF KV_BotLd <> -1 THEN
 1923   0000          REPEAT
 1924   0000             WITH LdMdHdrPtr(Get_LdMd)^ DO
 1925   0000               BEGIN
 1926   0000    (*
 1927   0000                PrtMem('HeaderSection', Get_LdMd, 300 );
 1928   0000    *)
 1929   0000                (* Move the size of the header section and of the associated
 1930   0000                   load sections to the stack *)
 1931   0000    
 1932   0000                (* Save old stack pointer a7 in a6 *)
 1933   0000                Rest := MOD_Size;
 1934   0000                TstPage(MOD_HSiz, 6);
 1935   0000                Rest := Rest - MOD_HSiz;
 1936   0000                (*Push MOD_HSiz *)
 1937   0000                ObjDscAddr := Get_LdMd + MOD_prog;
 1938   0000                WITH LdMdObjDscPtr(ObjDscAddr)^ DO
 1939   0000                  BEGIN
 1940   0000                   LDSDAddr := ObjDscAddr + MOD_FDSD;
 1941   0000                   FOR LDSD_Inx := 1 TO MOD_LDSS DO
 1942   0000                     BEGIN
 1943   0000                      WITH LdMdLDSDPtr(LDSDAddr)^ DO
 1944   0000                        BEGIN
 1945   0000                         LSDAddr := LDSDAddr + MOD_LDSz;
 1946   0000                         FOR LSD_Inx := 1 TO MOD_LSDS DO
 1947   0000                            WITH LdMdLSDPtr(LSDAddr)^ DO
 1948   0000                              BEGIN
 1949   0000                               TstPage(MOD_Slen,6);
 1950   0000                               Rest := Rest - MOD_Slen;
 1951   0000                               (* Push MOD_Slen *)
 1952   0000                               LSDAddr := LSDAddr + MOD_LSDZ
 1953   0000                              END;
 1954   0000                         LDSDAddr := LDSDAddr + MOD_DSiz;
 1955   0000                        END
 1956   0000                     END
 1957   0000                  END;
 1958   0000                IF Rest <> 0 THEN
 1959   0000                   Error(7);
 1960   0000                (* Push saved old stck pointer in a6 onto stack *)
 1961   0000    
 1962   0000                (* The stack now contains a word and a number of longs.
 1963   0000                   Create segment objects according to these values. *)
 1964   0000    
 1965   0000                (* items are read from the stack bottom i.e. in the
 1966   0000                   sequence they were pushed *)
 1967   0000    
 1968   0000                (* SegmentSize := signextend(unpush(a6)); *)
 1969   0000                REPEAT
 1970   0000                   MM_Cre(NEmb_Siz, 0, KernelPart, UserPart);
 1971   0000                   IF false THEN
 1972   0000                      Error(8);
 1973   0000                   (**** Remap data into new object *)
 1974   0000                   MakeSegm(SegmentSize, Get_LdMd, KernelPart);
 1975   0000                   (**** Remove data from the protecting alloc segment *)
 1976   0000                   WITH AllocObj DO
 1977   0000                     BEGIN
 1978   0000                      SE_Fir := SE_Fir + SegmentSize;
 1979   0000                      SE_Len := SE_Len - SegmentSize;
 1980   0000                      WITH SpaceDscPtr(OB_Spa)^ DO
 1981   0000                        BEGIN
 1982   0000                         SP_FirU := SP_FirU + SegmentSize;
 1983   0000                         SP_SizU := SP_SizU - SegmentSize;
 1984   0000                        END
 1985   0000                     END;
 1986   0000    (*
 1987   0000                   PrtMem('Unprotect', AllocObj, AllocSiz);
 1988   0000    *)
 1989   0000                   (**** Chain new segment object to local-2 of stub object *)
 1990   0000                   ChainOwn(KernelPart, Get_StubE, EN_Siz+PT_Siz (*,omitting a2*));
 1991   0000                   (* SegmentSize := unpush(a6) size of next segment *)
 1992   0000                UNTIL (* a6 = a7 *);
 1993   0000                (* Restore old stak pointer a7 := a6; *)
 1994   0000    
 1995   0000    
 1996   0000               END
 1997   0000             UNTIL LdMDHdrPtr(Get_LdMd)^.MOD_Size = 0 (* zero module is reached *);
 1998   0000             IF AllocObj.SE_Len <> 256 THEN
 1999   0000                Error(7);  (* Module jam *)
 2000   0000             RemoveUS(AllocObj.SE_Len, Get_LdMd);
 2001   0000    
 2002   0000          (**** Set up program ref in local-1 of stub *)
 2003   0000          IF KV_Stub <> -1 THEN  (* Stub module in ROM *)
 2004   0000            BEGIN
 2005   0000             (* Create a subsegment of the fulspace segment describing the local
 2006   0000                sections of the module *)
 2007   0000    
 2008   0000             MM_Cre(SU_Siz+SP_Siz, 0, KernelPart, UserPart);
 2009   0000             WITH LdMdHdrPtr(KV_Stub)^, SuPtr(KernelPart)^ DO
 2010   0000               BEGIN
 2011   0000                WITH CommonPart DO
 2012   0000                  BEGIN
 2013   0000                   OB_Kin := OB_SEOB;
 2014   0000                   OB_Sta := OB_SUB;
 2015   0000                  END;
 2016   0000                WITH SegmentPart DO
 2017   0000                  BEGIN
 2018   0000                   SE_Io := 0;
 2019   0000                   SE_Fir := KV_Stub + MOD_HSiz;
 2020   0000                   SE_Len := MOD_Size - MOD_HSiz;
 2021   0000                   InitHead(SE_Wait, DummyAddr);  (* Make list empty *)
 2022   0000                  END;
 2023   0000                ChainOwn(KernelPart, GetStubE, EN_Siz);
 2024   0000    
 2025   0000                (**** Let the segment pointer of the subsegment point to
 2026   0000                      the fulspace segment object *)
 2027   0000                WITH SubSegmentPart DO
 2028   0000                  BEGIN
 2029   0000                   SimplePt(SU_P, FulSpace);
 2030   0000                   SU_P.Common.PT_Kin := PT_Seg
 2031   0000                  END
 2032   0000               END
 2033   0000            END
 2034   0000          ELSE
 2035   0000             (* The stub is in RAM. The second object in the owner set
 2036   0000                of local-2 of the stub will be the code segment. Create a
 2037   0000                simple pointer to that object *)
 2038   0000             SimplePt(PointerPtr(EN_Siz+GetStubR)^,
 2039   0000                      SePtr(PointerPtr(EN_Siz+PT_Siz+GetStubE)^.Next)^);
 2040   0000    
 2041   0000          (**** Local-6 of the stub envelope should point to the fulspace
 2042   0000                object *)
 2043   0000          SimplePt( PointerPtr(EN_Siz+5*PT_Siz+GetStubE)^, FulSpace9;
 2044   0000    
 2045   0000          (**** Initialize the AllocObj as the initila alloc object
 2046   0000                of the kernel *)
 2047   0000          InitKnel(AllocObj, AllocSiz);
 2048   0000          WITH AllocObj.Common DO
 2049   0000            BEGIN
 2050   0000             OB_Kin := OB_Allo;
 2051   0000             OB_Sta := (.OB_Reen.);
 2052   0000    (*
 2053   0000             PrtMem('FinalAlloc', AllocObj, AllocSiz);
 2054   0000    *)
 2055   0000            END;
 2056   0000    
 2057   0000          (**** Local-3 of the stub should point to the AllocObj *)
 2058   0000          SimplePt(PointerPtr(EN_Siz+2*PT_Siz+GetStubE)^, AllocObj);
 2059   0000    
 2060   0000          (**** Locals 4,5,7,8, and 9 are initialized b the scheduler,
 2061   0000                local  10 by enter. *)
 2062   0000    
 2063   0000    (*
 2064   0000          PrtMem('EndOfMMprocs', (a7), 8)
 2065   0000    *)
 2066   0000         END;  (* InitMMU *)
 2067   0000    
 2068   0000    
 2069   0000    
 2070   0000       PROCEDURE InitSC;
 2071   0000    
 2072   0000          VAR
 2073   0000             Dummy: integer;
 2074   0000    
 2075   0000         BEGIN (* InitSC *)
 2076   0000    
 2077   0000          (**** The scheduler initialization gets control after
 2078   0000                mmproc has initiAlized .
 2079   0000    
 2080   0000                The following steps are carried out:
 2081   0000    
 2082   0000                (1) Initialize simple global variables.
 2083   0000                (2) Initialize initial objects.
 2084   0000                (3) Initialize stub object.
 2085   0000                (4) Initialize trap#8 = interrup_end. *)
 2086   0000    
 2087   0000          (**** Initialize simple variables *)
 2088   0000          InitHead(Timer,   Dummy);  (* Queues := empty *)
 2089   0000          InitHead(Running, Dummy);
 2090   0000          InitHead(Driving, Dummy);
 2091   0000          WITH RtCnt DO
 2092   0000            BEGIN
 2093   0000             msl := 0;
 2094   0000             lsl := 0
 2095   0000            END;
 2096   0000    
 2097   0000          (**** Initialize interrupt context and scheduler objects *)
 2098   0000    
 2099   0000    
 2100   0000    
 2101   0000    
 2102   0000    
 2103   0000         END;  (* InitSC *)
 2104   0000    
 2105   0000    
 2106   0000    
 2107   0000    
 2108   0000      BEGIN (* EosKernel *)
 2109   0000       InitPreface;
 2110   0000       InitMMU;
 2111   0000       InitSc;
 2112   0000       InitKnelOp;
 2113   0000       InitEnter;
 2114   0000      END. 
«eof»