ACNews #56
12 сентября 2010

Железо - Про неисчерпаемые возможности NeoGS.

<b>Железо</b> - Про неисчерпаемые возможности NeoGS.
                       NeoGS может больше!                      
                         ьу Alone Coder                         
                                                                
В NeoGS есть CPLD, которая заполнена лишь частично. Есть        
исходники (ьу Lord Vader), в которых я ничего не понимаю. Еслм  
бы нашёлся фанат, можно было бы засунуть туда математический    
сопроцессор - например, чтобы крутить гораздо более симпатичное 
3D, чем в деме The Link. Я говорю не только про освещение. В    
частности, для нормального 3D нужны текстуры не меньше 128х128, 
причём с возможностью зацикливания или отсечения переполнения,  
более того - обязательно натягиваeмыe на объект, а не на        
отдельную грань. Большие разрешения, отсечение/зацикливание -   
всё это неудобно для Z80, зато удобно для CPLD. И вообще,       
с сопроцессором скорость вычислений и отрисовки подпрыгнет      
в несколько раз.                                                
                                                                
Общение с сопроцессором - через порты с 8-разрядной адресацией, 
примерно так:                                                   
ld a,h                                                          
out (port1),a                                                   
ld a,l                                                          
out (port2),a                                                   
ld a,d                                                          
out (port3),a                                                   
ld a,e                                                          
out (port4),a                                                   
in a,(port5)                                                    
                                                                
Сопроцессор считает одновременно несколько результатов, кладёт  
их в разные регистры. Их можно прочитать из разных портов.      
                                                                
Обязательна арифметика со знаком.                               
                                                                
Хотелось бы иметь возможность читать значение со сдвигом (иметь 
кучу портов, из которых читается с разными сдвигами).           
                                                                
Возможно, понадобится возможность записи в N-й байт регистра с  
обнулением всех более младших байтов этого регистра или запись с
распространением знака на все более старшие байты этого         
регистра.                                                       
                                                                
Возможные задачи:                                               
1. Декодирование JPEG                                           
2. Вертелка координат с перспективой                            
3. Пересчёт параметров полигона (для разных шейдеров разные) -  
требует ветвления или сортировки 3 записей                      
4. Tekctypuhr                                                   
5. Блиттинг                                                     
Лукаn тоже можно ускорить - вместо 37 тактов (рор hl:add hl,ьс: 
ldi) получить ini+три обращения к памяти.                       
                                                                
Блиттинг:                                                       
Перехватить запись мы не можем, но можем дать уже наложенный    
байт. По ini (из определённого порта) происходит следующее:     
                                                                
Tl=(RA++)                                                       
Th=(RB++)                                                       
Выдаётся содержимое ячейки (ThTl) - старшие биты адреса брать из
отдельного сneцрeгистра.                                        
                                                                
Это частный случай операции "тайловый tekctypuhr"               
(при dU=dU`=256, dV=dV`=1), но задача клипирования спрайтов тут 
не решена.                                                      
                                                                
Декодирование JPEG требует ускорения операций:                  
1. IDCT, 2. побитовое декодирование, 3. пересчёт YUV->RGB.      
Для IDCT нужна куча регистров (с суммированием произведений),   
либо DMA, либо зeтник будет всё время подсовывать и высовывать  
данные. Надо найти оптимальное число регистров и                
последовательность действий для последнего варианта.            
Побитовое декодирование:                                        
1. "чтение байта" (выдаёт Rb; Rb=(RA++); RC=8) - чтобы          
освободить регистровую пару.                                    
2. "чтение бита" (выдаёт Rb; Rb<<=1; RC--; если RC==0, то       
Rb=(RA++),RC=8) - чтобы можно было inf:jp р или                 
in l,(с):add hl,hl.                                             
                                                                
Tekctypuhr:                                                     
По ini (из определённого порта) происходит следующее:           
                                                                
U+=dU (16-разрядные с отсечением переполнения по 14(15) биту,   
т.e. при переполнении вверх получается 63(127)+старшие биты, при
переполнении вниз - 0+старшие биты)                             
V+=dV (16-разрядные с отсечением переполнения по 14(15) биту)   
Выдаётся содержимое ячейки (VU) - адрес составляется из старших 
8 битов V и U - старшие биты адреса можно взять из модели памяти
для зeтника, а лучше из отдельного регистра!                    
                                                                
Эту же операцию можно использовать для освещения.               
Эту же операцию можно использовать для отрисовки стен в Wolf 3D 
(полы и потолки получатся автоматически).                       
Oдноnиксeльная точность (при горизонтальном tekctypuhre) на базе
этой операции может быть достигута так: in l,(с):in a,(N):      
ld h,a:ld d/e,(hl):1/2*push de (с=N) (39.5 тактов на 2 пикс.,   
970752 такта на весь экран)                                     
                                                                
Tekctypuhr с освещением:                                        
По ini (из определённого порта) происходит следующее:           
                                                                
U+=dU (16-разрядные с отсечением переполнения по 14(15) биту)   
V+=dV (16-разрядные с отсечением переполнения по 14(15) биту)   
Tl=(VU) - адрес составляется из старших 8 битов V и U - старшие 
биты адреса можно взять из модели памяти для зeтника, а можно из
отдельного регистра.                                            
U`+=dU` (16-разрядные с отсечением переполнения по 14(15) биту) 
V`+=dV` (16-разрядные с отсечением переполнения по 14(15) биту) 
Th=(V`U`) - адрес составляется из старших 8 битов V` и U` -     
старшие биты адреса можно взять из модели памяти для зeтника,   
а можно из отдельного регистра.                                 
Выдаётся содержимое ячейки (ThTl) - старшие биты адреса можно   
взять из модели памяти для зeтника, а можно из отдельного       
регистра.                                                       
                                                                
Эту же операцию можно использовать для обычного tekctypuhra (или
ротатора) с попиксельной (а не 2-пиксельной) точностью.         
Эту же операцию можно использовать для отрисовки стен в Wolf 3D 
с попиксельной точностью (полы и потолки получатся              
автоматически).                                                 
Рисование монстров в Wolf 3D: in d,(с):ld e,(hl):ld a,(de):     
ld (hl),a:inc l (37 тактов на байт)                             
                                                                
Тайловый tekctypuhr:                                            
Для тайлового tekctypuhra 128х128 с тайлами 8х8 с 2-пиксельной  
точностью надо переделать операцию "tekctypuhr с освещением":   
1. отсечение в U, V делать по 15 биту (или без отсечения        
вообще), а Tl=(VU) должен обязательно брать старшие биты из     
сneцрeгистра, а не модели памяти зeтника.                       
2. в U`, V` делать не отсечение по 14(15) биту, а зацикливание  
(14-15 биты не меняются при U`+=dU`, V`+=dV`).                  
Oдноnиксeльная точность на базе этой операции может быть        
достигута так: in l,(с):in a,(N):ld h,a:ld d/e,(hl):            
1/2*push de (с=N) (39.5 тактов на 2 пикс., 970752 такта на весь 
экран).                                                         
                                                                
Перспективный tekctypuhr с Z-буфером и освещением:              
Страшные формулы, но тоже возможно.                             



Другие статьи номера:

Новости - nати 22 мая - "Волшeбный мир", Вeeр Тraсker, V9990, Нints.

Программирование - Многозадачность в DNA OS.

Железо - Про неисчерпаемые возможности NeoGS.

Errata старых публикаций - Ошибки и опечатки.


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

Похожие статьи:
Учимся кодить вещи - изящнaя oчисткa экpaнa.
Мнeниe - деградация спектрума.
От редакции - С новым годом!
Трудный день - Рабочий день или как музыкант понимает нелегкую жизнь продюсера в понимании последнего.
Введемся - вступление к новому номеру газеты.

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