Здесь показаны различия между двумя версиями данной страницы.
Следующая версия | Предыдущая версия | ||
msx:basic_dialogue_programming_language:104 [2022-09-11 23:30] GreyWolf создано |
msx:basic_dialogue_programming_language:104 [2023-02-19 16:26] (текущий) GreyWolf |
||
---|---|---|---|
Строка 2: | Строка 2: | ||
~~TOC wide~~ | ~~TOC wide~~ | ||
- | ====== 1.4 Использование ловушек ====== | + | {{anchor:n104}} |
+ | ====== 1.4. Использование ловушек ====== | ||
+ | <WRAP group> | ||
+ | <WRAP half column> \\ </WRAP> | ||
+ | <WRAP half column><WRAP right> | ||
+ | ... И тут Пух все понял. Они с Пятачком попались | ||
+ | \\ в Хитрую Ловушку для Пухов, которую в отместку | ||
+ | \\ им вырыл Слонопотам!... | ||
+ | <WRAP rightalign> | ||
+ | —//Отрывок из неопубликованной главы повести | ||
+ | \\ А.Милн "Винни–Пух и все–все–все"// | ||
+ | </WRAP></WRAP> | ||
+ | </WRAP></WRAP> | ||
+ | |||
+ | Вы, конечно,помните, что программы, выполняющие всю "черную" работу,"зашиты" в ROM, поэтому изменить их //невозможно//. Однако,в некоторых важных подпрограммах ROM предусмотрены своеобразные "перехваты" — //ловушки// ("hooks"). | ||
+ | |||
+ | Вызов подпрограммы–ловушки организуется в ROM следующим образом: | ||
<code> | <code> | ||
- | ... И тут Пух все понял. Они с Пятачком попались | + | PUSH HL ; Сохранение содержимого |
- | в Хитрую Ловушку для Пухов, которую в отмест- | + | PUSH DE ; регистров микропроцессора |
- | ку им вырыл Слонопотам!... | + | PUSH BC ; в стеке |
- | Отрывок из неопубликованной главы повести | + | PUSH AF ; |
- | А.Милн "Винни-Пух и все-все-все" | + | CALL а д р е с ; Вызов подпрограммы-ловушки по заданному адресу |
+ | POP AF ; Восстановление значения | ||
+ | POP BC ; регистров микропроцессора | ||
+ | POP DE ; для дальнейших операций | ||
+ | POP HL ; | ||
+ | </code> | ||
+ | При включении компьютера подпрограмма–ловушка содержит только команду возврата (RET). Вы //можете// заменить эту команду на команду перехода (JP) к подпрограмме, которая написана Вами на машинном языке. | ||
- | Вы,конечно,помните, что программы, выполняющие всю "черную" работу,"за- | + | <WRAP centeralign>В этом случае о ловушке говорят, что она //обрабатывается//.</WRAP> |
- | шиты" в ROM, поэтому изменить их н е в о з м о ж н о. Однако,в некоторых | + | |
- | важных подпрограммах ROM предусмотрены своеобразные "перехваты" - л о в у- | + | Таким образом, Вы можете косвенно изменять ROM и вводить //новые// операторы! Приведенный ниже рисунок показывает, что означает термин "обработать" ловушку. |
- | ш к и ("hooks"). | + | <code> |
- | Вызов подпрограммы-ловушки организуется в ROM следующим образом: | + | |
- | PUSH HL ; Сохранение содержимого | + | |
- | PUSH DE ; регистров микропроцессора | + | |
- | PUSH BC ; в стеке | + | |
- | PUSH AF ; | + | |
- | CALL а д р е с ; Вызов подпрограммы-ловушки по заданному адресу | + | |
- | POP AF ; Восстановление значения | + | |
- | POP BC ; регистров микропроцессора | + | |
- | POP DE ; для дальнейших операций | + | |
- | POP HL ; | + | |
- | При включении компьютера подпрограмма-ловушка содержит только команду | + | |
- | возврата (RET). Вы м о ж е т е заменить эту команду на команду перехода | + | |
- | (JP) к подпрограмме, которая написана Вами на машинном языке. | + | |
- | ┌───────────────────────────────────────────────────────────────────────┐ | + | |
- | │ В этом случае о ловушке говорят, что она о б р а б а т ы в а е т с я.│ | + | |
- | └───────────────────────────────────────────────────────────────────────┘ | + | |
- | Таким образом, Вы можете косвенно изменять ROM и вводить н о в ы е | + | |
- | операторы! Приведенный ниже рисунок показывает, что означает термин "обра- | + | |
- | ботать" ловушку. | + | |
┌───────────────────────────────┬───────────────────────────────────────┐ | ┌───────────────────────────────┬───────────────────────────────────────┐ | ||
│ ┌───────────────────────────┐ │ │ | │ ┌───────────────────────────┐ │ │ | ||
Строка 55: | Строка 58: | ||
│ └───────────────────────────┘ │ │ | │ └───────────────────────────┘ │ │ | ||
└───────────────────────────────┴───────────────────────────────────────┘ | └───────────────────────────────┴───────────────────────────────────────┘ | ||
+ | </code> | ||
- | П р и м е р 1. О т м е н а действия клавиши "STOP". | + | {{anchor:e1040-01}} |
- | ───────────── При в ы п о л н е н и и п р о г р а м м ы на языке | + | __//Пример 1.//__ //Отмена// действия клавиши <key>STOP</key>. |
- | MSX-BASIC клавиатура постоянно опрашивается (сканируется). Нажатие клави- | + | |
- | ши порождает код, который записывается в буфер клавиатуры (начинающийся с | + | |
- | адреса &HF55E в рабочей области). До этого код нажатой клавиши временно | + | |
- | записывается в слово NEWKEY, начинающееся с адреса &HFBE5. | + | |
- | Регистр А микропроцессора необходимо загрузить значением | + | |
- | ┌──────────────┐ | + | |
- | │ 8·NS+NC │, | + | |
- | └──────────────┘ | + | |
- | где: NS - номер строки матрицы клавиатуры; | + | |
- | NC - номер столбца матрицы клавиатуры. | + | |
- | Поэтому поместим в регистр A значение | + | |
- | 8·7+4=60=&H3C . | + | |
- | ▲ ▲ | + | |
- | Номер с т р о к и матрицы ─┘ └─ Номер с т о л б ц а матрицы | + | |
- | клавиатуры,содержащей клавишу клавиатуры,содержащей клавишу | + | |
- | "STOP" "STOP" | + | |
- | Затем осуществим переход на ловушку с именем KEYKOD , расположенную по | + | |
- | адресу &HFDCC . | + | |
- | Обычно ловушка занимает 5 байтов памяти, содержащих только команду ас- | + | |
- | семблера RET (ее код &HC9). Введем вместо нее переход на подпрограмму о б- | + | |
- | р а б о т к и л о в у ш к и . Эта подпрограмма будет действовать только | + | |
- | при нажатии клавиши "STOP". | + | |
- | 10 CLEAR 200,&HD000 'Зарезервируем область для хранения подпрограммы | + | |
- | ' обработки ловушки | + | |
- | 20 POKE &HFDCC,&HC3 'Запишем команду перехода на ловушку с именем | + | |
- | 30 POKE &HFDCD,&H00 ' KEYCOD : ┌───────────┐ | + | |
- | 40 POKE &HFDCE,&HD0 ' C3,00,D0 │ JP D000 │ | + | |
- | 50 AD=&HD000 └───────────┘ | + | |
- | 60 READ A$:IF A$="Z" THEN END | + | |
- | 70 POKE AD,VAL("&H"+A$) | + | |
- | 80 AD=AD+1:GOTO 60 | + | |
- | 100 'П о д п р о г р а м м а о б р а б о т к и л о в у ш к и | + | |
- | 120 DATA FE,3C :' CP 3C ;Сравниваем константу 3Ch с | + | |
- | ;содержимым регистра A | + | |
- | 130 DATA C0 :' RET NZ ; "нет" ──▶ выход | + | |
- | 140 DATA 3E,FD :' LD A,FD ; A=FD | + | |
- | 150 DATA 32,EB,FB :' LD (FBEBh),A ; A ──▶ FBEB | + | |
- | 160 DATA 3E,3C :' LD A,3C ; A=3C | + | |
- | 170 DATA C9 :' RET ; Выход | + | |
- | 180 DATA "Z" :' | + | |
- | Выполните эту программу: обратите внимание на тот факт,что нажатие кла- | + | |
- | виши STOP производит такой же эффект, как и нажатие клавиш "CTRL"+"STOP" | + | |
- | в к о м а н д н о м режиме. | + | |
- | Подпрограмма обработки ловушки посылает значение | + | |
- | &H11111101=&HFD | + | |
- | по адресу &HFBEB (шестая строка матрицы клавиатуры),имитируя тем самым на- | + | |
- | жатие клавиши "CTRL". При этом нажатие клавиши "STOP" будет прочитано как | + | |
- | одновременное нажатие клавиш "CTRL" и "STOP",что будет обработано в MSX- | + | |
- | -BASIC уже по обычным правилам. | + | |
- | Удалите вышеприведенную программу и введите новую программу: | + | |
- | 10 POKE &HFBB0,1 | + | |
- | 20 ON STOP GOSUB 100:STOP ON | + | |
- | 30 PRINT A:A=A+1:GOTO 30 | + | |
- | 100 RETURN | + | |
- | Нажатие клавиши "STOP" теперь не приводит к прекращению программы и вы- | + | |
- | воду на экран курсора. Поскольку клавиша "STOP" превращена в"CTRL"+"STOP", | + | |
- | то клавиша "STOP" "перестает работать". | + | |
- | Отметим, что нажатие сложной комбинации клавиш | + | |
- | "CTRL"+"SHIFT"+"GRAPH"+"РУС" | + | |
- | прекращает работу этой программы. | + | |
+ | При //выполнении программы// на языке [[msx:basic:|]] клавиатура постоянно опрашивается (сканируется). Нажатие клавиши порождает код, который записывается в буфер клавиатуры (начинающийся с адреса &HF55E в рабочей области). До этого код нажатой клавиши временно записывается в слово NEWKEY, начинающееся с адреса &HFBE5. | ||
- | П р и м е р 2. При нажатии функциональной клавиши F4 печатается слово | + | Регистр А микропроцессора необходимо загрузить значением |
- | ───────────── "Миша". | + | <WRAP group> |
- | 10 CLEAR 200,&HD000 | + | <WRAP half column> |
- | 20 POKE &HFDCC,&HC3 ':\ | + | <code> |
- | 30 POKE &HFDCD,&H0 ': > JP D000 | + | 8·NS+NC |
- | 40 POKE &HFDCE,&HD0 ':/ | + | </code> |
- | 50 AD=&HD000 | + | </WRAP> |
- | 60 READ A$:IF A$="Z" THEN END | + | , |
- | 70 POKE AD,VAL("&H"+A$) | + | <WRAP half column> |
- | 80 AD=AD+1: GOTO 60 | + | |
- | 90 DATA FE,38 :' CP 38h ; A:=38h ? | + | |
- | 100 DATA C0 :' RET NZ ; Символ ":=" означает "содержит" | + | |
- | 110 DATA 3E,ED :' LD A,EDh ; A:=EDh ───▶"М" | + | |
- | 120 DATA CD,A2,00 :' CALL 00A2 ; | + | |
- | 130 DATA 3E,C9 :' LD A,C9h ; A:=C9h ───▶"и" | + | |
- | 140 DATA CD,A2,00 :' CALL 00A2 ; | + | |
- | 150 DATA 3E,DB :' LD A,DBh ; A:=DBh ───▶"ш" | + | |
- | 160 DATA CD,A2,00 :' CALL 00A2 ; | + | |
- | 170 DATA 3E,C1 :' LD A,C1h ; A:=C1h ───▶"а" | + | |
- | 180 DATA CD,A2,00 :' CALL 00A2 ; | + | |
- | 190 DATA 3E,40 :' LD A,40h ; A:=40h | + | |
- | 200 DATA C9 :' RET ; | + | |
- | 210 DATA "Z" :' К о н е ц ; | + | |
- | П р и м е р 3. Команда RUN приводит к появлению на экране слова | + | |
- | ───────────── "Миша". | + | |
- | 10 CLEAR 200,&HD000 | + | |
- | 20 POKE &HFECB,&HC3 ':\ | + | |
- | 30 POKE &HFECC,&H0 ': > JP D000 | + | |
- | 40 POKE &HFECD,&HD0 ':/ | + | |
- | 50 AD=&HD000 | + | |
- | 60 READ A$:IF A$="Z" THEN END | + | |
- | 70 POKE AD,VAL("&H"+A$) | + | |
- | 80 AD=AD+1:GOTO 60 | + | |
- | 90 DATA 3E,ED :' LD A,EDh ; A:=EDh ───▶"М" | + | |
- | 100 DATA CD,A2,00 :' CALL 00A2 ; | + | |
- | 110 DATA 3E,C9 :' LD A,C9h ; A:=C9h ───▶"и" | + | |
- | 120 DATA CD,A2,00 :' CALL 00A2 ; | + | |
- | 130 DATA 3E,DB :' LD A,DBh ; A:=DBh ───▶"ш" | + | |
- | 140 DATA CD,A2,00 :' CALL 00A2 ; | + | |
- | 150 DATA 3E,C1 :' LD A,C1h ; A:=C1h ───▶"а" | + | |
- | 160 DATA CD,A2,00 :' CALL 00A2 ; | + | |
- | 170 DATA C9 :' RET ; | + | |
- | 180 DATA "Z" :' К о н е ц ; | + | |
- | П р и м е р 4. | + | </WRAP> |
- | ───────────── | + | </WRAP> |
- | Программа позволяет на слух оценивать частоту обращений к ловушкам по | + | где: |
- | маскируемым прерываниям. Во время очередного прерывания по таймеру издает- | + | * ''NS'' — номер строки матрицы клавиатуры; |
- | ся звонок-сигнал. Таким образом ловушка "прозванивается". | + | * ''NC'' — номер столбца матрицы клавиатуры. |
+ | Поэтому поместим в регистр A значение | ||
+ | <code> | ||
+ | 8·7+4=60=&H3C . | ||
+ | ▲ ▲ | ||
+ | Номер с т р о к и матрицы ─┘ └─ Номер с т о л б ц а матрицы | ||
+ | клавиатуры,содержащей клавишу клавиатуры,содержащей клавишу | ||
+ | "STOP" "STOP" | ||
+ | </code> | ||
+ | Затем осуществим переход на ловушку с именем KEYKOD, расположенную по адресу &HFDCC . | ||
+ | Обычно ловушка занимает 5 байтов памяти, содержащих только команду ассемблера RET (ее код &HC9). Введем вместо нее переход на подпрограмму //обработки ловушки//. Эта подпрограмма будет действовать только при нажатии клавиши <key>STOP</key>. | ||
+ | |||
+ | \\ {{.examples:1040-01.bas|}} \\ [[+tab|wmsxbpge>1040-01.bas]] | ||
+ | <code> | ||
+ | 10 CLEAR 200,&HD000 'Зарезервируем область для хранения подпрограммы | ||
+ | ' обработки ловушки | ||
+ | 20 POKE &HFDCC,&HC3 'Запишем команду перехода на ловушку с именем | ||
+ | 30 POKE &HFDCD,&H00 ' KEYCOD : ┌───────────┐ | ||
+ | 40 POKE &HFDCE,&HD0 ' C3,00,D0 │ JP D000 │ | ||
+ | 50 AD=&HD000 └───────────┘ | ||
+ | 60 READ A$:IF A$="Z" THEN END | ||
+ | 70 POKE AD,VAL("&H"+A$) | ||
+ | 80 AD=AD+1:GOTO 60 | ||
+ | 100 'П о д п р о г р а м м а о б р а б о т к и л о в у ш к и | ||
+ | 120 DATA FE,3C :' CP 3C ;Сравниваем константу 3Ch с | ||
+ | ;содержимым регистра A | ||
+ | 130 DATA C0 :' RET NZ ; "нет" ──▶ выход | ||
+ | 140 DATA 3E,FD :' LD A,FD ; A=FD | ||
+ | 150 DATA 32,EB,FB :' LD (FBEBh),A ; A ──▶ FBEB | ||
+ | 160 DATA 3E,3C :' LD A,3C ; A=3C | ||
+ | 170 DATA C9 :' RET ; Выход | ||
+ | 180 DATA "Z" :' | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Выполните эту программу: обратите внимание на тот факт,что нажатие клавиши <key>STOP</key> производит такой же эффект, как и нажатие клавиш <key>CTRL + STOP</key> в //командном// режиме. | ||
+ | |||
+ | Подпрограмма обработки ловушки посылает значение | ||
+ | <code> | ||
+ | &H11111101=&HFD | ||
+ | </code> | ||
+ | по адресу &HFBEB (шестая строка матрицы клавиатуры),имитируя тем самым нажатие клавиши <key>CTRL</key>. При этом нажатие клавиши <key>STOP</key> будет прочитано как одновременное нажатие клавиш <key>CTRL</key> и <key>STOP</key>,что будет обработано в [[msx:basic:|]] уже по обычным правилам. | ||
+ | |||
+ | Удалите вышеприведенную программу и введите новую программу: | ||
+ | <code> | ||
+ | 10 POKE &HFBB0,1 | ||
+ | 20 ON STOP GOSUB 100:STOP ON | ||
+ | 30 PRINT A:A=A+1:GOTO 30 | ||
+ | 100 RETURN | ||
+ | </code> | ||
+ | Нажатие клавиши <key>STOP</key> теперь не приводит к прекращению программы и выводу на экран курсора. Поскольку клавиша <key>STOP</key> превращена в <key>CTRL + STOP</key>, то клавиша <key>STOP</key> "перестает работать". | ||
+ | |||
+ | Отметим, что нажатие сложной комбинации клавиш <key>CTRL + SHIFT + GRAPH + РУС</key> прекращает работу этой программы. | ||
+ | |||
+ | {{anchor:e1040-02}} | ||
+ | __//Пример 2//__. При нажатии функциональной клавиши F4 печатается слово "Миша". \\ {{.examples:1040-02.bas|}} \\ [[+tab|wmsxbpge>1040-02.bas]] | ||
+ | <code> | ||
+ | 10 CLEAR 200,&HD000 | ||
+ | 20 POKE &HFDCC,&HC3 ':\ | ||
+ | 30 POKE &HFDCD,&H0 ': > JP D000 | ||
+ | 40 POKE &HFDCE,&HD0 ':/ | ||
+ | 50 AD=&HD000 | ||
+ | 60 READ A$:IF A$="Z" THEN END | ||
+ | 70 POKE AD,VAL("&H"+A$) | ||
+ | 80 AD=AD+1: GOTO 60 | ||
+ | 90 DATA FE,38 :' CP 38h ; A:=38h ? | ||
+ | 100 DATA C0 :' RET NZ ; Символ ":=" означает "содержит" | ||
+ | 110 DATA 3E,ED :' LD A,EDh ; A:=EDh ───▶"М" | ||
+ | 120 DATA CD,A2,00 :' CALL 00A2 ; | ||
+ | 130 DATA 3E,C9 :' LD A,C9h ; A:=C9h ───▶"и" | ||
+ | 140 DATA CD,A2,00 :' CALL 00A2 ; | ||
+ | 150 DATA 3E,DB :' LD A,DBh ; A:=DBh ───▶"ш" | ||
+ | 160 DATA CD,A2,00 :' CALL 00A2 ; | ||
+ | 170 DATA 3E,C1 :' LD A,C1h ; A:=C1h ───▶"а" | ||
+ | 180 DATA CD,A2,00 :' CALL 00A2 ; | ||
+ | 190 DATA 3E,40 :' LD A,40h ; A:=40h | ||
+ | 200 DATA C9 :' RET ; | ||
+ | 210 DATA "Z" :' К о н е ц ; | ||
+ | </code> | ||
+ | |||
+ | {{anchor:e1040-03}} | ||
+ | __//Пример 3//__. Команда RUN приводит к появлению на экране слова "Миша". \\ {{.examples:1040-03.bas|}} \\ [[+tab|wmsxbpge>1040-03.bas]] | ||
+ | <code> | ||
+ | 10 CLEAR 200,&HD000 | ||
+ | 20 POKE &HFECB,&HC3 ':\ | ||
+ | 30 POKE &HFECC,&H0 ': > JP D000 | ||
+ | 40 POKE &HFECD,&HD0 ':/ | ||
+ | 50 AD=&HD000 | ||
+ | 60 READ A$:IF A$="Z" THEN END | ||
+ | 70 POKE AD,VAL("&H"+A$) | ||
+ | 80 AD=AD+1:GOTO 60 | ||
+ | 90 DATA 3E,ED :' LD A,EDh ; A:=EDh ───▶"М" | ||
+ | 100 DATA CD,A2,00 :' CALL 00A2 ; | ||
+ | 110 DATA 3E,C9 :' LD A,C9h ; A:=C9h ───▶"и" | ||
+ | 120 DATA CD,A2,00 :' CALL 00A2 ; | ||
+ | 130 DATA 3E,DB :' LD A,DBh ; A:=DBh ───▶"ш" | ||
+ | 140 DATA CD,A2,00 :' CALL 00A2 ; | ||
+ | 150 DATA 3E,C1 :' LD A,C1h ; A:=C1h ───▶"а" | ||
+ | 160 DATA CD,A2,00 :' CALL 00A2 ; | ||
+ | 170 DATA C9 :' RET ; | ||
+ | 180 DATA "Z" :' К о н е ц ; | ||
+ | </code> | ||
+ | |||
+ | {{anchor:e1040-04}} | ||
+ | __//Пример 4//__. | ||
+ | Программа позволяет на слух оценивать частоту обращений к ловушкам по маскируемым прерываниям. Во время очередного прерывания по таймеру издается звонок–сигнал. Таким образом ловушка "прозванивается". | ||
+ | \\ {{.examples:1040-04.asm|}} \\ [[+tab|wmsxbpge>1040-04.asm]] | ||
+ | <code> | ||
.Z80 | .Z80 | ||
Строка 199: | Строка 217: | ||
DW 0 ; | DW 0 ; | ||
DW 0 ; | DW 0 ; | ||
- | NACH: XOR A ; | + | NACH: XOR A ; |
CALL 00C3H ; Очистка экрана | CALL 00C3H ; Очистка экрана | ||
CALL 00CCH ; Выключение функциальных клавиш | CALL 00CCH ; Выключение функциальных клавиш | ||
Строка 234: | Строка 252: | ||
.DEPHASE ; | .DEPHASE ; | ||
END ; | END ; | ||
+ | </code> | ||
- | + | {{anchor:e1040-05}} | |
- | П р и м е р 5. Перемещение спрайта по прерываниям | + | __//Пример 5//__. Перемещение спрайта по прерываниям |
- | ────────────── | + | \\ {{.examples:1040-05.asm|}} \\ [[+tab|wmsxbpge>1040-05.asm]] |
+ | <code> | ||
;Некоторые макроопределения: | ;Некоторые макроопределения: | ||
Строка 253: | Строка 273: | ||
; | ; | ||
GASI MACRO ; | GASI MACRO ; | ||
- | BCALL 041H ; В ы к л ю ч е н и е экрана | + | BCALL 041H ; В ы к л ю ч е н и е экрана |
ENDM ; | ENDM ; | ||
; | ; | ||
GORI MACRO ; | GORI MACRO ; | ||
- | BCALL 044H ; В к л ю ч е н и е экрана | + | BCALL 044H ; В к л ю ч е н и е экрана |
ENDM ; | ENDM ; | ||
; | ; | ||
NETEND MACRO ; | NETEND MACRO ; | ||
RST 030H ; | RST 030H ; | ||
- | DEFB 08FH ; Отключение от с е т и (только для MSX-2) | + | DEFB 08FH ; Отключение от с е т и (только для MSX-2) |
DEFW 04016H ; | DEFW 04016H ; | ||
ENDM ; | ENDM ; | ||
Строка 356: | Строка 376: | ||
CALL VRAM ; атуры. | CALL VRAM ; атуры. | ||
... ; Здесь может находиться Ваша программа. | ... ; Здесь может находиться Ваша программа. | ||
- | ... ; Например, программа движения фона или движения | + | ... ; Например, программа движения фона или движения |
... ; других спрайтов. | ... ; других спрайтов. | ||
... ; | ... ; |