Важная информация

User Tag List

Показано с 1 по 8 из 8

Тема: Изредка посещаю этот форум для разрядки...

  1. #1
    Master
    Регистрация
    27.04.2005
    Адрес
    Москва
    Сообщений
    869
    Благодарностей: 3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию Изредка посещаю этот форум для разрядки...

    К сожаленинию у меня сейчас нет времени и возможностей вести какие-либо реальные разработки (хотя чем больше это длится тем острее желание вернуться и заделать что-нибудь этакое...)
    Так вот, очередная крейзи-идея на тему Flat Address Space на Z80. Это не детальная проработка, но возможно кто-то сможет на основе этого сделать нечто реальное.
    Итак, давайте вспомним i8086 Его регистры тоже были 16-разрядными, и адресовать можно было тоже 64 кб. Чтобы преодолеть этот барьер, использовались сегментные регистры. Их было 4: CS (код), DS (данные), SS (стек), ES (дополнительный). Они содержали старшую часть адреса.
    На Z80 сегментных регистров нет. А что если мы реализуем их, используя порты ввода/вывода, вместо переключения банков? Разумеется, нам понадобится самый настоящий северный мост - схема, связывающая между собой внешнюю шину, CPU и контроллер памяти.
    Как известно, Z80 имеет линии M1 (указывает что по указанному адресу мы читаем команду), WR и RD (соответственно запись и чтение в память).
    Итого, внешними средствами мы можем различить три состояния:
    1. CPU читает код команды.
    2. CPU производит чтение данных.
    3. CPU производит запись данных.
    Теперь вводим три порта ввода вывода:
    1. CSP - Command segment port.
    2. RSP - Read data segment port.
    3. WSP - Write data segment port.
    Получаем сегментированную модель, в которой, в отличие от страничной, мы не заперты в пределах страницы в 16 кб. Мы можем иметь целых 64 кб исполняемого кода, еще 64 кб данных, и при этом можем осуществлять межсегментный трансфер данных путем записи в WSP значения, отличного от RSP.
    Проблема №1: стек. Очевидно, что при RSP != WSP пользоваться стеком затруднительно. Перед возвратом нужно установить RSP равное WSP на момент вызова, иначе приедем совсем не туда.
    Проблема №2: прерывания. Собственно к предыдущей проблеме прибавляется то, откуда мы будем брать вектор. К сожалению тут я не знаток ибо тема прерываний Z80 в Спектрум-практике была освящена крайне слабо. Однако стоит вспомнить об устройстве под названием "Контроллер прерываний", которое упоминается в литературе по Z80 и служит для реализации IM 0. Следовательно - есть возможность извне определить, что CPU собирается перейти на обработчик прерывания.
    А если так, то можно предусмотреть следующие меры:
    1. Должна быть возможность в любой момент прочитать значение CSP, RSP и WSP.
    2. Вводим ISP - Interrupt segment port. Северный мост, обнаружив, что CPU перешел в режим обработки прерывания, выставляет значение ISP в качестве указателя на сегмент команд вместо CSP и CPU начинает работать в этом сегменте. Все регистры уже сохранены в стеке сегмента RSP, можно работать. Выход из режима обработки прерываний (обратная замена ISP на CSP) может производиться по команде RETI/RETN, а может и просто какой-либо манипуляцией с одним из управляющих портов северного моста.
    Проблема №3: межсегментные переходы. Это достаточно просто решить, добавив в северный мост еще чуточку интеллекта. Можно заставить его срабатывать скажем следующим образом:
    Код:
    007F54 LD A,#01
    007F56 OUT(CSR),A ; Установили новый сегмент
    007F57 JP 9E3B       ; Следующая команда выполняется все еще в
                                ; старом сегменте. Это не обязательно JP, это может
                                ; быть JR, CALL, RST, хоть NOP.
    019E3B                  ; Все, приехали в новый сегмент.
    В качестве вкусности можно добавить автоматический инкремент значения CSR при считывании процессором КОП по адресу 0xFFFF. Таким образом можем позволить себе спокойно выполнять программы длиннее 64 кб.

    Кто что скажет?

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2
    Guru Аватар для caro
    Регистрация
    14.01.2005
    Адрес
    Ekaterinburg
    Сообщений
    2,481
    Благодарностей: 776
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Этим наверное интересно было занятся лет 15 назад.
    Zilog для своих процессоров давно придумал механизм
    расширения памяти MMU -Memory Menegement Unit.
    Схема расширения до 4 Мбайт легко реализуется на двух регистрах ИР26 (74xx670)
    и одном дешифраторе ИД7 (74xx138).
    Последний раз редактировалось caro; 16.10.2006 в 15:22.

  4. #3
    Activist Аватар для captain cobalt
    Регистрация
    13.03.2005
    Адрес
    Пермь
    Сообщений
    294
    Благодарностей: 4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Очень хорошая идея.

    Есть предложение ускорить межсегментные переходы (и возвраты). Вместо трёх машинных команд, показанных в клочке кода, можно под это дело определить недокументированные команды из таблицы #ED. Освободится аккумулятор, и т. д., и т. п.

  5. #4
    Master
    Регистрация
    27.04.2005
    Адрес
    Москва
    Сообщений
    869
    Благодарностей: 3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от caro
    Этим наверное интересно было занятся лет 15 назад.
    Zilog для своих процессоров давно придумал механизм
    расширения памяти MMU -Memory Menegement Unit.
    Схема расширения до 4 Мбайт легко реализуется на двух регистрах ИР26 (74xx670)
    и одном дешифраторе ИД7 (74xx138).
    Схему, принцип - в студию!
    Почему в реализациях до сих пор нету???
    Блин, может будет дубль-2 - продолжу реанимацию Пентагончика-48. Хоцца на нем что-нибудь этакое откатать...

  6. #5
    Guru Аватар для caro
    Регистрация
    14.01.2005
    Адрес
    Ekaterinburg
    Сообщений
    2,481
    Благодарностей: 776
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Sonic
    Схему, принцип - в студию!
    Почему в реализациях до сих пор нету???
    Этот механизм давным давно используется в MSX-ах.
    Как пример посмотрите схему модуля памяти для MSX обьемом 1 Мбайт.
    Последний раз редактировалось caro; 10.10.2008 в 18:29.

  7. #6
    Veteran Аватар для jtn
    Регистрация
    15.01.2005
    Адрес
    Kievska Rus
    Сообщений
    1,147
    Благодарностей: 5
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от caro
    1. CSP - Command segment port.
    2. RSP - Read data segment port.
    3. WSP - Write data segment port.
    Получаем сегментированную модель, в которой, в отличие от страничной, мы не заперты в пределах страницы в 16 кб. Мы можем иметь целых 64 кб исполняемого кода, еще 64 кб данных, и при этом можем осуществлять межсегментный трансфер данных путем записи в WSP значения, отличного от RSP.
    не получится - по М1 именно что читается КОП, а аргументы - в частности константы будут браться черт знает откуда.
    пример - ld hl,nn ld (hl),n jp nn ....

  8. #7
    Moderator Аватар для Error404
    Регистрация
    14.08.2006
    Адрес
    Владимир
    Сообщений
    3,750
    Благодарностей: 1014
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от The Exploited
    Цитата:
    Сообщение от caro
    1. CSP - Command segment port.
    2. RSP - Read data segment port.
    3. WSP - Write data segment port.
    Получаем сегментированную модель, в которой, в отличие от страничной, мы не заперты в пределах страницы в 16 кб. Мы можем иметь целых 64 кб исполняемого кода, еще 64 кб данных, и при этом можем осуществлять межсегментный трансфер данных путем записи в WSP значения, отличного от RSP.

    не получится - по М1 именно что читается КОП, а аргументы - в частности константы будут браться черт знает откуда.
    пример - ld hl,nn ld (hl),n jp nn ....
    Да даже если бы и удалось - это никак не решает проблему malloc(65536). И нафига компьютер с мегабайтами памяти, если там нужно на ассемблере возиться с кусочками памяти? А если malloc(65536) нерешаем, то городить диспетчеры и не имеет смысла: в СР/М с 48к ОЗУ TPA уже 25 лет как половина компиляторов умеет работать с так называемыми "оверлеями" - перекрывать область кода/данных кодом из дисковых файлов. Загоняем эти файлы на быстрый электронный диск (любой конструкции) - и получаем решение на стандартной базе.
    Это было лирическое отступление. На самом деле, соглашусь - диспетчер по 16к годится только на организацию электронного диска из "лишнего ОЗУ", больше он мало на что годится. Страничный диспетчер по 64к менее удобен для эл. диска (медленнее), но он позволяет легко организовывать "коммутируемую многозадачность" - проще простого переключать "целые" странички по NMI. Имея такой диспетчер и кучу ОЗУ впихнуть, к примеру, UZI - проще простого: будет не очень тормозно - проблема со свопом на медленный дисковод не будет такой проблемой, какой она стала для автора UZI в условиях недостатка ОЗУ. Т.е. полезно наличие обоих типов диспетчеров, и не только (а может, и вовсе не для того), чтобы эмулировать расширение адресного пространства.

    Еще одна вытекающая мысль: эффективный компилятор (например, С) для недокомпьютеров, способный компилировать компактный код - вещь абсолютно необходимая, имея его может и 64к хватить... И вот парадокс- до сих пор нет такого, а диспетчеров разных вариантов - море. Кстати, и переключением страничек может заниматься сам компилятор, не нужно будет городить аппаратную обвязку (достаточно будет простейшего диспетчера на регистре и мультиплексоре), да и вообще вспоминать про диспетчеры.
    Последний раз редактировалось Error404; 16.10.2006 в 20:51.

  9. #8
    Master
    Регистрация
    27.04.2005
    Адрес
    Москва
    Сообщений
    869
    Благодарностей: 3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Ну тогда господа Z180... Там с Flat memory model проблем нету. Внутренние порты релоцируются, эту функцию может выполнять BootROM.
    А по софту, касаемо компилятора...
    Хорошая мысль однако. Думаю если ее развивать, то надо начать с некой стандартизации карты памяти. Придумывать новый формат исполняемых файлов и вводить понятие сегментов.
    Рассмотрим стандартный ZX. Мы имеем:
    16 K ROM
    16 K экран (условно)
    16 K - назовем это resident area
    16 K - назовем это page area
    Наш бинарный файл должен иметь возможность:
    1. Иметь произвольную длину.
    2. Иметь произвольное количество сегментов с длиной не более 16 кб.
    3. Иметь понятие атрибута сегмента. Один из сегментов может иметь атрибут Resident - именно он попадает в 0x8000. Остальные сегменты могут грузиться в произвольные страницы с 0xC000.
    Остается два сегмента: ROM и Screen.
    Тут я отступлюсь от энтузиазма и предложу нессчастный ROM оставить наконец в покое. Попытки его заменить генерируют массу проблем. Не все в состоянии это сделать. ROMABLE-система хороша как опция, но не более.
    Screen - куда интереснее. Нам известно, что экран ZX - это 6 кб. Остается еще 10 кб. Идеальное место для размещения того, что в рабочем варианте назовем ZX Runtime kernel. Ее основная функция - связывать между собой сегменты программы. Эдакое наноядро. Программиста не должно волновать реальное расположение сегментов в страницах. Страницы ведь абсолютно идентичны между собой. ZRK машиннозависима ибо ей придется знать о том, какие страницы есть у машины и как их переключать. Еще тут придется содержать в себе некоторые legacy-системные переменные SOS, которые изменяют свое значение по прерываниям (вероятно что-то можно релоцировать, изменив IY) и стек (по крайней мере начальный).
    Тут нужно еще ввести понятие BFI - Binary file interpreter (для знакомых с UNIX - функциональный аналог ELF Interpreter). Его задача - загрузить бинарник, совместно с ZRK раскидать его по сегментам и создать таблицу связей - какой логический сегмент программы какой физической странице соответствует. Кстати нет разницы, собирать программу из одного или кучи файлов, так можно в нагрузку и load-time библиотеки реализовать, наподобие .dll в Windows и .so в Linux - нагрузочная стоимость будет нулевой. Далее BFI может спокойно запускать загруженный код и прекращать свое существование.
    Из программы ZRK может быть вызван явным и неявным образом:
    1. Неявно - при осуществлении межсегментного перехода (far call) из одного paged-сегмента в другой или же обращении из одного Paged-сегмента к данным, находящимся в другом Paged-сегменте (не рекомендуемая практика ибо тормоз хотя в некоторых случаях это можно принести в жертву простоте).
    2. Явно - при необходимости обеспечить непосредственный доступ к данным в каком-либо из paged-сегментов. При этом просто происходит переключение страницы и все. Разумеется наиболее часто такие вызовы будут осуществляться из Resident Area.

    На языке C это могло бы в принципе выглядеть так:

    [code]
    #pragma resident // Объявляем Resident segment

    void main(void)
    {
    SetPage(__selectmode); // Устанавливаем сегмент, содержащий данные
    memcpy(0x4000, initscreen, 6192); // Данные были картинкой
    SelectGameMode(); // Это простой вызов - сегмент уже включен, компилятор следит за этим
    }

    #pragma paged("selectmode") // Именованный paged segment, символ __selectmode генерируется линкером из имени сегмента

    char initscreen[] = {...}; // ну вы поняли - это данные картинки

    void SelectGameMode(void)
    {
    char m;

    m = getch();
    switch (m) {
    case 's':
    StartGame();
    break;
    case 'j':
    SetupJoystick(); // А вот это - пример FAR CALL. Компилятор сам должен позаботиться об установке нужной страницы и то же самое по возврату.
    break;
    case 'k':
    SetupKeyboard();
    break;
    }
    }

    #pragma paged("setups") // Еще один paged-сегмент, в него мы вынесли все настройки

    void SetupJoystick(void)
    {
    // Тут мы выбираем тип джойстика
    }

    void SetupKeyboard(void)
    {
    // Тут мы производим назначение клавиш
    }

    #pragma physicalpage(#07,"screen2") // А тут мы просто определили __screen2, который понадобится нам для того, чтобы использовать теневой экран.

    Я думаю что если бы было желание, то можно было бы переработать IS-DOS под такое распределение памяти. IS-DOS - отличная система, но в ней заложена серьезная концептуальная ошибка - она попросту не рассчитана на использование страничной памяти приложениями. ОС должна занимать нижнюю память, а не верхнюю. При этом она должна быть модульной (в IS-DOS это есть, но модуль нельзя динамически выбросить из системы и запихать на его место то что мне нужно). А предлагаемая мной концепция вкупе с реализацией сборки программы из нескольких файлов на этапе загрузки (load-time-linking) позволит решить тонну проблем. Каждая программа при загрузке будет фактически собирать собственную ОС под себя (для этого головному модулю достаточно указать, что для работы ему например необходим драйвер для работы с диском, драйвер мышки и драйвер принтера. Если это графический редактор - можно запросить еще и GUI-оконную систему. Если эмулятор терминала - драйвер модема и текстовую консоль. Супер-мега-киллер-демо вообще обойдется без всего этого и сможет работать само по себе используя лишь переключалку страниц из ZRK.
    К сожалению сюда не вписываются некоторые расширения диспетчера памяти (например возможность Profi менять окно проецирования с 0xC000 на 0x4000, но это придется принести в жертву стандартизации. Если оно и подлежит использованию, то только машиннозависимыми модулями для внутренних нужд.
    А вот диспетчерам памяти II поколения (к коим я могу отнести только АТМ-Турбо с его возможностью переключать вообще всю память) можно как раз найти применение, связанное с многозадачностью. Внутри такой структуры можно выделять виртуальные машины, в которых будут работать различные программы. Единственным остается вопрос разделения экрана - это надо как-то проработать.
    Такая схема может позволить обеспечить совместимость и с классическими SOS, TR-DOS и IS-DOS-приложениями.
    С IS-DOS все просто, необходимо перетащить ZRK как можно выше по памяти (но не залезая за 0xC000 - там электронные диски всякие и прочая лабудень), написать эмулятор API RST#10 - и готово. То, что было ядром IS-DOS-48кб - в верхние страницы, обращение через ZRK (сорри любители RAM-дисков, на дворе XXI век, обзаводитесь винтами).
    У TR-DOS еще хуже - как правило из ее приложений нет выхода. Собственно, в качестве простейшего варианта решения можно вспомнить Windows 95 с ее опцией "Запускать в режиме MS-DOS". При попытке запуска такой программы сначала вылезает предупреждение о том, что любую среду придется покинуть. При утвердительном ответе Windows просто выгружается, оставляя программу работать в чистом MS-DOS. Плюс еще - TR-DOS-программы с дозагрузками можно запускать только с TR-DOS-дискет.
    Вот так, начал с концепции ПО следующего поколения, а закончил описанием прототипа концепции очередной ОС. Хотя судя по всему одно от другого не отделимо. Кстати а что если взять IS-DOS и переработать под этот принцип? Насколько я понимаю ее исходники доступны? Хотя конечно можно написать и прототип работающий поверх TR-DOS...

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Нет все-таки я покину этот форум...
    от Addison в разделе Форум
    Ответов: 5
    Последнее: 01.04.2006, 15:59
  2. Пожалуйста опознайте этот ZX!
    от Orionsoft в разделе Unsorted
    Ответов: 11
    Последнее: 25.06.2005, 13:53

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •