[<>] ~~TOC wide~~ {{anchor:n1022}} ====== 1.2. Использование подпрограмм BIOS ====== \\ Когда книга сталкивается с головой — и при //этом раздается глухой звук, разве всегда //виновата книга. —//Г.Лихтенберг// {{anchor:n10221}} ===== 1.2.1. Подпрограммы BIOS без параметров ===== Подпрограммы BIOS ("Basic Input–Output System") имеют фиксированные адреса ROM, которые называются //входными// точками. Прежде чем Вы начнете разработку собственных подпрограмм, написанных в машинных кодах,рекомендуем тщательно изучить, что делают подпрограммы [[msx:bios|BIOS]]. Достаточно одного взгляда на описание подпрограмм [[msx:bios|BIOS]], чтобы заметить, что некоторые подпрограммы для работы //не требуют// ввода параметров. Проиллюстрируем использование таких подпрограмм. {{anchor:e10201-01}} __//Пример 1//__. //Инициализация// системы. DEFUSR=0:A=USR(0) Это "убийственная" инициализация — уничтожается все содержимое RAM (аналогично нажатию кнопки "RESET"). {{anchor:e10201-02}} __//Пример 2//__. \\ {{.examples:10201-02.bas|}} \\ [[+tab|wmsxbpge>10201-02.bas]] \\ //Инициализация// значений функциональных клавиш. Если Вам время от времени необходимо возвращение к стандартному определению значений, присвоенных функциональным клавишам, то поступите следующим образом: 10 KEY 1,"AAAA":KEY 2,"BBBB" 20 DEFUSR=&H3E 'Запомните адрес &H3E ! 30 IF INKEY$="" THEN 30 40 A=USR(0):KEY ON Программа BIOS с именем INIFNK по адресу &H3E переопределяет функциональные клавиши. Однако следует выполнить оператор ''KEY ON,'' чтобы увидеть результат на экране дисплея. {{anchor:e10201-03}} __//Пример 3//__. //Включение и выключение экрана.// Если Вы хотите моментально вывести большое количество информации на экран, то можно вначале "выключить" экран, затем выполнить операторы вывода информации, а только после этого "включить" экран. Подпрограмма BIOS с именем DISSCR, расположенная по адресу &H41 , //"выключает"// экран, тогда как подпрограмма с именем ENASCR, расположенная по адресу &H44 , //"включает"// его. {{anchor:e10201-04}} __//Пример 4//__. \\ {{.examples:10201-04.bas|}} \\ [[+tab|wmsxbpge>10201-04.bas]] 10 DEFUSR=&H41:DEFUSR1=&H44 20 SCREEN 0:A=USR(0) 40 FOR I=0 TO 1200:PRINT "A";:NEXT 70 A=USR1(0) {{anchor:e10201-05}} __//Пример 5//__. Очистка буфера клавиатуры \\ {{.examples:10201-05.bas|}} \\ [[+tab|wmsxbpge>10201-05.bas]] 10 CLEAR 200,&HD000:DEFUSR=&HD000 20 READ A$:IF A$="RET" THEN 50 30 POKE &HD000+T,VAL("&h"+A$) 40 T=T+1:GOTO 20 50 FOR I=0 TO 1000:NEXT' З а д е р ж к а 60 A=USR(0) 61 PRINT CHR$(PEEK(&H9000)) :'Вывод п е р в о г о нажатого символа 70 DATA CD,9F,0 :'Ожидание нажатия клавиши 80 DATA 32,00,90 :'Код нажатой клавиши ──▶ по адресу 9000 90 DATA CD,56,1 :'CALL KILBUF ∗ BIOS 0156 100 DATA C9 :'RET ∗ Вход: Нет Выход: Нет 110 DATA "RET" :' ∗ Изменения: регистр HL Приведем еще ряд примеров: * {{anchor:e10201-06}} Инициализация системы \\ {{.examples:10201-06.bas|}} \\ [[+tab|wmsxbpge>10201-06.bas]] 10 CALL NETEND 'Для компьютеров MSX-2 20 DEFUSR=0:A=USR(A) * {{anchor:e10201-07}} Установка режима ''SCREEN'' \\ {{.examples:10201-07.bas|}} \\ [[+tab|wmsxbpge>10201-07.bas]] 10 DEFUSR0=&H6C:DEFUSR1=&H6F 30 DEFUSR2=&H72:DEFUSR3=&H75 50 INPUT"Режим";N 60 IF N=0 THEN A=USR0(A) 70 IF N=1 THEN A=USR1(A) 80 IF N=2 THEN A=USR2(A) 90 IF N=3 THEN A=USR3(A) * {{anchor:e10201-08}} Возврат в текстовый режим \\ {{.examples:10201-08.bas|}} \\ [[+tab|wmsxbpge>10201-08.bas]] 10 DEFUSR=&HD2:A=USR(A) * {{anchor:e10201-09}} Инициализация Таблицы шаблонов и Таблицы атрибутов спрайтов \\ {{.examples:10201-09.bas|}} \\ [[+tab|wmsxbpge>10201-09.bas]] 10 DEFUSR=&H69:A=USR(A) * {{anchor:e10201-10}} Инициализация Программируемого Звукового Генератора (PSG) \\ {{.examples:10201-10.bas|}} \\ [[+tab|wmsxbpge>10201-10.bas]] 10 DEFUSR=&H90:A=USR(A) * {{anchor:e10201-11}} Подача звукового сигнала \\ {{.examples:10201-11.bas|}} \\ [[+tab|wmsxbpge>10201-11.bas]] 10 DEFUSR=&HC0:A=USR(A) * {{anchor:e10201-12}} Очистка экрана \\ {{.examples:10201-12.bas|}} \\ [[+tab|wmsxbpge>10201-12.bas]] 10 DEFUSR=&HC3:A=USR(A) * {{anchor:e10201-13}} Вывод значений функциональных клавиш на экран дисплея \\ {{.examples:10201-13.bas|}} \\ [[+tab|wmsxbpge>10201-13.bas]] 10 DEFUSR=&HCF:A=USR(A) * {{anchor:e10201-14}} Отмена вывода значений функциональных клавиш на экран дисплея \\ {{.examples:10201-14.bas|}} \\ [[+tab|wmsxbpge>10201-14.bas]] 10 DEFUSR=&HCC:A=USR(A) \\ Может ли лакомка не есть, если стол \\ перед ним ломится от яств? Пусть же \\ он утолит, наконец, голод и жажду! //Голландская народная песня// {{anchor:n10222}} ===== 1.2.2. Подпрограммы BIOS, требующие параметров ===== Заметим, что большинство подпрограмм BIOS требуют для своей работы передачи параметров, значения которых должны быть помещены в определенные регистры перед вызовом подпрограмм. Такие подпрограммы обычно запускаются программой,написанной в машинных кодах и состоящей из: * α) записи исходных данных в определенные регистры микропроцессора; * β) вызова нужной подпрограммы BIOS. Ознакомим Вас с приемами написания подпрограмм на машинном языке, требующих для своей работы передачи параметров. {{anchor:e10202-01}} __//Пример 1//__. Программа, включающая и выключающая индикатор CAPS (ввод заглавных букв). Подпрограмма BIOS с именем CHGCAP,расположенная по адресу &H0132 выключает индикатор "CAPS", если регистр A процессора содержит ненулевое значение, и включает индикатор "CAPS", если этот регистр содержит 0. Сначала опишем алгоритм программы,которая позволяет включить индикатор "CAPS": * α) загрузить 0 в регистр A; * β) перейти к подпрограмме с именем CHGCAP. Запишем алгоритм на ассемблере: LD A,0 ;Загрузим 0 в регистр А JP 0132 ;Перейдем к адресу &Н0132 А теперь приведем запись программы на машинном языке (в шестнадцатеричных кодах): \\ {{.examples:10202-01.asm|}} 3E, 00 LD A,0 C3, 32, 01 JP 0132h и на языке [[msx:basic:|]]: \\ {{.examples:10202-01.bas|}} \\ [[+tab|wmsxbpge>10202-01.bas]] 10 CLEAR 200,&HD000 ' Резервирование области в RAM 20 AD=&HD000 ' Запись текста программы 30 READ A$ ' в машинных кодах в эту область 40 IF A$="Z" THEN 100 ' посредством "любимых" нами 50 A=VAL("&H"+A$):POKE AD,A ' операторов 70 AD=AD+1:GOTO 30 ' POKE 100 DEFUSR=&HD000:A=USR(0) ' Запуск программы 220 DATA 3E,00 :' LD A,0 230 DATA C3,32,01 :' JP 0132 240 DATA "Z" Эта программа включает индикатор "CAPS". Выключите его вручную и введите команду: PRINT USR(0) Заметьте, что подпрограмма с именем CHGCAP изменяет только состояние индикатора, не затрагивая состояния самой клавиши CAPS ! Отметим, что использование оператора ''CLEAR'' — это не единственный способ выделения //защищенной// области в RAM. Может быть также "передвинута" Таблица PIT; тогда все машинные подпрограммы могут быть введены в область, начинающуюся с адреса &Н8000. {{anchor:e10202-02}} __//Пример 2//__. Включение и выключение индикатора CAPS в соответствии со значением аргумента функции ''USR''. Для передачи //однобайтного// аргумента подпрограмме вызовите подпрограмму, размещенную в ROM по адресу &H521F. Аргумент передается в регистр А. На языке ассемблера это пишется следующим образом: \\ {{.examples:10202-02.asm|}} CD,1F,52 CALL 521F ; Вызов подпрограммы по адресу 521F C3,32,01 JP 0132 ; Перейти к адресу 0132 Приведем окончательную программу: \\ {{.examples:10202-02.bas|}} \\ [[+tab|wmsxbpge>10202-02.bas]] 10 CLEAR 200,&HD000 'Резервирование области в RAM 20 AD=&HD000 30 READ A$:IF A$="Z" THEN 100 50 A=VAL("&H"+A$):POKE AD,A:AD=AD+1:GOTO 30 100 DEFUSR=&HD000:A=USR(0) 220 DATA CD,1F,52 :' CALL 521F 230 DATA C3,32,01 :' JP 0132 240 DATA "Z" Заметьте, что команда ''PRINT USR(0)'' //включает// индикатор, а команда ''PRINT USR(1)'' //выключает// его. Для передачи подпрограмме //двухбайтного// значения (например, адреса) используется подпрограмма, размещенная в ROM по адресу &H2F8A и использующая значение, хранящееся в шестнадцатибитном регистре HL. Приведем теперь список некоторых подпрограмм BIOS, использующих при работе параметры. - 1) запись числа (data) в регистр (register) видеопроцессора LD C,register LD B,data CALL 0047 RET - 2) запись числа (data) в видеопамять (address) LD HL,address LD A,data CALL 004D RET - 3) заполнение VRAM одним и тем же числом LD HL,address LD BC,length LD A,data CALL 0056 RET - 4) копирование блока из VRAM в RAM LD HL,address VRAM LD DE,address MEMORY LD BC,length CALL 0059 RET - 5) копирование блока из ROM или RAM в VRAM LD HL,address MEMORY LD DE,address VRAM LD BC,length CALL 005C RET - 6) запись числа в звукогенератор LD A,register LD E,data CALL 0093 RET - 7) вывод символа на принтер LD A,code ASCII CALL 00A5 RET - 8) вывод символа на экран LD A,code ASCII CALL 00A2 RET - 9) установка курсора в нужном месте экрана LD H,coordinate X LD L,coordinate Y CALL 00C6 RET - 10) вывод символа на графический экран LD A,code ASCII CALL 008D RET {{anchor:e10202-03}} __//Пример 3//__. Запись в видеопамять. Изменение латинской буквы "A".\\ {{.examples:10202-03.bas|}} \\ [[+tab|wmsxbpge>10202-03.bas]] 10 CLEAR 200,&H9000:SCREEN 1 20 DEFUSR=&H9000:AD=&H9000 30 READ A$:IF A$="z" THEN 70 40 POKE AD,VAL("&h"+A$):AD=AD+1:GOTO 30 70 A=USR(0):END 90 DATA C3,0B,90 :' JP 900Bh ────┐ 100 DATA FF,81,81,81,81,81,81,FF:' Д а н н ы е │ 110 DATA 01,08,00 :' LD BC,08 ◀────┘ 120 DATA 11,08,02 :' LD DE,0208h 130 DATA 21,03,90 :' LD HL,9003h 150 DATA CD,5C,00 :' CALL 005Ch 190 DATA C9,"z" :' RET {{anchor:e10202-04}} __//Пример 4//__. Запись данных в регистр видеопроцессора (VDP).\\ {{.examples:10202-04.bas|}} \\ [[+tab|wmsxbpge>10202-04.bas]] 10 INPUT C,B:POKE &HA000,C:POKE &HA001,B 'C - регистр, B - значение 20 DEFUSR=&H9000:AD=&H9000 30 READ A$:IF A$="z" THEN 70 40 POKE AD,VAL("&h"+A$):AD=AD+1:GOTO 30 70 A=USR(0):END 90 DATA 3A,00,A0 :' LD A,(A000h) 100 DATA 4F :' LD C,A 110 DATA 3A,01,A0 :' LD A,(A001h) 120 DATA 47 :' LD B,A 130 DATA CD,47,00 :' CALL 0047h 140 DATA C9,"z" :' RET {{anchor:e10202-05}} __//Пример 5//__. Использование подпрограммы расширенного BIOS для построения линии.\\ {{.examples:10202-05.bas|}} \\ [[+tab|wmsxbpge>10202-05.bas]] 10 DATA 01,10,00 :' LD BC, начальная X-координата 11 DATA 11,10,00 :' LD DE, начальная Y-координата 12 DATA F7 :' RST #30 13 DATA 87 :' (для ученического компьютера - 83) 14 DATA 85,00 :' Адрес расширенного BIOS 15 DATA C9 :' RET 20 FOR I=0 TO 10:READ A$:POKE &HD000+I,VAL("&h"+A$):NEXTI 30 SCREEN 5 :' Возможны SCREEN 5 ÷ SCREEN 8 40 POKE &HFCB3,240 :' X-координата ─▶ GXPOS (FCB3,FCB4); 50 POKE &HFCB5,173 :' Y-координата ─▶ GYPOS (FCB5,FCB6); 60 POKE &HF3F2,15 :' Цвет ─▶ ATRBYT(F3F2); 70 DEFUSR=&HD000: Z=USR(0) :' Рисуем л и н и ю 80 A$=INPUT$(1) :' К о н е ц {{anchor:e10202-06}} __//Пример 6//__. \\ {{.examples:10202-06.bas|}} \\ [[+tab|wmsxbpge>10202-06.bas]] 5 'Автор программы: Беленький Г. (9 класс). 05.01.90 10 DATA 01,00,00 :' LD BC, X начальное 11 DATA 11,00,00 :' LD DE, ∗∗∗∗ ◀─────────────────┐ 12 DATA F7 :' RST #30 │ 13 DATA 87 :' (для ученического компьютера-83)│ 14 DATA 85,00 :' адрес расширенного BIOS │ 15 DATA C9 :' RET │ 20 FORI=0TO10:READA$:POKE &HD000+I,VAL("&h"+A$):NEXT:DEFUSR=&HD000:'│ 30 SCREEN 8 :' Возможны SCREEN 5 ÷ SCREEN 8 │ 40 POKE&HFCB3,255:POKE &HFCB4,0 :' X-координата фиксированой точки │ 50 POKE&HFCB5,0:POKE &HFCB5,0 :' Y-координата │ 60 FOR I=0 TO 211 :' │ 70 POKE &HF3F2,I :' Цвет │ 80 POKE &HD004,I :' Изменяющаяся Y-координата ──────┘ 90 Z=USR(0) :' Рисуем л и н и ю 100 NEXT I :' 110 A$=INPUT$(1) :' К о н е ц {{anchor:e10202-07}} __//Пример 7//__. Использование подпрограммы расширенного BIOS для построения прямоугольника \\ {{.examples:10202-07.bas|}} \\ [[+tab|wmsxbpge>10202-07.bas]] 10 DATA 01,10,00 :'LD BC, X-координата одного угла прямоугольника 11 DATA 11,10,00 :'LD DE, Y-координата 12 DATA F7 :'RST #30 13 DATA 87 :'(для ученического компьютера - 83) 14 DATA C9,00 :'Адрес расширенного BIOS 15 DATA C9 :'RET 20 FOR I=0 TO 10:READA$:POKE &HD000+I,VAL("&h"+A$):NEXTI:DEFUSR=&HD000 30 SCREEN 5 :' Возможны SCREEN 5 ÷ SCREEN 8 40 POKE &HFCB3,100 :' X-координата противоположного угла прямоуг. 50 POKE &HFCB5,100 :' Y-координата противоположного угла прямоуг. 60 POKE &HF3F2,15 :' Цвет 72 Z=USR(0) :' Рисуем п р я м о у г о л ь н и к 80 A$=INPUT$(1) :' К о н е ц В заключении пункта приведем более сложный пример. {{anchor:e10202-08}} __//Пример 8//__. "Утолщение" символов в режиме SCREEN 1. \\ {{.examples:10202-08.bas|}} \\ [[+tab|wmsxbpge>10202-08.bas]] 10 CLEAR 300,&HD000 20 AD=&HD000:DEFUSR=&HD00B 30 READ A$ 40 IF A$="RET" THEN A=USR(0):END 50 POKE AD,VAL("&h"+A$):AD=AD+1:GOTO 30 80 DATA 1E,00 :'D000 LD E,0 ; 90 DATA 3D :'D002 DEC A ; 100 DATA 1C :'D003 INC E ; 110 DATA BB :'D004 CP E ; 120 DATA C2,02,D0 :'D005 JP NZ,D002h ; 130 DATA C9 :'D008 RET ; 140 DATA 00,00 :'D009 NOP ; 150 DATA CD,6F,00 :'D00B CALL 006Fh ;Установка режима SCREEN 1 160 DATA 16,00 :'D00E LD D,0 ; 170 DATA 06,FF :'D010 LD B,FFh ;255 символов 180 DATA 21,00,00 :'D012 LD HL,0 ; 190 DATA 3E,08 :'D015 LD A,8 ; 200 DATA 32,3F,D0 :'D017 LD (D03Fh),A ; 210 DATA CD,4A,00 :'D01A CALL 004Ah ;Читаем видеопамять 220 DATA BA :'D01D CP D ; 230 DATA CA,2C,D0 :'D01E JP Z,D02Ch ; 240 DATA CB,87 :'D021 RES 0,A ; 250 DATA 4F :'D023 LD C,A ; 260 DATA CD,00,D0 :'D024 CALL D000h ; 270 DATA 79 :'D027 LD A,C ; 280 DATA B3 :'D028 OR E ; 290 DATA CD,4D,00 :'D029 CALL 004Dh ;Запись в видеопамять 300 DATA 23 :'D02C INC HL ; 310 DATA 3A,3F,D0 :'D02D LD A,(D03Fh) ; 320 DATA 5F :'D030 LD E,A ; 330 DATA 3E,00 :'D031 LD A,0 ; 340 DATA 1D :'D033 DEC E ; 350 DATA BB :'D034 CP E ; 360 DATA 7B :'D035 LD A,E ; 370 DATA 32,3F,D0 :'D036 LD (D03Fh),A ; 380 DATA C2,1A,D0 :'D039 JP NZ,D01Ah ; 390 DATA 10,D7 :'D03C DJNZ $-27h ;Переход по адресу D015h 400 DATA C9 :'D03E RET 410 DATA RET __//Примечание//__. Для написания программ на машинном языке обычно требуется //программа–монитор//(т.е. программа, позволяющая подключать подпрограммы, написанные на машинном языке). Если Вы не пользуетесь программой-монитором, то приходится вводить данные в операторах DATA, как мы это только что проделали. Однако для длинных программ этот метод утомителен. При малейшей ошибке система часто "зависает"; естественный выход при этом - нажать кнопку сброса "RESET",а это означает, что все должно быть начато заново. Перед проверкой таких подпрограмм убедитесь,что они записаны на дискету! {{anchor:n10223}} ===== 1.2.3. Подпрограммы BIOS, возвращающие параметры ===== \\ Всякая мудрость хороша, если ее кто–нибудь \\ понял. Непонятая мудрость может запылиться. —//Д. Хармс// Многие подпрограммы BIOS возвращают один или несколько параметров. Эти результаты, разумеется, можно передать через ячейки RAM с явно заданным адресом непосредственно перед выходом из подпрограммы. В дальнейшем применение функции ''PEEK'' позволит Вам прочитать полученные данные. Однако, когда подпрограмма возвращает только одно значение, проще всего присвоить его результат переменной в операторе: R = USR(A) , где: * α) ''USR'' ("USeR"-"пользователь") — служебное слово; * β) R — имя переменной-результата работы подпрограммы; * γ) A — арифметическое выражение, значение которого совпадает со значением аргумента. {{anchor:e10203-01}} __//Пример 1//__. Проверка состояния джойстиков и передача значений через переменную в программу на [[msx:basic:|]]. Подпрограмма с именем GTSTCK позволяет ввести данные с одного из трех джойстиков. Джойстик при этом выбирается по содержимому регистра А (0, 1 или 2); прочитанное значение помещается в регистр А. Если номер джойстика задается посредством аргумента функции ''USR()'', то подпрограмма может быть "запущена" путем обращения к подпрограмме ROM, начинающейся с адреса &H521F. Как только значение аргумента помещено в регистр А, вызывается подпрограмма с именем GTSTCK. Содержимое регистра А (состояние джойстика) затем передается в основную программу через регистр HL. Подпрограмма, размещенная с адреса &H2F99, передает содержимое регистра HL программе, составленной на языке [[msx:basic:|]]. Подпрограмма на языке ассемблера выглядит следующим образом: \\ {{.examples:10203-01.asm|}} D000 CD,1F,52 CALL 521F ; В A помещается однобайтный аргумент D003 CD,D5,00 CALL 00D5 ; A=STICK(A) D006 26,00 LD H,0 ; В регистр H помещается 0 D008 6F LD L,A ; Содержимое А помещается в L D00A C3,99,2F JP 2F99 ; Содержимое регистра HL передается ; основной программе D00D C9 RET Приведем теперь программу на языке [[msx:basic:|]]. \\ {{.examples:10203-01.bas|}} \\ [[+tab|wmsxbpge>10203-01.bas]] 10 CLEAR 200,&HD000 'Резервирование области в RAM 20 AD=&HD000 30 READ A$:IF A$="Z" THEN 100 50 A=VAL("&H"+A$):POKE AD,A:AD=AD+1:GOTO 30 100 DEFUSR=&HD000 110 A=USR(0) 120 IF A<>0 THEN PRINT A 130 GOTO 110 220 DATA CD,1F,52 :' CALL 521F 230 DATA CD,D5,00 :' CALL 00D5 240 DATA 26,00 :' LD H,0 250 DATA 6F :' LD L,A 260 DATA C3,99,2F :' JP 2F99 270 DATA C9,"Z" :' RET Вы легко убедитесь, что функция ''USR(0)'' здесь "работает" точно так же, как функция ''STICK(0)''! Перечислим теперь некоторые подпрограммы, возвращающие параметры: - 1) чтение из видеопамяти LD HL,adrVRAM CALL 004A LD H,0 LD L,A CALL 2F99 RET - 2) начальный адрес атрибутов спрайта CALL 521F CALL 004A CALL 2F99 RET - 3) размер спрайта CALL 008A LD H,0 LD L,A CALL 2F99 RET - 4) чтение числа из звукогенератора CALL 521F CALL 0096 LD H,0 LD L,A CALL 2F99 RET - 5) задержка до нажатия клавиши и чтение ее кода CALL 009F LD H,0 LD L,A CALL 2F99 RET - 6) чтение состояния рукоятки джойстика CALL 521F CALL 00D5 LD H,0 LD L,A CALL 2F99 RET - 7) чтение состояния кнопки джойстика CALL 521F CALL 00D8 LD H,0 LD L,A CALL 2F99 RET - 8) чтение состояния клавиши на графическом планшете CALL 521F CALL 00DB LD H,0 LD L,A CALL 2F99 RET - 9) чтение статуса манипулятора PDL CALL 521F CALL 00DE LD H,0 LD L,A CALL 2F99 RET {{anchor:n10224}} ===== 1.2.4. Примеры ===== {{anchor:e10204-01}} __//Пример 1//__. Чтение символа с заданной позицией из буфера клавиатуры \\ {{.examples:10204-01.bas|}} \\ [[+tab|wmsxbpge>10204-01.bas]] 10 CLEAR 200,&HA000:DEFUSR=&HA000:POKE &HA100,2 '◀── Позиция символа 20 FOR I=0 TO 14:READ R$:POKE &HA000+I,VAL("&h"+R$):NEXT 30 Z=USR(0) 40 DATA CD,B4,00 :' CALL 00B4h 50 DATA 3A,00,A1 :' LD A,(A100h) 60 DATA 4F :' LD C,A 70 DATA 06,00 :' LD B,0 80 DATA 09 :' ADD HL,BC 90 DATA 7E :' LD A,(HL) 100 DATA CD,A2,00 :' CALL 00A2h 110 DATA C9 :' RET {{anchor:e10204-02}} __//Пример 2//__. Вывод на экран слова "Миша"! \\ {{.examples:10204-02.bas|}} \\ [[+tab|wmsxbpge>10204-02.bas]] 10 AD=&HD000:DEFUSR=&HD000 20 READ A$:IF A$="Z" THEN A=USR(0):END 30 POKE AD,VAL("&h"+A$) 40 AD=AD+1:GOTO 20 50 DATA 3E,ED :' LD A,ED 60 DATA CD,A2,00 :' CALL 00A2h;Вывод на экран содержимого регистра А 70 DATA 3E,C9 :' LD A,C9 80 DATA CD,A2,00 :' CALL 00A2h;Вывод на экран содержимого регистра А 90 DATA 3E,DB :' LD A,DB 100 DATA CD,A2,00 :' CALL 00A2h;Вывод на экран содержимого регистра А 110 DATA 3E,C1 :' LD A,C1 120 DATA CD,A2,00 :' CALL 00A2h;Вывод на экран содержимого регистра А 130 DATA C9 :' RET 140 DATA "Z" :' К о н е ц {{anchor:e10204-03}} __//Пример 3//__. Вывод на экран дисплея //неподвижного// спрайта. \\ {{.examples:10204-03.bas|}} \\ [[+tab|wmsxbpge>10204-03.bas]] 10 SCREEN 1 20 KEY OFF:CLEAR 300,&HD000:I=&HD000 30 READ A$:IF A$="z" THEN SCREEN 1:GOTO 50 40 POKE I,VAL("&h"+A$):I=I+1:GOTO 30 50 DEFUSR=&HD00C:A=USR(0) 60 DATA FF,FF,C3,C3:'Д а н н ы е 70 DATA C3,C3,FF,FF:'Д а н н ы е 80 DATA 64,01,00,0F:'X, Y, Ш а б л о н , Ц в е т 90 DATA 21,00,D0 :'LD HL,D000 100 DATA 11,00,38 :'LD DE,3800 110 DATA 01,08,00 :'LD BC,0008 120 DATA CD,5C,00 :'CALL 005C 130 DATA 21,08,D0 :'LD HL,D008 140 DATA 11,00,1B :'LD DE,1B00 150 DATA 01,04,00 :'LD BC,0004 160 DATA CD,5C,00 :'CALL 005C 170 DATA 21,09,D0 :'LD HL,D009 180 DATA 34 :'INC (HL) 190 DATA C9 :'RET 230 DATA"z" :'К о н е ц {{anchor:e10204-04}} __//Пример 4//__. Вывод на экран дисплея //движущегося// спрайта \\ {{.examples:10204-04.bas|}} \\ [[+tab|wmsxbpge>10204-04.bas]] 10 SCREEN 1 20 KEY OFF:CLEAR 300,&HD000:I=&HD000 30 READ A$:IF A$="z" THEN SCREEN 1:GOTO 50 40 POKE I,VAL("&h"+A$):I=I+1:GOTO 30 50 DEFUSR=&HD00C:A=USR(0) 60 DATA FF,FF,C3,C3:'Д а н н ы е 70 DATA C3,C3,FF,FF:'Д а н н ы е 80 DATA 64,01,00,0F:'X, Y, Ш а б л о н , Ц в е т 90 DATA 21,00,D0 :'LD HL,D000 100 DATA 11,00,38 :'LD DE,3800 110 DATA 01,08,00 :'LD BC,0008 120 DATA CD,5C,00 :'CALL 005C 130 DATA 21,08,D0 :'LD HL,D008◀┐ 140 DATA 11,00,1B :'LD DE,1B00 │ 150 DATA 01,04,00 :'LD BC,0004 │ 160 DATA CD,5C,00 :'CALL 005C │ 170 DATA 21,09,D0 :'LD HL,D009 │ 180 DATA 34 :'INC (HL) │ 190 DATA CD,BA,00 :'CALL 00BA │ 200 DATA 06,F1,00 :'LD B,F1◀─┐ │Задержка 210 DATA 10,FD :'DJNZ ─┘ │Задержка 220 DATA C3,17,D0 :'JP D017 ───┘ 230 DATA"z" :'К о н е ц {{anchor:e10204-05}} __//Пример 5//__. Столкновение спрайтов \\ {{.examples:10204-05.bas|}} \\ [[+tab|wmsxbpge>10204-05.bas]] 10 POKE &HD000,0:KEYOFF 20 SCREEN 1:SPRITE$(0)="orpolrplor":SPRITE$(1)="orplorlorlo" 30 DEFUSR=&H9000:D=&H9000 50 READ A$ 60 IF A$="z" THEN 180 70 POKE D,VAL("&h"+A$) 80 D=D+1 90 GOTO 50 100 DATA CD,3E,01 :' CALL 013E 110 DATA E6,20 :' AND 20 120 DATA FE,00 :' CP 0 130 DATA C8 :' RET Z 140 DATA 3E,01 :' LD A,1 150 DATA 32,00,D0 :' LD (D000),A 160 DATA C9 :' RET 170 DATA "z" :' К о н е ц 180 FOR I=0 TO 255:PUT SPRITE 1,(I,40),6,0:PUT SPRITE 2,(255-I,40),5,1 190 A=USR(0):P=PEEK(&HD000): IF P=1 THEN FOR K=0 TO 10:COLOR 1,15,15:COLOR 15,1,1:NEXT: POKE &HD000,0 200 NEXT:GOTO 180 {{anchor:e10204-06}} __//Пример 6//__. Мгновенное "утолщение" символов! \\ {{.examples:10204-06.bas|}} \\ [[+tab|wmsxbpge>10204-06.bas]] 10 CLEAR 100,&HA000:AD=&HA000:DEFUSR=&HA000 30 READ A$:IF A$="z"THEN 80 50 POKE AD,VAL("&h"+A$):AD=AD+1:GOTO 30 80 A=USR(0):END 90 DATA CD,6F,00 :' CALL 006Fh 100 DATA 21,08,01 :' LD HL,0108h 110 DATA 11,F8,07 :' LD DE,07F8h 120 DATA CD,4A,00 :' CALL 004Ah ◀──┐ 130 DATA 47 :' LD B,A │ 140 DATA CB,38 :' SRL B │ 150 DATA B0 :' OR B │ 160 DATA CD,4D,00 :' CALL 004Dh │ 170 DATA 7D :' LD A,L │ 180 DATA BB :' CP E │ 190 DATA CA,1C,A0 :' JP Z,A01Ch──│──┐ 200 DATA 23 :' INC HL │ │ 210 DATA C3,09,A0 :' JP A009 ───┘ │ 220 DATA 7A :' LD A,D ◀──────┘ 230 DATA BC :' CP H 240 DATA CA,25,A0 :' JP Z,A025h──┐ 250 DATA 23 :' INC HL │ 260 DATA C3,09,A0 :' JP A009h │ 270 DATA C9 :' RET ◀──┘ 280 DATA "z" :' К о н е ц {{anchor:e10204-07}} __//Пример 7//__. Образование слова-"перевертыша" \\ {{.examples:10204-07.bas|}} \\ [[+tab|wmsxbpge>10204-07.bas]] 10 CLEAR 400,&HD000:DEFUSR=&HD00F:A=&HD00F 20 READ A$:IF A$="z" THEN R=USR(R):END ELSE 30 30 POKE A,VAL("&h"+A$):A=A+1:GOTO 20 40 DATA CD,C3,00 :' CALL 00C3 ; Очистка экрана 50 DATA CD,B4,00 :' CALL 00B4 ; Ввод строки 60 DATA 06,11 :' LD B,11h ; Загрузка параметра цикла 70 DATA 23 :' INC HL ; ◀──────┐ 80 DATA 10,FD :' DJNZ $-1 ; ───────┘ 90 DATA 06,11 :' LD B,11h ; Загрузка параметра цикла 100 DATA 7E :' LD A,(HL) ; 110 DATA 2B :' DEC HL ; 120 DATA CD,A2,00 :' CALL 00A2 ; Печать символа, код которого содер- ; жится в регистре A 130 DATA 10,F9 :' DJNZ $-5 ; Цикл, организованный для печати ; слова 140 DATA C9 :' RET ; К о н е ц 150 DATA "z" {{anchor:e10204-08}} __//Пример 8//__. Вычеркивание из слова латинской буквы "А" \\ {{.examples:10204-08.bas|}} \\ [[+tab|wmsxbpge>10204-08.bas]] 10 CLEAR 200,&HD000:DEFUSR=&HD001:A=&HD001 20 READ R$:IF R$="z" THEN 40 30 POKE A,VAL("&h"+R$):A=A+1:GOTO 20 40 P=USR(0) 45 DATA CD,C3,00 :'CALL 00C3 ; Очистка экрана 50 DATA CD,B4,00 :'CALL 00B4 ; Ввод строки 70 DATA 3E,41 :'LD A,41 ; Загрузка кода вычеркиваемого символа 75 DATA 23 :'INC HL ; 80 DATA BE :'CP (HL) ; 90 DATA 28,04 :'JR Z,$+6 ; 100 DATA 7E :'LD A,(HL) ; 110 DATA CD,A2,00 :'CALL 00A2 ; Вывод символа с кодом,содержащимся в ; регистре А 120 DATA 3E,00 :'LD A,00 ; 130 DATA BE :'CP (HL) ; 140 DATA 28,02 :'JR Z,$+3 ; Выход из программы по биту Z 141 DATA 18,EF :'JR $-15 ; 145 DATA C9 :'RET ; 150 DATA "z" {{anchor:e10204-09}} __//Пример 9//__. Подсчет количества символов во введенном слове \\ {{.examples:10204-09.bas|}} \\ [[+tab|wmsxbpge>10204-09.bas]] 10 CLEAR 200,&HD000:DEFUSR=&HD001:A=&HD001 20 READ R$:IF R$="z" THEN 40 30 POKE A,VAL("&h"+R$):A=A+1:GOTO 20 40 P=USR(0) 45 DATA CD,C3,00 :' CALL 00C3 ; Очистка экрана 50 DATA CD,B4,00 :' CALL 00B4 ; Ввод слова 60 DATA 06,00 :' LD B,00 ; 70 DATA 3E,00 :' LD A,00 ; 75 DATA 23 :' INC HL ; 80 DATA BE :' CP (HL) ; 90 DATA 28,03 :' JR Z,$+5 ; 100 DATA 04 :' INC B ; 110 DATA 18,F7 :' JR $-7 ; 120 DATA 78 :' LD A,B ; 130 DATA 32,00,A0 :' LD (A000),A; 140 DATA C9 :' RET ; 150 DATA "z" 160 PRINT PEEK(&HA000) {{anchor:e10204-10}} __//Пример 10//__. Иллюстрация работы подпрограммы BIOS по адресу 0010h \\ {{.examples:10204-10.bas|}} \\ [[+tab|wmsxbpge>10204-10.bas]] 10 CLEAR 100,&HD000:DEFUSR=&HD000:AD=&HD000 40 C$="YAMAHA !!!":C=LEN(C$) 50 FOR I=1 TO LEN(C$) 60 POKE &HA000+I,ASC(MID$(C$,I,1)) 70 NEXT 80 READ A$:IF A$="z"THEN 120 100 POKE AD,VAL("&h"+A$):AD=AD+1:GOTO 80 120 POKE &HD001,C:A=USR(0):END 130 DATA 06,00 :' LD B,0 ;В регистре B уже находится длина ;слова C$ 140 DATA 21,00,A0 :' LD HL,A000 150 DATA CD,10,00 :' CALL 0010 ;◀──┐ 160 DATA CD,A2,00 :' CALL 00A2 ; │ 170 DATA 10,F8 :' DJNZ D005 ;───┘ 180 DATA C9 :' RET 190 DATA "z" {{anchor:e10204-11}} __//Пример 11//__. Использование текстового представления для установки //точки// на графическом экране. \\ {{.examples:10204-11.bas|}} \\ [[+tab|wmsxbpge>10204-11.bas]] 10 SCREEN 7 20 POKE &HA000,&H28 :'Загрузка кода ASCII символа "(" 30 POKE &HA001,&HF :'Управляющий код. Если координата X двухбайтовая, то управляющий код равен &H1C, иначе - &h0F 40 POKE &HA002,&HFF :'Координата X 50 POKE &HA003,&H2C :'Код ASCII символа "," 60 POKE &HA004,&HF :'Управляющий код 70 POKE &HA005,&H1A :'Координата Y 80 POKE &HA006,&H29 :'Код ASCII символа ")" 90 POKE &HA007,&H2C :'Код ASCII символа "," 100 POKE &HA008,&HF :'Управляющий код 110 POKE &HA009,&HF :'Код цвета т о ч к и 120 POKE &HA00A,&H0 :'Конец т е к с т о в о г о представления 130 CLEAR 200,&HD000:DEFUSR=&HD000:P=&HD000 140 READ A$ 150 IF A$="z" THEN GOTO 170 160 POKE P,VAL("&h"+A$):P=P+1:GOTO 140 170 A=USR(0) 180 DATA 21,00,A0 :'LD HL,A000 Загрузка адреса текстового представления оператора 190 DATA F7,87,6D,00 :'RST 30[87/006D] Обращение к подпрограмме BIOS 200 DATA c9,"z" 210 A$=INPUT$(1) {{anchor:e10204-12}} __//Пример 12//__. Вывод на экран дисплея числа из регистра B \\ {{.examples:10204-12.bas|}} \\ [[+tab|wmsxbpge>10204-12.bas]] 10 DATA 3A,00,E0 :' D000:LD A,(E000) ;Исходное число 20 DATA 47 :' LD B,A ;сохраняем в регистре B 30 DATA CD,12,D0 :' CALL D012 ;──────────────────────┐ 40 DATA CD,A2,00 :' CALL 00A2 ;Печатаем символ │ 50 DATA 78 :' LD A,B ;Восстанавливаем │ 60 DATA CD,16,D0 :' CALL D016 ;──────────────────────│┐ 70 DATA CD,A2,00 :' CALL 00A2 ;Печатаем символ ││ 80 DATA C9 :' RET ;Возврат в MSX-BASIC ││ 90 DATA 0F :'D012: RRCA ;◀─────────────────────┘│ 100 DATA 0F :' RRCA ;Ставим старший полубайт│ 110 DATA 0F :' RRCA ;на место младшего │ 120 DATA 0F :' RRCA ; ▼ 130 DATA E6,0F :'D016: AND 0F ;Выделяем младший полубайт 140 DATA 0E,0A :' LD C,0A ;Сравниваем с 10 150 DATA B9 :' CP C ;··· 160 DATA FA,21,D0 :' JP M,D021 ;Если меньше, то ───────┐ 170 DATA C6,37 :' ADD A,37 ; │ 180 DATA C9 :' RET ; │ 190 DATA C6,30 :'D021: ADD A,30 ;◀──────────────────────┘ 200 DATA C9 :' RET ; 210 ' :'E000: заданное число 220 FOR I=0 TO 35: READ A$ 230 POKE &HD000+I,VAL("&h"+A$) 240 NEXT I 245 PRINT"Введите целое число, не превышающее 255"; 250 INPUT BYTE: POKE &HE000,BYTE 255 PRINT"Ваше число в шестнадцатеричном виде: &h"; 260 DEFUSR=&HD000:Z=USR(0) run Введите целое число, не превышающее 255? 255 Ваше число в шестнадцатеричном виде: &hFF Ok {{anchor:e10204-13}} __//Пример 13//__. Ввод в память компьютера числа с клавиатуры при помощи подпрограммы BIOS \\ {{.examples:10204-13.bas|}} \\ [[+tab|wmsxbpge>10204-13.bas]] 5' Автор программы: Поляков С.,10-й класс. 14.01.89 10 CLEAR 200,&HD000:AD=&HD000 30 READ A$:IF A$="z" THEN 60 50 A=VAL("&h"+A$):POKE AD,A:AD=AD+1:GOTO 30 60 DEFUSR=&HD000 70 PRINT"Введите десятичное трехзначное число от 0 до 255:" 80 A=USR(0):PRINT"Вы ввели число:"PEEK(&HB000):END 110 DATA F7,00,B4,00 :'RST 30[00/00B4];BIOS ввода строки 120 DATA 23 :'INC HL 130 DATA 7E :'LD A,(HL) ;В А - код первого символа 140 DATA 06,63 :'LD B,63h ;Блок получения числа сотен 150 DATA D6,30 :'SUB 30h ;;; В регистре А - число 160 DATA 57 :'LD D,A ;;; 170 DATA 8A :'ADC A,D ;;; 180 DATA 10,FD :'DJNZ $-1 ;;; 190 DATA 5F :'LD E,A ;В регистрах А и Е - число 200 DATA 16,00 :'LD D,00h ;сотен, умноженное на 100 210 DATA D5 :'PUSH DE ;Результат - в регистре DE 220 DATA 23 :'INC HL 230 DATA 7E :'LD A,(HL) ;В А - код второго символа 240 DATA 06,09 :'LD B,09h ;Блок получения числа десятков 250 DATA D6,30 :'SUB 30h ;;; В регистре А - число 260 DATA 57 :'LD D,A ;;; 270 DATA 8A :'ADC A,D ;;; 280 DATA 10,FD :'DJNZ $-1 ;;; 290 DATA D1 :'POP DE ; 300 DATA 8B :'ADC A,E ; 310 DATA 5F :'LD E,A ;В регистрах А и Е - сумма со- 320 DATA D5 :'PUSH DE ;тен и десятков 330 DATA 23 :'INC HL ; 340 DATA 7E :'LD A,(HL) ;В А - код третьего символа 350 DATA D6,30 :'SUB 30h ;В регистре А - число 360 DATA D1 :'POP DE 370 DATA 8B :'ADC A,E ;В А - введенное нами число 380 DATA 6F :'LD L,A 390 DATA 26,00 :'LD H,00 400 DATA 22,00,B0 :'LD (B000h),HL 410 DATA C9 :'RET 420 DATA "z" \\ Письмо это вышло более длинным только \\ потому, что мне некогда было написать \\ его покороче. —//Б.Паскаль. Письма к провинциалу, \\ 16-е письмо// {{anchor:e10204-14}} __//Пример 14//__. Инициализация текстово-графического режима SCREEN 1-2 на компьютерах MSX-1. \\ {{.examples:10204-14.bas|}} \\ [[+tab|wmsxbpge>10204-14.bas]] 10 CLEAR 400,&HD000:DEFUSR=&HD000:K=&HD000 40 READ A$:IF A$="Z" THEN A=USR(0):END 60 POKE K,VAL("&H"+A$):K=K+1:GOTO 40 90 DATA CD,6F,00 :' CALL 006F ;Режим SCREEN 1 100 DATA 3E,20 :' LD A,20 ; 110 DATA 32,B0,F3 :' LD (F3B0),A ;Установка 32 симв.в строке 120 DATA CD,7E,00 :' CALL 007E ;Установка SCREEN 1-2 130 DATA 21,00,00 :' LD HL,0000 ; 140 DATA 11,BF,1B :' LD DE,1BBF ; 150 DATA 1A :' LD A,(DE) ◀─────┐; ┌───────────────────┐ 160 DATA CD,2A,D0 :' CALL D02A ─────┐ │; │ Часть программы, │ 170 DATA 3E,F0 :' LD A,F0 │ │; │ │ 180 DATA CB,EC :' SET 5,H │ │; │ │ 190 DATA CD,2A,D0 :' CALL D02A ───┐ │ │; │ │ 200 DATA CB,AC :' RES 5,H │ │ │; │ │ 210 DATA 13 :' INC DE │ │ │; │ которая │ 220 DATA 23 :' INC HL │ │ │; │ │ 230 DATA 7C :' LD A,H │ │ │; │ │ 240 DATA D6,08 :' SUB 08 │ │ │; │ │ 250 DATA C2,11,D0 :' JP NZ,D011 ─┼─┼─┘; │ │ 260 DATA 00 :' NOP │ │ ; │ считывает │ 270 DATA C3,3F,D0 :' JP D03F ──┼─┼┐ ; │ │ 280 DATA 47 :' LD B,A ◀──┘◀┘│ ; │ │ 290 DATA CD,4D,00 :' CALL 004D │ ; │ │ 300 DATA CB,DC :' SET 3,H │ ; │ │ 310 DATA 78 :' LD A,B │ ; │ шаблоны │ 320 DATA CD,4D,00 :' CALL 004D │ ; │ │ 330 DATA CB,9C :' RES 3,H │ ; │ │ 340 DATA CB,E4 :' SET 4,H │ ; │ │ 350 DATA 78 :' LD A,B │ ; │ символов │ 360 DATA CD,4D,00 :' CALL 004D │ ; │ │ 370 DATA CB,A4 :' RES 4,H │ ; └───────────────────┘ 380 DATA C9 :' RET │ ; 390 DATA 21,F8,0F :' LD HL,0FF8 ◀──┘ ; 400 DATA 3E,FF :' LD A,FF ; 410 DATA CD,51,D0 :' CALL D051 ────┐ ; 420 DATA CD,4E,D0 :' CALL D04E ───┐│ ; 430 DATA C9 :' RET ││ ; К о н е ц 440 DATA 00,00,00 :' ││ ; 450 DATA 21,F8,17 :' LD HL,17F8◀┘│ ; 460 DATA 06,08 :' LD B,8 ◀────┘ ;Подпрограмма,"считывающая" 470 DATA CD,4D,00 :' CALL 004D◀──┐ ;курсор для 2-й и 3-й час- 480 DATA 23 :' INC HL │ ;тей экрана 490 DATA 10,FA :' DJNZ $ - 4──┘ ; 500 DATA C9 :' RET 510 DATA "Z" ---- [<>] {{tag>MSX msxbdpl}}