(c) Иван Рощин, Москва, 1996.
Предлагаю вашему вниманию
две процедуры в машинных кодах,
реализующие красивые и необычные
эффекты (по крайней мере, мне
таких видеть не приходилось).
Перед запуском первой проце-
дуры на экране должна быть ка-
кая-нибудь картинка. Вы увидите,
как эта картинка постепенно из-
меняется. Для выхода достаточно
нажать любую клавишу.
Этот эффект вы можете приме-
нить в своей программе, напри-
мер, так: если пользователь про-
должительное время не нажимает
на клавиши, сохраняем содержи-
мое экранной области и запус-
каем процедуру. Как только ка-
кая-нибудь клавиша будет нажата,
восстанавливаем картинку на эк-
ране (кстати, в этом может по-
мочь вторая процедура).
Эту процедуру нетрудно изме-
нить. Попробуйте в указанных
местах поставить команды CALL
SET_0 или CALL SET_1 и посмотри-
те что получится.
Привожу текст процедуры на
ассемблере:
148.
EFFECT LD HL,0 ;АДРЕС В ROM
LD (ADR_ROM),HL
;ПОЛУЧАЕМ В DE СЛУЧАЙНЫЕ КООРДИНАТЫ
;ОЧЕРЕДНОЙ ТОЧКИ И СОХРАНЯЕМ В ПАМЯТИ:
NEXT_X LD HL,(ADR_ROM)
LD B,(HL) ;КООРДИНАТА X
INC HL
LD A,R
XOR B
LD R,A
LD D,A
NEXT_Y LD B,(HL) ;КООРДИНАТА Y
INC HL
LD A,R
XOR B
CP 191
JR NC,NEXT_Y
LD E,A
LD (KRDS),DE
LD (ADR_ROM),HL
LD A,(HL)
PUSH AF
CALL GET_P ;УЗНАЛИ ЦВЕТ ЭТОЙ ТОЧКИ (0..1)
LD (COL),A
;ВЫБИРАЕМ НАПРАВЛЕНИЕ, В КОТОРОМ
;НАХОДИТСЯ ВТОРАЯ ТОЧКА, И УЗНАЕМ ЕЕ
;КООРДИНАТЫ:
POP AF
AND 3 ;ЧИСЛО 0..3 -НОМЕР НАПРАВЛЕНИЯ
LD HL,TABLE
LD B,0
LD C,A
ADD HL,BC
LD A,(HL) ;НА СКОЛЬКО ИЗМЕНЯТЬ Y
PUSH AF
LD BC,4
ADD HL,BC
LD A,(HL) ;НА СКОЛЬКО X
ADD A,D
LD D,A
POP AF ;НА СКОЛЬКО Y
ADD A,E
LD E,A
CP 192
JR NZ,NE_192
LD E,190
NE_192 CP #FF
JR NZ,X_OK
LD E,1
X_OK CALL GET_P ;УЗНАЛИ ЦВЕТ ВТОРОЙ ТОЧКИ
LD IX,COL ;СРАВНИВАЕМ ЕГО С ЦВЕТОМ ПЕРВОЙ ТОЧКИ
CP (IX) ;ЕСЛИ ОНИ ОДИНАКОВЫ,
JR Z,H_OK ;МЕНЯТЬ ТОЧКИ МЕСТАМИ НЕ НАДО.
PUSH DE ;СОХР. КООРД. ВТОРОЙ ТОЧКИ
LD DE,(KRDS) ;РИСУЕМ ЭТИМ ЦВЕТОМ ПЕРВУЮ ТОЧКУ
CP 0 ;ЭТИ 5 КОМАНД МОЖНО ЗАМЕНИТЬ НА
PUSH AF ;КОМАНДУ CALL SET_0 ИЛИ
CALL Z,SET_0 ;CALL SET_1, ПРИ ЭТОМ НАБЛЮДАЕМЫЙ
POP AF ;ЭФФЕКТ ИЗМЕНИТСЯ.
CALL NZ,SET_1
POP DE ;ВОССТ. КООРДИНАТЫ ВТОРОЙ ТОЧКИ
LD A,(COL) ;ЭТИ 6 КОМАНД МОЖНО ЗАМЕНИТЬ НА
CP 0 ;КОМАНДУ CALL SET_0 ИЛИ
PUSH AF ;CALL SET_1, ПРИ ЭТОМ НАБЛЮДАЕМЫЙ
CALL Z,SET_0 ;ЭФФЕКТ ИЗМЕНИТСЯ.
POP AF
CALL NZ,SET_1
LD A,(ADR_ROM+1) ;ПРОВЕРЯЕМ, НЕ ДОСТИГНУТ ЛИ
AND #1F ;ПРЕДЕЛЬНЫЙ ДОПУСТИМЫЙ АДРЕС
LD (ADR_ROM+1),A ;В ROM СПЕКТРУМА.
H_OK LD A,0 ;ПРОВЕРЯЕМ, НЕ НАЖАТО ЛИ
IN A,(#FE) ;ЧТО-НИБУДЬ НА КЛАВИАТУРЕ.
AND %00011111
CP %00011111
JP Z,NEXT_X
RET ;ЕСЛИ ДА, ВЫХОДИМ.
SET_1 CALL BYTE
LD B,(HL)
OR B
LD (HL),A
RET
SET_0 CALL BYTE
LD B,#FF
XOR B
LD B,(HL)
AND B
LD (HL),A
RET
GET_P CALL BYTE
LD B,(HL)
AND B
CP 0
RET Z
LD A,1
RET
BYTE PUSH DE
LD A,E
AND A
RRA
SCF
RRA
AND A
RRA
XOR E
AND #F8
XOR E
LD H,A
LD A,D
RLCA
RLCA
RLCA
XOR E
AND #C7
XOR E
RLCA
RLCA
LD L,A
LD A,D
AND 7
LD B,A
INC B
LD A,1
LOOP RRCA
DJNZ LOOP
POP DE
RET
KRDS DW 0 ;КООРДИНАТЫ ТОЧКИ
COL DB 0 ;ЦВЕТ ТОЧКИ
TABLE DB 0,#FF,0,1
DB 1,0,#FF,0
ADR_ROM DW 0
2
Вторая процедура предназначе-
на для вывода картинки на экран.
Перед ее запуском в регистровой
паре HL нужно указать адрес кар-
тинки.
Привожу текст процедуры на
ассемблере:
148.
DEMO LD HL,#C000 ;АДРЕС ВЫВОДИМОЙ КАРТИНКИ
CALL EFFECT
RET
;ПРОЦЕДУРА EFFECT ОСУЩЕСТВЛЯЕТ ВЫВОД
;КАРТИНКИ НА ЭКРАН.
;ВХОД: HL -АДРЕС ВЫВОДИМОЙ КАРТИНКИ.
;ПРИ ВЫЗОВЕ ПРЕРЫВАНИЯ ДОЛЖНЫ БЫТЬ
;РАЗРЕШЕНЫ !
Q EQU 7 ;Q МОЖНО МЕНЯТЬ В
Q_2 EQU Q*Q ;ПРЕДЕЛАХ [1..8], ОТ ЕГО
;ЗНАЧЕНИЯ ЗАВИСИТ ЭФФЕКТ.
EFFECT LD DE,#C000 ;НАСТРОЙКА АДРЕСА
ADD HL,DE ;ВНУТРИ ПРОЦЕДУРЫ
LD (ADR1+1),HL
LD D,#58 ;ПЕРЕНОСИМ ФАЙЛ
ADD HL,DE ;АТРИБУТОВ.
LD BC,#300
LDIR ;ПОСЛЕ ЭТОГО E=0.
LD D,-Q_2 ;D -НОМЕР ТЕКУЩЕЙ СТРОКИ.
;В РЕГИСТРЕ E -СКОЛЬКО СТРОК ОБРАБОТАНО (ПОКА 0).
LOOP1 HALT ;ЗАДЕРЖКА
LD BC,Q+1*256+Q_2 ;B- СЧЕТЧИК, C-СМЕЩЕНИЕ
LOOP2 LD A,D ;НОМЕР ТЕКУЩЕЙ СТРОКИ
ADD A,C ;ПРИБАВЛЯЕМ СМЕЩЕНИЕ
CP 192 ;ЕСЛИ НОМЕР СТРОКИ БОЛЬШЕ 192,
JR NC,NEXT ;ПРОПУСКАЕМ ЕЕ.
EXX
CALL ADR_STR ;ИНАЧЕ УЗНАЕМ АДРЕС СТРОКИ
ADR1 LD BC,0
ADD HL,BC ;В HL -АДРЕС В БУФЕРЕ
LD BC,#20 ;ДЛИНА ОДНОЙ СТРОКИ
LDIR ;ВЫВЕЛИ НА ЭКРАН.
EXX ;УВЕЛИЧИВАЕМ КОЛИЧЕСТВО
INC E ;ОБРАБОТАННЫХ СТРОК
NEXT LD A,C ;УМЕНЬШИЛИ СМЕЩЕНИЕ
SUB Q
LD C,A
DJNZ LOOP2 ;ПОВТОРЯЕМ ЦИКЛ.
INC D ;УВЕЛИЧИЛИ НОМЕР ТЕК.СТРОКИ
;ЕСЛИ ОН ДЕЛИТСЯ НА (Q+1), УВЕЛИЧИВАЕМ ЕГО НА Q
LD B,0 ;СЧЕТЧИК (256 ПОВТОРЕНИЙ)
LD A,D ;ПРОВЕРЯЕМОЕ ЧИСЛО
LOOP3 SUB Q+1 ;ВЫЧИТАЕМ ДЕЛИТЕЛЬ
JR Z,DEL ;ЕСЛИ ПОЛУЧИЛОСЬ 0,Т.Е. ДЕЛИТСЯ НАЦЕЛО
DJNZ LOOP3 ;ПРОДОЛЖАЕМ...
JR M12 ;ЕСЛИ ЧИСЛО НЕ ДЕЛИТСЯ НАЦЕЛО
DEL LD A,D ;УВЕЛИЧИВАЕМ НОМЕР
ADD A,Q ;ТЕКУЩЕЙ СТРОКИ
LD D,A ;НА Q.
M12 LD A,E ;СКОЛЬКО СТРОК ВЫВЕЛИ ?
CP 192 ;УЖЕ 192 СТРОКИ ?
JR NZ,LOOP1 ;ЕСЛИ НЕТ, ПРОДОЛЖАЕМ ВЫВОД.
RET
;
;ПРОЦЕДУРА ADR_STR
;ВХОД: A- НОМЕР СТРОКИ (0..191)
;ВЫХОД: HL,DE- АДРЕС В ДИСПЛЕЙНОМ ФАЙЛЕ.
ADR_STR LD E,A
AND A
RRA
SCF
RRA
AND A
RRA
XOR E
AND #F8
XOR E
LD H,A
XOR A
XOR E
AND #C7
XOR E
RLCA
RLCA
LD L,A
LD E,A
LD D,H
RET
2
********************************