Hi,

In the code below (tiny hobby OS), the PS/2 mouse moves erratically in QEMU
i386 (jumps around, looks broken). How can I fix this?

Thanks,
Emiralp
#!/usr/bin/env python3
import os

print("🔥 EmirAlp OS - MOUSE FIXED WITH PS/2 POLLING - Like KolibriOS!")

# === LINKER ===
with open("linker.ld", "w") as f:
    f.write("""ENTRY(start)
SECTIONS {
    . = 1M;
    .text : { *(.multiboot) *(.text) }
    .data : { *(.data) }
    .rodata : { *(.rodata) }
    .bss : { *(.bss) *(COMMON) }
}
""")

# === BOOT ===
with open("boot.s", "w") as f:
    f.write("""BITS 32
section .multiboot
align 4
    dd 0x1BADB002
    dd 0x00000003
    dd -(0x1BADB002 + 0x00000003)

section .bss
align 16
stack_bottom: resb 131072
stack_top:

section .text
global start
extern kmain

start:
    mov esp, stack_top
    call kmain
    cli
.hang:
    hlt
    jmp .hang
""")

# === KERNEL WITH PROPER PS/2 POLLING LIKE KOLIBRI ===
with open("kernel.c", "w") as f:
    f.write(r'''#include <stdint.h>
#include <stddef.h>

#define VGA_WIDTH 80
#define VGA_HEIGHT 25
#define MAX_WINDOWS 15

typedef struct {
    int x, y, w, h;
    char title[50];
    int active, minimized;
    uint8_t type;
} Window;

// === GLOBALS ===
uint16_t* vga = (uint16_t*)0xB8000;
uint16_t buffer[VGA_WIDTH * VGA_HEIGHT];
Window windows[MAX_WINDOWS];
int window_count = 0;
int current_window = 0;

// MOUSE - Simple polling
int mouse_x = 40;
int mouse_y = 12;
int mouse_left = 0;
int mouse_right = 0;
int mouse_middle = 0;

// Snake
int snake_x[100], snake_y[100], snake_len = 5;
int snake_dir = 0, food_x = 15, food_y = 10, snake_score = 0;

// === I/O ===
static inline void outb(uint16_t port, uint8_t val) {
    asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
}

static inline uint8_t inb(uint16_t port) {
    uint8_t ret;
    asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
    return ret;
}

static inline void io_wait(void) {
    outb(0x80, 0);
}

// === STRING ===
size_t strlen(const char* s) { size_t l=0; while(s[l]) l++; return l; }
void strcpy(char* d, const char* s) { while((*d++ = *s++)); }
void reverse(char s[]) { int i,j; char c; for(i=0,j=strlen(s)-1;i<j;i++,j--) { c=s[i];s[i]=s[j];s[j]=c; } }
void itoa(int n, char s[]) { 
    int i=0,sign=n; 
    if(sign<0)n=-n; 
    do{s[i++]=n%10+'0';}while((n/=10)>0); 
    if(sign<0)s[i++]='-'; 
    s[i]=0; 
    reverse(s); 
}

// === VGA ===
void set_char(int x, int y, char c, uint8_t color) {
    if(x >= 0 && x < VGA_WIDTH && y >= 0 && y < VGA_HEIGHT)
        buffer[y * VGA_WIDTH + x] = (uint16_t)c | ((uint16_t)color << 8);
}

void flip() {
    for(int i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) vga[i] = buffer[i];
}

void fill_box(int x, int y, int w, int h, char c, uint8_t color) {
    for(int j = y; j < y + h && j < VGA_HEIGHT; j++)
        for(int i = x; i < x + w && i < VGA_WIDTH; i++)
            set_char(i, j, c, color);
}

void draw_box(int x, int y, int w, int h, uint8_t color) {
    if(x<0||y<0||x+w>VGA_WIDTH||y+h>VGA_HEIGHT) return;
    set_char(x, y, 218, color); set_char(x+w-1, y, 191, color);
    set_char(x, y+h-1, 192, color); set_char(x+w-1, y+h-1, 217, color);
    for(int i=1; i<w-1; i++) { set_char(x+i, y, 196, color); set_char(x+i, y+h-1, 196, color); }
    for(int i=1; i<h-1; i++) { set_char(x, y+i, 179, color); set_char(x+w-1, y+i, 179, color); }
}

void draw_text(int x, int y, const char* text, uint8_t color) {
    for(int i = 0; text[i] && x + i < VGA_WIDTH; i++)
        set_char(x + i, y, text[i], color);
}

void draw_text_centered(int y, const char* text, uint8_t color) {
    draw_text((VGA_WIDTH - strlen(text)) / 2, y, text, color);
}

// === MOUSE - KOLIBRI STYLE POLLING ===
void ps2_wait_write() {
    volatile int timeout = 100000;
    while(timeout--) {
        if((inb(0x64) & 2) == 0) return;
    }
}

void ps2_wait_read() {
    volatile int timeout = 100000;
    while(timeout--) {
        if((inb(0x64) & 1) == 1) return;
    }
}

void ps2_write_cmd(uint8_t cmd) {
    ps2_wait_write();
    outb(0x64, cmd);
}

void ps2_write_data(uint8_t data) {
    ps2_wait_write();
    outb(0x60, data);
}

uint8_t ps2_read_data() {
    ps2_wait_read();
    return inb(0x60);
}

void mouse_write(uint8_t data) {
    ps2_write_cmd(0xD4);
    ps2_write_data(data);
    ps2_read_data(); // ACK
}

void init_mouse() {
    // Disable devices
    ps2_write_cmd(0xAD);
    ps2_write_cmd(0xA7);
    io_wait();
    
    // Flush output buffer
    inb(0x60);
    
    // Enable auxiliary device
    ps2_write_cmd(0xA8);
    io_wait();
    
    // Get config
    ps2_write_cmd(0x20);
    uint8_t status = ps2_read_data();
    
    // Enable interrupts and scanning
    status |= 0x02;  // Enable mouse interrupt
    status &= ~0x20; // Enable mouse clock
    
    ps2_write_cmd(0x60);
    ps2_write_data(status);
    io_wait();
    
    // Reset mouse
    mouse_write(0xFF);
    ps2_read_data(); // 0xFA - ACK
    ps2_read_data(); // 0xAA - self test
    ps2_read_data(); // 0x00 - mouse ID
    
    // Set defaults
    mouse_write(0xF6);
    
    // Enable data reporting
    mouse_write(0xF4);
    
    // Enable devices
    ps2_write_cmd(0xAE);
    ps2_write_cmd(0xA8);
}

void poll_mouse() {
    static int cycle = 0;
    static int8_t packet[3];
    
    // Check if data available
    uint8_t status = inb(0x64);
    if(!(status & 0x01)) return;
    
    // Check if it's mouse data
    if(!(status & 0x20)) return;
    
    // Read byte
    uint8_t data = inb(0x60);
    
    // Build packet
    packet[cycle++] = data;
    
    if(cycle == 3) {
        cycle = 0;
        
        // Validate packet (bit 3 must be 1)
        if(!(packet[0] & 0x08)) return;
        
        // Get buttons
        mouse_left = packet[0] & 0x01;
        mouse_right = packet[0] & 0x02;
        mouse_middle = packet[0] & 0x04;
        
        // Get movement
        int dx = packet[1];
        int dy = packet[2];
        
        // Sign extend if needed
        if(packet[0] & 0x10) dx |= 0xFFFFFF00;
        if(packet[0] & 0x20) dy |= 0xFFFFFF00;
        
        // Check for overflow
        if(packet[0] & 0x40) dy = 0;
        if(packet[0] & 0x80) dx = 0;
        
        // Update position - SLOW MOVEMENT
        mouse_x += dx / 4;
        mouse_y -= dy / 4;
        
        // Bounds
        if(mouse_x < 0) mouse_x = 0;
        if(mouse_x >= VGA_WIDTH) mouse_x = VGA_WIDTH - 1;
        if(mouse_y < 0) mouse_y = 0;
        if(mouse_y >= VGA_HEIGHT) mouse_y = VGA_HEIGHT - 1;
    }
}

void draw_mouse() {
    // Big cursor
    set_char(mouse_x, mouse_y, 219, 0x0F);
    
    // Show click state
    if(mouse_left) {
        set_char(mouse_x, mouse_y, 219, 0x0C);
        if(mouse_x > 0) set_char(mouse_x - 1, mouse_y, 175, 0x0C);
        if(mouse_x < VGA_WIDTH - 1) set_char(mouse_x + 1, mouse_y, 174, 0x0C);
    }
}

// === KEYBOARD ===
uint8_t get_scancode() {
    uint8_t status = inb(0x64);
    if(status & 0x01) {
        // Only read if it's keyboard data (not mouse)
        if(!(status & 0x20)) {
            return inb(0x60);
        } else {
            inb(0x60); // Discard mouse data
        }
    }
    return 0;
}

// === WINDOWS ===
void create_window(const char* title, int x, int y, int w, int h, uint8_t type) {
    if(window_count >= MAX_WINDOWS) return;
    Window* win = &windows[window_count++];
    strcpy(win->title, title);
    win->x = x; win->y = y; win->w = w; win->h = h;
    win->active = 1; win->minimized = 0; win->type = type;
    current_window = window_count - 1;
}

void draw_window(Window* win, int selected) {
    if(!win->active || win->minimized) return;
    
    // Shadow
    for(int j = win->y + 1; j <= win->y + win->h && j < VGA_HEIGHT; j++)
        set_char(win->x + win->w, j, 177, 0x08);
    for(int i = win->x + 1; i <= win->x + win->w && i < VGA_WIDTH; i++)
        set_char(i, win->y + win->h, 177, 0x08);
    
    // Title bar
    uint8_t title_color = selected ? 0x1F : 0x70;
    fill_box(win->x, win->y, win->w, 1, ' ', title_color);
    draw_text(win->x + 2, win->y, win->title, title_color);
    draw_text(win->x + win->w - 3, win->y, "[X]", 0xCF);
    
    // Content
    fill_box(win->x, win->y + 1, win->w, win->h - 1, ' ', 0x70);
    draw_box(win->x, win->y, win->w, win->h, selected ? 0x0F : 0x08);
    
    if(win->type == 1) { // Files
        draw_text_centered(win->y + 2, "FILE MANAGER", 0x0E);
        fill_box(win->x + 1, win->y + 3, win->w - 2, 1, ' ', 0x30);
        draw_text(win->x + 2, win->y + 3, "C:\\Users\\emiralpK", 0x3F);
        const char* files[] = {"Documents", "Pictures", "Music", "Videos", "Downloads"};
        for(int i = 0; i < 5; i++) {
            set_char(win->x + 2, win->y + 5 + i, 254, 0x0E);
            draw_text(win->x + 4, win->y + 5 + i, files[i], 0x0F);
        }
    }
    else if(win->type == 2) { // Editor
        draw_text_centered(win->y + 2, "TEXT EDITOR", 0x09);
        fill_box(win->x + 1, win->y + 3, win->w - 2, 1, ' ', 0x30);
        draw_text(win->x + 2, win->y + 3, "document.txt", 0x3F);
        fill_box(win->x + 1, win->y + 4, win->w - 2, win->h - 5, ' ', 0x1F);
        draw_text(win->x + 2, win->y + 5, "EmirAlp OS - Kolibri Style Mouse!", 0x09);
        draw_text(win->x + 2, win->y + 7, "Mouse is working now!", 0x0A);
        draw_text(win->x + 2, win->y + 8, "Click icons to open apps", 0x08);
        draw_text(win->x + 2, win->y + 9, "Click [X] to close windows", 0x08);
    }
    else if(win->type == 3) { // Paint
        draw_text_centered(win->y + 2, "PAINT", 0x0D);
        for(int i = 0; i < 16; i++) 
            set_char(win->x + 2 + i, win->y + 3, 219, i);
        fill_box(win->x + 2, win->y + 5, win->w - 4, win->h - 7, ' ', 0x77);
        draw_box(win->x + 2, win->y + 5, win->w - 4, win->h - 7, 0x00);
    }
    else if(win->type == 4) { // Snake
        draw_text_centered(win->y + 2, "SNAKE", 0x0A);
        char score[30] = "Score: ";
        char num[10]; itoa(snake_score, num);
        draw_text(win->x + 2, win->y + 2, score, 0x0E);
        draw_text(win->x + 9, win->y + 2, num, 0x0E);
        
        fill_box(win->x + 2, win->y + 4, win->w - 4, win->h - 6, ' ', 0x00);
        draw_box(win->x + 2, win->y + 4, win->w - 4, win->h - 6, 0x0A);
        
        for(int i = 0; i < snake_len; i++) {
            if(snake_x[i] >= 0 && snake_x[i] < win->w - 4 && 
               snake_y[i] >= 0 && snake_y[i] < win->h - 6) {
                set_char(win->x + 2 + snake_x[i], win->y + 4 + snake_y[i], 
                        i == 0 ? 2 : 219, 0x0A);
            }
        }
        if(food_x >= 0 && food_x < win->w - 4 && food_y >= 0 && food_y < win->h - 6)
            set_char(win->x + 2 + food_x, win->y + 4 + food_y, 4, 0x0C);
    }
    else if(win->type == 5) { // System
        draw_text_centered(win->y + 2, "SYSTEM INFO", 0x0B);
        draw_text(win->x + 2, win->y + 4, "OS:", 0x0E);
        draw_text(win->x + 18, win->y + 4, "EmirAlp OS v6.0", 0x0F);
        draw_text(win->x + 2, win->y + 5, "Mouse Style:", 0x0E);
        draw_text(win->x + 18, win->y + 5, "Kolibri Polling", 0x0A);
        draw_text(win->x + 2, win->y + 6, "Position:", 0x0E);
        char pos[30] = "";
        char num[10];
        itoa(mouse_x, num); strcpy(pos, num);
        draw_text(win->x + 18, win->y + 6, pos, 0x0A);
        draw_text(win->x + 21, win->y + 6, ",", 0x0A);
        itoa(mouse_y, num);
        draw_text(win->x + 22, win->y + 6, num, 0x0A);
        draw_text(win->x + 2, win->y + 7, "Left Button:", 0x0E);
        draw_text(win->x + 18, win->y + 7, mouse_left ? "PRESSED" : "Released", mouse_left ? 0x0C : 0x08);
    }
    else { // Welcome
        draw_text_centered(win->y + 3, "WELCOME!", 0x0E);
        draw_text_centered(win->y + 5, "EmirAlp OS v6.0", 0x0B);
        draw_text_centered(win->y + 6, "Kolibri Style Mouse!", 0x0A);
        draw_text_centered(win->y + 8, "CONTROLS:", 0x0E);
        draw_text(win->x + 3, win->y + 9, "MOUSE - Click icons & windows", 0x0F);
        draw_text(win->x + 3, win->y + 10, "F1-F5 - Quick launch apps", 0x0F);
        draw_text(win->x + 3, win->y + 11, "Arrow Keys - Snake game", 0x0F);
        draw_text(win->x + 3, win->y + 12, "ESC - Close window", 0x0F);
    }
}

void handle_click(int mx, int my) {
    // Check windows first
    for(int i = window_count - 1; i >= 0; i--) {
        Window* win = &windows[i];
        if(!win->active || win->minimized) continue;
        
        if(mx >= win->x && mx < win->x + win->w && my >= win->y && my < win->y + win->h) {
            current_window = i;
            
            // Close button
            if(my == win->y && mx >= win->x + win->w - 3) {
                win->active = 0;
                for(int j = i; j < window_count - 1; j++)
                    windows[j] = windows[j+1];
                window_count--;
                if(current_window >= window_count) current_window = window_count - 1;
            }
            return;
        }
    }
    
    // Desktop icons
    int icons_x[] = {2, 14, 26, 38, 50};
    int icons_y[] = {2, 2, 2, 2, 2};
    const char* titles[] = {"Files", "Editor", "Paint", "Snake", "System"};
    
    for(int i = 0; i < 5; i++) {
        if(mx >= icons_x[i] && mx < icons_x[i] + 10 && 
           my >= icons_y[i] && my < icons_y[i] + 5) {
            create_window(titles[i], 8 + i*3, 4 + i, 
                        i == 3 ? 45 : 50, 
                        i == 3 ? 16 : 14, i + 1);
            return;
        }
    }
}

// === DESKTOP ===
void draw_icon(int x, int y, const char* label, char icon, uint8_t color) {
    fill_box(x, y, 10, 5, ' ', color);
    draw_box(x, y, 10, 5, 0x08);
    set_char(x + 4, y + 1, icon, color | 0x0F);
    set_char(x + 3, y + 2, icon, color | 0x08);
    set_char(x + 5, y + 2, icon, color | 0x08);
    int len = strlen(label);
    draw_text(x + (10 - len) / 2, y + 4, label, color | 0x0F);
}

void draw_desktop() {
    for(int y = 1; y < VGA_HEIGHT - 1; y++) {
        for(int x = 0; x < VGA_WIDTH; x++) {
            char c = ((x + y) % 4 == 0) ? 176 : ' ';
            set_char(x, y, c, 0x03);
        }
    }
    
    draw_icon(2, 2, "Files", 254, 0x30);
    draw_icon(14, 2, "Editor", 240, 0x60);
    draw_icon(26, 2, "Paint", 234, 0x50);
    draw_icon(38, 2, "Snake", 2, 0x90);
    draw_icon(50, 2, "System", 15, 0x80);
}

void draw_taskbar() {
    fill_box(0, VGA_HEIGHT - 1, VGA_WIDTH, 1, ' ', 0x30);
    draw_text(2, VGA_HEIGHT - 1, "[KOLIBRI MOUSE]", 0x3F);
    
    int x = 19;
    for(int i = 0; i < window_count; i++) {
        if(windows[i].active) {
            char btn[20] = "[";
            int len = strlen(windows[i].title);
            if(len > 8) len = 8;
            for(int j = 0; j < len; j++) btn[j+1] = windows[i].title[j];
            btn[len+1] = ']'; btn[len+2] = 0;
            draw_text(x, VGA_HEIGHT - 1, btn, i == current_window ? 0x3E : 0x38);
            x += len + 3;
        }
    }
}

void update_snake() {
    int new_x = snake_x[0], new_y = snake_y[0];
    if(snake_dir == 0) new_x++; else if(snake_dir == 1) new_x--;
    else if(snake_dir == 2) new_y--; else if(snake_dir == 3) new_y++;
    
    if(window_count > 0 && windows[current_window].type == 4) {
        int max_x = windows[current_window].w - 4;
        int max_y = windows[current_window].h - 6;
        
        if(new_x < 0 || new_x >= max_x || new_y < 0 || new_y >= max_y) {
            snake_len = 5;
            for(int i = 0; i < 5; i++) { snake_x[i] = 10 - i; snake_y[i] = 10; }
            snake_score = 0;
            return;
        }
        
        if(new_x == food_x && new_y == food_y) {
            snake_len++; snake_score += 10;
            food_x = (food_x + 7) % max_x;
            food_y = (food_y + 5) % max_y;
        }
        
        for(int i = snake_len - 1; i > 0; i--) {
            snake_x[i] = snake_x[i-1]; snake_y[i] = snake_y[i-1];
        }
        snake_x[0] = new_x; snake_y[0] = new_y;
    }
}

// === MAIN ===
void kmain() {
    init_mouse();
    
    fill_box(0, 0, VGA_WIDTH, VGA_HEIGHT, ' ', 0x01);
    draw_text_centered(10, "==========================================", 0x0F);
    draw_text_centered(11, "   EmirAlp OS v6.0 - Kolibri Mouse!", 0x0E);
    draw_text_centered(12, "==========================================", 0x0F);
    draw_text_centered(14, "PS/2 Polling initialized...", 0x0A);
    flip();
    for(volatile int i = 0; i < 8000000; i++);
    
    for(int i = 0; i < 5; i++) { snake_x[i] = 10 - i; snake_y[i] = 10; }
    
    create_window("Welcome!", 18, 5, 44, 14, 0);
    
    int frame = 0;
    int old_mouse_left = 0;
    
    while(1) {
        draw_desktop();
        
        fill_box(0, 0, VGA_WIDTH, 1, ' ', 0x50);
        draw_text(2, 0, "EmirAlp OS v6.0 - Kolibri Style PS/2 Mouse", 0x5F);
        char mpos[30] = "X:";
        char num[10];
        itoa(mouse_x, num);
        draw_text(VGA_WIDTH - 20, 0, mpos, 0x5A);
        draw_text(VGA_WIDTH - 18, 0, num, 0x5A);
        draw_text(VGA_WIDTH - 15, 0, " Y:", 0x5A);
        itoa(mouse_y, num);
        draw_text(VGA_WIDTH - 12, 0, num, 0x5A);
        draw_text(VGA_WIDTH - 8, 0, mouse_left ? "[CLICK]" : "       ", mouse_left ? 0x5C : 0x58);
        
        for(int i = 0; i < window_count; i++)
            draw_window(&windows[i], i == current_window);
        
        draw_taskbar();
        draw_mouse();
        flip();
        
        if(frame % 15 == 0 && window_count > 0 && windows[current_window].type == 4)
            update_snake();
        
        // POLL MOUSE
        poll_mouse();
        
        // Detect new click
        if(mouse_left && !old_mouse_left) {
            handle_click(mouse_x, mouse_y);
        }
        old_mouse_left = mouse_left;
        
        // KEYBOARD
        uint8_t scan = get_scancode();
        if(scan) {
            if(scan == 72 && window_count > 0 && windows[current_window].type == 4) snake_dir = 2;
            else if(scan == 80 && window_count > 0 && windows[current_window].type == 4) snake_dir = 3;
            else if(scan == 75 && window_count > 0 && windows[current_window].type == 4) snake_dir = 1;
            else if(scan == 77 && window_count > 0 && windows[current_window].type == 4) snake_dir = 0;
            else if(scan == 1 && window_count > 0) {
                windows[current_window].active = 0;
                for(int i = current_window; i < window_count - 1; i++)
                    windows[i] = windows[i+1];
                window_count--;
                if(current_window >= window_count) current_window = window_count - 1;
            }
            else if(scan == 59) create_window("Files", 8, 4, 50, 14, 1);
            else if(scan == 60) create_window("Editor", 12, 5, 55, 15, 2);
            else if(scan == 61) create_window("Paint", 16, 6, 50, 16, 3);
            else if(scan == 62) create_window("Snake", 10, 5, 45, 16, 4);
            else if(scan == 63) create_window("System", 20, 6, 45, 12, 5);
        }
        
        for(volatile int i = 0; i < 80000; i++);
        frame++;
    }
}
''')

