Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .MODEL tiny
- .386
- include mylib.inc
- SET = 1
- CLEAR = 0
- SHIFT_PRESSED_MASK = 00001000b
- ALT_PRESSED_MASK = 00000011b
- M_SCANCODE = 032h
- Q_SCANCODE = 010h
- _CODE SEGMENT
- ORG 100h ; Место под PSP
- start:
- jmp Install ; Переход через данные и резидентный код к
- ; блоку инициализации
- ; Данные, необходмые резидентной части программы
- ; (распологаются в резидентной части программы, чтобы
- ; не быть "выброшенными" вместе с блоком инициализации)
- OldKeyboard DWORD ? ; Адрес предыдущего обработчика
- ; клав. прерывания
- OldMultiplex DWORD ? ; Адрес предыдущего обработчика
- ; мультиплексного. прерывания
- IsTSRActive BYTE 0 ; Инидикатор того, выполняется ли в
- ; в данный момент TSR
- IdentityNum BYTE ? ; Идентификационный номер данного TSR
- ; Идентификационная строка (нужна для определения, был ли данный TSR)
- ; установлен ранее
- IdentityStr BYTE "Beeper by Mikhail Gorbunov"
- ; Новый обработчик клав. прерывания
- NewKeyboard PROC FAR USES AX DX
- pushf ; Сохранить состояние флагов
- call cs:OldKeyboard ; Вызов предыдущего обработчика
- sti
- cmp IsTSRActive, SET
- je print_text
- mov ah, 02h
- int 16h
- test al, ALT_PRESSED_MASK
- jz stop
- test al, SHIFT_PRESSED_MASK
- jz stop
- in al, 60h
- cmp al, M_SCANCODE
- je print_info
- cmp al, Q_SCANCODE
- je deinstall
- jmp stop
- print_text:
- in al,60h
- cmp al,1eh
- jne next
- mov ah,2
- mov dl,' '
- int 21h
- mov dl, '1'
- int 21h
- mov dl, 'e'
- int 21h
- mov dl,'='
- jmp stop
- next:
- cmp al,9eh
- jne next1
- mov ah,2
- mov dl,' '
- int 21h
- mov dl, '1'
- int 21h
- mov dl, 'e'
- int 21h
- mov dl,'='
- int 21h
- mov dl,'a'
- int 21h
- jmp stop
- next1:
- cmp al,01h
- je recover_screen
- jmp stop
- print_info:
- ;
- ;------
- mov ah,5
- mov al,1
- int 10h
- mov IsTSRActive, SET
- ;------
- jmp stop
- deinstall:
- ; Выгрузить из памяти
- mov ax, WORD PTR cs:OldKeyboard[2]
- mov ds, ax
- mov dx, WORD PTR cs:OldKeyboard[0]
- mov ax, 2509h
- int 21h
- mov ax, WORD PTR cs:OldMultiplex[2]
- mov ds, ax
- mov dx, WORD PTR cs:OldMultiplex[0]
- mov ax, 252Fh
- int 21h
- mov ax, cs:[02Ch]
- mov es, ax
- mov ah, 49h
- int 21h
- mov ax, cs
- mov es, ax
- mov ah, 49h
- int 21h
- recover_screen:
- ; Восстановить содержимое экрана
- mov ah,6
- mov al,0
- mov bh,3
- mov ch,0
- mov cl,0
- int 10h
- mov ah, 5
- mov al,0
- int 10h
- mov IsTSRActive, CLEAR
- stop:
- iret ; завершить работу обработчика
- NewKeyboard ENDP
- ; Новый обработчик мультиплексного прерывания
- NewMulptilex PROC FAR
- pushf ; Сохранить состояние флагов
- call cs:OldMultiplex ; Вызов предыдущего обработчика
- cmp al,0 ; Была запрошена проверка установки?
- jne return ; нет: завершить работу обработчика
- cmp ah, cs:IdentityNum ; да: AH = Идентификационный номер?
- jne return ; нет: завершить работу обработчика
- mov ax, cs ; Иначе вернуть в DS:DI адрес
- mov ds, ax ; идентификационной строки
- mov di, OFFSET IdentityStr
- mov al, 0FFh ; А в AL индикатор установленности
- return:
- iret ; Завершить работу обработчика
- NewMulptilex ENDP
- ; Блок инициализации
- Install PROC
- mov cx, 191 ; Начать поиск свободных идентификационных номеров
- ; со 192 (номера ниже зарезервированы Microsoft)
- ; (CL = 191 т.к. в начале каждой итерации CL++)
- l:
- inc cx ; CL = след иденфикацонный номер
- ; Сообшить пльзователю о том, какой в иден. номер просматривается
- mprints tryingIdentityNumMsg,LENGTHOF tryingIdentityNumMsg
- mov ax,cx
- call PrintInt16
- mov ah, cl ; Вызов мультиплексного прерывания
- mov al, 0 ; для текущего иден. номера
- int 2Fh
- cmp al, 0FFh ; Номер занят?
- jne start_installation ; нет: начать установку
- push cx
- mov cx, LENGTHOF IdentityStr ; да: проверить установлен ли по этому номеру
- ; данный TSR
- mov ax, cs ; для этого: сравнить известную идент. строку с
- mov es, ax ; содержимым памяти по адресу, возвращенному в
- mov si, OFFSET IdentityStr ; DS:DI мультиплексным прерыванием
- repe cmpsb
- mov ax, cs ; вернуть в DS предыдушеее значение
- mov ds, ax
- cmp cx, 0 ; Идент. строка совподает с DS:DI?
- pop cx
- je installed_err ; да: ошибка: данный TSR уже установлен
- ; Сообшить пльзователю о том, что иден. номер свободен
- mprints IdentityTakenMsg, LENGTHOF IdentityTakenMsg
- mprintnl
- cmp cl, 255 ; нет: текущий иден. номер = 255?
- je no_free_identity_err ; да: ошибка: все номера заняты
- jmp l ; нет: просмотреть след. номер
- start_installation:
- mov ax, cs ; вернуть в DS предыдушеее значение
- mov ds, ax
- ; Сообшить пльзователю о том, что иден. номер свободен
- mprints IdentityFreeMsg,LENGTHOF IdentityFreeMsg
- mprintnl
- mov IdentityNum, cl ; Сохранить иденфикацонный номер
- ; для корректной работы мультиплексного
- ; прерывания
- ; Сохранить адрес текущего и зменить на новый обработчик
- ; клв. прерывания
- mov ax, 3509h
- int 21h
- mov WORD PTR OldKeyboard[0], bx
- mov WORD PTR OldKeyboard[2], es
- mov ax, 2509h
- mov dx, OFFSET NewKeyboard
- int 21h
- ; Сохранить адрес текущего и зменить на новый обработчик
- ; мультиплексного прерывания
- mov ax, 352Fh
- int 21h
- mov WORD PTR OldMultiplex[0], bx
- mov WORD PTR OldMultiplex[2], es
- mov ax, 252Fh
- mov dx, OFFSET NewMulptilex
- int 21h
- mprints InstalledMsg, LENGTHOF InstalledMsg
- mprintnl
- ; Завершить работу и остаться резидентно в памяти
- mov ax, 3100h
- mov dx, OFFSET Install ; DX = размер резидентной части (в байтах)
- shr dx,4 ; Конвертировать в кол-во параграфоф + 1
- inc dx
- int 21h
- installed_err:
- ; Сообшить пльзователю о том, что TSR уже установлен и завершить работу
- mprints installedErrMsg, LENGTHOF installedErrMsg
- mprintnl
- jmp return
- no_free_identity_err:
- ; Сообшить пльзователю о том, что все номера заняты и завершить работу
- mprints installedErrMsg, LENGTHOF installedErrMsg
- mprintnl
- return:
- mov ax, 04C00h
- int 21h
- Install ENDP
- ;-----------------------------------------------------------
- PrintInt16 PROC USES ax cx bx dx
- ;
- ; Описание: Вывод 16-битное целое число со знаком
- ; в консоль.
- ; Аругменты: AX = 16-битной целое число со знаком
- ; Возваращает: Ничего
- ;-----------------------------------------------------------
- TEST ah,1000000b ; первый бит 0? (число положительное?)
- jz positive_ax ; да: пропустить вывод минуса
- push ax ; сохранить ax
- mov ah,2 ; след 3 строки:
- mov dl,'-' ; вывод минуса в консоль
- int 21h
- pop ax ; восстановить ax
- neg ax ; negate ax (find its two's complement)
- positive_ax:
- mov bx,10 ; bx будет использован в качестве делителя при подсчете
- ; модуля AX/10 (модуль от /10 — последняя цифра числа)
- mov cx,0 ; инициализировать счетчик цикла
- l1:
- mov dx,0 ; очистить bx, потому что он будет содержать модуль
- div bx ; AX/BX
- add dx,30h ; перевести последнюю цифру числа в ее ASCII код
- push dx ; сохранить цифру на стек
- inc cx ; заинкременитть счетчик цикла
- cmp ax,0 ; если AX = 0 остановится, потому что все цифры
- jne l1 ; на стеке, иначе: в начало цикла
- mov ah,2 ; вторая функция 21h перывания (вывод символа в консоль)
- l2:
- pop dx ; вернуть цифру со стека (теперь они в правильном порядке)
- int 21h ; вывести цифру в консоль
- loop l2 ; после цикла l1 CX равна кол-ву цифру в числе, так что используем CX
- ; в качестве счетчика цикла
- ret
- PrintInt16 ENDP
- ; Данные, не нужные резидентной части
- ; (распологаются после кода, т.к. не быть внутри исполнемой части и
- ; при этом быть удобно выброшенными вместе с исполнемым блоком инициализации)
- IdentityTakenMsg BYTE " ...Taken"
- tryingIdentityNumMsg BYTE "Trying identity: "
- IdentityFreeMsg BYTE " ...Free"
- installedErrMsg BYTE " ...ERROR: Beeper is already installed"
- noIdentityErrMsg BYTE "ERROR: no free identity number found"
- InstalledMsg BYTE "Succesfully installed"
- _CODE ENDS
- END start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement