Автор Тема: SGDK  (Прочитано 74342 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ALKOSHA

  • Пользователь
  • Сообщений: 805
  • Люблю донди.
    • ВКонтакте
    • Просмотр профиля
SGDK
« Ответ #720 : 11 Декабрь 2021, 16:43:04 »
Гружу  карту уровня таким кодом:

int idx2=ind;
 ind+=BG1_Map.tileset->numTile;

 VDP_loadTileSet(&BG1_Tileset,idx2,DMA);
 BG1=MAP_create(&BG1_Map,BG_A,TILE_ATTR_FULL(PAL1,FALSE,FALSE,FALSE,idx2));
 VDP_setPalette(PAL1,BG1_Map.palette->data);

Вопрос,  как повысить приоритет отдельным тайлам - платформам в уровне - в пределах одного плейна?   Второй плейн отдан под фон.

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

(Ссылка на вложение) (Ссылка на вложение)

(Ссылка на вложение)
макрос TILE_ATTR_FULL() задаёт флаги сразу целому массиву тайлов.
Индивидуально задаётся атрибут через TILE_ATTR(), где второй флаг отвечает за приоритет.

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

Добавлено позже:
Внезапно,  нашёл решение, проверил - работает:
А, ну или так. Просто  я давно не следил за развитием фишек сгдк.

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3265
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #721 : 11 Декабрь 2021, 17:07:04 »
Так к примеру, с этим можно сделать эффект персонажа (спрайта) ходящего за стеклом
Почему нет? Как раз стекло, за которым яркость падает. В месте 'стелка' у обоих фонов должно быть приоритет лоу. А во всех остальных местах у скролла А - хайх. Или что имеется ввиду?

Оффлайн Werton

  • Пользователь
  • Сообщений: 878
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #722 : 11 Декабрь 2021, 18:24:32 »
Почему нет? Как раз стекло, за которым яркость падает. В месте 'стелка' у обоих фонов должно быть приоритет лоу. А во всех остальных местах у скролла А - хайх. Или что имеется ввиду?
Да не, не просто затенение, а наложение "текстуры" стекла на "текстуру" перса. Стекло в 2д играх, ведь обычно не просто однотонной серой областью изображают, там всё равно, какие то блики минимальные обозначают, + немного голубоватое или вообще цветное, что то типа такого:

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #723 : 12 Декабрь 2021, 06:54:02 »
На высоком уровне я бы просто разбил слой на две части, и грузил бы их по отдельности.

Как это сделать?

Сделал два PNG:  в одном платформы с высоким приоритетом, в другом PNG - платформы с низким приоритетом.

В res добавил так:

PALETTE Pal "BG1pal.png"

TILESET BG1_Tileset "BG1pal.png" NONE ALL

MAP BG1_Map_LO "BG1LO.png" BG1_Tileset NONE 0
MAP BG1_Map_HI "BG1HI.png" BG1_Tileset NONE 0

Код:

int idx2=ind;
 ind+=BG1_Map_LO.tileset->numTile;

 VDP_loadTileSet(&BG1_Tileset,idx2,DMA);

 BG1=MAP_create(&BG1_Map_LO,BG_A, idx2|TILE_ATTR(PAL0,FALSE,FALSE,FALSE) );
 BG1=MAP_create(&BG1_Map_HI,BG_A, idx2|TILE_ATTR(PAL0,TRUE ,FALSE,FALSE));


 VDP_setPalette(PAL0,Pal.data );

В итоге показываются  те платформы, что были загружены последними.  Старые затираются.

Как сделать загрузку мапы по слоям отдельно?

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #724 : 12 Декабрь 2021, 09:07:15 »
А, ну или так. Просто  я давно не следил за развитием фишек сгдк.

У этого способа есть недостаток.  Для платформ с высоким приоритетом нужно дублировать цвета палитры, иначе они не устанавливаются.

Желтые платформы - с высоким приоритетом
Синие платформы -  с низким.

Если сдублировать цвета жёлтых платформ (значения с +128), то  всё хорошо.



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



Проще говоря,  этот метод  не учитывает, что цвета приоритетных платформ могут сидеть с индексами от +128, и палитра ставится только по первым 16 индексам.  Работает только мапа.

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

В GIMP это делается по-уродски.

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #725 : 12 Декабрь 2021, 13:31:49 »
И ещё.  Поимел гоморой с клонированием цветов и назначением их на тайлы.  Есть какие-нибудь редакторы, которые позволяют жёстко переназначать цвета на разные индексы?

В GIMP это делается по-уродски.

Короч.  Всё свелось к написанию своей утилиты,  которая на входе получает 2 BMP файла (платформы, разделённые по приоритету) и даёт на выходе итоговый BMP, в котором платформы кодируются разными индексами цвета, в зависимости от приоритета.  Причём, утилита  сравнивает палитры с обоих файлов - объединяет  в одну палитру, повторяющиеся цвета выкидывает и переиндексирует пиксели.

Теперь платформы можно рисовать любыми цветами, независимо от приоритета.  :)

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #726 : 15 Декабрь 2021, 14:48:49 »
По спрайтам вопрос.

Дока на сегу говорит, что на X- и Y-координаты выделено 10 бит, то бишь X и Y могут быть в диапазоне 0..1023
И левый верхний угол экрана это X=128, Y=128.

Тогда почему, когда даёшь по X спрайту координату 512 - он снова появляется на экране ровно в том месте как и при X=0 ?

Хочется гонять спрайты немного за пределами кадра,  например для движущихся платформ, и не заморачиваться с онанизмом управления видимости Show/Hide спрайта.

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3265
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #727 : 15 Декабрь 2021, 18:31:31 »
Что за дока?
В офф. доке страница 53,  X = от 1 до 1FF,   Y от 0 до 1FF.   Только в interlace mode2 до 3FF и только для Y.  Плюс на следующей странице пометка о случае с X=0.

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #728 : 18 Декабрь 2021, 13:10:01 »
Что за дока?
В офф. доке страница 53,  X = от 1 до 1FF,   Y от 0 до 1FF.   Только в interlace mode2 до 3FF и только для Y.  Плюс на следующей странице пометка о случае с X=0.

