PDA

Просмотр полной версии : Изучая акселераторы Пентево



Hacker VBI
02.05.2014, 12:46
Итак, ТС конфа.
Начал разбор платформы соотечественника, сейчас в самом начале пути.
Хочу поделится мыслями. Дополнения крайне приветствуются.

Система программирования под ТС непривычна в первую очередь тем, что мы, неожиданно, к стандартному набору синклеровской обвязки имеем дополнительные акселераторы. Все акселераторы (http://zx-evo-fpga.googlecode.com/hg/pentevo/docs/TSconf/TSconf.xls) управляются программированием портов #xxAF (http://zx-evo-fpga.googlecode.com/hg/pentevo/demos/includes/tsconfig.asm), и в зависимости от полученных данных выполняют разные действия.

Итак, что можем?

Акселераторы предназначены для управления расширенной памятью, выводом графики, перебросом данных (dma), + имеем расширенную систему прерываний, которая может отрабатывать как стандартная (фреймовая, 50гц) и дополнительная строчная (http://zx-evo-fpga.googlecode.com/hg/pentevo/demos/examples/example02/example02a.asm) - можно вызывать прерывание каждую строку отображения.

Память имеет возможность отображаться во все доступные зоны по 16 к - с адресов 0, 4000, 8000 и с000. всего получаем 256 страниц по 16к.
для включения страницы в нужное место памяти - используем порты:
PAGE0 equ $10AF - страница расположена с адреса 0
PAGE1 equ $11AF - с #4000
PAGE2 equ $12AF - с #8000
PAGE3 equ $13AF - с #с000

Графика, кроме стандартного 256*192 имеет ещё несколько режимов (http://tslabs.info/forum/viewtopic.php?f=35&t=178), связанных с цветностью на точку. все цвета, включая цвет бордюра (бордюров имеем два - стандартный #fe и 256-цветный палитровый #0FAF), завязаны на палитру из 256 цветов. Стандартно используется дефолтная палитра, и для использования других цветов мы можем задать свои.
для этого нужно передать набор цветов железу (акселератору) путём указания на адрес данных самой палитры, для акселератора.
сразу после этого все цвета экрана будут отображаться из обновлённых данных палитры.
Вся графика экрана в дополнительных режимах отображается в памяти страниц как окно просмотра. тут стоит добавить, что "Видеопамять представляет собой битмап размеров 512x512 пикселей", соответственно для режима 320х200 у нас к каждой строке есть дополнительно неотображаемых 512-320=192 точки.
Плюс, мы можем указать, где конкретно в памяти находится наш экран - VPage :)

Акселератор позволяет управлять этим окном вывода. для этого стоит прописать в порты GXOffs и GYOffs положение окна в памяти - и оп, экран сместился.
Кроме этого "стандартного" экрана мы имеем ещё несколько плоскостей, предназначенных для вывода на экран. Здесь я ещё толком не разобрался, но вижу подобный подход - T0XOffs, T0YOffs - икс и игрек положения для нулевого тайлового экрана, и T1XOffs / T1YOffs для первого.
Кроме этого, акселератор позволяет выводить ещё и спрайты. тут я тоже ещё лох, но уже вижу, что спрайты могут иметь Х и Y на экране и иметь размер от 8 до 64 пикселей, выводятся аппаратно, могут быть перевёрнуты по Х или Y.
про дма ничего не скажу, лох ваще :)))

Итак, краткий вывод.
Все вот эти вещи (https://www.youtube.com/watch?v=hgGp10r6bwE) работают только лишь управляя акселератором. изучая исходники Робата (http://tslabs.info/forum/viewtopic.php?f=24&t=152) я обнаружил только лишь управление портами да куски обновления координат для окон вывода - как для всех экранов, так и спрайтов.

Довольно непривычно поначалу, но возможностей очень много, и процессор в момент отработки действий акселератора свободен.
Стоит использовать :)

Один момент. Тема техническая а не холиварная. Сразу прошу - различных сравнений не нужно. Нужны примеры кода / собственные мысли как это всё использовать.

Юзаем цветастую графику:
Продолжу примерами:

давайте переключим экран в графику 320х200, 256 цветов.


VPAGE equ $01AF
LD BC,VPAGE ; Указываем системе, что видеопамять начинается с #20
LD A,#20 ; Номер банки
OUT (C),A

что происходит? теперь система знает, что экран начинается в 32й банке. и продолжается дальше - 33..36, и часть 37го банка памяти по 16к. Начало памяти - #c000, на строчку - 320 байтов, ещё 192 запаса.
следующая строка - #c200



VCONFIG equ $00AF
LD BC,VCONFIG ; Включаем видеорежим: %10-320x240, %001-16 цветов %01 – 320x200
LD A,%01000010
OUT (C),A


режим включён, на экране цветной бардак - в памяти хз чо)
что-бы получить все доступные цвета, их нужно указать системе:


LOAD_PAL LD A,%00010000 ; Включаем маппинг по адресу #0000
LD BC,FMADDR
OUT (C),A

LD HL,ZXPAL ; Перебрасываем данные
LD DE,#0000
ld bc,#200
ldir

XOR A ; Отключаем маппинг
LD BC,FMADDR
OUT (C),A
RET

В данном случае маппинг - это место в памяти, где лежит палитра. ZXPAL - это метка в коде типа include "pollitra.bin". Можно взять готовую палитру из твоей картинки.
давай сконвертим картинку в формат tga и скормим конвертеру (http://tslabs.info/forum/viewtopic.php?f=26&t=395), и получим на выходе два файла - файло с точками, файло с уже подготовленной палитрой.

после выполнения кода весь экран резко окрашен в цвета палитры. Кроме бордюра :)
Красим бордюр в цвета палитры, в регистре а - номер цвета из палитры.


BORDER equ $0FAF
ld bc,BORDER
ld a,128
out (c),a


include со всеми equ для портов получаем здесь (http://zx-evo-fpga.googlecode.com/hg/pentevo/demos/examples/includes/tsconfig.asm)

denpopov
02.05.2014, 13:15
про дма ничего не скажу, лох ваще
лучше бы сказал, так даже доступнее:)

Hacker VBI
02.05.2014, 13:20
denpopov, по мере изучения бу делится.

daniel
03.05.2014, 08:31
Я так понимаю даже использую басик можно руля портами получать видеоэффекты.

