© РиккерВ.В. 1993 г., п.Провидения, Магаданской области.
Как известно, любой программе нужно удобное управление. Особенно удобно, если выбор режимов и команд производится джойстиком. Ниже приведена процедура, которая перемещает по экрану стрелочку и принажатии кнопки "огонь" имеет на выходе в регистровой паре HL адрес в дисплейном файле, соответствующий кончику стрелки ив регистровой паре ВС соответствующий адрес в области атрибутов. Эти адреса можно лихо использовать для определения дальнейших действий. Например, имея адрес атрибутов, можно проверить, скажем, бит 6 - яркость, попали ли Вы на команду или стрелка болтается, где ни попадя. Буду очень рад, если приведенная программка кому-нибудь пригодится.
|
00020 |
; Написана в |
августе 1993г | ||
|
00030 |
; Провидения | |||
|
00040 |
; автор |
Риккер В.В. | ||
|
00050 |
; | |||
|
00060 |
ORG |
40000 |
;нужный адрес ассемблирования | |
|
00070 |
ENT | |||
|
00080 |
EI | |||
|
00090 |
JP |
START | ||
|
п П 1 п п 00100 | ||||
|
00110 | ||||
|
00120 | ||||
|
00130 |
; * Переменные программах * | |||
|
00140 | ||||
|
00150 |
; | |||
|
00160 |
BUFFS |
DEFS |
30 |
;Буфер для сохранения того, |
|
;что под стрелкой на экране. | ||||
|
00170 |
STS |
DEFW |
0 |
;Адрес в видеообласти, соответствующий |
|
;острию стрелки. | ||||
|
00180 |
CRDS |
DEFW |
0 |
;Координаты острия стрелки. |
|
00190 |
; | |||
|
00200 |
; |
Шаблоны стрелки | ||
|
00210 |
; | |||
|
00220 |
ORSH |
DEFB |
#C0,#E0,#F0 |
;Шаблон для операции OR |
|
00230 |
DEFB |
#F8,#FC, #FE | ||
|
00240 |
DEFB |
#FF,#FE, #FC | ||
|
00250 |
DEFB |
#1C,#0E,#0E | ||
|
00260 |
DEFB |
#07,#07,#03 | ||
|
00270 |
XORSH |
DEFB |
#C0,#A0,#90 |
;Шаблон для операции XOR |
|
00280 |
DEFB |
#88,#84,#82 | ||
|
00290 |
DEFB |
#81,#86,#B4 | ||
|
00300 |
DEFB |
#14,#0A, #0A | ||
|
00310 |
DEFB |
#05,#05,#03 | ||
|
00320 |
; | |||
|
00330 |
STEP |
EQU |
2 |
;Скорость перемещения стрелки |
|
;(с увеличением скорости | ||||
|
;уменьшается точность) | ||||
|
nm/i п 00340 | ||||
|
00350 | ||||
|
00360 |
. * |
Подпрограммы * | ||
|
00370 | ||||
|
00380 |
; | |||
|
00390 |
SCRBF |
LD |
HL,(CRDS) |
;Координаты острия стрелки. |
|
00400 |
LD |
C,H |
;Подготавливаем регистры для вы | |
|
00410 |
LD |
B, L |
числения адреса по координатам. | |
|
00420 |
LD |
A, B | ||
|
00430 |
CALL |
#22B1 |
;Вычисляем адрес (процедура ПЗУ). | |
|
00440 |
LD |
(STS),HL |
;Сохраняем полученный адрес. | |
|
00450 |
LD |
DE, BUFFS |
;В DE адрес буфера. | |
|
00460 |
RB0 |
LD |
B,15 |
;Высота стрелки в пикселах. |
|
00470 |
RB1 |
PUSH |
HL | |
|
00480 |
LD |
C, 2 |
;Сколько смежных байт сохранять. | |
|
00490 |
RB2 |
LD |
A,(HL) | |
|
00500 |
LD |
(DE) ,A | ||
|
00510 |
INC |
L | ||
|
00520 |
INC |
DE | ||
|
00530 |
DEC |
C | ||
|
00540 |
JR |
NZ,RB2 | ||
|
00550 |
POP |
HL | ||
|
00560 |
CALL |
DAD1 |
;Получаем адрес в дисплейном ;файле на 1 пиксел ниже. | |
|
00570 |
DJNZ |
RB1 | ||
|
00580 |
RET | |||
|
00590 |
в | |||
|
; | ||||
|
00600 |
DAD1 |
INC |
H | |
|
00610 |
LD |
A, H | ||
|
00620 |
AND |
7 | ||
|
00630 |
RET |
NZ | ||
|
00640 |
LD |
A, H | ||
|
00650 |
SUB |
8 | ||
|
00660 |
LD |
H, A | ||
|
00670 |
LD |
A, L | ||
|
00680 |
ADD |
A,32 | ||
|
00690 |
LD |
L,A | ||
|
00700 |
RET |
NC | ||
|
00710 |
LD |
A, H | ||
|
00720 |
ADD |
A, 8 | ||
|
00730 |
LD |
H, A | ||
|
00740 |
RET | |||
|
00750 |
в | |||
|
; | ||||
|
00760 |
BFSCR |
LD |
HL,#771A |
;Подпрогр. восстановления экрана. |
|
00770 |
LD |
(RB2),HL |
;Сначала перепрограммируется ;процедура SCRBF. | |
|
00780 |
CALL |
SCRBF | ||
|
00790 |
LD |
HL,#127E |
;Восстанавл. код процедуры SCRBF. | |
|
00800 |
LD |
(RB2),HL | ||
|
00810 |
RET | |||
|
00820 | ||||
|
00830 |
; Подпрограмма |
создания образа стрелки | ||
|
00840 |
; по имеющимся |
координатам | ||
|
00850 |
FORM |
LD |
A,(CRDS+1) |
;По горизонт. координате получаем |
|
00860 |
AND |
7 |
;номер бита в байте экрана. | |
|
00870 |
EX |
AF, AF' |
;Сохраняем его. | |
|
00880 |
LD |
IX,ORSH |
;Накладываем маску по OR. | |
|
00890 |
CALL |
FORMS | ||
|
00900 |
LD |
IX, MS3 | ||
|
00910 |
LD |
(IX+0),#AA |
;Изменяем процедуру FORMS. | |
|
00920 |
LD |
(IX+9) ,#AB | ||
|
00930 |
PUSH |
IX | ||
|
00940 |
LD |
IX,XORSH |
/Накладываем маску по XOR. | |
|
00950 |
CALL |
FORMS | ||
|
00960 |
POP |
IX | ||
|
00970 |
LD |
(IX+0),#B2 |
;Восстанавл. код процедуры FORMS. | |
|
00980 |
LD |
(IX+9) ,#B3 | ||
|
00990 |
RET | |||
|
01000 |
FORMS |
LD |
C,15 |
;Число линий в стрелке. |
|
01010 |
LD |
HL,(STS) |
;Берем адрес в экране. | |
|
01020 |
MS1 |
LD |
D,B |
;Обнуляем DE. |
|
01030 |
LD |
E,B | ||
|
01040 |
EX |
AF, AF' | ||
|
01050 |
LD |
B, A |
;В рег.В номер бита в адр.экрана. | |
|
01060 |
EX |
AF, AF' | ||
|
01070 |
DEC |
B |
;Проверяем его на ноль. | |
|
01080 |
INC |
B | ||
|
01090 |
LD |
D,(IX+0) |
;В DE байт из шаблона стрелки. | |
|
01100 |
JR |
Z, MS21 |
;Если 0, то обходим ротацию DE. | |
|
01110 |
MS2 |
SRL |
D |
;Сдвигаем шаблон. |
|
01120 |
RR |
E | ||
|
01130 |
DJNZ |
MS2 | ||
|
01140 |
MS21 |
LD |
A,(HL) |
;Накладываем полученную маску. |
|
01150 |
MS3 |
OR |
D |
;Команды OR D и OR E заменяются |
|
;на XOR D и XOR E и обратно. | ||||
|
01160 |
LD |
(HL),A | ||
|
01170 |
INC |
L |
;Переходим к следующему байту. | |
|
01180 |
LD |
A, L | ||
|
01190 |
AND |
#1F |
;Если вышли за правую границу | |
|
01200 |
JR |
Z, MS4 |
;экрана, то обход. | |
|
01210 |
LD |
A, (HL) |
;Иначе накладываем маску и на | |
|
;соседний байт. | ||||
|
01220 |
OR |
E | ||
|
01230 |
LD |
(HL),A | ||
|
01240 |
MS4 |
DEC |
L |
;Переходим на нижнюю линию |
|
01250 |
INC |
IX |
;и на следующий байт в шаблоне. | |
|
01260 |
CALL |
DAD1 | ||
|
01270 |
LD |
A, H |
;Проверяем, вышли ли | |
|
01280 |
CP |
#58 |
;за низ экрана. | |
|
01290 |
RET |
NC |
;ДА - выход. | |
|
01300 |
DEC |
C |
;НЕТ - уменьшаем счетчик строк | |
|
01310 |
JR |
NZ,MS1 |
;в стрелке и повторяем фокус. | |
|
01320 |
RET | |||
|
П 1 Я. "3 п | ||||
|
013 3 0 | ||||
|
01340 | ||||
|
01350 |
* Головная программа * | |||
|
01360 | ||||
|
01370 | ||||
|
01380 |
START |
LD |
HL,#64 64 |
;Начальные координаты стрелки. |
|
01390 |
LD |
(CRDS),HL | ||
|
01400 |
PUSH |
IX | ||
|
01410 |
Q0 |
CALL |
SCRBF |
; Сохраняем... |
|
01420 |
CALL |
FORM |
; Формируем... | |
|
01430 |
HALT |
; Отдыхаем... | ||
|
01440 |
IN |
A,(31) |
; Опрашиваем... | |
|
01450 |
PUSH |
AF | ||
|
01460 |
CALL |
BFSCR |
; Восстанавливаем^„ | |
|
01470 |
POP |
AF | ||
|
01480 |
LD |
C,A | ||
|
01490 |
LD |
E,STEP | ||
|
01500 |
LD |
D,254 |
;Задали максимум по Х. | |
|
01510 |
LD |
HL,CRDS+1 |
;Изменяем координаты согласно | |
|
01520 |
BIT |
0,C |
;тому, что нажали | |
|
01530 |
CALL |
NZ, PL |
;на джойстике. | |
|
01540 |
BIT |
1,C | ||
|
01550 |
CALL |
NZ,MIN | ||
|
01560 |
LD |
D, 190 |
;Максимум по Y. | |
|
01570 |
DEC |
HL |
;Перешли на координату Y. | |
|
01580 |
BIT |
2,C | ||
|
01590 |
CALL |
NZ, PL | ||
|
01600 |
BIT |
3,C | ||
|
01610 |
CALL |
NZ,MIN | ||
|
01620 |
BIT |
4,C | ||
|
01630 |
JR |
NZ,EXIT | ||
|
01640 |
JR |
Q0 | ||
|
01650 |
в | |||
|
; | ||||
|
01660 |
PL |
LD |
A,(HL) | |
|
01670 |
LD |
B, E | ||
|
01680 |
L0 |
CP |
D | |
|
01690 |
JR |
Z, END | ||
|
01700 |
INC |
A | ||
|
01710 |
DJNZ |
L0 | ||
|
01720 |
END |
LD |
(HL),A | |
|
01730 |
RET | |||
|
01740 |
в | |||
|
; | ||||
|
01750 |
MIN |
LD |
A,(HL) | |
|
01760 |
LD |
B, E | ||
|
01770 |
INP |
AND |
A | |
|
01780 |
JR |
Z, END | ||
|
01790 |
DEC |
A | ||
|
01800 |
DJNZ |
INP | ||
|
01810 |
LD |
(HL),A | ||
|
01820 |
RET | |||
|
01830 |
в | |||
|
; | ||||
|
01840 |
EXIT |
LD |
HL,(STS) | |
|
01850 |
PUSH |
HL | ||
|
01860 |
LD |
A, H | ||
|
01870 |
AND |
#18 | ||
|
01880 |
RRCA | |||
|
01890 |
RRCA | |||
|
01900 |
RRCA | |||
|
01910 |
OR |
#58 | ||
|
01920 |
LD |
B, A | ||
|
01930 |
LD |
C, L | ||
|
01940 |
POP |
HL | ||
|
01950 |
POP |
IX | ||
|
01960 |
RET |
01970 01980
; Конец программы
В строках 220-310 программы задается рисунок стрелки. Две маски (по OR и по XOR)
нужны для того, чтобы при попадании стрелки на область, закрашенную INK, стрелка не сливалась бы с фоном, а приобретала оконтуривание цветом PAPER. Образ стрелки и значения байтов двух масок приведены на рисунке
Набор программы был выполнен нами при помощи ассемблера ZEUS. Для тех, кто хочет без лишних хлопот с ассемблером получить готовую программу, приводим шестнадцатеричный дамп (с контрольными суммами) кодового блока с адреса 40000. Его длина 328 байтов.
Теперь несколько слов тем, кто захочет усовершенствовать программу. Приведенный вариант программы работает только от KEMPS TON-джойстика (см. строку 1440). Это может оказаться не для всех удобно. Поэтому со своей стороны мы можем порекомендовать ввести дополнительные строки для опроса клавишей, например, SINCLAIR-джойстика, сохранив и KEMPSTON.
|
9C40 |
FB |
C3 |
27 |
9D |
00 |
00 |
00 |
00 |
5E |
|
9C48 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
E4 |
|
9C50 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
EC |
|
9C58 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
F4 |
|
9C60 |
00 |
00 |
00 |
00 |
00 |
00 |
C0 |
E0 |
9C |
|
9C68 |
F0 |
F8 |
FC |
FE |
FF |
FE |
FC |
1C |
FB |
|
9C70 |
0E |
0E |
07 |
07 |
03 |
C0 |
A0 |
90 |
29 |
|
9C78 |
88 |
84 |
82 |
81 |
86 |
B4 |
14 |
0A |
7B |
|
9C80 |
0A |
05 |
05 |
03 |
2A |
64 |
9C |
4C |
A9 |
|
9C88 |
45 |
78 |
CD |
B1 |
22 |
22 |
62 |
9C |
A1 |
|
9C90 |
11 |
44 |
9C |
06 |
0F |
E5 |
0E |
02 |
27 |
|
9C98 |
7E |
12 |
2C |
13 |
0D |
20 |
F9 |
E1 |
0A |
|
9CA0 |
CD |
A6 |
9C |
10 |
F0 |
C9 |
24 |
7C |
B4 |
|
9CA8 |
E6 |
07 |
C0 |
7C |
D6 |
08 |
67 |
7D |
2F |
|
9CB0 |
C6 |
20 |
6F |
D0 |
7C |
C6 |
08 |
67 |
22 |
|
9CB8 |
C9 |
21 |
1A |
77 |
22 |
98 |
9C |
CD |
F2 |
|
9CC0 |
84 |
9C |
21 |
7E |
12 |
22 |
98 |
9C |
83 |
|
9CC8 |
C9 |
3A |
65 |
9C |
E6 |
07 |
08 |
DD |
3A |
|
9CD0 |
21 |
66 |
9C |
CD |
F6 |
9C |
DD |
21 |
EC |
|
9CD8 |
0E |
9D |
DD |
36 |
00 |
AA |
DD |
36 |
EF |
|
9CE0 |
09 |
AB |
DD |
E5 |
DD |
21 |
75 |
9C |
01 |
|
9CE8 |
CD |
F6 |
9C |
DD |
E1 |
DD |
36 |
00 |
B4 |
|
9CF0 |
B2 |
DD |
36 |
09 |
B3 |
C9 |
0E |
0F |
F3 |
|
9CF8 |
2A |
62 |
9C |
50 |
58 |
08 |
47 |
08 |
BB |
|
9D00 |
05 |
04 |
DD |
56 |
00 |
28 |
06 |
CB |
D2 |
|
9D08 |
3A |
CB |
1B |
10 |
FA |
7E |
B2 |
77 |
76 |
|
9D10 |
2C |
7D |
E6 |
1F |
28 |
03 |
7E |
B3 |
B7 |
|
9D18 |
77 |
2D |
DD |
23 |
CD |
A6 |
9C |
7C |
E4 |
|
9D20 |
FE |
58 |
D0 |
0D |
20 |
D5 |
C9 |
21 |
CF |
|
9D28 |
64 |
64 |
22 |
64 |
9C |
DD |
E5 |
CD |
3E |
|
9D30 |
84 |
9C |
CD |
C9 |
9C |
76 |
DB |
1F |
8F |
|
9D38 |
F5 |
CD |
B9 |
9C |
F1 |
4F |
1E |
02 |
4C |
|
9D40 |
16 |
FE |
21 |
65 |
9C |
CB |
41 |
C4 |
E3 |
|
9D48 |
62 |
9D |
CB |
49 |
C4 |
6C |
9D |
16 |
DB |
|
9D50 |
BE |
2B |
CB |
51 |
C4 |
62 |
9D |
CB |
80 |
|
9D58 |
59 |
C4 |
6C |
9D |
CB |
61 |
20 |
16 |
7D |
|
9D60 |
18 |
CD |
7E |
43 |
BA |
28 |
03 |
3C |
C4 |
|
9D68 |
10 |
FA |
77 |
C9 |
7E |
43 |
A7 |
28 |
DF |
|
9D70 |
F9 |
3D |
10 |
FA |
77 |
C9 |
2A |
62 |
19 |
|
9D78 |
9C |
E5 |
7C |
E6 |
18 |
0F |
0F |
0F |
3D |
|
9D80 |
F6 |
58 |
47 |
4D |
E1 |
DD |
E1 |
C9 |
67 |
Другим, более изощренным моментом является изменяемая скорость перемещения стрелки
по экрану. Эти строки мы адресуем тем, кто захочет использовать предложенный интерфейс в серьёзной программе, претендующей на повышенное удобство для пользователя. Как Вы видите из приведенного листинга, скорость перемещения стрелки постоянна и зависит от значения, заданного в строке 330. Слишком быстрая скорость перемещения стрелки приведёт к необходимости более точно "прицеливаться" для попадания в нужное место и к более быстрой реакции Вашей руки, но, в то же время, не потребуется много времени для того, чтобы "перегнать" стрелку от одного края экрана к другому. При медленном перемещении всё наоборот. Великолепная точность попадания и удобство "прицеливания" сочетаются с томительным ожиданием, когда же, наконец, заветная фигурка доползет до нужного поля меню, находящегося почему-то как раз в противоположном конце экрана.
Проблему можно решить следующим образом. Организуется цикл подсчёта количества прерываний, произошедших с момента нажатия любой клавиши перемещения джойстика до её отпускания. При этом начальная скорость перемещения стрелки - минимальна. Если, скажем, через 64 или 32 прерывания кнопка не отпущена, изменяется параметр, задающий скорость перемещения стрелки - её движение убыстряется. Как только кнопка отпущена - счётчик тут же обнуляется и восстанавливается начальное значение параметра, определяющего скорость. Можно ограничиться одной ступенью увеличения скорости, а можно продолжать отсчёт дальше. Если ещё через 32 цикла кнопка не отпущена - скорость увеличивается ещё больше (в одной из версий ART STUDIO, например, увеличение скорости четырехступенчатое - управление при этом очень удобно). Это, так называемое интеллектуальное управление. Конечно, все числовые параметры должны быть тщательно подобраны и сбалансированы для обеспечения максимального удобства управления.
Применение прерываний 2-го рода для создания резидентных процедур всегда представляет особенную трудность для тех, кто делает только первые шаги в машинном коде. Мастерское же владение этим инструментом открывает перед программистом огромные возможности для создания собственных программ. Мы довольно редко получаем письма от наших читателей, в которых есть примеры подобных процедур, да и те далеко не всегда выдерживают наше тестирование. Поэтому мы особенно рады предложить нашим читателям работу, выполненную сотрудником Крымской Астрофизической Обсерватории. Программа прошла тестирование без проблем.
Share your thoughts about this chapter
No comments yet.