Да, ошибся с докой.
В заблуждение ввели вот эти утверждения:

Цитата
index + 0 = vertical coordinate
 ; ---- --yy yyyy yyyy

index + 6 = horizontal coordinate
 ; ---- --yy yyyy yyyy

https://huguesjohnson.com/programming/genesis/spritelist/

///

Столкнулся с новым явлением.

При использовании инициализированных переменных, типа:

int p=5;
char d=8;

Их начальные значения присваиваются только при Hard Reset (включение питания приставки).

При Soft Reset (на приставке "обычная" кнопка Reset) сохраняются последние значения в этих переменных.

На эмуляторах тоже самое.

Это вообще - нормально?

Я конечно могу сделать что-то типа:

void InitAllVariables()
{
}

и вызвать её в main().  Но это уже попахивает костылями.

Подскажите, что надо подправить в стартапе, чтобы при обоих ресетах оно присваивалось всегда как при Hard Reset.

Оффлайн Werton

  • Пользователь
  • Сообщений: 878
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #729 : 18 Декабрь 2021, 14:36:35 »
Это вообще - нормально?
нормально

Добавлено позже:
Подскажите, что надо подправить в стартапе, чтобы при обоих ресетах оно присваивалось всегда как при Hard Reset.

int main(int hard_reset) {

    if (!hard_reset) {
        SYS_hardReset();
    }
}

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #730 : 19 Декабрь 2021, 05:07:27 »
int main(int hard_reset) {

    if (!hard_reset) {
        SYS_hardReset();
    }
}

Спасибо! Теперь работает как следует.

///

Со спрайтами есть вопрос.

При смене персонажей игрока спрайты пересоздаются каждый раз.  Из-за этого их приоритет (по отношению к другим спрайтам) становится ниже, чем у спрайтов, которые были созданы раньше.  Выделение-освобождение спрайтов сделано пока как по умолчанию - аллокация аппаратных спрайтов на совести SGDK.

Используются такие функции:

SPR_releaseSprite();  //освобождаем спрайт

SPR_defragVRAM(); //дефрагментируем видеопамять - чтобы "приструнить" актуальные спрайты один к другому, без тайловых "дырок"

SPR_addSprite(); //добавляем новый спрайт

Можно ли сделать так? :

1. Спрайты игрока - задать их номер жёстко (к примеру с 1 по 7).
2. Остальные спрайты - динамически аллоцировать средствами SGDK  (но начиная с номера 8 и далее)

Какими функциями и их флагами нужно воспользоваться?

//

По звукам вопрос.  Использую XGM для воспроизведения музыки и звуков.

Раскладка каналов такая :  5 FM + 1 DAC(CH1) + 4 PSG - музыка.    DAC (CH2,3,4) - звуки.

Некоторые звуки звучат очень "сопливо" (как бы рывками, дёрганно).  Особенно которые сильно пищат или с ВЧ-шумами.  Также иногда слышится хруст на стыке повторяющихся фрагментов звука.  При этом, в музыке ударная партия (CH1) очень хорошо звучит всегда.  Проблема именно в звуках:

//init:
 XGM_setPCM(70,start_sfx,sizeof(start_sfx));

//in game loop:
XGM_startPlayPCM(70,15,SOUND_PCM_CH2);

Смотрел волну в Audacity - там виден эффект "склейки" фрагментов семпла.  В оригинальном семпле такого нет.

Пробовал конвертить семпл ffmpeg'ом сразу в нужный формат:   8 bit, unsigned, 1 channel(mono), 14 000 Hz.  Улучшений не дало.

Чем это можно пофиксить?
« Последнее редактирование: 19 Декабрь 2021, 05:17:08 от rep-stosw »

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #731 : 19 Декабрь 2021, 11:51:26 »
Какими функциями и их флагами нужно воспользоваться?

Вопрос с приоритетом вновь созданных спрайтов решён.
Помогла функция с флагом:

SPR_setDepth(SPR_MIN_DEPTH);
Ещё раз констатирую гениальность Стефа - создателя SGDK!  :)

P.S. Вопрос со звуками в предыдущем посте остаётся в силе...


Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #732 : 19 Декабрь 2021, 13:17:29 »
P.S. Вопрос со звуками в предыдущем посте остаётся в силе...

Оригинал звука:

* Original.flac

Звук на эмуляторе:

* fromXGM.flac



Почему-то страдает именно этот звук.  Остальные идут нормально.

Почему  второй вариант звучит с треском и сопливо ?
« Последнее редактирование: 19 Декабрь 2021, 15:01:50 от rep-stosw »

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
Re: SGDK
« Ответ #733 : 19 Декабрь 2021, 15:10:05 »
Загрузил чистый синус.  Таже самая фигня.

Складывается впечатление, что данные подгружаются - из-за этого вывод звука подтормаживается.   Есть ли способ убрать эту противную задержку?  Или это издержки обращения Z80 к памяти M68K ?



Добавлено позже:
Загрузил чистый синус.  Таже самая фигня.

Складывается впечатление, что данные подгружаются - из-за этого вывод звука подтормаживается.   Есть ли способ убрать эту противную задержку?  Или это издержки обращения Z80 к памяти M68K ?

Найден виновник:

SPR_update();
Без неё звучание чистое, но нет спрайтов (((

Добавлено позже:
Найден виновник:

Код: [Выделить]

SPR_update();

Без неё звучание чистое, но нет спрайтов (((

Расковырял SPR_update().   Основной тормоз в DMA_allocateAndQueueDma()

Что делать?  Как быть?
« Последнее редактирование: 19 Декабрь 2021, 16:23:53 от rep-stosw »

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3265
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #734 : 19 Декабрь 2021, 17:38:28 »
Загрузил чистый синус.  Таже самая фигня.

Складывается впечатление, что данные подгружаются - из-за этого вывод звука подтормаживается.   Есть ли способ убрать эту противную задержку?  Или это издержки обращения Z80 к памяти M68K ?

(Ссылка на вложение)

Добавлено позже:
Найден виновник:

SPR_update();
Без неё звучание чистое, но нет спрайтов (((

Добавлено позже:
Расковырял SPR_update().   Основной тормоз в DMA_allocateAndQueueDma()

Что делать?  Как быть?
Во время dma, у z80 нет доступа к ROM. Некоторые драйвера это обходят подгружая из rom в ram z80, и уже оттуда играют. xgm скорее всего это не делает, как и большинство драйверов. Ну можешь попробовать где-то без DMA сделать, если скорости хватит.

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #735 : 20 Декабрь 2021, 11:17:02 »
Ну можешь попробовать где-то без DMA сделать, если скорости хватит.

Попробовал.  Идея так себе. В SGDK через DMA идёт и обновление спрайтов и обновление тайлов.  Попробовал с помощью CPU это всё дело грузить.   Со спрайтами прокатило. Но этого мало.  Там через DMA ещё и обновление тайлов когда спрайт анимированный.  Повешать апдейт тайлов на VInt Не вышло - спрайты артефачили.

Из памяти M68k   в VRAM VDP перекидывал так:

#define VDP_CONTROL_32 (*(volatile u32*)0xC00004)
#define VDP_DATA_32    (*(volatile u32*)0xC00000)

#define VDP_VRAM_WRITE(a)  VDP_CONTROL_32=0x40000000+(((a)&0x3FFF)<<16)+((a)>>14)

void MEM_68k_to_VRAM_VDP_via_CPU(void)
{
 u32 *src=(u32*)vdpSpriteCache;
 u32 n=(sizeof(VDPSprite)*(highestVDPSpriteIndex+1))>>2;
 VDP_VRAM_WRITE(0xF400);
 while(n--)VDP_DATA_32=*src++;
}

Потом  вешал на VINt:

SYS_setVIntCallback(MEM_68k_to_VRAM_VDP_via_CPU);
В в цикле в main() вызывал:

My_SPR_update()
Который выглядит так:

void My_SPR_update(void)
{
    Sprite* sprite;

    // iterate over all sprites
    sprite = firstSprite;
    while(sprite)
    {
        u16 status = sprite->status;

        // trivial optimization
        if (status & NEED_UPDATE)
        {
            // ! order is important !
            if (status & NEED_FRAME_UPDATE)
                status = updateFrame(sprite, status);
            if (status & NEED_VISIBILITY_UPDATE)
                status = updateVisibility(sprite, status);

            // sprite not visible ?
            if (!sprite->visibility)
            {
                // need to update its visibility (done via pos Y) ?
                if (status & NEED_ST_POS_UPDATE)
                {
                    // hide sprite
                    updateSpriteTableHide(sprite);
                    status &= ~NEED_ST_POS_UPDATE;
                }
            }
            // only if sprite is visible
            else
            {
                if (status & NEED_TILES_UPLOAD)
                {
                 GlobalSprite=sprite;
                 My_loadTiles();
                }

                if (status & NEED_ST_ALL_UPDATE)
                    updateSpriteTableAll(sprite);
                else if (status & NEED_ST_POS_UPDATE)
                    updateSpriteTablePos(sprite);

                // tiles upload and sprite table done
                status &= ~(NEED_TILES_UPLOAD | NEED_ST_UPDATE);
            }

            // processes done !
            sprite->status = status;
        }

        // next sprite
        sprite = sprite->next;
    }
}


тайлы грузятся через CPU аналогично:

void My_loadTiles(void)
{
 TileSet* tileset = GlobalSprite->frame->tileset;
 u16 lenInWord = (tileset->numTile * 32) / 4;

 u32 *src=(u32*)FAR_SAFE(tileset->tiles, tileset->numTile * 32);
 VDP_VRAM_WRITE((GlobalSprite->attribut & TILE_INDEX_MASK) * 32);
 while(lenInWord--)VDP_DATA_32=*src++;
}

И тут я понял, что вся графическая под-система у Стефа на ДМА и нет смысла её всю переводить на CPU, ради звуков.

Вот этот вариант:

Цитата
Некоторые драйвера это обходят подгружая из rom в ram z80, и уже оттуда играют.

Вот этот вариант более интересен.

Можно ли заставить XGM движок играть семпл из памяти  Z80, предварительно скопировав его из ROM ?

Оффлайн SeregaZ

  • Пользователь
  • Сообщений: 2510
  • Пол: Мужской
  • ливнул с форума
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #736 : 21 Декабрь 2021, 13:15:47 »
rep-stosw, колись как правильно подготовить сэмпл для более менее адекватного вопроизведения. может там какой секрет есть? типа в аквалайзере низкие и высокие подрезать, а средние подкрутить?

а докучи бы еще придумать алгоритм, который более менее ровно кодирует в 4 битные DPCM... а то у меня не очень :)


хотя в данном случае пережатие было из уже пожатого источника - из 10.4к кажись... в 6.5к. и после второй раз из 8бит в 4бита по таблице DPCM для MK3.

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #737 : 21 Декабрь 2021, 14:32:43 »
И тут я понял, что вся графическая под-система у Стефа на ДМА и нет смысла её всю переводить на CPU, ради звуков.

И тут я более понял, что нужно посмотреть dma.c что там делается. И не зря.  Там творится полный ужас - останавливается Z80 когда идёт транзакция DMA:

    // define z80 BUSREQ restore state
    if (Z80_isBusTaken()) z80restore = 0x0100;
    else z80restore = 0x0000;

#if (HALT_Z80_ON_DMA != 0)
    vu16 *pw = (vu16*) Z80_HALT_PORT;

    // disable Z80 before processing DMA
    *pw = 0x0100;

    flushQueue(i);

    // re-enable Z80 after all DMA (safer method)
    *pw = z80restore;
#else
    flushQueueSafe(i, z80restore);
#endif

Весьма сопливое решение, когда нужно воспроизводить семплы через DAC и оперировать спрайтами-тайлами-скроллом через DMA.

В config.h  уставновил в 0 дефайн:

#define HALT_Z80_ON_DMA     0
На свой страх и риск.

А перед SPR_update()  ждать пока Z80 не освободит шину:

while(Z80_isBusTaken());
Всё отлично работает!  DMA успевает пролететь раньше - сразу же после освобождения шины Z80,  до того как Z80 снова её займёт.

Я рад!  Сопли в звуке прошли - все семплы  чётко и  ровно звучат, и спрайты не артефачат.  :)

Странно, что никто не пытался глубже ковырнуть этот SDK.

///

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

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

а докучи бы еще придумать алгоритм, который более менее ровно кодирует в 4 битные DPCM... а то у меня не очень

IMA ADPCM сжимает обычный PCM в 4 раза.  Исходники есть в интернете, алгоритм достаточно прост.  Странно, что он ещё  не интегрирован в SGDK.

Глянул ваши видео, в частности движок звука GEMS.   Пока более интересен XGM, потому что он даёт 4 PCM канала:  1 на ударные в VGM,  и 3 - на звуки.

Рассматриваю ещё Echo, интересен конвертером треков XM в формат для сеги.

Вот если бы написали конвертер XM/IT/S3M  в VGM - было бы круто :)   

А вот VGMMaker может MOD импортировать в VGM(VGE), с подбором инструментов. Мне понравилось! Откопал банк TFI-инструментов и WAV-ударных около 30 000 с разных игр.

Оффлайн SeregaZ

  • Пользователь
  • Сообщений: 2510
  • Пол: Мужской
  • ливнул с форума
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #738 : 21 Декабрь 2021, 19:19:45 »
Цитата
Пока более интересен XGM, потому что он даёт 4 PCM канала:  1 на ударные в VGM,  и 3 - на звуки.
и я и я и я того-же мнения, что для МК3 больше подошел бы XGM как раз из этого мультисэмплинга, точнее микширования сэмплов. НО! к сожалению игра содержит некое количество эффектов, которые воспроизводятся с помощью FM звуков. XGM такое не умеет. ему подавай спецэффекты в виде сэмплов - wav'ок. поэтому мы предали XGM анафеме.

по поводу размеров сэмплов - может IMA ADPCM и круче в плане занимаемого места, но для MK3 не подходит. там не оригинальный дравер GEMS - а химиченый, где добавили возможность играть два сэмпла одновременно, но правда ценой говёного качества - 6.5k (против 14к у XGM и против 10.4k у оригинального GEMS). поэтому в целях совместимости надо пережимать сэмпл в его родной DPCM, по таблице из 16 значений. понятно что будут потери... но оригинальные сэмплы звучат прям очень даже неплохо. хотелось бы знать каким образом они подходили к этому делу, чтобы можно было делать более менее похоже и хорошо. то есть знать бы какие предварительные танцы с бубном эти наши пращуры делали в 90годах, когда пилили МК3.

второй момент почему этого нет в XGM - видимо экономят циклы процессоров, чтобы не тратить производительность на разжатие. может быть vgm файлы и стали бы меньше по размеру, но это не имеет смысла, так как сэмплы там (по моему и это не точно) играют путем спама содержимого сэмпла в регистр... эээ... $2A? то есть по байтно бомбит в этот регистр ямахи и ямаха это играет. этот спам по идее записан в vgm файле. впрочем это могут быть и оптимизированные vgm'ки - где сэмплы вынесены в специальный раздел файла, и проигрывание происходит путем вызова из этой библиотеки, а не побайтная запись значений регистра во времени в файле. хотя система все равно должна будет бомбить этот регистр для проигрывания.

поэтому я вот и страдаю в поисках подобного алгоритма пережатия в DPCM и предварительной подготовки самого сэмпла.

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #739 : 22 Декабрь 2021, 04:49:21 »
второй момент почему этого нет в XGM - видимо экономят циклы процессоров, чтобы не тратить производительность на разжатие. может быть vgm файлы и стали бы меньше по размеру, но это не имеет смысла, так как сэмплы там (по моему и это не точно) играют путем спама содержимого сэмпла в регистр... эээ... $2A? то есть по байтно бомбит в этот регистр ямахи и ямаха это играет. этот спам по идее записан в vgm файле. впрочем это могут быть и оптимизированные vgm'ки - где сэмплы вынесены в специальный раздел файла, и проигрывание происходит путем вызова из этой библиотеки, а не побайтная запись значений регистра во времени в файле. хотя система все равно должна будет бомбить этот регистр для проигрывания.

К сожалению у Генезиса нет DMA для семплов, как это сделано в SNES и даже в NES.   Зилог ручками пуляет каждый семпл в YM2612 и даже без FIFO.

В VGM семплы DAC хранятся в единственном количестве.  Очень давно, я прикручивал YM2612 к LPT-порту компа и писал свой плеер-парсер VGM.  Правда, из-за ограниченной скорости самого LPT-порта, некоторые ударные через DAC играли медленно и затормаживали воспроизведение VGM (например, из игр: Alien3, T2 Arcade game).

Цитата
0x67, 0x66, tt, ss, ss, ss, ss – конкретно:
0x67 – маркер блока данных для DAC
0x66 – конец потока (здесь эта под-команда игнорируется!)
tt – тип данных (должно =0 – это значит YM2612 PCM data)
ssssssss – объём данных для DAC в байтах
Здесь логично запомнить смещение данных для DAC, тоесть начальный указатель
на PCM data в VGM-файле. Указатель музыкального потока увеличивается на ssssssss+7.

0x8* - конкретно:
A1=0 – выбираем Bank0
[0x2A]=Digital[Offset]
Задержка на * сэмплов
Увеличиваем Offset на 1 (указатель на PCM data)
Увеличиваем указатель потока на 1
Попросту говоря, данная команда пихает в DAC один байт PCM-данных (указатель
на PCM вычисляется командами 0x67 и 0xE0). Далее задержка на * сэмплов и увеличение
указателей музыкального потока и PCM data на 1.

0xE0, dd, dd, dd, dd – вычисление увеличения указателя на PCM data. Итоговое
значение указателя PCM data в данный момент: Offset=dddddddd+Адрес начала данных
для DAC в VGM-файле (адрес байта, следующего сразу после команды 0x67, 0x66, tt, ss,
ss, ss, ss). Указатель музыкального потока увеличивается на 5.

НО! к сожалению игра содержит некое количество эффектов, которые воспроизводятся с помощью FM звуков. XGM такое не умеет. ему подавай спецэффекты в виде сэмплов - wav'ок. поэтому мы предали XGM анафеме.

При написании игры, я сразу решил, что SFX - будут оцифровки, BGM -> 5FM + DAC + 4 PSG.

Сейчас озадачен выбором фоновой музыки для игры:

1. Брать VGM-ки с сеговских игр или демо из трекеров не хочется, так как это баяны, хоть и шедевральные, и с музыкой там всё ОК.

2. Пробовали VST GennyFL. Результат не понравился: итоговый VGM получается на несколько МБ, ноты проглатываются или наоборот вылезают. Часть каналов пропадает на реальной сеге.

3. Пробовали Deflemask.  В техническом плане для сеги - он очень крут: трек звучит также как и написали.  Но: большинство просто не могут написать полноценную музыкальную композицию с началом, раскачкой, активной частью, припевом, завершением, скруглением.   В итоге у большинства получается просто простой цикл на 10 - 20  секунд, и его повторы, разбавленные парой инструментов.

4. Лично пробовал переносить безымянные треки в формате MOD (с Амиги, 4 канала до 14 инструментов(?)) в VGE(VGM) с помощью VGMMaker и банка инструментов.   За шесть часов более-менее удалось подобрать схожие инструменты, подтюнить октавы.   Получается тот же трек что и MOD, но сыгранный инструментами YM2612.   Отдельно вручную прописывал ударные партии на 6-й канал  (DAC). В некоторых MOD, ударные размылены на несколько каналов - приходится  сводить в 1 канал.   К сожалению, OpenMPT далёк от удобного функционала - не хватает функции объединения выбранных инструментов в одну дорожку.
Результат порадовал - композиция трека сохраняется (нотная партия), музыка на несколько голов сложнее, чем простой копирование "тупо одного цикла по 10 с".

5. MID2VGM. Пока не успел с ним разобраться.

6. XM2ESF.  С наскоку не понял  как с ним возиться.

Для меня конечно, пока предпочтителен способ (4),  чем способы (2) и (3).  Как показала практика, фрилансеры ничего путного не напишут.

Оффлайн SeregaZ

  • Пользователь
  • Сообщений: 2510
  • Пол: Мужской
  • ливнул с форума
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #740 : 22 Декабрь 2021, 12:25:24 »
В VGM семплы DAC хранятся в единственном количестве.
это в случае оптимизированной vgm'ки. а ежели она была писана - скажем фрагмент какой-то в том-же Fusion из какой-то другой игры - там сэмплы будут "растянуты" во времени, путем спама этого самого регистра $2A и будут повторятся каждый раз. поэтому оптимизированные вгмки лучше. из Дефлемаска экспортированная вгмка с сэмплами возможно не подойдет. потому что там сэмплы 32 битные. не знаю каким там образом происходит экспорт сэмплов в вгм из дефлемаска - не смотрел, но не думаю что там происходит конвертация на лету из 32 в 8 бит.

что касается музыкантов - это зря поклеп на дефлемаск :) есть целый дискордовский канал дефлемасковский. там этих музыкантов... тьма. мы когда в RRR музыку конвертировали - эту самую музыку пилил буржуйский товарищ Alianger с этого дефлемасковского канала. правда он делал не авторскую, а каверы на свое усмотрение - типа Europe - Final Countdown, Billy Idol - More More More (хз как она называется). но поскольку XGM на тот момент мы предали анафеме - пришлось лепить велосипед по конвертации из Deflemask в RRR драйвер (не помню названия), но там свои проблемы вылезли... одна - размер песни в оригинальном драйвере не более 3кб. у меня же под 30кб получалось конвертирование (без оптимизации). Ti потом сделал изменение чтения этой самой мелодии и этот лимит 3кб мы обошли... нооооо у всего есть цена :) если оригинальный размер был не более 3кб - но можно было сделать так, чтобы фразы диктора не прерывали мелодию. то когда размер был увеличен - все вернулось в зад и диктор прерывал проигрывание мелодии, как было в оригинале RRR. посему драйвер RRR был предан анафеме тоже. был заменен RRR'шный драйвер на любимый GEMS и там пошла жара... но опять вылезло две проблемы :) первая - XGM не нужно ничего конвертировать и трек звучит классно. при переносе в GEMS нужно попытаться воспроизвести алогоритм изменения частоты в случае слайдов нот - у меня особо не получилось... и пьяные кошки звучат в треках во всех местах. это все Alianger виноват :) сделал такие музыкальные треки с миллионом слайдов и эффектов, что у меня мозг вспух в попытке все это перенести во вселенную GEMS. делал бы простые прямые ноты, без извращений - то там бы уже давно все закончили. но с этими слайдами я прям в расстройстве. их будем править только когда доделаю GEMS треккер. если доделаю. а вторая проблема - звук визга покрышек. при длительных заносах там появляются щелчки. что тоже портит впечатление. дело скорей всего в слишком частом вызове этого звука. инструмент потому что я ковырял и так и сяк - не помогает. думаю просто слишком часто вызывается. туда-бы паузу чуть побольше между вызовами визга...

сейчас, насколько я знаю, Alianger делает каверы на какой-то там проект по Кастлвании на сегу. так-же можно в соседней теме про 8 битную музыку написать - там есть, правда не дефлемасковский - а VGM MM'ский фанат Sprill - тоже класные треки делает. может ему будет интересно.

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #741 : 22 Декабрь 2021, 13:47:59 »
Удалось портировать и запустить движок Echo на SGDK.   Вначале ничего не шло, так как грузил инструменты не в том порядке.  Потом глянул моторольные сорцы (*.68k которые), оказалось, что часть инструментов заданы в виде набора байтов, так что те что в папках fm и pcm - это ещё не всё!  :lol:

Цепочки байтов перенёс с асма в Си, а инструменты из папок подцепил в ресурсы BIN.

Поиграл треки.  Есть интересные, но треков esf очень мало.
Пробовал осилить xm2esf, и понял что оно того не стОит.  У треков XM (которые писались неизвестно кем и для какой платформы) слишком много каналов (до 32) и уместить их в 10 каналов сеги - не выйдет.
Всё-же более перспективнее переносить MOD'ы.

А мне вот интересно стало.  Есть очень много тем c Adlib OPL2/3. 

Некоторые форматы данных я знаю (типа DRO, DAT, и прочие).  Можно ли перекодировать YMF262/YM3812 (OPL2/OPL3)  в YM2612 (OPN2) ?  Есть ли готовые решения?

Проще говоря - регистры OPL3  отмапить на OPN2 Без привязки к MIDI там всяким.

Пара "регистр-значение" OPL3 переводим в пару "регистр-значение" OPN2.   Ну с корректировкой битовых полей, и может записью в другие регистры, если биты параметров раскиданы в разных регистрах.

Понимаю, что у OPL3 9 каналов, а у сеги всего 6 FM каналов.  Но всё-же...  :)

Хочестя самостоятельно заняться конверсией и найти техническое решение,  а то кормить "случайных Бетховенов" уже порядком надоело.  ^_^

что касается музыкантов - это зря поклеп на дефлемаск :) есть целый дискордовский канал дефлемасковский. там этих музыкантов... тьма

Я не знаю ничего про этот канал.  А вот на форуме дефлемаска удалось зарегаться.  Там выкладывают треки, но они в основном под NES или GB.  Под сегу там мало, а хороших(по моему вкусу) треков там "раз, два и обчёлся"...  Часть треков не идёт в последней версии дефлемаска.

Дефлемаск - сама штука хорошая, но от него шарахаются те, кто привык работать с секвенсорами и VST.  Писать музыку я не умею, поэтому ищу решение задачи в техническом ключе.
« Последнее редактирование: 22 Декабрь 2021, 13:58:21 от rep-stosw »

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3265
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #742 : 22 Декабрь 2021, 19:55:00 »
Из памяти M68k   в VRAM VDP Из памяти M68k   в VRAM VDP перекидывал так:

 while(n--)VDP_DATA_32=*src++;
}
}
Без понятия что там сгенерится, но скорее всего
@loop:
   move.l (a0)+(a1)
    dbf d0,@loop