Hacker VBI, спасибо что начал эту тему, очень интересно! Продалжай.

denpopov
03.05.2014, 08:47
Я так понимаю даже использую басик можно руля портами получать видеоэффекты.

а стоит ли?

daniel
03.05.2014, 12:34
а стоит ли?

Интересно же :). Опять же можно не уметь кодить и хорошо рисовать и быть дизигнером.

Hacker VBI
03.05.2014, 19:56
daniel, насчёт прямого бейсика не уверен, довольно сложно будет юзать доп.графику. но всё-же.
добавил примеры переключения в режим.

drbars
03.05.2014, 20:19
А как обстоят дела с этой платформой у буржуев? Сколько вообще железа её поддерживает?

denpopov
03.05.2014, 20:21
До тайлов ты еще не добрался?

Hacker VBI
03.05.2014, 20:24
denpopov, ещё в процессе, времени не так много как хотелось-бы потратить)
drbars, признанный лидер сейчас - это Ева. Вот у ерза она есть

denpopov
03.05.2014, 20:26
denpopov, ещё в процессе, времени не так много как хотелось-бы потратить)
ну тогда, наверное, нужно внести изменения в пост, потому что пример говорит другое.

и про цвета палитры -полный туман.

Hacker VBI
03.05.2014, 20:32
denpopov, я не ставлю задачу расписать всё.
это вводный курс, как я его понимаю.

где пример говорит "другое"?
если есть обьяснение, как пользовать тайлы - welcome

denpopov
03.05.2014, 20:35
где пример говорит "другое"?
http://zx-evo-fpga.googlecode.com/hg/pentevo/demos/examples/example01/

вот смотри сколько тумана:


VCONFIG equ $00AF
LD BC,VCONFIG ; Включаем видеорежим: %10-320x240, %001-16 цветов %01 – 320x200
LD A,%01000010
OUT (C),A


из примера куда понятнее.


я не ставлю задачу расписать всё.
это вводный курс, как я его понимаю

bad try

SAM style
03.05.2014, 21:40
Я для эмуляции много почерпнул отсюда - http://zx-evo-fpga.googlecode.com/hg/pentevo/docs/TSconf/TSconf.xls

Buyan
04.05.2014, 10:14
если есть обьяснение, как пользовать тайлы - welcome
Пример по тайлам: отображение битмапа 320х240х16c в тайловом слое

Hacker VBI
04.05.2014, 13:02
Buyan, я прокомментирую, поправишь:




start di
ld sp,49151

call init_gfx ;устанавливаем режимы
call init_zx_pal ;грузим палитру
call gfx_copy ;грузим графику для 0-го тайлового слоя
call fill_tiles ;заполняем карту тайлов

stop jp stop




include dev\ts-ports.asm ; названия портов лежат здесь, в первом посте есть ссылка на подобный файл

init_gfx ld bc,VConfig ; 320x240
ld a,%10100001
out (c),a

ld bc,TSConfig ; 0й тайловый вкл., отображение тайлов с номером 0 - вкл.
ld a,%00100100
out (c),a

ld bc,PalSel
ld a,%00000000
out (c),a


ld bc,T0YOffsL ; смещения для 0-го тайлового слоя ставим по 0
out (c),a
ld bc,T0YOffsH
out (c),a
ld bc,T0XOffsL
out (c),a
ld bc,T0XOffsH
out (c),a

ld bc,T0GPage ; графика 0-го тайлового слоя
ld a,128
out (c),a

ld bc,TMPage ; страница карты тайлов
ld a,128+8
out (c),a
ret


Хорошо комментированный текст :) Смотрим екселевский файл, видим, что в TSConfig ложим %00100100, -

T0_EN Tile Layer 0 Enable
T0Z_EN Tiles with number 0 display Enable

0й тайловый вкл., отображение тайлов с номером 0 - вкл.

PalSel - Palette selection for 4 bit modes. выбор палитры в 0, в инициализации палитры ( init_zx_pal ) видим, что она начинается с адреса 0. палитра загружается стандартная спековская из файла.

для тайлов мы имеем 16 цветов онли. тут бы хотелось немного болше информации, по выбору палитры.

Дальше - указывается адрес отображения окна просмотра - х=0, y=0, выбирается страница с графикой тайлового слоя и выбирается страница карты тайлов, всё видно в комментариях.



;------------------------------------------------------------
init_zx_pal ld a,%00010000

ld bc,FMAddr
out (c),a

ld hl,zx_palette
ld de,0
ld bc,32
ldir

xor a
ld bc,FMAddr
out (c),a
ret
zx_palette include "dev\zx_palette.asm"

пример знаком

дальше интереснее. DMA
используется для переброски загруженной картинки в нужные страницы в нужном формате:
DMASххх - dma источник
DMADххх - dma приёмник

DMASAddrX - страница источника
DMASAddr - адрес откуда

DMALen - DMA Burst Length
Длина 1 бурста в словах минус 1. Т.е. 0 - 2 байта, 255 - 512 байт.
в данном случае - 160/2-1 - строками по 160 байт (320 точек 16С)
DMANum - колво строк

DMACtrl - %00010001. DMA Control / Start
включен бит D_ALGN, Destination Address Alignment.
"After each burst lower bits of address restored to their initial values before burst, upper bits increased by 1"
- выравнивание по 256b, т.е. каждая следующая строка будет загружена по адресу + 256

включенный бит 0 значит, что пишем из озу в озу: RAM (Src) is copied to RAM (Dst)

читаем статус (DMAStatus), пока операция не закончится.




;------------------------------------------------
gfx_copy ld bc,DMASAddrX
ld a,100 ; из spg графика загружена начиная с 100-й страницы
out (c),a
ld hl,0
ld bc,DMASAddrH
out (c),h
ld bc,DMASAddrL
out (c),l

ld bc,DMADAddrX
ld a,128 ; перекидываем в 128 ( T0GPage )
out (c),a
ld hl,0
ld bc,DMADAddrH
out (c),h
ld bc,DMADAddrL
out (c),l

ld bc,DMALen
ld a,160/2-1 ; строками по 160 байт (320 точек 16С)
out (c),a

ld bc,DMANum
ld a,240-1 ; 240 строк
out (c),a

ld bc,DMACtrl
ld a,%00010001 ; с выравниванием по 256b, т.е. каждая следующая строка
out (c),a ; будет загружена по адресу + 256

ld bc,DMAStatus
nm1cl in a,(c)
or a
jr nz,nm1cl
ret


дальше самое интересное.
тайловая карта задаётся двумя байтами на каждый тайл. первый байт - номер, второй байт: 4 младших бита - номер тайла, а так-же выбор палитры и возможность переворота тайла:

TNUM Tile Number for upper left corner. Bits 0-5 are X Position in Graphics Bitmap, bits 6-11 - Y Position.
XF Horizontal Flip
YF Vertical Flip
TPAL Tile Palette Selector, bits 0-1. Bits 2-3 are taken from PalSel register bits 6-7 or 4-5, dependently on tiles layer 1 or 0.


Тайловая карта генерится слева-направо, сверху-вниз. всего можем иметь 64*64

tpos_x tile X position on the plane 0-63
tpos_y tile Y position on the plane 0-63


размер тайла имеем 8*8 точек. других размеров быть не может, так?
Тайловых карт всего две, и они находятся в одной странице вперемешку. тайлы0 - от 0до 127, тайлы1 - от 128-155




fill_tiles ld bc,Page3 ; включаем страницу тайлмапа с #C000
ld a,128+8
out (c),a

ld ix,#c000 ; адрес 0-го тайла 0-го слоя ( для слоя 1 соответственно #C000+128 )

ld de,64
ld hl,0 ; начальный номер тайла
ld b,30 ; тайлов по вертикали (240/8)
fill_y push bc
push ix
push hl

ld b,40 ; тайлов по горизонтали (320/8)
fill_x ld (ix+0),l
ld a,h
and %00001111 ; биты номера палитры тайла и инверсий XY по 0-м т.е палитра №0 и зеркалирование тайла выкл.
ld h,a
ld (ix+1),h
inc hl ; номер следующего тайла
inc ix ; адрес следующего тайла (+2 т.к описатель тайла 2 байта)
inc ix
djnz fill_x

pop hl
add hl,de ; первый тайл следующей строки ( номер + 64 т.к. слой 64х64 тайла )
pop ix
inc ixh ; адрес следующей строки слоя в тайлмапе ( + 256 )
pop bc
djnz fill_y
ret


Сразу после вызова последнего сall видим девушку на экране.
нулевой цвет для тайлов должен обозначать прозрачность: 4 bits per pixel, transparent color is 0 from 16 (4'b0)

Buyan
04.05.2014, 13:28
что в TSConfig ложим %00100100, -

T0_EN Tile Layer 0 Enable
T0Z_EN Tiles with number 0 display Enable

1й тайловый вкл., отображение тайлов с номером 0 - вкл.

там опечатка у меня, 0й тайловый т.е., а не 1й.

Hacker VBI
04.05.2014, 13:33
Buyan, и я пропустил, хоть в описании битов всё нашёл правильно)
поправил

Buyan
04.05.2014, 14:07
для тайлов мы имеем 16 цветов онли. тут бы хотелось немного болше информации, по выбору палитры.

В описателе тайла за выбор палитры отвечают только 2 бита TPAL (биты 1,0), биты (3,2) прописываются в регистре PalSel для каждого из слоев, эти биты в сумме и задают конечный 4х битный номер палитры конкретного тайла. Т.е. получается что в пределах одного тайлового слоя для каждого тайла можно использовать 1 из 4х смежных палитр.

Hacker VBI
04.05.2014, 14:39
Народ, интересно?
На очереди разбор MindWarp - офигезный эффект палитры)

piroxilin
04.05.2014, 14:48
Hacker VBI, Да - интересно почитать про TS в доступном виде = продолжай ))

Hacker VBI
04.05.2014, 15:27
piroxilin, это хорошо.
в общем, есть ещё один разбор.

MindWarp (http://forum.tslabs.info/viewtopic.php?f=24&t=349)от DDp


Смотреть бум только первую часть балета - эффект, завязанный на палитре

Что имеем сразу в страницах памяти: сформированное изображение для экрана, сотни килобайт звука для ковокса.
Картинка для экрана - чёрнобелая.
Суть эффекта - в смене палитры для изображения на экране.
изображение палитры - во вложении.



org 0x6200
binclude "mw_pal.bin"

ld iyl,3
restart:di
ld sp,0x6000
ld hl,mw_int
ld (0x67ff),hl
ld a,0x67
ld i,a
im 2

; копируем палитру
ld hl,0x6200
ld de,0x6000
ld bc,0x0200
ldir

; начинаем заброс данных в порты:
ld hl,mwset
ld e,(mwset_end-mwset)/2
ld c,0xaf
wrrg1: ld b,(hl)
inc l
ld a,(hl)
inc l
out (c),a
dec e
jr nz,wrrg1


берём в b адрес порта, в а - данные, бросаем в порт:
0x20,6 - System Config, %10 -ставим частоту 14.0,normal, кеш включен.

0x00,0xc2 - VConfig, включаем макс разрешение 360x288, 256 цветов.
0x01,MW_PIC_PAGE - Video Page, включаем страницу 16 с изображением
0x02,0 - X-offset for graphics, отступы окна просмотра в 0.
0x03,0
0x04,0 - Y-offset for graphics
0x05,0

0x1a,0x00 - DMA Source Address
0x1b,0x20
0x1c,5 - DMASAddrX, страница

0x1d,0 - DMA Destination Address
0x1e,0
0x1f,0 - страница приёмника

0x26,255 - DMA Burst Length, 512 байт за один бурст
0x28,0 - DMANum, колво бурстов - 0 (это 1) штука.

0x27,0x84 - DMACtrl, здесь RAM (Src) is copied to CRAM (Dst)
насколько я понимаю, здесь перебрасывается палитра в память CRAM





ld hl,0x2000 ; палитра
ld de,0x0020 ; сдвиг по палитре
ld a,0x84 ; DMACtrl, здесь RAM (Src) is copied to CRAM (Dst)
exx
ex af,af'
ld bc,0x13af ; память со звуком
ld de,1 ; инкремент на 1 при воспроизведении
ei

sloop0:
; здесь происходит вывод звука в ковокс в основном цикле

ld a,MW_SND_PAGE
jp sloop3
snewpg: ld a,(sndpage)
sloop3: out (c),a
inc a
ld (sndpage),a
ld hl,0xc000

sloop1: ld a,(hl)
or a
jr z,sloop0
out (0xfb),a
add hl,de
jp c,snewpg
ld a,MW_SND_DELAY ; задержка при воспроизведении
sdly: dec a
jr nz,sdly
jp sloop1


; непосредственно инт, меняющий палитру

mw_int: ex af,af'
exx
add hl,de ; добавили #20
res 1,h ; больше #2200 адрес не увеличится
ld b,0x1a ;DMA Source Address младший байт
out (c),l
ld b,0x1b; DMA Source Address старший байт
out (c),h
ld b,0x27 ; выполнение DMACtrl
out (c),a
exx
ex af,af'
ei
ret
; всё, палитра сдвинулась, на экране красота)

sndpage:defb 0

mwset: defb 0x20,6
defb 0x00,0xc2
defb 0x01,MW_PIC_PAGE
defb 0x02,0
defb 0x03,0
defb 0x04,0
defb 0x05,0
defb 0x1a,0x00
defb 0x1b,0x20
defb 0x1c,5
defb 0x1d,0
defb 0x1e,0
defb 0x1f,0
defb 0x26,255
defb 0x28,0
defb 0x27,0x84
mwset_end:



что имеем выполняемого?
для эффекта: три аута в порты по прерыванию,

для звука - простой вывод в ковокс:


ld a,(hl)
or a
jr z,sloop0
out (0xfb),a
add hl,de
jp c,snewpg
ld a,MW_SND_DELAY ; задержка при воспроизведении
sdly: dec a
jr nz,sdly


Просто?


Описание работы эффекта от автора - DDp


Все данные уже подготовлены в нужном формате
и загружаются в загрузчиком SPG в заданные страницы памяти.
Программу можно разделить на две части:
подготовка(инициализация) и собственно эффект.
При инициализации устанавливается видео режим,
предустанавливается регистры DMA (делается
первая пересылка - запись в палитру) и др.
Перед запуском эффекта в следующих регистрах установлены значения:
DE = 0001
BC = 13AF
A'= 84
HL'= 2000
DE'= 0020
C'= AF
Основной цикл использует "первый" набор регистров,
а обработчик прерывания "второй".

Основной цикл программно проигрывает звук на covox.
В обработчике прерывания посредством DMA устанавливается новая,
циклически сдвинутая, палитра (пересылка "из RAM в ПАЛИТРУ").

;------------------------------------------------------------------------------
sloop0:
ld a,MW_SND_PAGE ;номер начальной страницы памяти со звуком
jp sloop3

snewpg: ld a,(sndpage)

sloop3: out (c),a ;установка страницы памяти в окне "С000"
inc a
ld (sndpage),a ;номер следующей страницы сохранить
ld hl,0xc000 ;HL - указатель

sloop1: ld a,(hl) ;читаем значение семпла из памяти
or a ;конец звука? (см. примечания)
jr z,sloop0 ; да - играем с начала
out (0xfb),a ;вывод семпла звука в порт covox-а
add hl,de ;HL+1 - инкремент адреса
jp c,snewpg ;конец страницы? да - включить следующую

ld a,MW_SND_DELAY ;задержка между семплами
sdly: dec a ; (подобрано значение для скорости
jr nz,sdly ; примерно 44100 семплов в секунду)

jp sloop1

;------------------------------------------------------------------------------
;кадровое прерывание
mw_int: ex af,af' ;переключаемся на "второй"
exx ;набор регистров

;в HL указатель на значения палитры в памяти
add hl,de ;HL+32 - коррекция указателя
res 1,h ;ограничивает перемещение указателя в пределах 512 байт
ld b,0x1a ;"DMA Source Address" - LOW
out (c),l
ld b,0x1b ;"DMA Source Address" - HIGH
out (c),h
ld b,0x27 ;"DMA Control / Start"
out (c),a ;0x84 - запуск DMA в режиме "из RAM в ПАЛИТРУ"

exx ;переключаемся на "первый"
ex af,af' ;набор регистров

ei
ret
;------------------------------------------------------------------------------

Примечание по звуку. Данные звука - PCM unsigned 8bit.
Отфильтрованы значения 0x00 и заменены на 0x01.
Значение 0x00 используется как флаг "конец звука".


Думаю, вполне можно уместить эффект в 256 байт,
если картинку и палитру сгенерировать программно.


"Гипножаба" работает похожим образом:
основной цикл программно проигрывает звук на covox,
а в обработчике прерывания посредством DMA обновляется
часть экрана размером 112x48 пикселей
(пересылка "из RAM в RAM_с_Выравниванием_512").
http://rghost.ru/55036812/image.png

Blade
04.05.2014, 17:08
0x28,0 - DMANum, колво бурстов - 256 штук, это странно, но так есть. 128кб получается.

Не 256, а 1.

Hacker VBI
07.05.2014, 22:58
Пример с фреймовыми\строчными интами не хочешь покурить для тренировки?

line-ints.zip (https://www.dropbox.com/s/tv6z3kurro3lyyr/line-ints.zip)
скрин эффекта - внизу

Итак, что имеем в эффекте:
все строки изображения плавно перемещаются в горизонтальной плоскости по синусу.
за прерывание :v2_dizzy_coder:
изображение - 320х200, 16 цветов

некоторые части кода, связанные с синусом я пока не затрагиваю, интересен именно механизм прерываний.
Buyan обьяснит свой прикольный эффект немного позже и гораздо доступней, чем я сейчас ;)

Начнём. Сначала - уже знакомая по этой теме предварительная фаза: установка разрешения/цветности, скорости/кеша, выбор палитры, инициализация позиций окна вывода экрана, указание на место экрана в памяти.
здесь можно отметить две интересные подпрограммы - очистка экрана с помощью дма, и с его-же помощью перемещение графики на экран.




device ZXSPECTRUM128
include dev\ts-ports.asm
org #8000

start di
ld sp,49151

ld a,128
call clear_vpage
call gfx_copy
call init_gfx
call init_zx_pal
call init_im2
ei
stop jp stop

init_gfx ld bc,VConfig
ld a,%10000001
out (c),a

ld bc,SysConfig
ld a,%00000111
out (c),a

ld bc,PalSel
ld a,%00000000
out (c),a

ld hl,0
ld bc,GYOffsL
out (c),l
ld bc,GYOffsH
out (c),h
ld bc,GXOffsL
out (c),l
ld bc,GXOffsH
out (c),h

