From 7c53c2ec02543477108cb615d5ea7a009065e02c Mon Sep 17 00:00:00 2001 From: Anatoliy Belyanskiy Date: Mon, 10 Jun 2024 00:33:25 +1000 Subject: [PATCH] bugfix with interrupts in 5x for FDD --- src/bios/exp/EXP.asm | 4 +- src/bios/exp/EXTENDED/FDD_DRIVER_2.asm | 625 +++++++++++++------------ src/bios/rom/ROM.asm | 10 +- src/bios/rom/SETUP/messages.z80 | 4 +- src/bios/shared/RECOVERY.IMG | Bin 98304 -> 98304 bytes 5 files changed, 340 insertions(+), 303 deletions(-) diff --git a/src/bios/exp/EXP.asm b/src/bios/exp/EXP.asm index 1fab850..80e0a9b 100644 --- a/src/bios/exp/EXP.asm +++ b/src/bios/exp/EXP.asm @@ -1105,7 +1105,7 @@ PORTS_INIT: INCLUDE 'FUNC_PIC.ASM' INCLUDE 'FUNC_RAM_ROM_DRV.ASM' INCLUDE 'FUNC_SYS.ASM' - INCLUDE 'FUNK_FOR_TRDOS.ASM' + INCLUDE 'FUNC_FOR_TRDOS.ASM' INCLUDE 'FUNC_5x.asm' INCLUDE 'FUNC_LOW_PRINT.ASM' ;-----------------------------------------------------------------------; @@ -1584,11 +1584,13 @@ DOS_OFF: DI PUSH AF PUSH BC + ; LD BC,(#5BFF) ; !HARDCODE LD A,#C9 ; Opcode RET LD (#5BFF),A ; !HARDCODE CALL #5BFF ; !HARDCODE LD (#5BFF),BC ; !HARDCODE + ; POP BC POP AF JP PO,.no_EI diff --git a/src/bios/exp/EXTENDED/FDD_DRIVER_2.asm b/src/bios/exp/EXTENDED/FDD_DRIVER_2.asm index 80ae606..4367bd5 100644 --- a/src/bios/exp/EXTENDED/FDD_DRIVER_2.asm +++ b/src/bios/exp/EXTENDED/FDD_DRIVER_2.asm @@ -72,52 +72,52 @@ FDD_5x_GETMED: ; D7 - "1" - High Density, "0" - Double Density ;Return: None ;[]===========================================================[] -FDD_5x_SETMED: - ;!TEST FDD 720/1440 - IF FDD_NormalCount - LD IY,FDD_INI_TABLE.FDD_0 - DEC A - JR C,.setParams - LD IY,FDD_INI_TABLE.FDD_1 - ENDIF -.setParams: - IN A,(SLOT3) - EX AF,AF' - LD A,SYS_PAGE - OUT (SLOT3),A - - ;!TEST FDD 720/1440 - IF FDD_NormalCount - LD (IY+1),L ;SECTORS - LD (IY+2),H ;HEADS - LD (IY+3),E ;CYLINDL - LD (IY+4),D ;CYLINDH - LD A,XL - LD (IY+5),A ;B_P_S low - LD A,XH - LD (IY+6),A ;B_P_S High - LD (IY+0),B ;F144/720 - LD A,B - ELSE - LD A,B - LD (FDD_INI_TABLE.FDD_0.SECTORS),HL - LD (FDD_INI_TABLE.FDD_0.CYLINDL),DE - LD (FDD_INI_TABLE.FDD_0.BytesPerSector),IX - LD (FDD_INI_TABLE.FDD_0.F144),A - ENDIF - EX AF,AF' - OUT (SLOT3),A - EX AF,AF' - - ;!TEST FDD 720/1440 - IF FDD_NormalCount - AND 1 - JP Z,FN_TURBO.SET_FDD_720 - JP FN_TURBO..SET_FDD_1440 - ELSE - AND A - RET - ENDIF +FDD_5x_SETMED: ;!TEST FDD 720/1440 + IF FDD_NormalCount + LD IY,FDD_INI_TABLE.FDD_0 + DEC A + JR C,.setParams + LD IY,FDD_INI_TABLE.FDD_1 + ENDIF + ; +.setParams: IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + ; + ;!TEST FDD 720/1440 + IF FDD_NormalCount + LD (IY+1),L ;SECTORS + LD (IY+2),H ;HEADS + LD (IY+3),E ;CYLINDL + LD (IY+4),D ;CYLINDH + LD A,XL + LD (IY+5),A ;B_P_S low + LD A,XH + LD (IY+6),A ;B_P_S High + LD (IY+0),B ;F144/720 + LD A,B + ELSE + LD A,B + LD (FDD_INI_TABLE.FDD_0.SECTORS),HL + LD (FDD_INI_TABLE.FDD_0.CYLINDL),DE + LD (FDD_INI_TABLE.FDD_0.BytesPerSector),IX + LD (FDD_INI_TABLE.FDD_0.F144),A + ENDIF + ; + EX AF,AF' + OUT (SLOT3),A + EX AF,AF' + ; + ;!TEST FDD 720/1440 + IF FDD_NormalCount + AND 1 + JP Z,FN_TURBO.SET_FDD_720 + JP FN_TURBO..SET_FDD_1440 + ELSE + AND A + RET + ENDIF ;[]===========================================================[] ;Function: Detect Disk Density @@ -125,34 +125,49 @@ FDD_5x_SETMED: ;Return: ; A - Flag D7 - "1" - High Density, "0" - Double Density ;[]===========================================================[] -FDD_5x_DETECT: - CALL SET_DOS_ON - CALL DISK_ID - PUSH AF - CALL SET_DOS_OFF - POP AF - RET +FDD_5x_DETECT: CALL SAVE_INTERRUPTS.switch_off + CALL SET_DOS_ON + CALL DISK_ID + PUSH AF + CALL SET_DOS_OFF + POP AF + JP SAVE_INTERRUPTS.restore + ;RET ;[]===========================================================[] ;Function: Reset Disk ; A - Disk ;Return: None ;[]===========================================================[] -FDD_5x_RESET: - CALL SET_DOS_ON - CALL S_FDD - CALL DISK_ID - LD A,4 ;NOT READY /NO DISK/ - JP C,MOTOR_OFF - CALL RESWG - XOR A - OUT (FDC_93.Track),A - IN A,(FDC_93.Command) - LD C,A - CALL SET_DOS_OFF - LD A,C - AND A - RET +FDD_5x_RESET: CALL SAVE_INTERRUPTS.switch_off + CALL SET_DOS_ON + CALL S_FDD + CALL DISK_ID + JR C,.MOTOR_OFF + ; + CALL RESWG + XOR A + OUT (FDC_93.Track),A + IN A,(FDC_93.Command) + LD C,A + CALL SET_DOS_OFF + LD A,C + AND A + JP SAVE_INTERRUPTS.restore + ;RET +.MOTOR_OFF: ;PUSH AF + LD A,#D0 + OUT (FDC_93.Command),A ;STOP OPERATION + LD A,#00 + OUT (FDC_93.DrvCTRL),A + LD A,#3C + OUT (FDC_93.DrvCTRL),A + CALL SET_DOS_OFF + ; CF=1 + LD A,4 ;NOT READY /NO DISK/ + ;POP AF + JP SAVE_INTERRUPTS.restore + ;[]===========================================================[] ;Function: Read Sectors ; A - Disk @@ -179,126 +194,124 @@ FDD_5x_READ: ; DE - Address + (Sector counter * Size sector) ;[]===========================================================[] FDD_5x_LONG_READ: - PUSH IY - PUSH BC - PUSH HL - PUSH IX - EX AF,AF' - LD C,A - EX AF,AF' - PUSH BC - CALL SET_DOS_ON - CALL S_FDD - CALL SPEED - CALL NTRACK - POP BC - EX DE,HL -; LD A,B -; OR A -; JP Z,RETDOS - IN A,(SLOT3) - EX AF,AF' - LD A,SYS_PAGE - OUT (SLOT3),A - LD IY,(FDD_INI_TABLE.FDD_0.BytesPerSector) - LD XH,C - LD A,(FDD_INI_TABLE.FDD_0.SECTORS) - LD C,A - EX AF,AF' - OUT (SLOT3),A -.DSK_LP: - LD A,D - EXX - CALL SEEK - EXX - PUSH DE - PUSH BC - PUSH HL - CALL RD_SEC - JP C,ERRDOS - LD D,YH - LD E,YL - POP HL - POP BC - ADD HL,DE - JR NC,.THISRD - IN A,(SLOT3) - EX AF,AF' - LD A,SYS_PAGE - OUT (SLOT3),A - LD D,#C2 - LD E,XH - LD A,(DE) - LD XH,A - EX AF,AF' - OUT (SLOT3),A - SET 7,H - SET 6,H -.THISRD: - POP DE - LD A,C - INC E - CP E - JP NZ,.NINC_T - LD E,0 - INC D -.NINC_T: - DJNZ .DSK_LP -.RETDOS: - CALL SET_DOS_OFF - LD A,XH - EX AF,AF' - EX DE,HL - POP IX - POP HL - POP BC - POP IY - LD A,B - LD C,B - INC B - DEC B - LD B,0 - JR NZ,.ADD8BIT - INC B -.ADD8BIT: - ADD IX,BC - LD BC,0 - ADC HL,BC - LD B,A - XOR A - RET - -ERRDOS: - POP HL - POP BC - POP DE - CALL SET_DOS_OFF - EX DE,HL - EX AF,AF' - EXX - LD C,XH - EXX - LD A,B - POP IX - POP HL - POP BC - POP IY - PUSH AF - LD C,A - LD A,B - SUB C - LD C,A - LD B,0 - ADD IX,BC - LD C,B - ADC HL,BC - POP BC - EXX - LD A,C - EXX - EX AF,AF' - SCF - RET + CALL SAVE_INTERRUPTS.switch_off + CALL .Start + JP SAVE_INTERRUPTS.restore + ; +.Start: PUSH IY + PUSH BC + PUSH HL + PUSH IX + EX AF,AF' + LD C,A + EX AF,AF' + PUSH BC + CALL SET_DOS_ON + CALL S_FDD + CALL SPEED + CALL NTRACK + POP BC + EX DE,HL +; LD A,B +; OR A +; JP Z,RETDOS + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD IY,(FDD_INI_TABLE.FDD_0.BytesPerSector) + LD XH,C + LD A,(FDD_INI_TABLE.FDD_0.SECTORS) + LD C,A + EX AF,AF' + OUT (SLOT3),A +.DSK_LP: LD A,D + EXX + CALL SEEK + EXX + PUSH DE + PUSH BC + PUSH HL + CALL RD_SEC + JP C,ERRDOS + LD D,YH + LD E,YL + POP HL + POP BC + ADD HL,DE + JR NC,.THISRD + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD D,#C2 + LD E,XH + LD A,(DE) + LD XH,A + EX AF,AF' + OUT (SLOT3),A + SET 7,H + SET 6,H +.THISRD: POP DE + LD A,C + INC E + CP E + JP NZ,.NINC_T + LD E,0 + INC D +.NINC_T: DJNZ .DSK_LP +.RETDOS: CALL SET_DOS_OFF + LD A,XH + EX AF,AF' + EX DE,HL + POP IX + POP HL + POP BC + POP IY + LD A,B + LD C,B + INC B + DEC B + LD B,0 + JR NZ,.ADD8BIT + INC B +.ADD8BIT: ADD IX,BC + LD BC,0 + ADC HL,BC + LD B,A + XOR A + RET + ; +ERRDOS: POP HL + POP BC + POP DE + CALL SET_DOS_OFF + EX DE,HL + EX AF,AF' + EXX + LD C,XH + EXX + LD A,B + POP IX + POP HL + POP BC + POP IY + PUSH AF + LD C,A + LD A,B + SUB C + LD C,A + LD B,0 + ADD IX,BC + LD C,B + ADC HL,BC + POP BC + EXX + LD A,C + EXX + EX AF,AF' + SCF + RET ;[]===========================================================[] ;Function: Write Sectors @@ -326,93 +339,93 @@ FDD_5x_WRITE: ; DE - Address + (Sector counter * Size sector) ;[]===========================================================[] FDD_5x_LONG_WRITE: - PUSH IY - PUSH BC - PUSH HL - PUSH IX - EX AF,AF' - LD C,A - EX AF,AF' - PUSH BC - CALL SET_DOS_ON - CALL S_FDD - CALL SPEED - CALL NTRACK - POP BC - EX DE,HL -; LD A,B -; OR A -; JP Z,RETDOS - IN A,(SLOT3) - EX AF,AF' - LD A,SYS_PAGE - OUT (SLOT3),A - LD IY,(FDD_INI_TABLE.FDD_0.BytesPerSector) - LD XH,C - LD A,(FDD_INI_TABLE.FDD_0.SECTORS) - LD C,A - EX AF,AF' - OUT (SLOT3),A -.DSK_LP2: - LD A,D - EXX - CALL SEEK - EXX - PUSH DE - PUSH BC - PUSH HL - CALL WR_SEC - JP C,ERRDOS - LD D,YH - LD E,YL - POP HL - POP BC - ADD HL,DE - JR NC,.THISWR - IN A,(SLOT3) - EX AF,AF' - LD A,SYS_PAGE - OUT (SLOT3),A - LD D,#C2 - LD E,XH - LD A,(DE) - LD XH,A - EX AF,AF' - OUT (SLOT3),A - SET 7,H - SET 6,H -.THISWR: - POP DE - LD A,C - INC E - CP E - JP NZ,.NINC_T2 - LD E,0 - INC D -.NINC_T2: - DJNZ .DSK_LP2 - CALL SET_DOS_OFF - LD A,XH - EX AF,AF' - EX DE,HL - POP IX - POP HL - POP BC - POP IY - LD A,B - LD C,B - INC B - DEC B - LD B,0 - JR NZ,.ADW8BIT - INC B -.ADW8BIT: - ADD IX,BC - LD BC,0 - ADC HL,BC - LD B,A - XOR A - RET + CALL SAVE_INTERRUPTS.switch_off + CALL .Start + JP SAVE_INTERRUPTS.restore + ; +.Start: PUSH IY + PUSH BC + PUSH HL + PUSH IX + EX AF,AF' + LD C,A + EX AF,AF' + PUSH BC + CALL SET_DOS_ON + CALL S_FDD + CALL SPEED + CALL NTRACK + POP BC + EX DE,HL +; LD A,B +; OR A +; JP Z,RETDOS + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD IY,(FDD_INI_TABLE.FDD_0.BytesPerSector) + LD XH,C + LD A,(FDD_INI_TABLE.FDD_0.SECTORS) + LD C,A + EX AF,AF' + OUT (SLOT3),A +.DSK_LP2: LD A,D + EXX + CALL SEEK + EXX + PUSH DE + PUSH BC + PUSH HL + CALL WR_SEC + JP C,ERRDOS + LD D,YH + LD E,YL + POP HL + POP BC + ADD HL,DE + JR NC,.THISWR + IN A,(SLOT3) + EX AF,AF' + LD A,SYS_PAGE + OUT (SLOT3),A + LD D,#C2 + LD E,XH + LD A,(DE) + LD XH,A + EX AF,AF' + OUT (SLOT3),A + SET 7,H + SET 6,H +.THISWR: POP DE + LD A,C + INC E + CP E + JP NZ,.NINC_T2 + LD E,0 + INC D +.NINC_T2: DJNZ .DSK_LP2 + CALL SET_DOS_OFF + LD A,XH + EX AF,AF' + EX DE,HL + POP IX + POP HL + POP BC + POP IY + LD A,B + LD C,B + INC B + DEC B + LD B,0 + JR NZ,.ADW8BIT + INC B +.ADW8BIT: ADD IX,BC + LD BC,0 + ADC HL,BC + LD B,A + XOR A + RET ; ;------------------------------- @@ -420,7 +433,7 @@ FDD_5x_LONG_WRITE: ;------------------------------- RD_SEC: LD D,5 ;RETRY COUNT .RRETRY: - DI + ;DI PUSH DE LD A,E INC A @@ -458,7 +471,7 @@ RD_SEC: LD D,5 ;RETRY COUNT EX AF,AF' ;------------------------------- POP DE - EI + ;EI IN A,(FDC_93.Command) LD C,A ;R01 @@ -499,7 +512,7 @@ RD_SEC: LD D,5 ;RETRY COUNT ;------------------------------- WR_SEC: LD D,5 ;RETRY COUNT .WRETRY: - DI + ;DI PUSH DE LD A,E INC A @@ -537,7 +550,7 @@ WR_SEC: LD D,5 ;RETRY COUNT EX AF,AF' ;------------------------------- POP DE - EI + ;EI IN A,(FDC_93.Command) LD C,A ;R01 @@ -629,17 +642,17 @@ S_FDD: PUSH BC ; ; -MOTOR_OFF: - PUSH AF - LD A,#D0 - OUT (FDC_93.Command),A ;STOP OPERATION - LD A,#00 - OUT (FDC_93.DrvCTRL),A - LD A,#3C - OUT (FDC_93.DrvCTRL),A - CALL SET_DOS_OFF - POP AF - RET +; MOTOR_OFF: +; PUSH AF +; LD A,#D0 +; OUT (FDC_93.Command),A ;STOP OPERATION +; LD A,#00 +; OUT (FDC_93.DrvCTRL),A +; LD A,#3C +; OUT (FDC_93.DrvCTRL),A +; CALL SET_DOS_OFF +; POP AF +; RET ; ; @@ -673,9 +686,9 @@ SPEED: IN A,(SLOT3) JP FDD.SET1440 ;NZ ; -; +; прерывания должны быть отключены DISK_ID: - DI + ;DI EXX CALL SPEED IN A,(FDC_93.Track) @@ -708,7 +721,7 @@ DISK_ID: OUT (SLOT3),A EX AF,AF' AND #80 - EI + ;EI RET .ID_LP4: DEC HL @@ -720,7 +733,7 @@ DISK_ID: JP NZ,.ID_LP0 EXX SCF - EI + ;EI RET ; @@ -828,6 +841,26 @@ NTRACK: LD H,A RET ; - - +SAVE_INTERRUPTS: +.switch_off: PUSH AF + LD A,R + LD A,#80 + JP PE,.set_R + XOR A +.set_R: LD R,A + DI + POP AF + RET + ; ; +.restore: PUSH AF + LD A,R + BIT 7,A + JR Z,.set_di + EI + POP AF ; PE + RET + ; +.set_di: DI + POP AF ; PO + RET ;[]===========================================================[] \ No newline at end of file diff --git a/src/bios/rom/ROM.asm b/src/bios/rom/ROM.asm index f0ea0db..dc04075 100644 --- a/src/bios/rom/ROM.asm +++ b/src/bios/rom/ROM.asm @@ -320,11 +320,13 @@ SW_ROM: DI PUSH AF PUSH BC - LD BC,(#5BFF) ; !HARDCODE + ; + LD BC,(#5BFF) ; !HARDCODE LD A,#C9 ; Opcode RET - LD (#5BFF),A ; !HARDCODE - CALL #5BFF ; !HARDCODE - LD (#5BFF),BC ; !HARDCODE + LD (#5BFF),A ; !HARDCODE + CALL #5BFF ; !HARDCODE + LD (#5BFF),BC ; !HARDCODE + ; POP BC POP AF JP PO,.no_EI diff --git a/src/bios/rom/SETUP/messages.z80 b/src/bios/rom/SETUP/messages.z80 index 43cda58..32e1de7 100644 --- a/src/bios/rom/SETUP/messages.z80 +++ b/src/bios/rom/SETUP/messages.z80 @@ -527,7 +527,7 @@ msgStrings: _mSetStr ideFail, tmp_Counter : DZ 'Fail ' ; !FIXIT strFail _mSetStr spModel, tmp_Counter : DZ 'Model : ' .str_ACEX_MODEL EQU $$$+2 ; указатель на строку ниже для патча апдейтером - _mSetStr spCNFver, tmp_Counter : DZ '1K30 core : v' + _mSetStr spCNFver, tmp_Counter : DZ 'Core 1K30 : v' _mSetStr spMemory, tmp_Counter : DZ 'Memory : ' _mSetStr cmosFound, tmp_Counter : DZ 'CMOS : Found' _mSetStr cmosNone, tmp_Counter : DZ 'CMOS : None' @@ -678,7 +678,7 @@ msgRusStrings: _mSetStrRus ideFail, tmp_Counter : DZ 'Не определён ' _mSetStrRus spModel, tmp_Counter : DZ 'Модель : ' .str_ACEX_MODEL EQU $$$+2 ; указатель на строку ниже для патча апдейтером ; !FIXIT ? вытягивать через FN_CRIPT.Acex_ver ? - _mSetStrRus spCNFver, tmp_Counter : DZ '1K30 ядро : v' + _mSetStrRus spCNFver, tmp_Counter : DZ 'Ядро 1K30 : v' _mSetStrRus spMemory, tmp_Counter : DZ 'Память : ' _mSetStrRus cmosFound, tmp_Counter : DZ 'CMOS : Найден' _mSetStrRus cmosNone, tmp_Counter : DZ 'CMOS : Нет' diff --git a/src/bios/shared/RECOVERY.IMG b/src/bios/shared/RECOVERY.IMG index 7d0d2afbe3e5db4a09cd45c74408c108d5bb0906..bb92284f03e0b2492eeddab5250ce240651374ae 100755 GIT binary patch delta 2267 zcmeHJUr1Y57{4dRn5d23*}BE9P43mg^}3Ca{W0E|bm)V_Fr?{pYXU9wVGo1VhcQql zNi^Q8o+ZuXc6}Mh(4n@p(C-5>O7C!{m_t; zv#cMYcI1vi*?`=05V^3|gNIx8oz;h&M?91^Q(lOicy)Gf`Cm4uR9g)uF6HONZ@P}C zKH$asU3IE;UVPGZBC-g+0^TU3=ODNZHY`p2>Og94fcnLkNevECy8a9shJEvA|3kNV@e+#Q-{`-aKRtH{}S zD=t&b!x}Zk56B+1qGu>Y!yHr8j6ng+5v7bFm2&0~S&0EE*Ttojp&6&?LaF>tnViL; zafFZb2%r;eY%X>8CMbfS{g8%m#xewPX7_B^X(L0KhRE~cvYPf@7P>d}XEye?z=?wL zIKz$zI4p|@*?>UzLqHJ7eM$H*Y$`{N&xKwLh}`1>I?Y4wqJTG7Y{MZH6^6~UO%FrV z8iL3%BJ@lp$*1?84h@lKLqgv?qivXJ&Y%|a@A(d|hOh*njt;^CqX>TnjK)}RTp97x zqmUgHFmd1f?Fm0SCLqUWLOeHv+(Ym!c9*x!#+20O(YyJ|Z4JQ%V292Os*ocf6y8%U zj&vS5AEA~s#_g~%%UFB(@)a z@$knAM%!kPkV~rE#yOC1GTEyFa$gftu0a_GiBoI0SUgx7L~4wmN=P{=9S6#e&I*q1 z#iBFTC##ZA8O^`tzn8Pf9o$tlPK|3R!9pmrI8zQLis|s_d7xs!QJ9MG+ASH!P%Gzh z_%un+aN*EWadB327@QT$?>+zCB?wFenw?6Z(=nLC#Hp^qzZVU1$6!I1CTkUEWa{i8*$5r>AYqof|X2aT3 zD)6T0EPW1iir&&D_2V6ah}r8bpr8ppK3P8^|JJ3OO@WAV9WX z1kVCA%QgCOdB}K>)1obG2A9PPVeat0!{)yEMwkLoaXn1eV6slI%ua@IxnjV^L@hZT z)VHo-jG9OtIUS;|g!ISP65Mo157wwFk&Z~W;h^mlTGBz=IcPiod)xU}SB3cMtEx#Y nP>tWWL`%UL9e8QMRRx|@XbP7L&+g?yd_Vn$xCmM%X>j&Wp;`CQ delta 2238 zcmeHJZ)h837{51dv!pF)&uV8mZ5TgAvZH{qe(&#jIKN-%_bcCw0S|v|^_k;i@RL`*mLQZC;-5?Wy{Op!xZk<*fvD9ea zLD1un4#9*u0I`&NdpM|ApxVOZS-$N{+INu~-O>yf_rcj2PQF)Qf*fXKo`Fo5qrDIi z1ad{W*HeZ@G#TjPf3`=P)$$4D&h?M2^f|7PW^gtlAealG>3t`3(N0LGIJbq zyv?nY6UY^SFES5t`)$TUofY(2rFln5uwgi$Hh~u82y@kYyw|Z-LC(9VcMaDauo=l% zzo#kJlRJ{r<=UFoi<9nNM}_~jPUpMK$$o1`)oHkPDr7RPI5`&d;*pe6ypPmQGX3WA+gLAhf%%NQ>m+@(mo~i1g<F4V7avd8%I ztF0XZMxKURT7Y6nES*@j6E^JS3^s8Ao49gwH;9|;KeuT8ev775g9 zC*0t;Vz)`SQU4bBr`L@mKw-1`8?EJrD=imPsyuhcyNq$YWJX^4X2mEK3dgs>_ d^WT`~Zz(=hfnhc1UK}C8gQmqZ?cnOme*z{B_)-7>