или
@loop:
   move.l (a0)+(a1)
   move.l (a0)+(a1)
    dbf d0,@loop
что недостаточно для большой скорости.

Должно быть примерно такое :
lea vdpSpriteCache,a0
lea $C00000,a1 ; vdp_data
move.l #$74000003,4(a1) ; vram: $F400

move.w highestVDPSpriteIndex,d1 ; количество спрайтов 1-80?
bne.s @have_spr
moveq #1,d1 ; (минимум 1 спрайт для обновления если нет спрайтов).
@have_spr
add.w d1,d1 ; *2
add.w d1,d1 ; *4 = 320
move.w #320,d0
sub.w d1,d0
jmp copy_to_vram(pc,d0.w)
copy_to_vram
dcb.w 160,$2298 ;  то есть move.l (a0)+,(a1) повторить 160 раз. (160*4 = 640)
rts
Это медленнее чем с DMA, но вполне неплохо. Тем более для 640 байтов. Звук семплов это улучшит.

С тайлами сложнее, там много уже не передать без DMA, но могут быть варианты:
а) Тайлы обновляются не всё время.
б) Пал режим, тут гораздо больше времени вбланка. (Проверять если VDP в ПАЛ - не использовать DMA).
Также можно с CPU только в момент когда семпл играет, а в остальных случаях с DMA.

