8-битный компьютер с BASIC и VGA-выходом на Arduino
C помощью Arduino можно собрать 8-битный ретро-компьютер с Basic (похожий на ZX Spectrum) с выводом цветного изображения на VGA-монитор.
Кроме того, этот проект можно использовать как простой способ вывода текстовых сообщений на монитор.
Сама по себе, идея использовать Arduino для создания компьютера с BASIC не нова, но насколько я знаю, все они не поддерживают вывод цветного изображения. В некоторых проектах использовались LCD-мониторы, а в других — библиотека TVout, которая выводит чёрно-белое изображение. Кроме того, многие из этих проектов требуют дополнительные модули и специальные платы расширения. Тут же нужно всего-то иметь два Arduino, несколько резисторов, плюс разъёмы для PS/2 клавиатуры и VGA-монитора.
Для проекта нужно две платы Arduino: один будет основным (или «мастером»), в нём работает интерпретатор Tiny Basic Plus (это порт Tiny Basic на языке Си, адаптированный для поддержки Arduino). Также этот Arduino управляет PS/2 клавиатурой. Вывод из первого Arduino через последовательный порт отправляется на второй Arduino, который с помощью библиотеки VGAx генерирует VGA-сигнал.
Программу на языке BASIC в собранный нами компьютер можно будет ввести с помощью PS/2 клавиатуры, а результат можно будет посмотреть на VGA-мониторе: разрешение получившегося изображения 24 столбца на 10 строк, размер символов — 5х6 пикселей, доступно 4 цвета.
После введения программы, её можно будет сохранить в энергонезависимой памяти самого Arduino, а также код программы предусматривает управление I/O пинами Arduino.
1. Подключаем основной Arduino с интерпритатором TinyBasic и с PS/2 клавиатурой
TinyBasic Plus и библиотека VGAx работают с Arduino IDE 1.6.4.
Если у вас уже установлена более новая версия, то лучшее решение — загрузить эту версию с официального сайта в формате .zip, и распаковать в отдельную папку. Здесь можно загрузить эту версию для Windows.
Потом нам понадобится библиотека PS2keyboard, её можно загрузить отсюда. После скачивания просто распакуйте архив, и скопируйте его содержимое в «arduino-1.6.4\libraries».
Дальше, загрузите файл TinyBasicPlus_PS2_VGAx.ino, и прошейте его в основной Arduino.
Это версия обычного TinyBasic Plus, где была добавлена поддержка библиотеки PS/2.
Больше информации о TiniBasic Plus и руководства (на английском языке) можно найти тут.
Если на этом этапе нет проблем (в том числе, проблем с совместимостью), то Tiny Basic будет автоматически запущен при включении Arduino. И его можно будет протестировать с помощью последовательного порта на вашем ПК. Для этих целей я использую PuTTY, но вы можете использовать и другую подобную программу, по вашему вкусу.
В настройках нужно правильно установить COM-порт (тот же, что используется в Arduino), и скорость передачи = 4800.
И тут уже можно протестировать нашу систему, набрав какую-нибудь программу на Basic с клавиатуры вашего ПК (позже мы подключим PS/2 клавиатуру напрямую к Arduino).
Для примера, можно набрать:
10 PRINT "Hello, World!" 20 GOTO 10 RUN
Прервать бесконечный цикл этой программы можно с помощью комбинации клавиш Ctrl+C (это не сработает, если мы будем делать это с клавиатуры PS/2).
Теперь подключим PS/2 клавиатуру.
2. Подключаем PS/2 клавиатуру к основному Arduino
Информация и библиотека были взяты из этого материала.
По существу, вам нужно соединить следующие четыре контакта:
Data клавиатуры к Arduino pin 8,
IRQ (clock) клавиатуры к Arduino pin 3;
а также подключить землю (GND) и питание +5V, соответственно.
Я использовал PS/2 разъём cо старой нерабочей материнской платы, его можно легко сдуть с помощью фена.
Распиновка PS/2 разъема есть на рисунке:

3. Загружаем библиотеку VGAx и код во второй Arduino, и соединяем его с основным

Для начала, загрузите код VGAx-PC.ino и скопируйте его к себе на компьютер в папку с таким же именем.
Потом — загрузите с GitHub бибилиотеку VGAx. Её нужно поместить в подпапку «libraries» Arduino IDE.
ВАЖНО! Эта бибилиотека работает с Arduno IDE 1.6.4 и может быть не совместима с другими, более новыми версиями.
Теперь загрузите VGAx-PC.ino во второй Arduino (я тестировал на Arduino Nano, но с Arduino Uno тоже не должно быть проблем).
Предупреждение, что мало доступной памяти — это нормально для нашего случая. Если других ошибок нет, то всё в порядке — и можно сделать ещё пару шагов, чтобы получить свой собственный 8-битный ретро-компьютер.
Для этого нужно:

- два Arduino Uno Rev.3, или два Arduino Nano 3.x (на основе ATmega328)
- разъем DSUB15, т.е. гнездо VGA или кабель с таким гнездом, который не жалко отрезать
- резисторы: 2 на 68 Ом и 2 на 470 Ом
- разъем PS2
- провода
- необязательно: макетная плата
Осталось всё соединить по схеме на рисунке, и наш 8-битный компьютер готов!
Видео, как это всё работает:
Простые проекты на Arduino Uno
Этот раздел wiki — сборник простых проектов. Если у вас без дела пылится Arduino Uno, по нашим рецептам вы за несколько минут соберёте законченное устройство. Для сборки проектов не понадобятся инструменты, кучи компонентов и даже рабочий стол — мы обойдёмся без пайки и проводов.
Все скетчи к проектам подробно прокомментированы. Вы можете просто скопировать код и получить готовое устройство. А можете проанализировать программы — в таком случае наверняка найдёте полезные трюки и лайфхаки.
Какие железки используем
Все представленные устройства собираются на базе контроллера Arduino Uno и платы Slot Shield. В зависимости от проекта к ним добавятся от одного до шести Тройка-модулей — сенсоров и индикаторов.
Контроллер
Железки и скетчи протестированы на оригинальной итальянской Arduino Uno третьей ревизии. Если у вас неоригинальная плата — вероятнее всего, проекты будут работать, но гарантировать это нельзя.
Troyka-модули
Мы используем готовые элементы в формате Тройка-модулей. У них на борту все необходимые для работы элементы и обвязка для быстрого подключения к управляющей плате. У нас на выбор более сотни модулей — от простейших светодиодов, до систем спутниковой навигации. Единый формат модулей избавит от проблем с совместимостью. Ко всем модулям написаны библиотеки, которые упростят процесс программирования и сделают код простым и прозрачным.
Slot Shield
Проекты собираются на Slot Shield. Эта плата расширения крепится поверх Ардуино и выводит гребёнки пинов на удобные разъёмы. На Slot Shield можно установить от одного до шести модулей в разных комбинациях. Новая комбинация — новое устройство.
Разумеется, вы можете повторить проекты и на обычной макетке или Troyka Shield — соедините указанные в схеме пины обычными проводами и всё заработает.
1. Электронные часы. Как собрать…
…простые часы

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

Простые часы, с четырёхкнопочной клавиатурой. Кнопками можно изменить текущее время — отдельно часы и минуты.
Для проекта понадобятся:
…автономные часы

Электронный гаджет с модулем часов реального времени. На модуле предусмотрена батарейка, часы не собьются даже при отключении питания. Время настраивается с помощью четырёхкнопочной клавиатуры.
Для проекта понадобятся:
…электронный будильник

Часы с громкой пьезопищалкой. Текущее время и время срабатывания сигнала задаются с помощью четырёхкнопочной клавиатуры. За точность хода отвечает модуль часов реального времени.
Для проекта понадобятся:
…световой будильник

Электронный будильник с функцией имитации рассвета. За пять минут до установленного времени будильник деликатно увеличивает уровень освещённости в комнате. Сначала будит спокойным зелёным цветом, затем добавляет жёлтый, после — начинает светиться красным.
Для проекта понадобятся:
2. Метеостанция. Как собрать…
…простую станцию для компьютера

Подключим цифровой метеодатчик и выведем результаты на компьютер.
Для проекта понадобится:
…метеостанцию с дисплеем

Метеостанция, которая выводит температуру и влажность на компактный четырёхразрядный экран.
Для проекта понадобятся:
…автономную метеостанцию с барометром

Станция для метеозаисимых людей. Гаджет выводит на экран температуру, влажность и атмосферное давление.
Для проекта понадобятся:
…метеостанцию с внешним датчиком температуры

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

Меня зовут Евгений, я студент 4 курса МатМеха УрГУ(урфу). Примерно на первом курсе я понял, что меня завораживают старые компьютеры и старые технологии. Примерно тогда же я купил себе советский клон ZX Spectrum`а — Урал-8/64K.
ZX Spectrum, для тех, кто в танке, это совершенно легендарный компьютер, его знают и любят все, кто даже далек от этой всей компьютерной темы. Об этом, так же, говорит и наличие современной разработки компьютерных игр для него. В общем, много чего можно рассказать о нем, но не будем сильно отвлекаться. Так вот, купил я себе такой, поигрался, попрограммировал, мне понравилась его простота, какое понимание он дает о своем устройстве тем, кто впервые с ним работает.
Идея
Немного раньше я делал небольшие проекты на Arduino и думал над каким то достаточно большим проектом, но сильно не хотел делать еще одну «умную поилку для собаки«, которых в интернете наплодили достаточно, чтобы потерять всякий интерес к этому, не то, чтобы он до этого был большой. Я подумал, мне нравится Spectrum, так почему бы не сделать его эмулятор, софтверных эмуляторов полно, да и физических тоже хватает, но я решил посмотреть что есть и сделать свое. Я погуглил и нашел статью, которая и толкнула меня к первым шагам.
Что мне не понравилось в уже готовых аналогичных проектах, чтобы просто их реализовать:

- Абсолютно нечитаемый код на 2000+ строк кода в одном файле с кучей комментариев — иногда не только пояснительных но и кода.
- Мощные платы — в моей задумке было использовать простенькую Arduino Nano, а точно не Mega!
- Много плат — опять же хотелось использовать всего одну простую плату и вместить на нее все необходимое.
- Необходимость обновления прошивки при появлении новых программ для устройства — убивает внутреннюю flash память устройства, нужно что то другое.
Начинаем разбор
Посмотрев на различные проекты и доступное оборудование, я решил сделать симулятор не ZX Spectrum, а полностью придуманного вычислителя — со своей системой инструкций, способом коммуникации с оборудованием, и языком ассемблера, соответственно! Приступим к описанию того, как строилась система. Но прежде рекомендую ознакомиться с инструкциями процессора — это основной репозиторий проекта, дальше информация оттуда будет упоминаться.
Одну из проблем, которые я пытался решить — это износ внутренней flash памяти, но оперативной памяти мало для хранения программ написанных для нашего компьютера — её всего 2 кб! Так что я решил использовать SD карту. Изначально я думал хранить на карточке файловую систему и в ней файлы и открывать нужную программу, выгружая её в оперативку. Однако для такой схемы нужна библиотека SD, использование которой не оставит от этой самой оперативки ничего. Я подумал — если понадобится ФС, напишем ее поддержку уже на нашем коде, а не будем занимать память Arduino для этого. Вполне хорошей альтернативой для работы с картой послужила библиотека sd_raw, которая предоставляет доступ к любому байту на карте на чтение и запись туда сырых данных, т.е. просто набора байт. В качестве основного устройства вывода текста я взял черно-белый дисплей Nokia 5110 — точное попадание в ретро стиль, как мне кажется. В качестве клавиатуры, понятно, возьмем PS/2. Остались свободные пины — заткнем пьезо-пищалкой. Мой хороший знакомый нарисовал и напечатал мне корпус, как многие заметили по картинке выше, похожий на корпус Macintosh.
Instruction Set Architecture
Ок, поговорили как он выглядит, что внутри, теперь углубимся в систему команд. Она строилась таким образом, чтобы пользователь не писал кучу лишнего кода, чтобы проинициализировать какое то устройство, как делал я, чтобы завести мышку в x86, используя только запись в порты.
Т.е. на манипуляции с устройствами выделены некоторые инструкции, такие как:
- gkey — получает сканкод нажатой клавиши, если ее не было, то 0.
- line x1, y1, x2, y2 — рисует линию по указанным координатам на экране.
- play label — играет музыку по смещению label в памяти.
- .
Как же будут устроены обработчики этих инструкций и их опкоды? Я решил этот вопрос очень просто — создал массив функций, теперь в основном цикле работы процессора байт, на который указывает указатель инструкции (IP) — будет восприниматься как номер функции в этом массиве. Если же у инструкции есть какие то аргументы, например операнды инструкции сложения add r0, r0, то соответствующая функция сама об этом знает и дочитывает их. Кстати говоря, поскольку регистров 16, то эту пару из инструкции выше можно упаковать в 1 байт, чем я и воспользовался, чтобы сократить код.
Регистры!
С ISA разобрались, немного о регистрах, их 2 набора по 16 штук — для целых чисел и чисел с плавающей запятой, все 32-битные. Есть инструкции кастинга из одного типа в другой, при этом сами регистры при программировании ничем не отличаются, инструкция сама понимает из какого именно регистра читать/писать (хотя можно сделать псевдонимы, чтобы не путаться). Кстати о плавающих числах, тут нам можно работать с плавающими числами как с целыми в плане использования их в инструкциях, не нужно использовать регистровый стек и обращаться по ссылке в память для получения константы, как это есть в x87. Однако вводя эти числа в свою систему, я не знал как безболезненно преобразовывать их, т.е. без битового разбора числа в формате IEEE754. Оказывается такой способ есть и он очень прост, нам не потребуются никакие логические операции в огромном количестве, а только 2 строчки:
unsigned int x = 0x3f322e3f; float y = *(float*)&x;
Тут мы просто записали в некоторую область памяти целое число (4 байта), изначально смотрим на них именно так, потом после взятия указателя на эту область (целое число), производим каст его к указателю на вещественное число и разыменовываем. Вся основная работа происходит во второй строчке и читать ее нужно справа налево. В итоге в переменной y окажется число, байтовое представление которого в формате IEEE754 равно числу в переменной x.
Пройдемся по устройствам.
- Дисплей — с ним особых проблем не возникало, открыл datasheet, написал библиотеку и все работает, возникла только одна проблема с тем, что необходимо сохранять содержимое буфера экрана (508 байт) в какой-то памяти для изменения отдельных пикселей. Хорошо бы можно было в оперативке, но места мало — примерно столько же ест массив инструкций и столько же библиотека sd_raw, в совокупности с прочими расходами на регистры и другие переменные и массивы. Это оставляет около 150-200 байт на локальные переменные, чего может оказаться мало. Но быстро стало ясно, что инструкции никто не будет менять (хотя идея интересная — налету подменять инструкции процессора), поэтому было решено перенести их во внутреннюю flash память, используя ключевое слово PROGMEM в Arduino IDE, которое позволяет сохранять константы любых типов в неизменяемую память, освобождая оперативную. Таким образом решилась проблема нехватки памяти для экрана.
- Клавиатура — тут интереснее то, что происходило в программном эмуляторе нашего девайса, но об этом позже. В остальном, я пока что с реальной клавиатурой разбираюсь — там нужно выбрать хорошую (для наших целей) таблицу сканкодов (их 3 в PS/2) и понять как легко транслировать их в символы ASCII, или хотя бы как это делает DOS.
- Карта памяти — в какой то момент мне пришло осознание, что даже, если у нас регистры 32-битные и карта не меньше 4 Гб, но мы все равно не можем адресовать больше 2 Гб — это связано с тем, какую плату картридера я установил в наш вычислитель — она не поддерживает карты большего объема. Это налагает ряд проблем — теперь мы можем использовать только карты на которых указан объем 2Гб, они всегда на самом деле меньше и даже так — они различаются по объему. Но так как раньше и IP и SP — специальные регистры были по умолчанию установлены в 0, то теперь для адекватного использования стека (который растет вниз) нужно знать верхнюю границу памяти. И очень кстати в библиотеке имелась функция для чтения заводской информации, а помимо производителя там было поле capacity (емкость). Вот именно в это значение мы и устанавливаем теперь SP перед началом основного цикла процессора.
- Пьезо-пищалка — здесь было совершено большое открытие для меня — что delay в Arduino не такой уж блокирующий, как нам все говорят. Остановимся поподробнее.
Начну с того, какая задача стояла. У нас есть набор пар частот и задержек, мы хотим перебирать их и проигрывать на пищалке функцией tone, которая как раз принимает пин, частоту и задержку, пищит с нужными параметрами и отключается по прохождении задержки. Перебирать нужно не абы как, а когда исполнится инструкция play, которая раньше упоминалась. Она укажет, где лежат эти ноты и запустит проигрывание, но стандартная функция tone не умеет по циклу ходить и изымать частоты с задержками. Значит нужно как-то детектировать то, что текущая нота должна уже закончиться и пора бы включить следующую. Самым простым решением будет в основном цикле процессора следить за этим с помощью millis, которая возвращает время прошедшее с запуска контроллера в миллисекундах. Но самое простое — не самое эффективное, у нас инструкции не имеют фиксированного времени исполнения, та же delay может занимать достаточно длительное время, не давая переключить ноту. Дальнейшим решением для меня было — покопаться в исходниках функции tone и создать аналог, который принимает обработчик завершения тона, обычно это была функция, которая отключает таймер, но теперь мы ее подменяем и вместо отключения мы включаем новый тон. После того, как проигрывание завершается нужно позвать noTone, чтобы вызвать правильный обработчик и подменить его обратно. Вроде все хорошо, все работает! Однако не совсем. Я загрузил следующий код:
#define N 39 int i = 0; int frequences[N] = < 392, 392, 392, 311, 466, 392, 311, 466, 392, 587, 587, 587, 622, 466, 369, 311, 466, 392, 784, 392, 392, 784, 739, 698, 659, 622, 659, 415, 554, 523, 493, 466, 440, 466, 311, 369, 311, 466, 392 >; int durations[N] = < 350, 350, 350, 250, 100, 350, 250, 100, 700, 350, 350, 350, 250, 100, 350, 250, 100, 700, 350, 250, 100, 350, 250, 100, 100, 100, 450, 150, 350, 250, 100, 100, 100, 450, 150, 350, 250, 100, 750 >; void executor() < tone(2, frequences[i], durations[i]); i = (i+1) % N; >void setup() < tone(executor); delay(10750); noTone(2); >void loop() <>
Оказалось, что проиграв одну ноту, он выключал проигрывание. Почему же. Обратите внимание на delay, если зайти в её исходники, то мы замечаем функцию, которая вызывается перед циклом задержки — yield, я мало чего про нее нашел, но, как я понял, это макрос, в который мы оборачиваем код и как-то можем параллельно его исполнять с основным кодом, если кто знает точно — поделитесь. Я сам попробовал решить эту проблему и у меня получилось! Покажу на примере. У нас есть такие строчки в функции noTone —

Первая строка тела записывает логический 0 в указанный выход, а вторая подменяет обратно обработчик. Что будет если их поменять? Все сломается, конечно. Вспомним, что у нас delay не совсем блокирует, а именно, код будет исполняться до «digitalWrite«, перед чем заблокируется. Если строчки будут в другом порядке, то вот эта замена приведет к тому что у нас старый обработчик вернется и будет отключать таймер, на котором работает пищалка. Таким образом, экспериментально проверено, что delay блокирует код, если он изменяет состояние пинов, иначе он исполняется. Каким образом это происходит — на это у меня ответов пока что нет.
Прочий софт

Вот такие были пироги при работе с периферией нашего компьютера. Помимо его самого, для него я сделал транслятор ассемблера в машинные коды, чтобы писать начальные программы было удобнее — работает на Python. На нем начал реализовывать оболочку, которая умеет разбирать FAT32, ходить по ее директориям и исполнять файлы. Так же для удобства отладки был написан эмулятор девайса — он использует общий код с самим компом. Рассмотрим подробнее оболочку и эмулятор.
Оболочка
Компьютер начинает исполнение инструкций с 0 байта. На карте памяти было решено создать файловую систему FAT32 и использовать ее резервные секторы для нашего загрузчика. Как правило, начало самого первого сектора содержит служебную информацию, но самые первые байты не критичны к изменению, а именно нам надо изменить первые 5 байт на инструкцию перехода к первому байту загрузчика. Ок, мы попали в загрузочную секцию, разобрали все байты, рассчитали константы в удобном виде. Сохранили это все, теперь, чтобы не пересчитывать это при каждом старте и не перезаписывать подменим еще раз инструкцию перехода на блок непосредственной загрузки. Можно видеть это в этом коде:
movw r0, [0xe] shl r0, 9 mov [first_fat], r0 movb r1, [0xd] shl r1, 9 mov [cluster_size], r1 movb r1, [0x10] ;number of fats movw r2, [0x24] ;sector per fat shl r2, 9 mov [fat_size], r2 mul r1, r2 add r0, r1 mov [data_area], r0 mov r0, start_main mov [1], r0 include "main.asm"
Про FAT ничего не буду рассказывать, можно посмотреть какие там есть поля, как строятся файлы и про терминологию в этом видео:
У нас в программе есть поле «текущая директория«, она обозначает номер первого кластера директории. Таким образом если мы в какой то директории начали работу при выключении компьютера, то при включении мы в ней и начнем работу. Выбирать файл в директории можно клавишами стрелками вверх-вниз, исполнять по Enter, при этом если это директория, то она становится в качестве текущей. Кстати говоря, под исполнение нужно выделить место. Поскольку доступно максимум 2 Гб, то 1 нижний гигабайт мы отдадим файловой системе, а старшую область под исполнение. Поскольку экран у нас может вмещать 6 строк текста по 14 символов, то мы можем отображать имя и тип файла (файл или директория) в каждой строке, а между строками перемещаться, используя скользящее окно.
Эмулятор
Наконец, немного про эмулятор. Чтобы все работало так же как на реальном компе, понятно, что нужно реализовать соответствующим образом библиотеки работы с устройствами. Карта памяти эмулируется, как не сложно догадаться — файлом.
Экран изначально был приложением на SFML, но это влияло на работу с клавиатурой, создавая две проблемы. Во-первых, нужно понимать, что SFML это библиотека для игр, поэтому там не получить никаких нормальных сканкодов, значит надо их получать откуда-то еще, но если фокус на окне SFML, то оно получает все события клавиатуры, поэтому приходится переключать фокус на консоль, но так чтобы и окно было видно. Во-вторых, SFML это графическая библиотека, т.е. в текстовой консоли (одной из тех, что доступны по ALT-CTRL-Fx) ее нельзя использовать для рисования чего-то на экране.
Хотя хотелось бы перейти в текстовую консоль, поскольку есть способ получения совсем хороших сканкодов — прямо таких, какие приходят от клавиатуры. Это показывает утилита showkey, но работает она только в текстовой консоли, так как графика в Linux для обработки хоткеев всегда читает /dev/console. Суть этого метода — перейти в неканонический вид консоли, где мы будем получать сырые сканкоды. Я просто нашел исходники утилиты showkey и подправил их для своих нужд, заодно научился компоновать программу на С++ с функциями на С — это нужно поскольку showkey написана на С, а весь проект мы пишем на плюсах. Ну а для отрисовки экрана мы воспользуемся популярной библиотекой для консольной графики — ncurses. Чтобы все отображалось хорошо, нужно настроить консоль так, чтобы размер шрифта вместо 8×16 был 8×8 — красиво, как пиксели на экране.
Заключение
Вот, вроде бы все основное рассказал. Вообще говоря, там еще много всего можно рассказать, с чем сталкивался по пути, но это, скорее, просто занимательные мелочи, чем что то важное. Столько удачных костылей было вставлено — о некоторых рассказал, о других молчу.
Сейчас делаю сетевой интерфейс для передачи по встроенному UART — нашел способ без дополнительных проводов, только UART и диоды, собрать общую шину из таких компьютеров и передавать между ними данные. Так же думаю как сделать транслятор из, скажем, wav в описанный формат музыкальных файлов. Еще поглядываю в сторону нормального компилятора на основе LLVM, но пока только мысленно, потому что итак есть чем заняться с этим проектом.
Спасибо за внимание, присоединяйтесь к проекту. Оставлю ссылки.
Как на arduino собрать крутой компьютер
Эй, я думал об этом, и чем больше я думаю об этом, тем больше я думаю, что на самом деле могу это сделать. Моя идея в основном такова: сделать функциональный компьютер из микроконтроллера Arduino Uno.
Моя единственная цель для этого компьютера — возможность редактировать и выполнять программы BASIC. Это все. Я хочу только это для программирования, потому что это единственное, что меня интересует сейчас
Поэтому, как я понимаю, мне понадобятся три основных аппаратных компонента:
- некоторая форма дисплея (экран VGA или что-то)
- какой-то способ регистрации ввода с клавиатуры, и
- какой-то способ хранения данных во внешней памяти.
Кто-нибудь знает какой-либо способ сделать это? Я знаю способы отображения на экране, но я не знаю хорошего API / аппаратного компонента для регистрации ввода с клавиатуры или для хранения внешней памяти.
Мне понадобится много помощи по этому вопросу. Кто-нибудь может мне помочь и предложить идеи и полезные советы и предложения для хорошего оборудования / хорошей библиотеки с открытым исходным кодом, или два, или три, или десять?
Добавлено:
Клавиатуру можно сделать просто, используя клавиатуру PS / 2 — она просто последовательная, и для нее есть множество обучающих программ.
Хранить данные можно просто на SD-карте — для этого уже есть щит.
Что касается видео — это значительно сложнее. Если вы хотите, чтобы Arduino генерировал, например, видеосигнал PAL, тогда ваша работа исключена для вас. Да, это возможно, и кто-то создал Arduino-игру «понг», но это очень короткая графика и только черно-белая.
Для VGA вам потребуется какой-то интерфейс, чтобы сделать работу за вас. Sparkfun продавал видеокарту Picaso, которую можно было бы использовать для работы с Arduino, но, увы, он был снят с производства, и пока нет планов его замены.
TBH ваш лучший выбор будет использовать что-то вроде терминала Wyse и общаться с Arduino полностью через последовательный порт. Гораздо проще, чем возиться с видеосигналами и тому подобным.
Я вижу точку зрения Олина — если вы хотите редактировать / запускать / изучать бейсик, просто используйте компьютер.
Однако, если целью является задача создания компьютера, который может запускать BASIC и одновременно изучать аппаратное обеспечение и реализацию более низкого уровня, то это будет немного иначе. Я за такие вещи, это отличный способ улучшить знания, и я уверен, что вы многое из этого получите. Как Стивен упоминает все запутанные и (в основном) нерелевантные слои, которые есть, например, в Windows, могут быть удалены, оставляя базовые (без каламбура) концепции.
В любом случае, вам, возможно, захочется взглянуть на что-то более мощное, например PIC32, поскольку оно должно иметь возможность самостоятельно справляться со всеми функциями (например, с базовым VGA).
Вот плата, совместимая с Arduino, UNO32
. Maximite — это компьютер с интерпретатором BASIC, основанный на PIC32, вы можете взглянуть на дизайн и конструкцию для нескольких идей.
Вам повезло, вроде как, потому что я сейчас работаю на Arduino PC! Это не так много, только первая модель. Прошивка также очень проста и имеет небольшой набор API. Но вещь работает! Недостаточно хорошо для редактирования BASIC (или любого языка, кроме его собственного), но это только первая модель. Мобо довольно прост, и я использовал это . Вот прошивка, которую я использовал:
Описание метода сложно объяснить, но код хранится в виде необработанных байтов. Я должен скоро разработать программное обеспечение . Надеюсь, это поможет! Если вы когда-либо захотите использовать это для каких-либо проектов, вы ДОЛЖНЫ ИМЕТЬ файл BIOS.mk8 в корневом каталоге SD, иначе система не будет работать.
При всем моем уважении к Дэвиду Брину (мне очень нравятся его книги; я не квалифицирован, чтобы судить, насколько он хорош в качестве астрофизика), он не программист и не педагог.
Я был в курсе и программировал в первые дни ПК, и я написал довольно много кода на бейсике. И с тех пор я профессионально пишу код.
Причина, по которой мы тогда использовали BASIC, заключалась в том, что у вас было два варианта — использовать BASIC или писать в сборке, а сборку было сложнее понять и гораздо труднее использовать. Итак, бейсик.
С тех пор за 30 с лишним лет в обучении программированию произошли значительные улучшения. Моя жена преподает начальный класс программирования, который использует Алису (www.alice.org), и это намного лучше концептуально, чем старые подходы.
Я думаю, что решение Брина было довольно элегантным. Вы можете создать что-нибудь довольно простое на Raspberry PI. На Arduino, я думаю, будет сложно собрать все необходимое в 2K RAM; он должен содержать любую ОС / монитор, которую вы в итоге пишете, интерпретатор команд, код для отображения и хранилище для самой базовой программы.
Не говоря уже о том, что вам придется выполнять множество сложных и нестандартных программ, чтобы вы могли писать код в простой среде.
Я не понимаю Если вы хотите, чтобы у вас были только средства для программирования на Basic, запустите на вашем компьютере базовый переводчик. Я не понимаю, как вы ожидаете, что Arduino поможет с этим. Arduino — это микроконтроллер с множеством модных программ, позволяющих скрыть детали оборудования. Отчасти это связано с более низкой производительностью и большим использованием ресурсов, чем с аналогичной программой, работающей непосредственно на голом микроконтроллере. Теперь вы хотите написать код Arduino, чтобы превратить его в компьютер более общего назначения, и все, чтобы вы в свою очередь могли запустить интерпретатор Basic на этом компьютере общего назначения? Это имеет мало смысла.
Поскольку ваша единственная цель — иметь возможность редактировать и выполнять базовые программы (запускать интерпретатор Basic), начните с вычислительной платформы более общего назначения, предпочтительно даже с уже имеющейся интерпретатором Basic. У вашего ПК именно такая платформа. Если вы хотите, чтобы это было внешнее оборудование, похоже, что готовый одноплатный компьютер будет отвечать вашим потребностям гораздо лучше, чем Arduino.
Добавлено:
Теперь вы говорите, что не хотите запускать на ПК, и разместите эту ссылку о ком-то, кто хочет, чтобы у его ребёнка была базовая строка Basic. По общему признанию, я не читал всю статью (мне не нравятся люди, отвечающие ссылками. Вы должны быть в состоянии изложить свою точку зрения независимо в нескольких предложениях), но я не вижу, как на ПК работает командная строка Базовый интерпретатор не решает вашу проблему. Почему интерпретатор Basic не может работать на ПК, но нормально работать на Arduino? Помните, вы заранее сказали, что ваша единственная цель — редактировать и запускать базовые программы. Ничто в этом утверждении не говорит о том, на каком оборудовании оно должно работать, и ни одно из ваших последующих объяснений не объясняет, почему ПК не будет работать нормально.
Вероятно, есть основные интерпретаторы, которые запускаются в командной строке. Старый QBASIC все еще может работать в режиме совместимости с DOS. Даже если нет, так как вы готовы посвятить этому оборудование, как работает DOS и QBASIC на ПК, а не то, что вы просили?
H Бортовой компьютер для авто на Arduino своими руками в черновиках Из песочницы
UPD 27.12.2017: Решил дополнить статью что проект был доработан другим пользователем, улучшен скетч в плане автоматической задержки, восстановления связи в случае разрыва соединения и много других нюансов… спасибо. Oleg его почта для вопросов: 2003shef@gmail.com
Его комментарии к переработке:
1.вся проводка и соединение всех модулей и узлов сохранены из первоначального проекта.(кроме подключения блутуз модуля, он теперь на серийном порте «1»)
2.программа жестко заточена под ардуино МЕГА 2560. на серийном порте «0» присутствует Дебаг при условии раскоментирования дефайна.
3.убран параметр задержки между опросами, задержка полностью интелектуальна и динамична, новый запрос не отправится пока не будет получен ответ на предыдущий с учетом таймаута.
4.добавлена функция восстановления связи в случае разрыва соединения (параметром потери связи служит отсутствие оборотов двигателя).
5.для работы требуется библиотека OBD.h вложенная в архив с проектом, этот экземпляр имеет несколько изменений от оригинала который можно скачать из интернета, и без неё скорее всего проект не будет работать или будет нестабилен.
папку нужно скопировать в папку » \Documents\Arduino\libraries»
Android приложение со всеми нюансами в Google Play: OliviaDrive
Мы сможем сделать бортовой компьютер, умеющий считать расход топлива, показывать температуру охлаждающей жидкости, скорость авто, расстояние поездки, потраченный бензин за поездку, обороты двигателя, давление во впускном коллекторе, температуру впускного коллектора, УОЗ, коррекции топлива, вольтаж датчиков кислорода, нагрузку двигателя и многое другое.








Список требуемых деталей для сборки БК

2) LCD2004 жк-модуль

3) Модуль Bluetooth HC-05

4) OBD ELM327 Bluetooth сканер

5) Резистор 10 кОм подстроечный, бипер для звука, 2 кнопки для смены экранов, провода для соединений, корпус
Настройка блютуз модуля HC-05 для работы
Подпаиваем провода к пинам блютуза: (картинку с выходами смотреть в описании требуемых деталей)
- 1 — это TX
- 2 — это RX
- 12 — это 3.3V
- 13 — это GND
- 34 — на этот вход тоже кидаем 3,3 V (нужен для перевода модуля в режим настройки с помощью AT команд).

- 1 — TX модуля в 6 пин ардуины. (внимание будет TX в TX это не ошибка!)
- 2 — RX модуля в 7 пин ардуины. (аналогично не ошибка!)
- 12 — и 34 пин к 3,3V ардуины.
- 13 — GND ардуины.
#include
SoftwareSerial BTSerial(6, 7); // TX | RX
void setup()
После успешной загрузки скетча открываем: Сервис->Монитор порта. Далее снизу ставим скорость 9600 бод и NL+CR вместе.
Далее вводим команды по одной и нажимаем [Послать]. После каждого ввода должен быть ответ ok.
AT // (возможно 1 раз вылетит Error, не пугайтесь… это нормально, повторите опять)
AT+NAME=Car //Присваиваем имя модулю Car
AT+ROLE=1 // Переводим модуль в режим Мастер
AT+PSWD=1234 // Ставим пароль 1234 как на OBD ELM327
AT+BIND=AABB,CC,112233 //Прописываем Mac адрес OBD ELM327.
AT+CMODE=1 // Подключение модуля с фиксированным адресом
AT+UART=9600,0,0 // Скорость работы по UART
Заметьте, что mac-адрес вида: «AA:BB:CC:11:22:33» вводится как «AABB,CC,112233». MAC- адрес своего модуля ELM327 можете посмотреть, подключившись для начала на него со своего мобильника. (Стандартные пароли обычно: 1234, 6789, 0000).
Всё, настройка модуля Bluetooth закончена.
Теперь нужно собрать схему Arduino + блютуз + LCD-экран

Схема:
- 1 — TX модуля засовываем в 7 Pin (Rx) арудины (именно TX в RX, не так как ранее);
- 2 — RX модуля засовываем в 8 Pin (Tx) арудины;
- 12 — Pin (3,3V) модуля в Pin 3,3V ардуины;
- 13 — Pin (Gnd) в Gnd арудуины;
- 34 — Pin мы никуда не подключаем (заизолируйте или отпаяйте).
- VSS экрана к GND ардуины;
- VDD экрана к 5V ардуины;
- V0 экрана к центральному выходу резистора;
- RS экрана к 12 пину ардуины;
- RW экрана к GND ардуины;
- E экрана к 11 пину ардуины;
- DB4 экрана к 5 пину ардуины;
- DB5 экрана к 4 пину ардуины;
- DB6 экрана к 3 пину ардуины;
- DB7 экрана к 2 пину ардуины;
- A — к 5V ардуины;
- K — GND ардуины.
Переменный резистор на 10кОм нужен, чтобы управлять контрастностью монитора, так что если при первом включении вы включите и ничего не увидите, попробуйте отрегулировать контрастность шрифта поворотом резистора.
3. Подключаем дополнительную кнопку для переключения экранов с данными.
[1 кнопка]: один конец от нормально-открытой кнопки подключаем в GND ардуино, а второй конец в пин 10.
[2 кнопка]: GND + пин 9.
Бипер для звуковых предупреждений подключить по следующей схеме «+» к пину 13, а минус к GND ардуино.
Заливаем скетч в Arduino с помощью Aduino IDE 1.0.6 (использовал эту версию).
Единственное, в скетче присутствуют переменные, которую нужно подправить.
Нужно будет обязательно учесть три переменных:
1) ED=1.998 Например объем двигателя в литрах 1.398;
2) VE_correct=1.0; Корректировка объёмного КПД ДВС по таблице: (если расход реально меньше — то уменьшаем значение в процентном соотношении). Если не хотите калибровать добейтесь чтобы при прогретом двигателе мгновенный расход в л/час был в районе половины обьема двигателя;
5)speed_korrect_val=1; Корректировка скорости машины, смотреть по GPS/
Управление
[Кнопка 1], [кнопка 2] — листать экран вперед назад.
При включении при надписи «Connecting»… держать [кнопку 1] вход в режим показывания технологических экранов и параметров отдаваемых ЭБУ в 16-чном формате. Если будете включать БК не в машине то нужно отключить функцию опроса блютуз, надо продолжать держать две кнопки при надписи «Recovery»… до появлении надписи «All off»… а то экран будет все время пустой.
[Кнопка 1] + [кнопка 2]: 4 секунды — Сброс журнала общего пробега и потраченного бензина на втором экране, также это сброс ошибок на экране информации об ошибках.
Скетч:
Старый скетч был удален в плане многих дефектов в работе… новая версия по ссылке вверху статьи… он был доработан пользователем Oleg, спасибо ему большое. его почта для вопросов: 2003shef@gmail.com
Все, идем в машину, вставляем ELM327 в порт, ардуину в зарядку для авто и проверяем.
Мой самодельный компьютер на Arduino Nano под управлением ОС CP/M
Raison d’être — в далекие 90-е годы у меня был «бытовой» (как он тогда назывался) компьютер «Байт» — брестский клон популярнейшего в те времена на просторах СНГ ZX Spectrum 48K. Но на нем невозможно было запустить операционную систему CP/M, бывшую де-факто стандартом для восьмибитных компьютеров (в середине 1980-х годов эта ОС запускалась на свыше 300 моделях микрокомпьютеров). И вот я решил восполнить это упущение и создать свой компьютер под управлением ОС CP/M 2.2 на базе . Arduino Nano 3.0 (с микроконтроллером ATmega328)!
В процессе его создания я решил несколько задач:
- создал симулятор процессора Intel 8080, а также реализовал эмуляцию оперативной памяти и дисковой системы;
- адаптировал к созданному устройству ОС CP/M;
- реализовал вывод текстовой информации на экран телевизора;
- разработал преобразователь PS/2-UART для подключения клавиатуры.
Подобные проекты часто именуются «homebrew computer» и технологии их построения весьма разнообразны — электромагнитные реле, дискретные транзисторы, микрсохемы логики, FPGA.
Текущая версия проекта — cpm4nano Mk VI (версия ПО — 0.7)
Проект постоянно развивается, поэтому описание может не успевать за текущим состоянием проекта!

Структурная схема проекта

Внешний вид проекта

Конфигурация системы

Симулятор процессора i8080

Эмуляция оперативной памяти

Эмуляция консоли

Эмуляция дисководов

Хранение данных на магнитной ленте

Адаптация операционной системы CP/M

Эксплуатация

Оценка быстродействия

Программирование

Игры

YouTube

Структурная схема проекта :

Внешний вид проекта :

Как все устроено —
Конфигурация системы :
- Arduino Nano 3.0;
- SD-карточка с адаптером;
- преобразователь USB-UART для связи через последовательный порт;
- преобразователь PS/2-UART для подключения клавиатуры;
- два чипа FM24C256;
- пассивный адаптер для подключения телевизора через композитный вход;
- пассивный адаптер для ввода/вывода информации через аудиоканал;
- дополнительные аксессуары — PS/2-клавиатура и телевизор с композитным входом.
Термины «эмулятор» и «симулятор» часто употребляются как синонимы. Вот интересная статья в Wikipedia с объяснением этих терминов — https://en.wikipedia.org/wiki/Emulator.
Симулятор процессора i8080
Я создал симулятор для Arduino Nano, способный воспроизводить все команды процессора i8080.
При этом под i8080 я понимаю все семейство X8080Y, не имевшее программных отличий.
Мой симулятор представляет собой интерпретатор, последовательно выполняющий команды микропроцессора i8080.
ТЕСТЫ ПРОЦЕССОРА i8080, УСПЕШНО ПРОЙДЕННЫЕ СИМУЛЯТОРОМ
Kelly Smith Test от MICROCOSM ASSOCIATES (версия 1.0, 1980 год) — подарен группе пользователей CP/M «SIG/M»

Этот тест тестирует большую часть флагов, режимов и инструкций (за исключением операций ввода-вывода, обработки прерываний, также тестируются не все постусловия инструкций).
8080PRE (предварительный (preliminary) тест) от Ian Bartholomew и Frank Cringles

DIAGNOSTICS I от SUPERSOFT ASSOCIATES (версия 1.2, 1980 год)

DIAGNOSTICS II от SUPERSOFT ASSOCIATES (версия 1.2, 1981 год)

Буквы A. Z обозначают пройденные тесты.
Согласно https://github.com/superzazu/8080/tree/master/cpu_tests на процессоре 8080 с тактовой частотой 2 МГц тест между BEGIN . и END . длится около двух минут.
В FAST-режиме мой «нанокомпьютер» выполняет этот тест за время около семи минут, что соответствует эквивалентной тактовой частоте около 500 — 600 кГц, в SLOW-режиме — за время около 26 минут (150 кГц). При отключенном кэше инструкций время выполнения теста намного возрастает — до 117 минут в FAST- режиме (35 кГц).
8080/8085 CPU Exerciser от Ian Bartholomew и Frank Cringles

Эмуляция оперативной памяти
Главная проблема в этом проекте — нехватка оперативной памяти, которой в ATmega328 только два килобайта! Для эмуляции оперативной памяти размером несколько десятков Кбайт я использую микросхемы FRAM.
Я использую две микросхемы FRAM (встречается сокращение и F-RAM) FM24C256-G:

Расшифровка обозначения чипа FM24C256-G:
FM — Cypress;
24 — I 2 C FRAM;
C — напряжение питания 4,5. 5,5 В;
256 — емкость 256 Кбит;
G — 8-выводный SOIC-корпус
Для удобства применения таких микросхем я применил
SOIC-DIP адаптеры:

FRAM — это запоминающее устройство, построенное по сегнетоэлектрической (англ. ferroelectric) технологии. Микросхема FM24C256-G обладает емкостью 32 КБайта и подключается к шине I 2 C. Эта микросхема выпускается в SOIC-корпусе:
Назначение контактов:
| Обозначение вывода | Назначение вывода: |
| A0 | бит 0 адреса |
| A1 | бит 1 адреса |
| A2 | бит 2 адреса |
| WP | защита от записи |
| SDA | данные/адрес (I 2 C) |
| SCL | тактирование (I 2 C) |
| VDD | напряжение питания 5 В |
| VSS | «земля» |
Подключение к Arduino Nano осуществляется так:
| Вывод FRAM | VDD | SDA | SCL | VSS |
| Вывод Arduino Nano | 5V | A4 | A5 | GND |

Схема подключения FRAM-памяти:
Я использую два чипа FRAM, задав их адреса как
0x50 (все адресные линии «плавающие»);
0x51 (адресная линия A0 подключена к выводу VDD, остальные адресные линии — «плавающие»).
Светодиод индицирует низкий уровень на линии SCL — при обращении к FRAM-памяти.
Для ускорения доступа к оперативной памяти я использую кэш инструкций — однолинейный, размером 8 байт с политикой «read ahead» (упреждающее чтение — считываются байты программы, расположенные после текущей инструкции) / «write through» (запись происходит всегда в ОЗУ).
Я оценил влияние размера кэша на быстродействие в разных задачах, определив время их выполнения:
расчет первого хода в Microchess:
нет кэша — 291 секунда;
кэш 4 байта — 580 секунд;
кэш 8 байт — 21 секунда;
кэш 16 байт — 26 секунд.
компиляция ADA-программы TOWERS (решение задачи о ханойской башне):
нет кэша — еще нет результатов;
кэш 4 байта — еще нет результатов;
кэш 8 байт — 71 минута;
кэш 16 байт — 87 минут.
Измерения выполнялись в FAST-режиме.
ТЕСТЫ ОПЕРАТИВНОЙ ПАМЯТИ, УСПЕШНО ПРОЙДЕННЫЕ СИМУЛЯТОРОМ
Популярным способом проверки памяти является запись/чтение в ячейки памяти/из ячеек памяти сначала байтов 0x55 (01010101), а затем байтов 0xAA (10101010), либо байтов 0xA5 (10100101) и 0x5A (01011010).
В статье «Ram Tests» (http://www.ganssle.com/articles/ramtest.htm) советуется записывать последовательно в ячейки памяти и проверять при чтении случайную последовательность из, например, 257 байт.
Я использую этот метод с длиной последовательности 33 — на единицу больше размера линии кэша — из байтов:
(случайная последовательность сгенерирована с помощью сервиса RANDOM.ORG).
Сначала я выполняю проход теста с исходной последовательностью, а затем — с инвертированной.

Я выполнил 7400 проходов теста памяти (с помощью команды монитора «M«) — ошибок обнаружено не было:
UMPIRE от Mel Cruts (1980 год)

MEMR Rasmussen Memory Test от Lifeboat Associates (версия 2.2, 1980 год)
— в процессе прохождения —
Сохранение и загрузка образов памяти
Для записи образа памяти на карточку используется команда монитора Pxx, где xx — номер образа памяти (от 00 до 99), например, команда P01 записывает образ памяти с номером 01.
Для загрузки образа памяти с карточки используется команда монитора Uxx, где xx — номер образа памяти (от 00 до 99), например, команда U01 загружает образ памяти с номером 01.
Эмуляция консоли
Ввод/вывод через последовательный порт
Для связи Arduino Nano с компьютером через последовательный порт (для ввода-вывода команд и данных) я использую преобразователь USB-Serial и терминальную программу
Tera Term (https://osdn.net/projects/ttssh2/releases/).
Для настройки последовательного порта в программе Tera Term предназначен пункт меню Serial -> Serial port. :

Последовательный порт должен настраиваться на скорость 115200 бод, 8 бит данных, без бита четности, 1 стоп-бит и аппаратное управление потоком:
Для управления потоком используется вывод CTS преобразователя USB-Serial, который соединен с выводом D2 Arduino. «Низкий» уровень на этом выводе разрешает передачу данных от компьютера к эмулятору.
Я сделал эмуляцию коммуникационных портов в соответствии с архитектурой компьютера «Altair 8800» , созданного Micro Instrumentation Telemetry Systems (MITS) :
основной последовательный порт Arduino отображается одновременно на порты двух плат:
плата SIO-A (88SIO) (чип COM2502):
порт 0x00 (0): порт статуса (TTS) (R — бит 5 = 1 (0x20) — есть символы для ввода, бит 1 = 1 (0x02) — терминал готов к выводу символа)
порт 0x01 (1): порт данных (TTI/TTO) (R/W)
первый порт платы 2SIO (88-2SIO) (чип EF6850 — 8-битный асинхронный адаптер коммуникационного интерфейса):
порт 0x10 (16): порт статуса (TTS) (R — бит 0 = 1 (0x01) — есть символы для ввода, бит 1 = 1 (0x02) — терминал готов к выводу символа)
порт 0x11 (17): порт данных (TTI/TTO) (R/W)

Для настройки терминала в программе Tera Term предназначен пункт меню Serial -> Terminal. :

По умолчанию размер экрана терминала — 80 колонок, 25 строк:
Вывод на экран телевизора
В качестве альтернативы выводу в последовательный порт я использую вывод на телевизионный экран через композитный вход.
Для вывода на ТВ используется таймер 1 и выводы D3 . D9 Arduino.

Схема реализации вывода изображения на экран ТВ:
Формат вывода на экран ТВ — 20 строк x 45 колонок, шрифт 4 x 8.

Шрифт описан в виде битовых последовательностей — сначала первая (верхняя) строка для 256 символов, затем вторая и т.д.:
(шрифт описывается в старших 4 битах в инвертированном виде: 1 — черный пиксель, 0 — белый пиксель, младшие 4 бита должны быть равны 1).
Русские буквы и символы псевдографики (согласн RFC 1489) соответствуют кодировке КОИ-8 (KOI-8R):
.
Вот как выглядит набор символов шрифта:

на экране LCD-телевизора:

на экране ЭЛТ-телевизора:

Снимок экрана ЭЛТ-телевизора с результатами дампа памяти из монитора:

Пример снимка телевизионного экрана с выполненной командой DIR и тестами процессора:
Я преодолел ограничение физического разрешения видеовыхода моего «нанокомпьютера» (45 колонок) в стиле портативного микрокомпьютера Osborne 1 — используя два виртуальных экрана.
Содержимое текущего виртуального экрана хранится в видеопамяти (ОЗУ микроконтроллера), а содержимое другого виртуального экрана — в основной памяти (I2C-чипах).
Они расположены горизонтально, разрешение виртуального экрана — 40 колонок и 19 строк + 1 строка статуса:

Таким образом, виртуальные экраны эмулируют физический экран с 80 колонками (Osborne эмулировал физический экран со 128 колонками посредством перекрывающихся виртуальных экранов шириной 56 колонок).
Переключение режимов (физический экран/виртуальные экраны) осуществляется из программы-монитора.
Переключение между виртуальными экранами осуществляется комбинацией клавиш CTRL-O.
Пример:
левый виртуальный экран

правый виртуальный экран

Видеовыход моего компьютера оснащен раъемом «тюльпан» RCA. Он подключается к композитному входу («AV IN«) телевизора — разъему «тюльпан» RCA («VIDEO«, желтый) или SCART:

Я использую вот такой кабель:

На телевизоре при этом необходимо выбрать соответствующий вход для сигнала:
При выводе информации на телевизор распознаются следующие ESC-последовательности:
ESC[nA — перемещение курсора на n позиций;
ESC[nB — перемещение курсора на n позиций;
ESC[nC — перемещение курсора на n позиций;
ESC[nD — перемещение курсора на n позиций;
ESC[r;cH — перемещение курсора в строку r колонку c;
ESC[nJ — стирание области дисплея;
ESC[nK — стирание части строки.

При выводе на экран телевизора позиция следующего символа указывается подстрочным «аппаратным» курсором:

Я сделал отображение видеопамяти в верхнюю часть адресного пространства процессора. Поэтому при записи в эту область памяти на экране появляется соответствующий символ:
Страничный режим вывода на экран
Если происходит полное заполнение экрана (после операции ввода с консоли), то вывод на экран и работа эмулятора приостанавливается, а в самой нижней строке экрана (она не используется для вывода текста) появляется приглашение «>>>» для нажатия какой-либо клавиши после просмотра информации на экране (страничный режим). После нажатия клавиши происходит прокрутка информации на экране и работа эмулятора продолжается до следующего полного заполнения экрана.
Ввод через PS/2-клавиатуру

В качестве альтернативы вводу из «большого» компьютера через последовательный порт я использую ввод с клавиатуры, подключенной через преобразователь PS/2—UART:
Я сделал такой преобразователь на основе микроконтроллера STM8S103F3P6. К PS/2-разъему этого преобразователя подключается клавиатура, оснащенная соответствующим разъемом, а выход преобразователя подключается к контактам UART Arduino Nano вместо преобразователя USB-UART.
Преобразователь получает скан-коды нажатых клавиш от клавиатуры, помещает их в кольцевой буфер и выдает их в последовательный порт, проверяя предварительно сигнал CTS.

Клавиша Scroll Lock на клавиатуре управляет режимом блокировки прокрутки — при включенной блокировке после непрерывного вывода 19 строк дальнейший вывод блокируется до нажатия любой клавиши на клавиатуре (при этом в самой нижней строке экрана отображается >>>):
Блокировка прокрутки управляется уровнем на выводе A3 Arduino («1» — блокировка выключена, «0» — блокировка включена).

Индикация включенного режима блокировки прокрутки осуществляется желтым светодиодом SCROLL:

Переключение языка ввода (английский/русский в кодировке КОИ-8) осуществляется нажатием сочетания клавиш Alt—Shift:

Включение русского языка ввода индицируется синим светодиодом RUS:
При нажатии сочетания клавиш Ctrl—Alt—Del на клавиатуре выполняется перезагрузка (подается импульс низкого уровня на вход RST Arduino).
Эмуляция дисководов
Я эмулирую поведение дисковода гибких дисков на уровне обращений чтения/записи к портам.
Порты контроллера дисковода/DMA:
порт 0xE0: порт статуса (R)/ команды (W)
порт 0xE1: порт дорожки (R/W)
порт 0xE2: порт сектора (R/W)
порт 0xE3: порт выбора диска (R/W)
порт 0xE4: порт младшего байта адреса DMA-буфера (W)
порт 0xE5: порт старшего байта адреса DMA-буфера (W)
Для эмуляции дисководов гибких дисков (на дискете 77 дорожек с 26 128-байтными секторами на каждой = 2002 (0x7D2) сектора = 256256 байт = 250,25 Кбайт) я использую SDHC-карточку, выделив в ней области, начиная с сектора 0x0001000, для эмуляции 100 дискет (128-байтный сектор эмулируемой дискеты размещен в начале 512-байтного сектора карточки, для каждой дискеты отводится 0x1000 секторов).
Для «общения» с карточкой используется шина SPI:
MISO — прием данных от карточки (D12)
MOSI — передача данных карточке (D11)
SCK — тактовый сигнал для карточки (D13)
SS — выбор устройства (D10)
3V3 — питание 3,3 В
GND — «земля»


Я подключил microSD-карточку посредством специального адаптера:
Для индикации доступа к карте я подключил красный светодиод с балластным резистором между выводами 3V3 (анод светодиода) и SS (катод светодиода).
Для записи образа дискеты на карточку используется команда монитора Nxxxxxxxx, где xxxxxxxx — номер сектора карточки, начиная с которого запиываются данные (в 16-ричной форме), например, команда N00001000 записывает образ дискеты с номером 00.

С помощью команды Z монитора я могу «вставить» дискету в любой из четырех дисководов A, B, C или D:
(например, команда ZB02 монтирует дискету с номером 02 в дисковод B)
Номера «вставленных» дискет запоминаются в EEPROM Arduino и восстанавливаются при повторном запуске эмулятора.
Дискету в дисководе можно отформатировать (заполнить байтами 0xE5) с помощью команды X монитора (например, XA — форматирование дискеты в дисководе A).
Файлы могут быть скопирован с одного диска на другой с помощью утилиты PIP:
например, PIP B:=A:TEST.COM копирует файл TEST.COM с диска A на диск B.
Хранение данных на магнитной ленте
Я реализовал запись данных на магнитную ленту/в аудиофайл и считывание данных с магнитной ленты/аудиофайла.

Для согласования уровней я использую такую схему:

Она рассчитана на запись данных на линейный вход и считывание с линейного выхода.
Схема реализована в виде небольшой платы:

Для подключения внешних устройств служат два RCA-разъема:
При работе с магнитной лентой приостанавливается работа видеогенератора.

Бит информации кодируется четырьмя импульсами: «1» — частотой 2400 Гц, «0» — частотой 1200 Гц (частоты соответствуют стандарту Kansas City standard (KCS)).
Байт данных содержит один стартовый бит («0»), восемь бит данных, начиная с младшего, и два стоповых бита «1».
Данные записываются блоками — каждый блок начинается с пилот-тона (64 «1»), затем следует номер блока (два байта, начиная с младшего), адрес блока в памяти (два байта, начиная с младшего), 128 байт данных и байт контрольной суммы.

Вот как биты представлены в аудиофайле:
Эксперименты показали, что отклонение скорости проигрывания на 20% не влияет на надежность считывания данных.
Пример WAV-файла с записью трех блоков:
tape.wav
Подключение внешних устройств

Для подключения внешних устройств я планирую использовать I 2 C-платы расширения портов PCF8574:
Звуковой сигнал

Для подачи звукового сигнала я использую пьезоизлучатель, подключенный к выводу A0 Arduino Nano (этот же выход используется и для записи на магнитную ленту):
Включение/выключение звукового сигнала управляется портом 0xD7 — для включения сигнала следует записать в порт 1 (OUT D7, 1) , а для отключения — 0 (OUT D7, 0).
Питание

В качестве источника питания (выходное напряжение 5 В) я использую интегральный стабилизатор 7805, входное напряжение (9 В) на который подается с выхода компактного блока питания:
Адаптация операционной системы CP/M

Операционная система CP/M («Control Program for Microcomputers«) версии 2.2 (однопользовательская и однозадачная) была выпущена компанией Digital Research Inc. (DRI) под руководством Гарри Килдалла (Gary Kildall) и его жены Дороти МакЭвен (Dorothy McEwen) в 1979 году.
Гарри Килдалл (Gary Kildall)
Руководство по ОС CP/M версии 2.2 (317 страниц!) можно загрузить здесь — http://www.cpm.z80.de/manuals/cpm22-m.pdf .
Система CP/M должна настраиваться под размер оперативной памяти конкретного компьютера — этот процесс называется «CP/M Alteration«.
Для адаптации операционной системы под актуальный размер памяти я создал проект на Go getcpm (проект доступен на GitHub — https://github.com/Dreamy16101976/getcpm).
Для компиляции программы на Go в исполняемый файл getcpm.exe требуется использовать команду:

При запуске программы getcpm.exe требуется указать размер памяти в килобайтах (XX) и желаемый серийный номер системы CP/M (6 байтов в 16-ричном виде, YYYYYYYYYYYY), после выполнения настройки создается файл CPMXXK.SYS и указывается его восьмибитная контрольная сумма:

Программа, используя файл CPMDIFF.SYS, корректирует адреса в файле CPM00K.SYS, выполняя настройку на заданный объем оперативной памяти:
Размер получаемого файла, содержащего CCP и BDOS операционной системы CP/M версии 2.2, равен 5632 байта.
Я выбрал вариант с 62 Кбайтами ОЗУ (62K system).
Для записи операционной системы CP/M на SD-карточку используется команда монитора N00000100, где 00000100 — номер сектора карточки (в 16-ричной форме), начиная с которого записывается образ системы.
После ввода команды монитор ожидает начала передачи от компьютера, передавая символы C. Затем в программе Tera Term необходимо выбрать для загрузки файл CPM64K.SYS с образом системы. После окончания загрузки происходит возврат в монитор.
CCP и BDOS располагаются на SDHC-карточке, начиная с сектора 256, откуда их загружает написанный мной начальный загрузчик.
Карта памяти системы:
0xFFFF
BIOS — базовая система ввода-вывода
0xFA00
BDOS — базовая дисковая операционная система
0xEC06
CCP — интерпретатор командной строки (командный процессор)
0xE400
TPA (Transient Program Area) —
область программ пользователя
0x0100
cлужебная область операционной системы
0x0000
Я сделал перехват функций BIOS (при обращении по соответствующим адресам памяти) и их реализацию:
(смещения указаны относительно адреса 0xFA00)
| Смещение | Функция |
| 0x00 | BOOT — «холодная» перезагрузка |
| 0x03 | WBOOT — «горячая» перезагрузка |
| 0x06 | CONST — получение состояния консоли |
| 0x09 | CONIN — ввод из консоли |
| 0x0C | CONOUT — вывод в консоль |
| 0x0F | LIST (не реализовано) |
| 0x12 | PUNCH (не реализовано) |
| 0x15 | READER (не реализовано) |
| 0x18 | HOME — переход в начало диска |
| 0x1B | SELDSK — выбор диска |
| 0x1E | SETTRK — выбор дорожки |
| 0x21 | SETSEC — выбор сектора |
| 0x24 | SETDMA — установка адреса DMA-буфера |
| 0x27 | READ — чтение сектора |
| 0x2A | WRITE — запись сектора |
| 0x2D | LISTST — получение состояния устройства вывода листинга (не реализовано) |
| 0x30 | SECTRAN — трансляция логических (с 0)/физических (с 1) секторов |
Для ввода/вывода информации в CP/M используются такие логические устройства:
CONSOLE — консоль;
LIST — устройство для вывода листинга (обычно принтер);
READER — устройство ввода c перфоленты;
PUNCH — устройство вывода на перфоленту.
Оптимизация проекта
Для оптимизации исходного кода проекта я использую утилиту avr-nm, которая позволяет отобразить размеры кода функций и областей памяти, занимаемых переменными:
avr-nm.exe —size-sort -r -C -S -t decimal cpm4nano-master.ino.elf >> size.txt
Указанная команда выводит результирующую информацию (о скомпилированном файле проекта cpm4nano-master.ino.elf) в файл size.txt.
Пример результата работы утилиты:
Вторая колонка указывает размер объекта в памяти в байтах, а третья — его тип (буква в нижнем регистре — локальный объект, в верхнем — глобальный):
T t — текст (код или данные во флэш-памяти), B b — неинициализированные данные в ОЗУ; D d — инициализированные во флэш-памяти данные, скопированные в ОЗУ; W — .
Имя объекта указывается в четвертой колонке.
Эксплуатация
Карта памяти SD-карточки (сектора карточки имеют размер 512 байт)
0x100 . 0x12B — CCP & BDOS (загружаемая ОС CP/M) (44 сектора, в каждом секторе заняты первые 128 байт)
0x1000 . 0x64FFF — данные эмулируемых дискет (доступно 100 дискет, на дискету выделено 4096 (0x1000) секторов) (сектор дискеты занимает первые 128 байт в одном секторе карточки)
0x80000 . 0x98FFF — образы памяти (доступно 100 образов, на образ выделено 1024 (0x400) сектора) (заняты первые 128 байт в секторах карточки)
ИТОГО: 306 МБайт

После включения Arduino Nano происходит детектирование FRAM-чипов памяти на шине I 2 C, проверка оперативной памяти:
Затем запускается монитор и отображается его приглашение к вводу команд «>».
Я реализовал для монитора следующие команды:
RXYY — запись байта YY (hex) в регистр X
DXXXX — отображение байта памяти по адресу XXXX (hex)
LXXXXYY — запись байта YY (hex) в память по адресу XXXX (hex)
W — включение/выключение режима отладки
G — запуск программы с адреса XXXX (hex)
QXXXX — установка точки останова (breakpoint) на адрес XXXX (hex)
F — загрузка двоичной информации из файла формата Intel HEX
BXXXX — загрузка двоичного файла в память с адреса XXXX (hex)
ZXYY — «вставка» дискеты с номером YY в дисковод X
XX — форматирование диска X (X = A,B,C,D) — область на карточке, отведенная для диска, заполняется байтами 0xE5
NXXXXXXXX — запись двоичного файла на карточку, начиная с блока XXXXXXXX (hex) (каждый фрагмент файла длиной 128 байт записывается в начало 512-байтного сектора карточки)
PRXX / PWXX — считывание (R) / запись (W) (карточка) образа памяти с номером XX
UR / UWAAAANN — считывание (R) / запись (W) (магнитная лента или аудиофайл) образа памяти, начиная с адреса AAAA (hex), размером NN (hex) блоков по 256 байт
C — загрузка ОС CP/M
HX — включение 8-битного (X=8) или 7-битного (X=7) режима вывода символов
V — вывод информации о текущем состоянии эмулятора
Запуск программ в мониторе
В мониторе можно запустить монитор от микрокомпьютера «Altair 8800«.

После запуска появляется приглашение в виде точки:

Вводя команду D, получаем дамп области памяти:
Загрузка операционной системы CP/M

При вводе команды «C» происходит загрузка операционной системы с SD-карточки (длится 7,8 секунды — в FAST-режиме / 11,7 секунды — в SLOW-режиме)):
64K SYSTEM — размер памяти, используемый системой, в килобайтах
CBASE — адрес начала CCP
FBASE — адрес начала BDOS
BIOS — адреса процедур BIOS
После загрузки отображается приглашение операционной системы «A>».
В ОС CP/M встроено несколько команд:
DIR — вывод списка файлов
REN — переименование файла
ERA — удаление файлов
SAVE — сохранение области памяти в файл
TYPE — вывод содержимого текстового файла
USER — задание текущего номера пользовательской области

Пример результата выполнения команды DIR:
При нажатии клавиш CTRL + / при запросе ввода с консоли происходит возврат из ОС CP/M в монитор.
Загрузка файлов в эмулятор
Для загрузки файлов в эмулятор посредством терминальной программы (я покажу этот процесс на примере программы Tera Term) используется протокол XMODEM.

Для загрузки в оперативную память двоичного файла используется команда монитора Bxxxx , где xxxx — начальный адрес в памяти для загрузки файла (в 16-ричной форме):
После ввода команды монитор ожидает начала передачи от компьютера, передавая символы C.

Затем в программе Tera Term необходимо выбрать пункт меню для передачи файла по протоколу XMODEM:

Затем следует выбрать файл для загрузки (например, CPU.COM):

После выбора файла начинается его загрузка:

После окончания загрузки происходит возврат в монитор:
При этом отображается количество принятых байт.
Для загрузки в оперативную память текстового файла используется команда монитора Txxxx , где xxxx — начальный адрес в памяти для загрузки файла (в 16-ричной форме). Если в загружаемом текстовом файле встречается байт со значением 0xA, то он считается символом конца файла и передаваемые дальше байты игнорируются.
Для загрузки в оперативную память данных из файла формата Intel HEX используется команда монитора F.

Для записи загруженных (с адреса 0x100) данных на диск необходимо загрузить ОС CP/M командой монитора C:

Затем следует записать содержимое памяти, начиная с адреса 0x100, на диск в файл FILE.COM командой
SAVE n FILE.COM , где n = [ размер файла FILE.COM / 256 ] + 1:

После окончания записи записанный файл CPU.COM отображается при просмотре директории командой DIR:
Я записал на эмулируемый флоппи-диск стандартные системные программы:
ASM.COM — ассемблер
DDT.COM — отладчик
DUMP.COM — вывод файла в 16-ричном виде
ED.COM — текстовый редактор
LOAD.COM — создание COM-файла из HEX-файла
PIP.COM — копирование файлов
STAT.COM — вывод состояния диска
SUBMIT.COM — выполнение SUB-файла
XSUB.COM — выполнение расширенной программы SUBmit
Также я разместил на диске интерпретатор бейсика TINYBAS.COM и тестовые программы TEST.COM, 8080PRE.COM, 8080EX1.COM.
Оценка быстродействия
Прогон из монитора 32768 команд:
| Команда | FAST-режим | SLOW-режим |
| NOP | 1,7 секунды | 3,0 секунды |
| MOV A, A | 1,8 секунды | 3,3 секунды |
| DAA | 2,0 секунды | 3,6 секунды |
Выполнение теста DIAGNOSTICS II V1.2:
(между BEGIN TIMING TEST и END TIMING TEST):
| FAST-режим | SLOW-режим |
| 899 секунд | 1743 секунды (x1,94) |
Выполнение тестовой программы в TINYBASIC:
| FAST-режим | SLOW-режим |
| 123 секунды | 202 секунды (x1,64) |
Выполнение скомпилированной программы PRIMES, написанной на Ada (найдено 1899 простых чисел):

| FAST-режим | SLOW-режим |
| 10320 секунд | 16980 секунд (x1,65) |
Программирование

Я запустил интерпретатор бейсика TinyBASIC (SHERRY BROTHERS TINY BASIC VER. 3.1):
Ссылка на скачивание zip-архива с исполняемым файлом TINYBAS.COM и файлом справки TINYBAS.DOC:
https://acdc.foxylab.com/sites/default/files/TINYBAS.ZIP

Мой «нанокомпьютер» успешно запустил BASIC (8 килобайт, версия 4.0) для микрокомпьютера Altair:
Файл 8kbas40.bin загружается в память с помощью команды монитора B000 . Затем он запускается командой G0000 (предварительно нужно отключить режим отладки командой W ). После загрузки можно сохранить образ памяти на SD-карточке с помощью команды PXX ( XX — номер образа), и затем загружать его командой UXX .
Особенности этого диалекта BASIC:


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

Для удаления последнего введенного символа необходимо ввести знак подчеркивания:

Программу можно загрузить с компьютера через терминальную программу из текстового файла такого формата:

Вот такой тест выполняется 110 секунд в FAST-режиме (162 секунды в SLOW-режиме):

Также я проверил работоспособность четырехкилобайтной версии Бейсика:
Я записал на эмулируемую дискету компилятор CBASIC от компании Digital Research, который представлен такими файлами:
CB80.COM — компилятор
LK80.COM — линкер
CB80.OV1 — оверлей
CB80.OV2 — оверлей
CB80.OV3 — оверлей
CB80.IRL — ран-тайм библиотека
В моем эмуляторе успешно выполняются компиляция и линковка программ.
Вот какую тестовую программу я записал в файл HELLO.BAS:
Компиляция тестовой программы выполняется командой

Результатом компиляции является объектный файл HELLO.REL.
Линковка программы выполняется командой

Получаемый в процессе линковки исполнимый файл HELLO.COM успешно запускается командой

и выводит сообщение:

Интерпретатор FOCAL для микрокомпьютера Altair успешно заработал на моем «нанокомпьютере»:

Я успешно испытал компилятор и линкер из пакета BD Software C:
Компиляция тестовой программы TAIL.C выполняется командой
Результатом компиляции является объектный файл TAIL.CRL.
Линковка программы выполняется командой
В результате создается исполняемый файл TAIL.COM.

Я запустил FORTH-83 (файл f83.com доступен здесь):

В качестве примера я ввел и исполнил простую программу, выводящую сообщение HELLO, WORLD!:
Основные команды FORTH-83:
(при успешном выполнении команды выдается ok)
10 CREATE-FILE HL.BLK — создание файла HL.BLK размером 10 блоков
OPEN HL.BLK — открытие файла HL.BLK
1 LOAD — загружает из открытого файла экран 1 и компилирует содержащиеся в нем описания слов
HL — выполнение слова HL из открытого экрана
BYE — выход в CP/M
Можно вводить немедленно исполняемые команды:
2 2 + . — складывает 2 и 2 и выводит результат (4):
2 — 2 помещается в стек
2 — 2 помещается в стек
+ — складывает аргументы из стека и помещает результат в стек
1 3 — . — вычитает 1 из 3 и выводит результат (-2):
Я записал на эмулируемую дискету компилятор языка программирования Ada версии 2.10 от компаний Supersoft Inc. и Maranatha Software Systems.
Архив с компилятором можно скачать здесь — acdc.foxylab.com/ada.zip .
Компиляцию программы TOWERS.ADA решения задачи о «Ханойской башне» я выполнил командой:

В процессе компиляции создаются временные файлы TOWERS.INT и TOWERS.OPT и результирующий файл TOWERS.COM.
Затем я запустил скомпилированную программу TOWERS.COM на выполнение командой

и получил решение задачи для трех колец:
Я запустил интерпретатор LISP/80 версии 1.1 от Thomas W. Yonkman:

Заметка об этом интерпретаторе в журнале BYTE:


Также я проверил работоспособность интерпретатора языка программирования MINOL («Tiny BASIC with Strings in 1.75K Bytes«), созданного для микрокомпьютера Altair :
Файл minol22.bin загружается в память с помощью команды монитора B000 . Затем он запускается командой G0000 (предварительно нужно отключить режим отладки командой W ). После загрузки можно сохранить образ памяти на SD-карточке с помощью команды PXX ( XX — номер образа), и затем загружать его командой UXX .
Игры

А вот как выглядит запуск игры реверси (Othello), написанной на языке C (файл OTHELLO.C скомпилировался в файл OTHELLO.COM):

В этой партии я играю *, а «нанокомпьютер» — @.
Ходя заключается в указании расположения фишки, размещаемой на доске:
34 — третья строка, четвертый столбец:
Цель игры — окружить фишки соперника, при этом окруженные по горизонтали или вертикали фишки «переворачиваются».
На обдумывание хода у «нанокомпьютера» уходит около шести минут.
А вот как выглядит запуск игры Star Trek, написанной на языке Ada (файл STARTREK.ADA скомпилировался в файл STARTREK.COM):


на ЭЛТ ТВ:
Star Trek представляет собой симулятор пилота космического корабля USS Enterprise (NCC-1701) во вселенной «Звездного пути» («Star Trek Universe«). Автор оригинальной версии игры — Mike Mayfield, (дата выпуска — 20 октября 1972 года).
Игровое поле (галактика) имеет размеры 8 x 8 квадрантов (quadrant), причем каждый квадрат состоит из 8 x 8 секторов (sector).

Цель игры — уничтожить с помощью фазеров космические корабли Клингонов — инопланетной цивилизации гуманоидов-воинов.
Флаг Клингонской империи (Klingon Empiry):
Quadrant, Sector — текущее местоположение игрока
Stardate — текущая звездная дата
Метки на карте текущего квадранта:
E — космический корабль Enterprise игрока;
B — база звездного флота (starbase);
K — корабль Клингонов (Klingon ship);
* — звезда (star)

Команды:
(список команд отображается при вводе номера команды, отличного от 0,1,2,3):
0 — дальнее сканирование (Long Range Scan);
1 — ближнее сканирование (Short Range Scan);
2 — фазеры (Phasors);
3 — навигация (Navigate).

При выполнении дальнего сканирования (команда 0) отображаются 9 квадрантов (в центре (E) — квадрант, в котором находится игрок). Для остальных квадрантов отображаются две цифры, например, 3 — 5:
(система координат: ось x — сверху вниз от 1, ось y — слева направо от 1).

При выполнении ближнего сканирования (команда 1) отображается карта текущего квадранта:
(система координат: ось x — сверху вниз от 1, ось y — слева направо от 1).
Для навигации (перемещения в космосе) (команда 3) необходимо указать тип двигателя (I (Impulse Drive) — перемещение в пределах квадранта между секторами, W (Warp Drive)- перемещение между секторами) и ввести новые координаты x и y:
перемещение между квадрантами:

перемещение внутри квадранта:

Для атаки корабля Клингонов фазером (команда 2) необходимо указать мощность выстрела. Фазер не требует прицеливания, но сила его удара уменьшается с удалением от цели. После выполнения атаки отображается урон, нанесенный вражескому кораблю, и полученный от вражеского корабля:

При нанесении достаточного урона корабль Клингонов уничтожается и исчезает с карты:

Играющая в шахматы программа Microchess для микрокомпьютеров на процессоре Intel 8080 была разработана в 1977 году компанией MICRO-WARE LTD.:
Авторы программы: Peter R. Jennings (канадский исследователь) и T. O’Brien.
Эта была первая коммерчески успешная (было продано сыше 10 тысяч копий) шахматная программа для микрокомпьютеров. Код игры продавался напечатанным в брошюре, поэтому пользователь должен был сам ввести его в компьютер.

Вот как выглядит запуск этой программы на моем «нанокомпьютере»:

Клетки доски пронумерованы таким образом:
На мой первый ход пешкой:


программа ответила ходом конем:
Эксперименты с Arduino. Часть 1. Бортовой компьютер

Как вы помните, предыдущую запись в своем блоге про круиз-контроль я закончил фотографией, на которой были запечатлены компоненты моей будущей игрушки. Следующие 2 недели я провел за изучением абсолютно новой для себя сферы, и стоит сказать наперед, что давно я так ничем не увлекался…
Не буду кривить душой, я всего несколько раз в своей жизни за 30 лет паял проводки и почти ничего не понимал в электронике на предметном уровне. Сам я по профессии программист, имею прикладное математическое образование. Программирование полюбил еще с детства, когда отец (ведущий инженер-электронщик, работающий на закрытом военном НИИ) принес нам домой собранную собственноручно вариацию популярного в 80-х — 90-х компьютера ZX-Spectrum. Отец подключил его к телевизору и показал простейшие команды на встроенном в Спектрум языке Бейсик — как заливать цветом экран телевизора, как рисовать круги, прямоугольники, овалы и прочее. Мне было 5 лет, был 90-й год и все это казалось безумно интересными вещами. Вот тогда я просто стал бредить компьютерными играми. Кто в теме, тот наверное помнит потрясающую ауру загрузки игр с кассет, помнит незабываемый скрипучий звук и медленно появляющееся изображение заставки игры. А игры… до сих пор скучаю по той атмосфере необычности некоторых игрушек, часы, проведенные за игрой Elite, которая дала огромный толчок к развитию космических симуляторов… Эта сфера так сильно меня очаровала, что свою первую игру я написал в 11 лет на языке Logo, который изучают в младших классах для «вдалбливания» основ программирования малолетним чадам. В то время как остальные рисовали простейшие фигуры, учили циклы, рекурсии меня влекло создание компьютерных игр. На зимних каникулах была написана игра-стратегия «Сечь» о запорожских казаках, которые отбивают землю у поляков и турков ) Потом футбольный симулятор, оболочку наподобие Norton Commander (помните такое? )))). Затем любовь к футбольному клубу Шахтер сподвигла на написание футбольного менеджера клуба и с этой игрой я уже ездил на Всеукраинскую Малую Академию Наук, что помогло затем поступить в универ на бюджет… Уже студентом я выбрал для себя Java как главный язык программирования и узнал, что на нем можно писать мобильные игры. А дальше пошло как по накатанной. Я был молод, у нас с моей будущей женой были общие интересы, она неплохо рисовала, мне хотелось что-то делать, мою игру заметили, позвали работать в большую как для студента компанию в Украине, а уж тем более в Донецке. Спустя год пошла переквалификация в веб-программиста и в данной сфере остаюсь и поныне.
Однако все это время меня не покидало желание пойти еще дальше и писать не только код в редакторе, но и работать непосредственно с железом. Именно поэтому у меня все время владением машины был постоянный зуд влезть то в один, то в другой узел автомобиля, что-то делать не только виртуально, но и руками.
Поставив почти все, что можно найти в Украине и не только на нашу машину, стал думать, а что еще можно сделать. И тут мой взгляд зацепился за Ардуино и я понял, это оно )

Если вы еще не слышали об Arduino, то вот вам маленький ликбез с офиц. сайта:
Arduino — это платформа с открытым исходным кодом, созданная для быстрой и легкой разработки разнообразных электронных устройств. Ардуино может получать данные об окружающем мире благодаря датчикам и реагировать, управляя светом, моторчиками и другими приводами. Микроконтроллер на плате программируется с помощью языка программирования Arduino и среды разработки Arduino. Для программирования не требуется программатор, программа зашивается через порт USB. Для начала работы понадобится только сама плата Arduino и компьютер с установленной средой разработки Arduino.
По сути ничего нового. Мой отец уже давно прошивает микроконтроллеры, проектирует платы, собирает устройства и все это известно и применяется многими радиолюбителями. Однако меня привлекла простота старта освоения этой сферы, доступность компонентов, хорошая документация и куча, нет не так, миллионы примеров в сети. Есть еще один плюс для наших итальянских машин — платформа итальянская. А уж тюнить итальянцев мы умеем )
Как человек сугубо практичный и не желающий практиковаться на абстрактных примерах, сразу решил делать реальную вещь, причем такую, которую можно использовать в машине. Свой рассказ я разобью на две части, которые будут связаны между собой и будут описывать то, что получилось в итоге.
В качестве первой вещи, которую хотелось бы сделать я выбрал проект бортового компьютера нашего драйвовчанина horhomun , отлично описанный в статье на Хабрахабр. Пользуясь статьей были куплены необходимые на первый взгляд компоненты:

А именно модуль Bluetooth HC-5, LCD экран 20×4, платку Arduino Uno, макетку и кучу перемычек. Ну а потом пошло-поехало ) Нашелся старый паяльник, отец прислал припой, инструменты, на местном радио рынке были куплены корпус, коннекторы, провода, кнопки и прочая хрень, на которую раньше просто не обращал внимания )
Остановимся немного на проекте. Проект представляет собой устройство, которое без проводов подсоединяется к бортовой сети машины через диагностический разъем OBD-II. Вы спросите, а чем родной то не устраивает? ) А я вам отвечу, а вы сможете в родной компьютер запихнуть новые функции, которые ограничиваются лишь вашей фантазией? ) Расход, скорость и пройденный путь это хорошо, но этого мало. Я знаю одного человека, который перепрограммировал родную приборку на пунто и смог выводить туда все, что хочет используя OBD и CAN. Но своим ноу хау он не захотел делиться. Также вы спросите, а как же твоя диагностика по wifi? Будете правы, все тоже самое я могу смотреть со своего айфона. Но вот, а если я хочу добавить что-то свое? Программу на айфоне я не переделаю, а тут свободное поле для творчества. При этом телефон при связи по wifi греется и быстро расходует заряд аккумулятора. А телефон, сами знаете, может сесть в самый неподходящий момент. Поэтому автономное удобно расположенное устройство, которые при необходимости покажет полезную информацию по машине в том виде, в каком я сам захочу — очень полезный в хозяйстве инструмент. А уж тем более — это отличный полигон для изучения новой для меня сферы, а также замечательный плацдарм для дальнейшего тюнинга.
Первой сложностью для меня стала настройка модуля блютуза:

Данная модель умеет работать в двух режимах master/slave, и чтобы она без пароля подсоединялась к адаптеру Bluetooth ELM 327 нужно было прописать в нее с помощью AT-команд MAC-адрес адаптера и перевести в режим master. Пару слов о bluetooth адаптере ELM 327. Как вы помните у меня стояла на постоянке wife версия ELM 327. Однако проект был заточен под bluetooth, поэтому встал вопрос поиска донгла. В современных донецких условиях это нереально. Поэтому окольными путями в ближайшем селе Селидово был куплен такой вот красивый донгл:

Удобной его фишкой является автоотключение от питания и наличие кнопки включения/выключения. Забегая вперед скажу, что вырезав небольшое отверстие в крышке обшивки удалось очень удобно расположить адаптер в диагностическом разъеме и иметь возможность быстро его включать/выключать:

Далее взяв ноут с виндой удалось найти MAC-адрес адаптера и добавить его в модуль блютуз для ардуино:

Далее пошло подключение экрана и прочих компонентов:

В коробке из-под конфет конструкция была отнесена в машину и был получен первый болт ) Блютузы обиделись друг на друга и не хотели упорно видеть попытки спариться ) Пришлось обратиться к автору проекта, попробовать одну штуку. Однако не помогло. Далее просто повторил инициализацию HC-05 по новой и о чудо, моя шайтан-коробка заработала )))
Пришел момент самого интересного ) Поиск корпуса. На местном радиорынке купил недорогую коробочку. И вот тут началось мучение — как аккуратно вырезать дыру под LCD экран. Сами понимаете опыта у меня нет, инструментов нет, ничего нет ) Пришлось кумекать:
1. Первым делом потренировался «на кошечках» ). Врезал кнопку включения/выключения (будет использоваться во второй части рассказа)


Но лиха беда начало ) Это были только цветочки. Далее в ход пошла тяжелая артиллерия:
Похожие публикации:
- Как добавить esp32 в arduino ide
- Как добавить комментарий в css
- Как убрать фокус с input css
- Как увеличить размер текста css
