Разработка и ромхакинг > Программирование
Ассемблер для PS2.
<< < (2/2)
Томахомэ:
Пошла полоса даже какого-то подозрительного везения. Ещё несколько типов инструкций подтвердили правильность своей работы.
dedok179:

--- Цитата: SeregaZ от 25 Октябрь 2024, 21:18:11 ---это нормально  :blush: у творческого человека мысль должна вызреть, дойти до кондиции, и потом заночь забабахать. главное за это время пока оно который год уже зреет - все не забыть, что сделано было ранее. а то сто раз такое было - открываешь проект... это я написал? а что я хотел сказать этим участком кода? а вот этим? а это для чего?...

--- Конец цитаты ---
В принципе у меня так бывает. Заходишь в проект, и вообще не понимаешь как оно работает
Turbo2000:

--- Цитата: SeregaZ от 25 Октябрь 2024, 20:16:09 ---и все равно когда начинаю думать как реализовать такую поддержку математики в качестве параметра - попаболь начинается такая, что думать сразу уже и не хочется
--- Конец цитаты ---
Да, есть такое, надо написать свой компилятор в m68k asm, но Sharpnull, как раз предлагал проекты для высокоуровневой разработки под консоли, там вроде была Nes, и дженерик под 8-и битные процессоры, но есть же SGDK. Или идея делать свои хаки со вставками на высокоуровневом языке?
SeregaZ:
в моем случае он нужен тупо для того, чтобы собирал точно такой-же 100% ром один в один после разбора  :lol: когда вникал в вопрос дизасма и увидел эти костыли, что существуют сейчас - ужоснулся! захотел сделать свое - однокликовое, и чтоб ASM68K.exe совместимое. то есть именно что не правильное --хххххх, а совместимое с этим старым ассемблером - то есть хххххххх. но оказалось что помимо этой проблемы там еще пяток. уже не помню какая функция, но там что-то типа замена параметров друг на друга. типа Замена(а, б) - по логике никакой разницы нет что Замена(а, б) или Замена(б, а) - оба варианта будут правильные. но если в игре был Замена(а, б), то ассемблер соберет его как Замена(б, а) и тогда при сравнении байт в байт два рома - оригинальный и после разборки и сборки - будут различия. это меня огорчает. ну и дальше там тоже какие-то ошибки находил в каких-то функциях... не помню детали. там впрочем все косячники... и IDA и сам ASM68K.exe и даже в шелловском Gens - там вообще швах как команды разбирает. поэтому подумал хорошо бы чтоб в одном флаконе сразу и разбирало и собирало, и чтоб итоговый результат был один в один. ну а дальше уже настигла печаль работы с итоговым кодом... все работает супер медленно и раздражающе. и полетело оно, как обычно, ко всем другим проектам в долгий ящик. но это уже совсем другая история :)
Turbo2000:
Это невозможно из-за абсолютной адресации (+ может быть неоднозначная интерпретация кода и данных, + есть неиспользуемый код, или код, который косвенно вызывают, рассчитывают по адресу в рантайме), если бы можно было сделать трейс игры (и то это все не покроет), и восстановить код, может быть когда-нибудь будут такие инструменты, а пока есть ида :)

Добавлено позже:

--- Цитата: Turbo2000 от 28 Октябрь 2024, 18:07:31 ---сравнении байт в байт два рома - оригинальный и после разборки и сборки - будут различия. это меня огорчает.
--- Конец цитаты ---
Да можно было бы так сделать, но надо все двигать, а чтобы можно было двигать, надо делать именнованные метки, в общем, все как обычно  :D :neznayu:


Добавлено позже:
Понятно, что будут различия, но если смотреть секторами, то все будет одинаково
SeregaZ:

--- Цитата: Turbo2000 от 28 Октябрь 2024, 18:07:31 ---Это невозможно
--- Конец цитаты ---
в моем случае разбор был пока-что тот, что при старте игры начинается. а вот как раз те, что просчитываются - нет. остаются необработанными кусками. может быть когданибудь докручу эмулятор, чтоб как в Иде, тем более что были не так давно продвижки с влезанием в оперативку приставки в эмуляторе, то значит можно будет и найти тот кусман, где эти адреса рожаются в шелловском эмуляторе. там правда дизассемблит криво, но это уже хоть что-то - какая-то подсказка где эти адреса лежат, чем в слепую тыкать мышкой в необработанный кусман и жмакать "определить", в надежде что это код, а не данные или какой-то другой мусор. так вот с тем кодом, что изначальный - все хорошо разбирает, и после потом ASM68K.exe собирает и получается один в один... за исключением некоторых ошибок в самом ASM68K.exe, что я описал.

по моему видос еще до того как докрутил функцию разбора кода в ручную, тыкнув куда-то мышкой.
Томахомэ:
Вы таки будете смеятся, но то, что я принял за баги трансляции команд addis andis. оказалось вовсе не багами, а просто дурной привычкой MAME'овского дизассемблера упрощать некоторые команды.

--- Код: ---else if ((op & ~(M_RT|M_RA|M_SIMM)) == D_OP(15))
{
if (G_RA(op) == 0)
{
mnem += "li"; // addis rT,0,value -> li rT,(value<<16)
oprs = util::string_format("r%d,0x%08X", G_RT(op), value << 16);
}
else
{
mnem += "addi";   // addis rT,rA,SIMM -> addi rT,rA,SIMM<<16
oprs = util::string_format("r%d,r%d,0x%08X", G_RT(op), G_RA(op), value << 16);
}
}
--- Конец кода ---

--- Код: ---else if ((op & ~(M_RT|M_RA|M_UIMM)) == D_OP(29))
{
mnem += "andi.";  // andis. rA,rT,UIMM -> andi. rA,rT,UIMM<<16
oprs = util::string_format("r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16);
}
--- Конец кода ---
Томахомэ:
Ну вот, братцы, допилил я таки свой ассемблер (в той, правда мере, в какой это касается общих для семейства MIPS в целом команд - специфические для Emotion Engine и спекоманды для сопроцессоров ещё только предстоит добавить) , испытал на работоспособность и подчистил "хвосты" от исходника ассемблера ARM, на который ориентировался, как на единственную дотоле присутствовавшую среди поддерживаемых ASMX RISC-архитектуру.

Исходник и готовый EXE-файл - в прикреплённом архиве.
Томахомэ:
Кстати, об ассемблере ARM - а у него есть вообще способ загрузить командой mov полноразмерное 32-битное число, где все 16-ричные цифры были бы разные?

Просто, как оказалось, соответствующий модуль у ASMX откровенно сырой и недопиленный - на данном этапе загрузить таким способом в регистр можно только однобайтные числа. Допилить за Томлином самому мешает тот факт, что структура такого типа опкодов у ARM специфическая (см. главу Data Processing), и далеко не всякое 32-битное число можно "ужать" до 8-битного методом банальной прокрутки.


--- Код: ---long ARMImmed(unsigned long val)
{
    // note: can't abort assembling instruction because it may cause phase errors

    if ((val & 0xFFFFFF00) == 0)
        return (val & 0xFF);
    else
    {
        // FIXME: need to handle shifts
        // bit 25 (I) = 1
        // bits 8-11 = rotate (immed8 is rotated right by 2 * this value)
        // bits 0-7 = immed8
        // the smallest value of rotate should be chosen
    }

    Error("Invalid immediate constant");
    return 0;
}
--- Конец кода ---
Dyons:

--- Цитата: Томахомэ от 19 Декабрь 2024, 12:13:30 ---Кстати, об ассемблере ARM - а у него есть вообще способ загрузить командой mov полноразмерное 32-битное число, где все 16-ричные цифры были бы разные?

--- Конец цитаты ---
тебе в какой регистр грузить то надо?
Томахомэ:

--- Цитата: Dyons от 19 Декабрь 2024, 12:26:25 ---тебе в какой регистр грузить то надо?

--- Конец цитаты ---

Загрузить число $4000000 (адрес регистра DISPCNT у GBA) в R0 - чтобы подготовиться к переводу в режим битмэпа. А ведь кроме DISPCNT,  видеорегистов есть ещё штук 40 (то есть с адресами $40000xx), и фиг ещё знает, какие понадобятся в дальнейшем - в случае с ними одной прокруткой точно не обойдётся.
Томахомэ:
Таааак, с загрузкой больших чисел в регистры вроде разобрался (хоть эта процедура и получилась очень уж многоступенчатой),  и даже с прерываниями. Остаётся только вопрос - почему выбранный кусок изображения всё ещё не выводится на экран?
Томахомэ:
Пошуровав немного по официальной документации по PS2 (см. прикрепления), решил проверить на работоспособность код отрисовки простейшего прямоугольника.

--- Код: ---org $bfc00000
lui t0, $1000
ori t0, t0, $3000
addi t1, t1, $6
sb t1, 0(t0)
addi t1, zero, $ffff
lui t1, $ff
addi t3, t3, $100
lui t4, $100
sb t1, 1(t0)
sb t2, 5(t0) ; 1st vertex
or t5, t4, t3
sb t1, 1(t0)
sb t5, 5(t0) ; 2nd vertex
sb t1, 1(t0)
sb t4, 5(t0) ; 3rd vertex
sb t1, 1(t0)
sb t3, 5(t0) ; 4th vertex
j $
--- Конец кода ---

Поскольку формировать исполняемые файлы я ещё не научился, скормить код решил попробовать через подставной псевдобиос. При таком раскладе экран почему-то (проверял на PCSX2) как был, так и остаётся чёрным. Никаких предварительных действий для активации экрана делать не надо?
Томахомэ:
Решил тут в ассемблерном модуле для PowerPC реализовать полноценную поддержку постфиксов o, ., a, l, и т. д., чтобы сэкономить размер на базе опкодов и немножечко даже на коде. Однако, почему-то если без постфикса собранный ассемблер ещё нужную инструкцию воспринимает, то с постфиксом - один сплошной Illegal opcode.
Пробовал я реализовать поддержку постфиксов разными способами, начиная с этого -
--- Код: ---oldLine=linePtr;
             if (GetWord(word) == 'O') parm=parm|0x400;
             else linePtr=oldLine;
             if (GetWord(word) == '.') parm=parm|1;
             else linePtr=oldLine;
--- Конец кода ---
- однако ни один по итогу не сработал.

В текущем своём сильно промежуточном состоянии ассемблерный модуль PPC прикреплён ниже.
Навигация
Главная страница сообщений
Предыдущая страница

Перейти к полной версии