DIRECTORY
BootFile USING [Location, nullLink],
BootStartList USING [Base],
DebuggerFormat USING [ DebugParameter, ExternalStateVector, SwapInfo, SwapReason, VersionID],
DebuggerSwap USING [Frozen],
DeviceCleanup USING [InitializeDeviceCleanup, Perform],
GermSwap USING [GetPStartListHeader, Initialize, InLoad, mdsiGerm, OutLoad, switches--.h, .i, .r--, Teledebug],
KeyboardFace USING [DownUp, keyboard],
Keys USING [KeyBits],
MPCodes USING [cantWorldSwap, emptyMP, hanging],
PrincOps USING [Byte, ControlLink, Frame, FrameHandle, FaultIndex, GlobalFrameHandle, NullFrame, NullLink, PageNumber, PDA, Port, Priority, PsbIndex, QueueHandle, sAlternateBreak, sBreak, sBreakBlock, sBreakBlockSize, SD, sError, sErrorList, sReturnError, sReturnErrorList, sSignal, sSignalList, StateVector, sUnnamedError, SVPointer, sXferTrap, XferTrapStatus, zDUP],
PrincOpsUtils USING [ DisableInterrupts, EnableAndRequeue, EnableInterrupts, GetReturnFrame, GetReturnLink, HighHalf, MyLocalFrame, PsbHandleToIndex, PsbIndexToHandle, ReadPSB, ReadPTC, ReadWDC, ReadXTS, SetReturnFrame, SetReturnLink, WritePSB, WritePTC, WriteWDC, WriteXTS],
Process USING [Detach, DisableTimeout, GetPriority, InitializeCondition, InitializeMonitor, Priority, priorityClient3, prioritySwatWatcher, SetPriority],
ProcessorFace USING [BootButton, GetClockPulses, microsecondsPerHundredPulses, SetMP],
RuntimeError USING [UCSProc];

DebugNub: MONITOR -- for CheckInterrupt
IMPORTS DeviceCleanup, GermSwap, KeyboardFace, PrincOpsUtils, Process, ProcessorFace
EXPORTS DebuggerSwap
SHARES DeviceCleanup =

BEGIN


teledebug: PUBLIC BOOL; -- TRUE forces teledebugging

diskDebugger: BOOL; -- TRUE means disk debugging is available

locDebuggee: BootFile.Location;
locDebugger: BootFile.Location;
pMicrocodeCopy: LONG POINTER; -- debugger's microcode (not implemented)
pGermCopy: LONG POINTER; -- debugger's germ (not implemented)
nGerm: CARDINAL; -- number of words in debugger's germ

CAbort: ERROR = CODE;
KillThisTurkey: ERROR = CODE;
Quit: ERROR = CODE;



InitBreakBlocks: PROC = -- Pilot remnant
BEGIN
PrincOps.SD[PrincOps.sBreakBlock] _ 0 --NIL--;
PrincOps.SD[PrincOps.sBreakBlockSize] _ 0;
END;

Break: PROC =
BEGIN
state: RECORD [
padding: ARRAY [0..2) OF UNSPECIFIED, v: PrincOps.StateVector];
state.v _ STATE;
state.v.dest _ PrincOpsUtils.GetReturnLink[];
state.v.source _ PrincOps.NullLink;
CoreSwap[breakpoint, @state.v];
IF PrincOpsUtils.ReadXTS[] = on THEN PrincOpsUtils.WriteXTS[skip1];
RETURN WITH state.v;
END;

WorryBreaker: PROC RETURNS [PrincOps.FrameHandle] =
BEGIN
state: RECORD [padding: ARRAY [0..2) OF UNSPECIFIED, v: PrincOps.StateVector];
state.v.instbyte _ 0;
state.v.stkptr _ 1;
state.v.stk[0] _ PrincOpsUtils.MyLocalFrame[];
state.v.dest _ PrincOpsUtils.GetReturnLink[];
state.v.source _ PrincOps.NullLink;
PrincOpsUtils.DisableInterrupts[];
DO
IF PrincOpsUtils.ReadXTS[] = on THEN PrincOpsUtils.WriteXTS[skip1];
PrincOpsUtils.EnableInterrupts[];
TRANSFER WITH state.v;
PrincOpsUtils.DisableInterrupts[];
state.v _ STATE;
state.v.dest _ PrincOpsUtils.GetReturnLink[];
state.v.source _ PrincOps.NullLink;
swapInfo.state _ @state.v;
swapInfo.reason _ worrybreak; -- set mds too
ToDebugger[@swapInfo];
ENDLOOP;
END;


