Arduino Nano - эмулятор компьютера под управлением ОС CP/M

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Приветствую всех любителей Arduino! Ностальгия по восьмибитным временам побудила меня сделать свой CP/M компьютер из ... чего бы Вы думали? Arduino Nano 3.0
За недели две-три я сделал эмулятор процессора i8080 для Arduino Nano (он проходит тест от MICROCOSM) и адаптировал CP/M. Основная проблема - в ардуинке всего 2 (!) кбайта ОЗУ. Но у нас же есть SD-карточка - я сделал 4-х линейный кэш (по 32 байта) к этой карточке, а сама карточка эмулировала все 64 кбайта ОЗУ. Скорость работы не такая уж и плохая, хотя я использовал примитивный алгоритм управления кэшем. Заодно эта карточка эмулирует и четыре гибких диска.
Вот quick-and-dirty прототип моего поделия:

Да, я не использовал адаптер для карточки, я вставил ее в разъем шлейфа от пятидюймового дисковода. :-)
Для связи с компьютером я использую терминальную программу (в будущем планирую PS/2-клавиатуру и ЖК-экран либо подключение к телевизору).
Вот скриншот проверки памяти:

Загрузка CP/M:

Тест процессора:

А вот моя первая программа на Бейсике за прошедшие двадцать (! )))) лет:

(я запустил на своем поделии TinyBASIC).
Более подробное описание я начал делать здесь - https://acdc.foxylab.com/node/76

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Круто!

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Спасибо!  После "прихорашивания" кода скетча для Arduino выложу его в этот репозитарий https://github.com/Dreamy16101976/cpm4nano - (там пока только Go-программа для заливки HEX-файлов с компьютера - мой первый опыт программирования на этом языке :-) ).

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

FoxyLab пишет:

Более подробное описание я начал делать здесь - https://acdc.foxylab.com/node/76

Пока низя?

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Спасибо, исправил (галочку "Опубликовано" забыл поставить - я то видел как администратор, а гости нет :-).

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

"эмуляция процессора Z80"
Ещё б озвучить потом )))

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

К своему клону Спектрума  48К я подключал Ямаховскую микросхему AY8910 (если не путаю наименование) - весьма задорно пиликала, там еще и GPIO-выводы были (как бы их сейчас назвали). Но эмулирование Спектрума как такового намного сложнее - из-за необходимости обеспечить повышенную скорость эмулирования, "уметь" его графический режим, интенсивное использование прерываний опять же. "Нано" не вытянет, с CP/M в этом плане проще.

OlegK
OlegK аватар
Offline
Зарегистрирован: 26.11.2014

Да я шутейно )) Вспомнились, просто, кассетные времена.
Это потом, когда приобрёл Спектрум 128, на борту был дисковод 5.25 - так казалось, что всё пулей грузилось...

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Да, были времена!!! Я к 48-кбайтному подключал дисковод - местные Кулибины мастерили платки. В TR-DOS был один интересный глюк-фича, который позволял посекторно писать/читать айбиэмовские дискеты - в итоге я сотворил программу, которая позволяла читать (и если опять же память не подводит - и писать) файлы с/на дискеты от ПК.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

FoxyLab, приятно конечно, что на форуме не только чайники есть, но и люди с руками и головой :) Тут  кстати вспомнился недавний пост нашего спектрумиста. Вот ещё б Ваши головы придумали что нибудь реально полезное -было б совсем прекрасно :-)) У меня вот прямо противоположная ситуация, нужно много всякого  сделать, и в мыслях рисутся мегаполезные вещи, но реально делать их, а особенно писать программы больше десятка строк - вселенски тоскливо (( Вот например к лету нужен контроллер аккумулятора фары для велосипеда, что б всегда точно знать сколько времени фара сможет светить, и уменьшать яркость, если нужно растянуть, или увеличивать -если энергии дофига. Но словами не описать, как же лень это разрабатывать. Ладно бы не мог, а то ведь могу.. ))

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Так оно то конечно так :-) Хобби у всех разные.

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Интересный проект! Закрепил - пусть будет повыше)

Ждём-с исходных кодов.

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Спасибо!

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

А команда XLAT эмулируется?

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

XLAT - это уже i8086 (опкод D7).
Вот i8080 машинные коды - http://pastraiser.com/cpu/i8080/i8080_opcodes.html

В 8080 опкоду D7 соответствует команда RST 2.

Выложил на YouTube видео работы моего проекта в реальном времени:
https://youtu.be/LHFmt3qWAuY

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

FoxyLab пишет:

XLAT - это уже i8086 (опкод D7).
Вот i8080 машинные коды - http://pastraiser.com/cpu/i8080/i8080_opcodes.html

В 8080 опкоду D7 соответствует команда RST 2.

Выложил на YouTube видео работы моего проекта в реальном времени:
https://youtu.be/LHFmt3qWAuY

Книга по I8080 должна где-то быть )))
 

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Я выгрузил очень сырую версию кода моего проекта на Github:
https://github.com/Dreamy16101976/cpm4nano

Также я сделал эмуляцию портов 0 и 1 в стиле "Альтаира". Это позволило мне запустить Альтаировский TinyBASIC без (!) CP/M.

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Упорядочил немного код, сделал эмуляцию консоли и контроллера флоппи-дисковода на уровне портов - теперь можно запускать программы и без загрузки CP/M.

Но один из тестов показал ошибку - из скудного описания вроде бы во флаге переноса. Возможно из-за этого глючит команда TYPE в CP/M.

alex_r61
Offline
Зарегистрирован: 20.06.2012

А карточки насколько хватит, при таком обращении?

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Вот я и проверю :-)

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Может, в будущем прикрутить SPI RAM? (IIC/Parallel/по вкусу).

И быстрее запись,чтение будут, и по циклам нормально)

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Да, ферроэлектрическая память на eBay 0.6$ за 32 Кбайт - 1 МГц, невообразимое количество циклов - но я выбрал пока что свой лимит на месяц по посылкам - а в BY у нас 22 евро в месяц. Так что "... непременно ... Но позже" (C) ДМБ :-)

alex_r61
Offline
Зарегистрирован: 20.06.2012

Можно в Proteus пока попробовать, симуляция работает, только в образ карты закинуть нужные файлы. Внешняя память не помешает, иначе карта быстро сдохнет.

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

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

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

Ну а потом можно и FRAM подключить...

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Для упрощения настройки CP/M под актуальный размер ОЗУ я извлек образ CCP и BDOS из MOVCPM.COM и проанализировал (с помощью программы, конечно) различия между этим шаблонным образом и реальным образом системы с 62 КБайтами. Результатом стал проект getcpmhttps://github.com/Dreamy16101976/getcpm .
При запуске программы getcpm.exe требуется указать размер памяти в килобайтах (XX) и желаемый серийный номер системы CP/M (6 байтов в 16-ричном виде, YYYYYYYYYYYY), после выполнения настройки создается файл CPMXXK.SYS и указывается его восьмибитная контрольная сумма:

Программа, используя файл CPMDIFF.SYS, корректирует адреса в файле CPM00K.SYS, выполняя настройку CCP и BDOS на заданный объем оперативной памяти:

Сама программа написана на Go и компилируется командой go build getcpm.go

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Я нашел и исправил ошибку в эмуляции команд INR N/DCR M.

Теперь команда TYPE работает правильно!!!

Эмулятор почти готов к применению, я напишу для интересующихся инструкцию, как "приготовить" SD-карточку.

P.S. Гарри знал свое дело, его система загружалась и выполняла многие команды даже при неверно работающих довольно часто встречающихся командах процессора!!!

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Добавил LRC-контрольную сумму для данных памяти при записи/чтении на карточку. Пока сбоев не было.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

FoxyLab пишет:

Добавил LRC-контрольную сумму для данных памяти при записи/чтении на карточку. Пока сбоев не было.

а код привести можете

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Код на Гитхабе (вверх, пост №16), я регулярно делаю туда коммиты :-)

P.S. Также я сделал ввод с консоли более универсальным - через прерывания - с прицелом на подключение в дальнейшем PS/2-клавиатуры + добавил команду R монитора для сброса ардуинки.

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Сделал 200 прогонов теста памяти (добавил команду в монитор) - сбоев не обнаружено:

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Где-то у меня пылится программатор, надо попробовать прикрутить )))

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

ua6em пишет:

программатор

Вы хотите залить в ATmega ардуинский загрузчик или Ардуино Мини решили прошить? Я Ардуино Нано, выделенную под этот проект, прошиваю через USB-Serial преобразователь (в отличие от юсб-шного  подключения он не сбрасывает Ардуино при открытии порта - это нужно для заливки файлов программ в эмулятор).

_mikka
Offline
Зарегистрирован: 01.11.2015

Автор порадовал, молодец, прям задушу взяло!

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Спасибо!!!

Я сейчас переписываю код под концепцию шин адреса и данных + использование внутренних регистров 80-го (W, Z, TMP и ACT) и эмуляция микроопераций (по возможности) по интеловскому мануалу - выйдет намного ближе к реальному 80-му да и интереснее опять же.

alex_r61
Offline
Зарегистрирован: 20.06.2012

А немецкий проект смотрели, там внешняя память используется.

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

У меня тоже микросхема SPI SRAM 32 КБайта лежит, в будущем подключу, я даже уже процедуры обращения к ней добавил, но этот момент не слишком интересный, лично для меня, конечно - с карточкой,конечно, медленнее, но для отладки алгоритмов не критично. А так - на чем только этот 80-й не моделировали. Первым был IMHO американский товарищ, который его на 6502 сэмулировал, в середине 70-х, втиснув эмулятор чуть ли не в 2 КБайта.

alex_r61
Offline
Зарегистрирован: 20.06.2012

Я не про древние века :) https://www.mikrocontroller.net/articles/AVR_CP/M

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Спасибо! Я много разных проектов посмотрел, я просто упомянул про истоки, так сказать :-)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

FoxyLab пишет:

У меня тоже микросхема SPI SRAM 32 КБайта лежит, в будущем подключу, я даже уже процедуры обращения к ней добавил, но этот момент не слишком интересный, лично для меня, конечно - с карточкой,конечно, медленнее, но для отладки алгоритмов не критично. А так - на чем только этот 80-й не моделировали. Первым был IMHO американский товарищ, который его на 6502 сэмулировал, в середине 70-х, втиснув эмулятор чуть ли не в 2 КБайта.

6502 хороший процессор на нем люмо был сделан если не ошибаюсь

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Так точно!

А еще на нем был сделан "Агат"!!!

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

FoxyLab пишет:

Так точно!

А еще на нем был сделан "Агат"!!!

А, точно, с цветным дисплеем )))
Такие два у Владимира на телевидении в Домбае были, там еще ось своеобразная была и, из языков программирования Рапира и Бэйсик вроде, помню, 100 строк кода и можешь ехать на покатушки )))

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Да, Бейсик там точно был - Агат был первой машиной (не считая МК-61 и МК-52 :-)), для которой я написал и запустил работающую программу на Бейсике :-)

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

С помощью эмуляции шин адреса и данных, а также внутренних регистров (W, Z, ACT, TMP), сделал эмуляцию микроопераций как можно ближе к "железному" процессору + с помощью #define сделал код эмуляции намного более наглядным. Новый код уже выложен на GitHub.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

FoxyLab пишет:

Да, Бейсик там точно был - Агат был первой машиной (не считая МК-61 и МК-52 :-)), для которой я написал и запустил работающую программу на Бейсике :-)

У нас проще было - сервисная машина, выдавала, что на неисправность проверять
Так что нарисовал диагностику одного блока и свободен
Сервисная документация в электронном виде - в оригинале 80 фолиантов толщиной с красный кирпич

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

По результатам тестов время случайного доступа к эмулируемой картой оперативной памяти составило около 7 миллисекунд.

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Из-за применения кэширования среднее время доступа при последовательном доступе к памяти составляет около 80 микросекунд.
Я использовал тест на Бейсике (в интерпретаторе TINYBASIC) для оценки влияния кэша на быстродействие в реальной задаче:
Изображение
(размер линии кэша составляет 64 байта)
кол-во линий кэша время выполнения теста (секунды)
2 ................................... 345
4 ................................... 155
6 ................................... 80
8 ................................... 60

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015
Я запустил на моей Ардуинке компилятор языка Ada!!!
Компиляция программы TOWERS.ADA решения задачи о "Ханойской башне":
 
[IMG]
 
Запуск скомпилированной программы TOWERS.COM:

[IMG]

 

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Изменил подход к эмуляции НГМД — выделил на карточке область для хранения содержимого 100 дискет и командой монитора Z «вставляю» дискету в один из дисководов A, B, C или D
(например, команда ZB02 монтирует дискету с номером 02 в дисковод B)
cpm_floppy.png
Номера «вставленных» дискет запоминаются в EEPROM Arduino и восстанавливаются при повторном запуске эмулятора.

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Сделал эмуляцию устройства управления памятью (MMU) с переключением банков, что позволило иметь доступ к 512 КБайтам памяти.
Я разделил адресное пространство 0x0000...0xFFFF на 16 блоков (с номерами от 0x0 до 0xF) размером по 4 КБайта. Каждый блок может быть отображен в один из 8 банков (размер банка - 64 КБайта). Соответствие банков блокам определяется значениями (номерами банков от 0 до 7) в наборе из 16 регистров (при запуске эмулятора активен только банк 0).
Для задания номера банка для определенного блока используются две команды вывода в порт:
OUT D0, номер_блока
OUT D1, номер_банка
Также для переключения блока памяти X на банк памяти Y можно использовать команду монитора YXY.

FoxyLab
FoxyLab аватар
Offline
Зарегистрирован: 10.06.2015

Тестирование 8 банков (512 КБайт памяти):

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Здорово продвинулись!!!