User Tag List

Показано с 1 по 10 из 77

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

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #11

    Регистрация
    05.03.2013
    Адрес
    г. Канев, Украина
    Сообщений
    1,596
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    4
    Поблагодарили
    3 сообщений
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)

    Lightbulb line ints TSconf

    Пример с фреймовыми\строчными интами не хочешь покурить для тренировки?

    line-ints.zip
    скрин эффекта - внизу

    Итак, что имеем в эффекте:
    все строки изображения плавно перемещаются в горизонтальной плоскости по синусу.
    за прерывание
    изображение - 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
    [свернуть]


    итак, инициализация прерывания.
    читаем мануал:
    "...В 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 фреймовых и -надцать строчных прерывания.

    аминь

    А вот слова автора эффекта, господина 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 отрубаем строчный инт и перенастраиваем фреймовый на первый обработчик и начало следующего кадра. Зе енд."

    Миниатюры Миниатюры Нажмите на изображение для увеличения. 

Название:	ints.gif 
Просмотров:	262 
Размер:	14.8 Кб 
ID:	47827  

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Акселераторы для amiga600
    от easy_john в разделе Amiga
    Ответов: 133
    Последнее: 25.07.2014, 10:11

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •