[<>]
~~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}}