Список форумов shedevr.org.ru shedevr.org.ru
Группа перевода приставочных игр "ШЕДЕВР"
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

Не хочет работать DMA в SEGA.

 
Начать новую тему   Ответить на тему    Список форумов shedevr.org.ru -> Ромхакинг в России и в мире
Предыдущая тема :: Следующая тема  
Автор Сообщение
IfoR



Зарегистрирован: 16.05.2006
Сообщения: 334

СообщениеДобавлено: Вт Янв 28, 2014 1:21 pm    Заголовок сообщения: Не хочет работать DMA в SEGA. Ответить с цитатой

Вот уж ерунда. Позавчера вечером вспомнил о уже забытой мною SEGA. Ну и подумал, нужно что ли позаниматься с этой архитектурой. Пролистал SEGA2.DOC, вроде бы всё более менее понятно на первый взгляд. Вроде как и архитектура довольно простая: периферийных устройств по пальцам левой руки пересчитать можно. Ну и... это писец...
Я засел на весь день и всю ночь только с ней. Попробовал чуть поуправлять процессором, компилируя код в EASy68k. Потом были часы компилирования GCC под M68000, настройки, составление скрипта линкера, startup файла, заголовочного файла с объявлением всех портов и регистров, хождения по многочисленным ресурсам интернета и исправления некоторых ошибок в SEGA2.DOC. Сегодня внедрил это всё в Eclipse и обработал всё напильником. И теперь у меня под рукой красивая среда для программирования на Си и Ассемблере под SEGA. Только что компилятора под Z80 не хватает. Smile Это, конечно, круто, но кошмар как обидно, когда после всего этого спотыкаешься на, вроде как, мелочи: я никак не могу завести DMA. Crying or Very sad
Пробовал сначала попробовать скопировать несколько полуслов из ПЗУ в VRAM - не пошло. Ладно, сделал задачу проще: заполнить какой-то участок VRAM какой нить константой - опять не то.

Вот что вообще есть:
Код:
#include "sega.h"

const short initVDPRegs[24] = {
      VDP_RegSet0,
      VDP_RegSet1   | VDP_Reg1V30CellMode | VDP_Reg1DMAEnable,
      VDP_RegSet2 | VDP_Reg2AddrScrollA(0),
      VDP_RegSet3 | VDP_Reg3AddrWindowH40(0),
      VDP_RegSet4 | VDP_Reg4AddrScrollB(0),
      VDP_RegSet5 | VDP_Reg5AddrSpriteH40(0),
      VDP_RegSet6,
      VDP_RegSet7 | VDP_Reg7Color(0) | VDP_Reg7Pallet(0),
      VDP_RegSet8,
      VDP_RegSet9,
      VDP_RegSet10 | VDP_Reg10HInterrupt(0xFF),
      VDP_RegSet11 | VDP_Reg11HFullScroll  | VDP_Reg11VFullScroll,
      VDP_RegSet12 | VDP_Reg12H40CellMode | VDP_Reg12NoInterlace,
      VDP_RegSet13 | VDP_Reg13AddrScrollA(0),
      VDP_RegSet14,
      VDP_RegSet15 | VDP_Reg15AutoIncData(1),
      VDP_RegSet16 | VDP_Reg16ScrollH32Cell | VDP_Reg16ScrollV32Cell,
      VDP_RegSet17 | VDP_Reg17HPositionLeft | VDP_Reg17HPosition(0),
      VDP_RegSet18 | VDP_Reg18VPositionUpper | VDP_Reg18VPosition(0),
      VDP_RegSet19 | VDP_Reg19DMALength(0x0500),
      VDP_RegSet20 | VDP_Reg20DMALength(0x0500),
      VDP_RegSet21 | VDP_Reg21DMASourceAddr(0),
      VDP_RegSet22 | VDP_Reg22DMASourceAddr(0),
      VDP_RegSet23 | VDP_Reg23DMASourceAddr(0) | VDP_Reg23VRAMFill
};

void __attribute__ ((interrupt)) VSync()
{ // Прерывание от вертикальной развёртки
  __asm("add.l #1, %d2");
};

void initVDP()
{
   // Устанавливаем регистры VDP
   unsigned char i;
   for (i = 0; i<24; i++) VDP_Control = initVDPRegs[i];

        // После установки регистров DMA включен и настроен на заполнение
       // Дальше следует указать адрес начала заполнения и чем заполнять
   VDP_ControlLong = VDP_AddressSetVRAMWrite | VDP_AddressSet(0);
   VDP_Data = 0xF0; // После этой операции DMA вроде как должен начать работать

        // Ждём завершения заполнения
   while (VDP_Control & VDP_ReadDMABusy);

        // Включаем экран
   VDP_Control = VDP_RegSet1 | VDP_Reg1DisplayEnable | VDP_Reg1V30CellMode;
       VDP_Control = VDP_RegSet15 | VDP_Reg15AutoIncData(2);

       // Просто как нить инициализируем палитру
   VDP_ControlLong = VDP_AddressSetCRAMWrite | VDP_AddressSet(0);
   VDP_Data = RGBtoColor(3,3,7);
   VDP_Data = RGBtoColor(0,0,3);
   VDP_Data = RGBtoColor(0,0,7);
   VDP_Data = RGBtoColor(0,3,0);
}

int main()
{
  initVDP();
 
  IntEnable;
  return 0;
}


Функция initVDP компилируется довольно дубово, но это сейчас и не важно (прошу прощения за формат констант):
Код:
 
20a:   4e56 0000         linkw %fp,#0

// Устанавливаем регистры VDP
 20e:   41f9 0000 02f0    lea 2f0 <initVDPRegs>,%a0
 214:   3018              movew %a0@+,%d0
 216:   33c0 00c0 0004    movew %d0,c00004 <VDP_Control>
 21c:   b1fc 0000 0320    cmpal #800,%a0
 222:   66f0              bnes 214 <initVDP>

// Отправляем адрес назначения
 224:   23fc 4000 0000    movel #1073741824,c00004 <VDP_Control>
 22a:   00c0 0004


// Отправляем содержимое заполнения
 22e:   33fc 00f0 00c0    movew #240,c00000 <VDP_Data>
 234:   0000

// Ждём завершения процесса, проверяя флаг занятости DMA.
// Однако здесь этот флаг постоянно сброшен, т.е. DMA не занят.
 236:   3039 00c0 0004    movew c00004 <VDP_Control>,%d0
 23c:   0800 0001         btst #1,%d0
 240:   66f4              bnes 236 <initVDP>

// Включаем дисплей и ставим автоинкриминирование на 2
 242:   33fc 814c 00c0    movew #-32436,c00004 <VDP_Control>
 248:   0004
 24a:   33fc 8f02 00c0    movew #-28926,c00004 <VDP_Control>
 250:   0004

// Устанавливаем палитру
 252:   23fc c000 0000    movel #-1073741824,c00004 <VDP_Control>
 258:   00c0 0004
 25c:   33fc 0e66 00c0    movew #3686,c00000 <VDP_Data>
 262:   0000
 264:   33fc 0600 00c0    movew #1536,c00000 <VDP_Data>
 26a:   0000
 26c:   33fc 0e00 00c0    movew #3584,c00000 <VDP_Data>
 272:   0000
 274:   33fc 0060 00c0    movew #96,c00000 <VDP_Data>
 27a:   0000

 27c:   4e5e              unlk %fp
 27e:   4e75              rts


После всего этого все регистры вроде как заполняются правильно, в VRAM появляется лишь одна запись с моим содержимым на 0-м адресе. Т.е. получается, что отработала только одна моя команда. Вот и не понимаю в чем дело. И вроде бы код идёт так же, как и других примерах на других ресурсах. Эмулирую в Gens. Подскажите, пожалуйста, что у меня здесь не так?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
IfoR



Зарегистрирован: 16.05.2006
Сообщения: 334

СообщениеДобавлено: Ср Янв 29, 2014 12:09 am    Заголовок сообщения: Ответить с цитатой

Блин, я - тупица! Я ковырялся в начальном коде инициализации мной любимой Comix Zone и когда дошёл до инициализации DMA. то туда в C00004 отправлялось не 0x40000000, а 0x40000080! Я же это видел и в одном исходном коде примера инициализации, но там автор написал комментарий, что не понял почему здесь значение оканчивается на 80. Да и я не предал этому значения. Пролистав ещё раз SEGA2.DOC я понял, что здесь установлен быт выбора режима адресации CD5, который в обобщённой таблице всегда равен 0, как и CD4. Однако при описании работы с DMA там всё таки этот момент указан, но о-о-о-очень ненавязчиво: там в списке действий стоит единичка в этом месте, где отправляется адрес, однако больше нигде не указано, что этот бит называется CD5 и что его нужно установить. Я и пропустил. В общем, сейчас всё работает! Smile
А CD4 так же устанавливается для режима копирования. В общем, тут нужно быть аккуратно.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
Показать сообщения:   
Начать новую тему   Ответить на тему    Список форумов shedevr.org.ru -> Ромхакинг в России и в мире Часовой пояс: GMT + 3
Страница 1 из 1

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


Powered by phpBB © 2001, 2005 phpBB Group