daily pastebin goal
66%
SHARE
TWEET

Untitled

a guest Dec 17th, 2017 67 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. .MODEL tiny
  2. .386
  3.  
  4. include mylib.inc
  5.  
  6. SET     = 1
  7. CLEAR   = 0
  8. SHIFT_PRESSED_MASK  = 00001000b
  9. ALT_PRESSED_MASK    = 00000011b
  10. M_SCANCODE = 032h
  11. Q_SCANCODE = 010h
  12.  
  13. _CODE   SEGMENT
  14.         ORG     100h        ; Место под PSP
  15. start:
  16.         jmp     Install     ; Переход через данные и резидентный код к
  17.                             ; блоку инициализации
  18.  
  19.         ; Данные, необходмые резидентной части программы
  20.         ; (распологаются в резидентной части программы, чтобы
  21.         ; не быть "выброшенными" вместе с блоком инициализации)
  22.         OldKeyboard     DWORD   ?       ; Адрес предыдущего обработчика
  23.                                         ;   клав. прерывания
  24.         OldMultiplex    DWORD   ?       ; Адрес предыдущего обработчика
  25.                                         ;   мультиплексного. прерывания
  26.         IsTSRActive     BYTE    0       ; Инидикатор того, выполняется ли в
  27.                                         ;   в данный момент TSR
  28.         IdentityNum     BYTE    ?       ; Идентификационный номер данного TSR
  29.  
  30.         ; Идентификационная строка (нужна для определения, был ли данный TSR)
  31.         ; установлен ранее
  32.         IdentityStr     BYTE    "Beeper by Mikhail Gorbunov"
  33.  
  34.        
  35.         ; Новый обработчик клав. прерывания
  36.         NewKeyboard PROC FAR USES AX DX
  37.             pushf                         ; Сохранить состояние флагов
  38.             call    cs:OldKeyboard        ; Вызов предыдущего обработчика
  39.             sti
  40.  
  41.             cmp     IsTSRActive, SET
  42.             je      print_text
  43.  
  44.             mov     ah, 02h
  45.             int     16h
  46.  
  47.             test    al, ALT_PRESSED_MASK
  48.             jz      stop
  49.        
  50.             test    al, SHIFT_PRESSED_MASK
  51.             jz      stop
  52.        
  53.             in      al, 60h
  54.  
  55.             cmp     al, M_SCANCODE
  56.             je      print_info
  57.  
  58.             cmp     al, Q_SCANCODE
  59.             je      deinstall
  60.  
  61.             jmp     stop
  62.         print_text:
  63.             in al,60h
  64.  
  65.             cmp al,1eh
  66.             jne next
  67.             mov ah,2
  68.             mov dl,' '
  69.             int 21h
  70.             mov dl, '1'
  71.             int 21h
  72.             mov dl, 'e'
  73.             int 21h
  74.             mov dl,'='
  75.             jmp stop
  76.             next:
  77.            
  78.             cmp al,9eh
  79.             jne next1
  80.             mov ah,2
  81.             mov dl,' '
  82.             int 21h
  83.             mov dl, '1'
  84.             int 21h
  85.             mov dl, 'e'
  86.             int 21h
  87.             mov dl,'='
  88.             int 21h
  89.             mov dl,'a'
  90.             int 21h
  91.             jmp stop
  92.              next1:
  93.              
  94.              cmp al,01h
  95.             je recover_screen
  96.            
  97.              jmp stop
  98.  
  99.         print_info:
  100.             ;
  101.             ;------
  102.             mov ah,5
  103.             mov al,1
  104.             int 10h
  105.            mov IsTSRActive, SET
  106.  
  107.             ;------
  108.             jmp     stop
  109.  
  110.         deinstall:
  111.             ; Выгрузить из памяти
  112.             mov     ax, WORD PTR cs:OldKeyboard[2]
  113.             mov     ds, ax
  114.             mov     dx, WORD PTR cs:OldKeyboard[0]
  115.             mov     ax, 2509h
  116.             int     21h
  117.  
  118.             mov     ax, WORD PTR cs:OldMultiplex[2]
  119.             mov     ds, ax
  120.             mov     dx, WORD PTR cs:OldMultiplex[0]
  121.             mov     ax, 252Fh
  122.             int     21h
  123.  
  124.             mov     ax, cs:[02Ch]
  125.             mov     es, ax
  126.             mov     ah, 49h
  127.             int     21h
  128.  
  129.             mov     ax, cs
  130.             mov     es, ax
  131.             mov     ah, 49h
  132.             int     21h
  133.  
  134.         recover_screen:
  135.             ; Восстановить содержимое экрана
  136.             mov ah,6
  137.             mov al,0
  138.             mov bh,3
  139.             mov ch,0
  140.             mov cl,0
  141.             int 10h
  142.             mov ah, 5
  143.             mov al,0
  144.             int 10h
  145.             mov IsTSRActive, CLEAR
  146.            
  147.         stop:
  148.             iret                          ; завершить работу обработчика
  149.         NewKeyboard ENDP
  150.  
  151.  
  152.         ; Новый обработчик мультиплексного прерывания
  153.         NewMulptilex    PROC FAR
  154.             pushf                           ; Сохранить состояние флагов
  155.             call    cs:OldMultiplex         ; Вызов предыдущего обработчика
  156.  
  157.             cmp     al,0                    ; Была запрошена проверка установки?
  158.             jne     return                  ; нет: завершить работу обработчика
  159.             cmp     ah, cs:IdentityNum      ; да:  AH = Идентификационный номер?
  160.             jne     return                  ;      нет: завершить работу обработчика
  161.  
  162.             mov     ax, cs                  ; Иначе вернуть в DS:DI адрес
  163.             mov     ds, ax                  ;   идентификационной строки
  164.             mov     di, OFFSET IdentityStr
  165.             mov     al, 0FFh                ; А в AL индикатор установленности
  166.  
  167.         return:
  168.             iret                            ; Завершить работу обработчика
  169.         NewMulptilex    ENDP
  170.  
  171.  
  172.         ; Блок инициализации
  173.         Install     PROC
  174.             mov     cx, 191                 ; Начать поиск свободных идентификационных номеров
  175.                                             ;   со 192 (номера ниже зарезервированы Microsoft)
  176.                                             ;   (CL = 191 т.к. в начале каждой итерации CL++)
  177.         l:
  178.             inc     cx                      ; CL = след иденфикацонный номер
  179.  
  180.             ; Сообшить пльзователю о том, какой в иден. номер просматривается
  181.             mprints tryingIdentityNumMsg,LENGTHOF tryingIdentityNumMsg
  182.             mov     ax,cx
  183.             call    PrintInt16
  184.  
  185.             mov     ah, cl                      ; Вызов мультиплексного прерывания
  186.             mov     al, 0                       ;   для текущего иден. номера
  187.             int     2Fh
  188.  
  189.             cmp     al, 0FFh                    ; Номер занят?
  190.             jne     start_installation          ; нет: начать установку
  191.  
  192.             push    cx
  193.             mov     cx, LENGTHOF IdentityStr    ; да: проверить установлен ли по этому номеру
  194.                                                 ;   данный TSR
  195.  
  196.             mov     ax, cs                      ; для этого: сравнить известную идент. строку с
  197.             mov     es, ax                      ;   содержимым памяти по адресу, возвращенному в
  198.             mov     si, OFFSET IdentityStr      ;   DS:DI мультиплексным прерыванием
  199.             repe    cmpsb
  200.  
  201.             mov     ax, cs                      ; вернуть в DS предыдушеее значение
  202.             mov     ds, ax
  203.  
  204.             cmp     cx, 0                       ; Идент. строка совподает с DS:DI?
  205.  
  206.             pop     cx
  207.             je      installed_err               ; да: ошибка: данный TSR уже установлен
  208.  
  209.             ; Сообшить пльзователю о том, что иден. номер свободен
  210.             mprints IdentityTakenMsg, LENGTHOF IdentityTakenMsg
  211.             mprintnl
  212.  
  213.             cmp     cl, 255                     ; нет: текущий иден. номер = 255?
  214.             je      no_free_identity_err        ;      да:  ошибка: все номера заняты
  215.             jmp     l                           ;      нет: просмотреть след. номер
  216.  
  217.         start_installation:
  218.             mov     ax, cs                      ; вернуть в DS предыдушеее значение
  219.             mov     ds, ax
  220.             ; Сообшить пльзователю о том, что иден. номер свободен
  221.             mprints IdentityFreeMsg,LENGTHOF IdentityFreeMsg
  222.             mprintnl
  223.             mov     IdentityNum, cl             ; Сохранить иденфикацонный номер
  224.                                                 ;   для корректной работы мультиплексного
  225.                                                 ;   прерывания
  226.  
  227.             ; Сохранить адрес текущего и зменить на новый обработчик
  228.             ;   клв. прерывания
  229.             mov     ax, 3509h
  230.             int     21h
  231.             mov     WORD PTR OldKeyboard[0], bx
  232.             mov     WORD PTR OldKeyboard[2], es
  233.  
  234.             mov     ax, 2509h
  235.             mov     dx, OFFSET NewKeyboard
  236.             int     21h
  237.  
  238.             ; Сохранить адрес текущего и зменить на новый обработчик
  239.             ;   мультиплексного прерывания
  240.             mov     ax, 352Fh
  241.             int     21h
  242.             mov     WORD PTR OldMultiplex[0], bx
  243.             mov     WORD PTR OldMultiplex[2], es
  244.  
  245.             mov     ax, 252Fh
  246.             mov     dx, OFFSET NewMulptilex
  247.             int     21h
  248.  
  249.             mprints InstalledMsg, LENGTHOF InstalledMsg
  250.             mprintnl
  251.  
  252.             ; Завершить работу и остаться резидентно в памяти
  253.             mov     ax, 3100h
  254.             mov     dx, OFFSET Install      ; DX = размер резидентной части (в байтах)
  255.             shr     dx,4                    ; Конвертировать в кол-во параграфоф + 1
  256.             inc     dx
  257.             int     21h
  258.  
  259.         installed_err:
  260.             ; Сообшить пльзователю о том, что TSR уже установлен и завершить работу
  261.             mprints installedErrMsg, LENGTHOF installedErrMsg
  262.             mprintnl
  263.             jmp     return
  264.  
  265.         no_free_identity_err:
  266.             ; Сообшить пльзователю о том, что все номера заняты и завершить работу
  267.             mprints installedErrMsg, LENGTHOF installedErrMsg
  268.             mprintnl
  269.  
  270.         return:
  271.             mov     ax, 04C00h
  272.             int     21h
  273.        
  274.         Install     ENDP
  275.  
  276.         ;-----------------------------------------------------------
  277.         PrintInt16 PROC USES ax cx bx dx
  278.         ;
  279.         ; Описание:    Вывод 16-битное целое число со знаком
  280.         ;              в консоль.
  281.         ; Аругменты:   AX = 16-битной целое число со знаком
  282.         ; Возваращает: Ничего
  283.         ;-----------------------------------------------------------
  284.             TEST ah,1000000b    ; первый бит 0? (число положительное?)
  285.             jz   positive_ax    ;   да: пропустить вывод минуса
  286.             push ax             ; сохранить ax
  287.             mov  ah,2           ; след 3 строки:
  288.             mov  dl,'-'         ; вывод минуса в консоль
  289.             int  21h
  290.             pop  ax             ; восстановить ax
  291.             neg  ax             ; negate ax (find its two's complement)
  292.  
  293.         positive_ax:
  294.             mov  bx,10          ; bx будет использован в качестве делителя при подсчете
  295.                                 ; модуля AX/10 (модуль от /10 — последняя цифра числа)
  296.             mov  cx,0           ; инициализировать счетчик цикла
  297.         l1:
  298.             mov  dx,0           ; очистить bx, потому что он будет содержать модуль
  299.             div  bx             ; AX/BX
  300.             add  dx,30h         ; перевести последнюю цифру числа в ее ASCII код
  301.             push dx             ; сохранить цифру на стек
  302.             inc  cx             ; заинкременитть счетчик цикла
  303.  
  304.             cmp ax,0            ; если AX = 0 остановится, потому что все цифры
  305.             jne l1              ; на стеке, иначе: в начало цикла
  306.  
  307.             mov ah,2            ; вторая функция 21h перывания (вывод символа в консоль)
  308.         l2:
  309.             pop dx              ; вернуть цифру со стека (теперь они в правильном порядке)
  310.             int 21h             ; вывести цифру в консоль
  311.             loop l2             ; после цикла l1 CX равна кол-ву цифру в числе, так что используем CX
  312.                                 ; в качестве счетчика цикла
  313.  
  314.             ret
  315.         PrintInt16 ENDP
  316.  
  317.         ; Данные, не нужные резидентной части
  318.         ; (распологаются после кода, т.к. не быть внутри исполнемой части и
  319.         ; при этом быть удобно выброшенными вместе с исполнемым блоком инициализации)
  320.         IdentityTakenMsg        BYTE    " ...Taken"
  321.         tryingIdentityNumMsg    BYTE    "Trying identity: "
  322.         IdentityFreeMsg         BYTE    " ...Free"
  323.         installedErrMsg         BYTE    " ...ERROR: Beeper is already installed"
  324.         noIdentityErrMsg        BYTE    "ERROR: no free identity number found"
  325.         InstalledMsg            BYTE    "Succesfully installed"
  326.  
  327. _CODE   ENDS
  328.         END     start
RAW Paste Data
Top