ld bc,VPage
ld a,128
out (c),a

ret



итак, инициализация прерывания.
читаем мануал: (http://forum.tslabs.info/viewtopic.php?f=35&t=157)
"...В TS-Conf можно запрограммировать несколько источников маскируемого прерывания. Среди них:
- кадровый (frame, индекс 0),
- строчный (line, индекс 1),
- окончание DMA транзакции (dma, индекс 2).

Источник frame срабатывает, когда значение счетчиков растра совпадает с регистрами HSINT и VSINT. Источник line срабатывает в каждой строке, когда горизонтальный счетчик растра равен 0. Источник dma срабатывает после окончания любой транзакции DMA.
Каждый источник прерывания формирует сигнал ~INT и выставляет собственный байт D[7:0] на ШД в цикле ~IORQ || ~M1.
- $FF - кадровый,
- $FD - строчный,
- $FB - DMA."

здесь можно отметить установку горизонтального HSINT и вертикального VSINT прерывания (INT) в ноль - начало отрисовки экрана. замечаем, что адрес обработчика прерывания записывается в адрес #beff, что говорит о фреймовом вызове. ну типа каждый кадр. как обычно, в общем :)
после разрешения, и как начинаем отрисовывать экран с абсолютного 0,0 - происходит прерывание im_blank.



init_im2 ld a,#be
ld i,a
ld hl,im_blank
ld (#beff),hl

ld bc,HSINT
ld a,0
out (c),a

ld hl,0
ld bc,VSINTL
out (c),l
ld bc,VSINTH
out (c),h

im 2
ret

init_zx_pal ld a,%00010000 ; маппинг на #0000 ; 0 - ZX palette
ld bc,FMAddr
out (c),a
ld hl,zx_palette
ld de,0
ld bc,32
ldir
xor a
ld bc,FMAddr
out (c),a
ret
zx_palette include "dev\zx_palette.asm"


im_blank di
push af
ex af,af
push af
push hl
push de
push bc
push ix
push iy
exx
push hl
push bc
push de

ld hl,30+24
ld bc,VSINTL
out (c),l
ld bc,VSINTH
out (c),h
ld hl,im_blank_off
ld (#beff),hl
ld de,(roll_beg)
ld (roll),de
inc de
ld a,d
and %00000001
ld d,a
ld (roll_beg),de
pop de
pop bc
pop hl
exx
pop iy
pop ix
pop bc
pop de
pop hl
pop af
ex af,af
pop af
ei
ret

frame_counter defw 0
flag defb 0
roll_beg defw 0



по приходу im_blank в строчный регистр интов VSINT устанавливаются значения нового обработчика фреймовых прерываний,
которые будут вызваны по началу отрисовки строки 30+24 (54).
другими словами, пропуск отрисовки линий, ибо пока малюется бордюр.

следующий инт приходит на 54 строке экрана, и попадает в im_blank_off




im_blank_off di
push af
push hl
push de
push bc
ld hl,31+24+240
ld bc,VSINTL
out (c),l
ld bc,VSINTH
out (c),h
ld hl,im_blank_on
ld (#beff),hl
ld bc,INTMask
ld a,%00000011
out (c),a
ld hl,line_proc
ld (#befd),hl
pop bc
pop de
pop hl
pop af
ei
ret


указываем, что следующее прерывание должно возникнуть на строке 31+24+240 - а это у нас конец экрана и начало бордюра, и вызывать im_blank_on для фреймового int.
Разрешаем строчный инт - по строкам будет приходить прерывание на line_proc. Отмечаем, что строчный инт у нас пишется по #befd

RTFM: "Регистр конфигурации INTMask содержит биты разрешения индивидуального источника маскируемого прерывания, 0 - запрещен / 1 - разрешен.
бит 0, FRAME - разрешение источника frame,
бит 1, LINE - разрешение источника line,
бит 2, DMA - разрешение источника dma,
биты 3-7 - не используются, записывать 0."





im_blank_on di
push af
push hl
push de
push bc
ld hl,0
ld bc,VSINTL
out (c),l
ld bc,VSINTH
out (c),h
ld hl,im_blank
ld (#beff),hl
ld bc,INTMask
ld a,%00000001
out (c),a
pop bc
pop de
pop hl
pop af
ei
ret



следующее прерывание пришло на im_blank_on. указываем приход нового фреймового с позиции 0 (новый кадр), вырубаем строчные инты - пропуск бордюра. и опять по кругу.

что же делают здесь строчные инты? КАЧАЮТ девочек :)

line_proc отрабатывает с позиции VSINT от 54 до 295 (область экрана) и бросает в порт GXOffs ("X-offset for graphics") сдвиг по х для текущей строки, взятой из текущего положения переменной roll, + sines_tab (которая указывают на таблицу синусов):




line_proc di
push af
push hl
push de
push bc
ld de,(roll)
sin_tb ld hl,sines_tab
add hl,de

inc de
ld a,d
and %00000001
ld d,a
ld (roll),de
ld a,(hl)
ld bc,GXOffsL
out (c),a
pop bc
pop de
pop hl
pop af
ei
ret
roll defw 0
sines_tab include "\dev\sineline.asm"



дма очистка и ldir на экран:



clear_vpage push af
ld bc,Page0
ld a,33
out (c),a
ld hl,0
ld (0),hl
ld bc,DMASAddrX
ld a,33
out (c),a
ld hl,0
ld bc,DMASAddrH
out (c),h
ld bc,DMASAddrL
out (c),l
ld bc,DMADAddrX
pop af
out (c),a
ld hl,0
ld bc,DMADAddrH
out (c),h
ld bc,DMADAddrL
out (c),l

ld bc,DMALen
ld a,255
out (c),a

ld bc,DMANum
ld a,255
out (c),a

ld bc,DMACtrl
ld a,%00000100
out (c),a

ld bc,DMAStatus
c1rl1 in a,(c)
or a
jr nz,c1rl1
ret




gfx_copy ld bc,DMASAddrX
ld a,100
out (c),a
ld hl,0
ld bc,DMASAddrH
out (c),h
ld bc,DMASAddrL
out (c),l
ld bc,DMADAddrX
ld a,128
out (c),a
ld hl,0
ld bc,DMADAddrH
out (c),h
ld bc,DMADAddrL
out (c),l

ld bc,DMALen
ld a,160/2-1
out (c),a

ld bc,DMANum
ld a,240-1
out (c),a

ld bc,DMACtrl
ld a,%00010001
out (c),a

ld bc,DMAStatus
s1cp1rl in a,(c)
or a
jr nz,s1cp1rl
ret
endcode nop
SAVEBIN "1-spg\line-ints.bin",start, endcode-start



Другими словами, за один отрисованный экран было вызвано 3 фреймовых и -надцать строчных прерывания.

аминь :v2_dizzy_priest:

А вот слова автора эффекта, господина Buyan, который любезно предоставил исходники для разбора, ознакомления и изучения принципа работы системы прерываний:

"Такс.. Для начала по растру - у нас в кадре 320 строк. Это размеры видеосигнала с учетом всех бланков, синхр и тд, а не видимой части изображения. Видимых из них соответственно 288 (при максимальном разрешении). Т.е. строки 0-31 на экране мы не видим никогда. Остальные отображаются. Но как они отображаются (т.е. что там отображается - бордер или графика уже зависит от включенного разрешения. Т.е. при 360х288 все строки отображают графику, при 320х240 соответственно 240 строк графику, а остаточные строки сверху и снизу уйдут на бордер.

Теперь по интам: тут у нас есть фреймовый и строчный. Фреймовый инт приходит 1 раз в кадре (при условии что мы по ходу кадра его не перепрограммируем на другую позицию по ходу луча. Строчные же инты после включения будут срабатывать в начале каждой строки, т.е. до 320 раз за фрейм. Отсюда и пляшем:

В данном случае т.к. разрешение выбрано 320х240 нам нужно обработать соответственно 240 строк, ибо качать строки которые на экране не отображаются смысла нет. Для этого и используется несколько обработчиков инта последовательно:

Изначально у нас фреймовый инт настроен на 0 строку. Поехали:

im_blank - пришло прерывание в начале кадра. Тут проинитили синусоиду для качения, ну и как обычно на спеке музычку можно проиграть и т.д. Далее чтобы проц не дергать и невидимые строки не дрюкать переставляем фреймовый инт на im_blank_off - на 30 (неотображаемых) + 24 (бордер) т.е. попадем за 2 строки до начала отображаемых.

im_blank_off - вот мы уже на 30+24 строке и нам пора начать обрабатывать видимые 240 строк строчным интом. Но как нам оганичиться 240 строками если строчные инты долбят по всему диапазону строк? Просто: переставляем фреймовый инт на конец отображения наших 240 строк, т.е. на im_blank_on, который придет в 32(невидимые)+24(бордер)+240 наших качаемых строк и вырубит строчные инты. Переставили. Включаем строчные инты (line_proc)

line_proc вызывается в каждой следующей строке и изменяет ее смещение. Проходит 240 строк и тут срабатывает опять фреймовый инт, который мы перенастроили перед этим:

im_blank_on отрубаем строчный инт и перенастраиваем фреймовый на первый обработчик и начало следующего кадра. Зе енд."

:v2_dizzy_rastoman:

TSL
08.05.2014, 04:57
А как обстоят дела с этой платформой у буржуев? Сколько вообще железа её поддерживает?
Все экземпляры Евы (вопреки тому, что трындит рупор), при условии прошивания сабжа в оные.
Медленно но верно портируется на Реверс U8, медленно потому что не в лоб, а допиливается, а процесс этот небыстрый. Потом портируем на U16, возможно на другие клоны. Например, она могла бы работать с некоторыми ограничениями v6z80p, если найдется смельчак, чтоб перетащить ее на Xilinx.

Hacker VBI
08.05.2014, 22:32
в пост MindWarp от DDp (http://zx.pk.ru/showpost.php?p=708479&postcount=22) добавил описание работы эффекта от автора.
Спасибо ему :)

denpopov
02.06.2014, 12:42
Есть такой прием, который называется "дрочка инта".
А как будет рендериться экран, если меняется вертикальное или горизонтальное положение тайлов?

jerri
02.06.2014, 12:54
denpopov, ты на сеге игры видел? :)
так же и будет
там каждую линию данные берутся

denpopov
02.06.2014, 13:05
denpopov, ты на сеге игры видел?
нет

Hacker VBI
02.06.2014, 13:11
denpopov, как будет рендериться экран, если меняется вертикальное или горизонтальное положение тайлов ты можешь увидеть в инвитре, там такого море.
в моей части с синими шарами меняется положение тайлов на экране по синусу, всех сразу - и норм

насчёт "дрочка инта" :) в сонике за фрейм вызывается два инта, соответственно два хальта стоит) один инт - начало экрана, красный бордюр, второй инт - средина, белый.
всё

denpopov
02.06.2014, 14:01
то есть, выходит, что линия рендерится в зависимости от параметров?

Hacker VBI
02.06.2014, 14:30
denpopov, рендерится каждая строка
и складывается графика/тайлы/спрайты

denpopov
02.06.2014, 14:31
а есть где пример спрайтов?

Hacker VBI
02.06.2014, 14:44
скролл из последней части, спрайтовый
суть такая - спрайты постоянно меняют позицию по Х, от 0 до 31, влево. как попали на позицию 0 - передвигаем адреса указателей на буквы скролла в дескрипторе спрайтов. всё)




SFileAddr EQU 512

ld ix,spr_db+12
ld b,font_quant ; кол-во букв (спрайтов) на экране
ld hl,0 ; x
fq1 push bc
xor a
ld (ix+0),a ;y
ld (ix+4),a
ld a,%11100000 ; palitra !!!!!!!!!!!!!!!!!!!
ld (ix+5),a

ld a,%00110100 ; 1
ld (ix+1),a

ld (ix+2),l
ld a,%00010110
or h
ld (ix+3),a
ld bc,#20 ; ширина буквы - 32 точки
add hl,bc
ld c,6 ; 6 байт на описание спрайта
add ix,bc
pop bc
djnz fq1
push ix ; завершаем формирование добавлением блока с концом отрисовки, бит leap
pop de
ld hl,spr_final
ld c,6
ldir
jp spr_out

spr_final DB 0
DB %01000000
DB 0
DB %00010000
DB 0
DB %11100000


fill_text
; сдвиг текста, положение графики букв в наборе спрайтов
; передвигаем адреса указателей на буквы скролла в дескрипторе спрайтов
ld ix,spr_db+18+4
ld hl,spr_db+12+4
ld b,12
ftroll1 push bc
ld a,(ix+0)
ld (hl),a
inc hl
ld a,(ix+1)
ld (hl),a
dec hl
ld bc,6
add ix,bc
add hl,bc
pop bc
djnz ftroll1

fill_text_adr ld hl,text
ld a,(hl)
or a
jr nz,text_fill1
ld hl,text
ld a,(hl)
text_fill1 inc hl
ld (fill_text_adr+1),hl
sub #20
add a,a
ld l,a
ld h,high font_db ; получаем адрес буквы в графике
ld de,spr_db+6*12+4 ; ставим в дескриптор адрес новой буквы
ld a,(hl)
ld (de),a
inc l
inc e
ld a,(hl)
or %11100000 ; palitra !!!!!!!!!!!!!!!!!!!
ld (de),a

spr_out
LD BC,FMAddr
LD A,%00010000
OUT (C),A
LD HL,spr_db
LD DE,SFileAddr
LD BC,6*font_quant ; закидываем в память фпга
LDIR
LD BC,FMAddr
XOR A
OUT (C),A
ret

org #ba00
spr_db
DB 0
DB %01000000 ; leap
DB 0
DB %00010000
DB 0
DB %11100000

DB 0
DB %01000000 ; leap to2
DB 0
DB %00010000
DB 0
DB %11100000



спрашивай

TSL
02.06.2014, 15:05
denpopov, ты на сеге игры видел? :)
так же и будет
там каждую линию данные берутся
Не так.
Ряд тайлов (8 линий) читает в течение 8 строк. Поэтому для тайловых слоев дергать можно только горизонтальные скролки. Дергание вертикальных ни к чему хорошему не приведет.

denpopov
02.06.2014, 15:38
Дергание вертикальных ни к чему хорошему не приведет.
что, совсем?

Hacker VBI
02.06.2014, 15:43
denpopov, смотря когда дёргать. в момент отрисовки - зло.

denpopov
02.06.2014, 16:23
нууууууууууууууу. это несерьезно.
то блиттер работает через задницу, то тайлы 8 высотой...:(

Hacker VBI
02.06.2014, 16:30
вот ты интересный.
тайлы - от 8 до 64, как и спрайты.
блиттер валит что надо.

может с руками что-то? ;)

TSL
02.06.2014, 17:59
Не совсем, но режим скаам так андокументированный. Прэдполагалось что для вертикальных знакоместных столбцов должен быть массив скрололо (как на этих ихних сегах), но оно то ли не влезло, то ли показалось ненужным. Поэтому вертикальную скролку для тайлов лучше дергать 1 раз на фрейм, причем минимум за 16 линий до первой линии тайлов.

denpopov
02.06.2014, 18:03
чота я непонел - 8 пикселей на тайлы, и на одну линию дернуть нельзя?
ну или на 1-7..

TSL
02.06.2014, 18:12
Дернуть то зя, но нельзя этого делать ВНУТРИ фрейма. Только в начале. И желательно 1 раз.

denpopov
02.06.2014, 18:16
Дернуть то зя, но нельзя этого делать ВНУТРИ фрейма. Только в начале. И желательно 1 раз.
надеюсь, что получая квартиры, ты более красноречив.

Hacker VBI
02.06.2014, 18:18
denpopov, пришло прерывание - указал все позиции.
а потом уже всё передаёшь/считаешь и т.д.

на ещё крапаль:


loop halt
ld hl,(char_sin1+1)
ld a,l
add #20
ld l,a
ld l,(hl)
ld h,high sin_tiles
ld a,(hl)
ld bc,T0XOFFSL
out (c),a
ld a,l
add #60
ld l,a
ld a,(hl)
sub #0e
ld bc,T0YOFFSL
out (c),a
jr loop

TSL
02.06.2014, 18:19
надеюсь, что получая квартиры, ты более красноречив.
Странно, ваш стиль общения очень напоминает некоего g0blinish-а. Вы случайно не знакомы?

denpopov
02.06.2014, 18:21
Вы случайно не знакомы?

Кэп намекает, что да.
ЧТО ТАКОЕ внутри ФРЕЙМА?

TSL
02.06.2014, 18:33
Фрейм - один кадр телевизионной развертки.
Начало фрейма соответствует началу первой строки кадрового гасящего импульса (http://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D0%B4%D1%80%D0%BE%D0%B2%D1%8B%D0%B9_% D0%B3%D0%B0%D1%81%D1%8F%D1%89%D0%B8%D0%B9_%D0%B8%D 0%BC%D0%BF%D1%83%D0%BB%D1%8C%D1%81). Всего строк КГИ - 32. За это время видеоконтроллер ничего не показывает, и есть время на программирование его параметров. Например, за это время можно перебросить готовые дескрипторы спрайтов (и только потом пересчитывать новые значения для следущего фрейма, а не наоборот), перекинуть палитру (опять же рассчитанную заранее) и т.д.
Если используется вертикальная скроллка для тайловых плоскостей, то ее значение нужно записать в порты именно в этот момент. И не менять в течении кадра (=фрейма).
Могу объяснить почему, но лучше не заморачиваться с деталями.

---------- Post added at 17:33 ---------- Previous post was at 17:29 ----------



тайлы - от 8 до 64, как и спрайты.

А это как? ))