Примерный код для тайлов - передаём в цикле по 64 байта (2 тайла), максимум 2560 байт.
lea tiles,a0 ; тайлы
move.w tiles_cnt,d1 ; количество тайлов от 1 до примерно 80, при превышении - DMA.
cmpi.w #80,d1
BCC.S too_many_tiles

        subq.w #1,d1
lsr.w #1,d1
bcc.s @odd
@copy
move.l (a0)+,(a1) ; 1тайл = 32байта.
move.l (a0)+,(a1)
move.l (a0)+,(a1)
move.l (a0)+,(a1)
move.l (a0)+,(a1)
move.l (a0)+,(a1)
move.l (a0)+,(a1)
move.l (a0)+,(a1)
@odd
move.l (a0)+,(a1) ; 2-ой тайл
move.l (a0)+,(a1)
move.l (a0)+,(a1)
move.l (a0)+,(a1)
move.l (a0)+,(a1)
move.l (a0)+,(a1)
move.l (a0)+,(a1)
move.l (a0)+,(a1)
dbf d1,@copy
rts

too_many_tiles:
        тут код с dma.

Также кроме тайлов и спрайтов, можно переделать обновление палитры и hscroll если они есть.

Добавлено позже:
Вот этот вариант:

Вот этот вариант более интересен.

