From 7ee5ff5bd4a146044ec1163004ec2811fe689c8b Mon Sep 17 00:00:00 2001 From: SpookyDervish Date: Thu, 29 Jan 2026 12:20:41 +1100 Subject: [PATCH] translate keyboard scancode --- OVMFbin/OVMF_VARS-pure-efi.fd | Bin 131072 -> 131072 bytes kernel/Makefile | 2 +- kernel/bin/CustomOS.img | Bin 48000000 -> 48000000 bytes kernel/bin/kernel.elf | Bin 28624 -> 33368 bytes kernel/lib/BasicRenderer.o | Bin 2584 -> 3336 bytes kernel/lib/Bitmap.o | Bin 1616 -> 1624 bytes kernel/lib/IO.o | Bin 1456 -> 1464 bytes kernel/lib/cstr.o | Bin 5024 -> 5048 bytes kernel/lib/interrupts/IDT.o | Bin 1480 -> 1488 bytes kernel/lib/interrupts/interrupts.o | Bin 3880 -> 3768 bytes kernel/lib/kernel.o | Bin 1960 -> 1992 bytes kernel/lib/kernelUtil.o | Bin 6016 -> 6048 bytes kernel/lib/memory.o | Bin 1840 -> 1848 bytes kernel/lib/paging/PageFrameAllocator.o | Bin 6072 -> 6088 bytes kernel/lib/paging/PageMapIndexer.o | Bin 1400 -> 1408 bytes kernel/lib/paging/PageTableManager.o | Bin 3480 -> 3480 bytes kernel/lib/paging/paging.o | Bin 1888 -> 1904 bytes kernel/lib/panic.o | Bin 1872 -> 1904 bytes kernel/lib/userinput/kbScancodeTranslation.o | Bin 0 -> 1640 bytes kernel/lib/userinput/keyboard.o | Bin 0 -> 2280 bytes kernel/src/BasicRenderer.cpp | 41 +++++++++++++++++- kernel/src/BasicRenderer.h | 5 ++- kernel/src/interrupts/interrupts.cpp | 5 ++- kernel/src/kernel.cpp | 3 +- kernel/src/math.h | 4 +- kernel/src/paging/PageFrameAllocator.cpp | 2 +- kernel/src/panic.cpp | 3 +- .../src/userinput/kbScancodeTranslation.cpp | 31 +++++++++++++ kernel/src/userinput/kbScancodeTranslation.h | 15 +++++++ kernel/src/userinput/keyboard.cpp | 36 +++++++++++++++ kernel/src/userinput/keyboard.h | 6 +++ 31 files changed, 142 insertions(+), 11 deletions(-) create mode 100644 kernel/lib/userinput/kbScancodeTranslation.o create mode 100644 kernel/lib/userinput/keyboard.o create mode 100644 kernel/src/userinput/kbScancodeTranslation.cpp create mode 100644 kernel/src/userinput/kbScancodeTranslation.h create mode 100644 kernel/src/userinput/keyboard.cpp create mode 100644 kernel/src/userinput/keyboard.h diff --git a/OVMFbin/OVMF_VARS-pure-efi.fd b/OVMFbin/OVMF_VARS-pure-efi.fd index 77e762c723d9b392da6cb63bb92a6b9128896682..453efac287a45c34a39f35ba5951498dff82f2f9 100644 GIT binary patch delta 419 zcmZo@;Am*z*wCdj`Ies2<~2I+I45s2QQLgLY!c&SJ0qpZA9PtZS6CD=PClorGp0RUk95_bRq diff --git a/kernel/Makefile b/kernel/Makefile index 6ef303b..8300f94 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -7,7 +7,7 @@ CC = gcc ASMC = nasm LD = ld -CFLAGS = -ffreestanding -fshort-wchar +CFLAGS = -ffreestanding -fshort-wchar -mno-red-zone ASMFLAGS = LDFLAGS = -T $(LDS) -static -Bsymbolic -nostdlib diff --git a/kernel/bin/CustomOS.img b/kernel/bin/CustomOS.img index 655e3c121714ce103fdcffdb1117f2d843e56a50..2f0d7ab7a015fd53dc3647ff7aa71d64b2a9382f 100644 GIT binary patch delta 12064 zcmb7}30PIt+Q;`ftfQ#tK@>$nIiez>A`WSkCJx7rGY*KeB7L(RNgH%m z*V4+&Y)~@+tq_MmZ&oyW%Z$3FC-EyPZ;@9$-+%4B&H?;x-}8O@d46ZD{eR!}u5qum zH{_iEr9}?d)=8{!mk&AAOGiZ)4`tWD9TYF_VjZH6{eo28{9pL@buc*1Jw_rQ)N zme>9dUKg!RlJaKvpVohxrpeT*$!q+Cf#W75CpkuscR9ig-DgkG1`16Z;T$*GInv>9 zjvRW2{a$U-I(^1PYf^CSsMEBP7Kcw*2MyTKHlWF<+7`3ExHyOJ3O3u}tIueTHfYS4 z3CiIPdjP_|6d=Ra=|+H2?ytj|)s7lCY_tsP96IcdZU`;m6GVO?pddOR>_W&m)GDt; z<5$xrW$Uq4(Pv%S)#*>%aF^AC}uV>P~L1idum&<%l(5Z_uAchQiy2b zKmg6`DCx7O<*EvLtwFK+uLqunbL$@{)y|Qb91j}Z*t2Q~W8@1#m z2D(p}In902UcB6t-DRE&w^f@^TYgfY;p0|~mr8wAJ~%Hi*j?gEIJr8~P-=An!QqH9 zfoQEeDRA3ay-za{mAx8{7!p-Aa;RFCwHIji;wr<41|*sdkY?2Y44G_zQe*>Ul)4S@ zxcm)}M%jQ6Ga~ws>#Vl8^0JMZ)|c2fEXTNS!w9PZc42Ia;0zK`ksM`=uz8DtK2c#s zN8Qef8m+k@pdw!xROohAl{wGJxvLzO=RD_n%4I)*GDa8AyDa4{eL!;&lr39Tl$X>2 zNjbWe>ns;oA=S98kWLBCa{4CMdCp>nxYy~S*JM+Diy;PWm5l?MYeUKMfo9$u4LO?U z&B21*7z8=2kc^3xT5=#ttqL;KGIOb!5j3-dMme|hk}3LzqdE_Y+v%xHMl*9gfkyYM zDieHO#-hva;I^VaRcLwz`cXy2xbxudQf`T{RM3}aRb`l-Y9njREGm_qS@r+zOx?cR zb;omqDZ!H{pFsc8z^!j>`j_URPNKPfxVf0!sMaX!5uxJEhW-^2rhgVH_F8vL)>pR> zQ@bWi*0fDQ!S({@_1qE*W;#DK8d9kU#*(##BkM02qkCJ3G;8c+y+Lcy-IceNHV ztxinxyB8o^%e|tdm~AbcWV&xu?$c}B$JKQ&2@@ICnabUv+<#B;N3TS-R`eHJiFE6q zDQ5IzDMn*@Z>w?NP}@BW1L!Gr{-(Kd*Lbv5c4RHCKc;(1ZQrEmyIYI*tSwXYIpJb) z=e-lvfF%DW2gOqE8xoCnaC z1K5$;HPbYGS6h+Ry`G`p_Cz2({ybbg*YUH->Gd>(Qrr|b#~o5GmOsDiJt9T3{@){C zEY;)fq`E`?e2Aao7^xXi)=BM{)Nm#%zeQ5pt3QGesgFw&YEY)3(zMpE86kQ~Z9aa` z=-cj6v#vH$Og2R?M8i{_FP=pF)a-zP`Y(|pG}6CN!raxFZs#?7q4S#i7=pa!d~nGh2$WazZD` zL=HqA-n87dv8FoCRMB+X7@5tt#TW)#>IhBCEOV9{^DrSCCb#nwEQ)eD-a}-w^PFd7 z{wCUB4P{wG@H`Qnze+4hf??#b2Zt}e|x%I7%C<~fXF>IurXJq8E= zWbQH7<#uTDA+IrBf7A=M-K_%q-sdV&v9~w@6GfdYorlH(F~XkI1YBxLGk; z@6%EAjq5KPfp-SCtrv2+*mv{rdiRv;US|azg~M#qOqa&FvcFEEk>a_DKEBXwk9L2J{3Ho)^t^ z!V`oe9WPn()`cNM>i$p;<^cUhv>5Ir1k_pes*f?p)pE6M_b8kvDm^?J}_`ZPN%nK1OV?zEr7y+ex&K ztHz2^Wls#RRrW1;lV>|36JObV!)4i2eO_nLWZq0^F&FN6%#OXFB)8gPf3jqK$?{kf zOqAvm6+z}R=v(4e!ToY&`QAx= zYT18OU#X)8>!PbzSaZ?@8xiH_k}*8;Qz;nV3wd2dFH0Z&cvsOrya^7R+$sy!<@)t< z$>rOMaRAD-HCn&bRkRA9Tx~qBMaC+0pRBdd$Lc-0iIJAW`r2+HCVV*dR2AqEGtdpE z8ECV9qMK-C*{**rlT7_z-NZ1AELf2Qw@ zL!g)Rf;a@~v7@`_Vd<>*>@Jd;d{gD$C33Gh^ex@R?3(vXhkm`g=u>kasK>{P$Xf3? z!TQ8_F#_Lp>eIy>zC2sSeZ~olUdi3*6Wq!18T6g8S)DSB4%npeh%}bLQzpJI0NXC9 z=7%b9Et1Kl_9QJH*mle0Q!&CPpO)Hl!3ZaHhJwX7C+ zYq)8=9e>|lzL$vLT#uu&sb4*(RDW+A?&?i=>nLzu>tBH8Wi2)m`_`9n(|^BIoJNvu z-?|-lxz!0-^YLTfy3x4nlhrG?x=;3+-0Ik@rufNTmRsE@p*pRlmrBkd-!LcY zzN=5)yA$HOp-W32%%H4Q%jYd#GIhG9r7la)oHKX+f`#{Xnx##9Xl2@p*^3_N8rNNm z)pYlG(J5Pd!|OHb8rUS5t%DoavyLncsvoFDpvHcnC+t7V+Wq#cemnmDrCASnz4Caf zvFG^ht0B*Y{a_vYtA6`V4f9(KheLH7Uh_M=1AX&BuXlu;QeOiChFYXU1f&a~;E>lF zhtzMMXB0O&a1-)r*dMHIw~{}8gazv>;!UqtR^$(0E%ZC|L&Zg~cdyfcSbqbiK`%S( z_5M(&e1*UKYS_2D<@H{wWB=A~-{`fM%Auhx)I-81F#Q;9p8C16|AkX%fEik zhkayiyY+se%>DBvyXYbkur*JkxZ#+;c3{{!rr#F zeR7Tc66~vCZ&KSnti~<`dIzO_aU(Fgx!J;`kNDQ(?8z!6-MpFFt^{^j(7u#L!_}0rt1z7Xh+8#KpFZOzS*LGN3(}2^kKLvZE+V-I} z_Ditm!oIGy-MYqCfhKI4_5p*441JeNxLC3w`&2@UP!QX=+u&*fbdZ*M0 zknFD@9rlB;Z>VFh**4b0-r|JUi*L(X4H#vXNB!C!IJn^OR{>7L{>EPgK>16sSHQld zP6ZqN4HWod9C^~~-C4)38}@9>fz|;IXW;N3TL}9Q*l+wr09igA_7(UF`K$8lVc!S4 zvHAO!bdp)W@l@`C!*l=H!LXl({mK8uehK!?u&=1o!=*JNfYn_A`~Q4qJLp5aaK>7zJHo{&aztnc$#QwaT`hY(}>tqtFP@# zgF7x%WL*1|?wD=f=a`A{*QgLg?I)Xs%lAg$fqyXK#HO3N@Ao(8(!V}>D6b#PL<_)F zK{q!LsTrpt(hwMAgLdE1pf+X!?R2mi!PwD|P4M}rntG0zXrq;X<94QC3_Y?_41esh ziBeynX-i~^i&TOA_)Cktj57r3Hl+_ydX!~ z{6DAEKQ+!$?Bdd2E`tfm@LWr&U`d#Xwp!`mN1B4MT_C$x>E*3W-8batpv#_B89l3c zcD_{p!FNpME$G>@MZW(=V)Yr9z}!k*{_##;zLAJiy8PRkypqgBn*m)`tfiZRZz|_0 z|1+v$W5a|?zVhEa%jmzR<)}creFZQ_@;YcH+PkViXH|hRYac8BOf_YLmH*F5@2y5? zr_!5YXO|5P^v6+;VI&N)$MR2(^78fAsq}HG2gZ>A`*fu@HzpCsg=*0YN{_;y_2lKN z_?*&L2vd(U6YX-gGPG-MD#nWqvNnvSY>@9#Up!iGr5CFTd~-ib=_|3|tt_Xu7fT+5Ue_&>en7u{?DqG z8y^L7{q0tUCU!H>pJt-HuJpBP=zK%{snWk{XF3{(AhK7W2g@mIuL7v#XXSq$i&9?3 z=MvIe(3@tXrH)iX*K*863&Bn;d*GN=SC3Y@rgW4yuDcA~rtMaXGd%*#`;(Li?&i3iX3KyWEJQ+rT?hrs-w~mD*YPPfV?i5iB_U?N02EP-&e?fr1WaF z(P1&B7#_bV!yvWbeXFz?bU6~cXPbd?%tQ;u9Lkk|h1= zV$nAkM&p`gCSU12mWb{l6>7;d$l^(*UMKrh!a@m&OJ(*&ku zrin}`Op}-I@1iMnM|{oQkiBmr7@*5WiVwj&0(6$G>>UM(*mZ2Ob;+E zVp`0!glQ=gF)d@tVp`6$g6Tn~l}xLc9%6c!X*JUtrnOAjOgT)CFs)SJ zrrk`>Grhp{BGVqGmzef4z09G96=jo9P{rDS*`km*>f?l9ExC`_FeZk!z0o()b z1^qyOa32@|62U+)2n+^8fD;S__X8Ig28M$XU?dm?MuRaR35*5fz<4kLB!h_{1xx~y z!4xnROas%w3@{VS0;ym&NCW9017w0ZU@n*k=7R-bA$R~R0*k>CuoTF7Tn4hha4S>N$unD-qW{?NAfPC;M*b26R$H3#@3GgJ? z4t4+?JO!Qx&w#&yo#0vU9M}bRgXh5u;6<p3fK=`1+RhE!5iQJI0z1b zH^E`>7B~V5Kp`jsN5L`hHh2fT3yQ&UPy$YXli(CM4c-H#pbVS=XTjgW``{e-0DK5O z0_EUi@Co=7d6M?!EfL?_!syc`~j-LpWp`gH@FFIf!n}q*-TbE{=fnOE9YHkc z1Y$sE5DU71uAm!;1KmM9=mC0yUZ6L)3-kef!QCJM+ym|f{Xl@Ag9TtAcmON{i@_4G6v%m82C~3%umU^?R)SUFA@DF*4c36QARFX> zN5DFe3)X`TfWbzv3An*#kO#JaeDEmP3bujAz~kTv@Fds{b^skb1)c`afWLvA;92k- z*adcj=fMl$MX(3F1oncL!9MT`*biO>uYuRW8{hyq2o8Za!C~+gI06blAt(Yz!7=bQ zcn7=-iotPE0#1OF;1oCw-UFqe44eUH!Qa9A;2ih>ds^eV!Y~FnhYofQjEi#)?0c8q%_y2K z$DXyPg;$LFppjQ+*GYS?9%~u})f`k&vD!;Yit}ILRzLjhncXpZJ@CMA?QoYK#IRd} zRM<+x2r}#aby%y}K|T8oR$-le``tARVRSjg$gc(MNeGHQ6Omlg>PM=T7)4WLOS|aU zvsg9bfMJf*!>#Pbxzh zF1Lzo78%V|HS9pTmhGwGGB-jDu~n7%QKE${T87pZ_u9tD{Mw>P=44j#dR)Rx%zlLJ zF~Sa%sP4RP-SSSPsC(bJEa!2X$9dfKlB=83J99@aXH-w9nzph) zzst;in-jr)YcILIj+h#(*FeVC6+5d~)n!Rt@rM1i0dje?7?tQ8U>M6o!^8GCuV>}i z*i=qbJDT!ExZ%oiG-p=V3ack3*t-spJz_+6`_2AxVT?$OI@v$qn$N6uypV@)r?fn8B*u-pLg1q_8 zUkz8*0ynWXjKcC5%!dSivptRv8y3nuUb>%X6*rwf0)? zugdk36J0q@wS8W4c^r#-Q_G1uX}X*?qr7q5=Q}u#+sZqIkNtAzdvbrAn2>2V3wOMc zOb>2Saw%`ioj$Kp4%A}dV4N}^P`7KmS+X$NILI>k zXf!>mDr0Bf^mFRI;V#W^r{7wxo?vI0Y}7z&qy~j91+)0tDm=pCwsqE8K#Em*q$}l-K zj`vYchh6T^y%%|I)9*vmQs5OFCp)IjmXZ(E@vfH3Y%)d#^rV+?ckIxe`YA-2RM8R9 zM;>e{>el#EZ5VgHihL?Wo^L9e+1kr$@uE-irE(=$wP~KF&b-S_7&MQiJoamBxlbp# zAYLR?Yi(K_4SUP&@gjb-gGFB$`)hd?c(GBNu@hV%%N~_ z1$if`t9pmoZiyaDFWI`8h|YXbd1iSRaT2`ryB+Z3*>A2y)f;LhoZkFY$4ZrE6r|d# zsy0TMZ4_B;l(KH?P=6a-YqRe0Kh3(Ox^8KpZmd~1+-}6MSKJl_d7}cA`KmN4=gPC} zVEj350dL$*pYOnJHf8PDkXtPJRB;n;-kY+1f=J0cdDU#Kh!b4QIa*@wov198c${Zw zy+EtAqoU?2E2q`;amen5kx}3*GN*b)4K)nsDK31G+I#C%&pggTl@DgaW}dHGkNGw% zRBv97+BUKzK~%~7PIc(qZRO@DNmVt|%O<*7MK)7U^=yat07s(Vd^wH+Is`UccCgu{ zPigy*zU9K7SA0JG8uA|D_d)rw%#R8#Cr9gX>}ECB(!Ai=)mYe?DrYnoomx&;MjJ=r zc$B#;p2;5Pb@K&SGIKxu9-vjfWxi}KQj+}N7+F`w@jGK5!*j2vZ*{o`Z4BGvs7>$e zys)LCZ9L8$B31TC6dP;Ju#WK(P7C|uNa-O<6GgM8iw!k)^?o*7hrFS#oHV}u2eC+# z`-GayZZf5X=-;4_(XyOJ*|Vc&&x&WhciE;79r;EJk;Zeq@jaro{m2!0yQOHF6v1WA z&YRte{r`^Z=DJ5cwru&7DtH{5aE2qqR31UH0*q%gZXWg}so+&zY8N7%B2>D-m_tNSdXJFW&cL8EK&c@a-j?x zKR@r2_1cK09YTV*{-rix;imF~k8j`xvvE8N6n z(cX4Ru1#jRrD}Itz0=`Vce28LE6*@o%=O>(iJ&%lrEqIycw5oW)d&ZbP!kf*61a!hh?Uk1|vzQDLU=1)3G|8sZ+O3H|lhcP78JVtxm7$)aYrL zSBy?WYFlOheb;yPWnp`R$Ma+e)-H0y1kp~GOb~IIX$O410m`*!&2ZRz*QjFe8yd`) zd;^;J{2BA9U#_J87|=)4?mFo6t*fNJ7|`d_ewh09O8T1teZ6618iVtEzJ!VnkC?jI zfsbe(PJLEI-99Z4;0*0ssqd?#?+WO*Xiq)l^R==u;~!v9f=xLzps9h4--QDX`+Vmr z1vnE3kiv?ge20`&(!UAl>S#Ys{d^_;Y(Sq+{kfw)-}jaDZv*=JOgaqt*ymGec@O6W zdiW9TJMw+L_)27&E>(!duk$Q14MupI5FYG_V`SX*#$nI@o)g z9_kgGLj6vGT$v#fsyxoTts9z1N@%>TxkF%^3-qP&aQ)Jv(?uc)V&>zk=xqHg{s z;a}u_<@!eVai)1OKRQeRk6x6d^L zs7-y8dbiJfzFrme1^)Ql@E7PXmJX;ig2jOm2nU0l@cBkm3}7D;Xds^Y4eCoP>5Bq- zAL`>i_xXla(g#^O+czfC;dwgzRe)^jWq%cb^*2**S>*FQTd9F%fesv{zJ~hxO1d=l zOf^Lp=n!%8FM3E_@UMnG)c;!mRX?73-v6lIhx#wnYgO#PK&yRo4JXp!!hd%#^=#^= z|A)SrdLi|h6&tWmEuR7E^-uk`XNL1{&Hx=E>2RykF8{->A}C$(@hJVm=X<oM6g zMI_tmpN>$HVVKVm)6K-rpBh7I%l=bElD%Y@oHtc$$ehV-UdsqJwhmL?hQXJcd1YyP zoVia8W0AH?+9Md}T0P5PE+VssXb)$c#NpaeC&#t_O+HrYI%g$@I+__L)7Y%$n3wq$ zV|tl_>d?l!I`q2^v{wJRYMwy!k6?Y%-<+%Rjy9)Vb@cT{DmwpKvJ&H7)1Sv2zfcV0 z3B#D7g#o$(%%g?xZf&2W?eW^)MBAU%_I2Tw!94PqU8(J_a*fpWy_FaneQhsoXc^3>h}o~TeSfHBucQ61YWwIY%V3_&%tmp`sevumam=Sx zov=N$u!5hq>e5@>c$9WEb)|Pr-3;yj$z4mcM%(>A_>Z^38Lw!&`uRg${s9-zo~e4I zex6X*SSvC9pr9Hy?phkVI*I8&Q!jx|j0D=vJ)dR;Sft~0(f*ye6zW=MCB_JC?^|8X zKd&BIn5~6tdNZ!q_Lp=6Rdt7SJoDY6I;4J_QI~&YpXfNJwBvS5Hh$1{L-%~9Zr`}A zh10byPxEcdY%lHw)xa6OH2w}v(e{Phcj`*85(C=)yFQ0Xw0(=V>!LA0XTHeP!ZUg; z{cEpgUp2f!@2aJ`LZY@u>5iJ;71V~)u9jej-Yfhu&%7Si{&z3g0&UN%svk4|S}xT> z6K&Utu}a%@+`tI(w0*ViP%rIpLfc#G^RAh;U#DGlG~8OsO!Zrad8r>O)rc4CgTVaA zrV^p;*Yz6zsr_TMy|bPn|I9gQ4`-aXSna5jLE68FkEgoKKQq+&kD{P@6nEE&J;QIm zYgcD$yP@qYn%8P()Bwsimu26k?N|BJo4U+TXQm%0dnPLk)l;O~H@?voKG!4mPu*2* zKf}$ct`hTZ7`L_E(2H*V`9UqTn$@A5`XKV}p(p8YKCYayBo$+ky75ZZ6~gu7=bzG% zw3{aN)n z6egpWh+6XEVi6`^I1>~uT}wpcYRQ({j8r*uiRdI-ED>RLk4?u}BElnbds-g3dP+A2 z%Nt8Xn_7Csk{`C@L}Ar=C`&{OWt4HB21Ux{S^RfZn)cbsv8zkXZIt{tOSB3p(+BH} zYVt;w=xBd@iforHMgRhE09Alspej%e2mz`Cp+F6wCJ+XM1GRt%pf(T*L;-bxx0h~Zz;C{db^aJ_>1Au|RAYd@?0FVX@ z0fqv@fZ;$oz=1yqJOn%pj08pjqk%ENSm1BKIN%XrJTL*62s{d80FMEW1CxNsz!Sg} zU@9;Tm=4SUo&;tBvw+#a9N;P7Y2X=PE-(-HJ1`$u04xMDfknV#UwuSm^}s8@2H;g-Bd`g04R{^c z3~T}30Nw<)0&f9t1KWV@z&pUZzNi?ZP>XR7KfHWkHNGypXjY$*Il*E%}B!M(1iKGQ-Nm`NCB!fIg9w(E?Wby== zLZ*^wWICBao+LBLEHazSAy1K~$undwnMeLk=92|vA;~0*$YQdDWRYyLlz=QF%ZZz; zARh88$ssGrb0n9nBF~f6q6M2oiPBxP*S2Mm`~*lH=qva)NwLipWWFiu{XwLB1rX$ycP9{F{7Dz9DDGx8yAOj+Bsd zX2^dh}UAL1l^$^FDd`jP%*02xRIk-_8vl17G*p=1~tPSVK;@*sJL zJWNKCQDih3L&lQ7k#Xb^GM-Ez6Un0_gFHqaCzHrz@&uVerjlu7I+;P9Bs0k@GMmgH zPm!m|Gh{BANB&OclLcfU$s~)&VzPu}k!-S*fGi`+iJPn-9`Y>7AuGvqB$uor&y&^U z1@ad5649-XlB6 z`(!8CMRt=9$R4tn>?8ZhhvXmRBl1sjfE*-w|u>7He94K313draY9ofH7cI!LSQP!qQogQGt0Gq*MUrsiU9y6rNSUV$ z!|yT5Xy&yNN%AMTMD3z4r{ngY5)Xw2LREdC@`LT_ z%V0aCbreCMqJ>C4Hz8BYvF)wW$!IIKT}8ueyTZ07_G=GmmR@j2JJf?HV*MLB)IL-O z`fo!2sBM>G+uMiQz*p41y=@pj)cw*Yp@AuVTf>`X=>v8YO$>!K+Y>5m*iX!wrBCY| zzm@bwGp<<(J=9TT4`pdVb-;o#g5ezWDO3mi-vt!4;8zUz!C-hC<1yQ2KfJKbWN$8c zFf`Dve!xOIigH5TqNarQ+xE5yI24J!`iXQO9MS2_VV;omGa(~n|6DkW2HU@3G9xB$ zLpT^kpO7=hq=g+?z|NLvMEyV-7$tZ2Z-5L;tkeoMXhmY#hXYK6Zbd>jB1_#MjK+}& z=|)mgb&F|+ZbT&A#tDfqFQ~>XXwX1g!nUm~(rq$IH0av}GJf>XIHWf*aoy1@xBvl= z#Ktp#ar8bI4-pYj50bt8WfUq8(R9OZo>-c05pW1_wXdI4>*{b$L(vD@f@)tjf<2CA zlvoSZKL2Y$^&m|*1bt17`G0Pn=jjyJV8)N4Z4I{+i@I=$7?3>%I(veAdkCv1NAl&M z)A}*oh=@fa2#TTAuNC@Xc>%AaMCI$)Vbg)KxYx-(?WWTM>)Lr z%E&$v40Eu-+8;=LFpF`n>gJHS>p#D_rf9{?A?wf@Gy(|C(}G*Zid~Ow^uYWpT6c69 z<|o=bqKl`#9C%dgjtwJ+Q9T$P(XM`I+ogWErwtrP4ktr>?dl29UoJgMA0l(AdSXjB zFrtfYCHt)`E}6+_#$&XmsPn7ogO6hFx9&mD&ptjf#4h#3iN4Surcly=b%u7K-?rzr zZG2S;T$)CJ+K5}QUWd>^{91lHNR&J4uhs0=IwyQ*g`%{N$t8$~|0{-%jlBKtziVKg=|O}S8p6po ztm)1Pmjdd^&P9^5UWBUQF0r^fX~C)kJ?gu*9`zmNt?y%Qq47KL9B&>nn_vRMvFvvB zy|#_-jcgsUXD$cN9=gbeA@6mL$wH@hQGLe}#=yF*GlV)c4UiCw+Rjdb-o5`u-Bs_f ztKOjju7awYS0J^b@vd%UH#nt{yHHIU8QS=&)`>_KHjelLZ0r$AepVarK5H9qN!nPE zYGd3Nf{95phkXHNx;~$o_Omwg!{x?Q_M>W=$~dK@q?ML0z{-y>A{OUooyd+UBq-IU>0`^2MBhI?D< zKAANuji4)K7oY9Du+Mg-dZ_h$=6&C`>70%dMe*5|ceB9$ z3lLTC4F%UgI~~Sibk-iA6C+@p7+YQ^Qje0yuow{oLh|#+Z8Lf$a5IaG_ozpe{u_an z$MMUWkD-p+RtOq#0{tpdaej!-X&BGI%;LZ##qp4sr=uLVN2zv|`m+BKp%HB!uUDCT zltU)*ab{l@LdvJv8p5$>;T6M+{EonHSs0#`K$c?Lu>t4mfO9wv0K_hk)Du201}&n- zF$C}Gw%v+tcUT+AL&t2pi-uFPJDRIQI8fnm*d4V?ATIPNt}L!7URvy2e#6oVC%*!A zsyL9TJ7Cuscn))VD)#m`9Ed)l!^D}`WAi2Zug;3SM`yoxNcQQ-X{5|U`&PlsQ?Wa7 zGHX|#z!W?Yio~Xzrzo)rAZ*iu2d3Y+a>cE#;v0)s6t674=@#up(sr*M)P3|THU(X` z-NFYVfo>;sG*A=MDPWQbuE^atg?NVZpr6Dhq1^W)Lg<~UT}{MB0oi*l8e)jOMEelG z1h$=;kJGQigxT>+2>cFVzb9-uVJvbpVS5P6CTt2d8|c?#gk=%Nd@BiifG~_L`4$ki z$-tPefUvdr1z&v<>Jb7jCJ?boU;-d>(i?lM2)}S5m&e7N(8`TbI z2%fkji~)Dxjbb8B$SD1Gaj=HdJv6)M$(J4^Ay@0XCR#ya zdt$F*rm#r*so6PU&%02WlYAfg&{2AfM(H#}uZZ~Roc$1Sbe{7g?v9P*#aQ+TmT*5K zk=SHR1^A=jkM5y=AwdBJBodoJLv>U|u^e_vPmCK)5H+nwm!cX`+4ucZ!Pf;s7l!&h z5kfsQl!e&82_A?A6}C9-qJ&Ky<-JW-wXjf)@16L3U8sirFMvI2 zn+o??E!@L;+)3*lr)H1#6*0vDYwYC5ru1s}MXY}USHgx~Vw_0qIZ`BK?E$WJSofhw z^>8ni7zmFM-5O=LVKlx;!B$*_ zgfAJZ_k{HvydQtWJ!7(G%;=fVqxOkW2hew!(RV=h?G}9pWZwa!?+3ILthuBvSeq-PdCi zji`M*oy#s_JO3yKiNs3D*bXdW#O^7m%5_AmcyWe0s3w=u|G=!+D~J`$*5iw*XBCCf zc+M0EqbDIjCc#eYKZC(ofRBom`XDgQ9R}gKw{ia`ww2g(IH!p!HjnB0bpftYkpZlm zX}qoBz(~|vQSV6=i zoK|*1&<-tBzTLLV`k&YIn>glXMKdAQ*>iN}Zw?-3@aSQIyPZNUmCriR)VUAfg^% z+ZJ@F2L`i^vn1OVn2fGy@{WQsMbtrv3aSTS3`rqlp6ItE7hhUPQ9{O+z$ZtlB6^%T z5tYs`ia1fzGU!lGL6)VjheV%(XlhctyiSuWH+;Jhtime@H*ztL5SLkG<1xBd2nXX9 z+qY?RSRm--@jcL5kuK{46Ryy{f>`_>)~$Ah*e0y^QlrEAAQf`!u(qSY=INgmg~k*GHOL~EF^*XtS>)8OVa=KCI^=)x@3iYDNK&6_R~$^zuI}qhc0EOn4(roY z=yvTu;|sPc7oLjuuYw;iOA}l)x^TxKq$9I2GoV}%k@XaU4uUg_@A$1>mc;%mw}Ev6 zwfNLx9Ys}^Po0Nhn0OhG!u|dbA2j~1*eMojZ4Haixs@ld1EE8)DnsW%@W90-P~%n_ zNq6T`YIImvQlW=axxjo>6sqy&v8-vxS_QzoVm?bmUGljjs`4$Kgfm+EQ}9S@n>3TP zHPq;^dZ^H?T`sV7RG6(@4d9El7U`C5=B+O*q8iD>u1mj98J!u#u#6x^PPc;gd2%X=R>PWyYih{XiQ)Kcp)zm zdy*J<>5~$44xw@o8?FPRwBeh=hLftW;T}3w;q;EK;Zz$QJi#`EPq)FBqODltk=PwH z@2A<|A=FSU-GJjn6$U^9>~^%z4`x6JjHw0`N&}v!^SU@S^rjl{@`r2yuJ-Wyk}?TD zNl{fd;2HLeJ~d$BN&YdFhHB{sIFbhRf(!dJonPb(bf^!VKKA8yt&iQ=E7u`L6s2y2s>~ zIeZiqRRR;Zft4|ub`^1QHLo*$tf7a&Ro}+AVtX)*JxiO?hx0M&#?B)14DE3U0x?Hj zSda;NJpp?%Bjs|QqJOtwqSG-;^xc!Np@%Y%(58@K^NnV!Q#o^)vAHSP!ADy!8mzUts)SxZce;$%CWrMLd%i zPr{4+tpM%>z*l61?tC5SDxhA;b~kwj?;RT<14qx%s5Wyo^}|}*E_{lMOQ}~NV;9ah zxSDF)nBYLQehH%RFH90*0v2P0=b!WC*(OuU2E}rLuPax%@6dhW`=a;7?(1`P)Y+a1(8Q zV`HEaeQImG%{qq})A=e|8UnTT-gMS9Sm!QjY-shOLt}%xPUu2oRW-CUyQ}NGNu;>M zSyth#sdLxXr-Guj_=ZaACmQAMrY5haY{}_}v(X=@Y;xDIc}{m7+u?Mt_SzS?Tj~Nz zX=4jUm5qho2Cv^;XLtG=1Kt`^Q4*Bvz5WJooxQf9Hc;!XtG&bPu{XEWz%R|dmb$w2 zQxs?M;NHcJ%4)3Q807X>^XDi73N=of64xh+r9q4`j*h{*(&AcJJ!{-RyWjtHSbDgh9c#TmjW$!R4A5pxt5E@jL6w$QItu*=|}lRBEeTP z#ba~7l~r=i@T^5WU}4(TAQyoC9`PCUw+;HufU}-RB>1Zo4SJhF-vIg=(08Wv|CvF5 z7{F{MCo=ha(Na-In`fmXJ-lr0YBPsO% zHs}w7?tD6tIGRE~Y|x(t{eoSI#G5JfKO6K{L4OVOAWB33VVey7P602%-^ENzp-(pG zlknGCrOzZ1Q_b>kVew-AL0mVs*~eqEo6r2fHr{s9nkS7DM|X$ zj$!v?hpg?xw~pA7vw7q2SML#re|$5}_ zpuZ0Ksg(FWkwpS1K1)I0)00TlrO01x$oGIgJd#Khndx^X?b`zSrJ!GKrhAg~M?udA zy~<3_5)PvA4}k6k{jL=H9me=aKtBLFz5~P*Um^ie|7`q4+i}n*rNs9I9N!B|O0Kd` zU%0sHa=T-8UO}G2UXWifC*P4jlY|ZZkf?0sFNt)H^M=65_k;0YHUvI<2pmVCLFK4J z;LC=k90IQ%0^cwMPJeDan4aGQelG0Vk!IK961P_iJKIFT-(ofn zp17I<6pwVP5(9rOt$(aN-|GqPmj#vGEoOyh#*_U-CbWuaBaK&qgS>NxW3z zQ<;jqC-L8m69Dg_s6H+6-6IA5rsV$(@LbrN{`^t$@3>G<$US*lVBtHzm|TM)21{^`EN>nIOl@* zL5b71Akf2Sew0tKd>E0>u<`%Q?SKnNpKy)9r%UoaDTltkiyl6EqC6_`KB?eQrYgz_ zi7&Pbph)6rX%ubg+zt)LZ4{3SkYVPBX0%Ow883k1Mt1ynak{4gKx6ovN?;EzeX z?@NMT_xC~IWY>VSOZVr0N&eildHh)7`v2F*XFQ0^#=MgL^kro9=zhqPIDJ_dJx)<5 zw*see6^{V)acd=iuN;^6P_T4L{_U#-f14v6!2ea^Q}KOc z^yuRrlz1!rO;4UEls6?lMZReB85cAwTuJ)qkNoEk$}EZRmGbp@UnTK%2z7e+ofzev z67QSHu(DMY%8w;}y-b{&CH^9C^3U`%{~VV1P8nCDB>zzG4v&8SS3xLl?sBQ*M`sYghpG4uK7#^{-eM-uYOs`(SN@u`41r;>EXKolpg~pJ?(CW zl{Qf*QmbiV40Ql|z)fXimm-$VP!}ldVUxvDlp9h@$u)SKy zX%mH#i}@qFZjk$wJ}*}RXTQn#)cKY9?&jK>3U3209lid%nx-aYer=%M-Ne&FqBB*i0=0GAbgi7_aJiZT?m%sg%ecZr ztFgi5Zt%D~UX0tq_kFJXR>ie&(USSai_oK`+EwP_o;A0*YS!H5^0{m4lzP5Em6BIF zW-jyw#4Thc?ggC%4s}79t6VK#QnA8Ss#ca%lsT6zsi?149kWGGVw=A{;B8ju9&&-- zUGFWft81)r2O5R-1mi}t3{F}nokY+wz8`frpep#9+^cIFR#G~xeh)XA{WVv@uk@4WZmw4#D`fy>jd$I$MptFPk0F+{1e#g` z^Ay+0#g2KTN~+S1S#W`VyFPMJB4d*C8 zfoQ}CX{{*-+ES@^A z-|3ibtVoxS!kPF?b8d1{X{{d@>-hYEr(!OQUr^^>t_rw=lxg$w*%FPYyA z$JHx7w1gjrR)Guzo19&wAdVPEq4?N=KY}=;8w+OZZZHD!4E!w!B$Gy`&3uVNbru@o zFvt>TLsG+SwiC-XpwbenZLX+Yy(Un(rq&n0GHJ$W+#z*&!JTq>@me1&Va(GV2|p?{ zOY$=nNOR0y==^lIEOyKyGm=RXmJKq^d_JtHLTBXyhik!-#kA-KkMCJ28i|-Z zUG!{T%4f(xNL2j6VA8C!-qH{ei@d(nfT;BZ{H*fn(N~ZXeXf-=Ya6O5H_WYVblvW* z4GiYe5_CF)XXey<>ygQwt!qrvpSr#slwylL9tv2vVPRckwY$#Pa4~#x2dG19UWK>b z-GmflN*JlzUE!j}n%l@*y2~B2L?+ai>KcVURTcR%DZGA=^)|CWX~F7B+i0bZ`YDOM znU)kC`NfqbWo4Y!Rl$(9APRUv%xY{2R0ptS=`ob<8?08{H{?M_flRKIb?#O#xxk#r z*P@*?$YTY;hMhX!9J$sH`ISE>LmIvL> zS%$JoSS*G!)_rDBmDgE_+PSL+fiqQ+Z zUXkTol=RA>kKa@z2u-rT{{AD-vPv?p6(xN!f69|KKHdM&`1vVJXvqHZ_1~cC=9o*vc7sb% z?6Q9w-k0d1f?mmV{pIVfg4eI4?x^d}b{U^e*-wYJ5UzQ=3r)7M%=mJ26HGtp8VtdGZP(T)`BNB~nr83CF1?Q_n(b7zu4 zUR}QRR@dCMm~+nlJA3c5&%XPfI}`pzURY%`7$o&FN;gV0D!hn8N(Ca~5gjz8Qn54& zpZU^QMr$IJC5hMfZkWVJYOB)G92XF(kmDt5YFjv+kEhKPa3O!myZ$D|C%~W8WKip~ z*s}Pn2eKZ>dLZk8tOv3l$a)~_fvg9z9>{ti>w&BX{;53RPy+8Nfi-a@&^e?895E#* z$CaQ1eS4nh$I!P>KU_L7fs1vS6F4x3`kU@}d6ST}KQI(ouR?y;E$TON#>mq z^oFjLBRkh(?m*uk&jyAjM>d2Wn5j+}ES(q#DduNnXupey6+=Yn9lwEe#W1cI2)duh zj7qmWWWXHVp*--E$V1-80E!y$5d(ZrcW4}g$IK6UVgDx0*6t%#_zp94M#J(6Av#Ki z4&Dvvv7nN}8scVzhvc+isih?1yNuvr5>AT8f~7gV z_Hon;*mIy^+<<-@!qA2$SIBBy2nbPyh%X ztQwpimiN%qgEFng7}gw-eW34V$SiHcDs| z?T+U5$RC@x$sg}n3j&15sX(MhKFRq-Y#So*+g0+(^&x-mb~=$7G%<0>SY~q)OX;2P(*=^$ zlW!pqoBktA9~*t|H~&`?vlSjexU2~$+YoZS6N&)p&#_2Kujv|eHCOFddXbb6>HYFC zbH994djAQmDYQKbud%ctf*g(y#d3P&57w^vVDzfo9dlT~?4Sco81X@Gz7b5v&^>Ah zVN%u3xm*=m0!ZkNn$J&y%6|H0)lEm4n~u^1bD`>kOOcB(IHnr77nH)lessBkfi(wU z-vMD??iXO+pSXhmsC_>?Z~MNHw68g7U%WX0^O7cx`T|V6_w$)peBLHrlr(Xa&O}N- zNec~MfQ1u2pN0FX&o@Y)2Biqnr_j}QArjVy5@i6X3!CsmgL3kYSik90kbLcPrn2|H z%~CXFv%8x4rBF6Itn{5SQm-$5lY-rrA+L?VN0f1+()Y zwNy7pbB{jNnZMo4s;LoX_-xH|iEo4n`xUVs4vs`=!;|2zfDrEgDZ0Y_-A4+Kn=h94 z2jVE%)~_vD*tGRd;4SSdZ$V|*` z+-NN-zQL^<# ztpX6|t65f8R$I2D%zo=FOKR;(_mPQ69aPC}g*`LjF|6g8*w%3O0Ur!_wFRg$BVjh%ZJ@PZL2^efrx_3{z zZQ0U0on^O`EiGGCw)_s|b<%yO71)>PBQ_cIqEzJ2%>*3_sE+6iU}`qkZWqf(+rKM@}%z&WkbNQ|u(%F??{?W*Yv2KK?{7D?Yfu?-Q(_VABZ3L_SEc zUlWX;mN;D-!G26I3MWptj9?EF4B7~~DuS)jU`$>S!5Z*^pgkMt=K`-FU=0T*0A!ST z1T4mfcr*x{3Jf&|9A|o{9KpZm9cPXSp9JV$dc^#^d?c{z2pj->g2xoAb^o?D={qZX z?x9*d5RU!FC|Y-fHH9`SmP|h{g9(>jdMPqSICl4k^sHn04q#aC!_Zv`(0a$7Kh6-V z34!4;(D9&5PP76OZEaG5IaA4*B;6LmJX`TtGZE!4TCa5nFp_feV_*lAuxXY|V?e^D zBDKpn6f5VngOf?HD7{}F3lb&JAA1E0gB>!ShP@Ns9fD>ovqwNnwQ{~fIW$1eulUzH z>t&+oy>L$@vE%OXdhC6?mxhEL3=)pz!1JJwfWi`@^zqrSYY7=yOp=4NI5kFO5in`XeKR8 ziM-wXNC=sh9tS}Q2GT30jY{(r6BDE^AsO3iXE_?v9!^f1OBS+4mqSdo5Jn-;+?k}A z!&M7$)!2aoE22x}koONDkD9N7`%Kp{4$~EAHUS!MQm*Ao>^H?ueX8YDJYhG7O(sw! z%;4hlgkxJtk$~y%<)n}4Fq%{kzknSD#9qRiqRj1Bh;Zn&vBXDrhp2FT`6&uPIoe-p z+DL74xYU?Oyx$|Wjqq8AFza>s>a5rvjCao` zY}O&cJEZYWV!Re3F(C1WL(4T@+*}y%Ce9ldym8KJHeB%zwo%M_I+57tEYx{s7%a}5mNTmuNFJU9bw9%3{iqG|6@rZhH$1J6sQ2idNj&`nK{ zo{t@e0OfmmLKi`?UW~@{*w=Bp49gL=h7VuJjC+Gi4#%D#3u!V0Y%bJgeTq_52XvEr z=PzW&I|vXgQM8me9TYp`S$aV1?1Y8le%xycgFxGL>vNe(zXyyZ3=Q$g5uEApJQsTz z6`3fC#K8^@#jxc~&(T~PLjKX{Z$*FbR&nApI4_7NXLc|GuTW^k^amr9ruw4!3}b31 zA#`eDa--LcGLiG*AjA6t1TO|OIeP%n;@ICKA5yD=!AoH+?OQzbLkN|ahkEGrik|`D zJY>K3E&b`#3asyToK8IpL0gqT&1Um9)0Z&E`jC0U?FLkWrW}lDqi+>Cv~#mUDK0Dz zNVw2a7)xO}M9rXsb~`f_WMt~II#YvEcRaVVfT^cijdLI0-~E-aV3CLl7~T3?V6G$TNcm zb(f`t5oKNEeO4Dz7ZGF63(HiONW502un)>-Ajc5tC$VQBmWC7~Z);~}x|2sJLf$}# z@k$Y5<04hOjL62BYIodV{x01Csz8frYvMbgu_RnI4%-?BVAmr4{(^m~e2w1=OmEO2 zX!rkHO;s(@}RR@uxvf!%;TrnhUq_jT>u z^8D-?96S%Z=E8VkSFYZ!Q}dWzr>RlxI)=d)Y?lR|iVv=UAFu%?{G4Xz?zl3|n6JX= z4-r~T8(`p+Ms{XwY7xl6>o3+%5lDL{0tN5%q)jKik^(K_jf)HdkluztbRS`UN$rwLjvpoz&>9{S^RTq_y-W zCuq6^vn0>32{K_Ar zH%=^C>1~sS=|0kd=)~QMZbgpAhgB!IL9mj9)j~J20~Ar!I*@L1B1!8HX5kf2;iQ9`$lU0*cE4W$abDraav8cBR1oekVZq6LA5z< zq=HR@^5hzhO(UpUbCY&8kdhx69M9#2W4|NhNz z^$u(Zfi;wB!*5SA8$!cvSeBwK-_POLeYEDoY-l2=rdqlIhY8CKfCjj;(Y<^m12%v# z)qqEFd`U8Nqqi@VSLlJ~wi9>eEjC-?fSrwL+ltPynx+@b2>v z3$Z|-^2dX8HmTj+$r^S?IJs{Jt@Ep3LylC@T3UumOsnv6N(aRhryme4flx z;Gk|zTrz(zgyKP&96{ZSzE+sV$pZEcj<3shY{CRRV}Mkjbtt3ga8y2Vz8wiODL#}? zCX;4R(4wN~&2!(ud}XwXP!k4@Yv=~51Wh;Fcu~)e7R-O87%|NT3~#6Llt`m#G@=;* z!=pB>ziB*Rc&^`g6&k*i=N@Flrwa+Ml}u9rMd{XTo|EKzRVly}A5z(r~WrC~tY@78!)&p4&WId4eK-L3U4`e-%^+47G zSr24Ako7>;1OKl*FtL=YS0LJXqP;16dDbJ&^T4)&p4&WId4eK-L3U4`e;?f9`>`sWVO~m77~?-9EQ> zmAk3N-P-Q$s_*J>OMotHcQv`a741#BQKif8B3yZUyT1-REsbuUN}-3TbhVvr{+3pE zI%yhMrLJgiTjd5rdz;I{b)mT&ZJj<>gU6kOlvUWPYu$|=S4(RukdGGKQb&AzP~+<8 za5q&i9uBd$d;N7Cu102_-Q{6+*j;zItyQj0k6)^6@5HQPFyGzg_PRV)ySLr%ZX^{2 zLY#I;(gL@)&F!(aw6*wKT%MNu+)Y+rXCwUMYwq-Tx+Y8ZvPIPulP6EM@)a1*8_95A ztz=kjFDHdrTc*&Ou_$6!`}|L z@=_x4L<;_U8vcI3cLD!&3jW_T{F8t$3MCR(>+vpzX1cuycs=kwJ>J-+@gD$uEAZ^g zsG9!2(eP)0FYQYtu7$mteWR{65W(dDT@LtyU5Ugy=xcc60gZni@cH-#e>4UEXAMtZ zdEW#4UsLdJYxw(t|Mu=g;$RB?Ee-!9@JoJ|Nc;<0ZT?aBY5Khg__O_q#FP~LBn^K6 z@aMvb1ipimGAg^@s}GVX&>;49&fB*1k(VU2mD#!uh-+31V=rb z6EO8$upxJS-h-ppjafUEXjg*PFmQgf-vw>XdC-pQxYw1<=<&uAn*1i< zKLY+TJ^q%YpVtFF1pHU@ct;Yy1^C0jvp}dz&GgmsgH~7I|Te!UP&bI zgOp?(lqdOf@TD~a@CNuY8E0p-IGO_d!B-QB+f(A~Rt;YX{FQq$?}H}b-v%B(yiCe( zPtLy{_~XEj)#Iy@_$|P{1^fegys?WBkbS#>zu^ywM7bWnCdq#Y_&b4rC`JEun*KQ^ z$apQ0xJA!zT%yUJ0{ki9H>BX#YWPavSG=A`)TZETG<*~Aj{u*Ee?9Q=bMS8g{;QEh z;#(>5zp2UJ4gB|ke=-ICn1(+D{J6cD^~=Gp+bV(2#6Jc2&^h=kfj%&;8vE5Bx$YC|1rSF z!LnnQasb<_==K3_ft+cy5V~uRpg)b=N!L5Pk*KC1Ia_Ei;qvhYKQiI^Y);eXV?qA| z@%O#iJqA4Ez)$*bW}70Z=QV(n{GU-k;$nLO?F>eb8yUVnO;-nRqy>WhA+fNEfVT+v z6al|V!0#3CCoCMm?rG?56!4#5FVc08H`0#*w?Loti+)N$dNy3bF)TNu`-XrYNb_@C zz$d~4x>!w$mVPZlauzZueyk(f>41}e;%WXY7I3RrFEu`Y13r@Ti14#8LsEqNZ?WP+ zl2{G|Z5xvVrL1B?;g5A<9YbPX72PG|&@YXD_g?7l75*2E zbT!~C{_RYRw3atgiJ+(aLDv(!k!}(2DxnXn*@5#5_%RWOPYU|Sh5S6Bj~c;LOOQVF z8*#c+yIvLWHw59+94);o;F3_B-GhPqRKWLri4(Hg3f*$V0m(lg)$fvX3c{QsFc#d!1KiZQrB^VfL|rxqLIEM;6kjXe@MU|75bD5g4YE6I+6FL3it`Y zNl%MdN3l&M`fCql?>dnH*fSz{#tHZdvA&-OIgrr$_|Ma-}rGOvBulDI;&rE24E8w-lKVo|6 z&jS9suvhilQ2{@IIHfDfJ`uM9E{O$a&(6T*kLLRPTI3%!e!c;Ewoiq_)(Sa=g5Dzb zo$AkJfHVJyxKin*a+j~AvDV#&!z{PAps}MvDsS<(x;j|5(dXwdw|Zd2z;`wISzBFM z&)SwYzuW8W?C|?Icrk14VMji?uEXErVMFJ#nKq}>=Xd#A8lBpa5Jv57PFGu#v&oHl zJJ~ssvv8H}MHH&MPIxFS6irQ*>{o>lzR@pX-a}rs3m*4G^=zOcn>uPnEc|7fnE`K|> zp1?RMtA>+S3nvk%o}Ih7+R){69j?1t+U{bCbhz4D8d=ZhZM+^1qkjc1U#kS76i#WS zdv$%gv(E1Y@8V8>N2kA7axPnBE2cS8wXw~FZR&YsZCQ;B=kSv?xvdFIwnBfqb0wSy zQLQ9oHebw^)pD!E*Q2_vxt%Cy*uCx!msgw{+KcIYlHrD{W19_zS$49>zMxUkxwC$$ zU3S*h*H$l@Uq{o~iVzZ&ZeOF^=J$4$K-tC3%|5rE^juZ~-MDH@)j2|eYAtw(NN>SP z)wnvp%j;+INAiiS*8Po6L=3r$O*FFW3Zad|=WY^i(|j|d4*In=F!3`|cEcQdr@vyQ z%PTkDeYfOIIR$2`$bHMAf^p9#4fH`#f}r7%DBD-n6*{F#cQYNH&abQ|Q|GV+CV*2x z*n8YwyKR=Xmz>QMh(xDbRGk+pTf8`G#fdcY^&D7N<#F95&#~7#sY8r2?9~-cL`IFv zhYd>Z&ET499LsWR%q{{1dlXX5A-YPX?#Ql(21=1g6Vs(%k z*oxaq_&GB>b3Uh+ie@cvcQv%TyiHm_orAs;fuPf9*veJdWP6FWoFi;eW=Lwd%(7$K z`DNN7!?yxlC$<9Hmm_WNV%2HznM5lh4$2|THfz59vt6*rmZngJ$BpQ{o2fICtVt#@ z7?@EJ+w5Ams|nkjdk9Q&<}AvDj}QX38ICrwXJ}@!iM*1k;mk$u)jT=aW+yG?8BLdx zhBMOo*la90Hgq;OW9O9E>#A(ds>O?FYmFS{GgCC;p_z#mNrk=jN$P&y_Z6w7$?s)K z3=gZKl(2Fxo6*wNKzn*lOS|)4SBrlnCslyy9JbDGb+;nL+E=aAEokb-wNdUXYih!J z_>dvzd)gaZ9_65A1gHds^kZZUT>0KDlX-Pq?BW#)( zMN%iWNZQ>_=%dyk%ya3{TEwDtW_zcgb96ougDY^c7aM=m_p zq+X)X*Zv5uK`uWK+!;aB-eIaPAz{$}R?=r-N=>!zEl znQp3T7I@t(q_DO+?g8d2IT|8RR*dOQV>TW-xwmED&%ukfFs zwq+I!IAo?v{>2tP&1h^jrD*I~Y{h7atrTN7*3E0CwgK%*fp21}?kp5|8H?J^8?dj$ zR#|}|G2eB%1gx$PN)M5Mz>ouV>dYNuujURRyMD8Em6GK)=iDj zt%4DEBW9l0G@OwyMq$&(YtE;DDjFVD;G6kkr@*VRj~rxSIdI<&%Ai}j!tV&D1taRN zc`N3w$5wM5?3Swjxk$uSD=KtcnP)=Uqnvw&5I#o{eio15v~g1@4)v zl=vNaP=(UHvj86`tc(gPL`7~z4r_vJ#74A?4bJEsiBN3hWp`{<(~pfvimlW0i0kEf zUBiYB`nVWd%E`3JE-?}BEzlUMHMZ0ig~(A_q}s>J&aZjCN#%y4XL;4R9<1|G z>T4)tFmtJxJL9drlz0bBA# zATC~j6r#*msX6H_=u=uq6`=pn<40W8;}y}~tFp7V^F`5Yxb5dM9#pX|mg+im-T8aJ zZlGIHIec~K9rPOr+da)qg=GWD95~jX|T4>(|jzoKJh-q^j+M)Kg=rWWK1EWE5fgWcLbbJy??%x+V|2_ulxLWl0Qe6Q}!+W8YvtG^o!(m zniW4T%q6pTB3G^Kue*C0##;O=HrRt$J_HLT;`5KqqZpk5eUU?8G&jQ+B|e0iMC26n z7Z{{}Ru)j?5*Xc`@C}KJ90L1U;&Tx!AR>2|=_^S3PqYxqn8+FCgRm$3vb=)G6)Bue z&yHt??5T^kV>^0gW`+$+Opl}|6vT#KA50wIrIqaERwB{wq$ll>+~}z7Sbf$j{fXiJ zmj_>Mrk?m;>d#oYY;r8^@XV!4O}sVeCge%W8K25>>s+Q8nVhiU_Hq-dPf+62X7q_c zdoBw@h$HJjY21hLH~n=0IUws0#^cZ-AzG@4y&;|rT=m1-AzbytVhC6L@MQ>B{ZI_y zsvjyLT=fIfXXhug=@HCX$D7C0%CRTXdKM{Q`o(lM&GeDkS*B;ECnxPGU{ljsTgNx( z*laePc~|b=nab%i&h(7!WapVKJlJEyqtr7pf_t0dFsD*b4T56G%~y?ARUpCK6L1KF zR1A!uEXo(VM}iMvrgPN$-YxORBrabwi88hwI#&_0ZPb=Mg%$Y>+gGK%I!_sd_X!Z> zQ^l$Dls$bHgQCt?^J$Q39n@>3ACx8%)_oB=Z5ZLaMx}i?u5kP#uqB^i`%}`s4lXER z`?o+gtKUtj__Z{q`Vpk;RsEWsO(s3Eq2ltw4+5hah3)Czi*W4#F^iG{ITlJ-Xp7&H R=Jv12|63-6m&PM(|1XB&=7<0Q delta 922 zcmZ8gO=uHA6rSCzo6RPsYb+)vqFAIf^(0D~Vlfd}8EKU&1Uwk92SI}ue_#C_;0L6=kKD^p=~xx7lpL2Q%-R?|bv!w*$M7TpqMX zK#vV~!w8j(?;fR^AwI-boQ(Cr{+hvGU5|bc~RgR`|Txl@NCaKCs7YWy`j| ztb49&qP&VqZO1Jd?;Wjt;&WRTYxo66+dJf-%g~E?m+&)%*{Pcin!RPhp1@%(igME` ztiq{4eEi3}*^n%=!I$|-)49E31n#Y>#pnCeROnf7vZOJzdA{6Pe+X>@|oSL zd^Qr)7(0N}1o0SKwE6mPU%x^;#xvS{{i&}%ARgmAZNC1-*Pj#5Sd0x*>KDwQ4qrnl z;Ob>*5?-nC8P_0|Jj4}a5}U$I;TpsI0vGXFiCE7N=8w3D|K{e;ZkTr zl3`TOgj&0LY65QPS>%qX`=F+$5pC)@+=s$BDd4h|a2nC;a83*KuGHX9cr4WM8dM-1 h8PhwS)?rYJWc0TC&oH*l;9VpWx~}$a-h{XMp?`ER^kD!1 diff --git a/kernel/lib/Bitmap.o b/kernel/lib/Bitmap.o index dd11b57b7bbe9ae0c2d7e7b08515b259521efd7e..36556c499d8e72cf2f10f0c238a0740e2b0c8c4f 100644 GIT binary patch delta 226 zcmcb>bAxAs24loTO&R9qHwqJ7a=A|)o)GHM`P8HNjmE?sn;1_{&Soq$E@uD&M?Qfz zCTCtYrlMm!>>La-Kp`8DI1uas5penKAoSSIT**+_!5164=^u@D0zLj_1V z5bT-U$P~|5G5I0Wc}A1T8=1|SN*E^#GKo!M(SWihJFsXlmQ2oMv1gh9mYRG3C@^92 kOBQ>^1CupbL1ZS7l$g8{NCL%K?KwX%K}=7d{E=B60En?T0RR91 delta 192 zcmcb?bAe}q24lcPO__kR$V;rfGr8xU^~{qt_Z$-|)@olk+%5}iNN zI$huJZ+CsudFV}t>wln{|0gGwGz7^r0D&W)KpT@YFI&_x9(E1}1{t7`4M-dart^&6lLeX08M}dIi%(8q)_}4WfLSM*?HQMYWfWL67*|a8WU*(wF}V{+ fa!fu6Bm*XMvf48~nC!`F&lvzR76{UT=E(y9u_aA8 delta 254 zcmdnNy@7jz2IGc_n$iZHzdAppb%y@waQ(r*4T!gg{&_bc_Hd|2=hMy~X`QZb__w>h z={)qN!}UK<{(tPmng%0j1|V?c6KG>{=4A`xVdnsHWq{ZQBn|{pAOa>I3X-3!$0)-L zWK2HDBt1EU(Lobz1W=U_7&9`!_+YI-F%T`pz{p@a`66RHqx57$CUHj7$(~H-8J#Cf zGMh6tPYz_Z2a*%P!DOfk5)YRjLKDK9=z$ngPsbt#Y;e|At35O zly_1*D0o#U@nA)GSTExwe2mMg@*ytwtDobtPy6&o=9@pY8o*L>GVva+ z41o}0+%T^xN3#iaAH2yVQ$?~4(O|Th!d&^nvEckP`-C;7C~rmiCH4tjrYQd!<@eba z;(+Mz6cwyS1uxhqH2yl^j65LrQpEwTEKUJd(UDc}4OG ztdoCJ@>9vLBzJH%>l7Yuqb&)%nL#7my&o;Zff30^mSBo?sA)BAQ4})Rxq`m;E_eQU@ILq6`@Y}f-CGV?!My`|B05-U zpWds@+1Jyj?tZ~F-Alq5<6{z@$gC$}kX;*wox;dhhCVQT&>_e*TIrhr_n7$A$ZZ_YqO0E8G#9 zctw>f*e14xJ>gg3G#Uk8KM=kYt_Y{lrutQ3OZb#oeluK>H*v^!hMPQu=lI%0ow!GM zNO%DYj$giLQY#t1a>*$9E?zCr6zVC7#67Y}AW1fkU#E z@Q=ER1yYm4_Wx6>SSr$q@x1t%{&dlu(h6NS)X(5~p@ReS&*}2IGl|nlckTE!blZPYCtsd^)kmi7|HK`BEc$1|V?c6KG>{=4GqmVdnsH zWq{ZQBn|`~AOa@OuxK#8n4HOC&nPi@C6F|j{1QkOOx9$z T2Z^)Vb0#oB%ub(N$Se;4dG#{g diff --git a/kernel/lib/interrupts/interrupts.o b/kernel/lib/interrupts/interrupts.o index 9cd6d79b88ef52f1d1d55aae221cc498e8a16c73..b0e5086e7351b8087eed5391a91d3435af287a17 100644 GIT binary patch delta 1061 zcmZ{jO(;ZB6vyu!2Jd<184E_fRy4CwFY4Jn7D5&%D;wWMiIS4g!-{N%v-eRJtR_uq zc1$TL3zm{tT3C=MMV#wB{G&N_@9F%`|D1E*$K9<=Rm7vRVJ(&}J?s-gyxs98mYWmi zL33i|*gp1FHM~{`xNu2$SaZS?l|v*^3z@t|bOm$xK=sf=C1&F;r0Z4#Z9j@y)Gc(pRGCEFf zWctn+H(8Ncp0R54OlEgRAm<^AJmclbjI82}A3&t+51=+721bV0KpF(ZAQS^PBLjoL zWI+~TQ&Aubq=FGhgMcc8Vo-;Qt3kzoLd8vhe2`9&$rD)*8@uP^Cne?trRJri7Nr(3 z#7FrV8apKxXC}jhOaqEC^GaL;ypw^F#+i9ZC6n{nZW^wIn#KgAIf3}ke+bxuB+d+E z>q7YlCMU9sOP+%ASb#J)5W{p`nmmzRy#5!GEH9F*0MrK{UC83{IK)9d1OaqgY>>nS zfbuZg-5}!i7#jR=Xoy7;M|MyWk~p#jg-GJa>dTPC1sLiPE^0-RK-SQOB#vysOeAq+ z_4AO#k=3t75{Ij=2gcwgBne~<2a&|#8i4ALA&DcazltP|to{~~II{YeKyje|A#sMR z;T;YQ|B%Fy)iZ+EEf|sk>5SG zK>X)F1XxcNWEPing32-hX=Wr@-^qo{;*236HH`)MOJ$tnFu6TOkM~iPfmUaB%e-JWV2^{F*y-PN=#k|Bxg*12qXh0E3(@& PI!sOkk{c#3WLF0O?v+2^ diff --git a/kernel/lib/kernelUtil.o b/kernel/lib/kernelUtil.o index 51112a97a320430d5c9c50b32e5de4995871d938..d26aecac561f6d01dfc20f24706ea4f862791489 100644 GIT binary patch delta 595 zcmYk2JxBs!7{~8D&+{ZJ^-ix7`>-Wlaw)8(L!vk*X-IJDYY18zYcNQJK!hlsNocUK zt#D~*aS0j(hb~8Md{k-Q6T3Yu`j#s=sG!3j20-4YEwxM_z%SSep!4YED%2- zA2mg#$G5w<%df~s^-<~Z#qPX@8UepNV`L>_&J);8JfgsaQhiNc5m_7>iq6{gCuLJ% zK1c`jm_~6_(`9!N+b|wli1Yv~pc^k79Ygo`&sH0b1A6Aip)`D)qaJ4)Y6|BkIDe4y zC*c!kO*@n}kvW=ySWq`|9QAN?1D23(ag@HIw`T#0!3kD^v)~TPLQK{1KC8a7Lx^c9 zZ_S5M)DWy`De+E%h8l)*E$(eP&sp%QrC1Y;kjX9~kM$9%AyfRaqn%KkeS;A;@dxLz bHlZ3eML~w=@Eo(i&`s~EYLD21Q*HDgl*yO? delta 536 zcmZ3W-=IH1gYm#d&9lt>cRad7pLle#G5~=`r|4t>mXnjOv9z%8uyZg>j$@UBFdA58 zltCggKvgv$r9kiiL^$#Zv@tpJvN7ETYuL{!4bgCqRfZWTGWnsf^yCX7ER$u}Oc-4z z2eOGXR&35>i)WHl0OM+R9ApnnmmEkT5P&FtAcl!6PZkss zm(+sFf?UFeBx^U>5h&}8B+HH@8!@>MC>xI?3-Sfbs zyfAsEs6Epgh*AMD4aN_XEye5^6(&~#$qkctirF*$V4eI+%#P7vvZc5^r-LxWhT6#o GMdSf?OpX!& diff --git a/kernel/lib/memory.o b/kernel/lib/memory.o index 7bd77d624892aebf7037002f9091cf838b21d173..c41b43adf71fe74d1e6163a3f57d264de4431735 100644 GIT binary patch delta 257 zcmdnMw}Wqj2IG&3nljAIZ!{*lRB)X<9O}{e)C0sjWW#uJ;{Q_PCI%pI=3^2aiWKX7kM)AoX znZy~D!DI}WOaqfOAaZg5vj$_+(*? z_CV5;)t*TOBD{cAgHdDhNuY4VWKK2^=?Nq^Ozs4;PqNu_b})mS%fOHWG*cb`aA86k delta 232 zcmdnNw}Eeh2IGf`nlckT%h_TNhkA5Aop{QIF?KRLW2s>s0}wd!3A8ae^Rh8j^00F- zFvtLfY(U~b-~=LI^0h$e$&4)0lTR=fNP=|&CChx>5`N3xhR-k3a*#eQ-+i{Rt~jO>$NuxKzcOcrFd2aS0vp+}-cvYw$q_?*CrS@1Aq+x%aMi zZ**s)a4&b@D2(MU?RZYECKeK29EO|jne8aPhe6zNm2se<3(vV;7CyNzyZUCfy@|}! zuf#%wM)vMab|{glB>vBf*F3kU=Yitl{@`8Li58E07Tz}R_I8k~kMog@u$bI6#8_iK z%6_t07K^7WKFNNv^DGu0u=o=DHEr54L9w>MF~Jwb@AGUGn6nC06_zD@^l=bBeE-^n$!)Zg&F#)Dq_u(t=D$L{6#>heWhLlLY z70o*|LKx}}oaI^6g6fx}UhDA*JgweT6Zm)GrOCQDa{vxJ{ z`sEi>_d#?-(PdomiQcNBvKgW;6b*T5IZgjZ<&T>F0yIs#A%bbYFm9-h`5etOs()%0 zz!jp0D3pz9fQCt9SoRAzEA;~E0RdxDpJJTW-#8YUae~$Y^Q8Nwc43LuM_7$1H|MQo z4$^F9evS|n#%mk(+vtX*Uv0F-Mk`F=ht%IvgP7C>oWXU*@FIp=?`-p z9u|*_y@MiMyuR%lEh8=N06}8|G~AQ2|4oHu}IpjG>$6y$62k1e(qcE+(EP5xdgLAS_>{3 zcF~HWUtF}!MK_p=pGto#4I*PoF^o0pc~f6?<5})OP)=599trZH^o^>0r}P(!rnD0J z!nuQcS7TVEs%xl`-d6emv4|8orO%Nf|23<%;p))k+W8(=S*Csul->=-R3-(<08+%Q>^)t*y;31Uh5WJP9q E0OX%5@c;k- diff --git a/kernel/lib/paging/PageTableManager.o b/kernel/lib/paging/PageTableManager.o index bfffc952aa0650878d031df5c2995410f35ede48..6bca8bba24af0f12da1f206c9a80f1e6bd9cfd4d 100644 GIT binary patch delta 513 zcmbOsJwtket3>k~0gukwA0C~hA3VBUe|U6lNm~e7qq%`y73g!?YIR+qb|91EC{$R#mZg2h1-tOlse3W$Xm7(qI~045#>OU`6P4sppgBw1uz=1dOc5NF&3CNF?(`H7?w*)QCaHv-KO zW`Z~uS&&nlu^3EFob1RcE_oP-%9~&{@4=+VOg`40h2lMR8gT}ZN=NU}>NCjw>nA<1$h$zGW}kzJhe6`16nd=RM8 z1nL@eTihmp1j_m$$s*g5FMj2a~;%9XZ7%_v27`6|Ckpm=u`2kkg(~YVt$Q f>x^QPcXE|8hD|o)wg-}hU~(gnEZY2$dpRQjIjNV% diff --git a/kernel/lib/paging/paging.o b/kernel/lib/paging/paging.o index 673c765a5c28c23463881f26a67b65a67c4d3ce3..eb34f8d2eba371544249f7758bb43f0f2ab2a9df 100644 GIT binary patch delta 411 zcmaFB_knMM24lfQO&R9qHwqJ7lDJMD4)y4K>H*@dF+=b;Cccp8K6!WoR8n9vAEP(p z$;nZSMfEuhK;XzH(8lD<%f^&`jE9|rK?W#f0}=-U2M__1uLetl}-3k@I1{DvT{E+EBW6tD*%;J(TwGB`?CLj&M*Cu~tKF_E<`5=oqQ#RvdM$h+?HPAWwq&zsTrs&4NCr&a2_%0^{>f&~$-x4# KA$>9QWp4 delta 422 zcmeys_keGL24liRO__^%*)1<%)`#Xz#sz@vH^($0hor# zmxHCj@-Yx;22~IZlTSd%*Ffb1k>#0uAPS&zKx%Rw3-4qFR+h;*Og5fiw*UprfLMru zkpaesxg{Pdz63~v0N8FI-3r7Y^`}6BKoB_jBh!7xjL8?7#U){C8^AIQ3`{^8gilRo zWI4|$J^3PwIa4&__knMM2IGf`np$SZ9aI7vjQmwkIv&Sz%+z=+(7{-2bVk!l49^U?!Ymz zE`H*J5aD_d-;qzCjmeppjj8Gw4?D-?i_DUf6Br{H>nHDI>|-pO?7?KgC_8y0lQ^U5 z8Yuc=@=G9JVzMTiJ!8V;OduIB Uc_ok(nEaB>o~eR)vKEUP0FX{lkpKVy delta 289 zcmeyscY$w$2IGZ^np)cX7#JA-dvqRu0i+o`x>-TgaR&*Y;C~noBm@*=nb;XW@oBhF z35e^+C(y>^%*)1<&%@3!`6IK`kV%|Td2%6; zGz62bVA5wYBeS?yxWt8wUpPRORVzoj;Rv~U03{<)Q{Z6yyj)@!kq;CqVM4{fX;fOD>UH(5))OT9Tu zVE1lo&*q-I-}@K(R+ks7@{?x(S|vX>Uszl!Uc2}l zo~~7ME4o=4RIb2fkYOT`h{*#J>Fgz09Z@2RDo4VR(XbjG!m6#vGV%#z41oYh9|+^S zNf)Z&!9tbQ zlB4M;9ov-!)@-AwDUMNfK*?*428v#(fMQ#&k+VuA!$hBHIfjBW3{@O0w--zN?l<3J((`Lu=2=KoL> zdqwb6It7IT`Ak&Qf`Bc+CdxYS#$j3j|VO(XJeYYZc>|}|>d(H_E4z#3-sPoY`J`;eY1u25TjjN4xkGmCOh5Bm z8{2`5HRP4!krL@T%Ui=NiiNt_;Vt8cy3p0Mk>ayZy zS7%pmXS}l;8nB*;gL+~B)PeDo7{7Z%vyY&U#Q13xjDLOnX z$O*^w-PPQl?=IV;W8ZV<{xR3ddpSo6JDUO!_?#qlIO=iyU#ZHE1W|OpRK-50?~LP1 zHTb;{KY;o>RsX)?RHG@x>7tWR-*Eh&KBaFBfIdd9^Oxd!{6C@ik3#V;L-F*yT<2AY zQxE24#fg0!;?3#<)%$*`xV}$Q)uDJAfmq(+taMUfdD5+}S=L;Ub1aEp0azJFI$)(d z53F=yc2?w({jP`J{u+AEcO=MUO~l z6P6)m@cm>T-($9qp+fIwh=E!+=rB;SDuLcLsrL4;YBR!w)vVL}mU`svF Zzhs0&l?_NcYEk)pYX7+)va0C$?*V@VXrcfB literal 0 HcmV?d00001 diff --git a/kernel/src/BasicRenderer.cpp b/kernel/src/BasicRenderer.cpp index 0f6810c..c87c1d9 100644 --- a/kernel/src/BasicRenderer.cpp +++ b/kernel/src/BasicRenderer.cpp @@ -25,6 +25,15 @@ void BasicRenderer::PutChar(char chr, unsigned int xOff, unsigned int yOff) { } } +void BasicRenderer::PutChar(char chr) { + PutChar(chr, cursorPosition.x, cursorPosition.y); + cursorPosition.x += 8; + if (cursorPosition.x + 8 > targetFramebuffer->Width) { + cursorPosition.x = 0; + cursorPosition.y += 16; + } +} + void BasicRenderer::Print(const char* str) { unsigned int x = 0; char* chr = (char*)str; @@ -42,7 +51,7 @@ void BasicRenderer::Print(const char* str) { } } -void BasicRenderer::Clear(uint32_t colour) { +void BasicRenderer::Clear() { uint64_t fbBase = (uint64_t)targetFramebuffer->BaseAddress; uint64_t bytesPerScanline = targetFramebuffer->PixelsPerScanline * 4; uint64_t fbHeight = targetFramebuffer->Height; @@ -51,11 +60,39 @@ void BasicRenderer::Clear(uint32_t colour) { for (int verticalScanline = 0; verticalScanline < fbHeight; verticalScanline ++){ uint64_t pixPtrBase = fbBase + (bytesPerScanline * verticalScanline); for (uint32_t* pixPtr = (uint32_t*)pixPtrBase; pixPtr < (uint32_t*)(pixPtrBase + bytesPerScanline); pixPtr ++){ - *pixPtr = colour; + *pixPtr = ClearColour; } } } +void BasicRenderer::ClearChar(){ + + if (cursorPosition.x == 0){ + cursorPosition.x = targetFramebuffer->Width; + cursorPosition.y -= 16; + if (cursorPosition.y < 0) cursorPosition.y = 0; + } + + unsigned int xOff = cursorPosition.x; + unsigned int yOff = cursorPosition.y; + + unsigned int* pixPtr = (unsigned int*)targetFramebuffer->BaseAddress; + for (unsigned long y = yOff; y < yOff + 16; y++){ + for (unsigned long x = xOff - 8; x < xOff; x++){ + *(unsigned int*)(pixPtr + x + (y * targetFramebuffer->PixelsPerScanline)) = ClearColour; + } + } + + cursorPosition.x -= 8; + + if (cursorPosition.x < 0){ + cursorPosition.x = targetFramebuffer->Width; + cursorPosition.y -= 16; + if (cursorPosition.y < 0) cursorPosition.y = 0; + } + +} + void BasicRenderer::Next() { cursorPosition.x = 0; cursorPosition.y += 16; diff --git a/kernel/src/BasicRenderer.h b/kernel/src/BasicRenderer.h index 877dc2a..5c08eeb 100644 --- a/kernel/src/BasicRenderer.h +++ b/kernel/src/BasicRenderer.h @@ -11,9 +11,12 @@ class BasicRenderer { Framebuffer* targetFramebuffer; PSF1_FONT* PSF1_Font; unsigned int Colour; + unsigned int ClearColour; void Print(const char* str); void PutChar(char chr, unsigned int xOff, unsigned int yOff); - void Clear(uint32_t colour); + void PutChar(char chr); + void ClearChar(); + void Clear(); void Next(); }; diff --git a/kernel/src/interrupts/interrupts.cpp b/kernel/src/interrupts/interrupts.cpp index 4cf7d17..bcf694d 100644 --- a/kernel/src/interrupts/interrupts.cpp +++ b/kernel/src/interrupts/interrupts.cpp @@ -1,6 +1,7 @@ #include "interrupts.h" #include "../panic.h" #include "../IO.h" +#include "../userinput/keyboard.h" __attribute__((interrupt)) void PageFault_Handler(struct interrupt_frame* frame) { Panic("Page Fault"); @@ -18,10 +19,10 @@ __attribute__((interrupt)) void GPFault_Handler(struct interrupt_frame* frame) { } __attribute__((interrupt)) void KeyboardInterrupt_Handler(struct interrupt_frame* frame) { - GlobalRenderer->Print("A"); - uint8_t scancode = inb(0x60); + HandleKeyboard(scancode); + PIC_EndMaster(); } diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index 7f792e4..2d25849 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -4,7 +4,8 @@ extern "C" void _start(BootInfo* bootInfo) { KernelInfo kernelInfo = InitializeKernel(bootInfo); PageTableManager* pageTableManager = kernelInfo.pageTableManager; - GlobalRenderer->Clear(0xFF191919); + GlobalRenderer->ClearColour = 0xFF191919; + GlobalRenderer->Clear(); GlobalRenderer->Print("Kernel initialized successfully!"); GlobalRenderer->Next(); diff --git a/kernel/src/math.h b/kernel/src/math.h index a14daa5..a83b255 100644 --- a/kernel/src/math.h +++ b/kernel/src/math.h @@ -1,6 +1,6 @@ #pragma once struct Point { - unsigned int x; - unsigned int y; + long x; + long y; }; \ No newline at end of file diff --git a/kernel/src/paging/PageFrameAllocator.cpp b/kernel/src/paging/PageFrameAllocator.cpp index e3ffb9e..52ee19d 100644 --- a/kernel/src/paging/PageFrameAllocator.cpp +++ b/kernel/src/paging/PageFrameAllocator.cpp @@ -33,7 +33,7 @@ void PageFrameAllocator::ReadEFIMemoryMap(EFI_MEMORY_DESCRIPTOR* mMap, size_t mM InitBitmap(bitmapSize, largestFreeMemSeg); // lock pages of bitmap - LockPages(&PageBitmap, PageBitmap.Size / 4096 + 1); + LockPages(PageBitmap.Buffer, PageBitmap.Size / 4096 + 1); //reserve pages of unsable/reserverd memory for (int i = 0; i < mMapEntries; i++) { diff --git a/kernel/src/panic.cpp b/kernel/src/panic.cpp index bbd1da9..ece1571 100644 --- a/kernel/src/panic.cpp +++ b/kernel/src/panic.cpp @@ -2,7 +2,8 @@ #include "BasicRenderer.h" void Panic(const char* panicMessage) { - GlobalRenderer->Clear(0xFF000000); + GlobalRenderer->ClearColour = 0xFF000000; + GlobalRenderer->Clear(); GlobalRenderer->Colour = 0xFFFF0000; GlobalRenderer->cursorPosition = {0,0}; GlobalRenderer->Print("PANIC!!! "); diff --git a/kernel/src/userinput/kbScancodeTranslation.cpp b/kernel/src/userinput/kbScancodeTranslation.cpp new file mode 100644 index 0000000..361c50c --- /dev/null +++ b/kernel/src/userinput/kbScancodeTranslation.cpp @@ -0,0 +1,31 @@ +#include "kbScancodeTranslation.h" + +namespace QWERTYKeyboard { + const char ASCIITable[] = { + 0 , 0 , '1', '2', + '3', '4', '5', '6', + '7', '8', '9', '0', + '-', '=', 0 , 0 , + 'q', 'w', 'e', 'r', + 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', + 0 , 0 , 'a', 's', + 'd', 'f', 'g', 'h', + 'j', 'k', 'l', ';', + '\'','`', 0 , '\\', + 'z', 'x', 'c', 'v', + 'b', 'n', 'm', ',', + '.', '/', 0 , '*', + 0 , ' ' + }; + + char Translate(uint8_t scancode, bool uppercase) { + if (scancode > 58) return 0; // longer than the length of our ascii array + + if (uppercase) { + return ASCIITable[scancode] - 32; + } + + return ASCIITable[scancode]; + } +} \ No newline at end of file diff --git a/kernel/src/userinput/kbScancodeTranslation.h b/kernel/src/userinput/kbScancodeTranslation.h new file mode 100644 index 0000000..c2867bb --- /dev/null +++ b/kernel/src/userinput/kbScancodeTranslation.h @@ -0,0 +1,15 @@ +#pragma once +#include + +namespace QWERTYKeyboard { + + #define LeftShift 0x2A + #define RightShift 0x36 + #define Enter 0x1C + #define Backspace 0x0E + #define Spacebar 0x39 + + extern const char ASCIITable[]; + char Translate(uint8_t scancode, bool uppercase); +} + diff --git a/kernel/src/userinput/keyboard.cpp b/kernel/src/userinput/keyboard.cpp new file mode 100644 index 0000000..c1bafb2 --- /dev/null +++ b/kernel/src/userinput/keyboard.cpp @@ -0,0 +1,36 @@ +#include "keyboard.h" + +bool isLeftShiftPressed = false; +bool isRightShiftPressed = false; + +void HandleKeyboard(uint8_t scancode) { + switch (scancode) { + case LeftShift: + isLeftShiftPressed = true; + return; + case LeftShift + 0x80: + isLeftShiftPressed = false; + return; + case RightShift: + isRightShiftPressed = true; + return; + case RightShift + 0x80: + isRightShiftPressed = false; + return; + case Enter: + GlobalRenderer->Next(); + return; + case Spacebar: + GlobalRenderer->PutChar(' '); + return; + case Backspace: + GlobalRenderer->ClearChar(); + break; + } + + char ascii = QWERTYKeyboard::Translate(scancode, isLeftShiftPressed || isRightShiftPressed); + + if (ascii != 0) { + GlobalRenderer->PutChar(ascii); + } +} \ No newline at end of file diff --git a/kernel/src/userinput/keyboard.h b/kernel/src/userinput/keyboard.h new file mode 100644 index 0000000..ad85d7e --- /dev/null +++ b/kernel/src/userinput/keyboard.h @@ -0,0 +1,6 @@ +#pragma once +#include +#include "kbScancodeTranslation.h" +#include "../BasicRenderer.h" + +void HandleKeyboard(uint8_t scancode); \ No newline at end of file