Catcher: PUBLIC RuntimeError.UCSProc =
BEGIN
signallerGF: PrincOps.GlobalFrameHandle;
state: PrincOps.StateVector;
f: PrincOps.FrameHandle;
state.stk[0] _ msg;
state.stk[1] _ signal;
state.stkptr _ 0;
f _ PrincOpsUtils.GetReturnFrame[];
signallerGF _ f.accesslink;
f _ (state.dest _ f.returnlink).frame;
IF f.accesslink = signallerGF THEN state.dest _ f.returnlink;
CoreSwap[uncaughtsignal, @state ! CAbort => GOTO abort];
EXITS
abort =>
IF signal = LOOPHOLE[ABORTED] THEN {BackStop[frame]; ERROR KillThisTurkey}
ELSE ERROR ABORTED;
END;

BackStop: PROC [root: PrincOps.FrameHandle] =
BEGIN
endProcess: PrincOps.ControlLink = root.returnlink;
Caller: PROC = LOOPHOLE[PrincOpsUtils.GetReturnLink[]];
root.returnlink _ [frame[PrincOpsUtils.MyLocalFrame[]]];
PrincOpsUtils.SetReturnFrame[PrincOps.NullFrame];
Caller[ ! KillThisTurkey => CONTINUE];
PrincOpsUtils.SetReturnLink[endProcess];
END;

StubSignalHandler: PROC = -- handles signals before SignalsImpl is available
BEGIN
state: RECORD [padding: ARRAY [0..2) OF UNSPECIFIED, v: PrincOps.StateVector];
state.v _ STATE;
DO WorryCallDebugger["Signal too early"L] ENDLOOP;
END;



swatWatcherEnabled: BOOL;
interruptWanted: BOOL;
interrupter: CONDITION;

CheckInterrupt: ENTRY PROC =
BEGIN
interruptState: KeyboardFace.DownUp _ up;
pKeys: LONG POINTER TO Keys.KeyBits = LOOPHOLE[KeyboardFace.keyboard];
wakeup: CONDITION;
Process.InitializeCondition[@wakeup, 1];
DO --FOREVER--
ENABLE ABORTED => CONTINUE;
WAIT wakeup;
IF pKeys[Spare3] = down AND pKeys[Ctrl] = down THEN
BEGIN
IF interruptState = up AND swatWatcherEnabled THEN
BEGIN
interruptState _ down;
teledebug _ pKeys[Spare1]=down;
IF pKeys[LeftShift] = down THEN
WorryCallDebugger["Keyboard interrupt (worry mode)"L]
ELSE { interruptWanted _ TRUE; NOTIFY interrupter };
END;
END
ELSE interruptState _ up;
ENDLOOP;
END;

InterruptSpawner: PROC =
BEGIN
WaitUntilWanted: ENTRY PROC =
BEGIN
ENABLE UNWIND => NULL;
interruptWanted _ FALSE;
UNTIL interruptWanted DO WAIT interrupter ENDLOOP;
END;
DO ENABLE ABORTED => CONTINUE;
WaitUntilWanted[];
Process.Detach[FORK Interrupt[]];
ENDLOOP;
END;

Interrupt: PROC =
BEGIN
CallDebugger["Keyboard interrupt"L];
END;

swatWatcherStarted: BOOL;

StartSwatWatcher: PUBLIC ENTRY SAFE PROC[enabled: BOOL] = TRUSTED
BEGIN
IF NOT swatWatcherStarted
THEN BEGIN
priorityPrev: PrincOps.Priority = Process.GetPriority[];
Process.InitializeCondition[@interrupter, 0];
Process.DisableTimeout[@interrupter];
Process.SetPriority[Process.priorityClient3];
Process.Detach[FORK InterruptSpawner[]];
Process.SetPriority[Process.prioritySwatWatcher];
Process.Detach[FORK CheckInterrupt[]];
Process.SetPriority[priorityPrev];
swatWatcherStarted _ TRUE;
END;
swatWatcherEnabled _ enabled;
END;

