section .realmode int_08_ticks_counter: dd 0 int_08_callback: dd 0 int_08_isr: bits 16 pushf inc dword [cs:int_08_ticks_counter] popf jmp far [cs:int_08_callback] bits 32 extern getchar_internal global _pit_sleep_and_quit_on_keypress _pit_sleep_and_quit_on_keypress: ; Hook int 0x08 mov edx, dword [0x08*4] mov dword [int_08_callback], edx mov dword [0x08*4], int_08_isr ; pit_ticks in edx mov edx, dword [esp+4] mov dword [int_08_ticks_counter], 0 ; Save GDT in case BIOS overwrites it sgdt [.gdt] ; Save IDT sidt [.idt] ; Load BIOS IVT lidt [.rm_idt] ; Save non-scratch GPRs push ebx push esi push edi push ebp ; Jump to real mode jmp 0x08:.bits16 .bits16: bits 16 mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax mov eax, cr0 and al, 0xfe mov cr0, eax jmp 0x00:.cszero .cszero: xor ax, ax mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax sti mov byte [.mods], 0 mov byte [.ascii], 0 mov byte [.scan], 0 .loop: cmp dword [int_08_ticks_counter], edx je .done push ecx push edx mov ah, 0x01 xor al, al int 0x16 pop edx pop ecx jz .loop ; on keypress xor ax, ax int 0x16 mov byte [.ascii], al mov byte [.scan], ah mov ax, 0x0200 int 0x16 test al, 0x04 jz .done ; ctrl handling mov byte [.mods], 0x04 add byte [.ascii], 0x60 .done: cli ; Restore GDT o32 lgdt [ss:.gdt] ; Restore IDT o32 lidt [ss:.idt] ; Jump back to pmode mov ebx, cr0 or bl, 1 mov cr0, ebx jmp 0x18:.bits32 .bits32: bits 32 mov bx, 0x20 mov ds, bx mov es, bx mov fs, bx mov gs, bx mov ss, bx ; Restore non-scratch GPRs pop ebp pop edi pop esi pop ebx ; Dehook int 0x08 mov edx, dword [int_08_callback] mov dword [0x08*4], edx cmp byte [.scan], 0 je .fail push dword [.mods] push dword [.ascii] push dword [.scan] call getchar_internal add esp, 3*4 ret .fail: xor eax, eax ret .gdt: dq 0 .idt: dq 0 .rm_idt: dw 0x3ff dd 0 .mods: dd 0 .ascii: dd 0 .scan: dd 0