ZX-Ревю 1992 №3-4 1991 г.

40 лучших процедур - дисплейные программы.


6.ДИСПЛЕЙНЫЕ ПРОГРАММЫ

6.1 Слияние картинок

Длина: 21

Количество переменных: 1 Контрольная сумма: 1709

Назначение: Эта программа объединяет картинку, хранящуюся в ОЗУ, с текущим экраном дисплея. Атрибуты не изменяются. Переменные: Имя - screen_store Длина - 2 Адрес - 23296

Комментарий: содержит адрес картинки в ОЗУ. Вызов программы:

RANDOMIZE USR адрес

Контроль ошибок: Нет

Комментарии: Для объединения картинок должна быть использована приведенная на листинге программа, однако интересные результаты могут быть также получены заменой OR (HL) на XOR (HL) или AND (HL).

ЧИСЛА ДЛЯ ВВОДА

33

0

64

237

91

0

1

0

24

26

182

119

35

19

11

120

177

32

246

201

ЛИСТИНГ МАШИННЫХ КОДОВ

МЕТКА АССЕМБЛЕР

LD HL,16384 LD DE,(23296) LD BC,6144 NEXT_B LD A,(DE) OR (HL) LD (HL),A INC HL INC DE DEC BC LD A,B OR C

JR NZ,NEXT_B RET

Как она работает.

В пару регистров HL загружается начальный адрес дисплейного файла, а в пару регистров DE - его длина. Регистровая пара BC используется в качестве счетчика.

В аккумулятор загружается байт с адресом в DE и выполняется логическое 'ИЛИ' ('OR') этого значения с байтом дисплейного файла. Результат затем помещается в область дисплея.

HL и DE перемещаются на следующую позицию, счетчик уменьшается. Если счетчик не равен 0, то подпрограмма возвращается назад для повторения процесса со следующим байтом.

6.2. Инвертирование экрана.

Длина: 18

Количество переменных: 0 Контрольная сумма: 1613

Назначение: Инвертирует все в дисплейном файле: если пиксел включен - он сбрасывается (OFF), если пиксел выключен, он устанавливается.

Вызов программы:

RANDOMIZE USR адрес

Контроль ошибок: Нет

Комментарий: Эта программа может быть использована для получения эффекта вспышки. Этот эффект усиливается, если делается вызов несколько раз и добавляется звук.

ЛИСТИНГ МАШИННЫХ КОДОВ

АССЕМБЛЕР

ЧИСЛА ДЛЯ

LD HL,16384

33

0

LD BC,6144

1

0

LD D,255

22

255

LD A, D

122

SUB (HL)

150

LD (HL),A

119

INC HL

35

DEC BC

11

LD A,B

120

OR C

177

JR NZ,NEXT B

32

247

RET

201

64 24

МЕТКА

NEXT

Как она работает:

В пару регистров HL загружается адрес дисплейного файла, а в ВС загружается его длина. В D-pегистр помещается значение 255. Всякий раз, когда подпрограмма возвращается к NEXT_B, в аккумулятор загружается значение из D регистра. Этот метод предпочтительнее, чем инструкция LD A,255 т.к. LD A,D выполняется приблизительно в 2 раза быстрее, чем инструкция LD A,255. Значение байта, хранящегося в ячейке по адреcy, указанному в HL, вычитается из аккумулятора, а результат загружается в тот же самый байт. Таким образом, делается инвертирование.

HL увеличивается, указывая на следующий байт, а счетчик BC, уменьшается. Если счетчик не равен 0, программа возвращается к NEXT_B. Если счетчик равен 0, программа возвращается в BASIC.

6.3 Инвертирование символа вертикально.

Длина: 20

Количество переменных: 1

Контрольная сумма: 1757

Назначение: Эта программа инвертирует символ вертикально. Например, стрелка, направленная вверх, должна стать стрелкой, направленной вниз, и наоборот.

Переменные:

Имя - chr. start

Длина - 2

Адрес - 23296

Комментарий: адрес символа в ОЗУ (ПЗУ).

Вызов программы:

RANDOMIZE USR адрес

Контроль ошибок: Нет

Комментарий: Эта программа полезна в играх, т.к. можно изменять отдельные символы, не затрагивая при этом соседние области изображения.

ЛИСТИНГ МАШИННЫХ КОДОВ

МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА

LD HL,(23296) 42 0 91 LD D,H 84

LD E,L 93

LD B,8 68

NEXT_B LD A,(HL) 126

INC HL 35

PUSH AF 245

DJNZ NEXT_B 16 251

LD B,8 68

REPL POP AF 241

LD (DE),A 18

INC DE 19

DJNZ REPL 16 251

RET 201

Как она работает:

В пару регистров HL загружается адрес данных символа. Этот же адрес затем копируется в DE. В регистр B загружается значение 8 для использования регистра в качестве счетчика. Для каждого байта в аккумулятор загружается имеющееся в настоящий момент значение. HL увеличивается, указывая на следующий байт, а содержимое аккумулятора помещается на стек. Счетчик уменьшается, и, если он не равен 0, подпрограмма возвращается, чтобы повторить процесс для следующего байта. В регистр "В" повторно загружается значение 8, чтобы снова использовать его в качестве счетчика. Изображение символа сохранено на стеке.

Процедура REPL возвращает данные со стека на то же знакоместо, но уже в обратном порядке.

Байт за байтом берутся со стека и через аккумулятор помещаются по адресу, содержащемуся в DE. DE увеличивается, чтобы указать на следующий байт, а счетчик уменьшается. Если он не равен 0, программа возвращается к REPL. В противном случае она возвращается в BASIC.

6.4 Инвертирование символа горизонтально.

Длина: 19

Количество переменных: 1

Контрольная сумма: 1621

Назначение: Эта программа инвертирует символ горизонтально - например, стрелка, направленная влево, становится стрелкой, направленной вправо.

Переменные:

Имя - chr_start

Длина - 2

Адрес - 23296

Комментарий - адрес данных символа.

Вызов программы:

RANDOMIZE USR адрес

Контроль ошибок: Нет

Комментарий: Нет

ЛИСТИНГ МАШИННЫХ КОДОВ

МЕТКА

АССЕМБЛЕР

ЧИСЛА ДЛЯ

LD HL,(23296)

42

0

LD A,8

62

8

NЕХТ В

LD B, 8

6

8

NEXT_P

RR (HL)

203

30

RL C

203

17

DJNZ NEXT P

16

250

LD (HL),C

113

INC HL

35

DEC A

61

JR NZ,NEXT B

32 243

Как она работает: В пару регистров HL загружается адрес данных символа, а в аккумулятор загружается количество байтов, которые должны быть инвертированы. В регистр B загружается число битов в каждом байте он используется, как счетчик.

Байт с адресом в HL сдвигается вправо таким образом, что крайний правый бит копируется во флаг переноса. C-регистр сдвигается влево так, что флаг переноса копируется в крайний правый бит. Счетчик (B-регистр) уменьшается. Если счетчик не равен 0, происходит переход к NEXT_P для работы со следующим пикселом.

Инвертированный байт, который находится в регистре C, помещается в ячейку, из которой он был взят. HL увеличивается, указывая на следующий байт, а аккумулятор уменьшается. Если аккумулятор не равен 0, происходит переход к NEXT_BYTE, в противном случае - возврат в BASIC.

6.5 Вращение символа по часовой стрелке.

Длина: 42

Количество переменных: 1

Контрольная сумма: 3876

Назначение: Эта программа поворачивает символ на 90 градусов по часовой стрелке, например, стрелка, направленная вверх становятся направленной вправо.

Переменные:

Ими - chr_start

Адрес - 23296

Комментарий: адрес данных символа.

Вызов программы:

RANDOMIZE USR адрес

Контроль ошибок: Нет

Комментарий: Эта программа полезна в играх и для серьёзных целей, например в графике.

ЛИСТИНГ МАШИННЫХ КОДОВ

АССЕМБЛЕР

ЧИСЛА ДЛЯ

LD HL,(23296)

42

0

LD E,128

30

128

PUSH HL

229

LD C,0

14

0

LD B,1

6

1

LD A, Е

123

AND (HL)

166

CP 0

254

0

JR Z,NOT S

40

3

LD A,C

121

ADD A^

128

LD C,A

79

SLA B

203

32

INC HL

35

JR NC,NEXT B

48

242

POP HL

225

PUSH BC

197

SRL Е

203

59

JR NC,N BIT

48

231

LD DE,7

17

7

ADD HL,DE

25

LD B,8

6

8

POP DE

209

LD (HL),E

115

DEC HL

43

DJNZ REPL

16

251

91

МЕТКА

N BIT

NEXT

NOT S

REPL

Как она работает:

Каждый символ состоит из группы пикселей размера 8x8, каждый из которых может быть в состоянии ON (1) или OFF (0). Рассмотрим любой бит B2 байта B1 на Рис1. Данные хранятся в ячейке (B2,B1) в форме:

|N1 N3| |N2 N4|

где: N1 = байт, в который пиксел (B2,B1) будет вставлен после вращения.

N2 = бит в N1, в который он будет вставлен.

N3 = значение, которое представляет текущее значение бита.

N4 = значение бита N2.

Каждый байт вращаемого символа будет сформирован добавлением значений всех битов N2, которые будут в новом байте.

1

128

2

64

3

32

4

16

5

8

6

4

7

2

8

1

0

1

0

1

0

1

0

1

0

1

0

1

0

1

0

1

1

128

2

64

3

32

4

16

5

8

6

4

7

2

8

1

1

2

1

2

1

2

1

2

1

2

1

2

1

2

1

2

1

128

2

64

3

32

4

16

5

8

6

4

7

2

8

1

2

4

2

4

2

4

2

4

2

4

2

4

2

4

2

4

1

128

2

64

3

32

4

16

5

8

6

4

7

2

8

1

3

8

3

8

3

8

3

8

3

8

3

8

3

8

3

8

1

128

2

64

3

32

4

16

5

8

6

4

7

2

8

1

4

16

4

16

4

16

4

16

4

16

4

16

4

16

4

16

1

128

2

64

3

32

4

16

5

8

6

4

7

2

8

1

5

32

5

32

5

32

5

32

5

32

5

32

5

32

5

32

1

128

2

64

3

32

4

16

5

8

6

4

7

2

8

1

6

64

6

64

6

64

6

64

6

64

6

64

6

64

6

64

1

128

2

64

3

32

4

16

5

8

6

4

7

2

8

1

7

128

7

128

7

128

7

128

7

128

7

128

7

128

7

128

1

2

3

4

Байт (B1)

5

6

7

8

76543210

Бит (B2)

Рис. 1 Ключ к подпрограмме вращения символа.

В HL загружается адрес первого байта символа. В регистр Е загружается значение байта, который имеет 7-й бит в состоянии ON и с 0 по 6 биты - в OFF т.е. 128. HL сохраняется в стеке. В регистр C засылается 0. Далее в него будут добавляться данные, давая новое значение для формируемого байта. В регистр B загружается значение байта, нулевой бит которого включен, а биты 1-7 - выключены т.е. это единица.

В аккумулятор загружается содержимое E-регистра (3). Это значение перемножается логически (AND) с байтом, адрес которого хранится в HL. Если результат равен 0, происходит переход к NOT_S, т.к. пиксель, адресованный регистром Е и регистровой парой HL, сброшен (OFF). Если же он установлен (ON), в аккумулятор загружается имеющееся значение байта (N1). Регистр B (N4) добавляется к аккумулятору, и это значение загружается в регистр С. Регистр затем устанавливается, чтобы указать на следующий байт (B1). HL увеличивается, указывая на следующий байт (B1). Если байт N1 не завершен, подпрограмма возвращается к NEXT_B.

HL восстанавливается из стека, чтобы снова указать на первый байт символа, ВС сохраняется в стеке, чтобы запомнить значение последнего байта для завершения в C регистре. E-регистр настраивается на адрес следующего бита каждого байта. Если вращение не завершено происходит переход к N_BIT.

В DE загружается значение 7, и это значение добавляется к HL. Теперь HL указывает на последний байт данных. В регистр B загружается число байтов, которые должны быть взяты из стека. Для каждого байта новое значение копируется в Е, и это значение помещается в ячейку с адресом в HL. HL уменьшается, чтобы указать на следующий байт и счетчик (B-регистр) уменьшается. Если счетчик не равен 0, происходит переход к REPL. Программа возвращается в BASIC.

6.6 Изменение атрибута.

Длина: 21

Количество переменных:2 Контрольная сумма: 1952

Назначение: Эта программа изменяет значение атрибутов всех символов экрана на задаваемое - например, могут быть изменены цвета всех символов, или весь экран может замигать и т. д.

Переменные: Имя - data saved Длина - 1 Адрес - 23296

Комментарий: неизменяемые биты атрибута. Имя - new_data Длина - 1 Адрес - 23297

Комментарий: Новые биты, вводимые в байт атрибута. Вызов программы:

RANDOMIZE USR адрес

Контроль ошибок: Нет

Комментарий: Отдельные биты атрибута каждого символа могут быть изменены с помощью инструкций AND и OR.

ЛИСТИНГ МАШИННЫХ КОДОВ

МЕТКА

91

NEXT B

АССЕМБЛЕР

ЧИСЛА

ДЛЯ

ВВОДА

LD HL,22528

33

0

88

LD BC,768

1

0

3

LD DE,(23296)

237

91

0

LD A,(HL)

126

AND E

163

OR D

178

LD (HL),A

119

INC H

35

DEC BC

11

LD A^

12O

OR C

177

JK NZ,NEXT B

32 246

RET

201

Как она работает:

В пару регистров HL загружается адрес области атрибутов, а в пару регистров BC количество символов на экране, в регистр D загружается значение new_data, а в регистр Е загружается значение data_saved.

В аккумулятор загружается байт с адресом, находящимся в HL, a биты устанавливаются соответственно значениям регистров D и Е. Результат помещается обратно в ячейку с адресом, хранящимся в HL. HL увеличивается, указывая на следующий байт, а счетчик ВС уменьшается. Если содержимое BC не равно 0, программа возвращается

к NEX^.

Программа возвращается в BASIC.

6.7 Смена атрибута.

Длина: 22

Количество переменных: 2 Контрольная сумма: 1825

Назначение: Эта программа ищет атрибуты с определенным значением и заменяет каждое найденное вхождение другим значением. Переменные: Имя - old_value Длина - 1 Адрес - 23296

Комментарий: Значение байта, подлежащего замене. Имя - new_value Длина - 1 Адрес - 23297

Комментарий: Значение замещающего байта. Вызов программы:

RANDOMIZE USR адрес

Контроль ошибок: Нет

Комментарий: Эта программа полезна для выделения областей текста и графических символов.

ЛИСТИНГ МАШИННЫХ КОДОВ

АССЕМБЛЕР

ЧИСЛА ДЛЯ

ВВОДА

LD HL,22528

33

0

88

LD BC,768

1

0

3

LD DE,(23296)

237

91

0

LD A,(HL)

126

CP Е

187

JR NZ,NO CH

32

1

LD (HL),D

114

INC HL

35

DEC BC

11

LD A^

120

OR C

177

JR NZ,NEXT B

32

245

RET

201

МЕТКА

91

NEXT B

NO CH

Как она работает:

В пару регистров HL загружается адрес области атрибутов, а в ВС загружается число символов на экране. В E-регистр загружается old_value, а в D-регистр - new_value. В аккумулятор загружается байт, адрес которого хранится в паре HL. Если аккумулятор хранит значение, которое эквивалентно содержимому Е-регистра, то в байт с адресом, имеющимся в HL, помещается содержимое D-регистра. При этом HL увеличивается, указывая на следующий байт, а счетчик ВС - уменьшается. Если ВС не равно 0, происходит переход к NEXT_B, иначе программа возвращается в BASIC.

6.8 Закрашивание контура.

Длина: 263

Количество переменных: 2

Контрольная сумма: 26647

Назначение: Эта программа закрашивает область экрана, ограниченную линией пикселей.

Переменные:

Имя - X_coord Длина - 1 Адрес - 23296

Комментарий: Координата X стартовой позиции. Имя - Y_coord Длина - 1 Адрес - 23297

Комментарий: Координата Y стартовой позиции. Вызов программы:

RANDOMIZE USR адрес

Контроль ошибок: Если координата Y>175 или POINT(X,Y)=1, то программа тотчас же возвращается в BASIC.

Комментарий: Эта программа - не перемещаемая, ее стартовый адрес - 31955. Когда закрашивается большая область сложной формы, нужно большое количество свободного пространства в ОЗУ. Если это невозможно, может произойти сбой.

ЛИСТИНГ МАШИННЫХ КОДОВ

АССЕМБЛЕР LD HL,(23296) LD A,H CP

RET NC CALL SUBR AND (HL) CP 0 RET NZ LD BC,65535 PUSH BC LD HL,(23296) CALL SUBR AND (HL) CP 0

JR NZ,LEFT LD HL,(23296) INC L

LD (23296),HL JR NZ,RIGHT LD DE,0 LD HL,(23296) DEC L

LD (23296),HL LD HL,(23296) PUSH HL CALL SUBR OR (HL) LD (HL),A POP HL LD A,H CP 175

ЧИСЛА ДЛЯ ВВОДА 42 0 91 124

254 176 208

205 143*125 166

254 0 192

1 255 255 197

42 0 91 205 143*125 166

254 0 32 9

42 0 91

44

34 0 91 32 236 17 0 0 42 0 91

45

34 0 91 42 0 91 229

205 143*125 182 119 225 124

254 175 40 44 123

254 0 32 16 36

205 143*125 166

254 0

32 7

42 0 91

36

229

МЕТКА

RIGHT

LEFT

PLOT

JR Z,DOWN

LD A,E CP 0

JR NZ,RESET INC H

CALL SUBR AND (HL) CP 0

JR NZ,RESET LD HL,(23296) INC H PUSH HL

LD E,1

RESET LD HL,(23296)

LD A,E CP 1

JR NX,DOWN INC H CALL SUBR AND (HL) CP 0

JR Z,DOWN LD E,0 JR DOWN L_JUMP JR RIGHT DOWN LD HL,(23296)

LD A,H CP 0

JR Z,NEXT_P LD A,D CP 0

JR NZ,REST DEC H CALL SUBR AND (HL) CP 0

JR NZ,REST LD HL,(23296) DEC H PUSH HL LD B,1

REST LD A,D

CP 1

JR NZ,NEXT_P LD HL,(23296) DEC H CALL SUBR AND (HL) CP 0

JR Z,NEXT_P LD D,0

NEXT_P LD HL,(23296) LD A,L CP 0

JR Z,RETR DEC L

LD (23296),HL CALL SUBR AND (HL) CP 0

JR Z,PLOT RETR POP HL

LD (23296),HL LD A,255 CP H

JR NZ,L_JUMP CP 1

JR NZ,L_JUMP RET

SUBR PUSH BC

PUSH DE LD A,175 SUB H LD H,A PUSH HL AND 7 ADD A,64

30

1

42

0

91

123

254

1

32

15

36

205

4

со *

125

166

254

0

40

6

30

0

24

2

24

167

42

0

91

124

254

0

40

40

122

254

0

32

16

37

205

4

со *

125

166

254

0

32

7

42

0

91

37

229

22

1

122

254

1

32

14

42

0

91

37

205

4

со *

125

166

254

0

40

2

22

0

42

0

91

125

254

0

40

12

45

34

0

91

205

4

со *

125

166

254

0

40

129

225

34

0

91

62

255

188

32

177

189

32

174

201

197

213

62

175

148

103

229

230

7

198

64

LD C,A 79

LD A,H 124

RRA 203 31

RRA 203 31

RRA 203 31

AND 31 230 31

LD B,A 71

AND 24 230 24

LD D,A 87

LD A,H 124

AND 192 230 192

LD E,A 95

LD H,C 97

LD A,L 125

RRA 203 31

RRA 203 31

RRA 203 31

AND 31 230 31

LD L,A 111

LD A,E 123

ADD A,B 128

SUB D 146

LD E,A 95

LD D,0 22 0

PUSH HL 229

PUSH DE 213

POP HL 225

ADD HL,HL 41

ADD HL,HL 41

ADD HL,HL 41

ADD HL,HL 41

ADD HL,HL 41

POP DE 209

ADD HL,DE 25

POP DE 209

LD A,E 123

AND 7 230 7

LD B,A 71

LD A,8 62 8

SUB B 144

LD B,A 71

LD A,1 62

ROTATE ADD A, A 135

DJNZ ROTATE 16 253

RRA 230 31

POP DE 209

POP BC 193

RET 201

Как она работает:

Эта программа вычерчивает горизонтальные линии из смежных пикселей. Назовем их строчками. Предел заполнения области строчками ограничен включенными (ON) пикселями. Каждая строчка запоминается с помощью занесения в стек координат крайнего правого пикселя этой строчки.

Запускаясь с определенных координат, программа делает заполнение в каждой строчке, отмечая позиции каждой из невыполненных строчек выше или ниже. По завершении одной строчки последнее значение отмеченных координат восстанавливается и для соответствующей строчки происходит заполнение. Этот процесс повторяется до тех пор, пока не останется незаполненных строчек.

Рис. 2 иллюстрирует технику процесса. Квадраты представляют пиксели, X обозначает стартовую позицию в пределах области штриховки, а * обозначает крайние правые пиксели строчек.

////

////

////

////

////

////

////

////

////

о

////

*

////

////

////

////

о

////

X

////

////

////

////

*

////

////

*

////

*

////

////

*

////

////

////

*

////

////

*

////

////

////

*

////

////

////

////

////

////

////

////

////

Рис. 2 Иллюстрация техники заполнения области. X - это стартовая позиция, * - начало строчек, о - оставшаяся незаштрихованная область.

Программа штрихует горизонтальную линию, содержащую стартовую позицию и сохраняет в стеке позицию начала строчки на линиях непосредственно выше и ниже. Далее она штрихует линию выше, а затем ниже, отмечая в последнем случае, что ещё 2 строчки запускаются на следующей нижней строке и т.д. Любая позиция в пределах области для штриховки может быть выбрана как стартовая позиция. Но заметим, что два пиксела, промаркированные нулями, нетронуты, т.к. они отделены от заштриховываемой области.

В регистр H загружается Y-координата, а в L-регистр - X-координата. Если значение Y больше, чем 175, программа возвращается в BASIC. Процедура SUBR вызывается, возвращая адрес бита (X,Y) в память. Если этот бит в состоянии 'ON' (включен), подпрограмма возвращается в BASIC.

Число 65535 помещается в стек, чтобы отметить первое сохраненное значение. Позднее, когда число восстанавливается из стека, оно интерпретируется, как пара координат. Однако, если число равно 65535, происходит возврат в BASIC, т.к. программа закончена.

В регистр H загружается Y-координата, а в регистр L - X координата. Процедура SUBR вызывается, возвращая в HL адрес бита (Х^). Если этот бит установлен (ON), происходит переход к LEFT. Иначе X-координата увеличивается, и делается переход к RIGHT, если X не равен 256.

В процедуре LEFT, DE устанавливается в 0. Регистры D и Е используются, как флаги: D - вниз (DOWN), Е - вверх (UP). X-координата уменьшается. SUBR вызывается, и вычерчивается точка (X,Y). Если Y-координата равна 175, подпрограмма переходит к DOWN. Если флаг "ВВЕРХ" установлен, происходит переход к RESET. Если бит (X,Y+1) сброшен, значение X и Y+1 сохраняются в стеке и флаг "ВВЕРХ" включается.

В процедуре RESET, если флаг "ВВЕРХ" включен, происходит переход к DOWN. Если бит (X,Y+1) включен (ON). Флаг "ВВЕРХ" выключается. В процедуре DOWN, если Y-координата равна 0, происходит переход к NEXT_PIXEL. Если флаг "ВНИЗ" включен, происходит переход к REST. Если бит (X,Y-1) сброшен (OFF), то значения X и Y-1 сохраняются на стеке и флаг "ВНИЗ" включается.

В процедуре REST, если флаг "ВНИЗ" выключен, происходит переход к NEXT_P. Если бит (X,Y-1) установлен (ON), то флаг "ВНИЗ" выключается. В процедуре NEXT_P, если X-координата равна 0, подпрограмма переходит к RETR. X-координата уменьшается, и, если новый бит (X,Y) сброшен (OFF), происходит переход к PLOT. В процедуре RETR X и Y-координаты извлекаются из стека. Если X и Y равны 255, то - возврат в BASIC, т.к.

заполнение области завершено. Иначе подпрограмма возвращается к RIGHT.

Процедура SUBR должна подсчитать адрес бита (X,Y) в памяти. В BASIC этот адрес

будет:

16384 + INT(Z/8) + 256 * (Z - 8 * INT(Z/8)) + 32 * (64 * INT(Z/64) + INT(Z/8) - 8 * INT(Z/64)), где Z=175-Y

Пары регистров BC и DE сохраняются на стеке. В аккумулятор засылается число 175 и из этого значения вычитается Y-координата. Результат копируется в Н-регистр. Затем HL сохраняется на стеке. Пять левых битов аккумулятора устанавливаются в 0, а затем к ним прибавляется 64. Результат копируется в C-регистр. При умножении на 256 получаем: 16384 + 256 * (Z-8 * INT(Z/8)).

В аккумулятор загружается Z, это значение делится на 8, результат копируется в регистр В. Этот результат - INT(Z/8). Установка трех крайних правых битов в 0 при ротации дает значения 8 * INT(Z/64), которое загружается в D-регистр. В аккумулятор загружается Z и 6 крайних правых битов выключаются, что дает 64 * INT(Z/64). Это значение загружается в E-регистр. Значение из C-регистра копируется в Н. В аккумулятор загружается X-координата, это значение делится на 8, а результат копируется в L.

В аккумулятор затем загружается значение E-регистра и к нему прибавляется содержимое В. Значение D-регистра вычитается и результат загружается в DE. Это значение умножается на 32. DE восстанавливается из стека и прибавляется к HL. Т.о. HL теперь хранит адрес бита (X,Y).

В аккумулятор загружается первоначальное значение X. Установка пяти левых битов в ноль дает значение X - 8 * INT(X/8). В B регистр затем загружается 8 минус значение аккумулятора, чтобы использовать его в качестве счетчика.

Аккумулятор устанавливается в 1, и это умножается на 2 (В-1) раз.

В этот момент в аккумуляторе необходимо установить бит, который соответствует биту (X,Y) с адресом в HL. DE и BC затем восстанавливаются из стека, и SUBR выполняет возврат в основную программу.

6.9 Построение шаблонов.

Длина: 196

Количество переменных:2 Контрольная сумма: 20278

Назначение: Эта программа чертит шаблон любого размера на экране. Под шаблоном понимается любая, ранее определенная фигура. Переменные: Имя - X_start Длина -1 Адрес - 23296

Комментарий: X-координата первого пиксела. Имя Y_start Длина -1 Адрес - 23297

Комментарий: Y-координата первого пиксела. Вызов программы:

RANDOMIZE USR адрес

Контроль ошибок: Если строковая переменная, хранящая информацию по шаблону A$, не существует, имеет нулевую длину или не содержит никакой информации, программа возвращается непосредственно в BASIC. Это происходит также в случае, если Y_start больве, чем 175.

Комментарий: Это полезная программа для хранения фигур в памяти и быстрого вычерчивания их на экране.

Использование этой программы:

(I) LET A$="информация по шаблону"

(II) POKE 23296, X-координата первого пиксела

(III)POKE 23297, Y-координата первого пиксела

(IV) RANDOMIZE USR адрес

Информация шаблона - это символов, который имеет следующий формат:

" 0 " поместить точку

" 5 " уменьшить X-координату

" 6 " уменьшить Y- координату

" 7 " увеличить X-координату

" 8 " увеличить Y координату

Любые другие символы игнорируются

Программа включает в себя возможность 'wrap-round'. Т.е. если X-координата выходит за левую часть экрана, шаблон появляется справа и т.п. Чтобы изменить программу для использования иной строковой переменной вместо A$, нужно изменить 65 * (код буквы A) на код иного символа.

ЛИСТИНГ МАШИННЫХ КОДОВ

МЕТКА

АССЕМБЛЕР

ЧИСЛА ДЛЯ

LD HL,(23627)

42

75

N EXT_V

LD A,(HL)

126

CP 128

254

128

RET Z

200

BIT 7,A

203

127

JR NZ,FORNXT

32

23

CP 96

254

96

JR NC,NUMBER

48

11

CP 65

254

65*

JR Z,FOUND

40

35

STRING

INC HL

35

LD E,(HL)

94

INC HL

35

LD D,(HL)

86

ADD

ADD HL,DE

25

JR INCR

24

5

NUMBER

INC HL

35

INC HL

35

INC HL

35

INC HL

35

INC HL

35

INCR

INC HL

35

JR NEXT V

24

225

FORNXT

CP 224

254

224

JR C,N BIT

56

5

LD DE,18

17

18

JR ADD

24

236

N_BIT

BIT 5,A

203

111

JR Z,STRING

40

228

NEXT_B

INC HL

35

BIT 7,(HL)

203

126

JR Z,NEXT B

40

251

JR NUMBER

24

228

FOUND

INC HL

35

LD C,(HL)

78

INC HL

35

LD B,(HL)

70

INC HL

35

EX DE,HL

235

LD A,(23297)

58

1

CP 176

254

176

RET NC

208

AGAIN

LD HL,(23296)

42

0

LD A,B

120

OR C

177

92

91 91

0

RET Z 200

DEC ВС 11

LD A,(DE) 26

INC DE 19

CP 48 254 48

JR NZ,NOT_PL 32 78

PUSH BC 197

PUSH DE 213

LD A,175 62 175

SUB H 148

LD H,A 103

PUSH HL 229

AND 7 230 7

ADD A,64 198 64

LD C,A 79

LD A,H 124

RRA 203 31

RRA 203 31

RRA 203 31

AND 31 230 31

LD B,A 71

AND 24 230 24

LD D,A 87

LD A,H 124

AND 192 230 192

LD E,A 95

LD H,C 97

LD A,L 125

RRA 203 31

RRA 203 31

RRA 203 31

AND 31 230

LD L,A 111

LD A,E 123

ADD A^ 128

SUB D 146

LD E,A 95

LD D,0 22 0

PUSH HL 229

PUSH DE 213

POP HL 225

ADD HL,HL 41

ADD HL,HL 41

ADD HL,HL 41

ADD HL,HL 41

ADD HL,HL 41

POP DE 209

ADD HL,DE 25

POP DE 209

LD A,E 123

AND 7 230 7

LD B,A 71

LD A,8 62 8

SUB B 144

LD B,A 71

LD A,L 62 1

ROTATE ADD A, A 135

DJNZ ROTATE 16 253

RRA 203 31

POP DE 209

POP BC 193

OR (HL) 182

LD (HL),A 119

HERE JR AGAIN 24 165

NOT_PL CP 53 254 53

JR NZ,DOWN

32

1

DEC 1

45

DOWN

CP 54

254

54

JR NZ,UP

32

8

DEC Н

37

LD H,A

124

CP 255

254

255

JR NZ,SAVE

32

19

LD H,175

38

175

UP

CP 55

254

55

JR NZ,RIGHT

32

8

INC H

36

LD A,H

124

CP 176

254

176

JR NZ,SAVE

32

7

LD H,0

38

0

RIGHT

CP 56

254

56

JR NZ,SAVE

32

1

INC L

44

SAVE

LD (23296),HL

34

0

JR HERE

24

215

Как она работает:

Для нахождения адреса строковой переменной используется немного измененная первая часть программы 'Поиск подстроки'.

Длина строковой переменной загружается в BC, а адрес первого символа A$ загружается в DE. В аккумуляторе устанавливается начальное значение Y, и, если оно больше 175, подпрограмма возвращается в BASIC. В H регистр загружается Y-координата, а в L X-координата. Если значение пары регистров ВС равно 0, подпрограмма возвращается в BASIC, т.к. достигнут конец строковой переменной. BC уменьшается, чтобы показать, что обрабатывается следующий символ. Следующий символ загружается в аккумулятор и DE увеличивается, указывая на следующий байт. Если аккумулятор не содержит код 48, происходит переход к NOT_PL. Точка (Х^) вычерчивается используя процедуру SUBR из программы "Закрашивание контура". Затем программа возвращается назад к 'AGAIN'. В процедуре NOT_PL, если аккумулятор содержит число 53, X-координата уменьшается. В процедуре DOWN, если аккумулятор не содержит число 54, делается переход к UP. Y-координата уменьшается, и, если ее значение становится равным -1, Y-координата устанавливается на значение 175.

В процедуре UP, если аккумулятор не содержит 55, происходит переход к RIGHT. Y-координата увеличивается, и, если она равна 176, то Y-координата устанавливается в 0. В процедуре RIGHT, если аккумулятор содержит значение 56, X-координата увеличивается. В процедуре SAVE координаты X и Y помещаются в память, а программа делает переход к HERE.

6.10 Увеличение экрана и копирование.

Длина:335

Количество переменных:8

Контрольная сумма: 33663

Назначение: Эта программа копирует часть дисплея в другую область экрана, увеличивая копию по Х или по Y.

Переменные: см. рис.3

Имя

Длина

Адрес

Комментарий

upper_Y_co-ord

1

23296

Y-координата верхнего ряда

lower_Y_co-ord

1

23297

Y-координата нижнего ряда

right_X_co-ord

1

23298

X-координата крайней правой колонки

left_X_co-ord

1

23299

X-координата крайней левой колонки

horizontal_scale

1

23300

Увеличение по X

vertical_scale

1

23301

Увеличение по Y

new_left_co-ord

1

23302

X-координата крайней левой колонки

области, в которую делается копирование

n ev_lowe r_co - o rd

1

23303

Y-координата нижнего ряда области, в

которую делается копирование

Вызов программы:

RANDOMIZE USR адрес

Контроль ошибок: Программа возвращается в BASIC, если одно из условий верно.

(I) horizontal_scale=0

(II) vertical_scale=0

(III) upper_Y_co-ord больше, чем 175

(IV) new_lower_co-ord больше, чем 175

(V) lower_Y_co-ord больше, чем upper_co-ord

(VI) new_lower_co-ord больше, чем right_X_co-ord

Однако, для краткости программы нет контроля, который проверял бы возможность размещения новой картинки на экране. Если этого не получается, может произойти сбой. Программа также требует большого объема свободной области ОЗУ, и, если это не доступно, может произойти сбой.

Комментарий: Эта программа - не перемещаемая из-за процедуры PLOT. Она размещается по адресу 65033 и, если скопированная область экрана имеет тот же самый размер, что и оригинал, масштаб должен быть установлен в 1, для двойного размера загружается масштаб 2:1, для тройного размера загружается масштаб 3:1 и т.д.

ЛИСТИНГ МАШИННЫХ КОДОВ

АССЕМБЛЕР

ЧИСЛА ДЛЯ

ВВОДА

LD IX,23296

221

33

0

LD A,175

62

175

CP (IX+0)

221

190

0

RET C

216

CP (IX+7)

221

190

7

RET C

216

SUB A

151

CP (IX+4)

221

190

4

RET Z

200

CP (IX+5)

221

190

5

RET Z

200

LD HL,(23296)

42

0

91

LD B,L

69

LD A,L

125

SUB H

148

RET C

216

LD (23298),A

50

0

91

LD E,A

95

LD HL,(23298)

42

2

91

LD C,L

77

LD A,L

125

SUB H

148

RET C

216

LD (23298),A

50

2

91

PUSH BC

197

LD L,A

111

LD H,0

38

0

INC HL

35

PUSH HL

229

POP BC

193

INC E

28

DEC E

29

JR Z,REMAIN

40

3

МЕТКА

91

ADD

ADD HL,BC

9

JR ADD

24

250

REMAIN

LD A, L

125

AND 15

230

15

LD B,A

71

POP HL

225

LD C,L

77

JR NZ,SAVE

32

2

FULL

LD B,16

6

16

SAVE

PUSH HL

229

CALL SUBR

205

13

255

AND (HL)

166

JR Z,OFF

40

2

LD A,1

62

1

OFF

POP HL

225

RRA

203

31

RL E

203

19

RL D

203

18

LD A,L

125

CP (IX+3)

221

190

3

JR Z,NEXT R

40

6

DEC L

45

N_BIT

DJNZ SAVE

16

231

PUSH DE

213

JR FULL

24

226

NEXT_R

LD L, C

105

LD A,H

124

CP (IX+1)

221

190

1

JR Z,COPY

40

3

DEC H

37

JR N BIT

24

241

COPY

PUSH DE

213

LD B,0

60

LD H^

96

LD L,В

104

RESET

LD (23306),HL

34

10

91

LD A,B

120

OR A

183

JR NZ,RETR

32

3

POP DE

209

LD B,16

6

16

RETR

SUB A

151

DEC B

5

RR D

203

26

RR E

203

27

RL A

203

23

PUSH DE

213

PUSH BC

197

PUSH AF

245

LD H,1

38

1

LOOP

LD L,1

46

1

PRESET

LD (23304),HL

34

8

91

LD A,(23307)

58

11

91

LD HL,0

33

0

0

LD DE,(23301)

237

91

5

LD D,L

85

MULTIP

OR A

183

JR Z,CALC

40

6

ADD HL,DE

25

DEC A

61

JR MULTIP

24

249

L JUMP

JR RESET

24

208

CALC

LD A,(23303)

58

7

91

ADD A,L

133

LD HL,(23304)

42

8

91

ADD A,L DEC A PUSH AF LD A,(23306) LD HL,0 LD DE,(23300) LD D,L REPEAT OR A

JR Z,CONTIN ADD HL,DE DEC A JR REPEAT CONTIN LD A,(23302) ADD A,L LD HL,(23305) ADD H,L DEC A LD L,A POP AF LD H,A POP AF PUSH AF OR A

JR NZ,PLOT CALL SUBR CPL

AND (HL) JR POKE PLOT CALL SUBR

OR (HL) POKE LD (HL),A

LD HL,(23304) INC L

LD A,(23301)

INC A CP L

JR NZ,PRESER INC H

LD A,(23300) INC A CP H

JR NZ,LOOP POP AF POP BC POP DE

LD HL,(23306) INC L

LD A,(23298) 58 INC A CP L

JR NZ,L_JUMP LD L,0 INC H

LD A,(23296) INC A CP H

JR NZ,L_JUMP RET

SUBR PUSH BC

PUSH DE LD A,175 SUB H LD H,A PUSH HL AND 7

133

61

245

58

10

91

33

0

0

237

91

4

85

183

40

4

25

61

24

249

58

6

91

133

42

9

91

133

61

111

241

103

241

245

183

32

7

205

13

255

47

166

24

4

205

13

255

182

119

42

8

91

44

58

5

91

60

189

32

165

36

58

4

91

60

188

32

155

241

193

209

42

10

91

44

2

91

60

189

32

164

46

0

36

58

0

91

60

188

32

154

201

197

213

62

175

148

103

229

230

7

ADD A,64 198 64

LD C,A 79

LD A,H 124

RRA 203 31

RRA 203 31

RRA 203 31

AND 31 230 31

LD B,A 71

AND 24 230 24

LD D,A 87

LD A,H 124

AND 192 230 192

LD E,A 95

LD H,C 97

LD A,L 125

RRA 203 31

RRA 203 31

RRA 203 31

AND 31 230 31

LD L,A 111

LD A,E 123

ADD A^ 128

SUB D 146

LD E,A 95

LD D,0 22 0

PUSH HL 229

PUSH DE 213

POP HL 225

ADD HL,HL 41

ADD HL,HL 41

ADD HL,HL 41

ADD HL,HL 41

ADD HL,HL 41

POP DE 209

ADD HL,DE 25

POP DE 209

LD A,E 123

AND 7 230 7

LD B,A 71

LD A,8 62 8

SUB B 144

LD B,A 71

LD A,1 62 1

ROTATE ADD A, A 135 DJNZ ROTATE 16 253

RRA 203 31

POP DE 209

POP ВС 193

RET 201 Как она работает:

В IX загружается адрес буфера принтера для использования его в качестве указателя переменных. Если верхняя Y-координата или новая нижняя координата больше 175, программа возвращается в BASIC. Если значение увеличения по горизонтали или вертикали равно 0, происходит возврат в BASIC.

В Н-регистр загружается нижняя Y-координата, а в L-регистр - верхняя Y- координата. L-регистр копируется в B-регистр и в аккумулятор. Н-регистр вычитается из аккумулятора и подпрограмма возвращается в BASIC, если результат отрицательный.

Значение аккумулятора затем помещается в ячейку 23298 для использования в качестве счетчика. Пара регистров ВС затем сохраняется на стеке.

Регистр HL загружается значением аккумулятора, увеличивается и копируется в регистр ВС. ВС прибавляется к HL E раз, результирующее значение в HL является числом пикселей для копирования. В аккумулятор загружается значение L-регистра и 4 крайних левых бита устанавливаются в 0. Результат копируется в B-регистр для использования его в качестве счетчика.

Пара регистров HL восстанавливается из стека и регистр L копируется в C-регистр. Если B-регистр содержит 0, в регистр загружается число 16 - это количество битов в регистровой паре. Затем вызывается процедура SUBR и в аккумулятор загружается значение POINT (L,H). Пара регистров DE сдвигается влево, а значение бита из аккумулятора загружается в крайний правый бит Е- регистра.

Если L-регистр равен левой X-координате, подпрограмма переходит к NEXT_R (следующий ряд). Иначе уменьшается L-регистр, а затем - B-регистр. Если B-регистр не содержит 0, подпрограмма возвращается к SAVE для подачи следующего бита в пару регистров DE. Если B-регистр содержит 0, пара регистров DE помещается в стек и происходит переход к FULL.

В процедуре NEXT_R в L-регистр загружается правая X-координата, а в аккумулятор загружается значение Н-регистра. Если значение аккумулятора равно нижней Y-координате, происходит переход к COPY, т.к. последний пиксель для копирования подан в DE. Иначе, Н-регистр уменьшается, указывая на следующий ряд, и подпрограмма возвращается к N_BIT.

В процедуре COPY содержимое пары BE помещается в стек, а B, Н и L-регистры устанавливаются в 0 для использования их в качестве счетчиков. Содержимое пары регистров HL помещается в ячейку с адресами 23306/7 - HL теперь может использоваться как счетчик последующих циклов без использования стека. Если B-регистр содержит 0, DE восстанавливается из стека, а регистр B повторно устанавливается на значение 16, определяя количество пикселей, хранимых в DE. B-регистр уменьшается показывая, что бит информации удален из DE. Крайний правый бит E-регистра загружается в аккумулятор, а пара регистров DE сдвигается вправо. DE,ВС и AF помещаются в стек до тех пор, пока выполнятся определенные расчеты.

В регистры H и L загружается 1 для использования их в качестве счетчика, a HL помещается в ячейки с адресами 23304/5. В аккумулятор загружается значение байта по адресу 23307 - это один из счетчиков, сохраненных ранее. В пару регистров DE загружается масштаб по вертикали. Это значение затем умножается на значение аккумулятора, а результат подаётся в HL. Это значение прибавляется к новой нижней Y-координате в аккумуляторе. Байт по адресу 23304 затем добавляется к аккумулятору, а результат уменьшается.

Аккумулятор теперь хранит Y-координату для построения следующего пиксела. Это значение хранится в стеке до тех пор, пока подсчитывается X-координата похожим способом. После расчета X-координата загружается в L-регистр. Y-координата восстанавливается из стека и загружается в Н-регистр. В аккумуляторе устанавливается последнее значение, хранящееся в стеке. Если оно равно 1, то должна быть построена точка (X,Y), иначе должна быть выполнена процедура UNPLOTTED. Вызывается SUBR и выполняются соответствующие действия.

Пара регистров HL загружается счетчиками цикла, хранящимися адресам 23304/5. Регистр L увеличивается, и, если он не содержит значение (1+vertical_scale), программа возвращается к PRESER. Регистр H увеличивается, и, ее он не содержит значение (1+horizontal_scale), происходит переход к LOOP.

Пары регистров AF,ВС и DE восстанавливаются из стека, а в пару регистров HL загружается второе значение набора счетчиков цикла, которое хранится по адресам 23306/7. Регистр L увеличивается и происходит переход к RESET, если результат не равен (right_X_co-ord-left_X_co-ord + 1)

Регистр L устанавливается в 0 - это первоначальное значение счетчика цикла. H-регистр затем увеличивается и подпрограмма переходит к RESET, если результат не равен (upper_Y_co-ord -lower_Y_co-ord + 1). Программа возвращается в BASIC,

Процедура SUBR идентична той, что используется в программе "Закрашивание контура".

Продолжение следует

Алексеев А. Г.




СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Дед мазай - чит к играм.
НА-ЧАЛО - Hello, wild spekk user!!! Чё дeлaeш? Я вoт вступлeниe тут щaс пишу...
TOP TEN - Десяточка лучших игр.
От автора - вышел ТРИНАДЦАТЫЙ номер...
Железо - Подключение принтера с интерфейсом Centronics к порту LPT.

В этот день...   23 ноября