111 lines
1.6 KiB
NASM
111 lines
1.6 KiB
NASM
section .realmode
|
|
|
|
int_08_ticks_counter: dd 0
|
|
|
|
int_08_isr:
|
|
bits 16
|
|
inc dword [cs:int_08_ticks_counter]
|
|
int 0x80 ; call callback
|
|
iret
|
|
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 [0x80*4], edx
|
|
mov edx, int_08_isr
|
|
mov dword [0x08*4], int_08_isr
|
|
|
|
; pit_ticks in edx
|
|
mov edx, dword [esp+4]
|
|
|
|
mov dword [int_08_ticks_counter], 0
|
|
|
|
; 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
|
|
|
|
.loop:
|
|
cmp dword [int_08_ticks_counter], edx
|
|
je .timeout
|
|
|
|
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
|
|
jmp .done
|
|
|
|
.timeout:
|
|
xor eax, eax
|
|
|
|
.done:
|
|
cli
|
|
|
|
; 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 [0x80*4]
|
|
mov dword [0x08*4], edx
|
|
|
|
push eax
|
|
call getchar_internal
|
|
pop edx
|
|
|
|
ret
|