Ассемблер - одна интересная штучка с ассемблером.

Echo #03
┌════════════════════════════════════════┐
│░░░░░░░░░░ Маленькие хитрости ░░░░░░░░░░│
└════════════════════════════════════════┘

(C) VfNG/NEW

   А  хотите  упасть?  Те кто не знает тот
фокус,  какой  я сейчас собираюсь описать,
точно упадут. Прикупите матов (нет,  спор-
тивных),  побольше ваты, йода  и медсестру
помоложе (пригодится).

   Набейте  или  выгрузите следующую прог-
рамку:

;-----------------------------------------
        ORG     #6200
;-----------------------------------------
        CALL    #C000 ;инициализация
                      ;музыкального
                      ;модуля
;-----------------------------------------
        DI               ;инициализируем
        LD      HL,#6000 ;IM 2
        LD      B,L      ;Вектор #6000
        LD      A,H      ;Процедура
        LD      I,A      ;обработки-
        INC     A        ;#C006, т.е.
L1      LD      (HL),A   ;проигрыватель
        INC     HL       ;мелодии
        DJNZ    L1
        LD      (HL),A
        LD      L,H
        LD      (HL),#C3
        INC     HL
        LD      DE,#C006 ;адрес процедуры
        LD      (HL),E   ;проигрывания
        INC     HL
        LD      (HL),D
        IM      2
;-----------------------------------------
        LD      HL,BEGIN         ;с
        LD      BC,#C000-BEGIN-3 ;адреса
L2      LD      (HL),#FB ;BEGIN создаем
        INC     HL       ;сколько влазит
        DEC     BC       ;команд EI
        LD      A,B
        OR      C
        JR      NZ,L2
        LD      (HL),#C3 ;после всей кучи
        INC     HL       ;EI переход на
        LD      DE,BEGIN ;BEGIN
        LD      (HL),E
        INC     HL
        LD      (HL),D
;-----------------------------------------
BEGIN           ;EI: EI: EI... JP BEGIN
;-----------------------------------------
        ORG     #C000
;-----------------------------------------
        INSERT  "MUSIC" ;какой-нибудь
                        ;музыкальный
                ;модуль, скомпилированый в
                ;#C000. Например, от PT2
                ;или Sound Tracker'а.

   Прикинем логику работы программки. Сна-
чала  она синициализирует IM 2, затем соз-
даст  в  памяти  процедуру,  состоящую  из
сплошных  EI-шек  и  одного  JP  чисто для
зацикливания.  Затем  эта  самая процедура
запустится.  Так как она состоит только из
EI,  то  на  какой-то  команде придет пре-
рывание,  значит  вызовется  проигрыватель
музыки  и из динамика польется сладкая ме-
лодия. Все верно? Запустите программу...

                   * * *

   Вас уже выписали из больницы? Как голо-
ва?  Все  еще  побаливает  после  падения?
Жаль,  что  так  получилось. Но я надеюсь,
вас  еще  интересует, почему эта программа
сработала  несколько  не  так,  как от нее
ожидалось?

   А ларчик открывается просто. Все дело в
команде  EI.  На  самом деле она не только
разрешает  прерывания,  а еще и ... запре-
щает  их! На время выполнения следующей за
собой  команды.  Этот  фокус встроен в Z80
чтобы  в  конце процедуры обработки INT'a,
заканчивающейся  EI: RET,  этот  самый RET
успевал  выполнится до прихода нового пре-
рывания. Кто-нибудь спросит: а как же тог-
да  EI: HALT, ведь по этой теории они дол-
жны  вызывать повисание? Все и тут просто:
на  самом деле команда HALT не просто ждет
INT,  а еще и вяжет носки, вaрит кашу, ме-
няет  ребенку  подгузники и генерирует ко-
манды  NOP.  Вот  на первый из HALT'овских
NOP'ов прерывания действительно запрещены,
а на все остальные-нет.

   Остается  вопрос:  где эту штучку можно
применить? Сам пока не знаю...