Index: lab5/Makefile
===================================================================
--- lab5/Makefile	(revision 126)
+++ lab5/Makefile	(revision 127)
@@ -2,11 +2,11 @@
 PROG=lab5
 
 # source code files to be compiled
-SRCS = lab5.c graphics.c keyboard.c kbc.c utils.c sprite.c
+SRCS = lab5.c graphics.c keyboard.c timer.c kbc.c utils.c sprite.c
 
 # additional compilation flags
 # "-Wall -Wextra -Werror -I . -std=c11 -Wno-unused-parameter" are already set
-CFLAGS += -pedantic -c
+CFLAGS += -pedantic
 
 # list of library dependencies (for Lab 2, only LCF library)
 DPADD += ${LIBLCF}
Index: lab5/lab5.c
===================================================================
--- lab5/lab5.c	(revision 126)
+++ lab5/lab5.c	(revision 127)
@@ -11,6 +11,7 @@
 #include "keyboard.h"
 #include "kbc.h"
 #include "kbc_macros.h"
+#include "timer.h"
 
 // Any header files included below this line should have been created by you
 
@@ -345,8 +346,127 @@
 }
 
 int(video_test_move)(xpm_map_t xpm, uint16_t xi, uint16_t yi, uint16_t xf, uint16_t yf, int16_t speed, uint8_t fr_rate) {
+    int r;
 
-    return 1;
+    if (vbe_get_mode_information(INDEXED_1024_768)) {
+        printf("%s: failed to get information for mode %x.\n", __func__, INDEXED_1024_768);
+        if (vg_exit())
+            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
+        return 1;
+    }
+
+    map_vram(); // if function fails it aborts program
+
+    if (set_graphics_mode(INDEXED_1024_768)) {
+        printf("%s: failed to set graphic mode %x.\n", __func__, INDEXED_1024_768);
+        if (vg_exit()) printf("%s: vg_exit failed to exit to text mode.\n", __func__);
+        return 1;
+    };
+
+    sprite_t *sp = sprite_ctor(xpm);
+
+    /// Timer interrupt handling
+    const uint32_t frequency = sys_hz(); // Frequency asummed at 60Hz
+    uint8_t timer_irq_bit = 0;
+    int timer_id = 0;
+    int timer_irq = BIT(timer_irq_bit);
+    if(subscribe_timer_interrupt(timer_irq_bit, &timer_id)) return 1;
+
+    no_interrupts = 0;
+    /// Keyboard interrupt handling
+    uint8_t kbc_irq_bit = KBC_IRQ;
+    int kbc_id = 0;
+    int kbc_irq = BIT(kbc_irq_bit);
+    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) {
+        if (vg_exit()) {
+            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
+            if (free_memory()) printf("%s: lm_free failed\n", __func__);
+        }
+        return 1;
+    }
+    ///
+    uint16_t dx = xf-xi;
+    uint16_t dy = yf-yi;
+    if(xi != xf) dy = 0;
+    else         dx = 0;
+    uint16_t dframe = (speed <= 0 ? 1 : speed);
+    uint16_t Nt     = (speed <  0 ? -speed : 1);
+    uint32_t dt     = frequency/(uint32_t)fr_rate;
+
+    /// loop stuff
+    int ipc_status;
+    message msg;
+    /// cycle
+    uint16_t x = xi, y = yi;
+    int i = Nt-1;
+    int good = 1;
+    while (good) {
+
+        /* Get a request message. */
+        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
+            printf("driver_receive failed with %d", r);
+            continue;
+        }
+        if (is_ipc_notify(ipc_status)) { /* received notification */
+            switch (_ENDPOINT_P(msg.m_source)) {
+                case HARDWARE: /* hardware interrupt notification */
+                    if (msg.m_notify.interrupts & timer_irq) { /* subscribed interrupt */
+                        timer_int_handler();
+                    }
+                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
+                        kbc_ih();
+                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
+                    }
+                    break;
+                default:
+                    break; /* no other notifications expected: do nothing */
+            }
+        } else { /* received standart message, not a notification */
+            /* no standart message expected: do nothing */
+        }
+        if(good == 0) continue;
+        if(no_interrupts == dt){
+            no_interrupts = 0;
+            i = (i+1)%Nt;
+            if(i == 0){
+                if(dx) x += dframe;
+                if(dy) y += dframe;
+                if((dx < 0 && x <= xf)||
+                   (dx > 0 && x >= xf)){
+                    x = xf;
+                    good = 0;
+                }
+                if((dy < 0 && y <= yf)||
+                   (dy > 0 && y >= yf)){
+                    y = yf;
+                    good = 0;
+                }
+                sprite_set_pos(sp,x,y);
+                sprite_draw(sp);
+            }
+        }
+    }
+
+    if (unsubscribe_interrupt(&kbc_id)) {
+        if (vg_exit()) {
+            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
+            if (free_memory()) printf("%s: lm_free failed\n", __func__);
+        }
+        return 1;
+    };
+
+    if (vg_exit()) {
+        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
+        if (free_memory()) printf("%s: lm_free failed\n", __func__);
+        return 1;
+    }
+
+    if (free_memory()) {
+        printf("%s: lm_free failed\n", __func__);
+        return 1;
+    }
+
+    return 0;
 }
 
 int(video_test_controller)() {
