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

  • Tutorial

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

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

В те годы компьютеры использовались лишь учеными и инженерами на больших предприятиях. И тут появляется компьютер, купить который может любой желающий. 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:

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

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

Получаем код команды 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. Его можно запустить прямо в браузере:

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

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

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

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

В 1975 г Билл Гейтс и Пол Аллан выпустили интерпретатор BASIC для ALTAIR, а в 1976 была основана компания "Micro-Soft". Началась новая страница в истории IT.

Заключение

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

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

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

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

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

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 35

    +1
    думаю обычно телетайп подключали
      0

      Не думаю, что тогда массово у частных лиц были телетайпы.

      +2
      1975 год. М-да уж. Мы в универе в 1996ом почти на таком ПК лабы творили — УМК назывался, тоже на 8080
        0
        Мы в универе работали на УМК и в 2000-ом. Тоже воспоминания нахлынули по мере чтения статьи :-)
          0
          Мы на УМК лабы делали в 2007 :)
            +1
            УМК! — не стареет в отличие от нас :)
            Можно саркастически издеваться конечно, но ИМХО это на тот момент был нормальный вход в микропроцессорную технику. На листочке накидал прогу в ассемблере, перевёл в процессорный шестнадцатеричный код по табличке, ввёл прогу кнопочками, запустил и либо радуешься, либо нет. Где косяк никто не подскажет если что-то не так. И тут как раз могут выделиться студенты знающие об макроассемблерах для РС, об отладчиках и т.д.
            Сейчас конечно УМК на пенсию пора, надо сразу приучать к современным МК и IDE
              0

              Нас в 2000 году заставляли так на железном pdp-8 тренироваться

                0
                и либо радуешься, либо нет
                Это просто цитата к миру IT и программирования!

                А про УМК, Вы это имеете ввиду?
                  0
                  Да да, он самый
            +1
            первая версия ALTAIR не имела ни клавиатуры, ни экрана, только панель тумблеров, как на фото

            Так ни в какой не было экрана и клавиатуры, не только в первой, как и не было собственно версий, разве нет?

            Для компьютеров того периода нормой была работа со внешним терминалом по последовательному порту. Объединение терминала с микрокомпьютером в единую конструкцию произошло где-то во времена Apple I (1976), а в Apple II терминальная прослойка была устранена, и компьютер уже сам занялся опросом клавиатуры и выводом на экран, что сформировало привычный формат последующих домашних микрокомпьютеров 80-х.
              0

              Бонусом-фичей оригинальной реализации "стеклянного терминала" на сдвиговых регистрах в Apple I был аппаратный скроллинг. Для "обычной" параллельной видеопамяти IMHO самым удобным было решение в Amstrad PCW — хранить указатели на начало каждой строки. Прекрасно подходит для гладкого попиксельного скроллинга.

                0
                Кстати, отечественный ПК «Вектор-06ц» имел аппаратный скроллинг по такому же принципу.
                0
                Вот, С. Возняк и изобретал дешевый видеотерминал к Альтаиру.
                А пока изобретал, ему попался в руки 6502 за четверть цены от 8080, и заверте…
                +3
                Та самая компиляция первого компилятора восемью рубильниками
                  0

                  Интересно, как тогда обстояло в США со стабильностью электропитания? Во времена Спектрума, если при вбивании страниц хекс-кодов из журнала кончалось электричество, это вызывало печаль-огорчение. А если бы они еще и переключателями забивались…

                    0
                    Также как и сейчас, напряжение в розетке пропадает не каждую пятилетку. Броски напряжения — несколько раз в год. Просадка напряжения ниже номинала- не скажу. В логе работы бесперебойника за последние 5 лет таких событий нет. Но наверняка от конкретного места зависит.
                      0
                      вам повезло, у меня до 250 при котором срабатывает реле напряжения поднимается раз в пару месяцев точно, и это в квартире, в спб
                  0
                  Даже просто умножить 2 числа, если у процессора нет готовой команды для этого, будет поинтереснее любой задачи про гномиков, не говоря уже про написание кода «на бумажке».
                  Это да, если заниматься любимым занятием — изобретением велосипедов ;)
                  INTEL 8080 assembly language manual
                  SOFTWARE MULTIPLY AND DIVIDE (page 53)


                    0

                    del

                      +2
                      Вот не знаю, нафига оно мне до сих пор надо, но машинный код 8080 (оно же 580ВМ80) до сих пор читаю, а началось всё в 1987-м году с Радио-86РК. :) Главное знать, откуда начать.
                        0
                        Именно для Радио-86РК пытался на ручном программаторе запрограммировать ПЗУ. Раз 10 ошибался, стирал, начинал сначала. Может бы до сих пор этим занимался, но мне друг на работе запрограммировал.
                        –1
                        Я все-таки сжульничал и скачал готовый компилятор, взять который можно здесь (полезно также посмотреть пример использования). Но как можно видеть, и на бумажке «скомпилировать» программу вручную вполне реально, хотя конечно, это и заняло бы куда больше времени.

                        Компиляция и компилятор — это процессы и программы, которые переводят с высокоуровневого языка на язык ассемблера. Эти слова неприменимы к процессу непосредственной сборки машинного кода из инструкций ассемблера.
                          0

                          От определения зависит. В некоторых слова "высокоуровневые" нет и перевод в машинные/бинарные коды.

                            0
                            Может быть в каких-нибудь современных словарях, написанных людьми, которые в глаза ассемблера не видели? Я не помню, чтоб 20+ лет назад кому-нибудь в голову пришло сказать про «компилятор» ассемблера. Тогда это были всё отдельные инструменты, которые можно было пощупать. Был ассемблер и писали «на языке ассемблера». Были компиляторы, которые могли вообще в тот же файл ассемблера скомпилировать для проверки/правки, был отдельный linker и т.д.
                              0
                              про «компилятор ассемблера» действительно никто не говорил (хотя транслятором его иногда называли. но чаще — просто ассемблером). но я и не слышал, чтоб компилятор обязательно «переводил с высокоуровневого языка на язык ассемблера».
                              Да, такие были — например, Small-C, но далеко не все — большинство компиляторов генерировало перемещаемый объектный код, обрабатываемый затем линкером. Меньшинство, которое генерило ассемблерный код, часто использовалось для кросс-компиляции (подготовки на одной системе программ для другой системы).
                                0

                                Что было 20-30 лет назад уже не актуально, наверное, но даже тогда мы говорили "компилируется", поскольку слабо отличались процессы: на входе человекочитаемый текст на языке программирования, на выходе — нечитаемый бинарный код.

                            +1
                            У нас на кафедре в 80-х были такие:
                            СПМ-80 (система проектирования микропроцессорных устройств)
                            Извиняюсь, только ссылку на гугледиск получилось дать.
                            photos.app.goo.gl/ChT4HkVzjJRFKVFKA


                              0
                              Я в ВУЗе такой фигнёй в 2003 году занимался, была лабораторная работа на микропроцессорном комплекте, советском клоне DEC, pdp-11 или что то типа, тоже прогу писали на ассемблере на листочке, переводили в код и вбивали в ячейки памяти, запускали и смотрели результат в регистре. Занимательно, но никакого практического смысла.
                                +1
                                Ну почему нет практического смысла?
                                Сразу видно, как работают все эти ассемблеры-трансляторы-компиляторы.
                                Если в двоичный вид перевести опкоды — понятно, как декодер команд работает.
                                Без абстракций, даже макроассемблеров и символьных имен, более понятно, как процессор обрабатывает данные, куда их надо положыть и откуда забрать по исполнении программы.
                                И вообще ассемблер должен быть вторым языком у программиста, чтобы уметь думать, как машына.
                                  0
                                  На Ассемблере писал достаточно сложные вещи, типа записной книжки с контактами, но в 21 веке его изучать особо смысла нет, Си решит 99% его задач.
                                    0
                                    знание ассемблера зачастую помогало понять, почему на том же Си написано «именно так». И помогает понять, как надо писать. Т.е. вещь не столько практическая, сколько «базово-общеобразовательная». Ну и, конечно, нишевая. Но тут — как с матаном: может, применять никогда и не будешь, но он мозги в порядок приводит.
                                +1
                                          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     
                                

                                
                                          DCR B
                                          JNZ LOOP
                                

                                И ячейка STEP вместе с регистром C становятся не нужны. Прошу прощения за занудство :)
                                  +1
                                  START:
                                          LDA    I
                                          MOV    B,A
                                          SUB    A
                                  LOOP:
                                          ADD    B
                                          DCR    B
                                          JNZ    LOOP
                                  PEND:
                                          STA    SUM
                                  PWAIT:
                                          JMP    PWAIT
                                  

                                  Ещё раз прошу прощения за занудство :)
                                    0
                                    Ожидал, что первая программа под Альтаир будет на том самом Бейсике.
                                      +1
                                      Я не настолько стар, чтоб на подобном работать, но когда-то примерно так программирование микроконтроллеров осваивал) Тоже все было вслепую, никаких отладчиков тогда еще не было. А если еще и единственный уарт был занят чем-то — вообще мрак начинался. Кто практиковал отладку через светодиод — поймут.

                                      Only users with full accounts can post comments. Log in, please.