Построение точки — различия между версиями
Материал из SpeccyWiki
Goblinish (обсуждение | вклад) |
NMI (обсуждение | вклад) м (Откат правок Goblinish (обсуждение) к версии Alone) |
||
Строка 1: | Строка 1: | ||
− | + | Процедура разработана Busy, встречается в построениях окружности и линии. Для построения точек необходимо подготовить вспомогательную таблицу, которая занимает 4*256=1024 байта: | |
+ | 0-255 байт: старшие значащие байты адреса экрана(координата Y) | ||
+ | 256-511 байт: младшие значащие байты адреса экрана(координата Y) | ||
+ | 512-767 байт: смещение по экрану(координата X) | ||
+ | 768-1023 байт: битовые значения(координата X) | ||
− | + | <code><pre> | |
+ | PIX_TAB EQU #7C00 | ||
+ | PIX_TAB_HI EQU PIX_TAB/256;#7C | ||
+ | |||
+ | ORG #6000 | ||
+ | ;формирование адресов | ||
+ | INIT LD DE,#4000;адрес экранной области | ||
+ | LD L,E | ||
+ | LD BC,#8000 | ||
+ | ILP1 LD H,PIX_TAB_HI;high - аналог [ в Storm. | ||
+ | LD(HL),D;старший байт | ||
+ | INC H | ||
+ | LD (HL),E;младший байт | ||
+ | INC H | ||
+ | LD (HL),C;смещение X | ||
+ | INC H | ||
+ | LD (HL),B;битовое значение | ||
+ | CALL DOWN_DE;следующая линия экрана | ||
+ | RRC B;циклический сдвиг битового значения - #80->#40->...->#4->#2->#1 | ||
+ | LD A,C; после того, когда в регистре B хранилось значение 1, сдвиг RRC установил флаг переноса C=1 | ||
+ | ADC A,0; поэтому вместо проверки выполняем сложение регистра C с учетом, получается C=C+1 | ||
+ | LD C,A | ||
+ | INC L; переходим к следующей таблице | ||
+ | JR NZ,ILP1;завершение цикла, 0-255 | ||
+ | ; при первоначальном выполнении в таблицу заносятся значения от #4000 до #5800 | ||
+ | ; поэтому процедура построения при значении Y>191 внесет изменения в атрибуты | ||
+ | ; чтобы не выполнять проверку, заполним часть таблицы нулями | ||
+ | LD HL,PIX_TAB+96 | ||
+ | ILP2 LD (HL),0 | ||
+ | INC L | ||
+ | JR NZ,ILP2 | ||
+ | RET | ||
+ | ;------------------------------- | ||
+ | DOWN_DE INC D | ||
+ | LD A,D | ||
+ | AND 7 | ||
+ | RET NZ | ||
+ | LD A,E | ||
+ | ADD A,32 | ||
+ | LD E,A | ||
+ | RET C | ||
+ | LD A,D | ||
+ | SUB 8 | ||
+ | LD D,A | ||
+ | RET | ||
+ | |||
+ | </pre></code> | ||
+ | ставим точку, входные данные DE=YX координаты | ||
+ | <code><pre> | ||
+ | PLOT PUSH HL | ||
+ | PUSH BC;сохранить на стеке используемые регистры | ||
+ | LD H,PIX_TAB_HI | ||
+ | LD L,D | ||
+ | LD B,(HL) | ||
+ | INC H | ||
+ | LD A,(HL) | ||
+ | LD L,E | ||
+ | INC H | ||
+ | OR (HL) | ||
+ | INC H | ||
+ | LD C,A;BC=адрес экрана | ||
+ | LD A,(BC); чтобы поставить точку нужно получить значение из экрана | ||
+ | OR (HL); проводим операцию OR | ||
+ | LD (BC),A; занести значение по адресу | ||
+ | POP BC;восстановить сохраненные регистры | ||
+ | POP HL | ||
+ | RET | ||
+ | </pre></code> | ||
+ | |||
+ | Существует и более быстрая процедура<ref>http://zxdn.narod.ru/coding/zg1etud2.txt</ref>: | ||
+ | |||
+ | <code><pre> | ||
+ | <Точка Старых>: по координатам,заданным | ||
+ | в регистрах L=y, E=x, в произвольном месте | ||
+ | экрана(и даже за экран)за 58(!)тактов ста- | ||
+ | вится точка.Регистр C равен старшему байту | ||
+ | адреса таблиц('TABLE), регистр D=C+2. | ||
+ | LD H,C | ||
+ | LD A,(DE);x/8 \ | ||
+ | INC D |-даёт младший байт | ||
+ | OR (HL);L(y) / | ||
+ | INC H | ||
+ | LD H,(HL);H(y) | ||
+ | LD L,A | ||
+ | LD A,(DE);byte(x) | ||
+ | (X)OR (HL);метод постановки точки | ||
+ | LD (HL),A | ||
+ | Если вместо последних 2 команд вставить | ||
+ | AND (HL),то это будет функция POINT. Чтобы | ||
+ | процедура работала многократно, в конце её | ||
+ | поставьте DEC D. Таблицы генерируются сле- | ||
+ | дующей программой: | ||
+ | LD HL,TABLE+256 | ||
+ | LD DE,#4000 | ||
+ | GEN0 LD (HL),D \ | ||
+ | DEC H | | ||
+ | LD (HL),E | | ||
+ | INC H | | ||
+ | DOWN DE | 1-я | ||
+ | LD A,D |- и | ||
+ | SUB 88 | 2-я | ||
+ | JR NZ,$+3 | | ||
+ | LD D,A | | ||
+ | INC L | | ||
+ | JR NZ,GEN0 / | ||
+ | INC H | ||
+ | LD A,128 | ||
+ | GEN1 LD (HL),E \ | ||
+ | INC H | | ||
+ | LD (HL),A | | ||
+ | DEC H | 3-я | ||
+ | RRCA |- и | ||
+ | JR NC,$+3 | 4-я | ||
+ | INC E | | ||
+ | INC L | | ||
+ | JR NZ,GEN1 / | ||
+ | </pre></code> | ||
+ | |||
+ | == Примечания == | ||
+ | <REFERENCES /> | ||
+ | |||
+ | [[Категория:Программирование графики]] |
Версия 16:03, 2 сентября 2015
Процедура разработана Busy, встречается в построениях окружности и линии. Для построения точек необходимо подготовить вспомогательную таблицу, которая занимает 4*256=1024 байта: 0-255 байт: старшие значащие байты адреса экрана(координата Y) 256-511 байт: младшие значащие байты адреса экрана(координата Y) 512-767 байт: смещение по экрану(координата X) 768-1023 байт: битовые значения(координата X)
PIX_TAB EQU #7C00
PIX_TAB_HI EQU PIX_TAB/256;#7C
ORG #6000
;формирование адресов
INIT LD DE,#4000;адрес экранной области
LD L,E
LD BC,#8000
ILP1 LD H,PIX_TAB_HI;high - аналог [ в Storm.
LD(HL),D;старший байт
INC H
LD (HL),E;младший байт
INC H
LD (HL),C;смещение X
INC H
LD (HL),B;битовое значение
CALL DOWN_DE;следующая линия экрана
RRC B;циклический сдвиг битового значения - #80->#40->...->#4->#2->#1
LD A,C; после того, когда в регистре B хранилось значение 1, сдвиг RRC установил флаг переноса C=1
ADC A,0; поэтому вместо проверки выполняем сложение регистра C с учетом, получается C=C+1
LD C,A
INC L; переходим к следующей таблице
JR NZ,ILP1;завершение цикла, 0-255
; при первоначальном выполнении в таблицу заносятся значения от #4000 до #5800
; поэтому процедура построения при значении Y>191 внесет изменения в атрибуты
; чтобы не выполнять проверку, заполним часть таблицы нулями
LD HL,PIX_TAB+96
ILP2 LD (HL),0
INC L
JR NZ,ILP2
RET
;-------------------------------
DOWN_DE INC D
LD A,D
AND 7
RET NZ
LD A,E
ADD A,32
LD E,A
RET C
LD A,D
SUB 8
LD D,A
RET
ставим точку, входные данные DE=YX координаты
PLOT PUSH HL
PUSH BC;сохранить на стеке используемые регистры
LD H,PIX_TAB_HI
LD L,D
LD B,(HL)
INC H
LD A,(HL)
LD L,E
INC H
OR (HL)
INC H
LD C,A;BC=адрес экрана
LD A,(BC); чтобы поставить точку нужно получить значение из экрана
OR (HL); проводим операцию OR
LD (BC),A; занести значение по адресу
POP BC;восстановить сохраненные регистры
POP HL
RET
Существует и более быстрая процедура[1]:
<Точка Старых>: по координатам,заданным
в регистрах L=y, E=x, в произвольном месте
экрана(и даже за экран)за 58(!)тактов ста-
вится точка.Регистр C равен старшему байту
адреса таблиц('TABLE), регистр D=C+2.
LD H,C
LD A,(DE);x/8 \
INC D |-даёт младший байт
OR (HL);L(y) /
INC H
LD H,(HL);H(y)
LD L,A
LD A,(DE);byte(x)
(X)OR (HL);метод постановки точки
LD (HL),A
Если вместо последних 2 команд вставить
AND (HL),то это будет функция POINT. Чтобы
процедура работала многократно, в конце её
поставьте DEC D. Таблицы генерируются сле-
дующей программой:
LD HL,TABLE+256
LD DE,#4000
GEN0 LD (HL),D \
DEC H |
LD (HL),E |
INC H |
DOWN DE | 1-я
LD A,D |- и
SUB 88 | 2-я
JR NZ,$+3 |
LD D,A |
INC L |
JR NZ,GEN0 /
INC H
LD A,128
GEN1 LD (HL),E \
INC H |
LD (HL),A |
DEC H | 3-я
RRCA |- и
JR NC,$+3 | 4-я
INC E |
INC L |
JR NZ,GEN1 /