|
nedoPC.orgElectronics hobbyists community established in 2002 |
|
Author |
Message |
SAA
Senior
Joined: 12 Jul 2016 21:30 Posts: 136
|
Это так, да! Впрочем при входе в прерывания Z80 точно так же вынужден будет сохранять контекст, разве нет? Точно так же и любой из 256 псевдо-регистров можно сохранить в стек, а именно Что займет 9 тактов на сохранение одного псевдо-регистра и 11 тактов на его восстановление. Z80 push/pop-ает пару регистров за 11/10 тактов, что дольше на такт при сохранении контекста и быстрее на 1 такт при его восстановлении. В принципе можно аппаратно подменять ZeroPage при входе в прерывание, переключаясь на страницу псевдо-регистров для прерывания и это не займет 3 такта - "плюнуть" в порт в той же ZeroPage. В последствии такой подход переноса базы ZeroPage реализовали в продолжателях 6502 уже на уровне архитектуры CPU.
|
28 Oct 2019 01:21 |
|
|
SAA
Senior
Joined: 12 Jul 2016 21:30 Posts: 136
|
| | | | barsik wrote: Недостатки 6502 устраняет 65C816, у которого с 16-ти разрядностью и ограничением в 64К нет проблем, он оставляет по всем параметрам Z80 далеко позади. Но по сути доработок 65C816 отбрасывает, как неудобные программисту, все идеи применённые в оригинальном 6502 ради экономии транзисторов, - его архитектура в его "родном" режиме похожа на архитектуру 6809, а не 6502. С ассемблером 65C816 может быть было бы интересно познакомиться на практике. Но опять-таки, ассемблер, это уже не модно, т.е эффективно, но слишком трудоёмко. Если нет компиляторов специально для 65C816, то и смысла в нём нет. Кстати, в то же время Zilog тоже сделал апгрейд - Z180, но там почти нет в системе команд и архитектуре ничего нового (лишь в один флакон запихали CPU и периферийные БИС). Это потому, что у Z80 уже ничего нельзя было заметно улучшить, т.к он изначально хорош, в отличие от 6502. | | | | |
Судя по параграфу с сайта WDC особенности обоих чипов 65C02 и 65C816 учитываются C-компилятором. Насчет улучшить Z80 до Z180. То же произошло и с 6502 при превращении его в 6502 и в 6510, где в последнем случае добавились линии порта внутрь процессора. Прям один в один. Что касаемо улучшений системы команд то аналогично z180, 65С02 и 6510 были "слегка модернизированы" избавлены от бага перехода через границу страницы и получили с пяток инструкций. Версия 65С02 в последствии была задрана до 14МГц.
|
28 Oct 2019 02:31 |
|
|
SAA
Senior
Joined: 12 Jul 2016 21:30 Posts: 136
|
Проще говоря back-end это та часть компилятора которая заведует получением машинно зависимого кода. На входе back-end получает какую то унифицированную информацию, для современных компиляторов это например синтаксическое дерево разбора, для более древних где back-end буквально вшит в код - это процедуры скажем привязанные к генерации кода для конструкции инкремента. Конструкция то одна, предположим выглядит она так p++; а вот применений много скажем так a = *p++ или так c = *++p. Не оптимизирующий компилятор просто вызовет процедуру генерации инкремента над ячейкой памяти p, а после вызовет процедуру генерации доступа по указателю. А оптимизирующий может заложить это все в одну машинную команду, ну в случае например pdp-11. Так вот если для Small-C имеем один и тот же front-end то back-end будет очень разный для Z80 и 6502 для операции например индексного доступа и это можно все рассмотреть в файле листинге и оценить соответственно кто точнее и ближе к платформе написал back-end. Поизучал минут 15 выхлоп cc65 при разных ключиках оптимизации -Os, Or, O1, O2, O3 никаких изменений в генерируемом коде, не умеет он оптимизировать по всей видимости P.S. Пардон муа, посвежей CC65 оптимизирует еще как оптимизирует! Вот два фрагмента без ключа -O и с ключом -O
|
28 Oct 2019 04:16 |
|
|
barsik
Doomed
Joined: 19 Feb 2017 03:46 Posts: 584 Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
|
Конечно, PL/M не критерий пригодности процессора для ЯВУ. Речь была о том, что имеется сейчас для практического использования, а PL/M по-моему как-раз лучшее, что можно найти (хотя похоже PLI от Digital Research не хуже, но он заметно сложнее). Ведь считается, что нет другого ЯВУ дающего более плотный код. В отличие от остального, о PL/M я немного в курсе, потому могу на эту тему порассуждать. Официально считается, что PL/M даёт код всего на 30-40% больший, чем код из под ассемблера. Может на больших программах и других компиляторах это так, но пока у меня сложилось мнение, что PLMX даёт код примерно вдвое больший, чем аналог написанный на ассемблере (хотя надо учесть, что я имея мало опыта, пишу неоптимальный код). Пока я написал в учебных целях всего несколько и весьма небольших программ на PL/M (редактор фонтов, текстов редактор и два простейших конвертора текстовых файлов в 25 строчек моего кода в каждом). Для сравнения, мой примитивный текстов редактор на ассемблере КР580 занимал 4 кб, чуть лучший по возможностям текстов редактор на Турбо-Паскале Z80 занимал 12 кб. А на PL/M это ~7 кб (примерно, т.к его ещё не дописал до конца). Редакторы - по возможностям примерно одинаковы (аналоги родного турбо-паскалевского). А ведь Турбо-Паскаль, похоже, даёт самый плотный код из всех компиляторов, что я пробовал, (хотя возможно так лишь потому потому, что остальные компиляторы были для КР580). По моим неточным (т.е без подтверждения многократной статистикой) данным: Турбо-Паскаль Z80 даёт объёмный коэффициент ~3, Си для КР580 - ~4, компилятор Паскаль МТ+ ~4.5, бейсик-компилятор - ~6. Это значит, чтобы писать на Паскале и Си надо турбировать компьютер в 4 раза. А при PL/M всего в полтора раза. Ясно, что сам PL/M примитивен относительно более молодых ЯВУ, например, нет структур, потоков, многомерных массивов, хоть какой-то арифметики за пределом 16-ти бит, не говоря уж об вычислениях с плавающей точкой с точностью 38 знаков, работы с указателями и управления динамической памятью. Потому облегчает программирование в меньшей степени, чем мощные алгоритмические языки. Т.е полезен только для не очень сложных программ, таких, что несложно написать и на ассемблере. В одной журнальной статье читал, что работу программиста на ассемлере PL/M ускоряет в 5 раз. Ясно, что на Си программа будет написана быстрее и с меньшим напрягом мозга (уже то, что запись программы на Си компактнее, нагляднее и понятнее, облегчает). Потому, из-за того, что PL/M менее удобный, чем Си, если ранее для контроллеров писали программы на PL/M, теперь лишь на Си. Но может-ли самый оптимизирующий компилятор Си выдать код такой же плотности, что даёт PL/M ? Кстати, ущербность архитектуры 6502 похоже сжирает все преимущества в объёме кода, что дают JR-команды и он уступает в этом даже 8080. Билл Гейтс с соратниками легко уместил бейсик 8080 при конверсии в тот же объём для процессора 6800, но при конверсии для 6502 это не получилось (6800 вообще очень экономный по коду, у него TINY-бейсик всего 768 байт против 1800 байт 8080). Сможет ли оптимизирующий компилятор Си дооптимизировать до уровня аналога написанного на ассемблере? Или хотя бы до уровня PL/M. Под эффективностью компилятора понимается скорость прогона и объём полученной программы. Хотя по логике понятие эффективность компилятора должна включать удобство и скорость разработки программ. Почему-то несмотря на использование оптимизации компиляторы для PC с каждым годом становятся всё менее эффективными. Получаемые из под них программы требуют всё больше и больше ОЗУ и скорость процессора. Т.е понижается качество выходного кода ради роста уровня языка для упрощения разработки и, соответственно, удешевления продукта.
Last edited by barsik on 01 Nov 2019 08:02, edited 5 times in total.
|
28 Oct 2019 10:14 |
|
|
SAA
Senior
Joined: 12 Jul 2016 21:30 Posts: 136
|
А не могли бы Вы как то охарактеризовать PL65 ? Я понимаю что Вам не довелось на нем пописать, но по спецификации смогли бы сказать насколько он прогрессивен относительно PL/M 8080? И вот еще вопрос который меня уже давно подмывает задать, а что скажите по поводу макро средств ассемблера. На C64 очень интересный в этом плане макроассемблер, напоминает нечто подобное PL/M. В конце того века (красиво звучит) на x86 были относительно не долго популярны зарезанные Си, C--. Такой интересный подход когда дают рулить переменными привязанными к регистрам и использовать синтаксис Си поверх. Не приходилось? Но библиотеки то он позволяет, можно расширить и fixed point и даже float? Насчет структур конечно не очень здорово, но в принципе терпимо если можно использовать какое то макросредство и подставлять смещение к указателю. Мне не приходилось работать на PL/M и Ваше мнение особенно ценно. Есть ли действительно непреодолимые трудности написания в нем ПО? Неоднократно удивлялся как это умеет делать C от TI для msp430, разглядывая код порой чувствовал что я написал бы хуже. Иногда долго не мог понять почему не могу "переубедить" компилятор поступить по другому, обнаруживая в конце что компилятор видит шире меня, не сосредотачиваясь на узком участке кода на котором я считал что получаю выигрыш. Оптимизируя как по размеру, так и по скорости. То что код при этом получается иногда больше чем на ассемблере, как правило влияние подключения необходимого для старта кода, в том числе множества trap-ов и начальной инциалиазции boot-а (по моему он так и называется bootstrap код). Он в принципе выключается, но тогда многое придется делать в рукопашную. Опять же что то постоянно тянется из библиотек, стоит обнаружить ему скажем умножение на 10 и в код летит почти вся библиотека математики. Слишком много в ней пересечений и линекр не может вырезать лишнее, ну или я туплю и не могу это настроить. Так что да думаю сравнимый по плотности с PL/M код получить на современных Си компиляторов микроконтроллеров можно. Другое дело что в принципе уплотнить код можно так как это делает Forth и тут совсем нет вариантов для ЯВУ, с ним тяжело тягаться наверное даже ассемблеру. Стив Возняк как бы возражает своими 4К Integer Basic это я про 8К в статье. Насчет тини конечно нет.
|
28 Oct 2019 10:59 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Тут дело немного в другом, а не в сохранении псевдорегистров в стек. Если мы сохранили в стек регистры 8080 или Z80, в подпрограмме или вызове прерывания, то мы теперь знаем, что все регистры для нашей задачи свободны. У 6502 сохранять их практически бесполезно: если работает ОС и наша задача, мы должны точно не портить псевдорегистры, которые использует ОС. Сохраняй их, не сохраняй, но если наша задача обращается к функциям ОС - нельзя портить содержимое её псевдорегистров. Собственно, 256 псевдо-регистров тем и хороши, что не надо сохраняться в стек, а можно сразу использовать свободные. Но надо точно знать, какие свободные. Я с этим четко столкнулся, когда попытался программировать в симуляции Apple I: поверху - Woz Monitor, у него - свои псевдо-регистры, под ним - Basic, у него - свои псевдо-регистры, а уже потом - моя задача, и куда мои псевдо-регистры назначить - от фонаря не получится. Нельзя портить псевдо-регистры Basic и Woz Monitor - надо точно знать, где они, а где свободно.
_________________ iLavr
|
28 Oct 2019 12:08 |
|
|
barsik
Doomed
Joined: 19 Feb 2017 03:46 Posts: 584 Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
|
А вот и мнение иностранного специалиста о том, что 6502 плохо годится для компиляторов ЯВУ: PL65 это развитый язык похожий на Паскаль. По первому впечатлению не имеющий ничего общего с PL/M. По плотности выходного кода, он вряд-ли лучше, чем PL/M для 8080 или 6502, но по всем остальным параметрам, он, естественно, намного мощнее и удобнее для программиста, чем PL/M. Трудно ожидать иного, ведь 8-ми разрядный PL/M официально из 1973 (хотя была и ранняя 4-х разрядная версия уже в 1972), а PL65 для Атари из 1987, разница в 15 лет. Интересно бы сравнить объём кодов компиляторов. Оригинальный PL/M был кросс-компилятором для майн-фрейма PDP-10 (написанный на фортране-IV), потому сравнивать можно лишь производные от него версии для "родных" платформ (т.е не кросс). Это PL/M для ОС ISIS от фирмы Intel из конца 70-тых с размеров в ~130 кб и компилятор PLMX для CP/M, который был написан в 1979 г. программистом по имени Roger Carlson размером в ~100 кб. Компилятор PL/M для ISIS фирмы Intel написан на самом PL/M, может даже на нём самом (первая версия конечно была странслирована кросс-средством). Возможно PL/M от Intel более эффективный, чем PLMX от Roger Carlson, т.к он всё-таки создан солидной фирмой с кучей программистов и опытом поддержки PL/M в течение многих лет (в Intel всё писали на PL/M, даже их ОС ISIS написана на PL/M), в то время как PLMX написан одним индивидуальным предпринимателем. PLMX по возможностям самого языка это несущественно усечённая версия PL/M стандарта 1976, но зато он для CP/M и имеет библиотеки для CP/M (хотя мне они не нужны, я предпочитаю на ассемблере написать своё). Ну и немаловажно, что PLMX запускается под TSR-эмулятором CP/M, т.е прямо из Windows XP (не более поздних). PL/M от ISIS вообще не использовать. А написанный на фортране PL/M наконец недавно (конвертировали на Си) и научились использовать, - он может и чуть эффективней, но в использовании очень неудобный. Возможно PL/M и не единственный пригодный инструмент для 8080, т.к судя по имеющейся информации, есть подозрение, что PL/I от Digital Research окажется не хуже, чем PLMX и PL/M. Но я уже потратил энергию на освоение PL/M и не хочу пока тратить силы и время на изучение другого, к тому же более сложного ЯВУ. C64 это компьютер Cоmmodore-64? Как макроассемблер может напоминать что-то из PL/M? Там нет макро. Макро-ассемблер позволяет определить макрокоманду, т.е задать цепочку команд ассемблера, которой передаются параметры и есть куча хитростей с макроподстановкой. Это, кстати, позволяет на ассемблере реализовывать даже некоторые операторы из ЯВУ, например, WHILE-ENDW, IF-THEN-ELSE. Ничего сравнимого по возможностям с макро средствами в PL/M нет. Там с помощью LITERALLY можно лишь задать замену одного любого слова на другое слово или цифру или несколько слов и цифр. Это аналог ассемблерного псевдооператора EQU и аналог define в Си. До макро-команд этому "фичу" далеко. Не видел, этого в СССР не было, лишь читал в Интернете. Ещё и Паскаль-0 был, упрощённый. Есть ли от подобного польза? Хоть что-то это улучшает, кроме экономии трудозатрат разработчика компилятора? Можно думать, что это ради упрощения компилятора, когда на полноценный компилятор, либо ОЗУ, либо энтузиазма, либо ума не хватило. Естественно, как и у всех линкующих компиляторов, можно писать модули на ассемблере или любом ЯВУ, если они используют линковку и их REL-формат совместим с Microsoft и Digital Research (а это не у всех компиляторов так). Как раз, когда я пишу на PL/M, всё что легко сделать на ассемблере, я делаю на нём и только в текстовом редакторе, который специально стал писать, чтобы оценить эффективность кода от PL/M, я всё делал только на самом PL/M. Этим-то все линкующие ЯВУ лучше, чем Турбо-Паскаль. Его по сути следует считать игрушкой. Он конечно позволяет ассемблерные вставки, но намного более утомительным способом. Кстати, с наличием Паскалей для 6502 дело обстоит похоже на порядок хуже, чем с Си для него же. В PL/M я пока не особо компетентен, хотя сейчас, похоже, в России кроме меня только Kakos-nonos имел дело с PL/M (он написал игру для Апогея). Я только пару месяцев, как этим озадачился, причём дважды за это время все написанные программы на PL/M утрачивались. А вообще в 80-тые PL/M-у учили на курсах программистов и инженеров конструкторов контроллеров (на 8085 и 8048/51), и PL/M был основным ЯВУ в дистрибутиве СМ-1800. Долго привыкать, после Паскаля и Си раздражает (приводит к ошибкам) CALL перед процедурами, когда они вызываются, как процедуры. Постоянно забываешь вставить CALL. Даже подумывал написать препроцессор, что будет находить в тексте процедуры и вставлять, где надо CALL. Сначала вообще получалось не в 5 раз быстрее, чем на ассемблере, а раз в 15 медленнее. Спустя время более-менее привык, но всё-равно получается никак не быстрее, чем на ассемблере. Видимо надо набраться больше опыта, тогда получится польза от ЯВУ. Но в принципе писать на любом ЯВУ намного легче и приятнее, чем на ассемблере. Чтобы оценить PL/M, я хотел бы написать CP/M-нортон. А вообще, если объём кода позволяет, то лучше писать на Паскале, получается намного быстрее и возможности выше. Особенно, если Паскаль не Турбо от Borland, а нормальный с линковкой (за счёт чего всё что удобно можно переписать на ассемблер). Или писать на Си. Но увы, на этих ЯВУ не написать программы даже средней сложности. Объём кода быстро нарастает за 32 кб. Например, более-менее полноценный Нортон получается в 40 кб, а ведь для него ещё нужен буфер копирования (чем он меньше, тем медленннее скорость копирования), а главное, совсем не остаётся места для реализациии "глЮкала": для графической машины нет места для буфера сохранения окон, только для текстовой. Потому и приходится использовать PL/M, несмотря на то, что он и не самый удобный ЯВУ. Нет, по сути это тот-же ассемблер, только синтаксис другой. Потому можно сделать всё то же, что и на ассемблере, т.е можно написать любую программу для которой хватает объёма ОЗУ (а если и появится что-то непреодолимое, то ассемблер в помощь). Но сложную по алгоритму программу лучше писать на Си или Паскале. Ещё Аду и Драко можно попытать. Они написаны позже, может быть эффективнее. Целочисленный бейсик и от Билла Гейтса занимает те же 4 кб. Там речь шла о полноценном бейсике. Ну и был упомянут TINY-бейсик. Не интересовался объёмом TINY-бейсика в кодах 6502, но уверен, что он больше, чем 768 байт. Любопытно, что Возняк писал ROM-BIOS-ы Apple и целочисленный бейсик в машинных кодах. У него не было дисковода и транслятора. Лишь мини-отладчик. А Билл Гейтс с компаньонами в работе использовали майн-фрейм PDP-10 и вот здесь написано, что у них благодаря этому был хоть и убогий, но транслятор ассемблера (реализованный в виде макро). Странно, что они поленились написать свой, ведь ассемблер без макрокоманд для 6502 (или 8080) пишется опытным программистом за 3-4 дня.
Last edited by barsik on 28 Oct 2019 20:12, edited 8 times in total.
|
28 Oct 2019 16:10 |
|
|
SAA
Senior
Joined: 12 Jul 2016 21:30 Posts: 136
|
Я правильно понимаю что обращение к функциям ОС происходит из прерывания? Или речь о работе вне прерывания, когда 256 регистров из прерывания используются кем то другим? | | | | Lavr wrote: Собственно, 256 псевдо-регистров тем и хороши, что не надо сохраняться в стек, а можно сразу использовать свободные. Но надо точно знать, какие свободные. Я с этим четко столкнулся, когда попытался программировать в симуляции Apple I: поверху - Woz Monitor, у него - свои псевдо-регистры, под ним - Basic, у него - свои псевдо-регистры, а уже потом - моя задача, и куда мои псевдо-регистры назначить - от фонаря не получится. Нельзя портить псевдо-регистры Basic и Woz Monitor - надо точно знать, где они, а где свободно. | | | | |
В случае когда ОС и BIOS (монитор) написан не Вами и не документирован - ситуация совершенно таки аховая. Тут даже смена банка ZeroPage ничем не поможет так как в задаче пользователя в этот момент прерывания разрешены и если подменить страничку "только для себя", не выключив прерывания, то подменишь ее для всех (кроме того такой возможности в Apple II и нет). Все печально в таких случаях, могу лишь заметить что потенциально удобную возможность "изгавнять", как оказывается, пара пустяков. А что у Воза все так плохо с документированием? Вроде бы его монитор для Apple I дизассемблировали, конечно там 512 байт и разобраться в них намного проще.
|
28 Oct 2019 19:30 |
|
|
SAA
Senior
Joined: 12 Jul 2016 21:30 Posts: 136
|
Я имел ввиду эффективность генерации машинного кода. Удобство и скорость разработки функция зависящая не только от компилятора как инструмента, но в большей степени от ЯВУ. Только что Вы приводили пример про то что на PL писать по сравнению с Си не настолько эффективно. Ну и "что бы два раза не вставать" по поводу эффективности генерации кода которая от того на чем компилятор написан не зависит, писали бы компилятор на Си, на ассемблере или на PL/M все равно для генерации машинного кода использовалась бы одна и та же стратегия. Поэтому и не зависит от того на чем компилятор написан. Тут другая проблема - желание разработчика увеличить скорость выхода готового продукта приводит к использованию множества библиотечного заимствованного кода, который в свою очередь написан с высоким уровнем абстракции, подразумевающим систему взаимосвязанных объектов с изоляцией их другу от друга (ООП). Очень распространены надстройки над этими библиотеками опять изолирующие свой код. Компилятор в этом случае не может рассмотреть цепочку вызовов на всем протяжении и скомпилировать код без лишних call. В итоге код разрастается по размеру, критические фрагменты не лезут в кеш, промахи приводят к потери производительности. Как то пришлось портировать код с С++ на Си на примере симулятора мк61. И было замечено что если в скорости код почти не теряет (за счет того что исходник полный без подключения каких либо библиотек реализуемых третей стороной) то по размеру на С++ он значительно больше чем на Си. И конечно это очень обозримый код, в котором ты ориентируешься от начала до конца.
|
28 Oct 2019 22:03 |
|
|
SAA
Senior
Joined: 12 Jul 2016 21:30 Posts: 136
|
Ну все понятно крутимся вокруг стека и рекурсии, плюс 16 битная арифметика. Хотя вот она то как то незаслужено обижена. Предложение для осуществления рекурсии перейти на интерпретируемый код и виртуальную машину, выглядит не вполне развернутым. Форт в некоей степени то же "виртуальная машина", про него не слова. Вполне можно вывернуться если нужна "бесконечная" рекурентность без потери производительности кода. На самом деле существуют ведь аппаратные стеки на 4,8,16 вложений. Это не новость и обходить рекурсивные алгоритмы научились. Ну да ладно, в этом фрагменте кроме 16-разрядности спорить особо не с чем. Все так. сложим два 16 р-р числа лежащих в ZeroPage и не в ZeroPage ИТОГО 20/26 тактов. А если код само-модифицирующийся будет еще быстрей ИТОГО 16/18 тактов. Поправьте меня если я не прав, 16 битное сложение для Z80 и 8080 это сложение пары регистров с HL, с передачей в HL результата. Я не говорю об выгрузке результата из HL, но загрузка пары из памяти или константой нужна, мы же не разбираем случай суммирования с накоплением. Загрузка пары HL это 16 тактов, для другой пары 20 тактов, само сложение еще 11 тактов. ИТОГО 47 тактов. Возможно тоже с само-модификацией загрузка константой HL это 10 тактов, другой пары 10 + сколько то на переброску из HL и само сложение 11, получим не меньше 31 такта. Возможно я не прав, ошибаюсь - поправьте меня.
|
28 Oct 2019 23:04 |
|
|
SAA
Senior
Joined: 12 Jul 2016 21:30 Posts: 136
|
| | | | barsik wrote: Долго привыкать, после Паскаля и Си раздражает (приводит к ошибкам) CALL перед процедурами, когда они вызываются, как процедуры. Постоянно забываешь вставить CALL. Даже подумывал написать препроцессор, что будет находить в тексте процедуры и вставлять, где надо CALL. Сначала вообще получалось не в 5 раз быстрее, чем на ассемблере, а раз в 15 медленнее. Спустя время более-менее привык, но всё-равно получается никак не быстрее, чем на ассемблере. Видимо надо набраться больше опыта, тогда получится польза от ЯВУ. Но в принципе писать на любом ЯВУ намного легче и приятнее, чем на ассемблере. Чтобы оценить PL/M, я хотел бы написать CP/M-нортон. | | | | |
А сколько в строках/Кб занимает исходник скажем Вашего редактора на PL/M? Препроцессор конечно бы ситуацию спас. Но вот вопрос - а где находится текст исходника при работе препроцессора? Буферизируется? Вычитывается и парсится по символьно, а куда складывается готовый результат?
|
28 Oct 2019 23:31 |
|
|
SAA
Senior
Joined: 12 Jul 2016 21:30 Posts: 136
|
Он самый. Макроассемблер может напоминать PL/M тем что использовать макроподстановку ключевых слов PL/M. Ниже фрагмент кода на таком ассемблере https://nurpax.github.io/c64jasm-browser/ !for здесь оператор макроподстановки размножения, не конструкции языка.
|
29 Oct 2019 01:46 |
|
|
Lavr
Supreme God
Joined: 21 Oct 2009 08:08 Posts: 7777 Location: Россия
|
Да я верю, что у Воза все не так уж и плохо документировано. Просто когда ты в первый раз берешься программировать под Эппл I всё это для тебя поначалу совершенно неизвестно, хотя монитор от Воза даже не 512 байт, а всго лишь 256 при двух свободных байтах, причем код давно доступен с комментариями от автора, и у меня он, безусловно есть, как и исходник Васика. Но когда собираешься просто попробовать свои силы в ассемблере 6502, поиск и чтение документации весь процесс просто зело и неконструктивно тормозит, хотя кодирование и несложно. Когда в дремучие времена я учился программировать под К580ВМ80, я читал мануал от Микроши и пытался действовать без ассемблера в кодах. Сунуться в дебри Монитора даже и не думал... Просто мы сейчас же и ведем разговор: что удобно, и что неудобно у 6502 и z80(8080) для программиста. Zero Page всё же не так удобно, как регистры на кристалле CPU, пусть даже этих псевдорегистров и больше.
_________________ iLavr
|
29 Oct 2019 07:37 |
|
|
barsik
Doomed
Joined: 19 Feb 2017 03:46 Posts: 584 Location: Санкт-Петербург, Россия, третья планета от Солнца, галактика Млечный Путь
|
Да, используя подпрограммы (там где для КР580 они не нужны) 6502 не много отстаёт и в 16-ти разрядной арифметике. А в Ваших расчётах увеличьте число тактов для 6502 вдвое (всегда сравнивают Z80 на 2 МГЦ с 6502 на 1 МГЦ). Всё проще. Препроцессор может быть отдельной программой конвертором и пишет в тот же файл. Компилятор запускается BAT-файлом (не вручную же набирать команды, этапов трансляции много). Просто перед запуском PLMX командный BAT-файл запускает простейшую программку конвертор написанную на том же PL/M. В ней есть загрузка/выгрузка файла целиком (это внешними библиотечными процедурами), потому сама программа в простом варианте это всего ~20 строк на PL/M делающих нужную обработку. В более сложном варианте сканируем исходник, и по поиску слова PROCEDURE создаём список имён процедур. А на втором проходе ищем имена этих процедур и контролируем, что, если они вызываются не как функции, то перед ними присутствует слово CALL. Но даже это мне делать было бы лениво, - я хотел ещё проще, чтобы не сканировать дважды, планировал как флаг процедур начинать их имена с символа '$', что упрощает. Символ '$' компилятор PL/M игнорирует, его вставляют в имена для улучшения читабельности имён. Пока сказать не могу, но более 1000 строк, причём процедуры сдвига больших массивов и процедуру экранного ролика для граф.машины писать на ЯВУ разумно только с целью анализа его эффективности, иначе получается тормозятина. Всё остальное допустимо и на ЯВУ. современные винты служат недолго Проблема в что, что у меня где-то 1.5 месяца назад сначала сдохли все данные на винчестере, погубив не только первые программки на PL/M, мелкие пробные, редактор фонтов (~350 строк) и почти законченный текстов редактор ~1000 строк, но и, что грустно, наработки по Паскалю МТ+ (это не восстановить, писалось давно и уже забыто). После переустановки DOS и ПО, т.к в голове всё ещё оставалось, за пару недель всё полезное по PL/M я почти восстановил (на 70%), но тут вдруг винчестер сдох окончательно. А я сдуру, т.к ещё не было доделано, снова не сделал копий на microSD 32 Гб или в облачном сервисе. Хотя всё нужное (наученный горьким опытом краха винта, когда потерял почти 50% архива программ и исходников 8-ми разрядок и все свои исходники за 3 последних года, лишь 50% сохранилось на винте ОРИОНА), привык резервировать. Но редко, а учебные программки и незаконченные исходники, естественно, вообще не резервировал.
Тогда до меня дошла подсказка, что вселенная не хочет, чтобы я в данный момент занимался программированием, потому решил немного позаниматься ретро железом. Это обычно: какое-то время что-то потихоньку программируешь (последние годы я этим занимаюсь на порядок меньше, даже, чем 10 лет назад и на 2 порядка, чем в 20 веке), а иногда для разнообразия, но редко, можно несколько недель подышать парами канифоли. На бОльший срок по железу меня никогда не хватает. Недавно начал написание текстового редактора на PL/M уже в третий раз. Пока восстановил лишь несколько подпрограмм. как устроен примитивный текстов редактор Вообще примитивный текстов редактор 8-ми разрядки даже на ассемблере пишется за несколько дней (я это делал много раз). Бывают и совсем примитивные редакторы, которые при редактировании хранят весь текст в ОЗУ в распакованном виде, но это для 8-ми разрядки с крошечным ОЗУ совсем глупость. Хотя скорость их работы не страдает.
Нормальный примитивный редактор состоит всего из нескольких основных подпрограмм. Главная циклически прогоняемая процедура это EDIT. Первым делом, она вызывает подпрограмму SCRN_OUT, которая по текущей позиции экрана в тексте (по OFFSET) вычисляет адрес в текстовом буфере, где начало экрана, и выводит на экран 23 строки (2 строки служебные). Далее ожидая нажатий крутится цикл опроса, т.е в цикле прогоняется петля опрашивающая STATUS клавиатуры. По нажатиям курсорных клавиш курсор смещается по экрану (это делают процедуры: UP, DN, LE, RI, CR, PgUp, PgDn, To_Top, To_Bottom) с выходом в цикл опроса, а если нужна перерисовка экрана, то на вход EDIT. Если же будет нажата некурсорная клавиша или ^N, то делается уход на процедуру LN_EDIT.
В LN_EDIT текущая строка перегружается в строчный буфер, причём табуляции распаковываются. И далее работает примитивный строчный редактор для одной строки (при входе ему передаётся код полученной клавиши). В конце редактирования строки по нажатию клавиши меняющей вертикальную позицию, LN_EDIT делает сохранение строки в буфере текста и делается переход на главную петлю редактора вход EDIT.
При сохранении строчного буфера первым делом вычисляется: стала отредактированная текущая строка больше или меньше по размеру, чем исходная (что была на момент входа в редактор строки). Для этого сначала строка нормализуется, т.е где можно пробелы заменяются на TAB, хвостовые пробелы удаляются и после последней отображаемой буквы строки вставляется строчный разделитель (только 13 или два байта 13 и 10).
Если строка стала меньше, то строка вставляется в буфер и делается схлопка, сдвижка всего последующего текста на число байтов, на которое строка сократилась. Если же строка стала больше, то сначала место отводимое в буфере на строку освобождается, текст раздвигается, - последующие строки сдвигаются к вершине ОЗУ на нужное число байт и затем увеличившаяся отредактированная строка вставляется в исходное место.
Таким образом редактор по сути состоит из несложного редактора всего на одну строку и процедур пересылок. Ясно, что такая концепция редактирования простая, но очень тормозная. Если объём сдвигаемого текста до 10 кб, то сдвижка происходит более-менее быстро и незаметно. Но если текст в 40 кб, а редактируемая строка в начале текста, то сдвиг ~40 кб длится 2-3 секунды, что неудобно пользователю. Для скоростных машин, типа PC, сдвижка и 5 мб текста мгновенна, но для 8-ми разрядки это не так. Особенно тормозно, если редактировалась последняя строка экрана (или первая) и при перемещении курсора дополнительно выполняется ещё и ролик экрана. Это тормозит, даже при ролике стеком (да кстати, никогда 6502 не обойдёт по скорости ролик КР580 стеком).
К упомянутым простейшим подпрограммам, составляющим редактор, добавляются ещё подпрограмма поиска конца текста, подпрограмма поиска строки с заданным номером, подпрограмма поиска начала предыдущей и последующей строки от текущей, и ролики экрана вверх/вниз стеком. Как видите, любой может написать такой редактор на ассемблере за несколько дней. продвинутые алгоритмы текстового редактора Есть несколько способов, как сделать работу текстового редактора нетормозной. Фирменные программы используют свопинг, отдельные буфера, разбивают огромный текст в 300 кб на кусочки и редактируют только небольшой текущий буфер. Потому в них уход с отредактированной строки не тормозит. А если писать на ЯВУ с поддержкой динамической памяти, то есть и более грамотные алгоритмы.
Но для машины, где ОЗУ с гулькин нос, доступ к флопу отсутствует (или дико тормозной), для ускорения нужны сложные алгоритмы. Я сделал для Специалиста такой скоростной редактор на ассемблере, идея отличная, скорости добился, но в итоге затрахался с отладкой, энтузиазма не хватило отладить до полной безглюковости (в каких-то ситуациях текст искажался). И до меня дошло, что сложные алгоритмы надо писать на ЯВУ.
Идея ускорения в том, чтобы делать долгую работу в паузы между нажатиями клавиш, в эти паузы процессор незаметно для пользователя, строчка за строчкой нормализует текст. Если при уходе с отредактированной строки, отредактированная строка меньше исходной, то она вставляется в исходное место, а лишние байты заполняются нулями (тогда подпрограмма поиска нужной строки, их пропустит), причём место где надо удалить лишние байты запоминается в списке. Если же строка имеет больший размер, чем исходная, то в текстовыё буфер вставляется байт-флага и следом за ним адрес динамического буфера, в котором теперь хранится эта строка. Динамические буфера под отдельные строки выделяются с RAMTOP и вниз.
Таким образом, получается мгновенная реакция на уход с отредактированной строки - курсор на экране переходит в другую строку без пауз. А затем, в паузу между нажатиями незаметно, без долгих зависов выполняется нормализация текста. И она не тормозит работу редактора, т.к текст нормализуется по-строчно. Т.е например, в случае, когда строка была короче и в тексте остались нулевые байты, то в цикле опроса STATUS-а клавиатуры, редактор сдвигает только одну очередную строку и так пока не дойдёт до конца текста. Если же надо делать сдвижку вверх, то начиная с последней строки, точно также построчно строки сдвигаются вверх. По окончании раздвижки строка из динамического буфера под вершиной ОЗУ ставится на место, а ОЗУ динамического буфера освобождается. Такой редактор имеет объём всего на 1 кб больше, чем тупой традиционный редактор, но зато работает без тормозов даже при такте 200 КГЦ.
Но такой алгоритм сложнее, чем примитивный, написать и отладить на ассемблере. Вот тут-то ЯВУ в помощь. А нет ли у кого-то идеи, как решить ту же задачу ускорения, но проще? Чтобы понять о редакторах какого уровня речь, ниже в спойлере список их возможностей. Исходника редактора на ассемблере из начала 90-тых, который сравнивался, не сохранилось, но есть дополненная версия - в ней ~3200 строк ассемблера. Число строк редактора на PL/M не знаю (более 1000), а для версии на Турбо-Паскале можно посчитать. Сохранён где-то на резервных CD-R оригинальный исходник CP/M-варианта редактора на Турбо-Паскале, но найти долго. Вот тот же исходник, лишь переделанный для трансляции TP MSDOS и затем переделанный для трансляции в Linux с помощью GPC. GPC ценен тем, что он перетранслирует исходники программ написанных для TP/BP/TPW в Linux (кстати, приятно, что есть модуль TP3, можно транслировать и программы CP/M-овского Турбо-Паскаля 3.0). Когда я в 1997 поставил себе Linux, то был в ужасе от качества их редакторов, они оказались вообще неэкранными. Пришлось перетранслировать CP/M-редактор под Linux и я им много пользовался (не этой версией, а доработанной, где было даже форматирование с правильными переносами), т.к ничего приличнее не было в дистрибутиве. Как видите команды в моих редакторах те же, что и в редакторе самого Турбо-Паскаля (это популярный в CP/M стандарт). Кстати, раз Турбо-Паскаль уступает в эффективости ассемблеру всего в 3 раза, то т.к Турбо-Си для CP/M нет, то очевидный второй кандидат в наилучший инструментарий ретро программиста, это именно TP 3.0. Для Z80 (но не КР580) вроде бы есть и кросс-компиляторы Паскаля и даже с IDE, но, похоже, они или платные или недоделанные (типа студенческих работ). "О каких редакторах шла речь [size=85] | | | | Code: HELP: RST 18H
TXHELP: defb CLSCOD,13,10,9 defb 'NEW SCREEN ',VL,'.',SH,SL,' -- ' defb DH,DL,'.',MH,ML,'.',YH,YL,13,10,10
if LAT
defb '^U TO LINE END ^ T LN BEG/END',13,10 defb '^Q R GOTO BEG (@B) ^Q C GOTO END (@E)',13,10 defb '^R PAGE UP (@UP) ^С PG DOWN (@DN)',13,10 defb '^Y,^D ERASE LINE ^N INSERT LINE',13,10 defb 'F5 CLEAR TO EOL ^K O MERGE LINES',13,10 defb '^K B SET BLK.BEG ^K K SET BLK.END',13,10 defb '^K C COPY BLOK ^K V MOVE BLOK',13,10 defb '^K Y ERASE BLOK ^K U UNMARK BLOK',13,10 defb '^Q F FIND (@F) ^Q L FIND NEXT (^L)',13,10 defb '^Q A REPLACE (@Z) ^QE INSERT EOF',13,10 defb '^K 1..3 SET MARK ^Q 1..3 GOTO MARK',13,10 defb 'F2 ERASE SYMBOL F3 INSERT SPACE',13,10 defb '^V TOGGLE INS. ^Q T SEL TAB MODE',13,10 defb '^K N NEW FILE (@N) ^K A ASSEMBLER',13,10 defb '^E EXIT',13,10,10,0 else defb '^T В НАЧ/КОН СТРОКИ ^U В В КОНЕЦ СТРОКИ',13,10 defb '^Q R В НАЧ.ТЕКСТА (@B) ^Q C В КОН.ТЕКСТА (@E)',13,10 defb '^R НА ЭКР.ВВЕРХ (@UP) ^С НА ЭКР.ВНИЗ (@DN)',13,10 defb "^Y,^D УДАЛИТЬ СТРОКУ ^N ВСТАВИТЬ СТРОКУ",13,10 defb "F5 ОЧИСТИТЬ ДО 'EOL' ^O СЛИЯНИЕ 2 СТРОК",13,10 defb '^K B УСТ.НАЧАЛО БЛОКА ^K K УСТ.КОНЕЦ БЛОКА',13,10 defb '^K C КОПИРОВАТЬ БЛОК ^K V ПЕРЕМЕСТИТЬ БЛОК',13,10 defb '^K Y УДАЛИТЬ БЛОК ^K U ОТМЕНИТЬ БЛОК',13,10 defb '^Q F ПОИСК ОБРАЗЦА (@F) ^Q L ПОИСК ДАЛЬШЕ (^L)',13,10 defb "^Q A ЗАМЕНА (@Z) ^QE УДАЛИТЬ ДО 'EOF'",13,10 defb '^K 1..3 УСТАН-ТЬ МЕТКУ ^Q 1..3 ИДТИ К МЕТКЕ',13,10 ; defb '^K P СТРОКУ В БУФЕР ^K G СТРОКУ ИЗ БУФЕРА',13,10 defb 'F2,^G СДВИЖКА СТРОКИ F3 РАЗДВИЖКА СТРОКИ',13,10 defb '^V СМЕНА РЕЖ.ВСТАВКИ ^Q T РАЗРЕШИТЬ ТАБ',13,10 defb '^K N НОВЫЙ ФАЙЛ (@N) ^K A В АССЕМБЛЕР (@A)',13,10 defb '^E ВЫХОД',13,10,10,0 endif RST 30H JR BTM3
DH EQU DAY/10 +'0' DL EQU (DAY MOD 10) +'0'
MH EQU MONTH/10 +'0' ML EQU (MONTH MOD 10) +'0'
YH EQU YEAR/10 +'0' YL EQU (YEAR MOD 10) +'0'
HOH EQU HOUR/10 +'0' HOL EQU (HOUR MOD 10) +'0'
MIH EQU MIN/10 +'0' MIL EQU (MIN MOD 10) +'0'
VL EQU (VERS MOD 10) +'0' SH EQU SUBVER/10 +'0' SL EQU (SUBVER MOD 10) +'0'
[/size] | | | | |
Last edited by barsik on 01 Nov 2019 08:17, edited 4 times in total.
|
29 Oct 2019 17:04 |
|
|
SAA
Senior
Joined: 12 Jul 2016 21:30 Posts: 136
|
Да нехорошо получилось, попутал, конечно же 256. Обидел Воза Но это верно для Apple I, а сколько занимает монитор Воза в Apple II? Если быть точнее то обсуждаем мы что удобней для программиста компиляторов ЯВУ, т.е. в некотором роде системного ПО. Я понимаю, Лавр, что Вы хотите сказать, но согласится с Вами на 100% не могу. То что Вы утверждаете верно для программиста приложений пользователя в ОС которая не регламентирует использование ресурсов и монополизирует их. Это так же верно и для других архитектур хоть z80 хоть x86, системный софт которых будет использовать на кристальные регистры безалаберно. 256 байт ОЗУ в версии 6508 было, кстати, перенесено на кристалл, но дело как мы понимаем не в локализации 256 регистров, а в регламентировании их использования.
|
29 Oct 2019 19:24 |
|
|
Who is online |
Users browsing this forum: No registered users and 25 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
|
|