(c) Федоров Денис,
г.Владивосток.
Предлагаю вашему вниманию
дельную, на мой взгляд, програм-
мку. Идея написать что-нибудь
этакое появилась после того, как
в одном из номеров вашего заме-
чательного журнала был опублико-
ван способ печати изображений с
точностью до пиксела без приме-
нения аналогов процедуы PLOT. Та
же идея присутствует и в моем
варианте, но все же немного из-
менена. Процедуры расчета экран-
ного адреса и HLDOWN - также
взяты из опубликованных вами ма-
териалов.
Если в памяти разместить нет-
ронутую копию экрана, то по мо-
тивам представленной мной прог-
раммы можно попробовать написать
процедуру восстановления изна-
чального изображения.
Название: Печать картинки
с маской с точностью до пиксела.
СПОСОБ ПЕЧАТИ - RR, AND, OR.
ФОРМАТ ШАБЛОНА - 1-маска, 2-байт
рисунка; 3-маска, 4-pисунок...
Вторая линия - 1,2; 3,4; ....
Третья, .... - ..............
Всего LY линий с длиной LX байт
каждая.
ВЫЧИСЛЕНИЕ ДЛИНЫ ШАБЛОНА - LX*
LY*2.
ПЕЧАТЬ ПРОИЗВОДИТСЯ НЕПОСРЕД-
СТВЕННО НА ЭКРАН.
WARNING! Если, к примеру, LY=16,
LX=2, то шаблон будет иметь раз-
меры 2*2 знакоместа. Это проис-
ходит потому, что единица изме-
рениния LX - один байт, а LY -
одна линия.
Чтобы печать производилась в
буфер, надо после ABC добавить
строки:
LD DE,STEP
ADD HL,DE
где STEP - модуль разницы
между началом реального экрана и
началом буфера, куда будет про-
изводиться печать.
Проверка на коллизию с грани-
цами экрана не реализована.
148.
Special for INFORCOM by SatSoft.
(F.D.)
text: ORG 40000 ; - ЛЮБОЕ ДРУГОЕ
;ДОПУСТИМОЕ
;ЗНАЧЕНИЕ
LD A,(LX) ;ПОДГОТОВКА
LD (LENX+1),A ;ПЕРЕМЕННЫХ
LD A,(LY) ;ДЛЯ РАБОТЫ
LD (LENY+1),A
LD IX,(START)
LD DE,(COORDS)
LD A,D ;ОПРЕДЕЛЕНИЕ ВЕЛИЧИНЫ
;СМЕЩЕНИЯ ИЗОБРАЖЕНИЯ
AND 7 ;ВНУТРИ БАЙТА
LD (SHIFT+1),A
LD A,#BF ;РАСЧЕТ ЭКРАННОГО
SUB E ;АДРЕСА С ТОЧНОСТЬЮ
LD C,A ;ДО ЛИНИИ
AND #38
RLCA
RLCA
SRL D
SRL D
SRL D
ADD A,D
LD L,A
LD A,C
RRCA
RRCA
RRCA
AND #18
XOR C
AND #F8
XOR C
ADD A,#40
ABC LD H,A
LEN-Y LD B,0 ;ЦИКЛ СТОЛБЦОВ
L3 PUSH BC
PUSH HL
LEN-X LD B,0 ;ЦИКЛ СТРОК
L2 PUSH BC
LD C,(IX+0);ПРИНЯТИЕ ТЕКУЩИХ
INC IX ;ДАННЫХ ПО ШАБЛОНУ
LD E,(IX+0)
INC IX
LD B,(IX+0)
INC IX
LD D,(IX+0)
INC IX
SHIFT LD A,0 ;ВЕЛИЧИНА СМЕЩЕНИЯ
OR A ;ПО ЛИНИИ
JR Z,CONT
L1 AND A
RR C
RR B
RR E
RR D
DEC A
JR NZ,L1
CONT LD A,(HL)
AND C
OR E
LD (HL),A
INC HL
LD A,(HL)
AND B
OR D
LD (HL),A
INC HL
POP BC
DJNZ L2
POP BC
POP HL
HLDOWN INC H ;ОПУСКАЕМ HL
LD A,H ;НА ЛИНИЮ ВНИЗ.
AND 7
JR NZ,EDOWN
LD A,L
ADD A,32
LD L,A
JR C,EDOWN
LD A,H
SUB 8
LD H,A
EDOWN DJNZ L3
RET
LY DEFB 0
LX DEFB 0
START DEFW 0000
COORDS DEFB 0 ;Y-COORD
DEFB 0 ;X-COORD
END
2
Мой вариант не предусматрива-
ет таких вещей, как нахождение
нужного шаблона по его номеру в
таблице или привязка исходных
данных к Бейсику по трем причи-
нам:
1.Все это вполне легко можно
осуществить, просмотрев статью
г-на В.Бодрова - "ГРАФИКА ВАШЕГО
КОМПЬЮТЕРА" (ZX РЕВЮ 95/4, стр.
15).
2.Самостоятельно поработав с
процедурой, изменяя ее на раз-
ные лады, читатель лучше поймет
структуру алгоритма и сможет, к
примеру, реализовать проверку на
коллизию шаблона с границами эк-
рана.
3. Я стараюсь делать как можно
более простые программы и дора-
батывать их по мере надобности.
Здесь же стоит рассмотреть
способ кодирования начального
изображения в формат, используе-
мый моей процедурой. Допустим, у
нас имеется готовое изображение,
кратное по размерам 8, причем
маска и сам растр находятся в
разных частях экрана. В этом
случае имеет место использова-
ние следующего приема:
148.
ORG 41000 ;ЛЮБОЕ ДРУГОЕ
;ЗНАЧЕНИЕ
MCOORD DEFW 0000
PCOORD DEFW 0000
YLEN DEFB 00
XLEN DEFB 00
MAIN LD A,(YLEN) ;УСТАНОВКА ДЛИНЫ
LD (YL+1),A ;РИСУНКА
LD A,(XLEN)
LD (XL+1),A
LD HL,(MCOORD) ;УСТАНОВКА
LD (CRD+1),HL ;ПАРАМЕТРОВ
LD HL,START ;ДЛЯ ВВОДА
LD (ADR+1),HL ;МАСКИ
CALL INPUT
LD HL,(PCOORD) ;УСТАНОВКА
LD (CRD+1),HL ;ПАРАМЕТРОВ
LD HL,START+1 ;ДЛЯ ВВОДА
LD (ADR+1),HL ;РАСТРА
CALL INPUT
RET
CRD LD DE,0000 ;РАСЧЕТ ДИСПЛЕЙ-
LD A,E ;НОГО АДРЕСА
AND #18 ;ПО КООРДИНАТАМ
ADD A,#40
LD H,A
LD A,E
AND 7
RRCA
RRCA
RRCA
ADD A,D
LD L,A
ADR LD DE,0000 ;УСТАНОВКА АДРЕСА
;РЕЗУЛЬТИРУЮЩЕГО
;БЛОКА
YL LD B,00 ;СЧЕТЧИК Y-ДЛИНЫ
YLOOP PUSH BC
PUSH HL
XL LD B,0 ;СЧЕТЧИК X-ДЛИНЫ
XLOOP LD A,(HL)
LD (DE),A
INC DE
INC DE
INC HL
DJNZ XLOOP
POP BC
POP HL
DOWN INC H ;ПОНИЖЕНИЕ HL
LD A,H ;НА ПИКСЕЛ ВНИЗ
AND 7
JR NZ,EDOWN
LD A,L
ADD A,32
LD L,A
JR C,EDOWN
LD A,H
SUB 8
LD H,A
EDOWN DJNZ YLOOP
RET
END
2
В этом случае START - начало
результирующего блока, PCOORD -
координаты растра, MCOORD - то
же, только для маски. Величины
M- и P- COORD, XLEN - задаются в
знакоместах , а YLEN - в пиксе-
лах.
В процессе творчества, как
говорится, рождаются новые идеи.
Вот и у меня возникла такая
идея. Я попытался разработать
собственный алгоритм расчета ад-
реса по координатам с точностью
до пиксела. Вот что у меня полу-
чилось:
148.
LD C,%11100000
LD A,D
AND 7
LD B,A ;СМЕЩЕНИЕ ВНУТРИ
SRL D ;ЛИНИИ
SRL D
SRL D
RR E
RR L
RR E
RR L
RR E
RR L
LD A,L
AND C
OR D
LD L,A ;L - СФОРМИРОВАН
LD A,E
AND C
CTRL OR %01000000
LD H,A ;H - СФОРМИРОВАН
END
2
Для своих целей алгоритм ис-
пользует регистры A, BC, HL, DE.
Условия стандатные:
На входе - в DE коодинаты
На выходе - HL - соответствующий
адрес.
Работая с тремя старшими битами
в строке с меткой CTRL, можно
получить адрес печати на другую
страницу памяти ZX-SPECTRUM для
печати в буфер.
А вот еще одна идея.
Если вам когда нибудь придет-
ся написать что-то вроде:
148.
XOR A
LD (VAR),A
LD B,255
CALL .......
...............
LOOP LD A,(VAR)
INC A
LD (VAR),A
DJNZ LOOP
То такой прием можно заменить
на:
LD B,255
LOOP LD A,B
XOR #FF
LD (VAR),A
CALL .......
...............
DJNZ LOOP
2
Где VAR - переменная, предназна-
ченная для CALL ...... .