Оригинальный Kenbak-1
Оригинальный Kenbak-1

Kenbak-1 не имел ни экрана, ни клавиатуры, ни даже микропроцессора (в современном понимании), но это не помешало ему войти в историю, как первый персональный компьютер. В статье я расскажу о том, как создал уникальный iOS‑эмулятор Kenbak-1, что послужило мотивацией к этому, о деталях реализации, и почему это устройство поможет вам понять фундаментальные принципы работы современной вычислительной техники.

Оригинальный Kenbak-1

 Джон Бланкенбейкер со своим творением
Джон Бланкенбейкер со своим творением

В 1971 году инженер Джон Бланкенбейкер создал и выпустил компьютер Kenbak‑1 — устройство, которое сегодня признают первым персональным компьютером в истории.

Цель создания была образовательной: Бланкенбейкер хотел показать, как работают вычислительные машины, и дать людям возможность познакомиться с основами вычислительной техники. Он стремился сделать компьютер не для крупных организаций, а для индивидуального использования ‑ чтобы с ним мог работать один человек без специальной подготовки.

Всего выпустили около 40 — 50 экземпляров по цене 750 долларов за штуку. В масштабах индустрии это очень мало, и коммерческого прорыва не случилось — массового спроса тогда ещё не существовало.

Тем не менее идея «компьютера для одного человека» оказалась пророческой: Kenbak‑1 вдохновил последующие поколения изобретателей и стал предтечей любительских ПК 1970‑х и 1980‑х годов (таких как Altair 8800 и Apple I).

Если есть желание узнать больше об оригинальном Kenbak-1 — на Хабре есть прекрасная статья, которой я вдохновлялся. Советую почитать!

Как возникла идея эмулятора

Сколько себя помню, мне всегда были интересны компьютеры, технологии и IT индустрия в целом. Уже в сознательном возрасте у меня появилась тяга к разным ретро‑девайсам. Хоть я и не застал золотой эпохи (мой первый компьютер был пресловутый Pentium на Windows XP), меня невероятно вдохновляет та особая атмосфера 70-80-х годов, в которой были разработаны и воплощены в жизнь многие легендарные технологии и устройства. Внешний вид, функциональность, инженерные и дизайнерские решения — это был настоящий расцвет вычислительной техники и персональных компьютеров в частности.

Вечерами я засматривал до дыр ролики на YouTube с обзорами старых компьютеров: Commodore 64, Psion 5mx, ZX Spectrum. Я никогда не держал их в руках, но ясно чувствовал: эти творения стоят на вершине инженерного искусства.

Однажды в одном из таких видео мне попался Altair 8800 — устройство, необычное для моего восприятия. Сознание привыкло, что компьютер — это клавиатура и экран (пусть и в виде подключаемого телевизора), а здесь были только переключатели и светодиоды. Как это программировать?!

Altair 8800 - микрокомпьютер, разработанный компанией MITS
Altair 8800 - микрокомпьютер, разработанный компанией MITS

Внешняя эстетика Altair 8800 (красивее для меня разве что PDP-11/70) заставила меня углубиться в его устройство и принципы работы. Я нашёл цикл видео о том, как он функционирует и как на нём программировать, затем отыскал онлайн‑эмулятор и попробовал писать программы машинным кодом. Это стало для меня открытием нового мира.

Вскоре я осознал, что пользоваться онлайн‑эмулятором удобно лишь дома. А мне хотелось изучать программирование машинными кодами в пути — в метро, в перерывах на работе, иметь быстрый и лёгкий доступ к компьютеру на ходу. Так родилась идея найти эмулятор для iOS. К сожалению, подходящего приложения не оказалось — и я решил создать его сам.

Но когда я начал разбираться с внутренним устройством Altair 8800 и оценил будущий объём работы, стало ясно: задача слишком масштабна для меня. Тогда я стал искать альтернативы.

И тут я наткнулся на Kenbak‑1. Изучив информацию о нём, я понял: по сути он очень похож на Altair 8800 — те же органы управления и вывода данных, программирование машинным кодом, — но при этом значительно проще в реализации. Его минимализм стал решающим фактором. Решение было принято: я начал разработку iOS‑эмулятора Kenbak‑1.

Устройство эмулятора

Технические моменты:

  • язык программирования — Swift

  • среда разработки — XCode 16

  • реализация UI — SwiftUI + UIKit, использование CADisplayLink для синхронизации обновления состояния панели с обновлением экрана смартфона (для снижения энергопотребления)

  • реализация процессора — полная эмуляция всех инструкций процессора в соответствии с документацией по оригинальному Kenbak-1

  • тестирование — написан тестовый модуль, покрывающий все инструкции процессора

Главный экран

Главный экран приложения - адаптированная передняя панель Kenbak-1
Главный экран приложения — адаптированная передняя панель Kenbak-1

В своих проектах я редко заранее прорабатываю пользовательский интерфейс. Действую, обычно, по наитию, создавая UI на ходу, на свой вкус.

В виду особенностей экрана смартфона пришлось разместить группы кнопок в два ряда, а не в один, как в оригинале.

В верхней части реализован информационный бар: текущее значение светодиодной панели в разных системах счисления, выбранный регистр (на Kenbak-1 их всего 9), выбранная инструкция процессора, а также текущее значение регистра PC.

Набор регистров Kenbak-1
Набор регистров Kenbak-1

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

Экран Program

Экран Program с возможностью сохранения и выгрузки программ
Экран Program с возможностью сохранения и выгрузки программ

На экране «Program» есть возможность сохранять и выгружать из памяти ранее написанные программы. Хранятся они в UserDefaults в ��иде полного дампа памяти. Благо объем одного дампа небольшой — всего 256 байт, поэтому чтение/запись мгновенные.

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

Если возникнет желание обновить уже сохраненную программу — это можно сделать введя то же имя при сохранении — приложение попросить вас подтвердить намерение и обновит дамп памяти.

В целом реализация этого модуля не содержит каких‑то особых решений.

Экран Memory Dump

Полный дамп памяти компьютера
Полный дамп памяти компьютера

На экране «Memory Dump» можно увидеть полный дамп памяти компьютера. В каждой ячейке данные отображаются в восьмеричной и десятеричной системах счисления. Есть возможность пошагово выполнять программу, чтобы следить как меняются данные.

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

Модель памяти реализована в приложении довольно просто:

typealias Byte = UInt8

final class Memory {
    
    private var memory: [Byte]
    
    init() {
        memory = .init(
            repeating: .zero,
            count: KenbakConstants.memorySize
        )
    }
    
    subscript(address: Address) -> Byte {
        get { memory[Int(address)] }
        set { memory[Int(address)] = newValue }
    }
    
    func clear() {
        memory = .init(
            repeating: .zero,
            count: KenbakConstants.memorySize
        )
    }
    
    func setDump(_ bytes: [Byte]) {
        bytes
            .enumerated()
            .forEach { index, byte in
                memory[index] = byte
            }
    }
    
    func getDump() -> [Byte] {
        memory
    }
}

Экран Settings

Экран настроек эмулятора
Экран настроек эмулятора

На экране настроек есть возможность изменить скорость работы процессора. В оригинальном Kenbak-1 скорость была около 480 инструкций в секунду.

Можно как понизить скорость до 1, так и повысить до 1000 инструкции в секунду. Это позволяет наглядно наблюдать работу процессора во время выполнения программы, что несет большой образовательный момент.

Реализация нужной частоты процессора достигается за счет использования функции usleep с нужным параметром задержки:

usleep(useconds_t(850_000 / AppSettings.shared.processorSpeed))

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

Экран Info

На экране информации есть описание приложения и набор оригинальной документации
На экране информации есть описание приложения и набор оригинальной документации

Чтобы не искать и не хранить информацию о Kenbak-1 я включил в состав приложения набор оригинальной документации по компьютеру от самого Джона Бланкенбейкера.

Это три документа в формате PDF, которые можно открыть прямо из приложения:

  • Инструкция к оригинальному Kenbak-1 c объемной теорией по программированию

  • Инструкция по работе с процессором Kenbak-1 и программированию машинными кодами

  • Набор лабораторных упражнений с Kenbak-1, которые можно попробовать выполнить самому

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

Экран Select command

На экране выбора командны можно настроить нужную команду
На экране выбора командны можно настроить нужную команду

