Oberon 69 — интро, погружение

от автора

Данная статья, является логичным продолжением предыдущей, в которой я описал свою идею, мотивацию и начало процесса вхождения в увлекательный мир 8bit. Эта статья будет короткой, опишу процесс разгребания вступительного мультика с целью идентификации необходимых для перевода ресурсов. Ресурсов раз два и три, но тем не менее, начало есть начало.

Загружаем «PRES» в Ghidra по известному ранее адресу 0x9000, добавляем области памяти

в карту памяти

в карту памяти

Точка входа нам известна из прошлой статьи, это 35074 или $8902, смотреть будем в «декомпилированный» код, он компактнее, хотя и не всегда соответствует действительности

void main(void)  {   undefined *puVar1;   short in_DE;   byte (*paabVar2) [8] [32];   byte *pbVar3;      Set_Interrupts_and_Run();   CLS();   Clean8000to9000and5E00to6200();   Print_msg(&txt_FOR_CASSETTE);   Colors_Fading();   Print_msg(&txt_PRESENTS);   Colors_Fading();   Sprite(0,7,10);   Sprite(1,10,0xe);   Print_msg((HDmessage *)&txt_Delay);   Colors_Fading();   FUN_ram_9b7c(in_DE);   DAT_ram_ac2c = 200;   DAT_ram_ac2d = 0x10;   DAT_ram_ac41 = 0xe0;   DAT_ram_ac42 = 0x10;   DAT_ram_ac56 = 0xf0;   DAT_ram_ac57 = 0x10;   DAT_ram_ac6b = 200;   DAT_ram_ac6c = 0x10;   do {     FUN_ram_9a4d();     BYTE_ram_9620 = 1;     halt();     halt();   } while (0x27 < DAT_ram_ac2c);   Print_msg((HDmessage *)&txt_Delay);   Colors_Fading();   FUN_ram_9b8f(in_DE);   DAT_ram_ac2c = 0;   DAT_ram_ac2d = 0x28;   DAT_ram_ac30 = 1;   DAT_ram_ac41 = 0;   DAT_ram_ac42 = 0x28;   DAT_ram_ac45 = 1;   DAT_ram_ac6a = 0xfd;   DAT_ram_ac55 = 0xfd;   do {     FUN_ram_9a4d();     BYTE_ram_9620 = 1;     halt();     halt();   } while (DAT_ram_ac40 != -3);   Print_msg(&txt_START_TAPE);   pbVar3 = &DAT_ram_b192;   paabVar2 = SCR_BITS;   puVar1 = &DAT_ram_1b00;   do {     *(byte *)paabVar2 = *pbVar3;     paabVar2 = (byte (*) [8] [32])((short)paabVar2 + 1);     pbVar3 = pbVar3 + 1;     puVar1 = puVar1 + -1;   } while (puVar1 != (undefined *)0x0);   disableMaskableInterrupts();   setInterruptMode(0);   enableMaskableInterrupts();   return;

Нас интересуют Print_msg и Sprite. Print_msg принимает ссылку на адрес комбинированной строки в регистре HL

        ram:9a9c       LD                     HL,txt_FOR_CASSETTE         ram:9a9f       CALL                   Print_msg         ram:9aa2       CALL                   Colors_Fading         ram:9aa5       LD                     HL,txt_PRESENTS         ram:9aa8       CALL                   Print_msg         ram:9aab       CALL                   Colors_Fading

Текст может содержать в себе заголовок со всем необходимым

и даже больше

и даже больше

В тексте могут содержаться маркеры, которые могут задать 1 — координаты на экране для вывода сообщения, 2 — цвет, как фона так и текста, стандартный байт аттрибута, 3 — размер шрифта, сообщение может выводиться с увеличением высоты символа в x раз, 6 — задержка, 0 — закончили с текстом. Знакогенератор находится по адресу 0xAC7E

красота красивая

красота красивая

Со спрайтами чуть проще, координаты задаются при вызове функции, координаты измеряются не в точках а в знакоместах, как у текста, скорее всего, чтобы не заморачиваться с клэшингом. Необходимая нам процедура Sprite принимает номер спрайта и координаты в регистрах A, B, C

        ram:9aae       LD                     A,0x0         ram:9ab0       LD                     B,0x7         ram:9ab2       LD                     C,0xa         ram:9ab4       CALL                   Sprite         ram:9ab7       LD                     A,0x1         ram:9ab9       LD                     B,0xa         ram:9abb       LD                     C,0xe         ram:9abd       CALL                   Sprite

Адреса спрайтов получаются складыванием базового адреса 0xAA9c и смещение из таблицы смещений по адресу 0x9889

        ram:9889       ushort[3]            ram:9889 [0]                0h,   146h,   190h 

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

        ram:aa9a       HDRsprite            ram:aa9a                 db        Ch                      width            ram:aa9b                 db        3h                      height         ram:aa9c       ??                     0Fh         ram:aa9d       ??                     F0h         ram:aa9e       ??                     FFh

Colors_Fading осуществляет «красивую» очистку экрана, с переливающимися цветами. Вроде всё рассказал… Далее будет разбор файла самой игры, или сначала загрузчик переделаю, ещё не решил. Ниже текстовые сообщения, спрайты в заголовке статьи.

начало

начало
середина

середина
финалочка

финалочка

1 часть

2 часть


ссылка на оригинал статьи https://habr.com/ru/articles/936990/