# === GRUB ===
os.makedirs("iso/boot/grub", exist_ok=True)
with open("iso/boot/grub/grub.cfg", "w") as f:
    f.write("""set timeout=3
menuentry "EmirAlp OS v6.0 - Kolibri Mouse!" {
    multiboot /boot/kernel.bin
    boot
}
""")

# === BUILD ===
with open("build.sh", "w") as f:
    f.write("""#!/bin/bash
set -e
echo ""
echo "🔥🔥🔥 EmirAlp OS v6.0 - KOLIBRI STYLE PS/2 MOUSE 🔥🔥🔥"
echo ""
nasm -f elf32 boot.s -o boot.o && echo "✓ ASM"
gcc -m32 -c kernel.c -o kernel.o -ffreestanding -O2 -Wall -Wextra -Wno-unused -nostdlib -fno-builtin -fno-stack-protector && echo "✓ GCC"
ld -m elf_i386 -T linker.ld -o iso/boot/kernel.bin boot.o kernel.o && echo "✓ LD"
grub-mkrescue -o emiralp_os.iso iso 2>/dev/null && echo "✓ ISO"
rm -f *.o
echo ""
echo "✅✅✅ KOLIBRI STYLE MOUSE READY! ✅✅✅"
echo ""
echo "🖱️  MOUSE FEATURES (KOLIBRI STYLE):"
echo "   ✓ Proper PS/2 controller initialization"
echo "   ✓ Device disable/enable sequence"
echo "   ✓ Config byte manipulation"
echo "   ✓ Mouse reset and self-test"
echo "   ✓ Polling mode (not interrupt)"
echo "   ✓ Packet validation"
echo "   ✓ Overflow handling"
echo "   ✓ Click detection"
echo "   ✓ Real-time position on top bar"
echo ""
echo "⌨️  KEYBOARD FIXED TOO:"
echo "   ✓ Proper scancode reading"
echo "   ✓ Mouse data filtering"
echo "   ✓ ESC closes windows"
echo "   ✓ Arrow keys for Snake"
echo "   ✓ F1-F5 quick launch"
echo ""
echo "🚀 RUN:"
echo "   qemu-system-i386 -cdrom emiralp_os.iso"
echo ""
""")

os.chmod("build.sh", 0o755)

print("\n✅✅✅ KOLİBRİ STYLE PS/2 MOUSE! ✅✅✅")
print("\n🖱️ YENİ YAKLAŞIM - KOLİBRİOS GİBİ:")
print("  ✓ PS/2 controller düzgün init")
print("  ✓ Device disable/enable")
print("  ✓ Config byte düzeltmesi")
print("  ✓ Mouse reset + self test")
print("  ✓ Polling mode (interrupt yok)")
print("  ✓ Keyboard ve mouse ayrımı")
print("  ✓ ESC tuşu artık çalışıyor!")
print("\n⌨️ KLAVYE DÜZELTİLDİ:")
print("  ✓ ESC - Pencere kapat")
print("  ✓ F1-F5 - Hızlı başlat")
print("  ✓ Arrow Keys - Snake")
print("\n🔨 BUILD:")
print("  ./build.sh")
print("\n🚀 RUN:")
print("  qemu-system-i386 -cdrom emiralp_os.iso")
print("\n💡 BU SEFER GERÇEKTEN ÇALIŞACAK! KOLİBRİ STYLE! 🎯")

Reply via email to