EnableSwatWatcher: PUBLIC ENTRY SAFE PROCEDURE[enabled: BOOL] =
CHECKED{ swatWatcherEnabled _ enabled };


CallDebugger: PUBLIC SAFE PROC [s: STRING] = TRUSTED
BEGIN
state: RECORD [a, b: UNSPECIFIED, v: PrincOps.StateVector];
state.v _ STATE;
state.v.stk[0] _ s;
state.v.stkptr _ 1;
state.v.dest _ PrincOpsUtils.GetReturnLink[];
CoreSwap[explicitcall, @state.v]
END;

worryCallIndirect: PORT;

WorryCallDebugger: PUBLIC SAFE PROC[STRING];

DoWorryCallDebugger: PROC RETURNS [SAFE PROC[STRING]] =
BEGIN OPEN PrincOps;
state: RECORD [padding: ARRAY [0..2) OF UNSPECIFIED, v: StateVector];
state.v.instbyte _ 0;
state.v.stkptr _ 1;
LOOPHOLE[worryCallIndirect, PrincOps.Port].frame _ PrincOpsUtils.MyLocalFrame[];
state.v.stk[0] _ @worryCallIndirect;
state.v.dest _ PrincOpsUtils.GetReturnLink[];
state.v.source _ PrincOps.NullLink;
PrincOpsUtils.DisableInterrupts[];
DO --FOREVER--
IF PrincOpsUtils.ReadXTS[] = on THEN PrincOpsUtils.WriteXTS[skip1];
PrincOpsUtils.EnableInterrupts[];
TRANSFER WITH state.v;
PrincOpsUtils.DisableInterrupts[];
state.v _ STATE;
state.v.dest _ state.v.stk[state.v.stkptr + 1];
PrincOpsUtils.SetReturnLink[state.v.dest];
state.v.source _ PrincOps.NullLink;
swapInfo.state _ @state.v;
swapInfo.reason _ worrycall;
ToDebugger[@swapInfo];
ENDLOOP
END;


freezeesTable: PUBLIC DebuggerSwap.Frozen;

freezer: PUBLIC POINTER TO local PrincOps.Frame;

qFreeze: PrincOps.FaultIndex = 3;

AllocFreezer: PROC RETURNS[ POINTER TO local PrincOps.Frame ] =
BEGIN
Caller: PROC[PrincOps.FrameHandle] = LOOPHOLE[PrincOpsUtils.GetReturnFrame[]];
DummyReturnLink: PROC = {ERROR}; -- PrincOps.NullLink breaks ValidateFrame
PrincOpsUtils.SetReturnLink[LOOPHOLE[DummyReturnLink]];
Caller[FreezingPoint[]];
ERROR
END;

FreezingPoint: PROC RETURNS[ POINTER TO local PrincOps.Frame ] =
BEGIN
freezeQueue: PrincOps.QueueHandle = @PrincOps.PDA.fault[qFreeze].queue;
state: RECORD[a, b: UNSPECIFIED, v: PrincOps.StateVector];
Caller: PROC[PrincOps.FrameHandle] = LOOPHOLE[PrincOpsUtils.GetReturnFrame[]];
Caller[PrincOpsUtils.MyLocalFrame[]];
PrincOpsUtils.DisableInterrupts[];
DO
state.v _ STATE;
FreezeTrapFrame[@state.v];
PrincOpsUtils.EnableAndRequeue[@PrincOps.PDA.ready, freezeQueue, PrincOpsUtils.ReadPSB[]];
PrincOpsUtils.DisableInterrupts[];
ENDLOOP;
END;

FreezeTrapFrame: PROC[sv: POINTER TO PrincOps.StateVector] =
BEGIN
-- executed with interrupts disabled --
state: RECORD[a, b: UNSPECIFIED, v: PrincOps.StateVector];
Caller: PROC = LOOPHOLE[PrincOpsUtils.GetReturnFrame[]];
psbi: PrincOps.PsbIndex = PrincOpsUtils.PsbHandleToIndex[PrincOpsUtils.ReadPSB[]];
state.v _ sv^;
PrincOpsUtils.SetReturnLink[freezeesTable[psbi]];
freezeesTable[psbi] _ [frame[PrincOpsUtils.MyLocalFrame[]]];
Caller[];
state.v.dest.frame _ PrincOpsUtils.GetReturnFrame[];
state.v.source _ PrincOps.NullLink;
RETURN WITH state.v;
END;