denpopov
02.06.2014, 18:34
Могу объяснить почему, но лучше не заморачиваться с деталями.
ну вот гоблин твистер написал, и по горизонтали все работает. мне интересно, пойдет ли такой же принцип за фрейм, если менять вертикальное смещение?


перекинуть палитру (опять же рассчитанную заранее) и т.д.
значит, во время обработки прерывания палитру менять нельзя?

Hacker VBI
02.06.2014, 18:40
TSL, ну, люди говорят, что
"Спрайт - Набор из расположенных рядом тайлов. Размер задается произвольно в диапазоне 1-8 тайлов (8-64 пикселей) независимо для высоты и ширины."
:)

denpopov, вертикальное смещение ты можешь менять для всего экрана, строчное - раз в строку. что произойдёт если менять его в строке предположить -мне- сложно, но можно предполагать глитчи.

во время обработки прерывания палитру менять нельзя - зя, попробуй, увидишь

всё зя, просто могут быть "неожиданные" эффекты))

TSL
02.06.2014, 19:07
значит, во время обработки прерывания палитру менять нельзя?
Можно.

ну вот гоблин твистер написал, и по горизонтали все работает. мне интересно, пойдет ли такой же принцип за фрейм, если менять вертикальное смещение?
Передай гоблину что твистер дергается и сечется с лучом и принцип не идет ни по вертикальному смещению ни за фрейм.


