.586 public beg_scan_ public end_scan_ public size_free_mem_ public info_pc_ public pause_ public test_t_ extern malloc_ :near extern free_ :near extern _eprintf :near ; .data? .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 ;------------------------------------------- ; mov bl,10h ; mov ax,203h ; mov edx,offset isk_0Fh ; 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 ; push offset err_24mes1 ; push 0000000eH ; call _eprintf ; add esp,00000008H mov ax,3 sti iretd err_24mes1 db "Критическая ошибка DOS",00 int_24h endp ;----------------------------------------------------- isk_0Fh proc push eax mov eax,[esp+4] cmp word ptr cs:[eax],75D8h ;fdiv je mfdiv cmp word ptr cs:[eax],70D8h ;fdiv je mfdiv cmp word ptr cs:[eax],0F1DEh ;fdivp je mfdivp cmp word ptr cs:[eax],0F9DEh ;fdivp je mfdivp cmp word ptr cs:[eax],35DCh ;fdiv_p je mfdiv_p mov eax,offset err_01mes2 jmp err_other mfdiv: add dword ptr [esp+4],3 jmp err_div mfdivp: add dword ptr [esp+4],2 jmp err_div mfdiv_p: add dword ptr [esp+4],6 err_div: mov eax,offset err_01mes1 err_other: push eax mov eax,0000000cH push eax call _eprintf add esp,00000008H pop eax iretd err_01mes1 db "Ошибка: Деление на ноль",00 err_01mes2 db "Ошибка: Другие ошибки FPU",00 isk_0Fh 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 ;----------------------------------------------------- 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 end