.586 public beg_scan_ public end_scan_ public size_free_mem_ public info_pc_ public pause_ public test_t_ public d_alc_DPMI_ public d_free_DPMI_ public DPMI_getvect_ public DPMI_setvect_ public real_edi public real_esi public real_ebp public res00 public real_ebx public real_edx public real_ecx public real_eax public cpusfl public real_es public real_ds public real_fs public real_gs public real_ip public real_cs public real_sp public real_ss extern malloc_ :near extern free_ :near .data? old_09 label fword ; in CSEG to allow addressing ofs09 dd ? seg09 dw ? .code tkeyb proc cli push eax ;сохранение регистров push ebx ; push ds ; получение скан-кода in al,60h ;получение скан-кода из порта mov ah,al in al,61h mov bl,al or al,80h out 61h,al mov al,bl out 61h,al ;загрузка регистра ES push ax mov ax,seg ofs09 mov ds,ax pop ax mov al,ah test ah,80h jnz quit mov word ptr ds:[41ah],30h mov word ptr ds:[41ch],32h mov al,20h mov ds:[430h],ax quit: mov al,20h out 20h,al pop ds pop ebx pop eax iretd ; tkeyb endp ;***** void beg_scan() beg_scan_ proc push eax push ebx push edx push ecx mov bl,09h mov ax,204h ;Чтение вектора прерывания 8 = es:ebx int 31h mov ofs09,edx mov seg09,cx cli mov bl,09h mov ax,205h mov edx,offset tkeyb mov cx,cs int 31h ;------------- Обработчик на int 24 -------- mov bl,24h mov ax,205h mov edx,offset int_24h mov cx,cs int 31h sti pop ecx pop edx pop ebx pop eax ret beg_scan_ endp ;******* void end_scan() end_scan_ proc push eax push ebx push edx push ecx mov bl,09h mov ax,205h mov edx, ofs09 mov cx, seg09 int 31h pop ecx pop edx pop ebx pop eax ret end_scan_ endp ;----------------------------------------------------- int_24h proc mov ax,3 sti iretd err_24mes1 db "Критическая ошибка DOS",00 int_24h endp ;----------------------------------------------------- info_pc_ proc push ebx push ecx push edx cli ; disable interrupts pushfd ; push flags to look at pop eax ; get eflags mov ebx, eax ; save for later xor eax, 200000h ; toggle bit 21 push eax popfd ; load modified eflags to CPU pushfd ; push eflags to look at pop eax ; get current eflags push ebx ; push original onto stack popfd ; restore original flags sti ; enable interrupts xor eax, ebx ; check if bit changed jnz upPentium ; changed, it's a Pentium mov ax, 4 ; set 80486 flag jmp uP_Exit upPentium: mov eax, 1 ; get family info function CPUID ; macro for CPUID instruction and eax, 0F00h ; find family info shr eax, 8 ; move to al up_Exit: ; mov ax,00400h ; int 31h ; movzx eax,cl movzx eax,al pop edx pop ecx pop ebx ret info_pc_ endp ;----------------------------------------------------- size_free_mem_ proc push edi mov eax,30h call malloc_ mov edi,eax mov ax,0500h int 31h mov eax,[edi] push eax mov eax,edi call free_ pop eax pop edi ret size_free_mem_ endp ;---------------------------------------------------- ;test() test_t_ proc db 0Fh,31h ;RDTSC mov ebx,eax mov ax,100 call pause_ db 0Fh,31h ;RDTSC sub eax,ebx ret test_t_ endp ;----------------------------------------------------- ;pause(eax) pause_ proc pushad mov cx,ax call READ_PIT mov bx, ax ;сохраняем текуще значение таймера waitRD: ;ждем CX тиков PIT call READ_PIT sub ax, bx ;разница с начальным значением neg ax ;то корректируем cmp ax, cx jc waitRD ;если еще нет, то ждем ; mov dx,ax ; shr eax,16 ; mov cx,ax ; mov ah,86h ; int 15h popad ret pause_ endp ;----------------------------------------------------- d_alc_DPMI_ proc ;short dos_alloc_(dword bufsize,void *ptr) push ebx push edx mov ebx,eax shr ebx,4 inc ebx mov ax,0100h int 31h jc err_dpmi and eax,0FFFFh shl eax,4 mov ebx,eax movzx eax,dx pop edx mov ds:[edx],ebx pop ebx ret err_dpmi: mov eax,0 pop edx pop ebx ret d_alc_DPMI_ endp ;----------------------------------------------------- d_free_DPMI_ proc ;void d_free_DPMI_(short) mov dx,ax mov ax,0101h ;Освобождаем DOS блок памяти int 31h ret d_free_DPMI_ endp ;----------------------------------------------------- READ_PIT proc near xor al, al ;0 = читать 0 канал out 43h,al ;порт управления in al,40h ;читаем LSB mov ah,al in al,40h ;читаем MSB xchg ah,al ret READ_PIT ENDP ;----------------------------------------------------- DPMI_getvect_ proc push ebx push ecx mov bx,ax mov ax,204h ;Чтение вектора прерывания 8 = es:ebx int 31h jnc ok mov edx,-1 ok: mov eax,edx mov edx,ecx pop ecx pop ebx ret DPMI_getvect_ endp ;----------------------------------------------------- DPMI_setvect_ proc push edx mov edx,ebx mov bx,ax mov ax,205h int 31h mov eax,0 jnc ok1 mov eax,-1 ok1: pop edx ret DPMI_setvect_ endp ;----------------------------------------------------- ;----------- Данные ------------------ .DATA real_edi dd 00h real_esi dd 00h real_ebp dd 00h res00 dd 00h real_ebx dd 00h real_edx dd 00h real_ecx dd 00h real_eax dd 00h cpusfl dw 00h real_es dw 00h real_ds dw 00h real_fs dw 00h real_gs dw 00h real_ip dw 00h real_cs dw 00h real_sp dw 00h real_ss dw 00h actvga dd 00h VBD_DEVFNa db 00h ; 7-3=device #, 2-0=function # AGP VBD_BUSNOa db 00h ; Bus # AGP VBD_CTL dw 00h ; Control register (bridge only) AGP VBD_DEVFN db 4 dup(?) ; 7-3=device #, 2-0=function # VBD_BUSNO db 4 dup(?) ; Bus # VBD_EROM dd 4 dup(?) ; Expansion ROM base address VBD_ESIZE dd 4 dup(?) ; Expansion ROM size in bytes VBD_EBASE dd 4 dup(?) ; Expansion ROM base address in low memory VBD_EINITS dw 4 dup(?) ; EROM initialization address LMA end