From f585cf0b409ec94f6a3fe30701fd8b8aa6b31287 Mon Sep 17 00:00:00 2001
From: "ivan.pavlovic" <ivan.pavlovic@hes-so.ch>
Date: Sat, 11 Jan 2025 16:53:09 +0100
Subject: [PATCH] Keyboard done

---
 guest/guest.bin                               | Bin 3501 -> 3637 bytes
 guest/guest_main.c                            |  30 +-
 guest/guest_main.o                            | Bin 1912 -> 2072 bytes
 guest/idt.c                                   |  10 +
 guest/idt.d                                   |   2 +-
 guest/idt.o                                   | Bin 1512 -> 1676 bytes
 guest/idt_asm.o                               | Bin 624 -> 640 bytes
 guest/idt_asm.s                               |   5 +
 shared/hypercall_params.h                     |   4 +
 vmm/peripheriques/disk/disk.c                 |   8 +-
 vmm/peripheriques/disk/disk.o                 | Bin 5448 -> 4912 bytes
 vmm/peripheriques/gfx_init/gfx_init.c         |   2 +-
 vmm/peripheriques/gfx_init/gfx_init.o         | Bin 2832 -> 2528 bytes
 vmm/peripheriques/keyboard/keyboard.c         |  13 +
 vmm/peripheriques/keyboard/keyboard.d         |   4 +
 vmm/peripheriques/keyboard/keyboard.h         |  17 ++
 vmm/peripheriques/keyboard/keyboard.o         | Bin 0 -> 1336 bytes
 vmm/peripheriques/peripheriques.c             |  53 +++-
 vmm/peripheriques/peripheriques.d             |   5 +-
 vmm/peripheriques/peripheriques.h             |   3 +-
 vmm/peripheriques/peripheriques.o             | Bin 4752 -> 4616 bytes
 .../sprites/content/sprite_content.c          |   4 +-
 .../sprites/content/sprite_content.o          | Bin 3664 -> 3256 bytes
 .../sprites/position/sprite_position.c        |   4 +-
 .../sprites/position/sprite_position.o        | Bin 2880 -> 2472 bytes
 .../sprites/visibility/sprite_visibility.c    |   4 +-
 .../sprites/visibility/sprite_visibility.o    | Bin 2656 -> 2272 bytes
 vmm/peripheriques/state_machine.h             |   1 +
 vmm/peripheriques/timer/timer.c               |   2 +-
 vmm/peripheriques/timer/timer.o               | Bin 2280 -> 2072 bytes
 vmm/vmm                                       | Bin 35376 -> 35680 bytes
 vmm/vmm.c                                     | 260 ++++++++++++------
 vmm/vmm.d                                     |   5 +-
 vmm/vmm.o                                     | Bin 12456 -> 13528 bytes
 34 files changed, 318 insertions(+), 118 deletions(-)
 create mode 100644 vmm/peripheriques/keyboard/keyboard.c
 create mode 100644 vmm/peripheriques/keyboard/keyboard.d
 create mode 100644 vmm/peripheriques/keyboard/keyboard.h
 create mode 100644 vmm/peripheriques/keyboard/keyboard.o

diff --git a/guest/guest.bin b/guest/guest.bin
index 759ecaeecba1bf277b968267be9c0982f1802b7f..3aeb9ac215e6ea70448c7764cd5014a429ca2b56 100755
GIT binary patch
delta 1073
zcmZ20y;WvHKI7eq1>(ZjIT#q4j|g<Tax}l;2*`4Hahqe}fANVMC7GHyCjOV7_*#g`
zpJU>G%X$%r!U-o2hju<~epB%xjh%tv#kYU||2Mzk$+*GE!0^KP|NsBZM+BPRaAZti
zWMIgMU}9i+kpK}q?)rs+fq~(*|3U{o1_s*&ZHx>h&R}*x#tTjchOCrc*9ieHE;ECj
z)BJ`9%>4*5{)oUr2fj!KhUOpArR>LDzc4Z|FdSzE83Qt<x%LY~$?6FZcXhjREEeGd
zNlWlCFo>RwW<Sm<!^gm|G2@=qaaILB28JcolbI&Og8UHN{6?f(RDy5v9!5V;kn)8f
zl?NZNb{+z=3@<DO34qxLU$A2neISM=s=zlnm?_Q*<b>TI?=qecyw&OYp)>SLx9f-Q
z&@Y`A3@?El*zNjZF~~U}2QV;z?O;5#P=RmqYo>O_iIa<&br~ZjFJu-ob7TbvNVhA;
z!5<v_+YW$YDFYM)FVvA_1Yj~>85tN}@Ul*R%PhzEb}|o(2IG;*rYyRQD<&ti6f>#t
zZN9<6&B*v=^ApxsruybL9L=>HjHN=&Z+Nm2Uff~;TeTPzvXJ0xej|}~oHap=f#E;<
zjs!jihQ&!@3=GY0STYzm7#Ok`GC*Q4GJb)heb)?528LeO4<N%BviO3sI09Y>f+JrB
z;`zlO)t#a#d<+b`=5R7FSfeR^3XW`;;tW0phECBOK9GGp86Y>j@PIgQ!pXyFllOD@
zFtcPaPUhlNW;*+CvOcG1eQ-%)QHergT3TjuMq+v@gLi7Bm4a#t7bqfZ*%%m>voSC{
zVkZyhLiI8r>5pP(U=RTr&cMLHSQRw+Jf|qrov)Lhamq0r{yLeBOOEO6*U4&Ja!l90
zPIlvxV|wv*avGN$)9<g7+qmR}#lHRjKOLmok&mO5$%&VhY4YUL+^USFlkalLGd52C
z%cab?V6q~&Jmcocj@;&q+a_0X%QNnqJd<0VQFHQ6Zga-S$sf7pmG1ud|6dc?oYbQ{
zEG!HR3JeSkF$@e0&wflc;;~|sn4HTaZ(R5L|9?ef#jy~@GEl|!zyJTAjV#YJee!;u
FcK{3(Wz+xw

delta 925
zcmdlgvsQXSKBMo%0&yXC4hDwiBLdy79L;Yy0<s)lcu)K%F>#|L(<k<c|K%sX7Gm1Z
zKJmY0eG5BS-Gq~eLpz@~zu|cCosEIv#kYU||2Mzk$#CIhV0hvD|NsByBLX0P!?YO;
zFSro=aFDz*gby*I+m&N+4=)45an=dE3=E=YquGzMPT^%>*qCw8>Nx8RUIvCG)svYf
z#Dc5~Zhpfm(k(iHcd`JJpC?HDLXgsf4_G@7fmwzZ7J~%9?1L}Zv57tqLld3BJ9#-%
zoE69oyBQc57#L3o-s*Jy&>8xr+x0_t=$Fn5hL^xD>~{UI7~~$10~i><b}$}VID>bx
zJ##x_=;Y(fx)L(1;K1p2<>23T02GcHpBWh#Ua(H)VUd)1%>t7=_(K3D{}m*Ek!7+Y
ziyY&|$q6hPj2)9ZS#%k5CU0jcW}3shS%;OIkuhhp1zRjrJtP#G-$<k#XFVXw!0?}a
z#{pgjhQ)_O85o-1uw*cBFfe2>WPrq8H2(re!Y&R@28LeO56y3QvKX@Xg0eUQUg&_s
zUk2j6#URz4qDOc^M(|{SjC~Qz0CwqwlZVqLAmD__0i52G=W{C6^Zx(;KZ1WH|3Y^8
z*!Z}p$modXBP{0`97{@4^GZ?`Qc@KR4M2d4!Lgv|@QPxEM2L){A{QuxU$QbV1hX+P
z^s$qN#U!Dc*Fb5IL2T@k?{O<JrF@&5$0f(){cUm|mmE{*x5?|c<e1{VO+LpZ$5ilb
z@;fd$rsi*x`MBkT=6(DB-x=f_M?Q{LCMRCj`pLJr)fiV!PUV(o+&a0HTbb#~_sQ?L
zq}Uo57#N;^pUlTCHu(X!0^_U6j6Cv;pC&8v$TP-HcH}W<?44Z6BhMuGbMiVavB?{F
zIGCh<PTs|1#ppBnE04VKrr-bnvmsmLbd-mMg@Hkafq@~0fq`Mh@Bjbvk>#1PC%f~$
F0|4e%K0p8f

diff --git a/guest/guest_main.c b/guest/guest_main.c
index 33bc27d..3611921 100644
--- a/guest/guest_main.c
+++ b/guest/guest_main.c
@@ -1,4 +1,5 @@
 #include <stdint.h>
+#include <stdio.h>
 #include "idt.h"
 #include "utils.h"
 #include "pmio.h"
@@ -15,6 +16,8 @@
 #define timer_sleep timer_sleep_phys
 #endif
 
+extern uint32_t key;
+
 void timer_sleep_pv(int usec) {
     hyper_timer_sleep_params_t *timer_sleep_params = (hyper_timer_sleep_params_t*)(SHARED_STORAGE_ADDRESS);
     timer_sleep_params->us = usec;
@@ -66,8 +69,29 @@ void guest_main() {
     // console_pv("Débloquage du display!\n");
     // affichage_pv(400, 300);
 
-    console_pv("Attente de 100000\n");
+    //console_pv("Attente de 100000\n");
     // timer_sleep(10000000);
-    timer_sleep_phys(10000000);
-    console_pv("Après attente!!\n");
+    //timer_sleep_phys(10000000);
+    //console_pv("Après attente!!\n");
+
+    console_pv("Start affichage");
+    affichage_pv(600, 400);
+
+    int quit = 0;
+
+    while (quit == 0)
+    {
+        if (key != 100000){
+            char buffer[100];
+            snprintf(buffer, 100, "Key: %d\n", key);
+            console_pv(buffer);
+            
+            if( key == 27){
+                quit = 1;
+            }
+
+            key = 100000;
+        }
+    }
+    
 }
diff --git a/guest/guest_main.o b/guest/guest_main.o
index cbc944be68e926c84b77b2cf92e4683f2d3acae0..d0161fb98f957fe75efcbfdb35053beac7cb5745 100644
GIT binary patch
delta 447
zcmeytH$z~80^^H~ib9O_6)*n$|NsBRw}1ctH^1S@U|?Wi0E;vq5omtHkuiahfgvM;
z2_bmg^$SSNYyX8H%635;BSVQZm>rNIz`($emD1}vApl_n4>A|5uK9;_Df@BPFN_Qf
z49B%tLB@bgX|DakP_lZ$gp-GZOA?Dp6cW?YGLthB(^DC|Q!A|$R8uxjVboz1o(@v)
z$j8yj<iyL$H2EkG3(MroOg9;)PhQI`E?5DQg<_CvY9?=GZs*TVtz;<9D=5m$D@kKu
zV3=&p;%TSB$iTqF&A?#E$iTqJ&%odcrM*Ek3j;$KNM3+}Ar(Y(F)-wU#Q7N*>cRBn
zSuC#@Cr)l<Rc777!obimc`d6l<I%|%S=GU$_+$Y#0oJ383=EQ!RoRpo?@jh(Q)m1&
zxsXkr@z3O$Z0bxZOp_0>sWI8GPJYFv#wNqez#zalS&UtYRfmOvp>?t?yRt+HD+5Cj
M)Gr_k6kZ@200<j?xc~qF

delta 297
zcmbOs@PluH0;9)9MIpvSju(Ia|NsBu+rR(+o8RzcFfcGMfJK^*2!Qwv(`KOXg^}bZ
zoILDUQj(filB$rBs$ggU0$dD^1x1Hf6e}b`WE2%Q-(l2Y6m|v~?8wK_%H+h$T7Q&>
zg@s|VH1kbPkhl;7BSZdVS(f(6TUb2Alo=TqnAjN@^cWc!7+Dw?j6r;^$yThd7;Pu3
zvMICLurM$rO!j3{W-Ods$fgb^#V2oI6JRZ5WMEL8tjH`p`39Q+<Fv^y+0+>~O%`NV
zXWTN`l3ktY4&&q`b~UCsER(y~)!42uF)(~!n7oZ$iS-CG149K^;|F#D)+;Ow3`HOw
E0O|x@82|tP

diff --git a/guest/idt.c b/guest/idt.c
index f49386d..2677ac4 100644
--- a/guest/idt.c
+++ b/guest/idt.c
@@ -2,9 +2,14 @@
 #include "utils.h"
 #include "descriptors.h"
 #include "x86.h"
+#include "pmio.h"
 
 #define GDT_KERNEL_CODE_SELECTOR 0x08
 
+// My test
+uint32_t key;
+// --------
+
 // Structure of an IDT descriptor. There are 3 types of descriptors:
 // task-gates, interrupt-gates, trap-gates.
 // See 5.11 of Intel 64 & IA32 architectures software developer's manual for more details.
@@ -53,9 +58,13 @@ static idt_entry_t idt_build_entry(uint16_t selector, uint32_t offset, uint8_t t
 
 // Low level handler defined in idt_asm.s
 void _irq0();
+void _irq1();
 
 // IRQ handler
 void irq_handler(uint32_t irq_number) {
+    if (irq_number == 1){
+        key = ind(0x60);
+    }
 }
 
 void idt_init() {
@@ -66,6 +75,7 @@ void idt_init() {
     memset(idt, 0, sizeof(idt));
 
     idt[0] = idt_build_entry(GDT_KERNEL_CODE_SELECTOR, (uint32_t)_irq0, TYPE_INTERRUPT_GATE, DPL_KERNEL);
+    idt[1] = idt_build_entry(GDT_KERNEL_CODE_SELECTOR, (uint32_t)_irq1, TYPE_INTERRUPT_GATE, DPL_KERNEL);
 
     idt_load(&idt_ptr);
 }
diff --git a/guest/idt.d b/guest/idt.d
index 65b389d..b6670f0 100644
--- a/guest/idt.d
+++ b/guest/idt.d
@@ -1 +1 @@
-idt.o: idt.c idt.h utils.h descriptors.h x86.h
+idt.o: idt.c idt.h utils.h descriptors.h x86.h pmio.h
diff --git a/guest/idt.o b/guest/idt.o
index 43d2c0acb517a821f18afa93c9c2cfe0ab72afb9..49136b163198f4506c134f23c97b4a027fc214c0 100644
GIT binary patch
delta 638
zcmaFC-NQRUfvJUMqS9>V<~JP8wH%D4Ld|b@vJzhW`Tzfa^AUl?3=9km6HXou?R?t&
zMk4Jvs{#iD!+-W23JeSki<LMS7@FU(WH4|rFk~@gC`^1RFChrlC)4fvp*!@;Vvw><
zQ56OThKV0UWS{;6nF*8AU|?YA6xCq>nZc8xFj<jNa<U_1yS^gGN=H79RwgH2*4U#w
zEG!HRG7Jn1F$@e0%NZCLW+TfpO`rUo(Nhp)56Bga3@i-X3=9kklLMLL>p==x7#J7?
z8CV$985kJa7#J8prVBAJG8ls-p;&-{fx#TfbdbCQR1QRe<lR9GC<gI;p==NZ;s=8m
zPz>TTWTs5s&!kYFom$C|SyULGk(if~lUl@(nU}(lnNkv;nU`6@keixYoLa&VpIKCB
z045E=ayj{lDGW0h7#Ns185kBYFfcH(Gcarb(aa1C+oALxD191AUjV7+W?;Ah;`1;t
z`~=a=1`G`U!3+il7DfgJMqUO6RS?b0z@QDKjiIy!BLf2y-{dIfLrhMLljT^HSUZ>*
z7%C>avM4i_O@7ECKDmKKfVF{<fkAEZR2F5%hRHiw)EVbYeh4NxS=AYjOg3ayXJTNP
o9L1`}YQx09@L_T*t1_z&GXq1+WJV_8$p=^kSS45(7_vY-0NiVS?EnA(

delta 493
zcmeC-eZf6Jf$0JBM5Wmp6JigCc0O%>BawETm4SnS;XnHh1_lO(#Y`Lw49#y?GC*Qk
z3>gfQ80C$0{{R2qd_<<(^+R{)m&G7uouVuZAay)obua#a6$nf?c^D+gz`!uMjB%1a
z8;Ik`$I;5<#LMb*l!t|dfkB3Wfgy&0fuV<ifgvARo+*2>Ig_U#NC;##BLfQqH;6NN
zB9pvr8v_Fa$TT4aMh1N(-5|aNNEH+dFfcIKL)jn-#CM%6%WPDiSyULGk(if~lUl@(
znNkv;nU`6@keixYoLa&VpIKCB02a;3PfTH8V3^9lz`)4Nz%U0&FND$?p!8M-1_mZh
z28O*LJ{JSSJrK>z!0-f0zk$*pLF%{}7!(*LGqLPr{5{!`NqF)V76DcsW(J0U$uC)y
z8TBXgvZ}K>FfuT(O}1oJW^|Yw%c{;4!#LTFNo?{QRsqJC$!l5FSz8zx7%C=jWEGzL
rhE;$mhI#ToRyEc?j0_A1CTp@Ov+iMHVDOt9$fnF%!py*s1+oVKBTHpO

diff --git a/guest/idt_asm.o b/guest/idt_asm.o
index fcb2a94a593a069eb5c5140768dbe5ef8bbfb6f6..075cc50f013c0946efde3f60635984055d3ac14d 100644
GIT binary patch
delta 98
zcmeys(!e^QhS7autv_SK#Iwq*222bL4impBGZsviWK?2i$zq&r#ppb_kujcChk=1X
rVDeK&eO?|02oPXkWKfta$fU^{pIKCBIN6d(QNWOafq{t~A`c<~q6HG5

delta 80
zcmZo*{lGGzhS7Oqtv_SI#Iwq*3QP<PRujJ}GbT)yWK^1L&*(I{mNA)Cje&uIXYx}<
a{mCj!YLf$)6vP<7K$n4mfr$;w1QP&VdJpOV

diff --git a/guest/idt_asm.s b/guest/idt_asm.s
index bfd31a8..1f0519f 100644
--- a/guest/idt_asm.s
+++ b/guest/idt_asm.s
@@ -15,6 +15,11 @@ _irq0:
     push    0  ; put irq number on the stack
     jmp     irq_handler_wrapper
 
+global _irq1
+_irq1:
+    push    1  ; put irq number on the stack
+    jmp     irq_handler_wrapper
+
 extern irq_handler
 
 irq_handler_wrapper:
diff --git a/shared/hypercall_params.h b/shared/hypercall_params.h
index 4dace22..c009169 100644
--- a/shared/hypercall_params.h
+++ b/shared/hypercall_params.h
@@ -39,4 +39,8 @@ typedef struct {
     int32_t y ; // y position
 } __attribute__((packed)) hyper_sprite_position_params_t;
 
+typedef struct {
+    uint32_t key ; // code of the pressed key
+} __attribute__((packed)) hyper_keyboard_params_t;
+
 #endif
diff --git a/vmm/peripheriques/disk/disk.c b/vmm/peripheriques/disk/disk.c
index bdba16d..a3a51fc 100644
--- a/vmm/peripheriques/disk/disk.c
+++ b/vmm/peripheriques/disk/disk.c
@@ -48,14 +48,14 @@ void disk_store_sector_4(void *addr) {
 }
 
 void disk_store_data(void *addr) {
-    printf("Storring on id=%ld\n", data_index);
+    //printf("Storring on id=%ld\n", data_index);
     buffer_16[data_index] = *(uint16_t *)addr;
     data_index++;
 
     if (data_index == SECTOR_SIZE/2) {
         stop_loop = true;
 
-        printf("Stopping loop after id=%ld\n", data_index);
+        //printf("Stopping loop after id=%ld\n", data_index);
     }
 }
 
@@ -63,7 +63,7 @@ void disk_conclude(void *addr){
 
     hyper_disk_params_t* tmp_params = addr == NULL ? &disk_params : (hyper_disk_params_t*) addr;
     
-    printf("Mem: %d\n", mem);
+    //printf("Mem: %d\n", mem);
 
     // Pv not working for some reason
     // Wrong data writen
@@ -95,5 +95,5 @@ void disk_conclude(void *addr){
     }
 
     fclose(disk);
-    printf("Storing data\n");
+    //printf("Storing data\n");
 }
\ No newline at end of file
diff --git a/vmm/peripheriques/disk/disk.o b/vmm/peripheriques/disk/disk.o
index f85163d96494c7e0bc36af65822977ce741f47f3..a66604d41d53db9c4038ced2b648bfd317b5df8c 100644
GIT binary patch
delta 913
zcmX@1wLxuy29p8*M6FlMowYwETQb^lu^(e)U|?WioDe&CKBJm^bL|O+QZA2f*Bc()
z4lJ*QJi0|e(lCKdOw5dvg_y-AFJR%G?7*VH$THcJS$%Q>3&-RNW(6?407{>L(2U<E
zFJzWyWSK0;;y+n{g=2CCi^AlE!s3$y1dS$hu_jKgV3nIZgY}AWAjlp^K7lqSXI?fY
zA0BoN1_l`h28KN#aRvqkFGdCi2ADjvD<cm($K;7Dl9LOVSvK!sb77PO8^FN8Fo}VI
zL5P8oK>?%zq;aw&$8^R=lQ(j>Gk%-g$RR#ifK!5zd9ov?_~Zi4dy_-Cbl4$wh)iC{
zCBAt9mja{YEr<vM69WSS3j+hg5~yJhCm-Y%XZ!&oCoAwsFmg>+<Pm3-nB2%C&S*3F
zA&+=s1XLwRCn)Ux{D**QBylkY1_qdTKaw~oD*i&0|DO&O2iY!;q<-Gyi@f6XOQEtL
zTR^%bq3+!P6$j~(K+<&xDh^XG3srv#Dh^T)G6UwSPe|fYNap;7h)-V5E6B(?nUPQ2
zQxIe%G?b)~RO%s#BfH-jDh{GRE_Z^u#2aLqYB)$3i)qQo;+tLhvl$r`CT|q@&X_fM
zrJy<23QmYA6PPEz5;S94#WZ;$i`e7>W{$}YLJCX=m?kF)*@37<LUv3RyptaZ*>M(t
zyv)GBkTf}wS$wjCuma~LsE7<$q(NAL=^YE)oCCrNoFAYH3??hG3s3$dtiq@;Sy9BE
wNq}#1l87DW50G~l7#J2zUMXVEIfDb@BrZ_;pUfdD!MT7BBGL&q-+`F}06&M`X#fBK

delta 1327
zcmdm>c0y}{29t;2M6Fk<&2I!eI%|J;bh9!rFfe#@9`ophvX1WniM#+2lf@bBG*pj)
zB^dE5op5q;JfoU5UgJEPYfmtgazYJyE$GoL3bF;t-@Js8nUNjpjLGwv<R(90)|mW(
zNnx^r0LNqrW(e&7r86Kj<G0C<%<_|1I4194_LwZd%rTjRMPc#=W{$}gES8fGFmYG}
zm*f`}W#*+T<mV}5rr4_Hq;N3=m*f`|fW&h0^9vLb(@Ii{;BvmHxmF6QDO{5aSdw@^
znnCJP5=#;%Uu2P={Ep?C@kEfL9r*;>n4Edpn0k2FIT#pZ7#JA#fW#RX7)lu#7#Lvk
z%ms`*>>QH~StK_Luz4^_f;BTRFic`#U=U(pWJmxh25FjH$UdF%>Ewg#;*%9P3>d#p
z4&=~hWSQK^A<oDJCIu%qa(rbgD9X$$Nt;~CsmoDNT2jowz#uaDAgB1|1DpzsjQ1uB
za*G>+qmF@rfr){E0TgwA|3ko6sQXwL7#KhS{|6%c|Ig%yT;hz(lO4Im8KuCaDwxy(
zk&;$W2ZBr!W?*3W4b|lYk~Q=}k_Fi%2(=>;DvoYf&E!IEamMz^3%SKTCqmVLOa|%I
zh3cIL6-U>*1}Y9x53>iPWh=<E`aL*guOo?zGcYi~eEk|p9Avv0$S4K|hR;xOknIvk
z>VHASLADDai8F!(KyeA8K?Vgu4dR(Rkw@H64kU~e8DUUaHK;hq8Yv{>{3a{%iq}U%
zWkD3k%zUV>M34Xj0|UCQTqJQ&QiOT33rQT=GxMS1APQuDHPrm&AOQx3Gz<$iLnOfB
z$QJC!A$|-h4x&I7Oov)<4kQ5efb3>n-fTw3gvm4czB68(Jdxj=tAh)o?gY!^OZ;X`
zqRf*wGKo!A5YS*!V4mzHU<abQ1nigs_$Qwdu;aV{3I_%Th82?q1<jc%SSNc4+A&RG
z1#4O$sKGRYb@C}eJH``}Ifd+*Gz2Dl3E6QjV1rn3Ve&*FbIt-z2v2PCMIm#}9Rd(u
J=VU<vc>t&iJAwcJ

diff --git a/vmm/peripheriques/gfx_init/gfx_init.c b/vmm/peripheriques/gfx_init/gfx_init.c
index afc4a6e..ced67f4 100644
--- a/vmm/peripheriques/gfx_init/gfx_init.c
+++ b/vmm/peripheriques/gfx_init/gfx_init.c
@@ -30,7 +30,7 @@ void gfx_init_conclude(void *addr){
     display_width = tmp_params->width;
     display_height = tmp_params->height;
 
-    printf("Initialising display!!! Width: %d, Height: %d\n", display_width, display_height);
+    //printf("Initialising display!!! Width: %d, Height: %d\n", display_width, display_height);
 
     sem_post(&display_sem);
 }
\ No newline at end of file
diff --git a/vmm/peripheriques/gfx_init/gfx_init.o b/vmm/peripheriques/gfx_init/gfx_init.o
index 73bd6e495105bbe4a8bbbd2bc7db3a95f116bbb1..c2a61831039f091a68e922550ab0a62173e3f8ed 100644
GIT binary patch
delta 483
zcmbOr_CR=ohPVP70~|PjSq=>R415#qb0(gZo%ljwaswmhWI;xGMyAPzjOtL5b#f!4
z{p9zI3X=txrU?0iv^nw#v@tpJvN3t_uyagqWR#kGfyrR91akzV|KvjEddB&a4>F5S
zR$!T|l#*Fokds&$U!0oDP@I|@Uyxs1!XN-LgMop8iGhKEWAa@VaY+uS2#E3m5pY>v
zR`JPqSa=xICnvIsGv-Y;WEE#Dn>>+KeDV!ep2<3FJiIfY>KPdr7+5F&Wfh<Nhn0u*
z21s=BMRwuI7Hs{K&$BILtesrQZZ7D-0+L{0SOK9JcqZ>;*Js>2xsg$P5{CxkfytU2
z_KXK6XL8sJet;@XKq%#qpDe*Cz_?(tCZ{^1|KvbUai%?tlN%YuCO5DPFvd@w$SKZw
z0OSw`1_p!4h8*&Y<&!URh;x2`idBHciY8BF7Z(j+g_!FBp%{1=7#O%F+j41(W`F{Q
nfq}sSs*9I_fq{8)EtfXu0%nNf6_Yn|nRCv7n$S48kX;@Cxusrh

delta 724
zcmaDLJV9)NhPVJb0~|PjSq=;W4Ez)AbL6^3LHur35ZQUmqZiEZ=sdmyB=BP5a>a?K
z<QSPJzEqz)fsJ#rB%?fxo_IrGasi`(o@ZWWNoHbBW^ra-x<X23aY0UErJ|yuLU?9M
zNrshzYKo46M`~tzMhS?`HF-Xx;^h5|Q-uma<~#BUv@tpJvN7fGuyagKWR#lRz+^DF
zfRTlnnSp)se5Ops!pWS>^^CJ7J2HziE(4L17cftjD=5m$D@kL3+7@4&n#)j}nj2q`
zUtGe#ATW6%i#V@3$b1F{1||ju2F}U3EaH>ru<-CkA&GKLp35RW`3wsWWA5aGEaLUW
z$Z`w}41fMZKn;>OGm>~GRGfu@fq@4}d;(M)WHT?4_zb8xNIf5tcmYJ5je(JYfq`}M
zUl#GnI;=dr2Oz>=QTEBYtm2dZu<%R{VC`os%1=owNt}F_bur`o$&GC0f)_wWGB7Z3
zfJ|UuVBnp6l1-oS{^UeP@yP=08jKGnTe90TKA2p|ZZCKP9Kj3>2~gvCC!b`OpS*%Y
zfb#%UxBg^Dc6mm>$q(7Z8Q)L-$*#^AK3S1NoQa!haw4PH<Oys7jOmjTIm9^yKt5z(
zU@!n{sGq!$L!8qADpmm&tD3x!O<dH14PuuEgkk^%3io7QPHoX0P}Lbwt3koSGTE0?
Yn^OVmrS+2=In6m6peA%qZe)`O0K8hOg8%>k

diff --git a/vmm/peripheriques/keyboard/keyboard.c b/vmm/peripheriques/keyboard/keyboard.c
new file mode 100644
index 0000000..661d996
--- /dev/null
+++ b/vmm/peripheriques/keyboard/keyboard.c
@@ -0,0 +1,13 @@
+#include "keyboard.h"
+
+state_t keyboard_states[] = {
+    {WRITE_KEY, 0x60, 0, 4, NULL},
+    {EMULATE, 0, 0, 0, NULL}
+};
+
+state_machine_t keyboard_state_machine = {
+    .current_state = 0,
+    .states = keyboard_states
+};
+
+hyper_keyboard_params_t keyboard_params;
\ No newline at end of file
diff --git a/vmm/peripheriques/keyboard/keyboard.d b/vmm/peripheriques/keyboard/keyboard.d
new file mode 100644
index 0000000..b0dee24
--- /dev/null
+++ b/vmm/peripheriques/keyboard/keyboard.d
@@ -0,0 +1,4 @@
+peripheriques/keyboard/keyboard.o: peripheriques/keyboard/keyboard.c \
+ peripheriques/keyboard/keyboard.h \
+ peripheriques/keyboard/../state_machine.h \
+ peripheriques/keyboard/../../../shared/hypercall_params.h
diff --git a/vmm/peripheriques/keyboard/keyboard.h b/vmm/peripheriques/keyboard/keyboard.h
new file mode 100644
index 0000000..7e0e3ae
--- /dev/null
+++ b/vmm/peripheriques/keyboard/keyboard.h
@@ -0,0 +1,17 @@
+#ifndef KEYBOARD_H
+#define KEYBOARD_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "../state_machine.h"
+#include "../../../shared/hypercall_params.h"
+
+extern state_t keyboard_states[];
+extern state_machine_t keyboard_state_machine;
+extern hyper_keyboard_params_t keyboard_params;
+
+void timer_store(void *addr);
+void timer_conclude(void *addr);
+
+#endif
\ No newline at end of file
diff --git a/vmm/peripheriques/keyboard/keyboard.o b/vmm/peripheriques/keyboard/keyboard.o
new file mode 100644
index 0000000000000000000000000000000000000000..c679dbac3a8d9ca8e5f3203200c200d62756fd74
GIT binary patch
literal 1336
zcmb<-^>JfjWMqH=Mg}_u1P><4z+l0IU^{@B4h%dD+;FuCU@-*2f?$GKtYDH1!rj@~
zN<qWjFH}>(&_vHj&rre0z{teF($D~G7|0$41_lO@`R;z93``7+2S8$ANd^W6MkpVf
zpI~Z0G)SI>;p2Z08yWL3Ffa%*AUq!cm6QRCBWx0YiW`H)nV~!e2Dpms)XJp%#G(|v
zWCj>BzPKc@B()fgAD^3;oROKAiV!YHEK1BRh8W2Kp}^sea1{dsgI;lEZb@PigI;k-
z5rocwu}V@aN*MG~5=#;p^pc8;8T5)$a}vRP5KAv7KRGdnK`%K!H#aq}gh4Maza&-9
z-7i$PxFj(-8_G}5E7dC~$}dPQDyf7zfg(y895)OMY-pxH(iWN^R4uZoB2)|!(hymg
zepoy~L>U-BX#~aw(drBg44|+?*FOOy$$%7ZP(CPqK$&355QqIR{jl@^R?NV_fX>%}
z+5vMfOx*^kMG{Z}PN+JNTR}oFaYv~AkX!(gf#3xYiUE{9p-eCZH5Qz1KmuM+{UA0n
z-h<3RV#D;qgrXQ27}yyYka7k@<^Y6ZKzA3+{ZMJJJ5bUuRN@1au7J{9P&;7yVg3h&
q3wqpvv}8aX>I~u_VW==%M38}j0h|64P=&d0l@JD07{Xy-U;qG_GFO@a

literal 0
HcmV?d00001

diff --git a/vmm/peripheriques/peripheriques.c b/vmm/peripheriques/peripheriques.c
index 0e02a86..8b24ed0 100644
--- a/vmm/peripheriques/peripheriques.c
+++ b/vmm/peripheriques/peripheriques.c
@@ -8,25 +8,45 @@ state_machine_t* state_machines[NB_STATE_MACHINE] = {
     &disk_state_machine,
     &sprite_content_state_machine,
     &sprite_visibility_state_machine,
-    &sprite_position_state_machine
+    &sprite_position_state_machine,
+    &keyboard_state_machine
 };
 
 void check_state(uint64_t addr, uint8_t* addr_p, uint8_t size, uint32_t value){
-    printf("Checking... addr: 0x%lX, size: %d, value: %d\n", addr, size, value);
+    //printf("Checking... addr: 0x%lX, size: %d, value: %d\n", addr, size, value);
     for (int i = 0; i < NB_STATE_MACHINE; i++){
-        printf("State machine n°%d\n", i);
-        printf("State machine state: %d\n", state_machines[i]->current_state);
+        //printf("State machine n°%d\n", i);
+        //printf("State machine state: %d\n", state_machines[i]->current_state);
 
         state_t tmp_state = state_machines[i]->states[state_machines[i]->current_state];
 
         switch (tmp_state.act)
         {
         case WRITE:
-            printf("WRITE\n");
+            //printf("WRITE\n");
             if(tmp_state.address == addr && tmp_state.size == size){
-                printf("Test OK\n");
+                //printf("Test OK\n");
                 *((uint32_t *)addr_p) = (uint32_t)tmp_state.value;
-                printf("Wrote %ld on 0x%lX\n", tmp_state.value, addr);
+                //printf("Wrote %ld on 0x%lX\n", tmp_state.value, addr);
+                state_machines[i]->current_state += 1;
+
+                if(tmp_state.callback != NULL){
+                    tmp_state.callback(addr_p);
+                }
+            }
+            else{
+                state_machines[i]->current_state = 0;
+            }
+            break;
+        case WRITE_KEY:
+            //printf("WRITE_KEY\n");
+            if(tmp_state.address == addr && tmp_state.size == size){
+                printf("Test OK\n");
+                *((uint32_t *)addr_p) = (uint32_t)keyboard_params.key;
+                printf("Wrote %d on 0x%lX\n", keyboard_params.key, addr);
+
+                usleep(100000);
+
                 state_machines[i]->current_state += 1;
 
                 if(tmp_state.callback != NULL){
@@ -38,10 +58,10 @@ void check_state(uint64_t addr, uint8_t* addr_p, uint8_t size, uint32_t value){
             }
             break;
         case STORE:
-            printf("STORE\n");
+            //printf("STORE\n");
 
             if(tmp_state.address == addr && tmp_state.size == size){
-                printf("Test OK\n");
+                //printf("Test OK\n");
                 tmp_state.callback(addr_p);
                 state_machines[i]->current_state += 1;
             }
@@ -50,10 +70,10 @@ void check_state(uint64_t addr, uint8_t* addr_p, uint8_t size, uint32_t value){
             }
             break;
         case STORE_LOOP:
-            printf("STORE_LOOP\n");
+            //printf("STORE_LOOP\n");
 
             if(tmp_state.address == addr && tmp_state.size == size){
-                printf("Test OK\n");
+                //printf("Test OK\n");
                 tmp_state.callback(addr_p);
                 if (stop_loop){
                     state_machines[i]->current_state += 1;
@@ -64,9 +84,9 @@ void check_state(uint64_t addr, uint8_t* addr_p, uint8_t size, uint32_t value){
             }
             break;
         case EQUALS:
-            printf("EQUALS\n");
+            //printf("EQUALS\n");
             if(tmp_state.address == addr && tmp_state.size == size && tmp_state.value == value){
-                printf("Test OK\n");
+                //printf("Test OK\n");
                 state_machines[i]->current_state += 1;
             }
             else{
@@ -77,10 +97,13 @@ void check_state(uint64_t addr, uint8_t* addr_p, uint8_t size, uint32_t value){
             break;
         }
 
-        printf("State machine state: %d\n", state_machines[i]->current_state);
+        //cprintf("State machine state: %d\n", state_machines[i]->current_state);
 
         if (state_machines[i]->states[state_machines[i]->current_state].act == EMULATE){
-            state_machines[i]->states[state_machines[i]->current_state].callback(NULL);
+            if(state_machines[i]->states[state_machines[i]->current_state].callback != NULL){
+                state_machines[i]->states[state_machines[i]->current_state].callback(NULL);
+            }
+            
             state_machines[i]->current_state = 0;
         }
     }
diff --git a/vmm/peripheriques/peripheriques.d b/vmm/peripheriques/peripheriques.d
index c4936e7..9695e32 100644
--- a/vmm/peripheriques/peripheriques.d
+++ b/vmm/peripheriques/peripheriques.d
@@ -14,4 +14,7 @@ peripheriques/peripheriques.o: peripheriques/peripheriques.c \
  peripheriques/sprites/visibility/sprite_visibility.h \
  peripheriques/sprites/visibility/../sprites.h \
  peripheriques/sprites/position/sprite_position.h \
- peripheriques/sprites/position/../sprites.h
+ peripheriques/sprites/position/../sprites.h \
+ peripheriques/keyboard/keyboard.h \
+ peripheriques/keyboard/../state_machine.h \
+ peripheriques/keyboard/../../../shared/hypercall_params.h
diff --git a/vmm/peripheriques/peripheriques.h b/vmm/peripheriques/peripheriques.h
index 6aadffa..afdc737 100644
--- a/vmm/peripheriques/peripheriques.h
+++ b/vmm/peripheriques/peripheriques.h
@@ -10,8 +10,9 @@
 #include "sprites/content/sprite_content.h"
 #include "sprites/visibility/sprite_visibility.h"
 #include "sprites/position/sprite_position.h"
+#include "keyboard/keyboard.h"
 
-#define NB_STATE_MACHINE 6
+#define NB_STATE_MACHINE 7
 
 void check_state(uint64_t addr, uint8_t* addr_p, uint8_t size, uint32_t value);
 
diff --git a/vmm/peripheriques/peripheriques.o b/vmm/peripheriques/peripheriques.o
index 9ca211e7e4f8933ade41de2a099d26236cb756f3..b045dc7a1c7766b669542cf895b2918bdb76a653 100644
GIT binary patch
delta 1544
zcmbQB+MzN*L;M6U0~|PjSq=<>3<4AFrMQl}?g0tBT*@*zfyH~WB%_W83x7KgGXq2C
z0gqmhR*<AeFDr=ZW?}M};n6D!VtX)N`2WD8+x3KprR$2)6#i|lH!NJ|ltz1WyI$x#
z<k9WApi^M7AdAH056tqDMVQQ!qnH>NUWPI;Fu*kNw=QI0V1R1mZ=J%xzyP(!qx1L+
zkR9C+o4{sugI(a!9lE0P7(&?&kTS5^{R`R{C&#eJ!R(W1W@KP^S;vU5uQUj1SE=XZ
zRwh>_CC14KEK-x@SlJ9-{s&nO^Gp;>U7$yID9DcsJUWm6zr?={?1YvBC6Q2%DKIKb
z7G#lEs(xJw^HixHOtY&;cj$#~*BKs`he|D>8lomwv6!;3^0ywD9M9sz>Cx?=;L&=Z
zBm^vdiY1YSjlVB&vOcTh<N#JSsgTs-5(R&6hVY{Nl2irN6ovde1%nFJoCvPTj;!L7
z+1cbLYp{g~-C<#1U~uFUXk&8bWpiz2X1+AJk8Kj8#bibH*^^z^MI>)AFfa%)FoJ>#
zjKLZh7#N;Sc4QZ4d<`algGg2;Mg|6f$&RcdlNmV<`DLe8Cgmp<rNkGPB$lMc=O!j+
zWagzZBxj^1XG6po3Q9|g8Q|&)5{nXZix~=vGV@B(7)pzCQd0}SHZm|Um`--&6lV+s
zk%sG_f=mny49pA+3=&ZOE+~yI{t2Xuk!NxumpG#%h?Fdc`Ua-*&wmK0pL~&1yuKAl
zmY;!v0VX>Uhxj}sagcjJ0Sa=;YN$AfFMwpuRwQvjB=M6F@yY32f{c$r?qrmh{E<tX
zF#$|gfyp@_Qt}eW;S3B6APQtU%!RK&vWzT~H*$+JDuc-sFj)sC=Yq+7VDc826q>w{
zN1Ra)Os0Uz1~9n;L{3iNoltK8@(2S1IQn^@Y!D>_BA_k+x#BRCuK=Y%Vjvs~@e_jz
znz#i>l7WFi15JE4R9pul&JFe=NX(Ua@+;m1=G2_T$sT;olP~ZoFy5K`k<VQ41_wl`
z0VwDh7#R2_Tk`8O$*@j#WEGp-z^}n71Il-kFA4}xKESWRsQ}_JFfdq5{>X2x$pQ7#
z3WymDd<+Z>AO%n};YrJNa-g7u21tg1fdLjKP(2Kw7=W=sw8LaUesRqWP@^kALLhfB
zFfgz)FfgDS?K^p*fH+eJ>*Q4eYK&o%FA9h=ErB^+fH7^dprAPC3Yg843kBpE>m~;Z
zh;!b6iaAU+6jYup!Y?AK0WGCr`2pk^p2>R!wFM>EAdc7ojSc?EKLzzgPk@}mz`(!>
W6$PsS2ULKN1g8Vkw2sMz{PF-67+Ht_

literal 4752
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
PLIwtgX1GcS16@A=SBjY4

diff --git a/vmm/peripheriques/sprites/content/sprite_content.c b/vmm/peripheriques/sprites/content/sprite_content.c
index a06e216..c0af462 100644
--- a/vmm/peripheriques/sprites/content/sprite_content.c
+++ b/vmm/peripheriques/sprites/content/sprite_content.c
@@ -55,7 +55,5 @@ void sprite_content_store_data(void *addr){
 void sprite_content_conclude(void *addr){
 
 
-    printf("Showing sprite SLOT: %d, WIDTH: %d, HEIGHT: %d\n", sprite_content_params.slot, sprite_content_params.width, sprite_content_params.height);
-
-    usleep(10000000);
+    //printf("Showing sprite SLOT: %d, WIDTH: %d, HEIGHT: %d\n", sprite_content_params.slot, sprite_content_params.width, sprite_content_params.height);
 }
\ No newline at end of file
diff --git a/vmm/peripheriques/sprites/content/sprite_content.o b/vmm/peripheriques/sprites/content/sprite_content.o
index e9e2e02761a9eb7a82a11bd22ef6f425f3c630d9..801b11bc51fe37d49bee9156f6a780495c4072f7 100644
GIT binary patch
delta 669
zcmca0vqN%%hWHN-1~_m4vm6-s8TcmJpJ3~({V^f-@Z?4&*~wXqa*QmKI~mm(Stf5}
zRG%EcBr(~6Ndt^OFbYiGz{oK<f=Pjqb#fq=#pH)fp9Q%=W;yZ+v@tpJvbpiFb4+ez
zlAgrkF*$*ygOPjkOP2c0GguiJbwJ7(7#IYhG!p{@14!$i{}7;oEI#=xo46!MmJ=%K
z3Z+51cqad46PM&=U|{$G(fU6eNtSQ2F1xrS4+8@O%;aJuS)R$UXtFIRvc2r$lVjL<
z7^hDTWEY=&f}IEK3Rb9^#ZVgL3hv2oA!-G8A&K%aFfja{ypcm#5T*wtc>qLAp2#IU
z`2`2h<U1TZyaJ3MAqEBz#W9(eQ+zTHCl9X&h|2&GWtnWtd1^90*Fwg#lMT7$Ctu)_
z5PShOv;nG)XYx-jeI{PU$$^YwlO4D<7zHM0a@#X1OkT-tFPOm&v0?&*V&IwllUsgr
z1djk?!Q@OHbw>Zm6M4j$dYGV^1sLNeU*r*IoG@9FN1d^JvLKH*=K+vM85kILOg7|^
zXDph0kxN|k2h`XKn6V5D3|y0Id9_6=m?1(LP}hNCh-LC#UTw|?ED#yS$sc*mISZf(
Iu@U4i09cNP%m4rY

delta 1041
zcmdlXc|m4^hIjxM0~|PjSq=;W4Ez)APdGHc5%B1&{n5<}67CiSk^I|OA=H7+V;;R=
zwnyjj9U!q6AYy;Rv>6Ow)`XLXCp$7JPu60Tn=HV@F*$%y0ZdmgDomch%rf~1qY4^r
zGg*U4U~&N?$7Baaj!B#v`oS6b<(YZu3dIFQnI)+T!9M;WRtl;qItt;QE+HNeriZJi
zy9Zd9YjQr*S0PuBD;)U*+L)Yq*_a%7*f}OUGD%II!0a*EfQf~dnSmXo0D>o9WbS8l
zot(&0&&tTiz#uSLkWrYG1IiLv{E&rFpr9x-uOyA3v^Xa<wSa*^aPmYpab69Gb_ON}
z1_qwVylmo<JPZsBoKR7)3m6!{vb>XR*~BIJ7#J9S{D**Ws49?N{>iy);*<Zd@h}!o
z{>Uaic?BB}h{xN4q=t9$S*QtrAO`%OjwH)B`7hLVa8xibFf2xr<(aI@E*=W99j12|
zk}N+11H*5qnHP}6k^OQFO&n&+T~IhUzC@B`VPIf@+42o44iXbU5@%q9NPxrzLE@7W
z*@Y+fu=DU9fJlH9uutw~7nkIKihw8qs6G(IIe9O;xFk}VW$*wAGcbVlvQB=>eu}Lq
zKP9mwaq?D<#Z2sslcPAz1Xr+u%wb><00lb(0|W2mg`E0~?vpQa+A{`B7UZ&LOqd+V
zWiPk`YV8Dwa*#SMc|oWqs2BsohRK24>XLp?I}PCC5XOVa7rE3~K=C~JBBu!BpUHyU
z>Rjmz4B(W<#4wqWNo;Ziw}N6lR6n}u2Fwt1c1(`sme;LfU|;}+7bI&!WI&_`G`UrP
zI3OP}FfedWe#)&a_yVeb12kOtCNJa?pKQS+!8rpOef*OndCWNvKuzeJ+{i3ES%--S
E06Y!GDF6Tf

diff --git a/vmm/peripheriques/sprites/position/sprite_position.c b/vmm/peripheriques/sprites/position/sprite_position.c
index 006319c..c26f799 100644
--- a/vmm/peripheriques/sprites/position/sprite_position.c
+++ b/vmm/peripheriques/sprites/position/sprite_position.c
@@ -29,7 +29,5 @@ void sprite_position_store_y(void *addr){
 }
 
 void sprite_position_conclude(void *addr){
-    printf("Showing sprite SLOT: %d, X: %d, Y: %d\n", sprite_position_params.slot, sprite_position_params.x, sprite_position_params.y);
-
-    usleep(10000000);
+    //printf("Showing sprite SLOT: %d, X: %d, Y: %d\n", sprite_position_params.slot, sprite_position_params.x, sprite_position_params.y);
 }
\ No newline at end of file
diff --git a/vmm/peripheriques/sprites/position/sprite_position.o b/vmm/peripheriques/sprites/position/sprite_position.o
index f1ee2bb632834dd7f877f619cae4c6eac68171de..9da0a592db38edc142945ab2c8ca888d4ab3b155 100644
GIT binary patch
delta 498
zcmX>gwnBJ<hWHCs1~_m4vm6-s8TcmJ`-pYc{+JMZ7%YY$SSCJHXJnbo$*9iAG}#c1
zWS#8DZZVmINq({h(-uK)kS<3)fi@;*UN$!#c8<v#8Koy1FtSYMVb+-(z+Aw{J^3KB
z`D6{2!$KgX41!>ifq{vEfq`=}FRQpGCj$e+-~SL`k1Wf;z`zLQ7eHwcp9RVWQ8PdU
zR2}Q&zpUbu|FH7#zCaRXpRCI!KAD4qXL11B^2z_%7BU7-UdV1P=m0gw1FDv1@=JDo
z#)*?ZGD%PF;N+R?z#+jnV{#;iJ>!DOGdb)9JD}<-5b8PPCwp)TFfCx59L1@|=s&rU
zQ=DlJ<K&HuVv{$p3oyn{KFBG~c>v^O1_lO$$%!2DjOCLVImJ0YK*eT&#fl~$WS8en
zfSJp{z`!**mrGl;0~ACI3=AKjGQ12749t_)a%po`Fhhh6PkzW{&Y1v>-Nwla+2sM5
CEm;@<

delta 905
zcmZ1>d_Zi1hPVSe0~|PjSq=;W4Ez)AeH@zK2zYeX{^;ff33rQvNd9fC5b8kZF^^s_
z+oSXN4v^Rj5V5~u+6)FTYr@IHlM5L|8JQ<8RA*$Kcv5}x0w$J;UsO=3i3>O;9^jb#
zfmK5-I3vG2GcR4CxS%MrBvm2U$3MhMK{Z83Ap$~0f+()Z^BEN<?`Pa9<jTOnz~IOy
z(8lD<%f{ru!_G0ekWp&#0w#mW4U8<z%na<4_cJvzx=wavHfKG|z`!6dxsXwq^%RsP
zGP#oZkWxWWW?o4eLuqkNYH9(<KoAxL5ey6rObiSRT$6oS#Ot{j7#RNkhX8wISq26M
zMkqf7N`rMFiASM{!^}xU6aND-{(ml#I5PtS!=L~E&A?JsPze?W1_o}31X#QUNt_2s
zykPP|7IEGgP+5>O*(R@L5ubdAg@+d$Lr_O@Ouow^&d4(PE6XOfqWqM^lEleNSr;>Q
zPoBsmJlU6>dvZFP<m3Y!9Go|xM)6Lb$fnPDdh$Uwd&Ucs8QJX_A53;+w->wtP7VwV
z6$o|g@{*wNfC_-A2OyU)Ffgc3=46*w^n*IW04#?f*rD2Fz^=H%&chPUz`!t>kwb(@
znQ3w%qZlX|fn2A=kj}us07}D99dI)=paKS9i|U~kK?UKeBA@~@K&o^>VGIgiNJfAw
zVhCV^uoEB@11LvuPrk~bE&2hf-va6_J_ZH`mdT==+MF67gBTbXE`q%P4oFT(&J9qL
JI$@%W3;+|kxLE)I

diff --git a/vmm/peripheriques/sprites/visibility/sprite_visibility.c b/vmm/peripheriques/sprites/visibility/sprite_visibility.c
index 896bdab..90e20cd 100644
--- a/vmm/peripheriques/sprites/visibility/sprite_visibility.c
+++ b/vmm/peripheriques/sprites/visibility/sprite_visibility.c
@@ -24,7 +24,5 @@ void sprite_visibility_store_toggle(void *addr){
 }
 
 void sprite_visibility_conclude(void *addr){
-    printf("Showing sprite SLOT: %d, VISIBILITY: %d\n", sprite_visibility_params.slot, sprite_visibility_params.toggle);
-
-    usleep(10000000);
+    //printf("Showing sprite SLOT: %d, VISIBILITY: %d\n", sprite_visibility_params.slot, sprite_visibility_params.toggle);
 }
\ No newline at end of file
diff --git a/vmm/peripheriques/sprites/visibility/sprite_visibility.o b/vmm/peripheriques/sprites/visibility/sprite_visibility.o
index 4105482dbfb26854589a9df0d65c21e8f5db8f21..f5ec981653ac8bc6357b95cecb080f09f42f3c85 100644
GIT binary patch
delta 441
zcmaDL@<4EchPVPN0~|PjSq=>R415#q&3HO%e@uuy3>IUVcu;+E0wc%74+@M-lLZ;o
z!KC=)07d~u*2#&C_LEOC%1?gII8~4vq~4KFppD6ym(7ibonvw$qx56}MwZEIm~<w8
zV2WVmp6tnNK6wN4K7IxUL6B+&1_mYu1_qAFy)5Fa91IK$e<v%l3Qw+K<>8$Hm1ksN
zU|^l>%PKzEhn0u*21s<WBD?V94%Yt3@@xwkttTI3GZ#F-43c1AFn~}DJd-)u^%<)t
zPh^swyn=&gass;qYc)u2@<LAG$rIQ$7#k+<WVaXm0M(ZOl4D>1>En=}oWUW$m@v7L
zL!Hro@<I-ArW(e{iHu^CFR%$P#!r68A<o$VauovugTZ7+4td7%$%-7}oExBG6=1QV
z$q(7YMFUtM=6XOV1|9|m2Cm7yoZ6xqAb&G3Fn~S8z`(%Ez`(#f`7Eb4Cj-<;`zAAT
PnRCv7n$S4;Ae%e@Q2SBh

delta 733
zcmaDL_&{WWhIj%S0~|PjSq=;W4Ez)A&3u~Q2zYeX{@~xn3KHkvb^*>h(0R<G7cA=0
zd3*;*_63O8-!N?k1DG}8<YABi95YXBRA*$KxKe%c1XhlTHxwY0z+?eNfr&E&CL1ss
zXar~EmuKdsD-;(LWtOBW1pD}hSShHc=qQAF275Yr`gn#!g7{pM;~5nuH!w~SbY@^+
zU~uFUXk&8bWvk<1=a{U>C_UMM$zZYpBMUP#1N-E7rc6fX$tRi2S@$t8FbGUmWE5sS
z3T25*W@O$gUr>~pSCYn1TAY)bS^zSSK@dzbFfcJNFmO&j%Pd~c$-uzy_df*KBg-O*
zd!mW|fhhkUiX_g=z`y_#PlAfGFfcH1A&KW8iE~55g}_EZ9LK=G$iTqBI{7cN_+%Xx
z9^L~`<seb^$+|4!lm9UDOb%e_XDiB2Ni0d6e3xZ0WAWrhR&&7ykW~x}3@e~ocqgA^
z)o0v1S&>nEvH+U~>t>MnWJM0)$pLH{j0YxHve^r2fTNg!Aps=Ez`(#e`6QeC<Q41!
zoC`oUGB7Y`PHtqEXY`x=kWHNN<m8`h>Wtx&71_m^o-$5WWE7h`fmMJpeR3kZIOB`S
zmF((_^^+H}i*rhV!j^%7p#rSAYVtx>anTN_RUR;_7#JA1C-ZV>i%x*5R)AW`$H2hA
fGTE0yn{xvwL>U+u&P;CPFz37gHKB8IBda_BQg*Nv

diff --git a/vmm/peripheriques/state_machine.h b/vmm/peripheriques/state_machine.h
index 11c0fd6..4d4d7c6 100644
--- a/vmm/peripheriques/state_machine.h
+++ b/vmm/peripheriques/state_machine.h
@@ -7,6 +7,7 @@
 typedef enum t_action_t
 {
     WRITE,
+    WRITE_KEY,
     STORE,
     STORE_LOOP,
     EQUALS,
diff --git a/vmm/peripheriques/timer/timer.c b/vmm/peripheriques/timer/timer.c
index fcc8978..180c370 100644
--- a/vmm/peripheriques/timer/timer.c
+++ b/vmm/peripheriques/timer/timer.c
@@ -20,6 +20,6 @@ void timer_store(void *addr){
 void timer_conclude(void *addr){
     hyper_timer_sleep_params_t* tmp_params = addr == NULL ? &timer_params : (hyper_timer_sleep_params_t*) addr;
 
-    printf("\nTime: %d\n", tmp_params->us);
+    // printf("\nTime: %d\n", tmp_params->us);
     usleep(tmp_params->us);
 }
\ No newline at end of file
diff --git a/vmm/peripheriques/timer/timer.o b/vmm/peripheriques/timer/timer.o
index 84284c1e7d0cdeab224af08a1a65de8800d67c67..c998ddc48f6a3977b0dd715af3d190061ca4a6fc 100644
GIT binary patch
delta 474
zcmaDMI7489#^eJW9Q+In3=9q+g291-pMh_pz4OF*a+4T2CZ14WWSaO=oso6&Ll%e0
zF^n>d43o<k%LGk8iXHg`+L)Yq+46bVIVKA-N>7$xGMJpe<iKb$c_EYkWDe$_@Y3R(
z)YJlyVh|Pp5ey6rObiSR><kPHfBr*&F%EGTs5lD)0|N(=dXLG1EaH=YF!M})!_33m
z0aeAwz`(#fS(c?~@^Y4ijNX$yS<M9nm?4rL5Q>3k@<djB#_q`nS?w9SCo{6yGcK6y
z$Yw7XfvJv7UeExl3q~1CW@J}q@n>LQnC!?d!ss*EkzJiN9^{$HYuThHcd#o+mNPIg
zfE)tyB1{{IZkT+KU0t_`fq?<!8Aw=z#36VA)OwhOJPZsBT$4pPv_)@#3}awmxB*ef
ezzg<dD2F!Z2B;O0lRG)gIWIs>Xq@cHDh~k4E?4CM

delta 606
zcmbOs@Ir8chWHB>1~_m4vm6)%82BgJJBuFk=w$_ocyu1$0is`kh>6vzlNebTnI|q(
zpZtN5W#So?i4O!OF&c1jg=FTYS}CZea81@{l$#vDSRxbv(%{G^(8lD<%f{r*!_G1B
zqtxUNj0Te!S(up_*eCNd1u_OqPGs_Djbvb85SaK;Wb#I)K<R>_%)F8`hSK7k)YJk7
z0gx#S3=B*R3=ABTWtqi2IT#oi{``jkHzZkRB=KOVILLdPNa6`d;#`w`nZ+m9F!S&h
zKt&lD7#P?l*D{MUvP_=J+{9LtpORRTI9ZfsF=P7Vhm69L&#<TnW`OKrU|^_#YT}*D
z$g0n{e6k^{J>&Apg{=0B2PSW1wHJH<Rp)_F$0k2{0h<IPH`FX1Nk0Y#29Tu&P&F_r
zda@y#I!ibM1H<G(HW9}1$%Sm{lIaW#4D8U5fGGsg6_YozsY}*FjRJ)eNEC)wO#aBG
zu3N>xzyJyhNF2lD7#K7_f(#4{FbD85FfedWc4gNV1qV1N%t7vBU|`?_nJ~GPU7M2w
U>ahffH`rA;BcP^qLPS`20O+K1L;wH)

diff --git a/vmm/vmm b/vmm/vmm
index 97e079146cc757008d6e95c24a2090587129cae2..e8276973c100f06f69b8301a73bf605f2f5b4172 100755
GIT binary patch
delta 12339
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
NG-o>AG?}YQ4FIB6H#z_S

delta 12302
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
PX6!a+n%p?qs#^^JzNt6c

diff --git a/vmm/vmm.c b/vmm/vmm.c
index 6ba03fc..a74227c 100644
--- a/vmm/vmm.c
+++ b/vmm/vmm.c
@@ -20,30 +20,36 @@
 
 #define SECTOR_SIZE 512
 
-typedef struct t_guest_os_t {
-    uint8_t* code;
+typedef struct t_guest_os_t
+{
+    uint8_t *code;
     long codeSize;
 } guest_os_t;
 
-guest_os_t* readByteCode(char* filePath){
+guest_os_t *readByteCode(char *filePath)
+{
     FILE *file = fopen(filePath, "rb");
-    if (file == NULL) {
+    if (file == NULL)
+    {
         err(1, "fopen");
     }
 
-    guest_os_t* guest_os = malloc(sizeof(guest_os_t));
+    guest_os_t *guest_os = malloc(sizeof(guest_os_t));
 
     fseek(file, 0, SEEK_END);
     guest_os->codeSize = ftell(file);
     fseek(file, 0, SEEK_SET);
 
     guest_os->code = malloc(guest_os->codeSize);
-    
-    fread(guest_os->code, 1, guest_os->codeSize, file); 
 
-    if (ferror(file)) {
+    fread(guest_os->code, 1, guest_os->codeSize, file);
+
+    if (ferror(file))
+    {
         err(1, "Error reading file.");
-    } else {
+    }
+    else
+    {
         printf("File read successfully.\n");
     }
 
@@ -52,13 +58,16 @@ guest_os_t* readByteCode(char* filePath){
     return guest_os;
 }
 
-void write_sector(uint32_t sector_number, const uint8_t *data) {
-    if (sector_number > MAX_SECTOR_NUM) {
+void write_sector(uint32_t sector_number, const uint8_t *data)
+{
+    if (sector_number > MAX_SECTOR_NUM)
+    {
         fprintf(stderr, "Sector number out of range\n");
     }
-    
+
     FILE *disk = fopen(disk_filename, "r+b");
-    if (!disk) {
+    if (!disk)
+    {
         perror("Failed to open disk file");
     }
 
@@ -66,14 +75,16 @@ void write_sector(uint32_t sector_number, const uint8_t *data) {
     uint64_t offset = (uint64_t)sector_number * SECTOR_SIZE;
 
     // Seek to the sector position
-    if (fseek(disk, offset, SEEK_SET) != 0) {
+    if (fseek(disk, offset, SEEK_SET) != 0)
+    {
         perror("Seek failed");
         fclose(disk);
     }
 
     // Write 512 bytes to the specified sector
     size_t bytes_written = fwrite(data, 1, SECTOR_SIZE, disk);
-    if (bytes_written != SECTOR_SIZE) {
+    if (bytes_written != SECTOR_SIZE)
+    {
         perror("Failed to write full sector");
         fclose(disk);
     }
@@ -90,47 +101,55 @@ sem_t display_sem;
 
 uint32_t display_width, display_height;
 
-static uint32_t read_data(uint8_t *addr, uint8_t size) {
+static uint32_t read_data(uint8_t *addr, uint8_t size)
+{
     uint32_t value;
 
-    switch (size) {
-        case 1:
-            value = *(uint8_t *)addr;
+    switch (size)
+    {
+    case 1:
+        value = *(uint8_t *)addr;
         break;
-        case 2:
-            value = *(uint16_t *)addr;
+    case 2:
+        value = *(uint16_t *)addr;
         break;
-        case 4:
-            value = *(uint32_t *)addr;
+    case 4:
+        value = *(uint32_t *)addr;
         break;
-        default:
-            errx(1, "Unsupported size trying to retrieve data.\n");
+    default:
+        errx(1, "Unsupported size trying to retrieve data.\n");
         break;
     }
 
     return value;
 }
 
-void* vcpu_thread_func(void* args){
-    while (1) {
-        if (ioctl(vcpufd, KVM_RUN, NULL) == -1){
+void *vcpu_thread_func(void *args)
+{
+    while (1)
+    {
+        if (ioctl(vcpufd, KVM_RUN, NULL) == -1)
+        {
             err(1, "KVM_RUN");
         }
-            
-        switch (run->exit_reason) {
+
+        switch (run->exit_reason)
+        {
         case KVM_EXIT_HLT:
             puts("KVM_EXIT_HLT");
             return 0;
         case KVM_EXIT_IO:
-            printf("KVM_EXIT_IO\n");
-            if (run->io.direction == KVM_EXIT_IO_OUT){
-                uint32_t value = read_data((uint8_t*) run + run->io.data_offset, run->io.size);
-                if(run->io.size == 1 && run->io.port == 0xABBA){
-                    printf("HYPERCALL!!\n");
+            // printf("KVM_EXIT_IO\n");
+            if (run->io.direction == KVM_EXIT_IO_OUT)
+            {
+                uint32_t value = read_data((uint8_t *)run + run->io.data_offset, run->io.size);
+                if (run->io.size == 1 && run->io.port == 0xABBA)
+                {
+                    // printf("HYPERCALL!!\n");
                     switch (value)
                     {
                     case 1:
-                        hyper_console_params_t console_params = *(hyper_console_params_t*)shared_mem;
+                        hyper_console_params_t console_params = *(hyper_console_params_t *)shared_mem;
                         printf("%s", (char *)mem + console_params.msg);
                         break;
                     case 2:
@@ -151,10 +170,10 @@ void* vcpu_thread_func(void* args){
                         gfx_init_conclude(shared_mem);
                         break;
                     case 4:
-                        hyper_disk_params_t disk_params = *(hyper_disk_params_t*)shared_mem;
-                        uint8_t *data_addr = (uint8_t*) mem + disk_params.data;
+                        hyper_disk_params_t disk_params = *(hyper_disk_params_t *)shared_mem;
+                        uint8_t *data_addr = (uint8_t *)mem + disk_params.data;
                         write_sector(disk_params.sector_idx, data_addr);
-                        
+
                         disk_conclude(shared_mem);
                         break;
                     case 5:
@@ -167,22 +186,26 @@ void* vcpu_thread_func(void* args){
                         break;
                     }
                 }
-                else{
-                    check_state(run->io.port, (uint8_t*) run + run->io.data_offset, run->io.size, value);
+                else
+                {
+                    check_state(run->io.port, (uint8_t *)run + run->io.data_offset, run->io.size, value);
                 }
             }
-            else if (run->io.direction == KVM_EXIT_IO_IN) {
-                check_state(run->io.port, (uint8_t*) run + run->io.data_offset, run->io.size, 0);
+            else if (run->io.direction == KVM_EXIT_IO_IN)
+            {
+                check_state(run->io.port, (uint8_t *)run + run->io.data_offset, run->io.size, 0);
             }
 
             break;
         case KVM_EXIT_MMIO:
-            printf("KVM_EXIT_MMIO\n");
-            if (run->mmio.is_write) {
+            // printf("KVM_EXIT_MMIO\n");
+            if (run->mmio.is_write)
+            {
                 uint32_t value = read_data((uint8_t *)run->mmio.data, run->mmio.len);
                 check_state(run->mmio.phys_addr, run->mmio.data, run->mmio.len, value);
             }
-            else if (!run->mmio.is_write) {
+            else if (!run->mmio.is_write)
+            {
                 check_state(run->mmio.phys_addr, run->mmio.data, run->mmio.len, 0);
             }
             break;
@@ -197,100 +220,135 @@ void* vcpu_thread_func(void* args){
     }
 }
 
-int main(int argc, char **argv){
+int main(int argc, char **argv)
+{
 
-    guest_os_t* guest_os = readByteCode(argv[1]);
+    guest_os_t *guest_os = readByteCode(argv[1]);
     disk_filename = argv[2];
     printf("Disk filename: %s\n", disk_filename);
 
     int kvmfd = open("/dev/kvm", O_RDWR | O_CLOEXEC);
-    if(kvmfd == -1){
+    if (kvmfd == -1)
+    {
         err(1, "/dev/kvm");
     }
 
     int version = ioctl(kvmfd, KVM_GET_API_VERSION, NULL);
-    if(version == -1){
-        err (1 , "KVM_GET_API_VERSION") ;
-    }   
-    if(version != KVM_API_VERSION){
+    if (version == -1)
+    {
+        err(1, "KVM_GET_API_VERSION");
+    }
+    if (version != KVM_API_VERSION)
+    {
         err(1, "Unsupported version of the KVM API");
     }
 
     int vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);
-    if(vmfd == -1){
-        err(1, "KVM_CREATE_VM");        
+    if (vmfd == -1)
+    {
+        err(1, "KVM_CREATE_VM");
     }
 
     uint64_t ram_size = 512 * 4096;
-    mem = mmap(NULL, ram_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0) ;
-    if(!mem){
+    mem = mmap(NULL, ram_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+    if (!mem)
+    {
         err(1, "Allocating guest memory");
     }
 
     printf("Size: %ld\n", guest_os->codeSize);
     memcpy(mem, guest_os->code, guest_os->codeSize);
 
-    struct kvm_userspace_memory_region memreg = {   
+    struct kvm_userspace_memory_region memreg = {
         .slot = 0,
         .guest_phys_addr = 0,
         .memory_size = ram_size,
         .userspace_addr = (uint64_t)mem,
-        .flags = 0
-    };
-    if(ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &memreg) == -1){
-        err(1 , "KVM_SET_USER_MEMORY_REGION");
+        .flags = 0};
+    if (ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &memreg) == -1)
+    {
+        err(1, "KVM_SET_USER_MEMORY_REGION");
     }
 
     uint64_t shared_size = 4096;
-    shared_mem = mmap(NULL, shared_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0) ;
-    if(!shared_mem  ){
+    shared_mem = mmap(NULL, shared_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+    if (!shared_mem)
+    {
         err(1, "Allocating guest memory");
     }
 
-    struct kvm_userspace_memory_region shared_memreg = {   
-        .slot = 1   ,
+    struct kvm_userspace_memory_region shared_memreg = {
+        .slot = 1,
         .guest_phys_addr = 3ULL * 1024 * 1024 * 1024,
         .memory_size = shared_size,
-        .userspace_addr = (uint64_t)shared_mem, 
-        .flags = 0
+        .userspace_addr = (uint64_t)shared_mem,
+        .flags = 0};
+    if (ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &shared_memreg) == -1)
+    {
+        err(1, "KVM_SET_USER_MEMORY_REGION 2");
+    }
+
+    if (ioctl(vmfd, KVM_CREATE_IRQCHIP, NULL) < 0)
+    {
+        err(1, "KVM_GET_IRQCHIP");
+    }
+
+    struct kvm_irqchip irqchip = {
+        .chip_id = 0, // 0 = PIC1 , 1 = PIC2 , 2 = IOAPIC
     };
-    if(ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &shared_memreg) == -1){
-        err(1 , "KVM_SET_USER_MEMORY_REGION 2");
+
+    // Retrieve the PIC registers
+    if (ioctl(vmfd, KVM_GET_IRQCHIP, &irqchip) < 0)
+    {
+        err(1, "KVM_GET_IRQCHIP 1");
+    }
+
+    irqchip.chip.pic.auto_eoi = 1;
+
+    if (ioctl(vmfd, KVM_SET_IRQCHIP, &irqchip) < 0)
+    {
+        err(1, "KVM_SET_IRQCHIP 2");
     }
 
     vcpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
-    if(vcpufd < 0){
+    if (vcpufd < 0)
+    {
         err(1, "KVM_CREATE_VCPU");
     }
 
     int vcpu_mmap_sz = ioctl(kvmfd, KVM_GET_VCPU_MMAP_SIZE, NULL);
-    if(vcpu_mmap_sz == -1){
+    if (vcpu_mmap_sz == -1)
+    {
         err(1, "KVM_GET_VCPU_MMAP_SIZE");
     }
-    if(vcpu_mmap_sz < sizeof(struct kvm_run)){
+    if (vcpu_mmap_sz < sizeof(struct kvm_run))
+    {
         err(1, "KVM_GET_VCPU_MMAP_SIZE unexpectedly small");
     }
 
     run = mmap(NULL, vcpu_mmap_sz, PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0);
-    if(!run){
+    if (!run)
+    {
         err(1, "mmap vcpu");
     }
 
-    struct kvm_sregs sregs ;
-    if(ioctl(vcpufd, KVM_GET_SREGS, &sregs) == -1){
+    struct kvm_sregs sregs;
+    if (ioctl(vcpufd, KVM_GET_SREGS, &sregs) == -1)
+    {
         err(1, "KVM_GET_SREGS");
     }
 
     sregs.cs.base = 0;
     sregs.cs.selector = 0;
-    sregs.ds.base = 0;  
+    sregs.ds.base = 0;
     sregs.ds.selector = 0;
     sregs.es.base = 0;
     sregs.es.selector = 0;
     sregs.ss.base = 0;
     sregs.ss.selector = 0;
 
-    if(ioctl(vcpufd, KVM_SET_SREGS, &sregs) == -1){
+    if (ioctl(vcpufd, KVM_SET_SREGS, &sregs) == -1)
+    {
         err(1, "KVM_SET_SREGS");
     }
 
@@ -300,8 +358,9 @@ int main(int argc, char **argv){
     regs.rip = 0;
     regs.rsp = ram_size;
     regs.rflags = 0x2;
-    
-    if(ioctl(vcpufd, KVM_SET_REGS, &regs) == -1){
+
+    if (ioctl(vcpufd, KVM_SET_REGS, &regs) == -1)
+    {
         err(1, "KVM_SET_REGS");
     }
 
@@ -317,7 +376,46 @@ int main(int argc, char **argv){
 
     gfx_context_t *ctxt = gfx_create("Display", display_width, display_height);
 
-    if(pthread_join(vcpu_thread, NULL)==-1){
+    bool quit = false;
+
+    while (!quit)
+    {
+        SDL_Keycode key = gfx_keypressed();
+
+        if (key != 0)
+        {
+            keyboard_params.key = key;
+
+            struct kvm_irq_level irq_level;
+            irq_level.irq = 1;
+
+            irq_level.level = 1;
+            if (ioctl(vmfd, KVM_IRQ_LINE, &irq_level) < 0)
+            {
+                err(1, "KVM_GET_IRQCHIP UP");
+            }
+
+            irq_level.level = 0;
+            if (ioctl(vmfd, KVM_IRQ_LINE, &irq_level) < 0)
+            {
+                err(1, "KVM_GET_IRQCHIP DOWN");
+            }
+
+            printf("Stored Key: %d\n", keyboard_params.key);
+            // sleep(10);
+            // usleep(10000000);
+
+            if (key == SDLK_ESCAPE)
+            {
+                quit = true;
+            }
+        }
+    }
+
+    pthread_cancel(vcpu_thread);
+
+    if (pthread_join(vcpu_thread, NULL) == -1)
+    {
         err(1, "pthread_join");
     }
     gfx_destroy(ctxt);
diff --git a/vmm/vmm.d b/vmm/vmm.d
index 9aaecd3..39fc2c3 100644
--- a/vmm/vmm.d
+++ b/vmm/vmm.d
@@ -14,4 +14,7 @@ vmm.o: vmm.c ../shared/hypercall_params.h gfx/gfx.h \
  peripheriques/sprites/visibility/sprite_visibility.h \
  peripheriques/sprites/visibility/../sprites.h \
  peripheriques/sprites/position/sprite_position.h \
- peripheriques/sprites/position/../sprites.h
+ peripheriques/sprites/position/../sprites.h \
+ peripheriques/keyboard/keyboard.h \
+ peripheriques/keyboard/../state_machine.h \
+ peripheriques/keyboard/../../../shared/hypercall_params.h
diff --git a/vmm/vmm.o b/vmm/vmm.o
index 4c48b43b41dd8dc4eb5610e5d1083e00fac67519..778c71c6720e4ea5ca446543501f6e961982c3bf 100644
GIT binary patch
delta 4824
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
BN?ZT{

delta 4024
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

-- 
GitLab