Имитатор "телевизора"
© Патрахин В.В., г. Оленегорск, 1994.
Программа создает эффект "снега" при отсутствии сигнала на входе телевизора. В программе используются переменные: YX двухбайтная величина, старший байт - строка, младший - столбец левого верхнего угла экрана
имитируемого "'телевизора". VERT размер по вертикали (в знакоместах) экрана имитируемого телевизора. HORIZ то же по горизонтали.
00010 |
|
ORG |
40000 |
00020 |
|
ENT |
|
00030 |
YX |
EQU |
#0904 |
00040 |
VERT |
EQU |
10 |
00050 |
HORIZ |
EQU |
14 |
00060 |
START |
LD |
DE,0 |
00070 |
|
CALL |
SNOW |
00080 |
|
LD |
DE,4000 |
00090 |
|
CALL |
SNOW |
00100 |
|
LD |
DE,7000 |
00110 |
|
CALL |
SNOW |
00120 |
|
LD |
DE,9000 |
00130 |
|
CALL |
SNOW |
00140 |
|
LD |
A, 127 |
00150 |
|
IN |
A, (254) |
00160 |
|
RRA |
|
00170 |
|
JR |
C,START |
00180 |
|
RET |
|
00190 |
SNOW |
LD |
HL, YX |
00200 |
|
LD |
A, L |
00210 |
|
AND |
#07 |
00220 |
|
RRCA |
|
00230 |
|
RRCA |
|
00240 |
|
RRCA |
|
00250 |
|
ADD |
A, H |
00260 |
|
LD |
H, L |
00270 |
|
LD |
L,A |
00280 |
|
LD |
A, H |
00290 |
|
AND |
#18 |
00300 |
|
OR |
#40 |
00310 |
|
LD |
H, A |
00320 |
|
LD |
B, 8 |
00330 |
L4 |
PUSH |
HL |
00340 |
|
PUSH |
BC |
00350 |
|
LD |
C,VERT |
00360 |
L3 |
LD |
B,HORIZ |
00370 |
|
PUSH |
DE |
00380 |
|
POP |
IX |
00390 |
|
PUSH |
HL |
00400 |
|
LD |
DE,#0020 |
00410 |
|
ADD |
HL, DE |
00420 |
|
EX |
DE, HL |
00430 |
|
POP |
HL |
00440 |
|
LD |
A, D |
00450 |
|
CP |
H |
00460 |
|
JR |
Z, L1 |
00470 |
|
PUSH |
HL |
00480 |
|
EX |
DE, HL |
00490 |
|
LD |
DE,#0700 |
00500 |
|
ADD |
HL, DE |
00510 |
|
EX |
DE, HL |
00520 |
|
POP |
HL |
00530 |
L1 |
PUSH |
DE |
00540 |
|
TUSH |
IX |
00550 |
POP |
DE |
00560 L2 |
LD |
A,(DE) |
00570 |
LD |
(HL),A |
00580 |
INC |
HL |
00590 |
INC |
DE |
00600 |
DJNZ |
L2 |
00610 |
POP |
HL |
00620 |
DEC |
C |
00630 |
JR |
NZ, L3 |
00640 |
POP |
BC |
00650 |
POP |
HL |
00660 |
INC |
H |
00670 |
DJNZ |
L4 |
00680 |
RET |
|
Эффект будет наиболее полным, если добавить шипение.
Комментарий ИНФОРКОМА.
Предложенная программа основана на том, что окно заданных размеров заполняется произвольной информацией, в качестве которой используется содержимое ПЗУ. Посмотрите: в строках 60, 80, 100, 120 в регистре DE задается некий произвольный адрес (в ПЗУ), а в строках 560-570 (в HL при этом находится адрес в дисплейном файле) происходит перенесение информации из ячейки ПЗУ на экран. За тем следует переход к следующей ячейке и повторение цикла (строки 580-600). Всего используется 4 повторения подпрограммы SNOW с разными адресами, благодаря этому и создается эффект "снега". Кстати сказать, в цикл переноса ин формации из ПЗУ в видео - ОЗУ удобно вставить звуковое сопровождение. Мы (по совету автора) сделали такое усовершенствование: 00572 AND #10
00574 OR #00
00576 OUT (#FE),A
В строке 572 "выделяется" бит, соответствующий управлению динамикой (устраняются полосы на бордюре в такт шипению), в строке 574 задается цвет бордюра (для черного цвета эту строку можно исключить, но лучше -оставить для простоты внесения изменений в уже готовый блок; для белого бордюра здесь должно быть OR #07), в строке 576 полученное (случайное) значение аккумулятора выдается в порт звукового динамика, создавая шипение. Таким образом. Вы слышите, как "шипит" Ваше ПЗУ.
Параметры блока кодов со звуковым сопровождением: Start of object: #9C40 (40000) Length: #00 6A (00106)
Executes: #9C40 (40000)
И его дамп:
9C4 0 |
11 |
00 |
00 |
CD |
60 |
9C |
11 |
A0 |
67 |
9C4 8 |
0F |
CD |
60 |
9C |
11 |
58 |
1B |
CD |
0D |
9C50 |
60 |
9C |
11 |
28 |
23 |
CD |
60 |
9C |
0D |
9C58 |
3E |
7F |
DB |
FE |
IF |
38 |
E1 |
C9 |
8B |
9C60 |
21 |
04 |
09 |
7D |
E6 |
07 |
0F |
0F |
B2 |
9C68 |
0F |
84 |
65 |
6F |
7C |
E6 |
18 |
F6 |
DB |
9C7 0 |
40 |
67 |
06 |
08 |
E5 |
C5 |
0E |
0A |
83 |
9C7 8 |
06 |
0E |
D5 |
DD |
E1 |
E5 |
11 |
20 |
D1 |
9C80 |
00 |
19 |
EB |
E1 |
7A |
BC |
28 |
08 |
67 |
9C88 |
E5 |
EB |
11 |
00 |
07 |
19 |
EB |
E1 |
F1 |
9C90 |
D5 |
DD |
E5 |
D1 |
1A |
77 |
E6 |
10 |
1B |
9C98 |
F 6 |
00 |
D3 |
FE |
23 |
13 |
10 |
F4 |
35 |
9CA0 |
E1 |
0D |
20 |
D4 |
C1 |
E1 |
24 |
10 |
F4 |
9CA8 |
CB |
C9 |
00 |
00 |
00 |
00 |
00 |
00 |
D8 |
Тестируя программу, мы отмети ли, что четырех повторений цикла SNOW может быть и достаточно для простейшей имитации "снега", но для более реалистичной - явно не достаточно - слишком заметен полный цикл из 4-х повторений. В идеале было бы желательно организовать один замкнутый цикл с использованием в качестве генератора адреса для регистра DE - генератор случайных чисел. Если Вы уже прочитали предыдущую статью, то, конечно, подумали о том же самом, что и мы: интересно было бы узнать, как поведет себя предложенный генератор RND в процедуре "телевизора". Для этого необходимо внести следующие изменения:
00060 START |
CALL |
RND |
00070 |
LD |
DE,(SEED) |
00080 |
LD |
A, D |
00096 |
AND |
#3F |
00100 |
LD |
D,A |
Строки 110-120 - удалите, а следом за процедурой SNOW расположите генератор случайных чисел из предыдущей статьи - подпрограмму RND. Результат её работы, находящийся в ячейке SEED, и будем использовать в качестве адреса, задаваемого в DE. Это будет число от 0 до 65535. В этом случае, естественно, результат работы такого "телевизора" будет за висеть от содержимого памяти ПЗУ+ОЗУ Вашего компьютера, поэтому введено ограничение на старший байт адреса: строка 90 не дает выходить за пределы ПЗУ.
Когда мы запустили программу, то были просто "сражены наповал" реалистичностью эффекта: на экране нашего "Спектрума" светился (и шипел) настоящий маленький теле экран, время, от времени пытаясь настроиться на какую-то слабую станцию, но у него это никак не получалось. Такому поведению "телевизора" быстро нашлось объяснение: в ПЗУ 1982 года имеется свободная область, заполненная кодом #FF, и когда генератор случайных чисел попадал в этот диапазон, создавался эффект попыток "захвата" АПЧ слабого сигнала передаю щей станции. Эффект "захвата сигнала" почти пропадает при использовании ПЗУ "TURBO-90" (в котором нет свободного участка, но, за счет инкремента регистра DE в строке 590, в процесс вовлекается часть видео - ОЗУ) и совсем исчезнет, если изменить строку:
00090 AND #1F
отрезав вероятность попадании о свободную область ПЗУ. Теперь видим полное отсутствие, какого бы то ни было
сигнала на входе нашего "телевизора", но, все равно, очень реалистичный "снег" на мини-экране. Правда программа
стала длиннее почти вдвое:
Start of object: #9C40 (40000)
Length: #OOB5 (00181)
Executes: #9C40 (40000)
Однако если процедура RND будет также использоваться в Вашей программе и для других целей, то её применение заодно и в "телевизоре", наоборот, сэкономит память. А полученный эффект, безусловно, покорит тех, кто будет пользоваться Вашими программами.
В заключение, приводим полный дамп блока кодов имитатора телевизора вместе с генератором RND.
9C4 0 |
CD |
A0 |
9C |
ED |
5B |
F3 |
9C |
7A |
36 |
9C4 8 |
E 6 |
3F |
57 |
CD |
56 |
9C |
3E |
7F |
DC |
9C50 |
DB |
FE |
1F |
38 |
EB |
C9 |
21 |
04 |
F5 |
9C58 |
09 |
7D |
E6 |
07 |
0F |
0F |
0F |
84 |
18 |
9C60 |
65 |
6F |
7C |
E6 |
18 |
F6 |
40 |
67 |
E7 |
9C68 |
06 |
08 |
E5 |
C5 |
0E |
0A |
06 |
0E |
E8 |
9C7 0 |
D5 |
DD |
E1 |
E5 |
11 |
20 |
00 |
19 |
CE |
9C7 8 |
EB |
E1 |
7A |
BC |
28 |
08 |
E5 |
EB |
16 |
9C80 |
11 |
00 |
07 |
19 |
EB |
E1 |
D5 |
DD |
CB |
9C88 |
E5 |
D1 |
1A |
77 |
23 |
13 |
E6 |
10 |
97 |
9C90 |
F 6 |
00 |
D3 |
FE |
10 |
F4 |
E1 |
0D |
E5 |
9C98 |
20 |
D4 |
C1 |
E1 |
24 |
10 |
CB |
C9 |
92 |
9CA0 |
2A |
F3 |
9C |
23 |
16 |
00 |
7C |
B5 |
5F |
9CA8 |
20 |
01 |
14 |
D5 |
E5 |
CB |
25 |
CB |
EE |
9CB0 |
14 |
CB |
12 |
D5 |
E5 |
CB |
25 |
CB |
B2 |
9CB8 |
14 |
CB |
12 |
CB |
25 |
CB |
14 |
CB |
DF |
9CC0 |
12 |
D5 |
E5 |
CB |
25 |
CB |
14 |
CB |
C2 |
9CC8 |
12 |
CB |
25 |
CB |
14 |
CB |
12 |
CB |
ED |
9CD0 |
25 |
CB |
14 |
CB |
12 |
C1 |
F1 |
09 |
08 |
9CD8 |
8A |
57 |
C1 |
F1 |
09 |
8A |
57 |
C1 |
B2 |
9CE0 |
F1 |
09 |
8A |
4F |
06 |
00 |
B7 |
ED |
F9 |
9CE8 |
42 |
ED |
4A |
B7 |
ED |
42 |
2B |
22 |
30 |
9CF0 |
F3 |
9C |
C9 |
00 |
00 |
00 |
00 |
00 |
E4 |