Пишем программу для компьютера ALTAIR 8800 1975г выпуска

Привет, Хабр.

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

oyriie2gwnkaxvbve5e7cb9aqsw.png

В те годы компьютеры использовались лишь учеными и инженерами на больших предприятиях. И тут появляется компьютер, купить который может любой желающий. Altair 8800 содержал процессор 8080, 256 байт памяти в первой версии, и имел цену ниже 1000$ — это был первый успешно продаваемый персональный компьютер. Это был тот самый компьютер, для которого Билл Гейтс и Пол Аллен разрабатывали язык BASIC, компьютер благодаря которому сотни и тысячи увлеченных студентов и школьников пришли в мир программирования.

Разумеется, дешевизна имела свою цену — первая версия ALTAIR не имела ни клавиатуры, ни экрана, только панель тумблеров, как на фото. Стало интересно разобраться, как же написать и запустить программу на таком ПК. Для тех, кто хочет узнать как это работает, продолжение под катом.

Код

Первым доступным языком был лишь Ассемблер. ALTAIR мог иметь до 64 КБайт памяти, и процессор 8080, работающий с тактовой частотой 2 МГц.

Чтобы лучше понять как это работает, я написал несложную программу, вычисляющую сумму чисел от 1 до 5:

; Code segment:

        ORG    0o       ; Set Program Counter to address 0
START:  LDA    I
        MOV    B,A      ; RegB => I (1..N)
        LDA    STEP
        MOV    C,A      ; RegC => STEP (always 1)
        LDA    SUM
        MOV    D,A      ; RegD => SUM (result)
LOOP:     MOV    A,D      ; Move value to Accumulator from Register D (SUM)
          ADD    B        ; Add value in Register B to value in Accumulator
          MOV    D,A      ; Save result back to D     I
          MOV    A,B      ; Mov B to A and decrement it
          SUB    C
          JZ     PEND     ; If A is zero, the calculation is complete
          MOV    B,A      ; If not, continue
          JMP    LOOP     
PEND:   MOV A,D         ; Save result in SUM value
        STA SUM
PWAIT:  JMP PWAIT       ; Nothing to do, infinite loop

; Data segment:

        ORG    200o     ; Set Program Counter to address 200
I:      DB     5o       ; Data Byte at address 200 = 5
STEP:   DB     1o       ; Data Byte at address 201 = 8 (10 octal)
SUM:    DB     0o       ; Data Byte at address 202 = 0

        END             ; End

Как можно видеть, я создал в памяти 3 переменные, I, STEP и SUM, которые используются для организации цикла от 1 до 5 с шагом 1. Далее эти значения загружаются в регистры B, C и D, с которыми и производятся арифметические операции. Команда JZ (Jump if Zero) завершает цикл, когда значение регистра А становится равным нулю. Последним шагом мы записываем результат обратно в ячейку памяти с именем SUM. Кстати, для ячеек памяти (data segment) мы указываем адрес первой ячейки, который в нашем случае равен 200o («o» здесь это octet, 8-ричная система счисления).

В общем, вышенаписанный код делает то же, что в Python можно записать одной строкой:

s = sum(range(6))

Кстати забавно, что на Хабре нет подсветки синтаксиса для ассемблера, видимо было решено что вряд ли это кому-нибудь еще пригодится. Но пойдем дальше.

Компиляция

Строго говоря, никакого компилятора по условию задачи у нас нет, перевести команды в машинные коды придется вручную. К примеру, можно найти описание команды LDA:

v4gp1igmcekvbgyy6fyks8j0kci.png

Команда «LDA I», где I это ячейка памяти 200о = 80h, будет записана как 3A 80 00.

Следующая команда MOV B, A описывается так:

mlf9bi1u--cvvysfwuk5_o2e_so.png

Получаем код команды 01000111b = 47h

Я все-таки сжульничал и скачал готовый компилятор, взять который можно здесь (полезно также посмотреть пример использования). Но как можно видеть, и на бумажке «скомпилировать» программу вручную вполне реально, хотя конечно, это и заняло бы куда больше времени. В итоге мы должны получить следующий бинарный код:

3a 80 00 47 3a 81 00 4f 
3a 82 00 57 7a 80 57 78 
91 ca 18 00 47 c3 0c 00 
7a 32 82 00 c3 1c 00

Размер программы — 38 байт. Никаких префиксов MZ, переключения страниц памяти и прочего — программа просто выполняется с адреса 0. До того времени, когда чтобы запустить программу на устройстве, нужно подписать её платным сертификатом, было еще лет 40…

Загрузка и запуск

Для тестирования программы я воспользовался бесплатным симулятором ALTAIR 8800, скачать который можно с github. Его можно запустить прямо в браузере:

zesagkwl61n3i1md0fofabtuj7e.png

Еще раз повторюсь, в первой версии ALTAIR не было ни экрана ни клавиатуры. Все что доступно пользователю — это фактически панель прямого доступа к ячейкам памяти. Например, чтобы загрузить в ячейку памяти с адресом 1 значение 10001000b, нужно выставить соответствующие тумблеры и нажать тумблер DEPOSIT, чтобы ввести следующий код, нужно снова переключить тумблеры и нажать DEPOSIT NEXT. Чтобы прочитать значение ячейки памяти, есть соответствующий тумблер EXAMINE/EXAMINE NEXT. Запустить программу можно нажатием тумблера RUN или SINGLE STEP.

Скажу по секрету, перейдя в закладку DEBUG симулятора, можно загрузить программу в виде hex-файла целиком. Однако, желающим прочувствовать весь процесс до конца пришлось бы переключить тумблеры порядка сотни раз даже для такой небольшой программы.

Результат выполнения показан на скриншоте. Запускаем программу, затем выбираем тумблерами ячейку памяти 202о = 10000010b, нажимаем тумблер EXAMINE. В ячейках D7…D0 получаем значение 00001111b = 15, что соответствует искомой сумме чисел от 1 до 5:

ixmd2qq8hvg_1jwfhglqa88eepg.png

Реальные программы были, разумеется, гораздо сложнее. В компьютер можно было доустановить платы расширения, включающие модули памяти, дающие возможность подключения терминала, serial-порта, внешнего диска и пр.

Заключение

Знакомство с подобными технологиями оказалось довольно любопытно. Также, посмотреть как работает ALTAIR, было интересно и с профессиональной точки зрения — понять, насколько может современный программист писать код под систему почти 50 летней давности. И надо сказать, что это оказалось ничуть не проще. Даже просто умножить 2 числа, если у процессора нет готовой команды для этого, будет поинтереснее любой задачи про гномиков, не говоря уже про написание кода «на бумажке». И чтобы написать интерпретатор BASIC в таких условиях, нужно быть весьма незаурядным программистом.

Интересно, что ALTAIR не забыт и до сих пор. Кроме онлайн-симулятора, можно собрать и «железный», на базе Ардуино:

И наконец, симулятор ALTAIR входит в пакет simh, доступный для Linux, с помощью которого может быть удобно запускать программу по шагам в консоли и просматривать содержимое ячеек памяти:

yjzjj9v790in-eb-zya4d8tkzow.png

В общем, желающие могут поэкспериментировать самостоятельно.

Как обычно, всем удачных экспериментов.

© Habrahabr.ru