|
nedoPC.orgElectronics hobbyists community established in 2002 |
|
Gigatron (компьютер на рассыпухе)
Author |
Message |
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Я посмотрел в исходники Gigatron ROM и увидел, что software stack там есть. Впрочем, это и не удивительно, авторы сами об этом везде рассказывают: И, действительно, судя по исходникам, программный стек начинается с адреса $80. Я решил не копать пока авторские муторные исходники, а попробовать реализовать software stackсамостоятельно. На мой взгляд всё должно работать примерно так: Предположим, что у нас выполняется некоторая программа, из которой будет вызов подпрограммы, и предположим пока для простоты, что ячейки адреса возврата находятся в нулевой странице ОЗУ по адресам 80Н и 81Н для младшего и старшего байтов адреса, соответственно, а в ячейке 7FH находится указатель "стека": | | | | Code: ORG 0000H LDA 80H; указатель "стека" STA [7FH]; инициализируем
... что-то делаем ...
LDA 00H LD AC,OUT; - clear port NOP; - Delay NOP; - 20 mS ;------------ собираемся вызвать подпрограмму LD 80H,X; Укажем на ячейку памяти "стека" LDA RETADDR<; в A - младший байт RETADDR STA [X]; сохраняем младший байт в ячейку памяти "стека" ADD 01Н,X; сдвинем вверх указатель стека LDA >RETADDR; в A - старший байт RETADDR STA [X]; сохраняем старший байт в ячейку памяти "стека" ;------------ адрес возврата сохранен в программном "стеке"
LDA [7FH]; берем указатель стека ADD 02Н; указатель сдвигаем на свободную ячейку 82Н STA [7FH]; сохраняем указатель "стека"
;------------ готовим вызов подпрограммы по адресу 3F55H LD 3FH,Y; - старший адрес (или сегмент) перехода LDA 30H; - аргумент, передаваемый в функцию JMP Y,55Н; переход к подпрограмме NOP; - after JMP RETADDR: - адрес возврата из подпрограммы (компилятор его знает) ... ... ... SUB3F55: ... что-то делаем ... ... ;------------ готовим возврат из подпрограммы LDA [7FH]; берем указатель стека SUB 01Н,X; сдвинем вниз указатель стека LDA [X]; взяли из "стека" старший адрес LD AC,Y; указали старший адрес возврата SUB 01Н,X; сдвинем вниз указатель стека LDA [7FH]; берем указатель стека SUB 02Н; указатель сдвигаем на свободную ячейку 80Н STA [7FH]; сохраняем указатель "стека" LDA [X]; взяли из "стека" младший адрес JMP Y,AC; возвращаемся из подпрограммы на RETADDR | | | | |
Да, несколько громоздко, но это плата за отсутствие аппаратного стека и неортогональность регистров. Если вызов подпрограммы ближний, типа BRA, то сохранять в стеке необходимо лишь младший байт адреса возврата - программа будет короче.
_________________ iLavr
|
08 Sep 2020 14:21 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
К примеру, есть команда: ST undef,[$OP]; ST <=> STORE Судя по логике работы механизма адресации это должно выполняться как ST [$OP],[$OP]То есть, байт из 0-страницы по адресу [$OP] записать в 0-страницу по адресу [$OP]. Но за один такт ОЗУ невозможно прочитать и записать по одному и тому же адресу, так что, видимо, запись в ОЗУ производится, но на шину данных не включен ни один источник. Поэтому, вероятно, в ОЗУ и запишется что-то undefind (" неопределеное") с шины.
_________________ iLavr
|
09 Sep 2020 06:20 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Попробовал... Плохо ложатся мнемоники Gigatron-а на мои исходники... В моих исходниках всюду под Интелловское соглашение расточено, типа: MOV [приёмник],[источник]А в мнемониках Gigatron-а всё наоборот: LD [источник],[приёмник]Много кода перелопатить придётся...
_________________ iLavr
|
09 Sep 2020 10:22 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
А вот есть мысль весьма недурственная на этот повод: Если на выход регистра OUT Gigatron-a прицепить эту самую PIA 6820, как в Apple I, или её аналог типа UART MC6850, как я сделал в Apple_I in Proteus, а затем пропатчить vCPU и v6502, чтобы вместо генерации VGA-сигнала они делали вывод на UART, то может получиться весьма быстрый виртуальный 6502 и виртуальный Apple I, как бы даже не пошустрее оригинала! Да, графики с цветом не будет, но у Apple I их и так не было... На выходе UART можно прицепить любую терминальную програму, или же терминалку на контроллере, коих развелось великое множество, как в "Аюше", к примеру...
_________________ iLavr
|
10 Sep 2020 00:14 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Я просмотрел внимательно систему команд, и пришел к выводу, что скобки там в большинстве случаев - это просто "понты", хотя и читается довольно удобно, но компилятор ассемблера писать неудобно... Но, к примеру, на мнемониках i8080 <-> z80: LHLD - это LD [HL], но LHLD проще обработать в компиляторе ассемблера. Так же и в Gigatron-е: LD [Y,X] (даже запятая для понтов есть! Хотя она не особо и нужна, поскольку это ничто иное, как LDA YX ( LYXD - плохо звучит ) Так скомпилировать легче, поскольку это целиком один код без аргумента. Вариант Gigatron-а: LD [X] - это, если по-честному, - LD [0,X] - обращение к zero page. На мой взгляд, LDA X - более простой и однозначный вариант, поскольку спутать не с чем. Остается LD $OP и LD [$OP] - здесь, как мне кажется, надо поступить, как в ассемблерах 6502: LDA #$OP - загрузка в А числа $OP, а LDA $OP - загрузка в А числа по адресу [0,$OP]. Я, честно говоря, префикс # для чисел не люблю, он противоречит привычкам... Но префикс # всё равно в ассемблере уже будет: #>, #< - взять старшую или младшую часть числа. Ну вот как-то так я предполагаю избавиться от скобок в мнемониках ассемблера Gigatron-а.
_________________ iLavr
|
10 Sep 2020 00:55 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
В общем, после внедрения в жизнь всех вышеперечисленных мероприятий, мнемоники ассемблерных команд Gigatron-а приняли следующий вид: КОДЫ 00_7FН КОДЫ 80_ВFН КОДЫ С0_FFН Самая неудачная мнемоника, как мне кажется, получилась: STIT = STore IT Coбственно и команда не совсем удачная: ST #$OP,$OP - сохранить операнд по адресу, заданному самим операндом. Если STore OPerand, то выйдет: STOP, а если STore ARgument, то получится: STAR... Остановился на STIT .
_________________ iLavr
|
10 Sep 2020 10:00 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
( Упорядочены по алфавиту)
_________________ iLavr
|
10 Sep 2020 11:37 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
| | | | Lavr wrote: Если на выход регистра OUT Gigatron-a прицепить эту самую PIA 6820, как в Apple I, или её аналог типа UART MC6850, как я сделал в Apple_I in Proteus, а затем пропатчить vCPU и v6502, чтобы вместо генерации VGA-сигнала они делали вывод на UART, то может получиться весьма быстрый виртуальный 6502 и виртуальный Apple I, как бы даже не пошустрее оригинала! | | | | |
Легче всего реализовать эту идею, что называется, "в лоб", т.е. поставить в схему Gigatron-a вместо регистра OUT простой UART AY-3-1015 или КР581ВА1 (или их аналоги)... Но там есть свои трудности с выбором тактирующих частот... Поэтому UART MC6850, PIA 6820, i8250, i8251 применить интереснее, поскольку эти БИС более гибкие. Только на этом пути подстерегает одно большое " НО"! У Gigatron-a всего один порт ввода и один порт вывода, причем аппаратно обращение к ним в схеме задействованно. Я сразу выкинул порт вывода (он - обычный регистр), и заменил его на шинный формирователь данных для устройств вывода. Осталось найти адресное пространство для устройств ввода-вывода. Можно было бы ввести их в карту памяти, как в " Специалисте", но отдельное пространство для устройств ввода-вывода с обращением к ним командами IN и OUT - удобнее! Я посмотрел на команды ввода-вывода Gigatron-a: и заметил, что большинство из них не использует операнд! Для простоты реализации я выбрал привычные всем команды LDA IN и LD AC,OUT, и слегка подправил схему так, чтобы они превратились в привычные всем IN PORT и OUT PORT, при этом значение PORTаппаратно фиксируется в отдельный регистр типа 74LS373 - он теперь регистр адреса для устройств ввода-вывода Gigatron-a. Остальные команды ввода-вывода на этот порт не влияют, т.е. пишут и читают по последнему записанному в него адресу. При программировании выяснилось, что такое решение не самое удачное, поскольку тайминги Gigatron-a (а он - RISC-типа и выполняет любую команду за 1 такт), так вот его тайминги плохо подходят к UART БИС, поэтому пришлось " потанцевать с бубном" при программировании. С другой стороны совместимость с оригинальным Gigatron-ом осталась полная. По сбросу в регистр адреса для устройств ввода-вывода записывается 00Н, и если подключить на этот адрес регистр вывода Gigatron-a, то всё будет работать как и было. А начиная с адреса 0F8H я подключил UART i8250! Его модель в Proteus чувствительна к сигналу /IOWR, поэтому его аналог в схеме Gigatron-a пришлось укоротить и подзадержать. Но в итоге - ВСЁ ЗАРАБОТАЛО! Выкладываю архивчик с моделью для тех, кто хочет "поиграть" в Gigatron с терминалом. Так что Apple_I на основе Gigatron-a может быть и не таким уж медленным! А вобще после двух этих экспериментов я укрепился в мысли, что лучший индикатор для Gigatron-a - это любой подходящий LCD с интерфейсом SPI: не надо постоянно выводить изображение, интерфейс SPI не критичен к частоте "вдвига", и это может позволить сделать быстрый компьютер, практически не меняя схемы Gigatron-a.
_________________ iLavr
|
12 Sep 2020 13:54 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
И в связи с последней фразой предыдущего поста здесь надо сделать следующее замечание, чтобы не получилось так, что я вроде как всех ввёл в заблуждение...
Дело в том, что на частоте 6.25 МГц в схеме Gigatron-а скорее всего ни один реальный UART работать не будет, потому как не рассчитаны они на такие скорости. Во всех материнских платах при обращении к УВВ автоматом включается задержка WAIT на несколько тактов, в схеме же Gigatron-а механизм WAIT не предусмотрен. Так что в реальном Gigatron-е все БИС UART скорее всего загнутся на частотах 2...4(max)МГц.
А вот LCD c интерфейсом SPI такие частоты совершенно не мешают, они и на бОльших частотах вполне прилично работают.
Второй момент связан с особенностями симуляции в Proteus: дело в том, что отрисовку симуляции Proteus делает не на каждом шагу, а с определённым периодом, который можно указать в настройках Proteus-а, можно и вовсе запретить индикацию логических уровней на выводах, так симуляция, естественно, шевелится быстрее...
Именно из-за этого у меня там странная тактовая частота - 990 Гц - она не кратна частоте отрисовки экрана. В противном случае, на частоте 1000 Гц может случится так, что в цикле проект как бы "завис", но на самом деле отрисовка попадает в одно и то же состояние.
На мой взгляд, на частотах от 1000 Гц и выше вся индикация становится менее информативна, поскольку пропускает часть логических состояний. Можно увеличить частоту отрисовки, но это зело тормозит симуляцию всего проекта.
_________________ iLavr
|
13 Sep 2020 03:11 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
В общем решил я "лучший индикатор для Gigatron-a" также проверить, как он работает... И заодно проверить все прелести программирования на ассемблере оригинальной конструкции: тут и software stack есть, и " трамплины", и косвенное чтение массива из ОЗУ. СХЕМА Gigatron + LCD И главная неприятность неожиданно всплыла совершенно в другом месте. Я уже в третий раз сталкиваюсь с этим: модель SRAM 62256 Proteus-a при несколько нестандартном включении начинает глючить. И глюк заключается в том, что после операции чтения она задерживает снятие данных с шины, что далее приводит к конфликту. Ясное дело, что и настоящие SRAM поступают примерно так же, но модель не реагирует и на собственные настройки: Менял я эти параметры, но к положительному результату это не привело... Пришлось " пошаманить с бубном". С точки зрения схемотехники зашаманить не получилось, хотя в схеме Nibbler-a похожая проблема решилась небольшой задержкой одного из сигналов. Здесь такого не получилось, а усложнять схему оригинального Gigatron-a я тоже не хотел. Проблема решилась весьма странным образом: если после чтения сразу же сделать запись по тому же адресу - глюк модели SRAM 62256 далее не мешает... Так что в ассемблерном тексте везде вот такое: это просто " шаманство с бубном"... Архив проекта Gigatron-SPI прилагаю: Там все необходимые "приблуды" для комфортной игры с моделью Gigatron-a + LCD. В старших версиях Proteus модель LCD Nokia-3310 работать не будет. Её надо заменить на родную модель Proteus-а, как я делал в проекте троичного компьютера. P.S. Тактовая частота модели Gigatron-a в проекте - максимально возможная. Если её увеличить, то придётся подобрать задержку Т2 и задержку /WR для SRAM.
_________________ iLavr
|
21 Sep 2020 00:14 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Без оригинального нативного ассемблера Gigatron-а всё же трудновато кодить... Хотя с третьего захода я уже приспособился копипастить сам у себя на ассеблере i8080. Главное и самое приятное, что ассеблер этот правильно вычисляет метки, причем вполне может выделить и старшую и младшую часть: Всё остальное вручную зело проще, но тем не менее компилятор ассемблера хотелось бы... И вот этот самый г-н H.G.Muller для себя простенький компилятор ассемблера написал. The Gigatron project - Page 4 - TalkChess.comЯ обратился к нему с письмецом, не поможет ли он с исходниками нативного ассемблера для Gigatron-а? A г-н H.G.Muller взял да и помог! Единственное, что получилось неудачно, так это то, что г-н H.G.Muller, так же, как и я здесь, решил изменить оригинальные мнемоники ассемблера Gigatron-а на более близкие к ассемблеру 6502, поэтому надо будет потестировать его на синтаксис... Ассемблер Gigatron-а собирается популярными компиляторами, и пару шероховатостей мы с Shaos-ом нашли и подправили. Я лично собирал в Microsoft Visual C++ 5.0 как консольное приложение, и если кому нужен рабочий экземпляр - выношу "в студию": Естественно, всё - " as is", я на нём тоже ещё не программировал, и писал свой последний код под ассемблером для i8080 для быстроты. P.S. Special thanks to Mr. H.G.Muller for his Gigatron assembler sources!
_________________ iLavr
|
21 Sep 2020 02:31 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
| | | | Lavr wrote: A г-н H.G.Muller взял да и помог! Единственное, что получилось неудачно, так это то, что г-н H.G.Muller, так же, как и я здесь, решил изменить оригинальные мнемоники ассемблера Gigatron-а на более близкие к ассемблеру 6502, поэтому надо будет потестировать его на синтаксис... | | | | |
Занялся я этим делом, и пришлось вспомнить знаменитую фразу, что порой легче написать программу просто заново, нежели разбирать исходники чужие, или даже свои... Но самое интересное оказалось не в этом... Практически с первых строк кода г-на H.G.Muller-а сложилось у меня стойкое ощущение, что этот код я ранее где-то видел! Хотя понятное дело, что с г-ном H.G.Muller-ом я ранее не был знаком... Пришлось покопаться в Интернете и на своих флешках, причем сразу было понятно в какую сторону следует искать: в сторону ассемблеров 6502. И, действительно, оказалось, что код г-на H.G.Muller-а очень близок к тому, как пишут ассемблеры для 6502! Гораздо интереснее для меня оказалось, что и пишут-то их все примерно одинаково! И если кому интересно, мне попалось даже текстовое описание, как примерно это делается: Собственно, в чем разница-то: когда пишешь ассемблер типа i8080, то в подавляющем большинстве случаев мнемонике сразу соответствует код + его немного доработать по аргументам. Поэтому у i8080 - MVI R,DATA и MOV Rx,Ry - разные мнемоники, хотя это и не всем нравится, но компилятор ассемблера написать легче... В случае, когда одной мнемонике, к примеру LD, соответствуют множество кодов, в зависимости от аргументов после неё, шаблон компилятора типа i8080 подходит довольно плохо. Но, тем не менее, в коде г-на H.G.Muller-а несколько интересных идей я увидел, видимо всё-таки сделаю свой вариант ассемблера, тем более, что в процессе разбора кода пришла мне в голову очень заманчивая идея, о которой расскажу я далее...
_________________ iLavr
|
26 Sep 2020 03:50 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
А идея, собственно, касается того, что в Gigatron-е при его оригинальной схемотехнике довольно просто можно реализовать аппаратный стек! Я тут ранее писал: И я эту идею проверил, она работает, вот только код сохранения адреса в программный стек и извлечения адреса из него довольно монструозный по объёму... Ситуацию не спасает даже то, что код выхода из подпрограммы всегда одинаков, и на него можно переходить из всех подпрограмм через JMP Y,$OP на его адрес. Код входа в подпрограмму с сохранением адреса возврата в программный стек все равно довольно объёмный, что зело увеличит объём программы и нивелирует удобство стека... Дело в том, что PDP-8 - 12-разрядный компьютер, и его 12-разрядный адрес легко сохранять в 12-разрядную же память одной операцией, как, собственно, и считывать адрес из памяти. Gigatron же - 8-разрядный компьютер с 16-разрядной шиной адреса, поэтому сохранять адрес возврата приходится по меньшей мере двумя операциями, а если манипулировать указателем стека программно, то операций, естественно, больше. Но у Gigatron-а есть некоторые схемотехнические " родимые пятна", которые могут помочь работу со стеком весьма упростить! Если взглянуть на схемотехнику мультиплексоров адреса: Схема мультиплексоров адреса Можно увидеть, что в младший байт адреса подаётся содержимое регистра Х или непосредственно операнда $OP. В старший же байт адреса подаётся содержимое регистра Y или просто 0, при этом мультиплексор старшей части адреса просто аппаратно выключается, а на входы мультиплексора поданы логические уровни " 1" просто, чтобы входы не потребляли ток. Так обеспечивается короткий доступ в Zero Page из любого места программы. Доступные режимы адресации при такой схемотехнике следующие: [0,$OP], [0,X], [Y,$OP] [Y,X]. Но у Gigatron-а есть аппаратная фишка автоинкремента X -> X++, мы её ранее разбирали: Суть её в том, что аппаратно регистром X является счётчик типа 74161, но этот счетчик вполне можно заменить на аналог типа 155ИЕ7, который работает как на увеличение, так и на декремент. Тогда кроме режима автоинкремента X -> X++ появится и возможность автодекремента X -> X--, что идеально с точки зрения указателя стека! Остаётся лишь доработать мультиплексор старшего байта адреса: подать на его неиспользуемые сейчас входы комбинацию 0000.0001b и изменить коммутацию этого мультиплексора так, чтобы были возможны режимы [01,Х++] и [01,Х--]. Но самая главная прелесть схемотехники Gigatron-а в том, что существует предвыборка, и после инструкции JMP он выполняет следующую за ней инструкцию, хотим мы того или не хотим... Вот этот момент и поможет автоматически сохранять младшую, быстроменяющуюся часть адреса в аппаратном стеке. То есть, если сейчас я для безопасности пишу: То с аппаратным стеком вместо бесполезной инструкции NOP будет инструкция сохранения в стек младшей части адреса, которая в Gigatron-е всегда на 1 больше. Конечно же на вход ОЗУ надо будет предусмотреть шинные драйверы от младшей и старшей половин РС, и также придётся несколько усложнить декодер команды - Control Unit, но мне кажется, что аппаратный стек этого ст Оит, если учесть и тот факт, что у Gigatron-а есть как повторяющиеся, так и вовсе неиспользуемые команды.
_________________ iLavr
|
26 Sep 2020 05:14 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Посмотрел я с этой точки зрения на неиспользуемые команды: В общем-то, судя по коду, отловить их и интерпретировать иначе весьма нетрудно. Да и количество самих команд весьма приличное. Тем более, что относятся они к группе ST = STORE (сохранить), значит половину функционала стека уже аппаратно реализуют. Осталось продумать вторую половину этой схемотехники...
_________________ iLavr
|
26 Sep 2020 12:10 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
| | | | Lavr wrote: И главная неприятность неожиданно всплыла совершенно в другом месте. Я уже в третий раз сталкиваюсь с этим: модель SRAM 62256 Proteus-a при несколько нестандартном включении начинает глючить. И глюк заключается в том, что после операции чтения она задерживает снятие данных с шины, что далее приводит к конфликту. Ясное дело, что и настоящие SRAM поступают примерно так же, ... Пришлось " пошаманить с бубном". С точки зрения схемотехники зашаманить не получилось, хотя в схеме Nibbler-a похожая проблема решилась небольшой задержкой одного из сигналов. Здесь такого не получилось, а усложнять схему оригинального Gigatron-a я тоже не хотел. Проблема решилась весьма странным образом: если после чтения сразу же сделать запись по тому же адресу - глюк модели SRAM 62256 далее не мешает... Так что в ассемблерном тексте везде вот такое: это просто " шаманство с бубном"... | | | | |
Попробовал я ликвидировать это " шаманство с бубном", но оказалось, что не так это просто... Действительно, реальные БИС SRAM удерживают данных на шине в операции чтения некоторое время после снятия управляющих сигналов. Вот, к примеру, диаграмма цикла чтения для SRAM HM62256 из её даташита: Понятно, что Proteus пытается эту диаграмму в меру сил симулировать, в том числе и " хвост" данных. С точки зрения корректности эмуляции SRAM - это однозначно верно, и время " хвоста" не может быть = 0. В большинстве процессоров в следующем такте Next t никто на шину не лезет, процессор обрабатывает данные и " хвост" ничему не мешает. Gigatron же воплощает RISC архитектуру, поэтому в следующем такте Next t на шину выдаёт свои данные один из источников, что приводит к конфликту, поскольку даже операция NOP у Gigatron-а - это либо MOV A,A, либо ORA A, то есть операция-то пустая, бестолковая, но транзакции данных на шине проходят. Получается, что " шаманство с бубном": оказалось самым верным и незатратным решением: на шину выдаётся то, что и так на ней "залипло", конфликта не происходит... Аппаратно устранить эту ситуацию можно двумя затратными способами: первый - укоротить цикл чтения разными RC-цепями, чтобы он влезал точно в такт Gigatron-а, второй - отделить выход SRAM от общей шины с помощью шинных формирователей, то есть: не пускать " хвост" на общую шину по завершению такта чтения. И то и другое требует аппаратного усложнения...
_________________ iLavr
|
05 Oct 2020 23:33 |
|
|
Who is online |
Users browsing this forum: No registered users and 13 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|