|
|
DataMuseum.dkPresents historical artifacts from the history of: Bogika Butler |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Bogika Butler Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 114816 (0x1c080)
Types: TextFile
Names: »KERNEL.PRN«
└─⟦08e5746f0⟧ Bits:30009789/_.ft.Ibm2.50007359.imd Mogens Pelles Zilog 80,000 / EOS projekt
└─⟦this⟧ »KERNEL.PRN«
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»