есть такой вот простенький скринсейвер под дос, который гасит монитор по прошествии определенного времени.
| Код | ; tasm /m scrsaver.asm ; tlink /t /x scrsaver.obj
.MODEL Tiny .486 .CODE ORG 100h
Start:
jmp main ; на начало программы Counter dw 0 ; Счётчик времени Time dw 70 ; Время для гашения экрана в 0.55 мсек тиках (минута) ; ==8h== Handler8 proc far ; Обработчик прерывания inc cs:Counter ; Увеличиваем на 1 mov ax, cs:Counter mov bx, cs:Time cmp ax, bx ; Прошло нужное время? jb cs:RealInt8 mov ax, cs:Time mov cs:Counter, ax ; Чтоб не было переполнения через час mov ax,1201h mov bl,36h int 10h ; Гасим экран RealInt8: db 0EAh ; jmp far RealAddr8 dd ? ; Адрес старого обработчика endp Handler8
; ==9h== Handler9 proc far ;push ax bx di si mov ax, cs:Time cmp cs:Counter, ax ; Экран погашен? jb Reset mov ax,1200h mov bl,36h int 10h ; Врубаем экран Reset: mov cs:Counter,0 ; При нажатии клавиши сбрасываем счётчик в 0 jmp cs:RealAddr9 ;pop si di bx ax RealInt9 db 0EAh ; jmp far RealAddr9 dd ? ; Адрес старого обработчика endp Handler9 TSREnd = $ ; Конец резидентной части ;--------------------------------------------------------------
Mess_hello db 'Скринсейвер запущен. Спустя указанное время "неработы" он потушит экран.', 0Ah, 0Dh, '$' cmd_wrong db 'Ошибка. Параметр запуска: Dk_laba4.com [время_в_минутах(не более 60 минут)]', 0Ah, 0Dh, '$'
main proc mov si, 80h mov ah, 0 lodsb cmp al, 4 jg mistake cmp al, 1 jbe mistake mov ch, 0 mov cl, al dec cx inc si call str_to_bin mov si, 444h mul si mov Time, ax lea dx, Mess_hello mov ah, 9h int 21h jmp SetIntVec
mistake: lea dx, cmd_wrong mov ah, 9h int 21h mov al, 0 mov ah, 4ch int 21h endp main
str_to_bin proc near ; перевод строкового десятичного числа в двоичное представление push di dx xor ax, ax xor dx, dx mov di, 10 cycle: mul di mov dl, [si] sub dl, 30h add ax, dx inc si loop cycle pop dx di ret endp str_to_bin
SetIntVec proc near mov ax,3508h ; 08 - номер прерывания (здесь - таймер) int 21h ; Получаем адрес старого обработчика (в ES:BX) mov word ptr RealAddr8[0],bx ; Сохраняем... mov word ptr RealAddr8[2],es ; ...его в RealAddr8 mov ah,25h lea dx,Handler8 int 21h ; Устанавливаем наш обработчик
mov ax,3509h ; 09 - номер прерывания (здесь - клава) int 21h ; Получаем адрес старого обработчика (в ES:BX) mov word ptr RealAddr9[0],bx ; Сохраняем... mov word ptr RealAddr9[2],es ; ...его в RealAddr9 mov ah,25h lea dx,Handler9 int 21h ; Устанавливаем наш обработчик
lea dx,TSREnd int 27h ; Выходим, но остаёмся резидентно endp SetIntVec END Start
|
проблемы небольшие две: -достаточно долго под ntdosvm работают прерывания. можно ли как-то ускорить обработку? -не могу поймать причину ошибки, которую выдает система.(что-то про недопустимую команду из-за обработчиков). похоже что проблема в обработчике прерывания клавиатуры.(Handler9)
подскажите что не так. за ранее спасибо.
|