Можно ли заставить XGM движок играть семпл из памяти  Z80, предварительно скопировав его из ROM ?
Ну это сложная система. Поэтому врядли.  Из движков GEMS это умеет.

Добавлено позже:
И тут я более понял, что нужно посмотреть dma.c что там делается. И не зря.  Там творится полный ужас - останавливается Z80 когда идёт транзакция DMA:
Ну как бы это также есть и в почти всех играх на SEGA.
Z80 в любом случае останавливается, при попытке доступа к РОМУ, если в этот момент используется DMA.
Но в играх это делается принудительно, что при любом обращении к памяти z80, так как по рекомендациям в мануале, сказано что так надо. Иначе могут быть проблемы, то ли в зависимости от ревизий Сеги, или от скорости памяти точно не скажу.  А вот в некоторых эмуляторах z80 не останавливается сам.


Добавлено позже:
Всё отлично работает!  DMA успевает пролететь раньше - сразу же после освобождения шины Z80,  до того как Z80 снова её займёт.

Я рад!  Сопли в звуке прошли - все семплы  чётко и  ровно звучат, и спрайты не артефачат.  :)
Такое врядли может быть:
При 14 кгц звуке если он читается напрямую из ROM, полностью дисторшен никак не может пропасть. Это по 233 байта за кадр. То есть в среднем почти каждую строку по байту. За vblank-dma это байтов 20 или больше.
Если только у тебя dma не разбито на много маленьких кусков, и то сомнительною

То есть тут либо xgm всё же умеет 'кешировать' семпл.  Либо эмулятор такой, если на нём проверял.
« Последнее редактирование: 22 Декабрь 2021, 20:28:45 от Ti_ »

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #743 : 23 Декабрь 2021, 02:44:39 »
Но в играх это делается принудительно, что при любом обращении к памяти z80, так как по рекомендациям в мануале, сказано что так надо. Иначе могут быть проблемы, то ли в зависимости от ревизий Сеги, или от скорости памяти точно не скажу.  А вот в некоторых эмуляторах z80 не останавливается сам.

То есть тут либо xgm всё же умеет 'кешировать' семпл.  Либо эмулятор такой, если на нём проверял.

На GENS и Fusion полёт нормальный. 
Также проверял на реальной приставкe (MegaDrive 1) - тоже всё ОК.  Играет VGM с партией ударных на DAC(CH1) и звуки (CH2), делается скролл плоскостей A, B и рисуются анимированные спрайты.

Но странно вот что: при попытке отловить захват шины Z80 перед SPR_update() - всегда возвращается, что шина свободна!

Тем не менее, при DMA транзакциях по дефолту Стеф всегда тормозит Z80, даже не проверяя перед этим - а захвачена ли шина действительно?  Я это убрал.

б) Пал режим, тут гораздо больше времени вбланка. (Проверять если VDP в ПАЛ - не использовать DMA).
Также можно с CPU только в момент когда семпл играет, а в остальных случаях с DMA.

Игра затачивается под NTSC, и приставка у меня тоже NTSC.  Смысла делать тормозной PAL не вижу, я люблю NTSC.

Это медленнее чем с DMA, но вполне неплохо. Тем более для 640 байтов. Звук семплов это улучшит.

Можно было самостоятельно не переделывать на CPU.
У Стефа в config.h есть дефайн:

#define DMA_DISABLED        0
Поставить его в 1, если DMA не нужен.  Проверял:  всё также работает, и звук без рывков.

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #744 : 23 Декабрь 2021, 10:42:55 »
///

Для подгрузки карты уровня использую: MAP_scrollTo( ).
В первый раз - первый фрейм - мусор в виде некорректной мапы.  Начиная со второго фрейма и дальше - всё нормально.

Как побороть мусор и заставить первый вызов MAP_scrollTo( ) отображать то, что надо?

P.S. Обнаружил артефакт на замедленной съёмке.

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3265
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #745 : 23 Декабрь 2021, 19:19:33 »
Но странно вот что: при попытке отловить захват шины Z80 перед SPR_update() - всегда возвращается, что шина свободна!

Тем не менее, при DMA транзакциях по дефолту Стеф всегда тормозит Z80, даже не проверяя перед этим - а захвачена ли шина действительно?  Я это убрал.

Никто и не проверяет, захвачена ли шина, в этой проверке отдельно смысла нет, если ты сам не делаешь захвата шины.

Как я уже же сказал так, во всех играх где драйвер читает из рома.

Везде последовательность примерно  такая:

  move.w #$100,$A11100    ; делаем захват
@wait
   btst #0,$A11100   ; ждём что шина стала свободна (вот это как раз во многих эмуляторах всегда свободна).
   bne.s @wait

   move.w   (sp)+,$C00004   ; DMA  (или другие операции с доступом к ОЗУ z80).

   move.w #0,$A11100  ; возвращаем


Добавлено позже:
Также проверял на реальной приставкe (MegaDrive 1) - тоже всё ОК.
Ну может он сумел это сделать (подгрузку семпла в ОЗУ), но где-то это не доделано или неидеально. И поэтому по дефолту был оставлен захват z80 при dma. На этот драйвер вроде часто жаловались что на железе 'виснет'.

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #746 : 24 Декабрь 2021, 03:00:53 »
На этот драйвер вроде часто жаловались что на железе 'виснет'.

На каком железе? Есть ли разница в том как будет работать софт, если вместо оригинального Мегадрайв-1, я возьму китайский нонейм на одной микросхеме-капле? "Сюрпризы" будут?  Предполагаю, что в последних "сегах" на "каплях" упрощена схемотехника и что-то может работать через одно место.

Как побороть мусор и заставить первый вызов MAP_scrollTo( ) отображать то, что надо?

Как оказалось - важен порядок вызова:

VDP_setScreenWidth320();
VDP_setHilightShadow(0);

 SPR_init();
// SPR_reset();
// SPR_clear();

VDP_clearPlane(BG_B,TRUE);
VDP_clearPlane(BG_A,TRUE);
VDP_clearPlane(WINDOW,TRUE);

VDP_loadTileSet(...);
VDP_setTileMapEx(BG_B,...);
VDP_setPalette(...);

VDP_loadTileSet(...);
BG1=MAP_create(&BG1_Map,BG_A,...);
VDP_setPalette(...);

