|
Системные программы - Удобный стрелочный интерфейс.
|
© РиккерВ.В. 1993 г., п.Провидения, Магаданской области.
Как известно, любой программе нужно удобное управление. Особенно удобно, если выбор
режимов и команд производится джойстиком. Ниже приведена процедура, которая перемещает по
экрану стрелочку и принажатии кнопки "огонь" имеет на выходе в регистровой паре HL адрес в
дисплейном файле, соответствующий кончику стрелки ив регистровой паре ВС соответствующий
адрес в области атрибутов. Эти адреса можно лихо использовать для определения дальнейших
действий. Например, имея адрес атрибутов, можно проверить, скажем, бит 6 - яркость, попали ли Вы на команду или стрелка болтается, где ни попадя. Буду очень рад, если приведенная программка кому-нибудь пригодится.
00010 |
|
|
|
|
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-го рода для создания резидентных процедур всегда представляет особенную трудность для тех, кто делает только первые шаги в машинном коде. Мастерское же владение этим инструментом открывает перед программистом огромные возможности для создания собственных программ. Мы довольно редко получаем письма от наших читателей, в которых есть примеры подобных процедур, да и те далеко не всегда выдерживают наше тестирование. Поэтому мы особенно рады предложить нашим читателям работу, выполненную сотрудником Крымской Астрофизической Обсерватории. Программа прошла тестирование без проблем.
|
|