Пожалуй, самой удобной фичей приложения можно считать экран «Select command». Хоть в Kenbak-1 и не большой набор инструкций запомнить их все в виде машинных кодов будет сложно, а каждый раз возвращаться к табличке из документации не удобно.

Таблица построения машинного кода для инструкции
Таблица построения машинного кода для инструкции

Реализованный селектор команд позволяет очень быстро настроить требуемую инструкцию процессора и внести ее в память. Это значительно ускоряет набор программ и дает сосредоточиться на логике и алгоритмах.

Структура команды:

enum Command {
    
    case halt
    case nop
    
    case rotate(reg: Register, direction: Direction, places: UInt8)
    case shift(reg: Register, direction: Direction, places: UInt8)
    
    case set(bite: Bite, position: UInt8)
    case skip(onBite: Bite, position: UInt8)
    
    case jmk(reg: Register?, directional: Bool, conditionMode: ConditionMode)
    case jmp(reg: Register?, directional: Bool, conditionMode: ConditionMode)
    
    case lneg(addressingMode: AddressingMode)
    case or(addressingMode: AddressingMode)
    case and(addressingMode: AddressingMode)
    
    case store(reg: Register, addressingMode: AddressingMode)
    case load(reg: Register, addressingMode: AddressingMode)
    case sub(reg: Register, addressingMode: AddressingMode)
    case add(reg: Register, addressingMode: AddressingMode)
}

Что получилось?

Эмулятор Kenbak‑1 — это не просто цифровой артефакт из истории IT, а увлекательный инструмент для гиков и любознательных пользователей, которые хотят заглянуть в истоки вычислительной техники. Приложение переносит в 1971 год — к самому началу эпохи персональных компьютеров. Здесь нет современных абстракций: только чистая логика, биты и байты, переключатели и мигающие светодиоды.

Работа с эмулятором превращается в интеллектуальный вызов: вы программируете через виртуальные переключатели, считываете результат по индикаторам и шаг за шагом постигаете, как на самом деле устроены компьютеры. Такой формат — мощный тренажёр для алгоритмического мышления: он учит чётко выстраивать последовательности, отслеживать промежуточные состояния вычислений и отлаживать логику без привычных инструментов.

При этом обучение удобно и доступно: можно экспериментировать с машинным кодом где угодно — в дороге, на перерыве, дома. Вы можете в любой момент запустить приложение, проверить гипотезу или написать простейшую программу. 

А ещё это подлинно гиковский опыт: ощущение тактильности (пусть и виртуальной), радость от запуска первой программы на «железной» логике и чувство связи с пионерами IT. Простота Kenbak‑1 вдохновляет: она наглядно показывает, что даже с минимальными ресурсами можно создать полноценную вычислительную систему. Такой взгляд на прошлое помогает иначе увидеть настоящее — и найти идеи для собственных проектов.

Планы на развитие

Последняя версия была выпущена пол года назад. Я реализовал тот функционал, который был интересен и полезен именно мне.

За это время я не заметил интереса к приложению и не получал никакой обратной связи. Но несколько идей у меня есть:

  • Добавить перевод машинного кода в ассемблер для Kenbak-1 для более лёгкого восприятия

  • Реализовать некий интерфейс расширения (работу с WiFi, консоль и тп)

  • Возможность делиться файлом программы с другими пользователями

  • Добавить вшитый список интересных программ для изучения

Если вам этот эмулятор покажется интересным и у вас будут идеи — пишите в комментарии — может, я продолжу его развивать.

Заключение

Для меня ретро‑девайсы больше, чем просто интересные вещи — это символ эпохи, когда люди изобретали и воплощали в жизнь самые смелые инженерные и дизайнерские идеи. Это то, что навсегда останется в истории и будет греть душу таким гикам, как я. Я сделал этот эмулятор для себя и вложил в него много сил и кусочек своей души. И было бы очень здорово, если среди хабровчан есть такие же любители девайсов из прошлого, как я. Если да — обязательно попробуйте узнать этот компьютер поближе.

Если вам захочется скачать и попробовать этот эмулятор вот ссылка в AppStore. Приложение полностью бесплатное. Есть возможность запуска на iPadOS и MacOS (но наиболее удачно интерфейс выглядит на iOS).

Всех с наступающим новым годом и удачи нам всем!