|
Читатель - читателю - Бегущая строка является важным элементом оформления программ.
|
Бегущая строка.
© Титов М., 1993.
Бегущая строка (БС) является важным элементом оформления программ. К сожалению, не во всех, даже фирменных программах, бегущая строка выполнена качественно. Хотя это совсем несложно.
Решающим фактором в БС является команда HALT (остановка до выполнения прерывания). Дело в том, что данные из экранной области на монитор поступают 50 раз в секунду. Обновление экрана происходит во время выполнения прерывания. Поэтому, если команда HALT отсутствует, то вначале могут обновиться, например, две нижние знаколинии БС а затем остальное. Поэтому иногда буквы начинают искажаться.
А теперь рассмотрим конкретный пример.
Задача: Разработать БС.
Условие: высота символов - 1 знакоместо, ширина - регулируемая по ходу строки.
Решение.
|
|
|
ORG |
26000 ; |
Расположим программу с адреса |
6590 |
|
FB |
EI |
; |
26000, разрешим прерывания (для HALT) |
6591 |
|
CDC165 |
CALL |
#65C1 ; |
Вызовем подпрограмму инициализации БС |
6594 |
LOOP1 |
0602 |
LD |
B, #02 |
Организуем циклический вызов |
6596 |
LOOP2 |
C5 |
PUSH |
BC ; |
БС до нажатия SPACE. От значения |
6597 |
|
CDDB65 |
CALL |
#65DB |
регистра B зависит скорость |
65 9A |
|
C1 |
POP |
BC ; |
БС. Чем больше число, тем больше |
659B |
|
10F9 |
DJNZ |
#6596 ; |
скорость. |
659D |
|
76 |
HALT |
|
|
659E |
|
3E7F |
LD |
A, #7F |
Проверяем клавишу SPACE, если |
65A0 |
|
DBFE |
IN |
A,(#FE) |
она не нажата, то переход на |
65A2 |
|
CB1F |
RR |
A ; |
LOOP1. |
65A4 |
|
38EE |
JR |
C,#6594 |
|
65A6 |
|
CDAA65 |
CALL |
#65AA |
При нажатии SPACE, очистка экрана |
65A9 |
|
C9 |
RET |
|
и выход в вызывающую подпрограмму. |
65AA |
CLS |
210040 |
LD |
HL,#4000 |
Очистим экран, заполним ярко- |
65AD |
|
110140 |
LD |
DE,#4001 |
желтым INK (число 4 6H = 70, |
65B0 |
|
010018 |
LD |
BC,#1800 |
его можно изменять; рассчитывается |
65B3 |
|
75 |
LD |
(HL),L |
так:INK+PAPER*8+BRIGHT* 64 + |
65B4 |
|
EDB0 |
LDIR |
|
+FLASH*128) и сделаем бордюр |
65B6 |
|
01FF02 |
LD |
BC,#02FF |
черным. |
65B9 |
|
3646 |
LD |
(HL),#46 |
|
65BB |
|
EDB0 |
LDIR |
|
|
65BD |
|
AF |
XOR |
A |
|
65BE |
|
D3FE |
OUT |
(#FE),A |
|
65C0 |
|
C9 |
RET |
|
|
65C1 |
INIT |
CDAA65 |
CALL |
#65AA |
Очистим экран, установим в |
65C4 |
|
215066 |
LD |
HL,#6650 |
STARTLET - начало текста, а в |
65C7 |
|
224B66 |
LD |
(#664B),HL |
COUNTLET - адрес текущего символа. |
65CA |
|
224D66 |
LD |
(# 664D) ,HL |
POSLET - содержит информацию |
65CD |
|
3E80 |
LD |
A, #80 |
о расположении текущего |
65CF |
|
324F66 |
LD |
(#664F),A |
пиксела. WIDTH - счетчик ширины |
65D2 |
|
3E02 |
LD |
A, #02 |
символов, а WIDTHLET - ширина |
65D4 |
|
324A66 |
LD |
(# 664A) ,A |
символа. |
65D7 |
|
324966 |
LD |
(#6649),A |
|
65DA |
|
C9 |
RET |
|
|
Итак, все вспомогательные процедуры позади, можно заняться самой БС.
65DB |
SCROL |
DD2A4B66 |
LD |
IX,(#664B) |
Поместим в регистр IX адрес |
65DF |
|
DD7E00 |
LD |
A,(IX+0) |
текущего символа и проверим его |
65E2 |
|
B7 |
OR |
A ; |
на ноль. Если текст БС не закончен, |
65E3 |
|
2007 |
JR |
NZ,#65EC |
то перейдем на SCROL1. |
65E5 |
|
DD2A4D66 |
LD |
IX, (# 664D) |
Из STARTLET поместим в IX |
65E9 |
|
DD7E00 |
LD |
A,(IX+0) |
адрес первого символа БС, а в регистр А первый символ БС. |
65EC |
SCROL1 |
FE20 |
CP |
#20 ; |
Если код поступившего символа больше 31 |
65EE |
|
3008 |
JR |
NC,#65F8 |
(любой знак), то перейдем на SCROL2, иначе код - это ширина символа. |
65F0 |
|
324A66 |
LD |
(# 664A) ,A |
Занесем в WIDTH и WIDTHLET |
65F3 |
|
324966 |
LD |
(#6649),A |
новую ширину символа, перейдем |
65F6 |
|
DD23 |
INC |
IX ; |
на следующий символ БС. |
65F8 |
SCROL2 |
DD224B66 |
LD |
(#664B),IX |
Сохраним в COUNTLET адрес |
65FC |
|
ED5B4F6 6 |
LD |
DE,(#664F) |
текущего символа. В регистр Е |
6600 |
|
1608 |
LD |
D, #08 |
поместим положение текущего пиксела данного символа, а в регистр D - число линий в знакоместе по вертикали. |
6602 |
SCROL3 |
DD6E00 |
LD |
L,(IX+0) |
Умножим код символа на 8, |
6605 |
|
2600 |
LD |
H, #00 |
прибавим адрес символьного набора |
6607 |
|
29 |
ADD |
HL, HL |
минус 256 (код пробела=32, |
6608 |
|
29 |
ADD |
HL, HL |
каждый символ занимает 8 байт |
6609 |
|
29 |
ADD |
HL, HL |
памяти, 8*32=256), прибавим текущую |
660A |
|
ED4B365C |
LD |
BC, (#5C36) |
линию БС минус 1 (последний |
660E |
|
09 |
ADD |
HL, BC |
байт символа равен 7+адрес |
660F |
|
4A |
LD |
C, D |
первого байта, а регистр D=8) и |
6610 |
|
0600 |
LD |
B, #00 |
получим в HL адрес знаколинии |
6612 |
|
0D |
DEC |
C |
данного символа. |
6613 |
|
09 |
ADD |
HL, BC |
|
6614 |
|
7E |
LD |
A, (HL) |
Поместим в регистр А текущий |
6615 |
|
21FF50 |
LD |
HL, #50FF |
байт из символьного набора, |
6618 |
|
42 |
LD |
B, D |
рассчитаем в HL адрес текущей |
6619 |
|
0E00 |
LD |
C, #00 |
линии на экране, поместим в регистр В |
661B |
|
05 |
DEC |
B |
длину экранной строки |
661C |
|
09 |
ADD |
HL, BC |
(32 знакоместа). |
661D |
|
0620 |
LD |
B, #20 |
|
661F |
|
A3 |
AND |
E |
С помощью регистра Е выделим |
6620 |
|
2F |
CPL |
|
из байта 1 пиксел, проинвертируем |
6621 |
|
FEFF |
CP |
#FF |
байт и получим в регистре |
А следующее: все биты, кроме одного равны 1, если текущий пиксел не 0, иначе все биты содержат 1. Если пиксел в символе не ноль, то байт < 255, иначе байт = 255. Значит, после сравнения с 255 флаг С установится в нужное для RL положение.
6623 |
SCROL4 |
CB16 |
RL |
(HL) |
Производим скрутку одной линии, |
6625 |
|
2B |
DEC |
HL |
не забывая о вычисленном |
6626 |
|
10FB |
DJNZ |
#6623 |
нами флаге С. |
6628 |
|
15 |
DEC |
D |
Повторяем операцию 8 раз |
6629 |
|
20D7 |
JR |
NZ,#6602 |
(снизу вверх на экране). |
662B |
|
3A4A66 |
LD |
A, (#664A) |
Уменьшаем счетчик ширины |
662E |
|
3D |
DEC |
A |
символов и, если не ноль, пере- |
662F |
|
2014 |
JR |
NZ,#6645 |
ходим на SCROL6. |
6631 |
|
3A4F66 |
LD |
A,(#664F) |
Переходим на следующий пиксел, |
6634 |
|
CB0F |
RRC |
A |
устанавливаем счетчик ширины. |
6636 |
|
324F66 |
LD |
(#664F),A |
Если весь символ выведен |
6639 |
|
3007 |
JR |
NC,#6642 |
на экран, переходим к следующему |
663B |
|
2A4B66 |
LD |
HL,(#664B) |
|
663E |
|
23 |
INC |
HL |
|
663F |
|
224B66 |
LD |
(#664B),HL |
|
6642 |
SCROL7 |
3A4 966 |
LD |
A,(#6649) |
|
6645 |
SCROL6 |
324A66 |
LD |
(# 664A) ,A |
|
6648 |
|
C9 |
RET |
|
Возврат в тело цикла. |
|
Для программных меток отведем специальный участок памяти. |
6649 |
WIDTHLET |
NOP |
|
Здесь после DEFM расположен |
664A |
WIDTH |
|
NOP |
|
текст БС, а после DEFB - ширина |
664B |
COUNTLET |
DEFW |
|
следующих символов (от 1 до 31) |
664D |
STARTLET |
DEFW |
|
NOP является признаком конца |
664F |
POSLET |
|
NOP |
|
текста (повторение БС). |
6650 |
SCROLTEXT |
DEFB |
2 |
|
|
|
|
DEFM |
"PROGRAMMED |
BY" |
|
|
|
DEFB |
4 |
|
|
|
|
DEFM |
" TITOV MAXIM" |
|
|
|
DEFM |
" (C)1993 " |
|
|
|
|
DEFM |
"STUDIO TM' |
M. " |
|
|
|
NOP |
|
|
Коментарий ИНФОРКОМА.
Представленная вниманию читателей программа "Бегущая строка" была успешно оттестирована в редакции и мы убедительно рекомендуем её читателям. БС очень плавно перемещается по экрану (дискретность составляет один пиксел), а скорость её можно регулировать в широких пределах. Она хорошо смотрится на экране и, несомненно, поможет Вам при оформлении Ваших программ.
Для устранения неоднозначности, ниже приводится дамп БС. Читатели, которые захотят повторить БС, могут для её набора воспользоваться другой программой в машинных кодах - шестнадцатеричным загрузчиком - которая приведена в этом же номере ZX-РЕВЮ.
6590 |
FB |
CD |
C1 |
65 |
06 |
02 |
C5 |
CD |
7D |
6598 |
DB |
65 |
C1 |
10 |
F9 |
76 |
3E |
7F |
3A |
65A0 |
DB |
FE |
CB |
1F |
38 |
EE |
CD |
AA |
65 |
65A8 |
65 |
C9 |
21 |
00 |
40 |
11 |
01 |
40 |
EE |
65B0 |
01 |
00 |
18 |
75 |
ED |
B0 |
01 |
FF |
40 |
65B8 |
02 |
36 |
46 |
ED |
B0 |
AF |
D3 |
FE |
B8 |
65C0 |
C9 |
CD |
AA |
65 |
21 |
50 |
66 |
22 |
C3 |
65C8 |
4B |
66 |
22 |
4D |
66 |
3E |
80 |
32 |
A3 |
65D0 |
4F |
66 |
3E |
02 |
32 |
4A |
66 |
32 |
3E |
65D8 |
49 |
66 |
C9 |
DD |
2A |
4B |
66 |
DD |
4A |
65E0 |
7E |
00 |
B7 |
20 |
07 |
DD |
2A |
4D |
F5 |
65E8 |
66 |
DD |
86 |
00 |
FE |
20 |
30 |
08 |
6C |
65F0 |
32 |
4A |
66 |
32 |
49 |
66 |
DD |
23 |
18 |
65F8 |
DD |
22 |
4B |
66 |
ED |
5B |
4F |
66 |
0A |
6600 |
16 |
08 |
DD |
6E |
00 |
26 |
00 |
29 |
1E |
6608 |
29 |
29 |
ED |
4B |
36 |
5C |
09 |
4A |
DD |
6610 |
06 |
00 |
0D |
09 |
7E |
21 |
FF |
50 |
80 |
6618 |
42 |
0E |
00 |
05 |
09 |
06 |
20 |
A3 |
A5 |
6620 |
2F |
FE |
FF |
CB |
16 |
2B |
10 |
FB |
C9 |
6628 |
15 |
20 |
D7 |
3A |
4A |
66 |
3D |
20 |
E1 |
6630 |
14 |
3A |
4F |
66 |
CB |
0F |
32 |
4F |
F4 |
6638 |
66 |
30 |
07 |
2A |
4B |
66 |
23 |
22 |
5B |
6640 |
4B |
66 |
3A |
49 |
66 |
32 |
4A |
66 |
22 |
6648 |
C9 |
02 |
02 |
50 |
66 |
50 |
66 |
80 |
67 |
6650 |
02 |
50 |
52 |
4F |
47 |
52 |
41 |
4D |
D0 |
6658 |
4D |
45 |
44 |
20 |
42 |
59 |
04 |
20 |
73 |
6660 |
54 |
49 |
54 |
4F |
56 |
20 |
4D |
41 |
0A |
6668 |
58 |
49 |
4D |
20 |
7F |
31 |
39 |
39 |
FE |
6670 |
33 |
20 |
53 |
54 |
55 |
44 |
49 |
4F |
01 |
6678 |
20 |
54 |
4D |
27 * * |
4D * |
2E |
20 |
00 |
61 |
|
|