Архітектура та програмування Philips Videopac (Magnavox Odyssey 2)

Hardware software is just crystallized early»
— Alan Kay


Комп'ютер Magnavox Odyssey 2 (Videopac) з'явився в 1978 році і позиціонувався як ігровий, однак з можливістю більш серйозного застосування (для чого у нього була вбудована плівкова клавіатура). Серйозних додатків, враховуючи назначительный обсяг пам'яті, було дуже мало, так що, за фактом, правильніше вважати Videopac ігровою приставкою.

Що стосується назв, Magnavox Odyssey 2 продавався в США і видавав NTSC відеосигнал (через RF вихід). Philips Videopac G7000 (він же C52) продавався в Європі, відповідно, з PAL відео. Крім цього розходження (яке, звичайно, впливало на працездатність частини ігор) комп'ютери абсолютно однакові.

Videopac був однією з перших ігрових приставок, для якої ігри випускалися у вигляді картриджів з програмами. Тому нічого дивного, що і технічно це пристрій досить аскетично.

Процесор і пам'ять
Процесор являє собою мікроконтролер Intel 8048. Один час він був досить відомий, так як ставилося (в різних варіантах виконання) в усі PC XT і AT клавіатури.

8048 має досить простий набір інструкцій і мало режимів адресації. Архітектура гарвардська (на противагу більш звичної всім — фон-неймановской).

Вся пам'ять ділиться на три типи — програмна ROM (1kb BIOS на кристалі і до 8kb ROM у картриджах), внутрішня RAM (64 байта в самому микронтроллере, 32 байта з якої зарезервована під регістри і стек) і зовнішня RAM (128 байт статичного RAM, частково знаходиться за тими ж адресами, що і відеоконтролер).

Загальний обсяг ОЗП доступний програмістові в підсумку становить менше 160 байт, та й то використовувати його цілком досить складно.

Для доступу до кожного з типів пам'яті існують окремі інструкції (MOVP, MOV, MOVX). Тактова частота 8048 в Videopac часто вказується як 5.37 МГц, однак фактично (у сенсі виконання інструкцій) вона всього лише 0.358 МГц. При цьому, щоправда, більшість інструкцій виконується за 1-2 такти. Є дев'ять регістрів загального призначення — A, R0-R7.

Також на кристалі 8048 є таймер, два порти введення-виведення та схему управління перериваннями. Через порти здійснюється опитування двох джойстиків і клавіатури.

Неприємна особливість 8048 — поділ пам'яті на сторінки по 256 байт (не можна звертатися до комірки пам'яті знаходиться на іншій сторінці) і банки 2kb (для звернення до сусіднього банку необхідно перемикання командами SEL RB), що доводиться постійно враховувати.

Існує вітчизняний аналог 8048 — 1816ВЕ48.

Відео і звук
Іншим важливим компонентом системи є чіп Intel 8245 (він же 8244 для NTSC). Це видеоаудиоконтроллер з масочний ROM, який випускався спеціально для Videopac (тобто інших версій або прошивок, мабуть, не існує).


Відеоконтролер досить дивний навіть за мірками домашніх комп'ютерів 1980-х. приміром, в ньому немає, як таких, ні графічних ні текстових режимів. Всі сутності які він підтримує (sprites, chars, quads, grids) являють собою спрайт з тими чи іншими обмеженнями. У зв'язку з цим, такі «звичайні» операції як малювання точок у певному місці екрану або заповнення екрану текстом — неможливі. З-за цього навіть не можна безумовно говорити про дозвіл екрана (дуже умовно можна говорити про цифри типу 228 x 262).

Фактично, цей відеоконтролер не є універсальним і заточений під типові (дуже прості) гри. Він може формувати:

Sprites — традиційні апаратні спрайт 8x8 пікселів. Одночасно на екрані може бути 4 спрайту. Їх вміст, координати, колір можна міняти записом в регістри відеоконтролера. Кожен спрайт може бути будь-якого з восьми (яскравих кольорів.

Також є досить дивна (хоч і корисна) можливість, що дозволяє зрушити спрайт на половину (!) пікселя, або непарні рядки спрайту на половину пікселя щодо парних.

Chars — символи. Букви, цифри і деякі знаки (всього 63), образи яких зберігаються в ROM BIOS і не можуть бути змінені. Одночасно на екрані можуть відображатися не більше 12 символів. Як і спрайт, вони виводяться в будь-яке місце на екрані (з точністю до пікселя) але, на відміну від них, не можуть накладатися один на одного. Кожен символ може бути будь-якого з 8 (яскравих кольорів.

Адресу, звідки береться образ символу залежить від координати Y в яку символ виводиться і коду символу (!). Тому, для виведення символів або потрібно обчислювати цю адресу за хитрою формулою (особливо, якщо хочеться отримати частині символів), або користуватися подпрограммой BIOS.


Quads — групи символів, об'єднані за 4 штуки.

Grid — сітка 9 x 8 сегментів. Використовується для відображення лабіринтів, поверхів, сходів і т. п. Є режим, який дозволяє замість сітки відображати суцільні блоки — наприклад, для імітації шахової дошки. Вся сітка одного кольору. Тобто для всього grid задається один з восьми (темних кольорів.

Grid знаходиться на задньому плані (поверх фону, який може бути будь-якого з 8 кольорів), поверх grid виводяться символи і, на передньому плані — спрайт.

Є можливість відстежувати факт зіткнення об'єктів між собою (по одному біту-прапору на кожен тип об'єкта — без вказівки на конкретний).

Крім того, відеоконтролер дозволяє, з рядом обмежень, відстежувати положення променя не тільки по кадру, але і по рядках. У найпростішому випадку це використовується для малювання горизонтальних смуг (землі і неба, наприклад) шляхом зміни кольору фону в потрібні моменти.


Крім відео, 8245 також дозволяє генерувати примітивні звуки. Для цього є 24-розрядний циклічний сдвиговый регістр, який може тактуватися однієї з двох частот на вибір і перемикатися в режим генерації шуму. Таким чином, генерація довільній ноти фактично неможлива, хоча з деякими хитрощами можна отримати приемлимое наближення.

Гучність на виході загальна, може бути заданий один із 16 рівнів. Підпрограми BIOS дозволяють видавати кілька звуків, які можна почути в більшості ігор (писк, постріл, вибух).

Картриджі з іграми являють собою просте ПЗУ розміром від 2kb (найбільш типово) до 8kb. Крім картриджів, для Videopac існує два периферійні пристрої — синтезатор мови (LPC стиснення, ПЗУ зі словами) і модуль шахового комп'ютера (з власним процесором z80).

Розробка

Кращим є емулятором o2em, причому є версія з вбудованим відладчиком. Хоча це дійсно дуже пристойний емулятор, тим не менше, ситуація, коли досить простий код працює в ньому, але дає чорний екран або не ті кольори на реальному Videopac — досить типова. Так само може бути корисний емулятор 1816ВЕ48 («SCM — Single Chip Machine by DCA Laboratory»). Як асемблера краще всього використовувати AS (ASW).

Збірка і запуск виглядають так:

asw.exe -L -x %1.a48
p2bin.exe %1.p %1.bin -r 1024-3071
o2em.exe %1.bin -euro

Для перевірки коду на реальному пристрої були придбані Mateos Videopac Multigame Cartridge і Mateos Burner/Dumper (тобто емулятор ПЗУ і програматор для нього, з USB портом).

Також має сенс доопрацювати Videopac, зробивши composite або RGB вихід (в інтернеті багато схем). У порівнянні зі стандартним RF це дасть більш якісне зображення і більш правильні і чисті кольори.

При включенні комп'ютера (якщо вставити будь-який робочий картридж) на екрані з'являється кольорова напис «SELECT GAME» (якщо картриджа немає, на екрані в кращому випадку сміття).
Після натискання клавіші, відбувається перехід за адресою 0400h — першою адресою в ПЗУ картриджа.

Типова програма виглядає наступним чином:

; Hello World for Philips Videopac (Magnavox Odyssey 2), 8048 CPU
; by Frog ( https://github.com/petersobolev )
cpu 8048
org 400h
include "g7000.h" ; стандартні для Videopac константи
; вектора переривань
jmp selectgame ; RESET. Ініціалізація VDC, внутрішнього і зовнішнього ОЗП. Відображення написи "SELECT GAME" і очікування клавіші. Потім перехід за адресою 0408h, тобто на jmp start (код клавіші A).
jmp irq ;
jmp timer ;
jmp vsyncirq ;
jmp start ; викликається після відпрацювання selectgame
jmp soundirq ;
timer:
ret ; таймер не використовується
start:
call gfxoff ; необхідно щоб можна було писати в регістри VDC
mov r0,#010h ; початковий адресу в VDC відображуваного символу (одного з 12)
mov r3,#40 ; x
mov r4,#100 ; y
mov r1,#hellostr & 0ffh ; покажчик на рядок повинен бути на тій же 255 байтного сторінці)
mov r2,#11 ; довжина рядка 11 символів
nextchar:
mov a,r1
movp a,@a ; отримуємо A символ взятий за адресою зберігається в r1
mov r5,a
inc r1 ; збільшуємо адресу символу
mov r6,#0eh ; білий колір
call printchar ; друкуємо символ (одночасно збільшуючи r0 і r3)
djnz r2,nextchar
call gfxon ; зображуємо те, на що запрограмували VDC
loop:
jmp loop ; просто чекаємо
; 'HELLO WORLD' (ASCII рядка не підтримуються ассемблером)
hellostr:
db 01dh, 012h, 00eh, 00eh, 017h, 00ch, 011h, 017h, 013h, 00eh, 01ah

Додаток — інтро Rash
За результатами вивчення Videopac, мною була написана (для конкурсу на Chaos Constructions) 256 байтна інтро (відео, джерело).


В роботі використовуються три види графічних примітивів (з чотирьох реалізованих в видеоконтроллере i8245) — grid, sprites і chars. Не використовується лише quads (представляє собою різновид chars).

Падаючі зверху вниз чоловічки — не спрайт, як це може здатися, а символи (chars) розміром 8x8. Втім, в 8245 chars і sprites — споріднені поняття. Використовується максимально допустима кількість одночасно відображуваних chars — 12 штук. Всі вони беруться із стандартного знакогенератора (там є символи чоловічків), що економить як мінімум 24 байта. Це важливий момент, оскільки архітектура i8048 і формат картриджа Videopac зовсім не сприяють компактності коду. Зокрема, незважаючи на велику кількість регістрів (a, r0-r7), у ряді випадків можна використовувати лише деякі (a, r0, r1), тому утворюється досить багато «зайвих» інструкцій, ганяють дані з регістру в регістр.

Фон з мінливих помаранчевих квадратів реалізований через grid. Це апаратно генерується сітка 9x8 (у спеціальному режимі «шахового поля»), в якій по якомусь алгоритмом включаються ті чи інші сегменти. Пріоритет grid завжди найменший, тому чоловічки летять поверх неї.

Невдачливий, але безжурний котик являє собою два спрайту (8x8 кожен). При цьому дані для спрайтів під час руху періодично змінюються на інші (всього два кадру)), щоб імітувати рухаються лапи.

Зіткнення chars і sprites фіксується відеоконтролером, при цьому за певним алгоритмом змінюється колір спрайтів котика, а також скидається або встановлюється спеціальний біт, він зсуває парні рядки спрайту на полпиксела щодо непарних.

В якості звуку зіткнення використовується один із звуків, доступних через підпрограму BIOS (що економить ще кілька байт).

Крім того
Крім ігор, для Videopac існувало також декілька більш серйозних додатків — програма для виведення титрів у вигляді рядка, що біжить і програма для навчання програмуванню, про яку варто сказати особливо.

Картридж називається «Computer Programmer» і дозволяє вводити програму в машинних кодах (тобто навіть не на асемблері) і запускати її. До картриджа додавалася книжка з описом архітектури та інструкцій 8048.

Нагадаю, що це був цілком комерційний продукт, розрахований на покупців ігровий (!) приставки.

відео можна подивитися, як це працює.

Посилання
Тут можна подивитися мої роботи під різні ретро-платформи, а тут исходники на github.

p.s. Спасибі tnt23 за переробку відеовиходу Videopac з RF на композит.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.