Advertisement
Guest User

Untitled

a guest
Dec 17th, 2017
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.44 KB | None | 0 0
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement