PDA

Просмотр полной версии : Расчет адреса точки на экране



Ares
27.04.2012, 22:18
Добрый день уважаемые программисты.Я новичок в машинных кодах,как мне рассчитать где будет какая точка на экране.Помогите пожалуста :(

Andrew771
27.04.2012, 22:57
Процедура ПЗУ по адресу 8880 (дес.). Входные параметры: a=вертик.координата точки (0..191), c=гориз.координата точки (0..255). Отсчет с верхнего левого угла экрана. Выходные параметры: hl=адрес байта экрана, a=номер бита от левого края байта.

AER
28.04.2012, 15:53
Добрый день уважаемые программисты.Я новичок в машинных кодах,как мне рассчитать где будет какая точка на экране.Помогите пожалуста
Вот (http://zxpress.ru/articles_list.php?tag=13) где всё узнавать надо!

GriV
29.04.2012, 23:50
Добрый день уважаемые программисты.Я новичок в машинных кодах,как мне рассчитать где будет какая точка на экране.Помогите пожалуста
Вы хотите сами вычислять по координате адрес и править область экрана или использовать готовое решение из ПЗУ?

Ares
01.05.2012, 10:33
Вы хотите сами вычислять по координате адрес и править область экрана или использовать готовое решение из ПЗУ?

Выставлять точки,а потом полученный рисунок что бы двигался :v2_conf2:

GriV
01.05.2012, 12:51
Вы ставите задачи с очень неконкретными условиями.
Вероятно Вам хватит пакета supercode20 или процедур из ПЗУ - там есть и выставление точек и печать символов и прорисовка линий, в принципе - всё что надо.

Если же вам что-то более конкретное нужно, то здесь только Вы и сможете себе написать то, что надо.
Если у Вас не хватает понимания архитектуры экрана и способов работы, то советую прочитать сборники книг "как написать игру для ZX-Spectrum" - их можно скачать на виртуал-тырдосе, по этому адресу (http://vtrdos.ru/book.php). Там чётко и популярно описаны адреса экрана и как с ними обращаться

AER
01.05.2012, 18:26
Выставлять точки,а потом полученный рисунок что бы двигался
какие точки выставлять? файл картинки надо запихать в адресс 16384 (длина 6912) и он появится на экране.


полученный рисунок что бы двигался
скролл? иначе, спрайт?



Выставлять точки
Размер экрана в нашем Speccy составляет ни много, ни мало, а 256 точек/пиксел/бит по горизонтали и 192 по вертикали. Каждые 8x8 пикселов - это одно знакоместо. Таким образом, экран делится на 24 символьные строки по 32 знакоместа в каждой.
Экранная область в целом делится на две части:
основной экран.......[#4000-#57FF] (6144b)
атрибуты.............[#5800-#5AFF] (768b).

Сумма битов, помноженных на двойку в степени их номеров, даст значение байта.
Основной экран делится на три абсолютно равных сегмента (по 2048 байт каждый):
первый сегмент...............[#4000-#47FF]
второй сегмент...............[#4800-#4FFF]
третий сегмент...............[#5000-#57FF]

Жми и я тебе расскажу что-то (http://zx-spectrum.ru/viewtopic.php?f=8&t=438)

---------- Post added at 17:26 ---------- Previous post was at 17:19 ----------

расчет адреса знакоместа -


как мне рассчитать

ld B,y
ld C,x
ld A,B
rrca
rrca
rrca
and #e0
ld L,A
ld A,B
and #18
or #40
LD H,A
ld B,#00
add HL,BC

адресс указанных координат будет в HL

ld a, точка
ld (HL),a
ура! точка в указанных наших координатах!

Destr
08.05.2012, 17:33
Выставлять точки,а потом полученный рисунок что бы двигался
Круто!
Прям ностальжи.
По молодости я тоже писал на бэйсике подобное.
PLOT 10,10:PLOT 10,11 ... - в общем куча команд PLOT (вывод точки по координатам) и сами координаты,
Получались маленькие картинки :)
Ломал голову как заставить двигатся. И однажды догадался прибавлять к каждой координате некую переменную!
Офигел конечно когда увидел с какой УЖАСНОЙ скоростью это всё работает. Да и экран чистить приходится (командой CLS, конечно).
Потом решил - надо изучать ассемблер! Там быстрей всё будет.
(принцип думал такой-же, по точкам строить спрайт).
И только благодаря инфоркомовскому трехтомнику понял как я сильно заблуждался...

bsivko
25.06.2012, 01:46
Процедура ПЗУ по адресу 8880 (дес.). Входные параметры: a=вертик.координата точки (0..191), c=гориз.координата точки (0..255). Отсчет с верхнего левого угла экрана. Выходные параметры: hl=адрес байта экрана, a=номер бита от левого края байта.
Если мне не изменяет память, эта процедура ест более 500 тактов на точку.


ld A,B
rrca
rrca
rrca
and #e0
ld L,A
ld A,B
and #18
or #40
LD H,A
ld B,#00
add HL,BC

Здесь - поиск адреса первого байта знакоместа. 17 байт, 67 тактов.


Вот где всё узнавать надо!
Узнавать можно.

Когда-то прочитал процедурах поиска координаты первого байта знакоместа и процедуры рисования точки на экране в "Инфорком Прикладная графика". Как оказалось, там процедура для знакоместа требовала 61 такт времени и 16 байт реализации (лучше, чем у AER). Процедура рисования точки - порядка 100 байт и более 300 тактов времени. Это - далеко не предельные характеристики. Представляю вашему вниманию свои реализации.

Поиск знакоместа:


;на входе bc - координаты (xy, в знакоместах 0..31, 0..23)
;на выходе hl - адрес.

koorp ld a,c
and #18
or #40
ld h,a
ld a,c
and #07
rrca
rrca
rrca
add a,b
ld l,a

; 14 байт, 53 такта

И процедура рисования точки:


;bc - координаты точки (x 0..255, y 0..191)
plot push bc
srl b
srl b
srl b
srl c
srl c
srl c
call koorp
pop bc
ld a,c
and #07
add a,h
ld h,a
ld de,table
ld a,b
and #07
add a,e ; (*)
ld e,a
ld a,(de)
xor (hl) ; это операция рисования.
; если хотите OR (рисовать наверх) или AND (стирать точку),
; то меняете эту команду (на or (hl) или xor #ff; and (hl) соответственно)
ld (hl),a
ret
table defb 128,64,32,16,8,4,2,1
; в данной реализации table не должна попасть на стык адресов младшего байта.
; Т.е. младший адрес байта (table) должен быть менее #f9,
; чтобы корректно сработал в программе add a,e (*)

; 191 такт (+27 на call и 10 на ret если необходимо)
; 41 байт памяти

GriV
26.07.2012, 13:03
Скорость прорисовки можно увеличить, если заменить финальную часть поиска начала таблицы на простое ld d,'tab; ld e,b и чтобы таблице tab была выровнена по 256 байтам + содержала все смещения от 0 до 255, даст выигрыш (10+4+7+4+4) - (7+4) = 18 тактов.
Ещё можно ускорить для случаев, когда надо только выставлять точку или только стирать точку - использованием команд Res <num>,(HL) и Set <num>,(HL). В этом случае используется самомодифицирующийся код: ld a,b; add a,a; add a,a; add a,a; or %01000101; ld (set_+1),a; set_: set 0,(hl)

---------- Post added at 13:03 ---------- Previous post was at 13:01 ----------


Если мне не изменяет память, эта процедура ест более 500 тактов на точку.
Зато выставляет цвет, проверяет положение точки в экране, чего не делает Ваша процедура :)

bsivko
26.07.2012, 17:46
Скорость прорисовки можно увеличить, если заменить финальную часть поиска начала таблицы на простое ld d,'tab; ld e,b и чтобы таблице tab была выровнена по 256 байтам + содержала все смещения от 0 до 255, даст выигрыш (10+4+7+4+4) - (7+4) = 18 тактов.
Можно. Но использование таблиц и макросов, раздувающих простые процедуры в сотни и более байт - это преждевременная оптимизация.

Чаще всего в случае необходимости быстрой печати точек используются другие подходы. Например обработка точек целыми блоками (используя особенности рисования или результаты предыдущих вычислений).


Ещё можно ускорить для случаев, когда надо только выставлять точку или только стирать точку - использованием команд Res <num>,(HL) и Set <num>,(HL). В этом случае используется самомодифицирующийся код: ld a,b; add a,a; add a,a; add a,a; or %01000101; ld (set_+1),a; set_: set 0,(hl)
set 0,(hl) имеется ввиду #CB #xx ? для set там вроде %11 bit SSS нужно, т.е. or %11000110.

По тактам ваша замена у меня получается 4+4+4+4+7+13+15=51 такт вместо заменяемых 4+7+4+4+7+7+7=40. Не нахожу оптимизации..
Проверьте мои вычисления, а то под рукой сейчас нет справочника, брал по памяти и отсюда (http://www.emuverse.ru/wiki/Zilog_Z80/%D0%A1%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D0%BA% D0%BE%D0%BC%D0%B0%D0%BD%D0%B4).



add a,a; add a,a; add a,a
Кстати, эта последовательность возможно может быть соптимизирована засчет уже имеющейся выше серии "srl b".


Зато выставляет цвет, проверяет положение точки в экране, чего не делает Ваша процедура
Просто она делает только то, что от неё требуется (;