строчное - раз в строку. что произойдёт если менять его в строке предположить -мне- сложно, но можно предполагать глитчи.

Ничего не произойдет. Чтоб не з80 не гнаться за лучом, некоторые регистры видеопроца стробируются на начало строки. Иначе бы ты увидел глитчи уже сейчас. Зетник с очень высокой вероятностью в строчных интах не успевает что либо поменять ДО пикселей.

denpopov
02.06.2014, 19:14
Передай гоблину что твистер дергается и сечется с лучом и принцип не идет ни по вертикальному смещению ни за фрейм.

на реале или нет?

TSL
02.06.2014, 19:16
Везде.

Kakos_nonos
02.06.2014, 19:17
Слишком всё у вас сложно, в Апогее проще.

denpopov
02.06.2014, 19:21
Везде.
проглядели)

---------- Post added at 19:21 ---------- Previous post was at 19:21 ----------


Слишком всё у вас сложно, в Апогее проще.

Да и на других железках выходит тоже..

Hacker VBI
02.06.2014, 20:13
Kakos_nonos, сам апогей простой. Нет подобной обвязки, управлять особо нечем. Ви53 и привет:)
А чтоб прям сложно - нет, порог вхождения, имхо, не высокий. Другая философия программирования, с использованием железа - это да, поначалу непривычно, потом начинаешь офигевать от того, что с этим всем можно сделать.
Приятно то, что пока ты считаешь свое - железо занято своими задачами:)

