|
|
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: 21632 (0x5480)
Types: TextFile
Names: »KNELVAR.PAS«
└─⟦08e5746f0⟧ Bits:30009789/_.ft.Ibm2.50007359.imd Mogens Pelles Zilog 80,000 / EOS projekt
└─⟦this⟧ »KNELVAR.PAS«
CONST (* Comdef *)
SchTemP = 3; (* #Temp pointers in ctx in general scheduler
objects (incl T(0) ) *)
SchTemD = 200;
(* #Temp data bytes in context in general
scheduler objects *)
KV_StkSiz = 16#800;
(* Initial size of the supervisor stack (in bytes) *)
Trp7Stak = 16#100;
(* Stack space (#bytes) required by normal kernel
operations i.e. operations called from normal
contexts only *)
Trp7Resi = 16#80 + 16#FF;
(* 16#FF is a "round up" value. The rest is the
stack space (#bytes) needed by the kernel on
each of the interrrupt levels to execute the
kernel operations called by resident contexts
and by the interrupt procedures. *)
(* KV_StkSiz - Trp7Stak - (Trp7Resi - 16#FF)*8
must be positive. The value gives number of bytes in the
supervisor stack that can be used by the interrupt
procedures.
Trp8Stack = 16#FE ? Stack space required to save the processor
state when trap #8 is called. It is not significant because
it is less than one page. (One page is ensured by Trp7Resi).
*)
TimeSlic = 10000000;
(* 10 seconds is used for test
25,6 millisecods is a reasonable value *)
Dont_Use = 0;
(* #bytes.
The last <dont_use> bytes of the memory will
never be used. If all available mamory can be
requested by the users, compression will often
take place when the system is heavily loaded
(slow alloc). If memory is divided in several
ram areas the memory exchange guarantee cannot
be fulfilled due to memory fragmentation. This
problem disappears if
largest_segment*no_of_ram_areas < dont_use.
(I think this is ok ???) *)
(* *** ??? *** *)
PTM_VEC = 16#8C;
(* Interrupt vector index for timer device.
Address of vector is index multiplied by 4 *)
CONST (* Preface *)
I_Config = -1;
(* address of the first ROM-OS-module to be
booted by the stub. -1 ignals that the
first module is in the boot owner set *)
RAM_TOP = 16#C000;
(* upper available ram address
384K = 16#6 * 64K
512K = 16#8 * 64K
640K = 16#A * 64K
768K = 16#C * 64K *)
Init_SSP = RAM_TOP;
(* use top RAM as initial stack pointer
Mem_ListLength = 1;
(* Only one record in the Mem_List *)
CONST (* MMProcs *)
AllocSiz = Se_Siz + Sp_Siz; (* *** ??? *** *)
(* NEmb_Siz now defined in file comdef.pas *)
TYPE (* Preface *)
ExceptionVectorAreaIndexType = 0..255;
ExceptionVectorAreaType = ARRAY (.ExceptionVectorAreaIndexType.) OF
AddressType;
MemListRecordType = RECORD
Start, (* lower memory address *)
End: AddressType; (* upper memory address *)
Mem_ListType = RECORD
Length: integer;
List: ARRAY (.1..Mem_ListLength.) OF MemListRecordType
END;
MmuChipType = byte;
(* *** ??? *** *) (* byte??? *)
TimerRegisterType = RECORD (* Interpretation based on M68000 *)
Filler1: byte; (* instruction MOVEP used in ENTER.SA *)
MSB: byte; (* page 4 *)
Filler2: byte;
LSB: byte;
END;
PtmChipType = RECORD
Filler1: byte;
Contrl13: byte; (* Control register 1 or 3 *)
Filler2: byte;
StatCon2: byte; (* Control register2 and Status *)
Filler3: TimerRegisterType;
(* Probably used for timer1 *)
Timer2,
Timer3: TimerRegisterType
END;
(*IMPORTED*) VAR (* Comdef *) (* Test panel status word *)
TstPanel: byte; (* based at 16#FE0000 *)
(*IMPORTED*) VAR (* Comdef *) (* Printer device control and data registers *)
PrtContA: byte; (* based at 16#FEE00B *)
PrtContB: byte; (* FEE00F *)
PrtStatu: byte; (* FEE00D *)
PrtBuf: byte; (* FEE009 *)
(*IMPORTED*) VAR (* Preface *) (* MMU device *)
KV_MMU: MmuChipType;
(* based at 16#FE2000 *)
(*IMPORTED*) VAR (* Comdef *) (* Timer device *)
PtmChip: PtmChipType;
(* based at 16#FEE040 *)
(*IMPORTED*) VAR (* Preface *)
KV_InVec: ExceptionVectorAreaType;
(* Interrupt vector (normally = 0), contains addresses
of the interrupt procedures. The addresses are
adjusted when the segments holding the procedures
are moved *)
(* KV_InVec(.0.) is assumed to be initialized to
the initial value of the SSP (System stack pointer)
= Init_SSP prior to boot loading.
KV_InVec(.1.) is assumed to be initialized to
the initial value of the PC prior to boot
loading *)
KV_FrMem: AddressType;
(* Initially: points to Mem_List;
Later: Number of free bytes for allocation of objects.
KV_FrMem is assumed to be initialized prior to
boot loading *)
KV_BotLd: AddressType;
(* Lower starting address of bootloaded OS-modules
(RAM-boot) or the value -1 (ROM-boot).
Initially states absolute minimum address
(First_OS) but is upward page aligned.
KV_BotLd is assumed to be initialized prior to
boot loading. *)
KV_Stub: long;
(* Contains the address of a ROM-stub or -1
when the stub is the first module of the
RAM-boot. *)
(* KV_Stub is assumed to be initialized to
the value -1 indicating that the stub is
booted in RAM *)
Mem_List: Mem_ListType;
(* Mem_List(.1.).Start is assumed to be initialized
to TOP_KNEL prior to boot loading.
Mem_List(.1.).End is assumed to be initialized
to RAM_TOP prior to boot loading *)
VAR (* Preface *) (* Variables used by test print procedures *)
TstCount: word;
(* Counts down from 50 the number of output lines *)
TstStatus: word;
(* State of test output *)
(* Test output from alloc/dealloc is generated
when bit zero of this variable equals one *)
TYPE (* MMPROCS *)
MR_FixType = (Dynamic, Initial);
MR_TypType = (Free, Kernel, User);
MemRecPointerType = ^MemRecType;
MemRecType = RECORD
MR_Nxt: MemRecPointerType; (* Addr. of next mem rec *)
MR_Prv: MemRecPointerType; (* Addr. of prior mem rec *)
MR_Fst: AddressType; (* Addr. of first free byte *)
MR_Fre: Integer; (* Number of bytes in the free part *)
MR_Fix: MR_FixType;
MR_Typ: MR_TypType;
END;
LoadModuleHeaderPointerType = ^LoadModuleHaeaderType;
LoadModuleHeaderType = RECORD
MOD_Hsiz: word; (* The size of the module header segment *)
MOD_Size: integer;
(* The size of the whole module
0 means dummy top module *)
MOD_Kind: word; (* Module kind. Should be 0=program module *)
MOD_Prog: word; (* The address of the program description
relative to MOD_HSiz *)
END;
LdMdObjectDescriptionType = RECORD
MOD_FDSD: word; (* Address of first data segment description
relative to MOD_Fdsd *)
MOD_Locs: word; (* No of local pointers in object *)
MOD_Temp: word; (* NO of temp pointers in contexts *)
MOD_TemD: integer;
(* No of temp bytes in contexts *)
MOD_Stk: SizeType;
(* Call stack requirement = Size of boot proc *)
MOD_Ent: AddressType;
(* Entry address to program *)
MOD_Nul1: word; (* Unused field *)
MOD_LDSS: word; (* No of local data segment descriptions *)
END;
LdMDLocalDataSegmentDescriptionType = RECORD
MOD_DSiz: word; (* Size of description *)
MOD_Nul2: ARRAY (.1..24.) OF byte;
(* Unused fields *)
MOD_LSDs: word; (* No of local section descriptions *)
MOD_LdSz: word; (* Size of fixed part of data segment description *)
END;
LdMdLoadSectionDescriptionType = RECORD
MOD_Nul3: ARRAY (.1..4.) OF byte;
(* Unused fields *)
MOD_SLen: integer;
(* Length of the load section segment *)
MOD_Nul4: ARRAY (.1..4.) OF byte;
(* Unused fields *)
MOD_LSDZ: word; (* Size of one load section description *)
END;
CONST (* MMPROCS *)
MR_Siz = sizeof(MemRecType);
VAR (* MMProcs *)
F_Alloc: AddressType; (* Address of the first mem_rec *)
L_Alloc: AddressType; (* Address of the last mem_rec *)
F_Supvs: AddressType; (* Address of the supervisor stack (first byte) *)
Page_Tab: AddressType; (* Address of the page table (addr of entry zero) *)
Supv_Stk: AddressType; (* "Last + 1" address of the supervisor stack *)
MM_Queue: ChainType;
(* chain of processes waiting to create/remove an object *)
MM_Lock: MM_LockType;
(* *** ??? *** *)
(**** Initial pointers *)
KV_IOwnP: PointerType;
(* Owns objects that are never deleted. Stub object
is first in set *)
KV_IManP: PointerType;
(* Manages envelopes that are never demanaged. Stub
envelope is first in set *)
KV_DummyOwn: PointerType;
(* Owns a kernel part while the user part is being
allocated. (Is not initialized) *)
(**** Initial objects *)
AllocObj: NonEmbeddedSegmentObjectType;
(* AllocObj holds the kernel part of the kernel
defined alloc object. During MM_initialization
the kernel part is used as the kernel part of
a non-embedded segmnet describing the boot
loaded modules *)
FulSpace: NonEmbeddedSegmentObjectType;
(* FulSpace is a segment object describing the whole
address space of the MC68000. Subsegments of
FulSpace is used by driver objects. The Stub
object gets a reference to FulSpace *)
(**** Global temporary variables used during calls to mm-procs *)
CurKMove: AddressType;
(* Current kernel move candidate *)
(* Also used as CurUMove = Current User move candidate *)
(* Holds the address of the next item (envelope,
context or segment) to be moved by the mm-procs. The
item will be moved when mm-procs reenters the
sub mm-monitor.
The item may be destroyed by a call to an mm-pop
procedure. In this case the mm-pop procedure will
update the variable *)
CurKHead: AddressType;
(* = Cur_Head. Holds the address of the head of a
context chain or of an envelope chain *)
CurObOb: AddressType;
(* Holds the address of an object *)
CurDist: integer;
(* Holds the distance that items should be moved *)
Cur_Stak: AddressType;
(* Holds the address of a context or an envelope *)
Cur_Embs: AddressType;
(* Holds the address of an embedded segment object *)
UserDest: AddressType;
(* Holds the fututre address of a user part being moved.
If the current user move candidate is destroyed,
the move is actually finished, and future allocation
of user segments should be allocated according to
the new position of the user part. This is ensured
by the MM-popu, by moving userdest to SP_FirU of
the space_Description, in case CurUMove is popped *)
SaveNeed: integer;
(* Holds the >>bytes needed<< during alloc.new_obj *)
Save_RPA: integer;
(* Holds the pointer argument during alloc.new_obj *)
KSavPrt: ARRAY (.1..15.) OF integer;
(* = USavPrt. Used by C_UParts and C_KParts *)
KSavCrs: ARRAY (.1..15.) OF integer;
(* = USavCrs. Used by M_Uacroes and M_Kacroes *)
KSavMov: ARRAY (.1..15.) OF integer;
(* = USavMov. Used by MoveUser and MoveKnel *)
Sav_Chk: ARRAY (.1..2.) OF integer;
(* Used by Check_Tir *)
(**** NewHead macro *)
PROCEDURE NewHead(
Curr: AddressType; (* Addr. of new MemRec head *)
Fix: MR_FixType; (* Value for MR_Fix field *)
Typ: MR_TypeType; (* Value for MR_Typ field *)
Prev: AddressType; (* Addr. of previous MemRec head *)
Next: AddressType (* Addr. of next MemRec head *)
);
(* The NewHead procedure creates a head for a new MemRec and
adjusts the chain to the next and prior MemRecs
OBS: MR_Fre Free Bytes are not assigned. The fields are
often reassigned by caller
*)
VAR
CurPtr: MemRecPointerType;
BEGIN
CurPtr := MemRecPtr(Curr);
WITH CurPtr^ DO
BEGIN
MR_Fst := Curr;
MR_Fix := Fix;
MR_Typ := Typ;
MR_Prv := MemRecPtr(Prev);
MR_Nxt := MemRecPtr(Next);
END;
WITH CurPtr^.Prv^ DO
MR_Nxt := MemRecPtr(Curr);
WITH CurPtr^.Nxt^ DO
MR_Prv := MemRecPtr(Curr);
END;
(**** MovLm Macro *)
PROCEDURE MovLm(
VAR AS: AddressType; (* Address of source *)
VAR AD: AddressType; (* Addres of destination *)
);
(* References to the element to be moved are changed to
reflct the new position of the element. The element is
moved. AS and AD are increased by the size of element (=8) *)
(* It might be considerably easier to have parameters of
chainpointertype depending on how the procedure is used *)
VAR
SrcPtr: ChainPointerType;
DstPtr: ChainPointerType;
BEGIN
SrcPtr := ChainPtr(AS);
DstPtr := ChainPtr(AD);
WITH SrcPtr^ DO
BEGIN
Next^.Prev := DstPtr;
Prev^.Next := DstPtr;
DstPtr^.Next := Next;
DstPtr^.Prev := Prev;
END;
AS := AS + Ch_Siz*2;
AD := AD + Ch_Siz*2;
END;
(**** MovHd macro *)
PROCEDURE MovHd(
AS: AddressType; (* Address of source *9
AD: AddressType; (* Address of destination *)
NR: AddressType (* New reference for the Ch_hold field *)
);
(* All references (CH_Hold) in elements in chain are set to NR.
References to the chain head are changed to reflect the
new position of the chain head. The element is moved.
AS and AD are increased by the size of the head (= 8) *)
(* It might be considerably easier to have parameters of
chainpointertype depending on how the procedure is used *)
VAR
SrcPtr: ChainPointerType;
DstPtr: ChainPointerType;
BEGIN
SrcPtr := ChainPtr(AS);
DstPtr := ChainPtr(AD);
WITH SrcPtr^ DO
BEGIN
Next^.Prev := DstPtr;
Prev^.Next := DstPtr;
CurPtr := Next;
WHILE CurPtr <> DstPtr DO
(* *** ??? *** Why is SrcPtr^.Prev^.CH_Hold not updated with NR ??? *** *)
WITH CurPtr^ DO
BEGIN
CH_Hold := NR;
(*
PrtMem('MovHd_NewRef', CurPtr^, PT_Siz);
*)
CurPtr := CurPtr^.Next
END;
DstPtr^.Next := Next;
DstPtr^.Prev := Prev;
END;
AS := AS + Ch_Siz*2;
AD := AD + Ch_Siz*2;
END;
(**** TstPage macro *)
PROCEDURE TstPage(
A: AddressType; (* Address to test *)
E: ErrorNo (* Error number
);
(* Tests that a value is a multiple of 256. Generate an address
exception if it is not the case. The Test is used in the
initialization (WIR says) *)
BEGIN
IF A mod 256 <> 0 THEN
Error(E)
END;
CONST (* SC *)
A_Formal = 0; (* Direct address of formal pointer *)
A_Local = 16#8000; (* Direct address of local pointer *)
A_Temp = 16#4000; (* Direct address of temporary pointer *)
Act_Siz = AR_Siz; (* Size of actual arg/subsegm arg/void value arg *)
TYPE (* SC *)
ChannelIndexType = 0..255;
StakTabRecordType = RECORD
IntStk: word;
level: word
END;
DrivTabType = ARRAY (. ChannelIndexType .) OF AddressType;
StakTabType = ARRAY (. ChannelIndexType .) OF StakTabRecordType;
(* Both entries are zero for an unused channel and -1 for a
permanently reserved channel.
After a driver for a cahnnel is installed DrivTab(Channel)
contains the address of the field "Env.Enstk" of the driver
envelope (<> 0) and StakTab(Channel) contains int_stk and
level (<> 0).
Int_Stk tells the max number of bytes used uring processing
of a channel interrupt. Level gives the interrupt level of
the associated interrupt procedure of the channel. *)
RtCntType = RECORD
msl, (* most significant long word *)
lsl: integer (* least significant long word *)
END;
SchedulerType = byte;
DDivSchType = byte;
SegmentObjectType = byte;
InterruptContextType = byte;
SchdArgType = byte;
VAR (* SC *)
DrivTab: DrivTabType;
StakTab: StakTabType;
Timer: ChainType; (* Processes waiting for time out.
Proc= running_current or
proc.state= wait=2 or =D_wait=4 *)
Running: ChainType; (* Processes executing normal contexts.
Proc.state=run=0 *)
Driving: ChainType; (* Processes executing resident contexts.
Proc.state=run=0 or =D_wait=4 *)
KV_Ctx: AddressType; (* Top context of current process.
zero when dummy process is running *)
KV_Proc: AddressType; (* Current process. Used to identify the
process that called the kernel.
Undef when dummy process is running *)
KV_SPSave: AddressType; (* Current supervisor stack pointer.
Changes when a recursion of the
scheduler is created or removed
(see tr_tr8 ff). Points to saved
A4,A5,A6,SR,PC in the stack *)
SAVE_PC: AddressType;
SAVE_SR: word;
(* Used by scheduler to save PC and SR
of current process *)
RTCNT: RtCntType; (* 64 bit real time counter. Initially
zero. Counts the elapsed time in micro
seconds *)
(**** Initial objects *)
Init_Sch: SchedulerType; (* Initial scheduler object *)
Norm_Sch: SchedulerType; (* Normal scheduler object *)
Intr_Sch: SchedulerType; (* Interrupt scheduler object *)
DDiv_Sch: DDivSchType; (* Decl_Div object *)
Sch_Code: SegmentObjectType; (* Segment object holding code of Sched *)
Int_Ctx: InterruptContextType; (* ST_fields + CT_Topt are present
in the interrupt_Ctx. The
context is "Current context"
when an interrupt procedure calls
the kernel *)
Schd_Arg: SchdArgType; (* Used when a gate creates a cond by calling
scheduler object *)
«eof»