swapInfo: DebuggerFormat.ExternalStateVector; -- nub-debugger communication area

CoreSwap: PROC [why: DebuggerFormat.SwapReason, sp: PrincOps.SVPointer] =
BEGIN
DP: DebuggerFormat.DebugParameter;

Decode: PROC RETURNS [proceed: BOOLEAN] = -- decode the SwapReason
BEGIN
f: PrincOps.GlobalFrameHandle;
lsv: PrincOps.StateVector;
SELECT swapInfo.reason FROM
proceed, resume => RETURN[TRUE];
call =>
BEGIN
lsv _ swapInfo.parameter.sv;
lsv.source _ [frame[PrincOpsUtils.MyLocalFrame[]]];
TRANSFER WITH lsv;
lsv _ STATE;
swapInfo.parameter.sv _ lsv;
why _ return
END;
start =>
BEGIN
f _ swapInfo.parameter.frame;
IF ~f.started THEN START LOOPHOLE[f, PROGRAM] ELSE RESTART f;
why _ return
END;
quit => ERROR Quit;
ENDCASE => RETURN[TRUE];
RETURN[FALSE]
END; --decode--


swapInfo.state _ sp;
DP.spare _ NIL;
swapInfo.parameter _ @DP;
DO
swapInfo.reason _ why;
PrincOpsUtils.DisableInterrupts[];
ToDebugger[@swapInfo];
PrincOpsUtils.EnableInterrupts[];
BEGIN
IF Decode[
! CAbort => IF swapInfo.level > 0 THEN {why _ return; CONTINUE};
Quit => GOTO abort] THEN EXIT
EXITS abort => ERROR CAbort
END
ENDLOOP
END;

level: INTEGER;

ToDebugger: PORT [POINTER TO DebuggerFormat.ExternalStateVector]; -- formerly WBPort
FromPilot: PORT RETURNS [POINTER TO DebuggerFormat.ExternalStateVector]; -- formerly CSPort

MemorySwap: PROC [pESV: POINTER TO DebuggerFormat.ExternalStateVector] =
BEGIN

PKeys: PROC RETURNS [LONG POINTER TO Keys.KeyBits] = INLINE
{RETURN[LOOPHOLE[KeyboardFace.keyboard]]};

SwapIt: PROC = INLINE
BEGIN
savewdc, saveptc: UNSPECIFIED;
xferTrapStatus: PrincOps.XferTrapStatus = PrincOpsUtils.ReadXTS[];
xferTrapHandler: UNSPECIFIED = PrincOps.SD[PrincOps.sXferTrap];
pESV.level _ level;
pESV.mds _ PrincOpsUtils.HighHalf[LONG[LOOPHOLE[1, POINTER]]];  -- ("1" since
pESV.psb _ PrincOpsUtils.PsbHandleToIndex[PrincOpsUtils.ReadPSB[]];
PrincOps.SD[PrincOps.sXferTrap] _ PrincOpsUtils.MyLocalFrame[];  -- in case we are restarted in trap mode
PrincOpsUtils.WriteXTS[off];
saveptc _ PrincOpsUtils.ReadPTC[];
savewdc _ PrincOpsUtils.ReadWDC[];
PrincOps.PDA.block[pESV.psb].context.frame _ PrincOpsUtils.MyLocalFrame[];
PrincOps.PDA.block[pESV.psb].link.vector _ FALSE;
DeviceCleanup.Perform[turnOff];
IF GermSwap.switches[h] THEN
BEGIN
AddToStack: PROC [BOOLEAN] = MACHINE CODE BEGIN END;
GetTOS: PROC RETURNS [BOOLEAN] = MACHINE CODE BEGIN PrincOps.zDUP; END;
RemoveFromStack: PROC RETURNS [BOOLEAN] = MACHINE CODE BEGIN END;
AddToStack[TRUE];
ProcessorFace.SetMP[MPCodes.hanging];
WHILE GetTOS[] DO ENDLOOP;
[] _ RemoveFromStack[];
END
ELSE IF NOT diskDebugger OR teledebug OR GermSwap.switches[r] THEN
BEGIN
ProcessorFace.SetMP[MPCodes.cantWorldSwap];
GermSwap.Teledebug[@locDebugger];
END
ELSE IF GermSwap.OutLoad[@locDebuggee, restore] = outLoaded THEN
BEGIN
IF pMicrocodeCopy ~= NIL THEN
DeviceCleanup.Perform[kill];
GermSwap.InLoad[
pMicrocodeCopy,
pGermCopy,
nGerm,
@locDebugger]
END;
PrincOpsUtils.WriteWDC[savewdc];
PrincOpsUtils.WritePTC[saveptc];
PrincOpsUtils.WritePSB[PrincOpsUtils.PsbIndexToHandle[pESV.psb]];
DeviceCleanup.Perform[turnOn];
level _ pESV.level;
PrincOpsUtils.WriteXTS[xferTrapStatus];
PrincOps.SD[PrincOps.sXferTrap] _ xferTrapHandler;
ProcessorFace.SetMP[MPCodes.emptyMP];
END;
DO
pESV _ FromPilot[];
PrincOpsUtils.SetReturnLink[LOOPHOLE[FromPilot, PrincOps.Port].dest.link^];
DO
SwapIt[];
SELECT pESV.reason FROM
kill => ProcessorFace.BootButton[];
showscreen =>
BEGIN
pulsesThen: LONG CARDINAL = ProcessorFace.GetClockPulses[];
prevSpare3: KeyboardFace.DownUp _ PKeys[][Spare3];
DO
IF (ProcessorFace.GetClockPulses[] - pulsesThen)
> LONG[20]*1000000*100/ProcessorFace.microsecondsPerHundredPulses THEN EXIT;
IF prevSpare3=down THEN prevSpare3 _ PKeys[][Spare3]
ELSE IF PKeys[][Spare3]=down THEN
{WHILE PKeys[][Spare3]=down DO --snoore-- ENDLOOP; EXIT}
ELSE NULL -- both up
ENDLOOP;
END;
ENDCASE => EXIT;
pESV.reason _ return;
ENDLOOP
ENDLOOP
END;


Initialize: PUBLIC PROC =
BEGIN
h: BootStartList.Base;
teledebug _ FALSE;
diskDebugger _ FALSE;
swatWatcherStarted _ FALSE;
swatWatcherEnabled _ FALSE;
level _ -1;
GermSwap.Initialize[GermSwap.mdsiGerm];
Process.InitializeMonitor[@LOCK]; -- because our main program is never executed
DeviceCleanup.InitializeDeviceCleanup[];
h _ GermSwap.GetPStartListHeader[];
pMicrocodeCopy _ pGermCopy _ NIL; -- until microcode swapping installed
NoteDiskDebugger[debugger: h.locDebugger, debuggee: h.locDebuggee];
NoteLoadstate[h[h.initLoadState].base + h[h[h.initLoadState].parent].vmPage];
swapInfo.versionident _ DebuggerFormat.VersionID;
swapInfo.vmRunTable _ NIL;
swapInfo.fill _ ALL[0];
LOOPHOLE[PrincOps.PDA.available, DebuggerFormat.SwapInfo].externalStateVector
_ @swapInfo;
InitBreakBlocks[];
PrincOps.SD[PrincOps.sSignalList] _ StubSignalHandler;
PrincOps.SD[PrincOps.sSignal] _ StubSignalHandler;
PrincOps.SD[PrincOps.sErrorList] _ StubSignalHandler;
PrincOps.SD[PrincOps.sError] _ StubSignalHandler;
PrincOps.SD[PrincOps.sReturnErrorList] _ StubSignalHandler;
PrincOps.SD[PrincOps.sReturnError] _ StubSignalHandler;
PrincOps.SD[PrincOps.sUnnamedError] _ StubSignalHandler;
PrincOps.SD[PrincOps.sBreak] _ WorryBreaker[];
PrincOps.SD[PrincOps.sAlternateBreak] _ Break;
PrincOps.SD[205B] _ freezer _ AllocFreezer[];
LOOPHOLE[@(PrincOps.SD[206B]), POINTER TO LONG POINTER TO DebuggerSwap.Frozen]^ _
LONG[@freezeesTable];
FOR p: PrincOps.PsbIndex IN PrincOps.PsbIndex
DO freezeesTable[p] _ PrincOps.NullLink ENDLOOP;
WorryCallDebugger _ DoWorryCallDebugger[];
LOOPHOLE[ToDebugger, PrincOps.Port].out _ @FromPilot;
LOOPHOLE[FromPilot, PrincOps.Port].out _ @ToDebugger;
LOOPHOLE[FromPilot, PrincOps.Port].in _ MemorySwap;
ToDebugger[NIL]; -- allocate frame for MemorySwap
END;

NoteDiskDebugger: PUBLIC PROC[debugger, debuggee: BootFile.Location] =
BEGIN
locDebuggee _ debuggee;
locDebugger _ debugger;
IF locDebuggee.diskFileID.firstLink ~= BootFile.nullLink THEN diskDebugger _ TRUE;
END;

NoteLoadstate: PUBLIC PROC[page: PrincOps.PageNumber] =
{ swapInfo.loadstatepage _ page };

NoteVMRunTable: PUBLIC PROC[table: LONG POINTER] =
{ swapInfo.vmRunTable _ table };


END.

���ö��Cedar Nucleus: interface with debugger
DebugNub.mesa
Andrew Birrell  July 26, 1983 4:52 pm
Last Edited by: Levin, June 20, 1983 4:53 pm

******** Global variables ********

******** Breakpoints ********
executed by (non-worry) BRK instruction
executed by worry-mode BRK instruction

******** Uncaught signals ********
The call stack below here is: Signaller, [Signaller,] offender
******** Interrupts (CTRL-SWAT) ********
Must not be invoked until KeyboardFace and Process have been initialized.

******** CallDebugger ********
The following dance is needed because fixed frame procedures that are not
called as trap handlers don't have source & destination links put on the
stack.  We insert an indirect link to force them to be put there.

******** Data structures for process freezing ********
The rest of this procedure is magic.  It is simultaneously on the stack of several processes.

******** Procedures that cause swap to debugger ********
Body of CoreSwap:
versionident, debuggee, lspages, fill, mapLog set by Initialize
level, loadstatepage. mds set by MemorySwap
0 collides with NIL.)
Save processor state not captured in PDA:
Manually save the state of the current process so that Copilot
will be able to examine it just as if we were waiting:
OutLoad onto swatee, then boot Debugger.
The next line should be in GermSwap.InLoad but blows up the compiler
never returns
Restore processor state not captured in PDA:
Restore process state not captured in PDA:
Set our return link so Display Stack will work:

******** Initialization ********
Remember:  this module has NOTRAP in its bootmesa description, so the main program is never executed.  Therefore, this procedure is responsible for any required initialisation of global variables (like the monitor lock!).  In addition, this procedure is called before the mesa runtime has been initialised, so beware of KFCB's or instructions that trap to software.
swapInfo.state set in caller of MemorySwap
(e.g. CoreSwap, WorryBreaker, WorryCallDebugger)
swapInfo.reason set in caller of MemorySwap
(e.g. CoreSwap, WorryBreaker, WorryCallDebugger)
swapInfo.level set in MemorySwap
swapInfo.parameter set by debugger and obeyed by CoreSwap
swapInfo.mds set in MemorySwap
connect ToDebugger to FromPilot
connect FromPilot to ToDebugger
ÊÍ��–
"Cedar" style˜�J™&J™
J™%J™,J˜�šÏk	˜	Jšœ	œ˜$Jšœœ˜JšœœI˜]Jšœ
œ
˜Jšœœ$˜7Jšœ	œFÏcœ
˜oJšœ
œ˜&Jšœœ˜Jšœœ#˜0Jšœ	œiœ`œ”˜ðJšœœ€˜“JšœœŒ˜™JšœœC˜VJšœ
œ˜—J˜�šœ
œž˜'JšœM˜TJšœ
˜Jšœ˜—J˜�š˜J˜�—J™�šœ"™"J˜�Jšœœœž˜4J˜�Jšœœž)˜=J˜�J˜J˜Jšœœœž)˜GJšœœœž$˜=Jšœœž%˜6J˜�Jšœœœ˜Jšœœœ˜Jšœœœ˜J˜�—J™�šœ™J˜�J˜�šÏnœœž˜(Jš˜Jšœ	œžœ˜.Jšœ	œ˜*Jšœ˜J˜�—šŸœœ˜
Jšœ'™'Jš˜šœœ˜Jšœ	œœœ˜?—Jšœ
œ˜Jšœ-˜-J˜#Jšœ˜Jšœœ˜CJšœœ	˜Jšœ˜J˜�—šŸœœœ˜3Jšœ&™&Jš˜Jš	œœœœœ˜NJ˜J˜Jšœ.˜.Jšœ-˜-J˜#Jšœ"˜"š˜Jšœœ˜CJšœ!˜!Jšœœ	˜Jšœ"˜"Jšœ
œ˜Jšœ-˜-J˜#J˜Jšœž˜,J˜Jšœ˜—Jšœ˜J˜�——J™�šœ"™"J˜�šÏbœœ˜&Jš˜J˜(J˜J˜J˜J˜J˜Jšœ>™>J˜#J˜Jšœ&˜&Jšœœ˜=Jšœ,œ˜8š˜˜Jš
œ
œœœœ˜JJšœœœ˜——Jšœ˜J˜�—šŸœœ˜-Jš˜J˜3JšŸœœœ ˜7J˜8J˜1Jšœœ˜&J˜(Jšœ˜—J˜�šŸœœž2˜LJš˜Jš	œœœœœ˜NJšœ
œ˜Jšœ(œ˜2Jšœ˜J˜�——J˜�šœ(™(J˜�Jšœœ˜Jšœœ˜Jšœ
	œ˜J˜�šŸœœœ˜Jš˜J˜)Jš	œœœœœ˜FJšœ	œ˜J˜(šœž˜Jšœœœ˜Jšœ˜šœœ˜3Jš˜šœœ˜2Jš˜Jšœ˜Jšœ˜šœ˜Jšœ5˜5—Jšœœœ˜4Jšœ˜—Jš˜—Jšœ˜Jšœ˜—Jšœ˜—J˜�šŸœœ˜Jš˜šŸœœœ˜Jš˜Jšœœœ˜Jšœœ˜Jšœœœ
œ˜2Jšœ˜—šœœœœ˜J˜Jšœœ˜!—Jšœ˜Jšœ˜—J˜�šŸ	œœ˜Jš˜J˜$Jšœ˜—J˜�Jšœœ˜J˜�š
Ÿœœœœœ
œ˜AJšœI™IJš˜Jšœœ˜šœ˜
J˜8Jšœ-˜-Jšœ%˜%Jšœ-˜-Jšœœ˜(J˜1Jšœœ˜&J˜"Jšœœ˜Jšœ˜—Jšœ˜Jšœ˜—J˜�šŸœœœœ	œ
œ˜?Jšœ!˜(J˜�——J™�šœ™J˜�šŸœœœœœ˜4Jš˜Jšœœœ˜;Jšœ
œ˜J˜J˜J˜-J˜ Jšœ˜J˜�—Jšœœ˜J˜�Jš
Ÿœœœœœ˜,J˜�šŸœœœœœœ˜7Jšœœ
˜Jš	œœœœœ˜EJ˜J˜JšœI™IJšœH™HJšœA™AJšœH˜PJ˜$Jšœ-˜-J˜#Jšœ"˜"šœž˜Jšœœ˜CJšœ!˜!Jšœœ	˜Jšœ"˜"Jšœ
œ˜J˜/Jšœ*˜*J˜#J˜J˜J˜Jš˜—Jšœ˜J˜�——J™�šœ6™6J˜�Jšœœ˜*J˜�Jšœ	œœœ˜0J˜�Jšœ!˜!J˜�š
Ÿœœœœœ˜?Jš˜JšŸœœœ!˜NJšŸœœœž)˜JJšœœ˜7Jšœ˜Jš˜Jšœ˜—J˜�š
Ÿ
œœœœœ˜@Jš˜Jšœ.œ˜GJšœœœ˜:JšŸœœœ!˜NJšœ%˜%Jšœ]™]Jšœ"˜"š˜Jšœ
œ˜Jšœ˜Jšœ)œ.˜ZJšœ"˜"—Jšœ˜Jšœ˜—J˜�šŸœœœœ˜<Jš˜Jšž'˜'Jšœœœ˜:JšŸœœœ!˜8JšœR˜RJšœ˜Jšœ1˜1Jšœ<˜<Jšœ	˜	Jšœ4˜4Jšœ#˜#Jšœœ	˜Jšœ˜J˜�——J™�šœ8™8J˜�Jšœ.ž"˜PJ˜�šŸœœ;˜IJš˜Jšœ ˜"J˜�š	Ÿœœœœž˜BJš˜J˜J˜šœ˜Jšœœœ˜ ˜Jš˜Jšœ˜Jšœ3˜3Jšœœ˜Jšœœ˜Jšœ˜J˜Jšœ˜—˜Jš˜Jšœ˜Jšœœœœœœœ˜=J˜Jšœ˜—Jšœœ˜Jšœœœ˜—Jšœœ˜
Jšœž
˜J˜�—Jšœ™J˜�J˜Jšœ	œ˜Jšœœ˜Jšœ?™?Jšœ+™+š˜J˜J˜"J˜J˜!Jš˜šœ˜
šœœœœ˜@Jšœœœ˜——Jšœ
œ˜Jš˜Jš˜—Jšœ˜J˜�—Jšœœ˜J˜�Jšœœœœ&ž˜TJš
œœœœœ&ž˜[J˜�šŸ
œœœœ&˜HJš˜J˜�š
Ÿœœœœœœ˜;Jšœœœ˜*J˜�—šŸœœ˜Jš˜Jšœœ˜JšœB˜BJšœœœ˜?J˜šœ"œœœž
˜MJšœ™—JšœC˜CJšœ	œ6ž(˜iJšœ˜Jšœ)™)Jšœ"˜"Jšœ"˜"Jšœ>™>Jšœ6™6Jšœ	œ>˜JJšœ	œœ˜1Jšœ˜šœ˜Jš˜JšŸ
œœœœœœœ˜4JšŸœœœœœœœœ˜GJšŸœœœœœœœœ˜AJšœœ˜J˜%Jšœ
œœ˜J˜Jš˜—šœœœœœ˜BJš˜J˜+J˜!Jš˜—Jšœ(™(šœœ5˜@Jš˜JšœD™Dšœœ˜Jšœ˜—šœ˜Jšœ˜Jšœ
˜
Jšœ˜Jšœ
˜
Jšœ
™
—Jšœ˜—Jšœ,™,Jšœ ˜ Jšœ ˜ Jšœ*™*JšœA˜AJšœ˜J˜Jšœ'˜'Jšœ	œ'˜2Jšœ%˜%Jšœ˜—š˜J˜Jšœ/™/Jšœœ'˜Kš˜J˜	šœ
˜J˜#˜
Jš˜Jšœœœ"˜;J˜2š˜šœ.˜0Jšœœ<œœ˜L—Jšœœ˜4šœœ˜!Jšœœœž
œœœ˜8—Jšœœž
˜Jšœ˜—Jšœ˜—Jšœœ˜—J˜Jš˜—Jš˜Jšœ˜J˜�———J™�šœ ™ J˜�šŸ
œœœ˜Jš˜Jš œå™íJšœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜J˜J˜'Jšœœž-˜OJ˜(J˜#Jšœœž%˜GJšœC˜CJšœM˜MJšœ*™*Jšœ0™0Jšœ+™+Jšœ0™0Jšœ ™ Jšœ9™9J˜1Jšœœ˜Jšœ™Jšœœ˜šœ
œ8˜MJ˜—J˜Jšœ	œ+˜6Jšœ	œ'˜2Jšœ	œ*˜5Jšœ	œ&˜1Jšœ	œ0˜;Jšœ	œ,˜7Jšœ	œ-˜8Jšœ	œ#˜.Jšœ	œ#˜.Jšœ	œ"˜-Jšœœ	œœœœœœ˜gJšœœ˜-Jšœ&œ˜0J˜*šœ-˜5Jšœ™—šœ-˜5Jšœ™—Jšœ+˜3Jšœœž ˜1Jšœ˜—J˜�šŸœœœ)˜FJš˜Jšœ˜Jšœ˜Jšœ7œœ˜RJšœ˜—J˜�šÐbn
œœœ˜7Jšœ"˜"—J˜�š
¡œœœœœ˜2Jšœ
œ˜ —J˜�—J˜�Jšœ˜J˜�—�…—����9Ò��U•��