DIRECTORY Basics USING [BITAND, BITOR, BITSHIFT, bitsPerWord, LongDiv, LongMult], ColorDisplayDefs USING [ChannelsVisible, ChannelValue, ColorDisplayType, ColorMode, ColorTriple, ColorValue], ColorDisplayDefsExtras USING [ColorTripleArray, ColorValueArray], ColorDisplayDorado USING [AEntry, AIndex, ATable, Base, base0, BCDatum, BCTable, bMapRegister, ChannelControlBlock, ClockControl, cMapRegister, ColorControlBlock, ColorCSB, csb, Flags, HorizontalControl, MixerDatum, mixerRegister, MonitorControlBlock, pixelsPerLineOffset, RNIL, ScanControl, VerticalControl], ColorDisplayFace USING [nullMode], ColorDisplayFaceExtras USING [], DeviceCleanup USING [Await, Item, Reason], DoradoInputOutput USING [DMuxAddr, InputNoPE, IOAddress, MufManResult, Output, RWMufMan], PrincOpsUtils USING [HighHalf, LowHalf], ProcessorFace USING [GetClockPulses, microsecondsPerHundredPulses]; ColorDisplayHeadDorado: PROGRAM IMPORTS Basics, DeviceCleanup, DoradoInputOutput, PrincOpsUtils, ProcessorFace EXPORTS ColorDisplayFace, ColorDisplayFaceExtras ~ BEGIN OPEN ColorDisplayFace, ColorDisplayDefs, ColorDisplayDefsExtras, ColorDisplayDorado; ErrorHalt: PROC ~ { ERROR }; displayType: PUBLIC ColorDisplayType _ none; -- display type, "none" if display not available width: PUBLIC NAT _ 0; -- raster width in pixels height: PUBLIC NAT _ 0; -- raster height in pixels pixelsPerInch: PUBLIC NAT _ 0; -- approximate pixel size globalStateSize: PUBLIC NAT _ SIZE[MonitorControlBlock]+2*SIZE[ChannelControlBlock]+SIZE[ColorControlBlock]; oldRev: BOOL _ FALSE; -- TRUE if color board has an old revision level (less than Cj) vControl: VerticalControl _ [0, 0, 0, 0]; hControl: HorizontalControl _ [0, 0, 0, 0]; clkControl: ClockControl _ [mul: 0, div: 0]; clkControlDouble: ClockControl _ [mul: 0, div: 0]; marginOffset: CARDINAL _ 0; mcb: LONG POINTER TO MonitorControlBlock _ NIL; channelA: LONG POINTER TO ChannelControlBlock _ NIL; channelB: LONG POINTER TO ChannelControlBlock _ NIL; color: LONG POINTER TO ColorControlBlock _ NIL; currentMap: ColorMap _ NIL; turnOnFlags: Flags _ []; showA, showB: BOOL _ FALSE; state: {uninitialized, disconnected, connected, displayed} _ uninitialized; SetDisplayType: PUBLIC SAFE PROC [type: ColorDisplayType] RETURNS [ok: BOOL] ~ CHECKED { SELECT type FROM standard => { width _ 640; -- must be a multiple of 32 height _ 480; -- must be a multiple of 2 pixelsPerInch _ 42; -- *** approximate *** vControl _ [VBtoVS: 3B, VStoVS: 3B, VStoVB: 20B, VisibleLines: 240]; hControl _ [HRamMaxAddr: 379, HBLeadLength: 6, HSTrailAddr: 28, HBTrailLength: 25]; clkControl _ [mul: 130B, div: 14B]; clkControlDouble _ [mul: 130B, div: 16B]; marginOffset _ 65B; }; highResolution => { width _ 1024; -- must be a multiple of 32 height _ 768; -- must be a multiple of 2 pixelsPerInch _ 72; -- *** approximate *** vControl _ [VBtoVS: 0, VStoVS: 3, VStoVB: 18, VisibleLines: 384]; hControl _ [HRamMaxAddr: 601, HBLeadLength: 3, HSTrailAddr: 50, HBTrailLength: 35]; clkControl _ [mul: 54, div: 14]; marginOffset _ 111; }; ENDCASE => RETURN[FALSE]; displayType _ type; RETURN[TRUE]; }; RP: PROC[p: LONG POINTER] RETURNS[Base RELATIVE POINTER] ~ INLINE { RETURN[LOOPHOLE[PrincOpsUtils.LowHalf[p]]] -- assumes high half is zero }; Initialize: PUBLIC PROC [globalState: LONG POINTER] = { allocated: NAT _ 0; -- words allocated from globalState block Allocate: PROC[size: NAT] RETURNS[LONG POINTER] ~ INLINE { p: LONG POINTER ~ globalState+allocated; allocated _ allocated+size; RETURN[p]; }; IF state#uninitialized THEN ErrorHalt[]; IF NOT SetDisplayType[displayType] THEN ErrorHalt[]; IF PrincOpsUtils.HighHalf[globalState]#0 THEN ErrorHalt[]; mcb _ Allocate[SIZE[MonitorControlBlock]]; channelA _ Allocate[SIZE[ChannelControlBlock]]; channelB _ Allocate[SIZE[ChannelControlBlock]]; color _ Allocate[SIZE[ColorControlBlock]]; IF allocated>globalStateSize THEN ErrorHalt[]; mcb^ _ [flags: [], channelA: RNIL, channelB: RNIL, color: RP[color]]; channelA^ _ channelB^ _ nullChannelControlBlock; color^ _ [tableA: NIL, tableB: NIL, tableC: NIL, vc: vControl, hc: hControl, clk: clkControl]; state _ disconnected; }; HasMode: PUBLIC SAFE PROC[mode: ColorMode] RETURNS[BOOL] ~ CHECKED { a: NAT ~ mode.bitsPerPixelChannelA; b: NAT ~ mode.bitsPerPixelChannelB; IF displayType=none THEN RETURN[FALSE]; -- no color display IF mode.full THEN RETURN[displayType=standard]; IF a=0 AND b=0 THEN RETURN[FALSE]; SELECT a FROM 0, 1, 2, 4, 8 => NULL ENDCASE => RETURN[FALSE]; SELECT b FROM 0, 1, 2, 4 => NULL ENDCASE => RETURN[FALSE]; IF (a+b)>10 THEN RETURN[FALSE]; IF oldRev AND a#0 AND b#0 THEN RETURN[FALSE]; RETURN[TRUE]; }; NextMode: PUBLIC SAFE PROC [mode: ColorMode] RETURNS [ColorMode] ~ CHECKED { Next: SAFE PROC [mode: ColorMode] RETURNS [ColorMode] ~ CHECKED { a: NAT ~ mode.bitsPerPixelChannelA; b: NAT ~ mode.bitsPerPixelChannelB; IF mode.full THEN RETURN[nullMode]; IF b<4 THEN RETURN[[FALSE, a, b*2]]; IF a<8 THEN RETURN[[FALSE, a*2, 0]]; RETURN[[TRUE, 0, 0]]; }; IF NOT(mode=nullMode OR HasMode[mode]) THEN RETURN[nullMode]; -- illegal mode FOR next: ColorMode _ Next[mode], Next[next] UNTIL next=nullMode DO IF HasMode[next] THEN RETURN[next]; ENDLOOP; RETURN[nullMode]; }; nullScanControl: ScanControl ~ [mode24: FALSE, aChannelOnly: FALSE, bBypass: FALSE, pixelMode: VAL[0], resolution: VAL[0], bitsPerPixel: 0]; nullChannelControlBlock: ChannelControlBlock ~ [link: RNIL, wordsPerLine: 0, address: NIL, linesPerField: 0, pixelsPerLine: 0, leftMargin: 0, scanControl: nullScanControl]; bitsPerWord: NAT ~ Basics.bitsPerWord; Connect: PUBLIC PROC[mode: ColorMode, baseA, baseB: LONG POINTER, map: ColorMap] ~ { vc: VerticalControl _ vControl; hc: HorizontalControl _ hControl; clk: ClockControl _ clkControl; template: ChannelControlBlock _ nullChannelControlBlock; template.linesPerField _ height/2; template.pixelsPerLine _ width+pixelsPerLineOffset; template.leftMargin _ marginOffset; template.scanControl.resolution _ full; IF mode.full THEN { template.scanControl.mode24 _ TRUE; template.scanControl.aChannelOnly _ FALSE; template.scanControl.bBypass _ TRUE; template.scanControl.pixelMode _ a8b2; clk _ clkControlDouble; hc.HRamMaxAddr _ 2*hc.HRamMaxAddr; hc.HBLeadLength _ 2*hc.HBLeadLength; hc.HSTrailAddr _ 2*hc.HSTrailAddr; hc.HBTrailLength _ 2*hc.HBTrailLength; template.leftMargin _ 2*marginOffset + 40B--HWindow-- + 40B--marginCounter--; template.pixelsPerLine _ 2*width+pixelsPerLineOffset; channelA^ _ template; channelA.address _ baseA; channelA.wordsPerLine _ (width*16)/bitsPerWord; channelA.scanControl.bitsPerPixel _ 8; channelB^ _ template; channelB.address _ baseB; channelB.wordsPerLine _ (width*8)/bitsPerWord; channelB.scanControl.resolution _ half; channelB.scanControl.bitsPerPixel _ 8; color.tableA _ LOOPHOLE[@map.tableA]; color.tableB _ LOOPHOLE[@map.tableB]; color.tableC _ LOOPHOLE[@map.tableC]; turnOnFlags _ [vc: TRUE, hc: TRUE, clk: TRUE, a: TRUE, b: TRUE, c: TRUE]; } ELSE { bitsPerPixelA: NAT ~ mode.bitsPerPixelChannelA; bitsPerPixelB: NAT ~ mode.bitsPerPixelChannelB; template.scanControl.mode24 _ FALSE; template.scanControl.aChannelOnly _ (bitsPerPixelB=0); template.scanControl.bBypass _ FALSE; template.scanControl.pixelMode _ (IF bitsPerPixelB>2 THEN a6b4 ELSE a8b2); channelA^ _ channelB^ _ template; IF bitsPerPixelA=0 THEN channelA.address _ NIL ELSE { channelA.address _ baseA; channelA.wordsPerLine _ (width*bitsPerPixelA)/bitsPerWord; channelA.scanControl.bitsPerPixel _ bitsPerPixelA; }; IF bitsPerPixelB=0 THEN channelB.address _ NIL ELSE { channelB.address _ baseB; channelB.wordsPerLine _ (width*bitsPerPixelB)/bitsPerWord; channelB.scanControl.bitsPerPixel _ bitsPerPixelB; }; color.tableA _ LOOPHOLE[@map.tableA]; color.tableB _ NIL; color.tableC _ NIL; turnOnFlags _ [vc: TRUE, hc: TRUE, clk: TRUE, a: TRUE]; }; color.vc _ vc; color.hc _ hc; color.clk _ clk; currentMap _ map; state _ connected; }; setBlack: BOOL _ TRUE; Disconnect: PUBLIC SAFE PROC = TRUSTED { IF state=displayed THEN TurnOff[]; IF state#connected THEN ErrorHalt[]; IF setBlack THEN { MixerOutput: PROC [datum: MixerDatum] ~ INLINE {DoradoInputOutput.Output[datum: LOOPHOLE[datum], register: mixerRegister]}; BMapOutput: PROC [datum: BCDatum] ~ INLINE {DoradoInputOutput.Output[datum: LOOPHOLE[datum], register: bMapRegister]}; CMapOutput: PROC [datum: BCDatum] ~ INLINE {DoradoInputOutput.Output[datum: LOOPHOLE[datum], register: cMapRegister]}; MixerOutput[[keep: T, body: null[]]]; MixerOutput[[keep: T, load: T, body: addr[addr: 0, select: lo]]]; MixerOutput[[keep: T, write: T, body: data[data: 0]]]; MixerOutput[[keep: T, load: T, body: addr[addr: 0, select: hi]]]; MixerOutput[[keep: T, write: T, body: data[data: 0]]]; MixerOutput[[keep: F, body: null[]]]; BMapOutput[[keep: T, body: null[]]]; BMapOutput[[keep: T, load: T, body: addr[addr: 0]]]; BMapOutput[[keep: T, write: T, body: data[data: 0]]]; BMapOutput[[keep: F, body: null[]]]; CMapOutput[[keep: T, body: null[]]]; CMapOutput[[keep: T, load: T, body: addr[addr: 0]]]; CMapOutput[[keep: T, write: T, body: data[data: 0]]]; CMapOutput[[keep: F, body: null[]]]; }; color.tableA _ NIL; color.tableB _ color.tableC _ NIL; channelA.address _ channelB.address _ NIL; currentMap _ NIL; turnOnFlags _ []; state _ disconnected; }; TurnOn: PUBLIC PROC = { IF state#connected THEN RETURN; mcb.flags _ turnOnFlags; mcb.channelA _ (IF showA AND channelA.address#NIL THEN RP[channelA] ELSE RNIL); mcb.channelB _ (IF showB AND channelB.address#NIL THEN RP[channelB] ELSE RNIL); base0[csb].mcb _ RP[mcb]; state _ displayed; }; TurnOff: PUBLIC SAFE PROC = TRUSTED { IF state#displayed THEN RETURN; base0[csb].mcb _ RNIL; Wait[]; -- be sure the microcode is no longer touching bitmaps or color tables state _ connected; }; SetVisibility: PUBLIC SAFE PROC [visibility: ChannelsVisible] ~ CHECKED { SELECT visibility FROM none => { showA _ showB _ FALSE }; aOnly => { showA _ TRUE; showB _ FALSE }; bOnly => { showA _ FALSE; showB _ TRUE }; all => { showA _ showB _ TRUE }; ENDCASE; IF state=displayed THEN TRUSTED { mcb.channelA _ (IF showA AND channelA.address#NIL THEN RP[channelA] ELSE RNIL); mcb.channelB _ (IF showB AND channelB.address#NIL THEN RP[channelB] ELSE RNIL); }; }; ColorMap: TYPE ~ LONG POINTER TO ColorMapRep; ColorMapRep: PUBLIC TYPE ~ RECORD[ shiftA, shiftB: INTEGER _ 0, maskA, maskB: WORD _ 0, unused: ARRAY [4..256) OF WORD _ ALL[0], tableA: ATable _ ALL[[redH: 0, redL: 0, blue: 0, green: 0]], tableB: BCTable _ ALL[[value: 0]], tableC: BCTable _ ALL[[value: 0]] ]; wordsForColorMap: PUBLIC NAT _ SIZE[ColorMapRep]; InitializeColorMap: PUBLIC PROC [mode: ColorMode, pointer: LONG POINTER] RETURNS [ColorMap] ~ { map: ColorMap ~ LOOPHOLE[pointer]; map^ _ []; IF NOT mode.full THEN { IF mode.bitsPerPixelChannelB>2 THEN { map.shiftA _ 4+(6-mode.bitsPerPixelChannelA); map.shiftB _ 4-mode.bitsPerPixelChannelB; } ELSE { map.shiftA _ 2+(8-mode.bitsPerPixelChannelA); map.shiftB _ 2-mode.bitsPerPixelChannelB; }; map.maskA _ Basics.BITSHIFT[1, mode.bitsPerPixelChannelA]-1; map.maskB _ Basics.BITSHIFT[1, mode.bitsPerPixelChannelB]-1; }; RETURN[map]; }; SetColor: PUBLIC PROC[map: ColorMap, pixelA, pixelB: ChannelValue, r, g, b: ColorValue] ~ { index: AIndex ~ Basics.BITOR[ Basics.BITSHIFT[Basics.BITAND[pixelA, map.maskA], map.shiftA], Basics.BITSHIFT[Basics.BITAND[pixelB, map.maskB], map.shiftB] ]; entry: AEntry ~ [redH: r/16, redL: r MOD 16, green: g, blue: b]; map.tableA[index] _ entry; IF map=currentMap AND state=displayed THEN mcb.flags.a _ TRUE; }; SetColorArray: PUBLIC PROC[map: ColorMap, pixelB: ChannelValue, array: LONG POINTER TO ColorTripleArray] ~ { FOR pixelA: ChannelValue IN ChannelValue DO t: ColorTriple ~ array[pixelA]; index: AIndex ~ Basics.BITOR[ Basics.BITSHIFT[Basics.BITAND[pixelA, map.maskA], map.shiftA], Basics.BITSHIFT[Basics.BITAND[pixelB, map.maskB], map.shiftB] ]; entry: AEntry ~ [redH: t.red/16, redL: t.red MOD 16, green: t.green, blue: t.blue]; map.tableA[index] _ entry; ENDLOOP; IF map=currentMap AND state=displayed THEN mcb.flags.a _ TRUE; }; GetColor: PUBLIC SAFE PROC[map: ColorMap, pixelA, pixelB: ChannelValue] RETURNS [r, g, b: ColorValue] ~ TRUSTED { index: AIndex ~ Basics.BITOR[ Basics.BITSHIFT[Basics.BITAND[pixelA, map.maskA], map.shiftA], Basics.BITSHIFT[Basics.BITAND[pixelB, map.maskB], map.shiftB] ]; entry: AEntry ~ map.tableA[index]; RETURN[r: entry.redH*16+entry.redL, g: entry.green, b: entry.blue]; }; SetR: PUBLIC PROC[map: ColorMap, in: ChannelValue, out: ColorValue] ~ { index: AIndex ~ Basics.BITSHIFT[in, 2]; entry: AEntry ~ [redH: out/16, redL: out MOD 16, green: 0, blue: 0]; map.tableA[index] _ entry; IF map=currentMap AND state=displayed THEN mcb.flags.a _ TRUE; }; SetRArray: PUBLIC PROC[map: ColorMap, array: LONG POINTER TO ColorValueArray] ~ { FOR in: ChannelValue IN ChannelValue DO out: ColorValue ~ array[in]; index: AIndex ~ Basics.BITSHIFT[in, 2]; entry: AEntry ~ [redH: out/16, redL: out MOD 16, green: 0, blue: 0]; map.tableA[index] _ entry; ENDLOOP; IF map=currentMap AND state=displayed THEN mcb.flags.a _ TRUE; }; SetG: PUBLIC PROC[map: ColorMap, in: ChannelValue, out: ColorValue] ~ { map.tableC[in] _ [value: out]; IF map=currentMap AND state=displayed THEN mcb.flags.c _ TRUE; }; SetGArray: PUBLIC PROC[map: ColorMap, array: LONG POINTER TO ColorValueArray] ~ { FOR in: ChannelValue IN ChannelValue DO out: ColorValue ~ array[in]; map.tableC[in] _ [value: out]; ENDLOOP; IF map=currentMap AND state=displayed THEN mcb.flags.c _ TRUE; }; SetB: PUBLIC PROC[map: ColorMap, in: ChannelValue, out: ColorValue] ~ { map.tableB[in] _ [value: out]; IF map=currentMap AND state=displayed THEN mcb.flags.b _ TRUE; }; SetBArray: PUBLIC PROC[map: ColorMap, array: LONG POINTER TO ColorValueArray] ~ { FOR in: ChannelValue IN ChannelValue DO out: ColorValue ~ array[in]; map.tableB[in] _ [value: out]; ENDLOOP; IF map=currentMap AND state=displayed THEN mcb.flags.b _ TRUE; }; GetR: PUBLIC SAFE PROC[map: ColorMap, in: ChannelValue] RETURNS [out: ColorValue] ~ TRUSTED { index: AIndex ~ Basics.BITSHIFT[in, 2]; entry: AEntry ~ map.tableA[index]; RETURN[entry.redH*16+entry.redL]; }; GetG: PUBLIC SAFE PROC[map: ColorMap, in: ChannelValue] RETURNS [out: ColorValue] ~ TRUSTED { RETURN[map.tableC[in].value]; }; GetB: PUBLIC SAFE PROC[map: ColorMap, in: ChannelValue] RETURNS [out: ColorValue] ~ TRUSTED { RETURN[map.tableB[in].value]; }; hundredPulsesPerSecond: CARDINAL ~ Basics.LongDiv[ 1000000, -- microsecondsPerSecond ProcessorFace.microsecondsPerHundredPulses -- (assumed >15) ]; pulsesPerField: CARDINAL ~ Basics.LongDiv[ Basics.LongMult[hundredPulsesPerSecond, 100], -- pulsesPerSecond (assumed <3932160) 60 -- fieldsPerSecond (approximate) ]; waitPulses: LONG CARDINAL ~ Basics.LongMult[pulsesPerField, 3]; -- 3 fields, just to be sure Wait: PROC ~ INLINE { -- inline, because device cleanup must not do procedure call startPulses: LONG CARDINAL ~ ProcessorFace.GetClockPulses[]; WHILE (ProcessorFace.GetClockPulses[]-startPulses) { csbState _ base0[csb]; base0[csb].mcb _ RNIL; Wait[]; }; turnOn => { IF state=displayed THEN mcb.flags _ turnOnFlags; base0[csb] _ csbState; }; ENDCASE; ENDLOOP; }; colorBoardAddr: DoradoInputOutput.IOAddress ~ 360B; colorDeviceAddr: DoradoInputOutput.IOAddress ~ 361B; colorRevAddr: DoradoInputOutput.DMuxAddr ~ 3107B; colorBoardData: WORD _ 0; colorDeviceData: MACHINE DEPENDENT RECORD[type: [0..17B], junk: [0..7777B]] _ [0, 0]; colorRevData: DoradoInputOutput.MufManResult _ [0, 0]; base0[csb] _ [mcb: RNIL]; colorBoardData _ DoradoInputOutput.InputNoPE[colorBoardAddr]; IF colorBoardData#0 THEN { -- Color display board is installed colorDeviceData _ LOOPHOLE[DoradoInputOutput.InputNoPE[colorDeviceAddr]]; SELECT colorDeviceData.type FROM 17B => displayType _ standard; 16B => displayType _ highResolution; ENDCASE; -- unknown display type colorRevData _ DoradoInputOutput.RWMufMan[[useDMD: FALSE, dMuxAddr: colorRevAddr]]; oldRev _ (colorRevData.dMuxData=1); }; END. JColorDisplayHeadDorado.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) June 17, 1985 4:38:05 pm PDT Doug Wyatt, June 9, 1986 3:13:40 pm PDT Public interface variables (valid as soon as the head has been started) Internal globals. Not enough bandwidth to handle 24 bits per pixel at high resolution. Old revision boards can't run both channels at the same time. channelA fetches two pixel values per screen pixel channelB runs at half resolution: 2 pixel clocks for each pixel from the frame buffer double the pixel clock rate horizontal control is measured in pixel clock periods adjust leftMargin to compensate for the faster pixel clock Initialization Since the runtime support may be in a delicate state when the heads are started, this code avoids software-implemented operations like long integer multiply or divide. Start The following determines whether an old rev DispY board is installed. Margin offsets for various monitors... AltoTerminal: 107B, Ramtek525: 66B, Ramtek1000: 0, ConracRQB525: 66B, ConracRQB875: 107B, ConracRQB1225: 0, Κλ˜codešœ™Kšœ Οmœ7™BK™0K™'—K˜šΟk ˜ Kš œžœžœžœžœ"˜GKšœžœW˜mKšœžœ%˜AKšœžœωžœ ˜΅Kšœžœ ˜"Kšœžœ˜ Kšœžœ˜*KšœžœB˜YKšœžœ˜(Kšœžœ0˜C—K˜KšΠblœž˜KšžœG˜NKšžœ)˜0KšœžœžœP˜\K˜KšΟn œžœžœ˜K˜KšœG™GK˜Kšœ žœΟc0˜]Kšœžœžœ‘˜0Kšœžœžœ‘˜2Kšœžœžœ‘˜8K˜Kš œžœžœžœžœžœ˜mK˜Kšœ™K˜Kšœžœžœ‘Πck‘8˜UKšœ)˜)Kšœ+˜+Kšœ,˜,Kšœ2˜2Kšœžœ˜K˜Kš œžœžœžœžœ˜/Kš œ žœžœžœžœ˜4Kš œ žœžœžœžœ˜4Kš œžœžœžœžœ˜/K˜Kšœžœ˜Kšœ˜Kšœžœžœ˜K˜K˜KK˜š œžœžœžœžœžœžœ˜Xšžœž˜šœ ˜ Kšœ ‘˜(Kšœ‘˜(Kšœ‘˜*K˜DK˜SKšœ#˜#Kšœ)˜)K˜K˜—šœ˜Kšœ‘˜)Kšœ‘˜(Kšœ‘˜*K˜AK˜SKšœ ˜ Kšœ˜K˜—Kšžœžœžœ˜—Kšœ˜Kšžœžœ˜ J˜J˜—šΠbkœžœžœžœžœžœžœžœ˜CJšžœžœ‘˜GJšœ˜J˜—š   œžœžœžœžœ˜7Kšœ žœ‘)˜=š œžœžœžœžœžœžœ˜:Kšœžœžœ˜(Kšœžœ˜&Kšœ˜—Kšžœžœ ˜(Kšžœžœžœ ˜4Kšžœ'žœ ˜:Kšœžœ˜*Kšœžœ˜/Kšœžœ˜/Kšœžœ˜*Kšžœžœ ˜.Kšœžœ žœ žœ ˜EKšœ0˜0Kšœžœ žœ žœ/˜^Kšœ˜K˜K˜—š œžœžœžœžœžœžœ˜DKšœžœ˜#Kšœžœ˜#Kš žœžœžœžœ‘˜;šžœ žœžœ˜/K™D—Kš žœžœžœžœžœ˜"Kš žœžœžœžœžœžœ˜=Kš žœžœžœžœžœžœ˜:Kšžœ žœžœžœ˜š žœžœžœžœžœžœ˜-Kšœ=™=—Kšžœžœ˜ K˜K˜—š  œžœžœžœžœžœ˜Lš  œžœžœžœžœ˜AKšœžœ˜#Kšœžœ˜#Kšžœ žœžœ ˜#Kšžœžœžœžœ ˜$Kšžœžœžœžœ ˜$Kšžœžœ ˜K˜—Kš žœžœžœžœžœ ‘˜Mšžœ*žœž˜CKšžœžœžœ˜#Kšžœ˜—Kšžœ ˜K˜K™—K˜Kš œ(žœžœ žœžœžœ˜K˜Kšœ6žœžœS˜¬K˜Kšœ žœ˜&K˜š  œžœžœ žœžœ˜TKšœ˜Kšœ!˜!Kšœ˜Kšœ8˜8Kšœ"˜"Kšœ3˜3Kšœ#˜#Kšœ'˜'šžœ žœ˜Kšœ2™2KšœU™UKšœžœ˜#Kšœ$žœ˜*Kšœžœ˜$Kšœ&˜&šœ˜Kšœ™—K˜"K˜$K˜"˜&Kšœ5™5—šœ*‘ œ‘œ˜MKšœ:™:—Kšœ5˜5Kšœ˜Kšœ˜Kšœ/˜/K˜&Kšœ˜Kšœ˜Kšœ.˜.Kšœ'˜'K˜&Kšœžœ˜%Kšœžœ˜%Kšœžœ˜%Kš œžœžœžœžœžœžœ˜IK˜—šžœ˜Kšœžœ˜/Kšœžœ˜/Kšœžœ˜$Kšœ6˜6Kšœžœ˜%Kšœ"žœžœžœ˜JKšœ!˜!Kšžœžœž˜.šžœ˜Kšœ˜Kšœ:˜:K˜2K˜—Kšžœžœž˜.šžœ˜Kšœ˜Kšœ:˜:K˜2K˜—Kšœžœ˜%Kšœžœ˜Kšœžœ˜Kš œžœžœžœžœ˜7K˜—K˜K˜K˜K˜Kšœ˜K˜K˜—K˜Kšœ žœžœ˜K˜š   œžœžœžœžœ˜(Kšžœžœ ˜"Kšžœžœ ˜$K˜šžœ žœ˜š  œžœ˜%Kšœžœ"žœ#˜U—š  œžœ˜!Kšœžœ"žœ"˜T—š  œžœ˜!Kšœžœ"žœ"˜T—K˜Kšœ%˜%KšœA˜AKšœ6˜6KšœA˜AKšœ6˜6Kšœ%˜%K˜Kšœ$˜$Kšœ4˜4Kšœ5˜5Kšœ$˜$K˜Kšœ$˜$Kšœ4˜4Kšœ5˜5Kšœ$˜$K˜—K˜Kšœžœ žœ˜6Kšœ&žœ˜*Kšœ žœ˜K˜K˜K˜K˜—š œžœžœ˜Kšžœžœžœ˜Kšœ˜Kšœžœžœžœžœžœ žœžœ˜OKšœžœžœžœžœžœ žœžœ˜OKšœžœ˜Kšœ˜K˜K˜—š  œžœžœžœžœ˜%Kšžœžœžœ˜Kšœžœ˜Kšœ‘F˜NKšœ˜K˜K˜—š   œžœžœžœ!žœ˜Išžœ ž˜Kšœžœ˜"Kšœžœ žœ˜)Kšœžœ žœ˜)Kšœžœ˜ Kšžœ˜—šžœžœžœ˜!Kšœžœžœžœžœžœ žœžœ˜OKšœžœžœžœžœžœ žœžœ˜OKšœ˜—K˜K˜—K˜Kš œ žœžœžœžœ ˜-šœ žœžœžœ˜"Kšœžœ˜Kšœžœ˜Kš œžœ žœžœžœ˜(Kšœžœ(˜Kšœžœžœ ˜=K˜—Kšœ%žœ˜@Kšœ˜Kšžœžœžœžœ˜>K˜K˜—š   œžœžœ-žœžœžœ˜lšžœžœž˜+K˜šœžœ˜Kšœžœžœ!˜>Kšœžœžœ ˜=K˜—Kšœ-žœ#˜SKšœ˜Kšžœ˜—Kšžœžœžœžœ˜>K˜K˜—š  œžœžœžœ/žœžœ˜ršœžœ˜Kšœžœžœ!˜>Kšœžœžœ ˜=K˜—Kšœ"˜"Kšžœ=˜CK˜K˜—K˜š œžœžœ6˜GKšœžœ˜'Kšœ)žœ˜DKšœ˜Kšžœžœžœžœ˜>K˜—š   œžœžœžœžœžœ˜Qšžœžœž˜'K˜Kšœžœ˜'Kšœ)žœ˜DKšœ˜Kšžœ˜—Kšžœžœžœžœ˜>K˜—š œžœžœ6˜GKšœ˜Kšžœžœžœžœ˜>K˜—š   œžœžœžœžœžœ˜Qšžœžœž˜'K˜Kšœ˜Kšžœ˜—Kšžœžœžœžœ˜>K˜—š œžœžœ6˜GKšœ˜Kšžœžœžœžœ˜>K˜—š   œžœžœžœžœžœ˜Qšžœžœž˜'K˜Kšœ˜Kšžœ˜—Kšžœžœžœžœ˜>K˜K˜—K˜š  œžœžœžœ#žœžœ˜^Kšœžœ˜'Kšœ"˜"Kšžœ˜!K˜—š  œžœžœžœ#žœžœ˜^Kšžœ˜K˜—š  œžœžœžœ#žœžœ˜^Kšžœ˜K˜K˜—Kšœ™K˜K™§K™Kšœžœ‘œ+‘œ˜“KšœžœA‘&œ‘!œ˜₯Kšœ žœžœ'‘˜\K˜š œžœžœ‘<˜RKšœ žœžœ"˜Kšœžœ/˜Išžœž˜ Kšœ˜Kšœ$˜$Kšžœ‘˜ —KšœE™EKšœ3žœ˜SKšœ#˜#K˜—K˜šœ&™&Kšœ2™2Kšœ8™8—K˜Kšžœ˜—…—?$VY