Листинг (1071452), страница 2
Текст из файла (страница 2)
273 022F 3C 3D cmp AL, ignore_key
274 0231 74 03 je new09h_goFarExit
275
276 0233 EB 04 90 jmp new09h_dontExit ; если до сюда дошли, значит не Fx была нажата, тогда пропустим+
277 и выйдем
278 0236 new09h_goFarExit:
279 0236 E9 00A1 jmp new09h_newExit
280 0239 new09h_dontExit:
281
282 ; запуск таймера
283 0239 3C C3 cmp AL, tmr_key + 80h ; Fx отпущена?, отвечающего за вывод по таймеру
284 023B 75 08 jne new09h_tmr_key ; если не этот Fx, идем дальше
285
Turbo Assembler Version 3.1 04/18/14 08:08:07 Page 6
kurs1.asm
286 023D C6 06 0155r 01 mov tmr_active, 1 ; если да, поставим флаг таймера на 1
287 0242 E9 0095 jmp new09h_newExit ; выходим
288 0245 new09h_tmr_key:
289
290 ; Работа с курсивом
291 0245 3C BB cmp AL, kurs_key + 80h ; проверка, отпущена ли Fx, отвечающего за вывод курсивной +
292 буквы
293 0247 75 2E jne new09h_kurs_key ; не этот Fx, идем дальше
294
295 0249 0E push CS ; ES = CS
296 024A 07 pop ES
297
298 024B 80 3E 0158r 00 cmp kurs_active, 0
299 0250 F6 16 0158r not kurs_active ; проверка осуществлена, можно переключить переменную, а +
300 потом уже перейти или нет
301 0254 75 14 jne oldKursReturn ; если kurs_active != 0, значит символ курсивный +
302 восстановим
303 ; Установка курсива
304 0256 B8 1100 mov AX, 1100H ; загрузка пользовательской таблицы
305 0259 BB 1000 mov BX, 1000H
306 025C B9 0001 mov CX, 1 ; сколько букв меняем
307 025F BA 0088 mov DX, kurs_symbolIndex ; код буквы
308 0262 BD 0159r lea BP, kurs_symbolNew ; таблица будущей буквы
309 0265 CD 10 int 10H
310 0267 EB 71 90 jmp new09h_newExit
311 026A oldKursReturn: ; Восстановление старого шрифта
312 026A B8 1104 mov AX, 1104H ; загрузка первоначального шрифта
313 026D B3 00 mov BL, 0
314 026F BA 0088 mov DX, kurs_symbolIndex ; код буквы
315 0272 CD 10 int 10H
316 0274 EB 64 90 jmp new09h_newExit
317 0277 new09h_kurs_key:
318
319 ; Работа с руссификацией
320 0277 3C BC cmp AL, russ_key + 80h ; проверка, отпущена ли Fx, отвечающего за вывод +
321 руссифицированной буквы
322 0279 75 07 jne new09h_russ_key ; если не этот Fx был нажат, идем дальше
323
324 027B F6 16 0169r not russ_active ; переключаем флаг
325 027F EB 59 90 jmp new09h_newExit ; выходим
326 0282 new09h_russ_key:
327
328 ; Работа с блокировкой символов
329 0282 3C BD cmp AL, ignore_key + 80h ; проверка, отпущена ли Fx, отвечающего за последнее +
330 задание
331 0284 75 07 jne new09h_ignore_key ; если не этот Fx был нажат, идем дальше
332
333 0286 F6 16 0175r not ignore_active ; переключаем ignore_active
334 028A EB 4E 90 jmp new09h_newExit ; выходим
335 028D new09h_ignore_key:
336
337 ; Проверка CTRL + U
338 028D 3C 16 cmp AL, 16h ; В AL лежит скан-код U?
339 028F 75 1B jne new09h_ctrlU ; если нет, выходим
340
341 0291 50 push AX
342 0292 B4 02 mov AH, 02h ; загрузим флаги клавиатуры
Turbo Assembler Version 3.1 04/18/14 08:08:07 Page 7
kurs1.asm
343 0294 CD 16 int 16h ; загружаем
344 0296 24 04 and AL, 00000100b ; проверка на ctrl
345 0298 3C 00 cmp AL, 0 ; если 0, ctrl НЕ нажат
346 029A 58 pop AX
347 029B 74 0F je new09h_ctrlU ; уходим к старому прерыванию
348
349 029D B4 09 mov AH, 09h ; если нажат ctrl + U, выведем
350 029F BA 0103r lea DX, msg_unload ; сообщение о выгрузке
351 02A2 CD 21 int 21h
352
353 02A4 B8 FF01 mov AX, 0FF01h ; FF - сообщение нашей программе, 01 - подфункция выгрузки
354 02A7 CD 2F int 2Fh ; запускаем выгрузку
355
356 02A9 EB 2F 90 jmp new09h_newExit ; выходим
357 02AC new09h_ctrlU:
358
359 ; Русификация
360 02AC 80 3E 0169r 00 cmp russ_active, 0
361 02B1 74 09 je new09h_russ_active ; если русификация выключена, идем смотреть другие +
362 флаги
363
364 02B3 50 push AX
365 02B4 E8 FF31 call russLetter ; если включена - русифицируем
366 02B7 3C 00 cmp AL, 0 ; если русифицировали удачно, будет стоять 0
367 02B9 58 pop AX
368 02BA 74 1E je new09h_newExit ; если успешно, то выходим
369 02BC new09h_russ_active:
370
371 ; Блокировка
372 02BC 80 3E 0175r 00 cmp ignore_active, 0
373 02C1 74 0E je new09h_ignore_active
374
375 02C3 9C pushf
376 02C4 2E: FF 1E 0133r call dword ptr CS:[int09h_offset]
377 02C9 E8 FEDF call ignoreLetter
378 02CC 1F pop DS
379 02CD 07 pop ES
380 02CE 5B pop BX
381 02CF 58 pop AX
382 02D0 CF iret
383 02D1 new09h_ignore_active:
384
385 02D1 new09h_oldExit: ; Выйти, со старым обработчиком прерывания
386 02D1 1F pop DS
387 02D2 07 pop ES
388 02D3 5B pop BX
389 02D4 58 pop AX
390
391 02D5 2E: FF 2E 0133r jmp dword ptr CS:[int09h_offset] ; запускаем старый обработчик +
392 прерывания
393
394 02DA new09h_newExit: ; Выйти, сказав клавиатуре, что символ считан
395 02DA 1F pop DS
396 02DB 07 pop ES
397 02DC 5B pop BX
398 02DD 58 pop AX
399
Turbo Assembler Version 3.1 04/18/14 08:08:07 Page 8
kurs1.asm
400 02DE E4 61 in AL, 61h ; контроллер состояния клавиатуры
401 02E0 0C 80 or AL, 10000000b ; клавишу нажали
402 02E2 E6 61 out 61h, AL ; отправим в порт
403 02E4 24 7F and AL, 01111111b ; клавишу отпустили
404 02E6 E6 61 out 61h, AL ; отправим в порт
405 02E8 B0 20 mov AL, 20h
406 02EA E6 20 out 20h, AL ; отправим в контроллер прерываний признак конца прерывания
407
408 02EC CF iret ; выходим из прерывания самостоятельно
409 02ED new_09h ENDP
410
411
412 ; ------------------------------------------------------------
413 ; Прерывание 1Сh вызывается компьютером каждые 55 миллисекунд, само
414 ; ------------------------------------------------------------
415
416 02ED new_1Ch PROC
417 02ED 0E push CS ; DS = CS
418 02EE 1F pop DS
419
420 02EF 80 3E 0155r 00 cmp tmr_active, 0 ; если таймер выключен
421 02F4 74 2F je new1Ch_exit ; выходим
422
423 02F6 83 06 0156r 37 add tmr_time, 55 ; прерывание вызывается каждые 55 миллисекунд. +
424
425 02FB 81 3E 0156r 1B58 cmp tmr_time, tmr_timeAll ; сколько прошло и сколько должно
426 0301 7C 22 jl new1Ch_exit ; если прошло меньше - выходим
427
428 0303 C7 06 0156r 0000 mov tmr_time, 0 ; если прошло положенное время, обнуляем
429 0309 C6 06 0155r 00 mov tmr_active, 0 ; и выключаем
430
431 030E B4 00 mov AH, 0h ; очистка экрана
+ 432 0310 B0 03 mov AL, 3h
433 0312 CD 10 int 10h
434
435 0314 B4 02 MOV AH, 2 ; номер функции
436 0316 B7 00 MOV BH, 0 ; номер страницы
437 0318 B6 0B MOV DH, 11 ; строка
438 031A B2 14 MOV DL, 20 ; столбец
439 031C CD 10 INT 10H ; ставим курсор
440
441 031E B4 09 mov AH, 09h ; вывод строки на экран
442 0320 BA 013Br lea DX, tmr_msg ; адрес выводимой строки
443 0323 CD 21 int 21h ; выводим
444
445 0325 new1Ch_exit:
446 0325 CF iret ; выход
447 0326 new_1Ch ENDP
448
449
450 ; -----------------------------------------------------------------------------------
451 ; Прерывание 2Fh
452
453 ; - Возвращает определенный код (что бы проверить, загружен ли резидент)
454 ; - Выгружает резидент
455 ; -----------------------------------------------------------------------------------
456
Turbo Assembler Version 3.1 04/18/14 08:08:07 Page 9
kurs1.asm
457 0326 new_2Fh PROC
458 0326 0E push CS ; DS = CS
459 0327 1F pop DS
460 0328 0E push CS ; ES = CS
461 0329 07 pop ES
462
463 032A 80 FC FF cmp AH, 0FFh ; вызвана пользователем или другой программой?
464 032D 75 08 jne old2Fh_call ; если программа - стандартный обработчик
465 032F 3C 00 cmp AL, 0 ; загружен ли резидент в +
466 память
467 0331 74 09 je new2Fh_QQ
468 0333 3C 01 cmp AL, 1 ; выгрузить из памяти
469 0335 74 09 je new2Fh_TSRunload
470
471 0337 old2Fh_call:
472 0337 2E: FF 2E 012Fr jmp dword ptr CS:[int2Fh_offset]
473
474 033C new2Fh_QQ:
475 033C B8 5151 mov AX, 'QQ' ; вернём QQ, если резидент в памяти
476 033F CF iret
477
478 0340 new2Fh_TSRunload:
479 0340 1E push DS ; сохраним регистры
480 0341 06 push ES
481 0342 52 push DX
482
483 0343 0E push CS ; ES = CS
484 0344 07 pop ES
485
486 0345 B8 1104 mov AX, 1104H ; загрузка первоначального шрифта
487 0348 B3 00 mov BL, 0
488 034A 26: 8B 16 0088 mov DX, ES:kurs_symbolIndex ; код буквы
489 034F CD 10 int 10H
490
491 0351 B8 2509 mov AX, 2509h ; восстановим 09h (AH = 25h - установить прерывание, AL = +
492 09h - какое прерывание)
493 0354 26: 8B 16 0133r mov DX, ES:int09h_offset ; возвращаем вектор прерывания
494 0359 26: 8E 1E 0135r mov DS, ES:int09h_segment
495 035E CD 21 int 21h ; восстанавливаем
496
497 0360 B8 252F mov AX, 252Fh ;восстановим 2Fh
498 0363 26: 8B 16 012Fr mov DX, ES:int2Fh_offset ; возвращаем вектор прерывания
499 0368 26: 8E 1E 0131r mov DS, ES:int2Fh_segment
500 036D CD 21 int 21h
501
502 036F B8 251C mov AX, 251Ch ;восстановим 1Ch
503 0372 26: 8B 16 0137r mov DX, ES:int1Ch_offset ; возвращаем вектор прерывания
504 0377 26: 8E 1E 0139r mov DS, ES:int1Ch_segment
505 037C CD 21 int 21h
506
507 037E 2E: A1 002C mov AX, CS:2Ch
508 0382 8E C0 mov ES, AX ; загрузим в ES адрес окружения
509 0384 B4 49 mov AH, 49h ; выгрузим из памяти окружение
510 0386 CD 21 int 21h ; выгружаем
511
512 0388 0E push CS
513 0389 07 pop ES ; ES = CS: в ES - адрес резидентной программы
Turbo Assembler Version 3.1 04/18/14 08:08:07 Page 10
kurs1.asm
514 038A B4 49 mov AH, 49h ; выгрузим из памяти резидент
515 038C CD 21 int 21h
516
517 038E 5A pop DX ; восстановим регистры
518 038F 07 pop ES
519 0390 1F pop DS
520 0391 CF iret ; выйдем
521 0392 new_2Fh ENDP
522 =CODESEGMENT:0392 tsr_end=$ ; создает метку
523
524
525 ; ---------------------------------------------------------
526 ; init принимает управление при старте резидента (start: jmp init)
527 ; ---------------------------------------------------------
528
529 0392 init PROC
530 0392 E8 006B call params ; параметры
531 0395 E8 0000 call load ; загрузка
532 0398 init ENDP
533
534 0398 load PROC
535 0398 0E push CS ; DS = CS
536 0399 1F pop DS
537
538 039A B8 FF00 mov AX, 0FF00h
539 039D CD 2F int 2Fh ; резидент в памяти?
540 039F 3D 5151 cmp AX, 'QQ' ; если QQ - резидент в памяти
541 03A2 75 0C jne i_go_loading
542
543 03A4 B4 09 mov AH, 09h ; сообщение об ошибке
544 03A6 BA 0119r lea DX, msg_alreadyLoaded
545 03A9 CD 21 int 21h
546 03AB B8 4C01 mov AX, 4C01h ; выйти с кодом ошибки 1
547 03AE CD 21 int 21h
548
549 03B0 i_go_loading:
550 ; -----------------------------------------------------------------
551 ; изменим прерывание 2Fh
552 03B0 B8 352F mov AX, 352Fh ; получим адрес прерывания 2Fh
553 03B3 CD 21 int 21h
554
555 03B5 89 1E 012Fr mov int2Fh_offset, BX ; запишем смещение старого обработчика
556 03B9 8C 06 0131r mov int2Fh_segment, ES ; запишем сегмент
557
558 03BD B8 252F mov AX, 252Fh ; установим новый адрес
559 03C0 BA 0326r lea DX, new_2Fh
560 03C3 CD 21 int 21h
561 ; -----------------------------------------------------------------
562 ; изменим прерывание 09h
563 03C5 B8 3509 mov AX, 3509h ; получим адрес обработчика
564 03C8 CD 21 int 21h
565
566 03CA 89 1E 0133r mov int09h_offset, BX
567 03CE 8C 06 0135r mov int09h_segment, ES
568
569 03D2 B8 2509 mov AX, 2509h ; установим новый адрес
570 03D5 BA 021Br lea DX, new_09h
Turbo Assembler Version 3.1 04/18/14 08:08:07 Page 11
kurs1.asm
571 03D8 CD 21 int 21h
572
573 ; -----------------------------------------------------------------
574 ; изменим прерывание 1Ch
575 03DA B8 351C mov AX, 351Ch ; получим адрес обработчика
576 03DD CD 21 int 21h
577
578 03DF 89 1E 0137r mov int1Ch_offset, BX
579 03E3 8C 06 0139r mov int1Ch_segment, ES
580
581 03E7 B8 251C mov AX, 251Ch ; установим новый адрес
582 03EA BA 02EDr lea DX, new_1Ch