VDP_setScrollingMode(HSCROLL_TILE,VSCROLL_PLANE);

ScrollY=...;
ScrollX=...;

MAP_scrollTo(BG1,ScrollX,ScrollY);
SYS_doVBlankProcess();

while(1)
 {
  ControlInput();
 ...
 VDP_setHorizontalScrollTile(BG_B,...);
 MAP_scrollTo(BG1,ScrollX,ScrollY);
 ...
 //управляем логикой игры, спрайтами...

 SPR_update();
 SYS_doVBlankProcess();
}

При таком порядке:

1. Появляется задняя плоскость - 2 фрейма
2. затем появляется плоскость платформ (фрагмент уровня) - 1 фрейм
3. Затем появляются спрайты - 1 фрейм
4. начинает всё двигаться и идти

Если же перед циклом выбросить это:

ScrollY=...;
ScrollX=...;

MAP_scrollTo(BG1,ScrollX,ScrollY);
SYS_doVBlankProcess();

То первый фрейм - будет мусор.

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3265
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #747 : 24 Декабрь 2021, 18:01:27 »
На каком железе? Есть ли разница в том как будет работать софт, если вместо оригинального Мегадрайв-1, я возьму китайский нонейм на одной микросхеме-капле? "Сюрпризы" будут?  Предполагаю, что в последних "сегах" на "каплях" упрощена схемотехника и что-то может работать через одно место.
Некоторые модели md2, также мб md1 va0, и некоторые клоны.
В этой же теме обсуждалось:
http://www.emu-land.net/forum/index.php/topic,70308.msg1448141.html#msg1448141

Добавлено позже:
Вот ещё:
http://gendev.spritesmind.net/forum/viewtopic.php?f=8&t=2478&p=30259&hilit=xgm+freeze#p30259
« Последнее редактирование: 24 Декабрь 2021, 18:14:45 от Ti_ »

Оффлайн rep-stosw

  • Пользователь
  • Сообщений: 110
  • Пол: Мужской
  • Аппаратчик
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #748 : 25 Декабрь 2021, 03:07:30 »
Некоторые модели md2, также мб md1 va0, и некоторые клоны.
В этой же теме обсуждалось:
http://www.emu-land.net/forum/index.php/topic,70308.msg1448141.html#msg1448141

Почитал я мытарства Сегамена; уже представляю как у меня будет бомбить, когда игра пойдёт не так или вообще не пойдёт на разных версиях Сеги.

А вот на этой модели сеги(которая у меня есть) можно отключать Z80 во время DMA:



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

Изначально, я предполагал, что конфигурация железа Сеги везде одинакова (в отличие от ПК) и не будет гемороя с совместимостью.  Китайцы со своими клонами разбили мою хрустальную мечту! :?

Вот ещё:
http://gendev.spritesmind.net/forum/viewtopic.php?f=8&t=2478&p=30259&hilit=xgm+freeze#p30259

Та же самая проблема - Стеф не имеет возможности самостоятельно протестировать на всех клонах свой SGDK.

Он там пишет, что отключение Z80 во время DMA - это "clever solution", но я с ним не соглашусь:  получать рваный звук (речь идёт только о проигрывании PCM) во время работы DMA - не лучшее решение.

К сожалению, других вариантов нет, так как у самого Z80 памяти как кот наплакал (8 кБ) и грузить туда целый семпл PCM длительностью хотя бы 0,3 с - не выйдет. Так как с этих 8 кБ на буфер отведён всего 1 кБ.

Из того же форума (сохранил, не помню уже тему, где взял):

Цитата
XGM music playing state: 0xA00102 bit 6
PCM channel playing state: 0xA00102 bit 0 to bit 3 (channel 0 to channel 3)
D1L / RR registers state: 0xA00144-0xA0015B (6 channels * 4 operators)
PSG envelop: 0xA0015C-0xA0015F (4 channels)
DAC enabled: 0xA00160 (bit 7)
Circular PCM buffer: 0xA01800-0xA01BFF

You can find the current read PCM segment at 0xA00140.
Note that the address is stored as byte so you only have bit 8 and bit 9 as the lower bits are always 0.
For instance if you read 0 from 0xA00140 then current PCM read buffer is 0xA01800, if you read 3 then current read PCM buffer is 0xA01B00...

Всего 1 кБ на кольцевой буфер :

Цитата
Circular PCM buffer: 0xA01800-0xA01BFF

А теперь считаем:   

1 кБ/ 2 = 512 байт (семплов)
Семплирование: 14 000 Гц

Время проигрывания одной половинки буфера:   512/14000 ~ 36.57 мс.  С такими интервалами Z80 лезет к 68k ROM для полученния новых данных.

В случае семпла 0,3 с, число обращений Z80 к памяти 68k: 300/35.57 ~ 9 обращений.

Тоесть, обращения неизбежны!

А теперь вопрос:

можно ли приостанавливать уже начатую передачу DMA, когда Z80 нужны новые данные (обращения к M68k RAM) ? А потом продолжить ДМА.

Совсем от DMA отказываться нежелательно, так как с ним выше скорость копирования тайлов-спрайтов, чем в случае 68k.

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3265
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
SGDK
« Ответ #749 : 25 Декабрь 2021, 09:56:41 »
можно ли приостанавливать уже начатую передачу DMA, когда Z80 нужны новые данные (обращения к M68k RAM) ? А потом продолжить ДМА.
Нет, нельзя.
Касаемо размера буффера, так и в GEMS всего 256 байт. Да, и раз ты не слышишь ухудшения звука, то вероятно в этом движке работает буффер так, чтобы пополняться только вне vblanka (флаг 'dma' тут не используется, в gems - есть). По сути буффер для этого и нужен. Без него будет дисторшен звуков независимо от того, захватываешь ли ты шину или нет.
Тут может быть проблема что это сделано только для семплов, а для остальных данных трека (fm,psg) это не делается и/или не учитывается когда можно обращаться к рому.