denpopov
03.06.2014, 12:02
получился эффект, но работает он тормозно, если нажать NumLock, то выходит побыстрее. а можно сделать программно? никак не вспомню, где и как это включается..

Hacker VBI
03.06.2014, 12:08
denpopov, включи кеш и 14мгц.
defb #20af ,6 ; SYSCONFIG

вот небольшая дока (https://github.com/earl1k/ts-doc)

Hacker VBI
14.07.2014, 09:52
В архив Rubicon (http://www.pouet.net/prod.php?which=63737) входит исходник демы + расписание памяти для спг билдера
пользуйтесь :)

исходник местами корявый)

хех. начало темы - 02.05.2014. два месяца...

denpopov
14.07.2014, 10:02
а я все жду, когда ты про палитру опишешь:)

Hacker VBI
14.07.2014, 10:30
denpopov, а чо именно описывать (http://tslabs.info/forum/viewtopic.php?f=35&t=157)?

denpopov
14.07.2014, 11:06
denpopov, а чо именно описывать?

а, ну ты знаешь. просто меня удивило твое упоминание о конвертере TGA.

Hacker VBI
14.07.2014, 11:13
denpopov, я не парюсь, всё конверчу :)

denpopov
14.07.2014, 11:15
denpopov, я не парюсь, всё конверчу

а все трюки с палитрами ты игнорируешь?

TSL
14.07.2014, 11:27
Конвертор экстрагирует палитру в отдельный фаел.

denpopov
14.07.2014, 11:30
Конвертор экстрагирует палитру в отдельный фаел.

ну.. с другой стороны psb на Питоне тулзу написал.
просто интересно - верно ли предложение Amixgris'ом:
данные RGB считаются как R/10, G/10, B/10.
?

Hacker VBI
14.07.2014, 11:33
denpopov, трюки с палитрой в самом начале, там где солнце
вообще - есть исходники в паке

TSL
14.07.2014, 11:47
просто интересно - верно ли предложение Amixgris'ом:
данные RGB считаются как R/10, G/10, B/10.
?
Ну +- верно.
В сумме, нужно сделать преобразование 0-255 в 0-24.
А в моем конвертере вообще есть табличка, юзер сам может задавать гамму.

Sergey
14.07.2014, 12:07
Ну +- верно.
Верно-верно, - как учили. ;)

А в моем конвертере вообще есть табличка, юзер сам может задавать гамму.
Есть математическая формула выбора из заданной ограниченной палитры цветов, которые наиболее схожи с оригинальными с точки зрения физиологии человеческого цветовосприятия. Я не жадный, могу поделиться исходником, если нужно. Только результат, вряд ли будет заметно отличаться от простого деления.

denpopov
04.08.2014, 08:31
Граждане, кто в теме:

Нужна строчка для spgbuild, чтобы код поместился с адреса $6000, другие странички не нужны.

; Blocks description: address (512 multiple, #C000-#FE00), page number, filename
Block = #6000,200,myprog.bin

EARL
04.08.2014, 13:00
Вот так будет нужный адрес.
Block = #D000,2,myprog.bin

denpopov
04.08.2014, 13:13
мне сказали, что 5 а не 2.

Теперь еще интереснее - программа не работает до полного сброса в Unreal'e, т.е. атрибуты не отображаются полностью.

Загадка однако...

TSL
04.08.2014, 13:51
Block = #6000,200,myprog.bin
Block = #E000,5,myprog.bin

---------- Post added at 12:51 ---------- Previous post was at 12:50 ----------


Теперь еще интереснее - программа не работает до полного сброса в Unreal'e
Необходимо инициализировать все регистры железа, не рассчитывать, что это сделает сброс, биос или коммандер!

denpopov
19.08.2014, 17:24
А есть ли осмысленный пример спрайтов?
Ссылка на шарики r0bata'a не катит.

SAM style
19.08.2014, 17:37
А есть ли осмысленный пример спрайтов?
Ссылка на шарики r0bata'a не катит.Вот то, что я когда-то сделал для теста. Карта тайлами, человеки спрайтами. Управляемо - QAOP.

denpopov
19.08.2014, 17:38
Вот то, что я когда-то сделал для теста.
исходники зажал, значит?

SAM style
19.08.2014, 17:44
исходники зажал, значит?
Добавил. Делал почти год назад, мог что-то забыть. sjasm+ у себя где-нибудь откопаешь. Палитру и тайлы-спрайты создавал наколеняхнаписанным редактором.

denpopov
19.08.2014, 18:43
Да, понятно пока что мало. Буду пробовать разбираться..