Просмотр полной версии : Ищу Си для Z80
Подскажите, где можно взять компилятор Си для процессора Z80, желательно с описанием?
Требуется для написания приложений, пригодных для запуска на ZX-Spectrum, т.е. для создания в результате кодовых файлов с заданием адреса запуска, а не с фиксированным 0x100, как для CP/M или MSXDOS. Уже пробовал поискать на IAR (вроде бы у них есть), но так ничего там и не понял.
Если у кого-нибудь есть возможность - пришлите, пожалуйста по емейл (если объем в разумных пределах) или выложите куда-нибудь с прямой ссылкой. не хочется с ассемблером заморачиваться, долго очень...
Подскажите, где можно взять компилятор Си для процессора Z80, желательно с описанием?
Требуется для написания приложений, пригодных для запуска на ZX-Spectrum, т.е. для создания в результате кодовых файлов с заданием адреса запуска, а не с фиксированным 0x100, как для CP/M или MSXDOS. Уже пробовал поискать на IAR (вроде бы у них есть), но так ничего там и не понял.
Если у кого-нибудь есть возможность - пришлите, пожалуйста по емейл (если объем в разумных пределах) или выложите куда-нибудь с прямой ссылкой. не хочется с ассемблером заморачиваться, долго очень...есть под тырдос всякие, но как я посмотрел буржуй свои игры некоторые последние тоже на сях пишут.... не соврать, но ихний компилятор под линух.... возможно я ошибаюсь....
кросскомпилеры:
http://sdcc.sourceforge.net/
http://www.z88dk.org
первый ANSI-C совместимый и вообще попрямей, под второй есть некоторое кол-во готовых либ для работы со спектрумовским железом (клава, экран, прерывания...)
кросскомпилеры:
http://sdcc.sourceforge.net/
http://www.z88dk.org
первый ANSI-C совместимый и вообще попрямей, под второй есть некоторое кол-во готовых либ для работы со спектрумовским железом (клава, экран, прерывания...)
Спасибо, сейчас схожу.
Я забыл написать, что компилер нужен для PC :)
Спасибо, сейчас схожу.
Я забыл написать, что компилер нужен для PC :)
я юзаю SDCC + небольшая доводка crt0.s + gui codeblocks (нужно брать тут http://forums.codeblocks.org/index.php?board=20.0)
получается очень удобно, но, правда, не всегда оптимально.
пример есть в исходниках http://zx.pk.ru/showthread.php?t=6679
Подскажите, где можно взять компилятор Си для процессора Z80, желательно с описанием?
Коммерческий IAR С неплохой код генерит.
Искать в файло-обменных сетях.
вот тут прочитал, что обновился ccz80!
http://perso.orange.es/emilio.guerrerog/ccz80/ccz80.html
вот тут прочитал, что обновился ccz80!
http://perso.orange.es/emilio.guerrerog/ccz80/ccz80.html
Судя по:
--------------------------------------------------
NEWS
Jan 13 2008: Released initial version 1.0.0 of compiler, libraries and documentation.
Jan 14 2008: Compiler versiуn 1.0.2
--------------------------------------------------
это вообще что то новое, и кстати имеет библиотеки для Спектрума.
Для начала посмотреть бы тут (http://zx.pk.ru/showthread.php?t=5335), а потом уже в случае непоняток спрашивать.
я юзаю SDCC
Очень не плохой вариант, пользовался одно время
это вообще что то новое, и кстати имеет библиотеки для Спектрума.
Очень даже хороший, конечно не идеал, но достоин внимания.
эх.... жалко в сях неразбираюсь..... придётся дальше асм ковырять :)))))))))
жалко в сях неразбираюсь
А займись, простые вещи (типа print 1+2) там не сложнее бейсика, а когда начнёшь то дальше пойдёт проще. (в любом языке как в прочем и любом деле самое сложное это первые шаги)
Првет.
Да, SDCC код даёт более красивый, чем Z88DK. Жаль, его на Амигу не портировали.
Кстати, а как бинарники-то получаем? Там же на выходе *.ihx. Отдельную утилитку качать?
Shadow Maker
20.01.2008, 19:23
Хм, я почему-то думаю, что всё равно ничего мощного не написать... Памяти мало.
Написать можно. Другое дело что методы MS проникают в головы и часто вместо оптимизации кода покупают более быстрые машины %) А зачем? Вон в далёких 1970x годах писали на форте на 32 кб ОЗУ программу управления телескопом, тривиальная задачка что ли??? Так что не поддерживаю общий тренд высказывания
эх.... жалко в сях неразбираюсь..... придётся дальше асм ковырять ))))))))
И не учи ... Вот уже год вынужден писать проги на СИ, поскольку зарубежники ничего другого понять не могут. На изучение потратил аж 3 дня ... IF'ы они и в африке IF'ы, а возможность произвести операцию в математическом выражении, например: "if ((a=a+7)==b) {}" не есть достижение и в большинстве случаев совсем не нужно. Кроме всего все СИ разные, на их примере можно изучать RND. То у них константы струткуры заполняюся с ошибкой, то не работает "(a=(b+7)<<6)", а работу надо сделать, ведь не будешь заказчику объяснять, что компания ST лохонулась в соём супер СИ кмпиляторе. Так и получается, что бы написать портирующийся и универсальный код, только IF'ы и юзать !!! Ну или не писат вовсе.
Вот чего я не могу понять, а зачем компилятор ??? Интерпритатор для Speccy по горло хватит. Или вы собираетесь Plot'ами спрайты выводить ??? Decrunch на СИ или ВАСИКЕ, и 90% кода на ASSM'е !!! Тут совсем не нужна супер скорость математики.
На изучение потратил аж 3 дня
Вот и уровень знаний у вас соответствующий этим трём дням
Одни высказывания типа
все СИ разные
уже чего стоят...
По изучайте Си хотя бы годик и будете вместе со мной смеяться над своим сегодняшним сообщением !!!
По изучайте Си хотя бы годик и будете вместе со мной смеяться над своим сегодняшним сообщением !!!
Уже годик есть ... Написал 7-емь проектов из них 6-ть под не менее идиотский нежели СИ линукс. Изучил ... Мнение не изменилось ... Ну а урвень это дело жизни ... Вечное совершенство - стиль моей жизни ... Просто я не стопорюсь на одном и том же. Си не есть идеал и не станет им, он просто развивает лень в программировании. Последний проект был под "BlackFin BF561", и мена кробит результат компиляции Сишного кода, зная каке команды процессора есть у ядра. Практически ядро в данном случае используется на 10%. Теперь Вы попробуйте написать что-то под это ядро на асме и ощутите разницу. Невероятная компактность кода. Так же под ARM-7, а особенно в 32-битном режиме. Изучте в этих ядрах кэш, и увидете как СИ их методично рубит под ноль. На обоих ядрах табличный метод программирования просто "конфетка". Целые операцие с вложенными подпрограммами будут испоняться за пару тактов.
Так что пока мой годичный опыт подтверждает, что асм по-прежнему рулит как икогда. А СИ порождает лень.
СИ нужен это очень полезная вещь но не в 100% кода, от силы 10%.
На изучение потратил аж 3 дня
Уже годик есть ... Написал 7-емь проектов
Год писания не значит год изучения !!! (я вот свою первую программу на бейсике уже почти 20 лет назад написал, но это вовсе не значит что я все эти 20 лет учился)
Добавлено через 3 минуты
СИ порождает лень.
Сама идея языков высокого уровня в том что они порождают лень, такова их природа и их предназначение !!!
Более того есть поговорка "Лень двигатель прогресса!"
Если бы древним людям не было лень таскать на горбу тяжёлые грузы так никто не изобрёл бы колесо (а в следствии этого телегу которая упростила перемещение грузов)
Добавлено через 8 минут
Да, на 3.5МГц при 64кб (включая ROM) памяти Си больше похож на извращение чем на необходимость, но в современных компах (когда все инструкции выполняются за один такт в 2-4 потока) человеку просто не под силу оптимизировать ASM код, уж слишком многое надо принимать во внимание (у человека столько "оперативки" в голове нет чтоб учесть все тонкости)
Сама идея языков высокого уровня в том что они порождают лень, такова их природа и их предназначение !!!
Я не хочу порождать проекты ленью ... Мои работы будут достигнуты путём труда, они будут быстрые и адёжные ... Лень в моих целях будет помехой ... Пусть другие изобетают колесо, я им представлю инструмент для того, что бы они могли его сделть. Для мея лучше созедать нежели потреблять ...
Год писания не значит год изучения !!! Ты так говоришь, как будто я целый год набивал одну программу. Я думал, что практика это и есть изучение. Уверяю тебя, что я испльзовал все приёмы СИ которые он имеет, по мере необходимости, конечно.
Пусть другие изобетают колесо, я им представлю инструмент для того, что бы они могли его сделть
Так вот Си это тоже инструмент чтоб люди могли делать то что делать на ASM было бы сложно
Я думал, что практика это и есть изучение.
практика это вторая стадия изучения (без неё первая стадия не имеет смысла) но вторая стадия без первой также бессмысленна как и первая без второй...
Так вот Си это тоже инструмент чтоб люди могли делать то что делать на ASM было бы сложно
У меня пявилась идея ... Напишу-ка я СИ компилятор для ZX'а ... На АСМЕ ... Будет поддержвать только стандарт С99 ... Люблю в качестве инструмента АСМ !!! Единственное не хочется библиотеки переписывать ... Они в СИ такие ограниченные. Но придётся ...
---
Кстати, у тебя на аватарке герой - "SPOOKED", игра велеколепно написана, вообще вся ONE-FRAME, и главное на АСМЕ !!!
Кстати, у тебя на аватарке герой - "SPOOKED", игра велеколепно написана, вообще вся ONE-FRAME, и главное на АСМЕ !!!
Я не против того что асм рулит (сам так считаю и пользуясь гуглем/яндексом можно найти много тому подтверждений) я просто против того что другие языки не имеют право на существование...
(а Spooked я знаю что великолепная игра, фанатею с того момента как увидел её)
СИ их методично рубит под ноль
Господа, когда вы перестанете путать кислое и длинное.
Объясняю для тех, кто на бронепоезде:
СИ ничего не знает про
а) особенности распараллеливания
б) кеш
в) особенности работы с внешними устройствами
г) и т.д.
Иметь в виду все вышеперечисленное- дело конкретного компилятора. И крайне глупо ругаться на ЯЗЫК, используя неподходящий КОМПИЛЯТОР, не НАСТРАИВАЯ его подобающим образом.
СИ ничего не знает про
Это всё последствие полимики ...
Давайте лучше разберём стандарты:
1) while (TRUE) { };
На сколько принципиально ругаться на отсутствие ";" после "}" ???
2) char s[32];
sprintf (s,"Ura dedu morozu /* ");
sprintf (s,"Aru na deda moroza */ ");
Практическ все компиляторы думали, что между "/*" и "*/" всё заремлено, только мотороловский компилятор такое компилирует. В стадарте С99 наисано что такого делать нельзя и подобный код считаеся ошибкой. Предлагаю считать ошибкой, что считается ошибкой !!! Натуральная лень создателей сделать всё по-людски !!!
3) switch (?) {
case 0x02: assish;
case 0x01: popish;
case 0x00: kukish;
case 0x03: kakish;
}
В данной ситуации если "?" будет равен "1", то исполнится "popish; kukish; kakish;". С99 снова гласит, что нужно заканчивать "break;", прикрывая задницу, что это типа так придумали. На сколько это принципиально ??? Есть ли примеры, когда это так необходимо ?
a. Я изучил эту ситуацию и увидел, что KEIL под ARM-7 вообще тупо сортирует и исполнение получается таким: "popish; assish; kakish;".
b. IAR под ARM-7, херит регистры и память из-за оптимизации в зависимости от того, что в нутри "кейса".
c. ST-RealView исполняет често один "кейс".
Если стандарт С99 гласит писать "break;", может нужно сделать это автоматом и не парить мозги программисту !!!
4) Самое главное "жлобские маленькие буквАчки" !!! Предлагаю сделать универсально любыми !!! Как хочешь, так и пиши !!! Если етсь весомый довод, маленьких букв, то жду предлений ?
1) while (TRUE) { };
На сколько принципиально ругаться на отсутствие ";" после "}" ??? нинасколько, после закрывающей скобки блочного оператора ";" не нужна (но и не запрещается -- это просто пустой оператор, в строчке ";;;;;;;;" тоже нет никакой ошибки)
char s[32];
sprintf (s,"Ura dedu morozu /* ");
sprintf (s,"Aru na deda moroza */ "); GCC компилит спокойно. 1й раз слышу, что так нельзя )
switch (?) {
case 0x02: assish;
case 0x01: popish;
case 0x00: kukish;
case 0x03: kakish;
}
В данной ситуации если "?" будет равен "1", то исполнится "popish; kukish; kakish;". С99 снова гласит, что нужно заканчивать "break;" принято, но не обязательно. BTW, ты что за книжку по с99 читаешь? сроду break не был обязаловкой AFAIK, и кейсы без брейков используются на каджом шагу, например при разборе условных выражений в стиле php:
switch(operator)
{
case OP_IF:
/*пхаем на стек новую условную секцию*/
case OP_ELSEIF:
/*разбираем и вычисляем выражение, синтаксис которого одинаков для if и elseif*/
break;
default: err_exit("случилась фигня");
}
Самое главное "жлобские маленькие буквАчки" !!! Предлагаю сделать универсально любыми !!! Как хочешь, так и пиши !!! Если етсь весомый довод, маленьких букв, то жду предлений ? ты про чувствительность сишных идентификаторов к регистру? это юзается, и жить IMHO не мешает сршенно. к примеру константы препроцессора и значения enum'ов принято писать заглавными, чтоб не пересеклись с какой случайной переменной (переменные принято писать строчными) -- а то они на глобальном уровне, всякое может быть.
Давайте лучше разберём стандарты:
это не проблема стандарта, а проблема кривой реализации этого самого стандарта разработчиками некоторых компиляторов.
СИ нужен это очень полезная вещь но не в 100% кода, от силы 10%
с этим я бы согласился если поменять 10% на 98% :) оговорюсь, это если разрабатывать под нормальные платформы типа десктопа, а не под маленькую тормозную железячку с минимумом памяти
оговорюсь, это если разрабатывать под нормальные платформы типа десктопа, а не под маленькую тормозную железячку с минимумом памяти
Cи на спеке полезен для общей организации кода -- на нем хорошо писать этакий фреймворк, который вызывает ассемблерные процедуры (для такого, вобщем-то, хоть бейсик можно юзать) -- ресурсы не критичны, зато код легко структурировать. пример: z88dk+spritepack, на которых, насколько понимаю, писаны phantomasa и еще кое-чего из последнего (при всей неоптимальности пусть и ассемблерного spritepack, который построен по слишком обобщенной архитектуре, чтоб эффективно юзать ресурсы, игрулька вполне играбельная ;))
На сколько принципиально ругаться на отсутствие ";" после "}" ???
Глупо. Стандарт разрешает их не ставить.
Натуральная лень создателей сделать всё по-людски !!!
Ну может так им было проще. Тем не менее- нарушение.
С99 снова гласит, что нужно заканчивать "break;", прикрывая задницу, что это типа так придумали. На сколько это принципиально ??? Есть ли примеры, когда это так необходимо ?
В случае, если "break" не стоит, что говорит стандарт? По идее, должно выполняться дальше до ближайшего или до конца свитча.
Если етсь весомый довод, маленьких букв, то жду предлений ?
1) совместимость
2) стандартизация (как задали, так и пиши, не надо вводить в заблуждение)
3) шире пространство для идентификаторов
сроду break не был обязаловкой AFAIK, и кейсы без брейков используются на каджом шагу
Я у себя на рабте вижу обратное ... Вот поэтому меня и раздражают СИ стандарт один а код разношёрстый. А потом сидишь и правишь половину чего-то кода, что бы можно было откомпилировать.
с этим я бы согласился если поменять 10% на 98% оговорюсь
Кстати это как бы слеующий принципиальый вопрос, как красиво подружить СИ с асмом ... Надо будет подумать ...
это если разрабатывать под нормальные платформы типа десктопа, а не под маленькую тормозную железячку с минимумом памяти
Ну на калькулятор МК-61 писать не будем ... Как сказал Vitamin, СИ не знает какова железяка ... И я не вижу разницы в медленной или быстрой железяки ... Нет ничего плохого если прекрасно оптемизированный код будет велеколепно работать на супер быстрой железяке типа нашего Speccy !!! Но прикол с "МК-61" мне понравился ... :)
Cи на спеке полезен для общей организации кода -- на нем хорошо писать этакий фреймворк, который вызывает ассемблерные процедуры
соглашусь, хотя при наличии нормальной и документированной асмовой библиотеки, выигрыш в скорости разработки будет не очень большой
Как сказал Vitamin, СИ не знает какова железяка ...
СИ не знает, знает компилятор :) кста, большинство твоих "притензий" относятся к кривым компиляторам, а не к языку/библиотекам
СИ не знает, знает компилятор кста, большинство твоих "притензий" относятся к кривым компиляторам, а не к языку/библиотекам
Ха ... Ещё бы ... Исключительно к компиляторам ... Так же как и ПиЦи, если бы его "кодеры" были порядочными, то и на ПиЦи было бы большенство шедевров.
"Притензии" к людям которые подходят к языку с точки зрения школьной программы. Тестирование заполнения экрана FF'ами, это кощунство. Никто не трёт память FOR'ом ии WHILE'ом. Только отдельно написанная процедура затирания куска памяти на !!!асме!!!. Вот меня и коробит, когда я это вижу. Просто, более серьёзный подход должен быть. А по-скольку 99% людей к таким вещам подходят как начинающий программист, я просто уверен что для таких нужно поставить рамки не более 10% кода на СИ !!! Конечно я такое делать не буду, но каждый уважающий себя CODER обязан свою работу доводить до идеала. Этим и славились Speccy, Atari и подобные монстры. Эти машины взростили примеры на которые по сей день равняются все ... А ПиЦи взростил комерческий подход и винду со всякой хренью. Вот поэтому в этом посте постоянно шла речь о том, что "где-то нельзя выкладывать кряк", или "там денег стоит" или ещё что-то в подобном жанре. А если создатель печётся о доходе а не о профессионализме, то тут только руками можно развести.
Ибо Мир делится на Созедателей и Потребителей. А деньги это потебление.
И сколько не говоите мне "Лень двигатель прогресса", двигают его трудом а не ленью. Вам это колесо кто-то придумает, а у вас едиственная фраза на всё будет - "зачем его изобретать заново". Ну спалите все книги к чёрту ... Чё их хранить, есть в электронном виде, можно экранизацию псмотреть ... Прогресс же ... Перестаньте читать ... Вот вам и лень ...
Так что мой компилятор будет всё учитывать ...
Добавлено через 13 минут
О самом главном: Кто пользуется "mak" файлами ??? В котором описание проекта, типа там путь к INCLUDE'ам, какой файл является MAIN'ом ???
Error404
22.01.2008, 20:32
... я такое делать не буду, но каждый уважающий себя CODER обязан свою работу доводить до идеала. Этим и славились Speccy, Atari и подобные монстры. Эти машины взростили примеры на которые по сей день равняются все ... А ПиЦи взростил комерческий подход и винду со всякой хренью. Вот поэтому в этом посте постоянно шла речь о том, что "где-то нельзя
Дело в том, что объем проектов сильно вырос (я тут не считаю программирование микроконтроллеров - это отдельный сегмент) и если заниматься вылизыванием кода, то программистам в пересчете на человеко-час будут платить очень мало - на хлеб не хватит. Поэтому раз железо позволяет неоптимальный код, то хвала такому железу. :)
Так что мой компилятор будет всё учитывать ...
Очень нужен ANSI-совместимый С (С99 совместим или нет? Я не шибко силен в стандартах) для Z80 (в идеале, работающий на собственно 8-битке) с прямой, т.е. некорявой и неглючной поддержкой 32-битных целочисленных типов. Я пока ни одного такого не видел. Чем все прочие немного ближе к идеалу HiTech C (хотя бы ANSI-совместим), но он страшно глючный (имеется в виду CP/M версия).
вот я пишу демокод... первые 10% времени занимает чисто создание эффектов - 90% кода по объему - потом 90% времени уходит на собирание и фикс этих эффектов в кучу (дему), настройка переменных для эффектов и прочая дребедень - это даже меньше 10% кода в результате, но занимает процентов 90 времени.
короче - все как положено =)
в принципе последний этап может было бы проще писать на каком-нить языке выше ассемблера - чтобы малейшая ошибка в цифре не приводила к сбросу.
О самом главном: Кто пользуется "mak" файлами ??? В котором описание проекта, типа там путь к INCLUDE'ам, какой файл является MAIN'ом ???
Привет ROB F! Приятно видеть что кровь в твоих жилах все еще _кипит_ как и много лет назад в начале 90-х ! :) Более того забавляет _ВСЕ ЕЩЕ ТО!_ рвение переписать всех и вся на ASM-e.
Слабо мне верится что ты проникнешся моим коментарием по поводу твоего рвения создать СВЕРХ оптимальный С-компилер для Z80. Поэтому ПРОШУ! все кто со мной согласен скажите что я прав а те кто не согласен скажите что не прав. А коментарий такой:
1. не надо лазить в make file-ах и писать свой жутко оптимальный "gnu make" на ASM-e;
2. не нaдо писать свой С компилер с нуля на ASM-e;
3. нужно разобратся немного с open source компилерами типа sdcc и gcc, посмотреть какие есть недостатки у текущих генераторов кода для Z80, внести улучшения и выложить свои patch-и для других на обсуждение (если что-то толковое сделаешь - поверь народ вкомитит твои изменения);
Привет ROB F! Приятно видеть что кровь в твоих жилах все еще _кипит_ как и много лет назад в начале 90-х !
Во блин ... Заинтригован ... Кто это ??? Мне да же не стало обидно что "ROB F" без точки !!!
1. не надо лазить в make file-ах и писать свой жутко оптимальный "gnu make" на ASM-e;
Не буду ... Будет на TMT-Pascal'е, и да же под всвеми любимую винду !!!
2. не нaдо писать свой С компилер с нуля на ASM-e;
Компилятор будет безусловно на TMT-Pascal'е, но, прости, сам компилятор уже начат и он на асме ... Не всё, основа анализа стринга, и подобное только на асме, то есть основное мясо !!! Собственно это уже сделано ... Это просто ... Щас библиотеку приоритетных команд сделаю, потом макросы, а там уже и первая версия ...
3. нужно разобратся немного с open source компилерами типа sdcc и gcc, посмотреть какие есть недостатки у текущих генераторов кода для Z80, внести улучшения и выложить свои patch-и для других на обсуждение
На это тратить время не буду ... Мне и так на работе за простой влетит ... А не достатки я и сам понимаю, уже писал компилятор ASAM, кстати, практически язік программирования ...
поддержкой 32-битных целочисленных типов
Безусловно !!! Это очевидно !!!
потом 90% времени уходит на собирание и фикс этих эффектов в кучу
Для этого я уже сделал ASAM там вообще ничего не надо собирать, автоматом любіе лоадеры компилятся !!! Но традиция останется старая, Linker будет в виде асмасково кода, компилирующийся моим же ASAM'ом, то есть будет выполнять тривиальную задачу ... Но, вообще-то, советую обратить внимание на ASAM, покрайненй мере со сборкой проблем не будет ... Странно, я думал что эти проблемы уже решены в SjASMPlus ...
Добавлено через 5 минут
Кстати ... В последней версии ASAM'а я выложил MATH модуль ... Я так же на праздниках делал дему ... Убил около стни зайцев одним выстрелом, дописывая этот модуль ... Любую математику можно реализовать ... Вообщем в последнем эффекте сделал всё за пару часов ...
Компилятор будет безусловно на TMT-Pascal'е, но, прости, сам компилятор уже начат и он на асме Robus, так ты кросс-компилятор хочешь написать? а зачем, хочешь, чтобы он генерил более оптимальный код, чем sdcc/z88dk/gcc/IAR etc...? надо ли оно... все равно критичные по ресурсам части проги на асме писать, а для некритичных частей и существующие кросс-компилеры подходят.
(...а твой компилятор, подозреваю, под дос будет? а то для юниксоидов/макосников дос ваще не вариант, и для виндузоидов неудобно :rolleyes:)
эх, вот если б нативный спектрумовский компилятор С99, вот это я понимаю :v2_rolley
Для этого я уже сделал ASAM там вообще ничего не надо собирать, автоматом любіе лоадеры компилятся !!! Но традиция останется старая, Linker будет в виде асмасково кода, компилирующийся моим же ASAM'ом, то есть будет выполнять тривиальную задачу ... Но, вообще-то, советую обратить внимание на ASAM, покрайненй мере со сборкой проблем не будет ... Странно, я думал что эти проблемы уже решены в SjASMPlus ...
проблема не в подключении лоадера - это как раз делается на раз в любом ассемблере
основное время занимает распихивание эффектов по банкам и обработка взаимодействия между модулями... ну и всякий мелкий код - типа управление перемещениями, то есть работа с переменными...
Q-Master
23.01.2008, 09:47
Более того, написаный на асме цомпилятор будет абсолютно непортируемым.
основное время занимает распихивание эффектов по банкам и обработка взаимодействия между модулями... ну и всякий мелкий код - типа управление перемещениями, то есть работа с переменными...
Ну ... От этого практически не уйти ... Это и есть искусство программирования на Speccy ... Однако я тебя очень хорошо понимаю, и сам по сегодняшний день в каждом новом проекте пытаюсь применить новые способа решения подобных задач. В мучаемом мною уже два года CuberDie, я использовал макросы для заполнения банков.
В итоге код выглядит так:
;Выбираем сегмент в который мы поместим эффект (кусок) демки для будущего исполнения
;Мой "SEG" переключится на страницу 17 и установит адрес компиляции (ORG) в предыдущий для этой странице, допустим сейчас это 49152, этот адрес будет храниться в переменной "BP17.S" но из этого значения вычитается 49152, то есть размер блока для 17-ой страницы составляет "0"
SEG 17
SuperEffect_2 ;Адрес эффекта в сегменте
;Адрес компиляции останется в 49152, но компилятор будет думать что весь код помещается по адресу "FreeSpace", допустим это 35000. Этот адрес указывает на свободное место для исполнения эффектов. Допустим у нас их 10-ть. Первый уже тут лежал, в "FreeSpace" исполнился и освободил память. То есть каждый эффект будет компилироваться с учёт адреса на "FreeSpace".
PHASE FreeSpace
;Далее, собственно, эффект ... Ну типа покажем на экране мега картинку.
HALT
LD HL,22528
LD DE,22529
LD BC,767
LD (HL),L
LDIR
LD HL,MegaPicture
LD DE,16384
LD BC,6144
LDIR
WaitLinePos (16,3) ;Типа ждём музыку
LD B,3
LDIR
RET
MegaPicture IncTRD "GFX\gfx.trd","pic.c" ;Загружаем мегакартинку из TRD модуля
UNPHASE
;Далее самое главное. Пакуем то что накодили. Сейчас адрес $=49152+6912+??? короче много.
DSQ.Pack SuperEffect_2,$-SuperEffect_2
;Теперь адрес $=49152+??? вообщем теперь меньше.
EndSeg ;Теперь в "BP17.S" сохранён новый размер этого блока
Ну а распаковка становится банальна, знаешь адрес в странице, знаешь куда "FreeSpace" ...
Единственное, что нужно - следить за размером блока в странице, что бы не вылез за 16384 !
Как ты сам понимаешь, сам эффект можно хранить как отдельный файл, его инклудить между PHASE и UNPHASE ... Таким образом легко автоматизировать труд. И главное - постоянно запакованная дема до последнего битика.
А вот как такое реализовывать в СИ я не представляю. А в асме нет ограничений и можно писать практически на языке высокого уровня. Да и что над от него ? Математику, возможность в скобках получать значения из процедур. Это главное. А это всего 10%.
Тестирование заполнения экрана FF'ами, это кощунство. Никто не трёт память FOR'ом ии WHILE'ом. Только отдельно написанная процедура затирания куска памяти на !!!асме!!!.
если компилятор уже такой тупой цикл компилирует в уродливую конструкцию с индексными регистрами, то понятно, что он любой цикл скомпилит в подобную фигню... а то, что основная библиотека функций должна быть на асме - это очевидно
более того, узкие места тоже нужно переписывать на асме
но когда я пишу макет программы, я хочу, чтоб его, во-первых, можно было написать быстро (хотя бы пока интерес не угас), и, во-вторых, чтоб его пришлось как можно меньше дорабатывать и оптимизировать
собственно ради этого я и тестировал именно цикл заполнения экрана FF-ами, ибо ничего проще придумать не смог :) но уже на таком примере видно, что z88dk генерит порнографию, а IAR и sdcc более-менее приятный глазу и процу код
Robus, так ты кросс-компилятор хочешь написать?
Нет ... Это будет компилятор СИ, который будет генерить обектные файлы. Далее будет линкер, который превратит это всё в бинарник исполняемый на Speccy, так же он будет оптимизировать. Я вот думаю, что откажусь от асмовских вставок !!! Их будет компилить отдельно линкер. Как отделные файлы.
дос ваще не вариант
Да чего вы так панически боитесь дос приложение ??? Вы что боитесь, что винда не выделит сегмент для исполнения EXE'шника ??? Мало того я уже сказал, что будет вариант и для винды и для доса.
Ещё раз "ВИНДА" = "TRUE" !!!
А вот Unix'ы, увольте ... Не в данный момент ...
Нет ... Это будет компилятор СИ, который будет генерить обектные файлы. Далее будет линкер, который превратит это всё в бинарник исполняемый на Speccy, так же он будет оптимизировать. да нет же, если он у тебя будет под дос/винду x86, а генерить будет код для Z80, значит кросс-компилятор :)
(http://ru.wikipedia.org/wiki/Кросс-компилятор)
так же, как sdcc/IAR/z88dk и др.
Q-Master
23.01.2008, 15:49
нафиг такие "кросс-компиляторы".
значит кросс-компилятор
Ну тогда оно ... Не разбераюсь я в терменологии ...
нафиг такие "кросс-компиляторы".
Что бы хорошо работали ... Лучше качественно но локально, чем унивесально, но посредственно ...
ILoveSpeccy
11.03.2008, 08:31
я юзаю SDCC + небольшая доводка crt0.s + gui codeblocks (нужно брать тут http://forums.codeblocks.org/index.php?board=20.0)
получается очень удобно, но, правда, не всегда оптимально.
пример есть в исходниках http://zx.pk.ru/showthread.php?t=6679
Скачал и установил SDCC 2.7.0 и CodeBlocks 8.02.
Открыл проект загрузчика "boot" из Speccy2007 (файл boot.cbp) и попробовал
скомпилировать (выбрал в меню Build).
Выскакивает ошибка:
-------------- Build: Release in boot ---------------
Compiling: main.c
Linking executable: hex\boot
obj\main.o: cannot open.
Process terminated with status 1 (0 minutes, 3 seconds)
0 errors, 0 warnings
В чём может быть дело???
James DiGreze
11.03.2008, 09:14
Очень похоже на то, что sdcc не любит длинные имена файлов/каталогов, и может быть имена на русском.
Попробуй перекинуть файлы проекта типа на c:\proj\*.* и потом компильнуть.
ILoveSpeccy
11.03.2008, 15:48
Очень похоже на то, что sdcc не любит длинные имена файлов/каталогов, и может быть имена на русском.
Попробуй перекинуть файлы проекта типа на c:\proj\*.* и потом компильнуть.
Нет, не получается.
Попробовал вручную. написал скрипт для компиляции.
as-z80 -o crt0.o crt0.s
sdcc.exe main.c -mz80 --code-loc 0x8000 --data-loc 0xa000 --opt-code-size --no-std-crt0 crt0.o
pause
Получил файл main.ihx
Командой hex2bin main.ihx получил бинарник.
Что сразу заметил, размер .bin файла 22878 байт, когда в Speccy2007 всего 7314.
Запускаю boot.bin из архива Speccy2007, появляется "Press any key" и меню выбора снапшота.
Запускаю мною скомпиленый .bin - появляется в басике "0 OK, 0:1"
Ничего понять не могу :(
as-z80 -o crt0.o crt0.s
sdcc.exe -mz80 --opt-code-size -c main.c -o main.o
sdcc.exe --no-std-crt0 -mz80 --code-loc 0x8000 --data-loc 0xa000 crt0.o main.o -o boot
hex2bin.exe boot.ihx
pause
такое генерит codeblocks
проверь в настройках codeblocks
Settings -> Compilled & debugger -> SDCC -> Other settings -> Advanced settings -> Other -> Object file extension
болжно быть .o (помоему там .rel по умолчанию)
ILoveSpeccy
11.03.2008, 17:51
as-z80 -o crt0.o crt0.s
sdcc.exe -mz80 --opt-code-size -c main.c -o main.o
sdcc.exe --no-std-crt0 -mz80 --code-loc 0x8000 --data-loc 0xa000 crt0.o main.o -o boot
hex2bin.exe boot.ihx
pause
такое генерит codeblocks
проверь в настройках codeblocks
Settings -> Compilled & debugger -> SDCC -> Other settings -> Advanced settings -> Other -> Object file extension
болжно быть .o (помоему там .rel по умолчанию)
Спасибо!!!! Всё заработало!!! :D
Ха ...
Так что мой компилятор будет всё учитывать ...
Не надо все лепить в кучу, поработай с "Hisoft C", имхо не стоит реализовывать сразу всйо. Если ты писал на асме проги для Спека, то сам знаешь какие операторы и команды необходимы в первую очередь. Во всяком случае, в компиляторе спектрум-бэйсика я не рвался сразу реализовывать весь его словарь. Да хотя бы потому, что лишней памяти-то нет.
зы:
А кто-нибудь (в 1993-2002гг.) помышлял о том, чтобы написать Си-компилер на Спеке?
А кто-нибудь (в 1993-2002гг.) помышлял о том, чтобы написать Си-компилер на Спеке?
Помышлял, но дальше мыслей дело не дошло...
(В итоге упирался в "вилку", либо совместимость с оригинальным Си, либо скорость откомпилированного кода. Компромисс мне кажется не возможен...)
Barmaley_m
26.07.2008, 23:23
Компромисс возможен в виде настроек компилятора.
Например, в MS Visual Studio 2005 есть такие режимы компиляции кода, работающего с дробными числами: Fast (быстрый код) и Precise (точный, или совместимый). "Точный" код не является более точным в математическом смысле - он более точный лишь в смысле совместимости со стандартом Си.
Так, например, если идут вычисления с числами одинарной точности (float), то быстрее всего их провести на стеке сопроцессора в двойной точности, а результат перевести в одинарную. Такой код генерирует компилятор в случае опции "Fast". В случае "Precise" он будет после каждой операции огрублять числа до одинарной точности. И точность меньше, и быстродействие, зато - по стандарту.
А вообще я присоединяюсь к той точке зрения, что если кто-то желает произвести на свет хороший кросс-компилятор С для Z80, то надо брать существующие open-source проекты и отталкиваться от них. Создание компиляторов - сложная задача, и даже самый талантливый и амбициозный человек потерпит неудачу, если задумает одним махом создать хороший компилятор.
Как минимум, надо изучить теорию, почитать книги классиков. Теорию создания компиляторов. Теория - она для того и создается, чтобы облегчить практикам поиск конкретных решений.
И, конечно, писать компилятор на ассемблере (особенно - ассемблере не Z80) - полный абсурд. Приоритет при создании компилятора - не в его быстродействии, а в его надежности, портируемости и легкости понимания. Ведь программы компилируются один раз, и после этого уже не важно, быстрым ли был компилятор, который сгенерировал код.
И даже если цель стоит в максимальной оптимизации по быстродействию, то обычно имеет смысл написать и отладить алгоритм на языке высокого уровня, и лишь затем перевести его на ассемблер или еще что-нибудь.
И, конечно, писать компилятор на ассемблере (особенно - ассемблере не Z80) - полный абсурд. Приоритет при создании компилятора - не в его быстродействии, а в его надежности, портируемости и легкости понимания. Ведь программы компилируются один раз, и после этого уже не важно, быстрым ли был компилятор, который сгенерировал код.
Согласен с этой точкой зрения, полностью поддерживаю...
если нужон Си именно для спектрума и на спектруме, то это наверно только под ЦПМой можно найти. их там с пяток примерно..+ под тырдосом была какая то сятина..забыл название.
Под CP/M есть BD Software C compiler. Лучший, на то время. Кому нужно, легко найдет исходные тексты, благо они выложены автором.
К слову, написан на ассемблере i8080. Товарищу, собравшемуся писать компилятор должно быть интересно оценить размер кода. И это не просто без поддержки C99, но даже без плавучки и прототипов функций.
Теперь что касается соответствия ANSI/ISO и оптимальности целевого кода. Можно, конечно, ради этой оптимальности отойти от стандартов и заточить язык так, чтобы он удобнее ложился на целевую платформу, но:
1) это будет небольшим прогрессом, если сравнивать с макроассемблером и
2) это очень мало поможет в части качества кодогенерации.
Основа хорошей оптимизации в компиляторе -- реализация довольного сложного анализа входной программы. Кроме того, что очень трудно себе представить "быструю и надежную" реализацию на ассемблере, скажем, построения SSA-формы, нужно еще иметь в виду, что любой такой анализ требует много памяти.
Никто не замерял результаты dhrystone у разных компиляторов C для Z80? А то в интернетах только один результат приведён: http://www.csa.ru/CSA/Benchmarking/dhrytbl.shtmr
С для AVR и PIC (8бит) имеют весьма эффективный код хорошо оптимизированный.
Разница между чисто на асме не очень велика как в плане быстроты так и в плане размера, микроконтроллеры имеют ресурсы примерно такие же как и Спек. Кстати для AVR используется портированный GCC.
Естественно сам компиляторы работают на ПЦ. и генерят готовые прошивки.
Вот если б такой компилятор для z80...
уже тут говорили, скажу еще раз.
1. у авр куча регистров, как минимум поэтому его сложно адекватно сравнить с z80 (в плане компилятора си).
2. у пика вообще ппц архитектура. может компилер и "делает все возможное", но так или иначе, вменяемый компилятор си там не возможен. мне такое чудо как hi-tech picc для 16х пиков на спеке даром не надо.
Вот если б такой компилятор для z80...
а IAR чем не устраивает?
А MicroC? Он считается самым лучшим компилятором для PIC, правда сам PIC убогий.
Насчет AVR, плотно пользуюсь CodeVisionAVR, изучал генерируемый листинг на Асме.
Там используются в основном несколько регистров, а большинство (2-24) из 32 для хранения переменных. AVR не чистый RISC процессор. и регистры другие используются по разному, например, R31,R32 как HL, так, что не сильно то ушел от Z80. Единственно: у AVR простая команда выполняется за 1 такт, и при 16МГЦ тактировании получается 16000000 операций в секунду! Но все же код получается компактный. Кстати нашел я порт GCC для Z80, в ввиде патча, че с ним делать и как использовать непонял.
Он считается самым лучшим компилятором для PIC, правда сам PIC убогий.
ну вот ты сам все объяснил:) я не говорю, что hi-tech picc плохой, я о том, что сам пик такой, что вменяемый компилер под него сделать сложно.
Насчет AVR, плотно пользуюсь CodeVisionAVR, изучал генерируемый листинг на Асме.
аналогично:)
что касается распределения регистров - так это также зависит от компилируемой программы. поищи по форуму, здесь уже обсасывали особенности компиляторов, в частности gcc.
Error404
13.08.2009, 12:20
Кстати нашел я порт GCC для Z80, в ввиде патча, че с ним делать и как использовать непонял.
Вот тут написано, что это такое, что реализовано а что нет, и как собрать gcc для z80:
http://gcc.gnu.org/ml/gcc-patches/2001-06/msg01546/README
Кстати, хорошая тема - написать автору. Возможно у него за прошедшие 8 лет уже и что-то более доведенное до ума есть (и для более свежих gcc). Его имя и адрес можно взять отсюда:
http://gcc.gnu.org/ml/gcc-patches/2001-06/msg01546.html
Если что-то получится с gcc - сигнализируйте. Это интересно :)
не совсем понял, чего потом делать с компилированным ыфайлом в линухах? для куда он его компилит? в сна, или в тап или в трдос или как?...не шибко я силён в инглише..
http://gcc.fyxm.net/gcc/releases/gcc-2.95.2/ ссылка на нужную версию.
В принципе его по идее можно скомпилить и под винду.
Результат наверно будет бинарный файл. а вот с какого адреса хз, я не понял.
Ну а далее придется видимо как при образовывать в стандартный формат.
Короче дело это не простое...
Люди !! HELP!! может у кого осталось IAR EWZ80 кроскомпилер, поделитесь пож.
А то на оф. сайте его уже нет
Кинте ссылку (рабочую) в личку или в тему.
Заранее благодарен.
Люди !! HELP!! может у кого осталось IAR EWZ80 кроскомпилер, поделитесь пож.
А то на оф. сайте его уже нет
Кинте ссылку (рабочую) в личку или в тему.
Заранее благодарен.
Присоединяюсь! Мне тоже, пожалуста!
Error404
20.08.2009, 12:43
Присоединяюсь! Мне тоже, пожалуста!
И мне, пож! И по возможности ссылку на лекарство. :v2_rolley
вроде был куда-то нарезан, погляжу дома, если никто до этого не выложит
не знаю, что это...
http://slil.ru/27915142
__________________
wbw, psb.[/quote]
не знаю, что это...
http://slil.ru/27915142
__________________
wbw, psb.
Самое то, что нужно !
Большое человеческое СПАСИБО.
Увы, крякнуть эту версию не удается :(
Iccz80 формирует не стандартный OBJ файл,
а заставить родной линкер генерить HEX неудается
Может у кого есть FULL версия ??
Наконец-то нашел у китайцев.
Выложил на http://upload.com.ua/get/901006120/
Пользуйтесь, кому нужно.
Нашел куда положить. С этой рекламопомойки не качается.
---------- Post added at 13:22 ---------- Previous post was at 13:20 ----------
Мегабайтунг пер суткен.
Нашел куда положить. С этой рекламопомойки не качается.
Скажите куда лучше, я выложу.
Скажите куда лучше, я выложу.
Ну хотя бы сюда http://ifolder.ru/ или на рапиду.
Это полная крякнутая версия.
Выложил : http://ifolder.ru/13653352
HI-TECH C (Z80) Cross Compiler V7.80
Спасибо.
caro, Перезалейте пожалуйста , ссылка сдохла.
Перезалейте пожалуйста , ссылка сдохла.HI-TECH C (Z80) Cross Compiler V7.80
http://speccy.ifolder.ru/13960638
Aprisobal
26.09.2009, 03:30
http://gcc.fyxm.net/gcc/releases/gcc-2.95.2/ ссылка на нужную версию.
В принципе его по идее можно скомпилить и под винду.
Результат наверно будет бинарный файл. а вот с какого адреса хз, я не понял.
Ну а далее придется видимо как при образовывать в стандартный формат.
Короче дело это не простое... Попробовал скомпилировать. Процесс компиляции не завершился, но программы cc1 и xgcc уже были собраны. Отдал xgcc простейшую программу - cc1 вернул ему Segmentation fault.
Да и в компиляторе не реализовано умножение и деление, поэтому пользы от него ноль.
И на чём остановились?
Нужен Си компилятор, желательно с либами, и дружелюбным интерфейсом.
и дружелюбным интерфейсом.
А какой это может быть интерфейс у компилятора? О_о командная строка вроде как везде...
у IAR есть интерфейс (кроме ком. строки). но смысла в нем маловато...
кстати, кто-нить серьезно юзал иар? возможно в нем сделать общую секцию данных ДО секции банков? в доке написано что он поддерживает модель "наоборот".
у IAR есть интерфейс (кроме ком. строки). но смысла в нем маловато...
Не путай компилятор и IDE.
Не путай компилятор и IDE.
да я-то не путаю:)
А какой это может быть интерфейс у компилятора? О_о командная строка вроде как везде...
Нда, нагнал что то я про интерфейс. Избаловался с VS.
Какой есть компилятор с библиотеками под спек?
Скорость и компактность скомпилированного приложения не имеет значения, главное чтоб работало.
И желательно с русскими доками.
Нда, нагнал что то я про интерфейс. Избаловался с VS.
Вообще-то у VS компилятор тоже из командной строки работает.
Какой есть компилятор с библиотеками под спек?
Скорость и компактность скомпилированного приложения не имеет значения, главное чтоб работало.
И желательно с русскими доками.
Луркай на http://zx.pk.ru/showthread.php?t=5335
necroTrue
13.04.2010, 15:04
у вас ккой-то школьный холивар в последних коментах имхо.
языки высокого уровня нужны для задач высокого уровня.
это не есть труЪ-аутло ковырять чайной ложкой скалу, это признак глупости
зы. уже 2й раз читаю комменты с последней страницы трида, кидаю пост, а потом смотрю что это были далеко не последнии комменты. или ослеп или бажит сайтег
Нда, нагнал что то я про интерфейс. Избаловался с VS.
если к VS привык, думаю тебе будет удобнее IAR, но он вроде как платный
Результаты Dhrystone для разных компиляторов C для Z80 (пользуюсь формулой "DMIPS (Dhrystone MIPS) obtained when the Dhrystone score is divided by 1757" (http://en.wikipedia.org/wiki/Dhrystone) и привожу результаты к 3.5 MHz)
Hitech C v3.09 - 0.135 DMIPs (http://unixarchive.tliquest.net/local/unix/tmp/cpm/uzi-102/-README.)
IAR v4.06A (iar\iccz80 -v0 -ml -uua -q -e -K -gA -s9 -RCODE -t4 -T -Llist\ -Alist\ -I"iar/" dry.c) - 0.129 DMIPs (thanks to DimkaM!) или 0.125 DMIPs (thanks to deathsoft!)
SDCC v3.3.0 - 0.121 DMIPs (thanks to DimkaM!) или (v3.4.0 - эта версия пока нестабильна) 0.142 DMIPs (http://oneweekwonder.blogspot.ru/2013/12/z80-dhrystones.html) (проверено DimkaM)
Aztec C II - 0.0714 DMIPs (http://www.megalextoria.com/usenet-archive/news035f1/b55/net/micro/00012536.html ) или 0.0725 DMIPs (http://wiretap.area.com/Gopher/Library/Techdoc/Bench/dhryst.txt)
cc - 0.0455 DMIPs (http://www.csa.ru/CSA/Benchmarking/dhrytbl.shtmr)
Заодно нашёл таблицу сравнения бейсиков :) http://www.retroprogramming.com/2010/01/8-bit-home-computer-benchmarks.html
Добавил результат по IAR.
Добавил исходник от DimkaM (под ZX Evo).
Добавил новые данные по SDCC (надёжнее старых).
ZX_NOVOSIB
03.04.2014, 17:39
А можно посмотреть примеры игр, написанных на си? Си сильно уступает ассемблеру, применительно ко спектруму?
Есть два основных источника игр на Си для ZX:
1. Движок La Churrera для 48/128K (игры от Mojon Twins и некоторых других испанских авторов).
2. Движок Evo SDK для ATM Turbo 2/ZX Evo (игры XNX, Project R.O.B.O и др.)
Си на Z80 компилируется не очень эффективно. Вывод спрайтов пишется в любом случае на ассемблере, он входит в движок. Но в общем-то, игры писать можно. У меня есть исходники всех игр под Evo SDK, могу передать.
Alcoholics Anonymous
04.04.2014, 01:08
Есть два основных источника игр на Си для ZX:
1. Движок La Churrera для 48/128K (игры от Mojon Twins и некоторых других испанских авторов).
2. Движок Evo SDK для ATM Turbo 2/ZX Evo (игры XNX, Project R.O.B.O и др.)
Здравствуйте, просто проходил мимо, хотел посмотреть, как дела у наших друзей в России :)
Большинство игр на C написаны на z88dk, испрользуя спрайтовый движок sp1. Предшественник sp1 называется splib2, его использует Churrerra и Mojon Twins написали большую часть своих игр, используя его.
La Churrerra - это фреймворк для скриптов игр, похожий по своей сути на AGD. Основой Churrerra является splib2, используемый как спрайтовый движок.
Около 30 игр в архивах WOS написанных на z88dk с sp1/splib2. Вы, наверное, не знали, что они были написаны на С, но вот некоторые названия:
BeTiled
http://www.worldofspectrum.org/infoseek.cgi?regexp=^BeTiled!$&pub=^Computer+Emuzone$
Future Looter
http://www.worldofspectrum.org/infoseek.cgi?regexp=^Future+Looter$&pub=^Timmy$
Maritrini Freelance Monster Slayer
http://www.worldofspectrum.org/infoseek.cgi?regexp=^Maritrini%2c+Freelance+Monste r+Slayer$&pub=^Ubhres+Productions$
Phantomas Tales #4: Severin Sewers
http://www.worldofspectrum.org/infoseek.cgi?regexp=^Phantomas+Tales+%234%3a+Sever in+Sewers$&pub=^Ubhres+Productions$
Sgt Helmet Zero
http://www.worldofspectrum.org/infoseek.cgi?regexp=^Sgt.+Helmet+Zero$&pub=^Ubhres+Productions$
UWOL Quest for Money
http://www.worldofspectrum.org/infoseek.cgi?regexp=^Uwol%2c+Quest+for+Money$&pub=^Ubhres+Productions$
Здесь можно найти несколько простых примеров использования sp1 в z88dk:
http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/sprites/software/sp1/spectrum/examples/
English, I know the automatic translation will be bad:
Hello, just wandering past to see how our friends in Russia are doing
Most games in C are written with z88dk using the sp1 sprite engine. The predecessor of sp1 is called splib2, which is what Churrerra uses and is what the Mojon Twins write most of their games with.
La Churrerra is a scripting framework for games, similar in idea to AGD. Underneath Churrerra is splib2 which is the actual sprite engine.
Around 30 games are in the WOS archives written with z88dk and sp1/splib2. You probably were unaware they were written in C, but here are some titles:
BeTiled
http://www.worldofspectrum.org/infoseek.cgi?regexp=^BeTiled!$&pub=^Computer+Emuzo ne$
Future Looter
http://www.worldofspectrum.org/infoseek.cgi?regexp=^Future+Looter$&pub=^Timmy$
Maritrini Freelance Monster Slayer
http://www.worldofspectrum.org/infoseek.cgi?regexp=^Maritrini%2c+Freelance+Monste r+Slayer$&pub=^Ubhres+Productions$
Phantomas Tales #4: Severin Sewers
http://www.worldofspectrum.org/infoseek.cgi?regexp=^Phantomas+Tales+%234%3a+Sever in+Sewers$&pub=^Ubhres+Productions$
Sgt Helmet Zero
http://www.worldofspectrum.org/infoseek.cgi?regexp=^Sgt.+Helmet+Zero$&pub=^Ubhres +Productions$
UWOL Quest for Money
http://www.worldofspectrum.org/infoseek.cgi?regexp=^Uwol%2c+Quest+for+Money$&pub= ^Ubhres+Productions$
You can find some very simple examples of using sp1 in the z88dk source tree:
http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/sprites/software/sp1/spectrum/examples/
SDCC v3.3.0 - 0.121 DMIPs (thanks to DimkaM!) или (v3.4.0 - эта версия пока нестабильна) 0.142 DMIPs (http://oneweekwonder.blogspot.ru/2013/12/z80-dhrystones.html) (проверено DimkaM)
Получается, SDCC v3.4 по качеству кода сильно превосходит v3.3, и даже уделывает Hitec C. Однако мои исходники под 3.3. и 3.4 абсолютно одинаково компилятся :( Даже ассемблерные тексты один в один.
Надо игры в EvoSDK, что-ли, перекомпилить по 3.4 - может, тогда разница заметна будет.
Возможно, ускорение в 3.4 - из-за ошибок в компиляции. По Dhrystone это проверить невозможно.
Надо игры в EvoSDK, что-ли, перекомпилить по 3.4 - может, тогда разница заметна будет.
Возможно, ускорение в 3.4 - из-за ошибок в компиляции. По Dhrystone это проверить невозможно.
Ну что, новый SDCC, вполне себе, более компактный код генерит. Проверил на XNX: SPG, собранный (под TS-Config) на 3.4 на 1536 байт короче, чем на 3.3. SPG рабочий, хотя всю игру, конечно, не проходил. Желающие могут проверить, файл прилагается.
SPG рабочий, хотя всю игру, конечно, не проходил.
Здесь должна быть надпись "LEVEL 1"
Здесь должна быть надпись "LEVEL 1"
Верно! Глючокс. Вай-вай!
---------- Post added 15.04.2014 at 00:26 ---------- Previous post was 14.04.2014 at 23:27 ----------
Здесь должна быть надпись "LEVEL 1"
main.c:925: warning 196: pointer target lost const qualifier
levelData=levelsData[gameLevel];
комментарии специалистов?
Не работает инициализация для это переменной:
;main.c:801: static u8 str[]="LEVEL ";
нужен crt0.s
Не работает инициализация для это переменной:
;main.c:801: static u8 str[]="LEVEL ";
нужен crt0.s
.globl _main
.area _HEADER (ABS)
.org 0x0000 ;--code-loc 0x0006
init:
call gsinit
jp __pre_main
.area _CODE
__pre_main:
push de
ld de,#_HEAP_start
ld (_heap_top),de
pop de
call _main
di
halt
.area _DATA
_heap_top::
.dw 0
gsinit: .area _GSINIT
.area _GSFINAL
ret
.area _HEAP
_HEAP_start::
Попробуй такой. SDK надо пересобрать.
Попробуй такой. SDK надо пересобрать.
По-моему, нужно crt0 просто в .rel скомпилить и в SDK засунуть. Нет? Щас работу сделаю, - попробую.
По-моему, нужно crt0 просто в .rel скомпилить и в SDK засунуть. Нет? Щас работу сделаю, - попробую.
Blade, Твой crt решил проблему с надписью "LEVEL". Как я и предполагал, - нужно было просто твой crt0 скомпилить в rel и подставить вместо старого.
на всяк случай, кому если интересно нашёл ещё кросс компилятор, под винду.
https://www.dropbox.com/s/6f3v8g5l3pwj7jo/tcp61ez80-before.zip?dl=0
Error404, зачисти свою личку, а?!
HiSoftC
ПАМЯТКА ПО ИСПОЛЬЗОВАНИЮ
(лучше брать версию с редактором 51 символ в строке)
Загрузка/выгрузка исходников осуществляется в редакторе.
Переход в редактор: [CS+1], enter.
Работа с файлами возможна с ленты и дисководов.
Лента - устройство №0 ("0:" опускается при наборе команды).
Дисковод "А" - устройство №1,
Дисковод "B" - устройство №2. (дальше не пробовал. возможно работает с "С" и "D")
Загрузить исходник:
команда GET,
G ,,[device:]filename.c
Например, загрузить файл "test.c" с дисковода "A":
G ,,1:test.c
Причем, если у вас уже был какой-то текст, то загружаемый файл добавится к нему с перенумерацией строк (как по MERGE в бэйсике).
Записать исходник:
команда PUT,
P start_line,end_line,[device:]filename.c
Например, записать исходник со строки 10 по строку 50 включительно в файл "test2.c" на дисководе "B":
P 10,50,2:test2.c
Вывод каталога;
Команда X.
X [device]
Например, вывести каталог дисковода A:
X 1
Двоеточие после номера устройства можно не указывать.
Без параметров выводит каталог текущего диска.
Компиляция и запуск программы:
загрузили компилятор.
вошли в режим редактирования: [CS+1] enter.
загрузили исходник командой "G".
можно его просмотреть командой "L".
отредактировали, если требуется (замудреный неудобный процесс - проще строки заново вводить).
вышли в компилятор: команда "C".
набираем: "#include", enter.
наблюдаем прогон нашей программы.
жмем [SS+I]
соглашаемся - жмем "Y".
Профит!
Выгрузка объектного кода:
в режиме компилятора набираем:
"#translate [device:]object_name.code", enter.
"#include [device:]source_name.c", enter.
любуемся на прогон листинга
жмем [SS+I]
соглашаемся - жмем "Y".
объектный код записан на диск и запускается наша откомпилированная прога.
можно уже нажать на RESET, потому что после выполнения программы компилятор всё равно сбросится (так задумано)
Профит!
Примечание: расширения в файлах условны. Они для вас, а не для компилятора. Т.е. вы сами должны помнить,
где у вас исходные тексты, хедеры и объектники. Имена, всё равно, обрезаются до 8 символов и в TR-DOS
записываются как кодовые, с расширением "C".
Запуск откомпилированной программы из бэйсика:
1. загружаем файл программы с адреса 25200
2. заносим код 201 (команда RET) по адресу 25218 (а то всё улетит в космос).
3. вызываем код с адреса загрузки.
10 RANDOMIZE USR 15619:REM: LOAD "MYPROG" CODE
20 POKE 25218,201 : RANDOMIZE USR 25200
Профит!
Примечание: после отработки программа сбросится. Чтобы этого избежать, как рекомендует разработчик, выход
из программы необходимо завершать инструкцией DI:HALT:
inline(0xf3,0x76);
Ссылка на скан официальной документации (куча опечаток, но дарёному коню...): ftp://ftp.worldofspectrum.org/pub/sinclair/games-info/h/HiSoftC.pdf
Подсказки:
1. Чтобы присвоить указателю фиксированное значение, например адрес экрана и т.п., необходимо давать явное приведение типов, причём не так:
char *screen;
screen = (char *) 0x4000;
а, из-за упрощённости компилятора, так:
typedef char * this_is_char_ptr;
char *screen;
screen = cast ( this_is_char_ptr ) 0x4000;
ОШИБКИ КОМПИЛЯТОРА:
1. Файловый ввод/вывод для TR-DOS присутствует и работает (например, функции fopen/fclose, getc/ungetc/putc).
Но работают они только в присутствии самого компилятора, - в объектный код при компилировании НЕ включаются.
Получим вылет "в космос". Таким образом, чтобы программа отработала, как задумано, придётся каждый раз её
компилировать и запускать из среды HiSoftC.
Попробуй такой. SDK надо пересобрать.
странно, но при попытке собрать данный crt0, компилятор выдаёт несколько ошибок на строки типа:
call s__GSINIT
ld bc, #l__INITIALIZER
ld de, #s__INITIALIZED
ld hl, #s__INITIALIZER
транно, но при попытке собрать данный crt0, компилятор выдаёт несколько ошибок на строки типа:
Попробуйте добавить три строчки:
.globl l__INITIALIZER
.globl s__INITIALIZED
.globl s__INITIALIZER
т.е. у меня так (начало crt файла)
.module crt0
.globl _main
.globl l__INITIALIZER
.globl s__INITIALIZED
.globl s__INITIALIZER
.area _HEADER (ABS)
;;
.org 0x5000
jp init
;
init:
Информация из форума по sdcc, почему не пофиксили не знаю.
да, это я потом тоже нашёл. но вот что не могу понять и нигде не нахожу, это алгоритм по которому crt0 вообще прикручивается к компилируемому файлу. такое ощущение, что он прикручивается уже после main где или вообще где то в самом конце. пытаюсь сделать так, чтобы при сборке первыми байтами в файле бл заголовок ехе файла от спринтера. не лезет... что-то не так делаю или...?
crt0 должен быть первым в списке линкуемых модулей.
Т.к. crt0 содержит порядок следования сегментов, он должен быть строго первым, в коммандной строке, когда вызывается линкер.
Если линкеру первым файлом не дать crt0, то порядок сегметов скорее всего не будет соблюден. Это заметно только если смотреть map файл.
Эта инфа, про такие грабли, уже была много раз в форумах, но это нигде особо не написано в доках.
http://develissimo.com/forum/topic/3703/
crt0 должен быть первым в списке линкуемых модулей.
Т.к. crt0 содержит порядок следования сегментов, он должен быть строго первым, в коммандной строке, когда вызывается линкер.
Если линкеру первым файлом не дать crt0, то порядок сегметов скорее всего не будет соблюден. Это заметно только если смотреть map файл.
Эта инфа, про такие грабли, уже была много раз в форумах, но это нигде особо не написано в доках.
http://develissimo.com/forum/topic/3703/
вот кусок из evosdk
sdcc -mz80 --code-loc 0x0000 --data-loc 0x0000 --no-std-crt0 -I..\evosdk ..\evosdk\crt0.rel ..\evosdk\evo.rel --opt-code-speed main.c -o %temp%\out.ihx
а вот сам crt0
.module crt0
.globl _main
.globl l__INITIALIZER
.globl s__INITIALIZED
.globl s__INITIALIZER
.globl s__GSINIT
.area _HEADER (ABS)
.org 0x8100-512 ;--code-loc 0x0006
;init:
; call s__GSINIT
; jp __pre_main
.area _CODE
; заголовок для запуска в досе спринтера
.db 0x45,0x58,0x45
.db 0
.dw 0x200
.dw 0
.dw 0
.dw 0
.dw 0
.dw 0
.dw __pre_main
.dw __pre_main
.dw 0xbfff
.ds 490
;---------------------------------
__pre_main:
push de
ld de,#_HEAP_start
ld (_heap_top),de
pop de
call _main
di
halt
;; Ordering of segments for the linker.
.area _HOME
.area _CODE
.area _INITIALIZER
.area _GSINIT
.area _GSFINAL
.area _DATA
.area _INITIALIZED
.area _BSEG
.area _BSS
.area _HEAP
.area _DATA
_heap_top::
.dw 0
.area _GSINIT
gsinit::
.area _GSFINAL
ld bc, #l__INITIALIZER
ld a, b
or a, c
jr Z, gsinit_next
ld de, #s__INITIALIZED
ld hl, #s__INITIALIZER
ldir
gsinit_next:
ret
.area _HEAP
_HEAP_start::
при компиляции простого тестового main.c, его код при компиляции становится первым, после него только уже crt0.
при этом в строке компиляции в батнике параметры типа --code-loc должен указывать на 0x8100. т.е. в заголовке бинарника первые 512 байт досом будут откушены, код следующий за ним как раз и должен начинаться с 8100. а там соответственно должно быть бла бла call main и сам main должен быть ниже. при компиляции древнющим hi-tech-c всё так и есть. только он под цпм и файлы создаёт с кратностью 128байт..не удобна совершенно.
и ещё, там в crt0 часть именуемая как .area header (abs) после сборки из ihx или hex файлов в bin тупо исчезает. для получения бинарника делаю так:
packihx "%temp%\out.ihx" > "%temp%\out.hex"
hex2bin -p 0 -s some_addr "%temp%\out.hex"
Error404
19.03.2015, 18:43
Для сборки SDCC с самописным crt0, который должен идти первым в коде и в котором делалось org 100H (ибо для CP/M) я использовал такие ключи:
--code-loc 0x0198 --data-loc 0
где 98H (100H+98H=198H) - некий офсет как раз на размер кода crt0.
При этом объектные модули перечислялись последовательно, crt0 - первым.
Сам crt0 был примерно таким (в комментах "0x170" там от Конами/MSX остался, я переписывал кое что и у меня поэтому вырос до 0x198 ):
;--- crt0.s for MSX-DOS - by Konami Man, 11/2004
; Advanced version: allows "int main(char** argv, int argc)",
; the returned value will be passed to _TERM on DOS 2,
; argv is always 0x100 (the startup code memory is recycled).
; Overhead: 112 bytes.
;
; Compile programs with --code-loc 0x170 --data-loc X
; X=0 -> global vars will be placed immediately after code
; X!=0 -> global vars will be placed at address X
; (make sure that X>0x100+code size)
.globl _main
.area _HEADER (ABS)
.org 0x0100 ;MSX-DOS .COM programs start address
;--- Step 1: Initialize globals
init: ld hl,#initb
push hl
ld hl,#gsinit-1
inita: inc hl
ld a,(hl)
inc a
jr z,inita
jp (hl)
;--- Step 2: Build the parameter pointers table on 0x100,
; and terminate each parameter with 0.
; MSX-DOS places the command line length at 0x80 (one byte),
; and the command line itself at 0x81 (up to 127 characters).
initb: ld hl,(#6)
ld sp,hl ; set SP = TPA top
dec h ; HL=SP-256
ex de,hl ; de=parloop destination
;* Check if there are any parameters at all
ld a,(#0x80)
or a
ld c,#0
jr z,cont
;* Terminate command line with 0
; (DOS 2 does this automatically but DOS 1 does not)
ld hl,#0x81
ld bc,(#0x80)
ld b,h ; #0
add hl,bc
ld (hl),b ; #0
;* Copy the command line processing code to 0xC000 and
; execute it from there, this way the memory of the original code
; can be recycled for the parameter pointers table.
; (The space from 0x100 up to "cont" can be used,
; this is room for about 40 parameters.
; No real world application will handle so many parameters.)
ld hl,#cont ;To continue execution at "cont"
push hl ;when the routine RETs
push de ;next ret = jmp parloop
ld hl,#parloop
ld c,#parloopend-#parloop ; bc
ldir ; BC=0
;* Initialize registers and jump to the loop routine
ld hl,#0x81 ;Command line pointer
; ld c,#0 ;Number of params found
ld ix,#0x100 ;Params table pointer
ret
;>>> Command line processing routine begin
;* Loop over the command line: skip spaces
parloop: ld a,(hl)
or a ;Command line end found?
ret z
cp #32
jr nz,parfnd
inc hl
jr parloop
;* Parameter found: add its address to params table...
parfnd: ld (ix),l
ld 1(ix),h
inc ix
inc ix
inc c
ld a,c ;protection against too many parameters
cp #40
ret nc
;* ...and skip chars until finding a space or command line end
parloop2: ld a,(hl)
or a ;Command line end found?
ret z
sub a,#32
jr nz,nospc ;If space found, set it to 0
;(string terminator)...
ld (hl),a ;#0
inc hl
jr parloop ;...and return to space skipping loop
nospc: inc hl
jr parloop2
parloopend:
;>>> Command line processing routine end
;* Command line processing done. Here, C=number of parameters.
cont: ld hl,#_HEAP_start
ld (_heap_top),hl
ld hl,#0x100
ld b,l ;#0
push bc ;Pass info as parameters to "main"
push hl
;--- Step 3: Call the "main" function
call _main
;--- Step 4: Program termination.
; Termination code for DOS 2 was returned on L.
ld c,#0x62 ;DOS 2 function for program termination (_TERM)
ld b,l
call 5 ;On DOS 2 this terminates; on DOS 1 this returns...
ld c,#0x0
jp 5 ;...and then this one terminates
;(DOS 1 function for program termination).
;--- Program code and data (global vars) start here
;* Place data after program code, and data init code after data
.area _CODE
_bios:: ; uchar bios(int FuncNo, int Param)
_bioshl:: ; int bioshl(int FuncNo, int Param)
ld hl,#2
ld d,h ; d=0
add hl,sp
ld e,(hl) ; Func No
inc hl
inc hl
ld c,(hl)
inc hl
ld b,(hl) ; Parameter
ld hl,(#1)
add hl,de
add hl,de
add hl,de
ld a,#8
cp e
jr nz,abios
jp (hl) ; return HL (16 bit)
abios: ld de,#bbios
push de
jp (hl)
bbios: ld l,a ; return A (8 bit)
ret
.area _DATA
_heap_top::
.dw 0
gsinit: .area _GSINIT
.area _GSFINAL
ret
;* These doesn't seem to be necessary... (?)
;.area _OVERLAY
;.area _HOME
;.area _BSS
.area _HEAP
_HEAP_start::
---------- Post added at 18:43 ---------- Previous post was at 18:25 ----------
А вообче, связываться с SDCC - обрекать себя на фейл, причем который приходит неожиданно и после кучи потраченных дней.
sdcc -mz80 --code-loc 0x0000 --data-loc 0x0000 --no-std-crt0 -I..\evosdk ..\evosdk\crt0.rel ..\evosdk\evo.rel --opt-code-speed main.c -o %temp%\out.ihx
Строка правильная,
не знаю в чём проблема...
P.S.
У меня между .area _HEADER (ABS) и .area _HOME нет объявления никаких других .area
У вас же там есть .area _CODE, попробуйте удалить одну строку .area _CODE.
; jp __pre_main
.area _CODE удалить эту строку
; заголовок для запуска в досе спринтера
Error404,
А вообче, связываться с SDCC - обрекать себя на фейл, причем который приходит неожиданно и после кучи потраченных дней.
да ну как сказать. есть же народ который пользуется и вполне себе доволен. Хайтех, конечно, хороший компилятор, но уж сильно бесит как он толкает тупые конструкции в код. Например, просто пачка, целая серия jp для перехода на нужный адрес. Он их делает штук 5. Ещё раздражает, как он после вызова каких-то функций/процедур, после call func толкает ld h,h ld l,l. Не понимаю, зачем он это делает. оптимизатор у него не работает, значит получить оптимизацию по скорости или размеру не получится. С другой стороны, если не прокатит с sdcc, то видимо да, остаётся только юзать эмуль цпм и гонять хайтеха. вариант с z88dk - ну его в баню.
кстати, при компиляции получается набор файлов, среди которых ihx. чем ты его в бинар перегоняешь?
ТУТ немного примеров на SDCC http://zx-pk.ru/showthread.php?t=23473 от меня.
Многофайловая компиляция, библиотеки.
среди которых ihx. чем ты его в бинар перегоняешь?
srec_cat $SOURCE -intel -offset -0x5000 -o $TARGET -binary
http://srecord.sourceforge.net/
Есть утилита HEX2BIN. Очень простая и хорошая.
ТУТ должна быть http://zx-pk.ru/showthread.php?t=20047
Alcoholics Anonymous
19.03.2015, 20:43
размеру не получится. С другой стороны, если не прокатит с sdcc, то видимо да, остаётся только юзать эмуль цпм и гонять хайтеха. вариант с z88dk - ну его в баню.
кстати, при компиляции получается набор файлов, среди которых ihx. чем ты его в бинар перегоняешь?
Если вы хотели бы попробовать, у нас есть SDCC работы с z88dk. Все операции выполняются автоматически, с ЭЛТ специализируется на спектр, который уже включен.ЭЛТ настраиваемый по в исходных директив или файла конфигурации. Он заботится о всех данных и BSS инициализации секции, а также инициализацию кучи и, возможно, размещая драйверов на stdin/stdout/stderr.
Выход необработанных двоичных данных, к которым вы можете предварять заголовок, если это то, что вам нужно.
Пример:
#include <stdio.h>
#include <stropts.h>
#include <arch/spectrum.h>
#include <string.h>
#include <stdlib.h>
char buffer[100]; // max edit buffer size is 64
main()
{
unsigned int i;
zx_border(INK_WHITE);
ioctl(1, IOCTL_OTERM_CLS);
for (i=0; ; ++i)
{
printf("%5u %0#5x %I\n", i, i, i + ((unsigned long)(~i) << 16));
if (rand() > 32100)
{
printf("\nEnter a message:\n");
fflush(stdin);
scanf("%[^\n]", buffer);
printf("\nMessage received and reversed:\n%s\n\n", strrev(buffer));
}
}
}
zcc +zx -vn -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test
все, что нужно для компиляции с SDCC.Выход необработанных двоичных данных "test_CODE.bin" org 32768 по умолчанию.
Есть много вариантов CRT, выбранные, используя опцию "-startup = N", чтобы выбрать один по количеству.
zcc +zx -vn -startup=8 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test
выберет ЭЛТ с fzx водителя прилагается стандартный вывод (fzx является пропорциональная система шрифта, шрифт "Soxz" по умолчанию). Концевые водители настраиваемый и оконный.
Вы можете уменьшить размер исполняемого путем удаления вещи на ЭЛТ с помощью директив измените значения по умолчанию и при выборе ЭЛТ, который не имеет ничего, прикрепленный к stdin/stdout/stderr (-startup = 31)
#include <stdio.h>
#include <stropts.h>
#include <arch/spectrum.h>
#include <string.h>
#include <stdlib.h>
#pragma output CRT_ORG_CODE = 30000 // change ORG
#pragma output REGISTER_SP = 60000 // change location of stack
#pragma output CLIB_MALLOC_HEAP_SIZE = 0 // change size of heap
#pragma output CRT_ENABLE_RESTART = 1 // on exit restart program
// many more pragmas
char buffer[100]; // max edit buffer size is 64
main()
...
Мы ищем людей, чтобы помочь тест. Библиотеки в z88dk позволит вам сделать гораздо больше вещей, чем может быть сделано с один и с SDCC в качестве дополнительного генератора кода вы не должны терять качество кода SDCC.
Мы не имеем 64-разрядных целыми или с плавающей точкой, поддерживаемый с SDCC еще.
Вам нужна последняя ночную сборку отсюда:
http://nightly.z88dk.org/
Вы также должны модифицированную версию SDCC.Патч будет применен к официальной SDCC раз регрессии испытания прошли. В этом молнии является исполняемым окна и СВН патч, который может быть применен к источнику SDCC собрать на месте.
https://drive.google.com/open?id=0B6XhJJ33xpOWdkhJWFdRdlo3bWs&authuser=0
Если у вас возникли проблемы с SDCC, все происходит автоматически и легко z88dk. Есть, конечно, могут быть некоторые ошибки присутствуют :)
===========
If you would like to try it, we have sdcc working with z88dk. Everything is automatic, with crt specialized for the spectrum already included. The crt is highly customizable by in source pragmas or config file. It takes care of all the data and bss section initialization as well as initialization of the heap and optionally placing drivers on stdin/stdout/stderr.
The output is a raw binary to which you can prepend a header if that's what you need.
Example:
#include <stdio.h>
#include <stropts.h>
#include <arch/spectrum.h>
#include <string.h>
#include <stdlib.h>
char buffer[100]; // max edit buffer size is 64
main()
{
unsigned int i;
zx_border(INK_WHITE);
ioctl(1, IOCTL_OTERM_CLS);
for (i=0; ; ++i)
{
printf("%5u %0#5x %I\n", i, i, i + ((unsigned long)(~i) << 16));
if (rand() > 32100)
{
printf("\nEnter a message:\n");
fflush(stdin);
scanf("%[^\n]", buffer);
printf("\nMessage received and reversed:\n%s\n\n", strrev(buffer));
}
}
}
zcc +zx -vn -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test
is all it takes to compile with sdcc. The output is a raw binary "test_CODE.bin" org 32768 by default.
There are many crt variations chosen by adding a "-startup=N" option to choose one by number.
zcc +zx -vn -startup=8 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test
will choose a crt with fzx driver attached to stdout (fzx is a proportional font system, font "Soxz" is default). The terminal drivers are customizable and are windowed.
You can reduce the size of the binary by removing things from the crt using pragmas to alter the defaults and by choosing a crt that has nothing attached to stdin/stdout/stderr (-startup=31)
#include <stdio.h>
#include <stropts.h>
#include <arch/spectrum.h>
#include <string.h>
#include <stdlib.h>
#pragma output CRT_ORG_CODE = 30000 // change ORG
#pragma output REGISTER_SP = 60000 // change location of stack
#pragma output CLIB_MALLOC_HEAP_SIZE = 0 // change size of heap
#pragma output CRT_ENABLE_RESTART = 1 // on exit restart program
// many more pragmas
char buffer[100]; // max edit buffer size is 64
main()
...
We're looking for people to help test. The libraries in z88dk enable you to do many more things than can be done with sdcc alone and with sdcc as optional code generator you don't have to lose any code quality.
We do not have 64-bit ints or floating point supported with sdcc yet.
You need the latest nightly build from here:
http://nightly.z88dk.org/
You also need a modified version of sdcc. The patch will be applied to official sdcc once the regression tests have passed. Included in this zip is a windows executable and an svn patch that can be applied to sdcc source to compile locally.
https://drive.google.com/open?id=0B6XhJJ33xpOWdkhJWFdRdlo3bWs&authuser=0
If you're having trouble with sdcc, everything is automatic and easy with z88dk. Of course there may be some bugs present :)
А ещё, как узнать размер crt0.rel? т.е. сколько там кода накидано? не ручками же считать?
Error404
19.03.2015, 23:35
Error404,
да ну как сказать. есть же народ который пользуется и вполне себе доволен. Хайтех, конечно, хороший компилятор, но уж сильно бесит как он толкает тупые конструкции в код. Например, просто пачка, целая серия jp для перехода на нужный адрес. Он их делает штук 5. Ещё раздражает, как он после вызова каких-то функций/процедур, после call func толкает ld h,h ld l,l. Не понимаю, зачем он это делает.
Делает это он оттого, что:
Error404,
оптимизатор у него не работает,
не у него не работает, а у тебя не работает. :)
Тот же Юзикс + все либы + приложения, которые я собирал (а это под сотню тысяч строк кода) - все собрано с оптимизацией. Да, иногда оптимизатору не хватает памяти (он все же в 64к работает, а не в безразмерном ОЗУ РС), и надо исходник поделить на более мелкие части, да, он не все ассемблерные вставки съедает (их лучше вынести в другой модуль - их же глупо оптимизировать, сразу пиши оптимально свои ассемблерные блоки). Но на выходе результат не уступающий ассемблеру (ну, если по-крупному, без придирок), и уж повсякому в полтора раза лучше чем у SDCC как по объему, так и по качеству кода. И работает без нежиданностей, в отличие от. Утверждаю это, я Юзикс в дебагере прошагал вдоль и поперек пока запустил.
---------- Post added at 23:35 ---------- Previous post was at 23:28 ----------
А ещё, как узнать размер crt0.rel? т.е. сколько там кода накидано? не ручками же считать?
Я ручками считал: чего уж сложного - один раз скомпилировать "начерно" и в HEX посмотреть что куда легло.
не у него не работает, а у тебя не работает.
у меня при запуске optim.com в любом эмуляторе, хоть в линуксе, хоть в винде, он просто тупо молчит. файл подсунутый ему не меняется, ничего не происходит. пустой экран, без единой строчки. пробовал запускать его из разных комплектов/архивов. всегда одно и тоже. да же на профике. поэтому я плюнул и не пользуюсь им.
полтора раза лучше чем у SDCC как по объему, так и по качеству кода
про объём всё-таки сомнительно. я использую сейчас последний снапшот из репозитария. на фоне старых версий типа 2.9.0 (на котором был изначально evosdk) или 3.3.0, результаты очень интересные. код вполне компактный. Тем более, несколькими страницами ранее, Алоне Кодер проводил тесты производительности, не намного там между ними разница была, тем более, что sdcc он использовал старый. ну а главное преимущество - не нужны никакие эмуляторы, всё работает прям в винде из любого места, нет ограничений по памяти (TPA) и т.д. я ничего не говорю, с хайтехом я прошол и огонь и воду, знаю его фишки. Но, при портировании юзикса ты не мог не заметить местами в коде строки типа
// don`t change, HTC crazyness
и подобное. исходники такими строками нашпигованы. я одно время тоже с такими граблями столкнулся, не мог понять, почему компилятор то вылетает, то код получался не рабочий. а когда нашол исходники юзикса понял куда копать. не очень хочется разбираться каждый раз в чём проблема сборки.
да, это я потом тоже нашёл. но вот что не могу понять и нигде не нахожу, это алгоритм по которому crt0 вообще прикручивается к компилируемому файлу. такое ощущение, что он прикручивается уже после main где или вообще где то в самом конце. пытаюсь сделать так, чтобы при сборке первыми байтами в файле бл заголовок ехе файла от спринтера. не лезет... что-то не так делаю или...?
Я по таким мелочам не заморачиваюсь, в принципе.
Главное, что мне нужно от SDCC - получить откомпилированную с нужного адреса программу. А проблему, во что её "обернуть", т.е. заголовок добавить и т.п., я решаю с помощью отдельного "сборщика" на REXX, специального для каждого формата. Так, я в один-клик собираю прогу в SCL с boot, а также плагины для Wild Commander.
Если не чураешься REXX, могу написать тебе сборщик в нужный ком-файл. А также научу как настроить Code::Blocks для работы с SDCC и REXX, чтобы собирать твои файлы "в один клик".
Можешь, в общем, использовать вместо REXX питон, или ещё что - но тут - я не помощник.
Для пробы могу собрать ком-файл сам. Нужны исходники твоей проги и инфа по формату файла.
Если не чураешься REXX, могу написать тебе сборщик в нужный ком-файл.
не, не чураюсь. мне в целом всё ровно на чём скрипт написан. shell, bath, vbs, rexx, lua, python. всё ровно. под линуксом сейчас ничего не собираю. у меня все линуксы теперь это сервера. нет желания по ним шарится с целью компиляции. потому, всё что под виндой пашет, всё годится)))
А также научу как настроить Code::Blocks для работы с SDCC и REXX
этой штукой я не пользуюсь. я привык идти более сложным путём)))
у меня настроенный под z80 asm, c/c++, bath, vbs, lua самый обычный synwrite2 для total commander`а. в нём я накидываю текст, а потом если нужно, то запускаю батник или если нужно, то из консоли ручками и вылавливаю нужные ошибки, включая генерацию map, sym и lst файлов. в synwrit`е уже всё настроенно, со всякими табуляциями, пробелами, подсветка. с коде блокс я не очень хочу разбираться и что-то переделывать.
Для пробы могу собрать ком-файл сам.
даже не знаю. что там можно собрать. примитивный hello world чтобы собрать, нужно знать тсистемные вызова для работы с выводом от доса спринтера. хотя, именно консольный вывод в z88dk был поддержан по спринтеру. под все прочие компиляторы всё нужно писать с нуля. хотя, заголовок у exe файла вот такой:
ORG #8100-512
DB "EXE" ;EXE ID
DB #00 ;EXE VERSION
DW #0200 ;CODE OFFSET LOW
DW #0000 ;CODE OFFSET HIGH
DW #0000 ;END-BEG ;PRIMARY LOADER
DW #0000 ;
DW #0000 ;RESERVED
DW #0000 ;
DW #8100 ;LOAD ADDRESS
DW #8100 ;START ADDRESS
DW #BFFF ;STACK ADDRESS
DS 490
заголовок размером в 512 байт. обычно собирается под адрес не ниже 8000h (теоритически, можно и ниже, но я не пробовал). В этом заголовке можно оставлять всё как есть (в примере), только если бинарник не превышает размер области TPA. обычно, 32кб. если выше, тогда в область заголовка пихается свой загрузчик. таким образом снимается ограничение на размер исполняемого файла (хоть 100килобайт, хоть там сколько то мегабайт). поля обозначенные как load address и start address можно сделать так:
ORG #8100-512
DB "EXE" ;EXE ID
DB #00 ;EXE VERSION
DW #0200 ;CODE OFFSET LOW
DW #0000 ;CODE OFFSET HIGH
DW #0000 ;END-BEG ;PRIMARY LOADER
DW #0000 ;
DW #0000 ;RESERVED
DW #0000 ;
DW BEGIN ;LOAD ADDRESS
DW BEGIN ;START ADDRESS
DW #BFFF ;STACK ADDRESS
DS 490
BEGIN: ; some code
если в заголовке есть загрузчик. то заголовок имеет примерно такой вид:
; из flex navigator
EXEhead: db "EXE"
db 0 ; +3
dw EntryExec-EXEhead
dw 0x0000 ; +4
dw EXEend-EntryExec ; +8
dw 0, 0 ; +10
dw 0 ; +14
dw EntryExec ; +16
dw EntryExec
dw 0x80FF
EntryExec: ; тут начинается код загрузчика
исходников проги на си как таковых сейчас нет. я взялся за разбор evosdk под спринтера. при чём в перерыве от основного проекта (который на си явно не прокатит).
хотя, у меня есть исходник одной цпм проги, которую давно на спринтера хотел перекинуть. fdisk под профика. но под спринтера чтобы его запустить. нужно все "консольные" функции перебрасывать. могу его тебе заслать, но он всё ровно на спринтере работать не будет))))
не, не чураюсь. мне в целом всё ровно на чём скрипт написан.
Приятно удивлён. :)
у меня настроенный под z80 asm, c/c++, bath, vbs, lua самый обычный synwrite2 для total commander`а... запускаю батник...
Тем проще, вместо батника будешь запускать REXX-скрипт. Ставь Regina REXX.
даже не знаю. что там можно собрать. примитивный hello world чтобы собрать, нужно знать системные вызова для работы с выводом от доса спринтера.
Это не мои проблемы ;)
хотя, именно консольный вывод в z88dk был поддержан по спринтеру.
Мне всё равно, чем ты будешь компилить - можно и z88dk прикрутить, и асм. Я, к слову, освоил собирать сишные проги под Спек почти любым CP/M-ным компилятором.
исходников проги на си как таковых сейчас нет. я взялся за разбор evosdk под спринтера.
Как напишешь, - так напишешь. Я не тороплю ;)
Я, к слову, освоил собирать сишные проги под Спек почти любым CP/M-ным компилятором.
интересно. как решаешь проблему последних 128 байт в конце файла? просто режешь всё начиная от кода eof (1Ah)?
мне вот ещё интересно, а кто-то вообще пользовался этим evo-sdk? или всё что есть из написанного это три примера из пакета? был ещё, кажется, бомберман, но не помню, "на сдк" он написан или нет.
интересно. как решаешь проблему последних 128 байт в конце файла? просто режешь всё начиная от кода eof (1Ah)?
Никак пока не решаю - они ж не мешают. Да и не юзаю я их: просто умею. Попробовал ради эксперимента. Для работы мало пригодны: 1) K&R синтаксис (кроме HiTech), 2) по качеству кода они все одинаково ни в какое сравнение не идут с SDCC. Но, в общем, их можно использовать.
Надо, наверное, выложить здесь эти комплектики. Может, кто-то и заморочится на связку cp/m-эмулятора и REXX.
мне вот ещё интересно, а кто-то вообще пользовался этим evo-sdk? или всё что есть из написанного это три примера из пакета? был ещё,
Hippiman (http://zx-pk.ru/showthread.php?t=20220&highlight=ROBO), должно быть, Денис Грачев.
Blade (Sergey78?) адаптировал evo-sdk под TS-Config. По-моему не менее 5 игрушек написано с помощью SDK.
кажется, бомберман, но не помню, "на сдк" он написан или нет.
бомбермен писан на асме и исключительно под TS-Config. К evo-sdk отношения не имеет.
Hippiman (http://zx-pk.ru/showthread.php?t=20220&highlight=ROBO), должно быть, Денис Грачев.
глянул. интересно, но таааак тормозно и под sdcc 3.4.0 не собирается. последний crt0 не помагает (выдаёт две ошибки, что не может инициализировать какие то переменные и потом ещё две ошибки, что размер не известен и кирдык).
Blade (Sergey78?) адаптировал evo-sdk под TS-Config
видел такое, но это немного другое. в самомо сдк из игр только котоксоникс и две лёгкие демки - шарики и слайдшоу. ROBO получается ещё одна игра. пока других не слышал. был ещё uwol, но нет уверенности, что оно под сдк. там или под z88dk (оригинал под него писан) либо там уже всё на асме. исходников evo/ts версии я не видел.
Никак пока не решаю - они ж не мешают.
это сильно мешает, когда в конце кода начинаешь размещать какие то ресурсы. лишние сколько-то байт всю малину портят.
Error404
20.03.2015, 13:24
у меня при запуске optim.com в любом эмуляторе, хоть в линуксе, хоть в винде, он просто тупо молчит. файл подсунутый ему не меняется, ничего не происходит. пустой экран, без единой строчки. пробовал запускать его из разных комплектов/архивов. всегда одно и тоже. да же на профике. поэтому я плюнул и не пользуюсь им.
Я не знаю как ты этого добился. Может просто не так вызываешь? Глянь мои make-файлы на предмет параметров.
У меня оптимизатор HitechC на версии v3.09 (CP/Mовская бесплатная) работал всегда, что на реале Орионе, что на Винде под эмулятором (причем под несколькими разными эмуляторами).
Разница была только в том, что на реале Орионе меньше места в ТПА и соответственно меньшие исходники проглатывает оптимизатор (чаще пишет "out of memory"), поэтому я использую PC(WIN)-эмулятор CP/M c максимальным ТРА (порядка 63кб).
Попробуй ту версию HitechC, что размещена в моей темке по UZIX, там и эмулятор уже в общем архиве.
На LINUX я не пробовал.
Но, при портировании юзикса ты не мог не заметить местами в коде строки типа
// don`t change, HTC crazyness
и подобное. исходники такими строками нашпигованы. я одно время тоже с такими граблями столкнулся, не мог понять, почему компилятор то вылетает, то код получался не рабочий.
Все подобное я нимало не беспокоясь много раз "change" и все прекрасно компилировалось и работало, никакого "crazyness".
Я писал в своей темке по портированию: авторы Юзикса собирали его не на публичной бесплатной V3.09 (потому что на ней их исходники сразу искаропки тупо не собираются, тупо нет таких операторов какие там используются - исходники пришлось поправить), а на какой-то другой (подозреваю на платной и мультиплатформенной Z80/Z180/8086 версии 5.х, жившей в конце 90-х, а сейчас платные HitechC уже 7-ю версию перешагнули).
---------- Post added at 13:24 ---------- Previous post was at 13:15 ----------
Кстати, то что ты запускаешь на Профи, может играть отрицательную роль. Hitech C использует некоторые вызовы от CP/M 3.x (какие-то вызовы для работы с датой с номерами около сотни). И соответственно если твоя "допиленная" Q-DOS пересекается по этим вызовам, но возвращает не FF как нормальная CP/M 2.2 для несуществующей функции, а напротив при таком вызове какую-нибудь несовместимую с СРМ 3.x отсебятину делает, то это может влиять, как мне кажется.
А что касается SDCC, то подбираясь к пятому десятку прожитых лет, я перестал верить что продукт однажды попробованный (к тому времени продукту, на секундочку, уже десяток лет) и сформировавший устойчивое мнение "написано недоумками", может в какой-то новой версии через пару лет стать конфеткой. Потому что если у людей системная проблема с мышлением, это не лечится и всегда где-нибудь вылезет неожиданным и неприятным образом, угробив кучу моего времени.
на счёт сборки Libc от юзикса, там только в одном месте есть употребление "не нашей" директивы inline asm - в syscalls. старый htc про такое не знает. легко превращается в asm текст и собирается через as.com. в остальных исходниках я не замечал ничего сверхъестественного. кстати, интересно. вот он рабочий порт. а что дальше? чем всё закончилось? есть какой-то "не стоковый" софт?
А что касается SDCC
хорошо. т.е. по твоему только HTC 3.09 является исключительным компилятором? и никаких других больше нельзя использовать? что ты скажешь про z88dk, особенно про ночные сборки? или, например, про iar?
в данной теме многие пришли к противоположному выводу касательно sdcc - продукт годный к употреблению. я пока не могу что-то конкретное сказать. потраченного времени, в целом, не жалко. Хотя почитал комент от Ширу по теме evosdk. там описана причина использования старого sdcc. ну, значит не судьба вкарячить последнюю версию. я прекрасно знаю что такое хайтех, но хотелось бы иметь инструмент работающий не под эмулем с кучей ограничений, а нормальный, под винду. скачал я последнюю версию z88dk, собрал два простых теста - hello world и демку aes256 (которая собирается влёт на хайтехе!). hello весит 1937байт, демка весит 9463 байта. многовато.
и кстати, в отличии от цпм, мне разрешено получать запускаемые файлы, в целом, неограниченного размера. т.е. зависимости между запускаемым файлом и размером tpa у меня нет. htc не даёт такой свободы. sdcc, видимо, тоже.
Error404
20.03.2015, 15:18
на счёт сборки Libc от юзикса, там только в одном месте есть употребление "не нашей" директивы inline asm - в syscalls. старый htc про такое не знает. легко превращается в asm текст и собирается через as.com. в остальных исходниках я не замечал ничего сверхъестественного. кстати, интересно. вот он рабочий порт. а что дальше? чем всё закончилось? есть какой-то "не стоковый" софт?
В ядре было полным полно этих операторов asm(). Плюс какие-то объявления сегментов, которые не понимает ассемблер. вроде еще что-то было несовместимое на уровне директив препроцессора.
А где есть нестоковый софт? :)
Если не брать в расчет CP/M как признанного тяжеловеса для которого писал без преувеличния ВЕСЬ МИР в течении пары десятилетий, c точки зрения всех известных мне самописных ОС для Z80, на UZIX пожалуй поболее всего будет, сравнимо с легендарной UNIX Seventh Edition (UZIX по сути и есть "семерка"). Что-то ни один хакер за прошедшие 35 лет не пожаловался на то, что в "семерке мало стока" .
А дальше - что напишешь, тем и богат. Как по мне, то это только плюс. Плюс, портировать можно что приглянется.
Я возлагаю надежды и на FUZIX - оттуда можно будет делать обратный порт когда они наконец то раскачаются. Правда пока там приложений меньше чем в UZIX.
хорошо. т.е. по твоему только HTC 3.09 является исключительным компилятором? и никаких других больше нельзя использовать? что ты скажешь про z88dk, особенно про ночные сборки? или, например, про iar?
IAR я не нашел бесплатных версий, или хотя бы с беспроблемным краком. Поэтому с ним не знаком, ничего не могу сказать. z88dk на момент моего с ним знакомства (2008-2009 год) был одним из самых неэффективных компиляторов для Z80 и привлекал только наличием какой-то реализации TCP/IP. Про глюки тогдашнего z88dk сказать не могу, т.к. переключился на SDCC, в котором тоже разочаровался.
Положа руку на сердце, хорошего компилятора С для Z80 нет. Потому что то, что для Hitech C приходится исходники "подрихтовывать" тоже не радует. Но учитывая когда он написан, в какой минималистической среде живет, и качество его кода, в сравнении с современными это конечно недостижимый образец.
Если не брать в расчет CP/M как признанного тяжеловеса
не не. цпм это цпм, юзикс это юзикс. если подумать, то какая практическая польза от юзикса? ядро большое и медленное. я не буду говорить за Орион, но, к примеру, порт под ту же "evo". какая там может быть польза? сомнительно, что она там может быть. игры? демы? тот же запилятор (тьфу, блин)?! маловероятно. вот он есть на Орионе и, вот его нет. только если для галочки, для фана. лучше уж тогда игрушку написать.
про z88dk, кто-то из разрабов тут выше отписывал, что какие то работы ведутся. если честно, не понятно что там изменилось. да, действительно, под зетника нет нормального компилятора.
кстати, ты можешь более детально пояснить, что в sdcc тебе не понравилось? какие версии использовал?
Error404
20.03.2015, 19:02
не не. цпм это цпм, юзикс это юзикс. если подумать, то какая практическая польза от юзикса? ядро большое и медленное. я не буду говорить за Орион, но, к примеру, порт под ту же "evo". какая там может быть польза? сомнительно, что она там может быть. игры? демы? тот же запилятор (тьфу, блин)?! маловероятно. вот он есть на Орионе и, вот его нет. только если для галочки, для фана. лучше уж тогда игрушку написать.
Ну, игрушек тоже что-то никто не написал, в т.ч. и на evosdk ничего играбельного не было - по сути только демонстрашки что evosdk хоть что-то может. Такие игрушки на Орионе на С делали в начале 90-х (например ranger) безо всяких sdk и SDCC, а нативно на Орионе на простом С-компиляторе под Ордос. (понимаю, что для спектрумиста это звучит как набор букв :) )
И фан - это очень немаловажно. Кроме того, это растущий класс программиста. Писать под UZIX это ровно то же, что писать под любой Юникс (я например в молодости довольно много писал на C под AIX, а до того - под OpenVMS). Вот впилю туда TCPIP (а именно туда и надо впиливать, т.к. только там есть нормальная многозадачность и нормальная - на уровне ОС - реализация очередей/блокировок/консоли), и будет это единственная ОС на Z80 c нормальной поддержкой сети (не считая того же UZIX c MCX от которой потеряны исходники). И это будет реальное преимущество над любой ОС для Z80, которого сейчас для обычного пользователе не видно. Учитывая, что и CPM тож унаследуем - сам же знаешь, на UZIX есть эмулятор CP/M, надо только опять же сесть и адаптировать его нормально в мой дистриб - то это будет нормальная ОС с кучей ПО, многозадачная, многопользовательская и сетевая. А то что для нее надо 10Мгц (а лучше 20Мгц), так это путь немного голова у наших аппаратчиков поболит, а то тоже нихрена не делают.
Просто пока мне интереснее приложения поковырять. Я уже накачал десятка три того что хотелось бы портировать, все они непростые (объемные). Так что фана у меня запланировано на десятилетие вперед. :) Да и вообще на всех бы хватило, только не хочет никто (как никто не пишет игры, не пишет демодроч. Ничего никто не пишет). Я сам бы хотел раз в неделю что-нить новенькое для Ориона скачивать "на побаловаться", но - увы, всё сам.
про z88dk, кто-то из разрабов тут выше отписывал, что какие то работы ведутся. если честно, не понятно что там изменилось. да, действительно, под зетника нет нормального компилятора.
кстати, ты можешь более детально пояснить, что в sdcc тебе не понравилось? какие версии использовал?
Использовал такое крайний раз:
>sdcc --version
SDCC : mcs51/gbz80/z80/z180/r2k/ds390/pic16/pic14/TININative/ds400/hc08 3.1.4 #7
479 (Mar 23 2012) (MINGW32)
Не понравилось то, что при сборке из одного и того же исходника, HitechC мне собрало работоспособные httpd и telnetd (я тогда развлекался портированием uIP), a SDCC собрал частично работающих, но зависающих непонятно почему уродов в полтора раза большего размера (при всех включенных оптимизациях).
---------- Post added at 18:52 ---------- Previous post was at 18:38 ----------
Я считаю, на Эволюшен и на АТМ обязательно надо портировать UZIX. Да и на Спринтер. С большими страницами процессов. Если не ошибаюсь, они же умеют переключать страницы озу куском по 64к (включая сразу 4 окна диспетчера по 16к)? Надо бы Алония подключить. А то выпилили с форума единственного программера и сидят как сычи.
Ибо как показал опыт FUZIX на Спеке-128, 16к на процесс -это очень мало, особенно если использовать это чудо - SDCC.
---------- Post added at 19:02 ---------- Previous post was at 18:52 ----------
Чтобы не показаться совсем необъективным, отмечу что препроцессор у SDCC лучше чем у Hitech C - SDCC умеет распутывать такие заковыристые макросы, от которых у Hitech едет крыша. Например - Contiki весь на этих заковыристых макросах построен (те самые уродские ПротоТреды). Но тут опять же до смешного доходит: к Контики идет целая телега какими версиями SDCC оно компилируется, какими не компилируется, какими компилируется но не работает. Для FUZIX тоже - только определенная версия SDCC годится. :v2_dizzy_facepalm:
ндэээ, это всё сплошной гемор. да, что примечательно, есть исходники которые на htc собираются влёт. опять-таки, тот же literatecode (aes256). sdcc отказался с ним работать. я не стал вникать в причины. но, что примечательно - z88dk собрал его с правкой всего 5 или 6 функций (прототипы выправил). и запускается на спринтере. но размер - 9.8кб...
Я сам бы хотел раз в неделю что-нить новенькое для Ориона скачивать "на побаловаться",
а что мешает так же взять и что-то игровое или демодроч. забацать?
кстати, давно спросить хотел - какой порядок расположения "модулей" в lib файле? я тут как то пересобирал под её и накосячил с порядком.
Error404
20.03.2015, 21:34
а что мешает так же взять и что-то игровое или демодроч. забацать?
Я не люблю работать с графикой. Вообще не люблю. И рисую плохо. Все эти пикселы... Даже знакогенератор/фонт в редакторе поправить - сразу приступ тошноты. :)
В молодости делал текстовые игрушки типа Президента, но только пока не втянулся в системное программирование, от которого меня прет. Не знаю почему так.
кстати, давно спросить хотел - какой порядок расположения "модулей" в lib файле? я тут как то пересобирал под её и накосячил с порядком.
А в какой? Под CP/M или под Юзикс? Там разные модули.
В целом, если у тебя есть образцовая либа, порядок должен быть примерно такойже как показывает "libr s libname". Общее правило: если из модуля идут вызовы других функций этой же либы, то этот модуль должен добавляться в либу раньше, чем модули которые он вызывает (они идут позже).
---------- Post added at 21:34 ---------- Previous post was at 21:15 ----------
но размер - 9.8кб...
Размер небольшой программы во многом зависит от того как написан stdio (все эти printf/scanf/putc/getc). Поэтому helloworld где в main() всего один вызов, на одном компиляторе будет одного размера, а на другом - другого, т.к. у них разные либы (там тупо разный функционал реализован - более или менее полный. Например, могут отсутствовать редиректы, а могут присутствовать). А вот большие вычислительные программы, это да - уже можно судить о том хорошо ли компилятор оптимизирует именно код.
Alcoholics Anonymous
20.03.2015, 22:35
Я хотел бы в полной мере участвовать, но языковой барьер действительно трудно преодолеть :(
English in spoiler tags.
скачал я последнюю версию z88dk, собрал два простых теста - hello world и демку aes256 (которая собирается влёт на хайтехе!). hello весит 1937 байт, демка весит 9463 байта. многовато.
Есть несколько вещей, здесь отметить. В текущем z88dk имеются два независимых C библиотеки - первый старый, с которым вы можете быть знакомы (двоичный размер 1937 байт мала и означает, что вы использовали, чтобы старый), а второй новый, который стремясь к подгруппе С11. Это новый был полностью переписан с нуля на языке ассемблера и была сделана совместим с SDCC.
Кроме того, вы можете использовать любой sccz80 или SDCC для компиляции С, но при использовании SDCC можно использовать только новую библиотеку С.
There are a couple of things here to note. In the current z88dk there are two independent c libraries -- the first the old one with which you may be familiar (a binary size of 1937 bytes is small and indicates you have used to old one) and the second is the new one which is aiming for a C11 subset. This new one has been completely rewritten from scratch in assembler and has been made compatible with sdcc. In addition you can use either sccz80 or sdcc to compile the C. But when using sdcc you can only use the new c library.
Helloworld.c
// SCCZ80
// zcc +zx -vn -clib=new helloworld.c -o helloworld
//
// SDCC (LIBRARY USES IX)
// zcc +zx -vn -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 helloworld.c -o helloworld
#include <stdio.h>
main()
{
printf("Hello World\n");
}
Программа настолько коротка, что не имеет значения, если она скомпилирована с sccz80 или SDCC.
Вот что я получаю:
The program is so short that it doesn't matter if it is compiled with sccz80 or sdcc. Here's what I get:
2015-03-20 11:46 AM 0 helloworld
2015-03-20 11:43 AM 267 helloworld.c
2015-03-20 11:46 AM 6,666 helloworld_CODE.bin
Выход 6666 байт.
Но мы можем сделать его меньше.ЭЛТ создания кучи для таНос, что нам не нужно, это создание выездной стек нам не нужно, это создание STDIO кучу нам не нужно (мы не FOPEN FILEs). Другие значения по умолчанию уже установлены для гх цели исправить размер таблицы дескрипторов файлов и других вещей.
Чтобы избавиться от этих вещей, которые я добавить некоторые прагмами на источник:
The output is 6666 bytes. But we can make it smaller. The crt is creating a heap for malloc that we don't need, it's creating an exit stack we don't need, it's creating a stdio heap we don't need (we don't fopen FILEs). Other defaults already set for the zx target fix the size of the file descriptor table and other things. To get rid of these things I add some pragmas to the source:
// Helloworld2.c
#pragma output CRT_ORG_BSS = -1
#pragma output CLIB_EXIT_STACK_SIZE = 0
#pragma output CLIB_MALLOC_HEAP_SIZE = 0
#pragma output CLIB_STDIO_HEAP_SIZE = 0
#include <stdio.h>
main()
{
printf("Hello World\n");
}
Орг для сегменте BSS заставляет его быть записаны в отдельном файле, так что она не является частью двойной системы. Я, вероятно, не стоит заключать надоели с этим, но это делается.
Теперь я получаю:
The org for the BSS segment causes it to be written to a separate file so that it is not part of the binary. I probably shoud not have bothered with that but it is done. Now I get:
2015-03-20 12:10 PM 0 helloworld2
2015-03-20 12:10 PM 430 helloworld2.c
2015-03-20 12:10 PM 8 helloworld2_BSS.bin
2015-03-20 12:10 PM 5,383 helloworld2_CODE.bin
Вплоть до 5383 байт.
Мы до сих пор не сделано. Printf поддерживает следующие преобразователи: %d, %u, %x, %X, %o, %n, %i, %p, %B (binary), %s, %c, %I (IPv4 address), %ld, %lu, %lx, %lX, %lo, %ln, %li, %lp, %lB (binary).
Сколько из них действительно использует наша программа? Ни один. Так что я удалить их из библиотеки, редактируя файл clib_cfg для серии ZX цели:
http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/target/zx/clib_cfg.asm?revision=1.11&view=markup
Я могу изменить линию 247 в "defc __CLIB_OPT_PRINTF = 0". Это можно выбрать, какие именно преобразователи вы хотите быть доступны.
После этого изменения я должен восстановить библиотеку. С z88dk / libsrc / _DEVELOPMENT я запускаю "Winmake ZX" С окна командной строки.
Теперь я получаю это для размера программы:
Down to 5383 bytes. We're still not done. printf supports the following converters: %d, %u, %x, %X, %o, %n, %i, %p, %B (binary), %s, %c, %I (IPv4 address), %ld, %lu, %lx, %lX, %lo, %ln, %li, %lp, %lB (binary). How many of these does our program use? None. So I remove them from the library by editing the clib_cfg file for the zx target: http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/target/zx/clib_cfg.asm?revision=1.11&view=markup I change line 247 to "defc __CLIB_OPT_PRINTF = 0". It's possible to select exactly which converters you want to be available. After that change I have to rebuild the library. From z88dk/libsrc/_DEVELOPMENT I run "Winmake zx" from a windows command prompt. Now I get this for the program size:
2015-03-20 12:16 PM 0 helloworld3
2015-03-20 12:11 PM 430 helloworld3.c
2015-03-20 12:16 PM 8 helloworld3_BSS.bin
2015-03-20 12:16 PM 3,699 helloworld3_CODE.bin
Вплоть до 3699 байт из 6666 байт.
Если это все еще слишком велик для вас, вы должны задаться вопросом, если вам нужно Printf. Учтите, что z88dk необходимо предоставить драйверы для стандартного ввода, стандартный вывод, стандартный поток ошибок. Printf посылает потокового на стандартный вывод и водитель там должно пары, чтобы стандартного ввода, чтобы позволить возможности редактирования линия. Так что это водитель Printf не только печатает символы, это позволяет редактировать линии, прокрутка текста окна, подает звуковой сигнал, эмуляции терминала и т.д. Это не просто RST $ 10, хотя вы могли бы написать такой драйвер. Мы не имеем, как мы сначала писать все, независимо от любого системного программного обеспечения.
Одна вещь, вы можете сделать, это удалить все драйверы, поэтому нет ничего прикреплены к стандартного ввода, стандартный вывод, стандартный поток ошибок. У нас есть такой лучевой трубки, которая может быть выбрана с "-startup = 31" на линии компиляции. Если мы уберем STDOUT мы не можем использовать Printf больше так вместо этого мы можем использовать sprinf () для печати в буфер, который вы можете затем вывести на экран с вашей собственной небольшой рутины.
Down to 3699 bytes from 6666 bytes. If this is still too large for you, you need to wonder if you need printf. Consider that z88dk needs to provide drivers for stdin, stdout, stderr. printf is sending streamed output to stdout and the driver there needs to couple to stdin to allow line editing capabilities. So this printf driver not only prints chars, it enables line editing, scrolling, text windows, beeps, terminal emulation, etc. It's not a simple RST$10 although you could write such a driver. We haven't as we are first writing everything independently of any system software. One thing you can do is remove all the drivers so there is nothing attached to stdin, stdout, stderr. We have such a crt which can be selected with "-startup=31" on the compile line. If we remove stdout we can't use printf anymore so instead we can use sprinf() to print into a buffer which you can then output to the screen with your own small routine.
// SCCZ80
// zcc +zx -vn -startup=31 -clib=new helloworld4.c -o helloworld4
//
// SDCC (LIBRARY USES IX)
// zcc +zx -vn -startup=31 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 helloworld4.c -o helloworld4
#pragma output CRT_ORG_BSS = -1
#pragma output CLIB_EXIT_STACK_SIZE = 0
#pragma output CLIB_MALLOC_HEAP_SIZE = 0
#pragma output CLIB_STDIO_HEAP_SIZE = 0
#include <stdio.h>
char buffer[20];
main()
{
sprintf(buffer, "Hello World\n");
}
Я не показывая пользовательского процедуру печати, которые будут принимать "буфер" и вывод на экран. Вы можете себе представить то, что занимает десяток байт, если вы используете RST 10 $.
Теперь вот что я получаю:
I am not showing a custom print routine that will take "buffer" and output to the screen. You can imagine something that takes a dozen bytes if you use RST$10. Now here's what I get:
2015-03-20 12:29 PM 0 helloworld4
2015-03-20 12:29 PM 483 helloworld4.c
2015-03-20 12:29 PM 29 helloworld4_BSS.bin
2015-03-20 12:29 PM 535 helloworld4_CODE.bin
С 6666 байт до 550!
... слишком долго, так будет продолжаться и в следующем посте
... too long so will continue in next post
Alcoholics Anonymous
20.03.2015, 22:56
... продолжал
С 6666 байт до 550!
Существует много всего происходит с водителями, связанных на стандартный вывод, стандартный ввод и т.д., чтобы такие вещи, как редактирование текста и линий окон. Если вы не нужны эти вещи, которые вы не должны использовать их.
Вы не должны действительно быть глядя на то, как Printf и говорят "6666 байт! Слишком много!". Это может быть, но вы должны помнить, что z88dk и SDCC используете, связывающие монтажников. Что-то вроде Printf тянет во многих библиотеки кода, чтобы сделать что-то вроде разделения, число-> преобразования текста, и т.д., и этот код будет повторно использоваться любой другой C код, который вы пишете. Так что если вы PRINTF что-то, а затем разделить два числа подразделение будет использовать тот же код деления, как Printf делает.
From 6666 bytes down to 550! There is a lot going on with the drivers connected to stdout, stdin, etc to allow things like line editing and text windows. If you don't need those things you don't have to use them. You shouldn't really be looking at something like printf and saying "6666 bytes! Too much!". It may be but you have to remember that z88dk and sdcc are using linking assemblers. Something like printf is pulling in a lot of library code to do things like division, number->text conversion, etc, and this code will be reused by any other C code that you write. So if you printf something and then divide two numbers the division will use the same divide code as printf does.
Сообщение от Sayman Посмотреть сообщение
но размер - 9.8кб...
Размер небольшой программы во многом зависит от того как написан stdio (все эти printf/scanf/putc/getc). Поэтому helloworld где в main() всего один вызов, на одном компиляторе будет одного размера, а на другом - другого, т.к. у них разные либы (там тупо разный функционал реализован - более или менее полный. Например, могут отсутствовать редиректы, а могут присутствовать). А вот большие вычислительные программы, это да - уже можно судить о том хорошо ли компилятор оптимизирует именно код.
Это несколько верно, но соединительные монтажники, что SDCC и использование z88dk гарантировать, что только код, который называется входит в двоичном виде. Призыв к Е () не тянет в коде для зсапЕ (), например. Однако есть и более глубокая связь на уровне ЭЛТ. Если у вас есть стандартный ввод, стандартный вывод эти два потока в сочетании с строки редактирования требует общения между входным терминалом и выходным терминалом. Таким образом, некоторые код библиотеки тянут в поддерживать редактирование линии, когда сама программа С не может использовать зсапЕ (). Если размер программы очень важно, вы можете уменьшить требования к памяти, заменяя простые драйверы на стандартный вывод, например, или отказаться от всего потока стандартного ввода, стандартный вывод, как я сделал выше и просто ограничивать себя sscanf и Sprintf.
Я отправлю еще один пример того, что может быть сделано с библиотеками позже, что демонстрирует пропорциональных шрифтов в текстовых окнах. Существует большая разница между библиотеками z88dk и всех других компиляторы. Это качество кода компилятора самой C, что люди жалуются, и именно поэтому мы работаем с SDCC, чтобы SDCC использовать z88dk библиотеки.
This is somewhat true but the linking assemblers that sdcc and z88dk use ensure that only the code that is called is included into the binary. A call to printf() does not pull in code for scanf() for example. However there is a deeper connection at the crt level. If you have stdin, stdout these two streams are coupled since line editing requires communication between the input terminal and the output terminal. So some library code is pulled in to support line editing when the C program itself may not use scanf(). If program size is important you can reduce the memory requirements by substituting simpler drivers on stdout, for example, or forego all of stdin, stdout as I did above and just confine yourself to sscanf and sprintf. I'll post another example of what can be done with the libraries later on that shows off proportional fonts in text windows. There is a large difference between the libraries in z88dk and all other c compilers. It's the code quality of the C compiler itself that people complain about and that is why we have been working with sdcc to allow sdcc to use the z88dk libraries.
Что касается качества кода, SDCC улучшилась много в прошлом году.То же самое с библиотеками в z88dk. Оба проекта видели большой рост в последнее время и, конечно, всегда есть больше, чтобы сделать.
With regards to code quality, sdcc has improved a lot in the past year. The same goes with the libraries in z88dk. Both projects have seen a lot of growth recently and of course there is always more to do.
Alcoholics Anonymous
21.03.2015, 06:38
Я отправлю еще один пример того, что может быть сделано с библиотеками позже, что демонстрирует пропорциональных шрифтов в текстовых окнах.
https://drive.google.com/file/d/0B6XhJJ33xpOWR3RLekZzX1F2WXc/view?usp=sharing
Два fzx выходные клеммы создаются, один с шрифтом "префект", а другой с шрифта "RoundelSerif". Существует один входной терминал прикреплен к выходной клемме с меньшим шрифтом.
То же случайный текст напечатан на обоих выходных клемм и через случайные интервалы, текст с клавиатуры и записывается в другой выходной клемме.
Чтобы сделать это демо, я создал новый ЭЛТ с двумя выходными клеммами и один вход. Мы создаем ЭЛТ с помощью винтов M4 макросов.Шаблон я использовал:
http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/target/zx/startup/zx_crt_ram.m4?revision=1.1&view=markup
который является шаблоном для 48k барана ZX. Я заменил строки 73-84 с моими собственными экземпляров драйверов:
Two fzx output terminals are created, one with font "Prefect" and another with font "RoundelSerif". There is one input terminal attached to the output terminal with the smaller font.
The same random text is printed to both output terminals and at random intervals, text is read from the keyboard and written to the other output terminal.
To make this demo, I created a new crt with two output terminals and one input terminal. We create crts using m4 macros. The template I used is:
http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/target/zx/startup/zx_crt_ram.m4?revision=1.1&view=markup
which is a template for the 48k ram zx. I replaced lines 73-84 with my own driver instantiations:
include(../../clib_instantiate_begin.m4)
include(../driver/terminal/zx_01_input_kbd_inkey.m4)dnl
m4_zx_01_input_kbd_inkey(_stdin, __i_fcntl_fdstruct_1, 0x03b0, 64, 1, 500, 15)dnl
include(../driver/terminal/zx_01_output_fzx.m4)dnl
m4_zx_01_output_fzx(_window_1, 0x2330, 0, 0, 1, 14, 1, 19, 0, _ff_ao_Prefect, 14, 0, 14, 8, 112, 8, 152, 1, 0, 3, 0)dnl
include(../driver/terminal/zx_01_output_fzx.m4)dnl
m4_zx_01_output_fzx(_window_2, 0x2330, 0, 0, 16, 14, 3, 19, 0, _ff_ao_RoundelSerif, 26, 0, 26, 128, 112, 24, 152, 1, 0, 3, 0)dnl
include(../../clib_instantiate_end.m4)
Эти драйверы относятся к файловым дескрипторам 0, 1, 2 и данного файла * по имени стандартного устройства ввода, window_1 и window_2. Аргументы двумя выходными клеммами определить окно, цвет, шрифт и указать, что окно будет прокручиваться, не останавливаясь.
После определения того, что водители экземпляра, я сделал ЭЛТ, запустив m4 на него и создания ЭЛТ с уникальным именем:
These drivers are assigned to file descriptors 0, 1, 2 and are given FILE* named stdin, window_1 and window_2. The arguments to the two output terminals define the window, colour, font and indicate that the window will scroll without pausing.
After defining what drivers are instantiated, I made the crt by running m4 on it and creating the crt with a unique name:
m4 zx_crt_ram.m4 > zx_crt_200.asm
Затем я добавил zx_crt_200 к файлу zx_crt.asm используемой серии ZX цели:
http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/target/zx/zx_crt.asm?revision=1.13&view=markup
путем вставки этого в файле:
I then added zx_crt_200 to the zx_crt.asm file used by the zx target:
http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/target/zx/zx_crt.asm?revision=1.13&view=markup
by inserting this into the file:
IF startup = 200
; three terminal windows on screen
;
; stdin = zx_01_input_kbd_inkey (connected to window_1)
; window_1 = fzx terminal (font = Prefect)
; window_2 = fzx terminal (font = RoundelSerif)
INCLUDE "startup/zx_crt_200.asm"
ENDIF
Имея это в месте, где я могу выбрать, что ЭЛТ с "-startup = 200" на линии компиляции.
Программа C прост:
With that in place I can select that crt with "-startup=200" on the compile line.
The C program is simple:
// sccz80
// zcc +zx -vn -startup=200 -clib=new fzx_term2.c -o fzx_term2
//
// sdcc
// zcc +zx -vn -startup=200 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 fzx_term2.c -o fzx_term2
#include <stdio.h>
#include <stropts.h>
#include <arch/spectrum.h>
#include <stdlib.h>
#include <string.h>
extern FILE *window_1;
extern FILE *window_2;
main()
{
static int i;
static char buffer[100];
zx_border(INK_BLACK);
zx_cls(INK_GREEN | PAPER_GREEN);
ioctl(1, IOCTL_OTERM_CLS);
ioctl(2, IOCTL_OTERM_CLS);
while (1)
{
// fill buffer with random letters
memset(buffer, 0, 100);
for (i = rand() % 100; i >= 0; --i)
buffer[i] = (char)((rand() % ('z' - ' ')) + ' ');
// print to both windows
fprintf(window_1, "%s\n", buffer);
fprintf(window_2, "%s\n", buffer);
// gather input
if (rand() > 32200)
{
fprintf(window_1, "\nEnter some text: ");
fflush(stdin);
scanf("%99[^\n]", buffer);
i = ioctl(2, IOCTL_OTERM_FCOLOR, INK_YELLOW | PAPER_BLUE);
fprintf(window_2, "\n%s\n\n", buffer);
ioctl(2, IOCTL_OTERM_FCOLOR, i);
}
}
}
Вы можете видеть, что вы можете печатать на клеммах определенных ЭЛТ, и вы можете настроить терминалов во время выполнения с помощью IOCTL ().
Я вижу ошибку в терминальной кода, что атрибуты подвергаются воздействию ниже текстовых окон. Это может быть ошибка в шрифтах или в fzx водителя, который я должен буду смотреть.
Я не ожидал, что кто следуют за этим, это просто указание на различие между минимальным едва функциональной библиотеки (SDCC) или простой зависит от операционной системы (HiTech) и одной, которая пытается быть полным (z88dk).
При сравнении размеров кода, вы также должны иметь в виду, компилятор, как ВЫСОКОТЕХНОЛОГИЧНЫЙ полагается на операционную систему для обеспечения функциональности. Таким образом, ее бинарные может занять определенный размер, но это также делает использование кода операционной системы, которые могут быть 8k или более в размере, который скрыт от выходного двоичного файла. бинарные z88dk являются полностью независимыми и могут существовать отдельно от любой операционной системы. У вас есть возможность писать драйверы, использующие программное обеспечение системы, но мы не сделали, что еще для новой библиотеки.
В ZIP Вы также можете сравнить выход АНМ, порожденную SDCC и sccz80 по исследуются файлы "fzx_term2_sdcc.asm" и "fzx_term2_sccz80.opt". В этом случае SDCC скомпилированные бинарные файлы 13514 байт и sccz80 скомпилированные бинарные файлы 13185 байт. При использовании статических переменных, я сделал sccz80 произвели код лучше. Другие различия связаны с SDCC необходимости IX сохранились и конвенций призвание sccz80 быть гораздо лучше.
Далее ~ 5k может быть сбрил, делая то же рода вещей, которые я сделал в прошлом посте.
You can see that you can print to the terminals defined by the crt and you can configure the terminals at runtime via ioctl().
I can see a bug in the terminal code in that attributes are being affected below the text windows. It may be an error in the fonts or in the fzx driver that I will have to look into.
I don't expect anyone to follow this, it's just an indication of the difference between a minimal barely functional library (sdcc) or a simple one reliant on the operating system (hitech) and one that tries to be complete (z88dk).
When comparing code sizes, you also have to keep in mind a compiler like hitech is relying on the operating system to provide functionality. So its binaries may occupy a certain size but it's also making use of operating system code that might be 8k or more in size that is hidden from the output binary. z88dk's binaries are completely independent and can exist apart from any operating system. You do have the option to write drivers that use the system software but we haven't done that yet for the new library.
In the zip you can also compare the asm output generated by sdcc and sccz80 by examing the files "fzx_term2_sdcc.asm" and "fzx_term2_sccz80.opt". In this case the sdcc-compiled binary is 13514 bytes and the sccz80-compiled binary is 13185 bytes. By using static variables, I've made sccz80's produced code better. The other differences have to do with sdcc needing ix preserved and the calling conventions of sccz80 being much better.
A further ~5k can be shaved off by doing the same sorts of things I did in the last post.
Alcoholics Anonymous, this is all good, but i need worked library for Sprinter. I can see - z88dk have small (for console and file io) Sprinter support (pps config). ok, but i can`t understand library source structure for make gfx library. Hi-Tech C and sdcc have many simple lib src structure. if you have some docs for make libs, please, give me...
and pps_lib, as i think, very old. clib_ix or clib_iy is not support Sprinter. need to rewrite it for add Sprinter. and if we speech for new generation zx clones, then need to support zx-evolution to.
Что ещё могу сказать: При попытке пересобрать библиотеки под windows 7, получаю 100500 ошибок. ваш makefile не совместим с windows. нет тут команды rm, а ключи для системных команд нужно задавать через символ / например, для rm -f эквивалент будет del /f. так же пути в makefile указаны через обратный slash, как в linux, в то время как в windows для указания пути используют \, а не /. и так по мелочам косяков хватает. адаптируйте для windows версии все makefile. опять таки - скудная документация по библиотекам и самому компилятору.
Error404, спросить ещё хотел, у хайтеха в асми тексте при задании области через defs, область не инициализируется линкером. всегда заполняется кодом 1Ah. а надо бы нулями. не знаешь, чё ему надо?
Error404
22.03.2015, 11:17
Error404, спросить ещё хотел, у хайтеха в асми тексте при задании области через defs, область не инициализируется линкером. всегда заполняется кодом 1Ah. а надо бы нулями. не знаешь, чё ему надо?
Ну, такая особенность ассемблера. Объявления через defs не инициализируются. Если надо занулить, просто объявляй их как "psect bss" - эта область обнуляется при старте программы из модуля crt (т.к. странно тащить в коде программы кучу нулевых массивов, увеличивая размер бинаря - это практически на всех реализациях С так сделано). Если надо ненулевые инициализированные переменные, то через defw/defb
Ну, такая особенность ассемблера. Объявления через defs не инициализируются. Если надо занулить, просто объявляй их как "psect bss" - эта область обнуляется при старте программы из модуля crt (т.к. странно тащить в коде программы кучу нулевых массивов, увеличивая размер бинаря - это практически на всех реализациях С так сделано). Если надо ненулевые инициализированные переменные, то через defw/defb
очень интересно, а размер области тогда как задать? у меня 490 байт нулей в заголовке без загрузчика должно быть, иначе дос на спринтере выплюнет такой файл.
Ещё момент, часто при компиляции в хайтехе нарываюсь на один и тот же варнинг:
declared implicit int (warning)
и второй:
illegal conversion of pointer to integer (warning)
например, выдаёт вот на таком месте:
static char *icvt(register char *cp)
{
ival = atoi(cp);
while(isdigit((unsigned)*cp))
cp++;
return cp;
}
ругается вот так:
22: cp++;
^ isdigit() declared implicit int (warning)
117: if(isupper(c)) len = sizeof(long)/sizeof *a;
isupper() declared implicit int ^ (warning)
вроде всё нормально, но ему что-то не нравится. как ты такое решаешь?
да, это я потом тоже нашёл. но вот что не могу понять и нигде не нахожу, это алгоритм по которому crt0 вообще прикручивается к компилируемому файлу. такое ощущение, что он прикручивается уже после main где или вообще где то в самом конце. пытаюсь сделать так, чтобы при сборке первыми байтами в файле бл заголовок ехе файла от спринтера. не лезет... что-то не так делаю или...?
Пляши, Sayman :)
Решил я твою проблему. Даже скрипт не понадобился.
Проблема была в том, что ты хедер exe-файла не в ту секцию положил, а нужно, непосредственно ПЕРЕД меткой 'init:'.
Вот так:
; CRT startup module for Sprinter DOS executable by Amixgris. 22.03.2015.
.module crt0
.globl _main
.area _HEADER (ABS)
.org 0x7f00 ;--code-loc = 0x8100 + 0x20 = 0x8120
; воообще для получения значения --code-loc нужно к адресу запуска прибавить
; размер стартапа от метки init до конца процедуры _exit. 0x20 - прибавлено с запасом.
.ascii 'EXE'
.db 0
.dw 0x200
.dw 0
.dw 0
.dw 0
.dw 0
.dw 0
.dw init
.dw init
.dw 0xc000
.ds 490
init:
;; Initialise global variables
; ld sp,#0x0000
call gsinit
call _main
jp _exit
_exit::
1$:
halt
jr 1$
.area _HOME
.area _CODE
.area _INITIALIZER
.area _GSINIT
.area _GSFINAL
.area _DATA
.area _INITIALIZED
.area _BSEG
.area _BSS
.area _HEAP
.area _CODE
.area _GSINIT
gsinit::
ld bc, #l__INITIALIZER
ld a, b
or a, c
jr Z, gsinit_next
ld de, #s__INITIALIZED
ld hl, #s__INITIALIZER
ldir
gsinit_next:
.area _GSFINAL
ret
Далее. Если у тебя Спринтер запускает код с 0x8100, то ПОЧЕМУ ты значение --code-loc выставляешь в 0x0000?! code-loc должен начинаться ЗА процедурой инициализации, а не перед ней. Здесь инит занимает 12 байт, т.о. codе-lock = 0x7f00 + 0x200 + 0x0c = 0x810c. В этом свете, мне кажется, что "в лоб" адаптировать evo-sdk на Sprinter нельзя - она компилится с 0x0000. А твой екзешник не может с 0x0000 стартовать.
Но ты можешь надергать оттуда процедур, и что-нибудь написать, чтоб уместилось с 0x8100 до 0xc000, включая стэк.
Компилить exe для Sprinter DOS надо так:
Один раз компилим crt0-файл, чтобы получить "crt0.rel":
sdasz80 -g -o crt0.s
Затем каждый раз:
sdcc -c - mz80 my_exe_for_Sprinter.c
sdcc -mz80 --code-loc 0x8120 --data-loc 0x0000 --no-std-crt0 crt0.rel my_exe_for_Sprinter
hex2bin my_exe_for_Sprinter.ihx
Переименуешь расширение с bin на exe, и будет тебе счастье ;)
Да, оформление выхода в DOS оставляю за тобой. Пока там вечный цикл.
Sergey, это, конечно, спасибо (пошёл плясать :) )! я с sdcc пока не очень дружу. Однако, в лоб evosdk я не собирался адаптировать. в том виде как она сейчас есть, мне сильно не нравится. например, что почти все куски либы написаны на sjasm и собраны банально в bin файл. вся это громада, 8 с лишним килобайт, обязательно загружается. таким образом в этом sdk есть ложка дёгтя - минимальный размер собранного проекта, даже пустого, будет весить не менее 9кб (код либы+код того, что успел нагадить сам sdcc). меня это не устраивает. есть механизм линковки объектных файлов. те же lib файлы. если процедура не нужна, её в коде никогда не будет (если её не тянет какая-то другая процедура). в этом плане данный сдк сильно коряв. я как раз хочу перетащить всё в нормальные библиотеки. пока воюю с хатехом. с ним я знаком и там привычнее.
ещё одним недостатком сдк является то. что оно использует заведомо известные страницы. т.е. проект забирает под себя любую страницу, какую захочется. в досе на Спринтере такой подход не работает. есть системный механизм выделения памяти. соответственно, работа с памятью требует сильного вмешательства, не только под порты, но и по работе с "динамически" выделяемыми страницами. Аксель ещё везде.
Error404
22.03.2015, 17:21
очень интересно, а размер области тогда как задать? у меня 490 байт нулей в заголовке без загрузчика должно быть, иначе дос на спринтере выплюнет такой файл.
Раз нули должны быть в psect text, тогда используй "defw 0". Поскольку v3.09 несет весьма убогий ассемблер ZAS (ну как убогий, надо понимать: он же для С-компилятора, а не для удобного программирования на сыром ASM) и не знает про "документированный" макрос REPT c которым было бы просто:
REPT 245
defw 0
ENDM
То надо написать что-то такое:
defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0
defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0
defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0
defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0
defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0
defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0
defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0
Ещё момент, часто при компиляции в хайтехе нарываюсь на один и тот же варнинг:
declared implicit int (warning)
Это оттого что функция не объявлена, а все необъявленные функции или переменные для С - это int. Найди заголовочный файл где она объявлена и включи его по #include, или объяви сам как "extern ...."
и второй:
illegal conversion of pointer to integer (warning)
Это или опять из-за невключеного хидера или из-за ошибки/неаккуратности в коде
Alcoholics Anonymous
22.03.2015, 19:42
Alcoholics Anonymous, this is all good, but i need worked library for Sprinter. I can see - z88dk have small (for console and file io) Sprinter support (pps config). ok, but i can`t understand library source structure for make gfx library. Hi-Tech C and sdcc have many simple lib src structure. if you have some docs for make libs, please, give me...
and pps_lib, as i think, very old. clib_ix or clib_iy is not support Sprinter. need to rewrite it for add Sprinter. and if we speech for new generation zx clones, then need to support zx-evolution to.
Для "классического" z80 библиотеки и графики поддержки, другой разработчик лучше спросить об этом у z88dk форумах, как я не так много с ним делать. Одна из проблем, что мы (как в не-русский) не слишком хорошо знакомы с Sprinter и других новых российских машин. Языковой барьер делает его трудно понять, как именно это работает. Sprinter, например, могут быть использованы как Spectrum, но он также имеет и другие родные графические режимы, какой-то простой растрового и, возможно, аппаратные спрайты?
Я не думаю, что это трудно быстро добавить цель спринтер спектра мод на новый C Library без диска IO. Позвольте мне попробовать, что сегодня и, возможно, вы можете, дайте мне знать, где я сделал ошибки. Одна вещь, я не уверен, о том, что ORG по умолчанию должно быть и будет ли указатель стека устанавливается ОС спринтер к стоимости, указанной в этом заголовке 512 байт. Я также не уверен, о размещении командной строки в памяти, но я оставлю это при первом проходе.
Вы правы по поводу отсутствия документации в настоящее время, в частности, о новой библиотечной. Это слишком для того чтобы иметь любое письменное еще!
For the 'classic' z80 library and graphics support, another developer is better to ask about it at the z88dk forums as I don't have much to do with it. One problem is we (as in non-Russian) are not too familiar with the Sprinter and other new Russian machines. The language barrier makes it hard to understand exactly how things work. The Sprinter, eg, can be used like a Spectrum but it also has other native graphics modes, some kind of simple blitter and maybe hardware sprites?
I don't think it is hard to quickly add a spectrum mode sprinter target to the new c library without disk io. Let me try that today and maybe you can let me know where I've made mistakes. One thing I am not sure about is what the default ORG should be and whether the stack pointer is set by the sprinter's OS to the value listed in that 512-byte header. I'm also not sure about the placement of the command line in memory but I will leave that out at first pass.
You are right about the lack of documentation currently, especially about the new c library. It is too new to have any written yet!
Q-Master
22.03.2015, 22:01
Что ещё могу сказать: При попытке пересобрать библиотеки под windows 7, получаю 100500 ошибок. ваш makefile не совместим с windows.
Для таких штук лучше юзать не мэйкфайлы ибо там 100500 ifdef будет. Проще переписать, к примеру, на cmake. Ну или собирать под cygwin каким-нить.
... пока воюю с хатехом. с ним я знаком и там привычнее.
Ну, раз так, будь добр, поделись настройками HiTech C для хорошего кода.
Речь же о версии 3.09 для cp/m? Пробовал его "в общем порядке" - сгенереный код ничем не отличается от кучи других компиляторов тех лет.
Sergey, я по совету Еррора перепроверил доку на предмет работы оптимизатора, перепроверил то, что я ему скармливал и пришёл к выводу, что всё время я ему пытался скормить файлы получаемые от p1.com. он же генерирует подобие "байткода", который потом нужно скормить cgen, который потом выдаст асм листинг. я и не думал, что оптимизатору нужно именно его подсовывать. я думал, байткодовый файл оптимизатору нужен. устранив свой же косяк я увидел ооочень хорошо оптимизированный код. ну как оптимизированный, на фоне того, что он генерит до оптимизации, это оптимизация. да и sdcc явно не лучше даёт код ну или в крайнем случае, рядом где-то ходят. самое простое, пример с hello world, без оптимизатора:
psect text
global _main
_main:
global ncsv, cret, indir
call ncsv
defw f38
global _printf
ld hl,19f
push hl
call _printf
ld hl,2
add hl,sp
ld sp,hl
l3: jp cret
f38 equ 0
psect data
19: defb 72,101,108,108,111,32,119,111,114,108,100,33,33,33 ,10,0
а это с оптимизатором:
global _main
global ncsv, cret, indir
global _printf
psect text
_main:
ld hl,19f
push hl
call _printf
pop bc
ret
psect data
19: defb 72,101,108,108,111,32,119,111,114,108,100,33,33,33 ,10,0
psect text
тем более, если говорить про тот же evosdk, то там используется старая версия sdcc, а с новой, говорят. косяки. у меня у самого не получается нормально заставить нормально работать сдк с новым sdcc.
... тем более, если говорить про тот же evosdk, то там используется старая версия sdcc, а с новой, говорят. косяки. у меня у самого не получается нормально заставить нормально работать сдк с новым sdcc.
Надеюсь, ты добавил еще одно подчеркивание к "_asm", "_endasm" и "_naked" в исходниках evo-sdk? ;) У меня всё работает:
http://zx-pk.ru/showpost.php?p=702247&postcount=100
Правда, там надо было crt0.s поправить. и заработало как надо: http://zx-pk.ru/showpost.php?p=702743&postcount=107
Вот здесь есть EVO-SDK (под TS-Config, правда) переделанная под SDCC v.3.x.x.
http://forum.tslabs.info/viewtopic.php?f=28&t=211&start=25
C 3.4.0 будет работать. Почитай тред - увидишь, какие были проблемы с переводом.
Sergey, я незнаю. crt0 я тоже правил. мелкие проектики из пакета сдк собрались. а вот ксоникс, с ним пришлось попарится, но в итоге оно заработало, хотя при сборке выдавало несколько варнингов. а вот robo, там даже автор в теме про игру пишет, что тоже не смог пересобрать под 3.х.х.
не знаю почему, но хайтеховый оптимизатор нагло выкидывает из кода строку с halt. например, делаю ei halt, оптимизатор выкидывает halt. свинья!!!
Error404
24.03.2015, 09:15
не знаю почему, но хайтеховый оптимизатор нагло выкидывает из кода строку с halt. например, делаю ei halt, оптимизатор выкидывает halt. свинья!!!
А еще он выкидывает RET. Ну выкидывает и выкидывает, подумаешь. Я же писал: ассемберные процедуры компилируй без оптимизации в отдельном объектном модуле. Оптимизатор там для оптимизации его собственных С-транслированных конструкций, в которых не предусмотрены ни HALT ни лишние RET из тела процедур. А твой АСМ нафига оптимизировать? Он небось и так нормальный. :)
сделал иначе:
#define _sync() asm(" ei"); asm(" defb 76h");
на это макросе компилятор выдаёт несколько ошибок:
: asm(" ei"); asm(" defb 76h");
) expected ^
; expected ^
( expected ^
expression syntax ^
) expected ^
) expected ^
; expected ^
( expected ^
expression syntax ^
) expected ^
но при этом всё собирается, и халт на месте.
если засовывать в либу, тогда конструкция выростает до:
_sync: pop de ; return address
push de
ei
halt
ret
т.е. лишние телодвижения.
Alcoholics Anonymous
24.03.2015, 10:14
[b] i need worked library for Sprinter. I can see - z88dk have small (for console and file io) Sprinter support (pps config).
Sayman, ЭЛТ вы показываете здесь PPS у всех есть код, начинающийся в 0x8100 и стек на 0xc000. Этот регион (~ 16k) достаточно мала для скомпилированной программы C.
Рассматривали ли вы другие карты памяти?
Для PPS-ZX цели я хотел бы поставить барана в 0-16k области и заполнить, что с библиотекой кода. Область между конец файла отображения и 0x8000 я мог бы использовать для STDIO дисковых буферов и таНос регионе. В 0x8000 - 0x8300 я бы поставил стека и im2 блок. После 0x8300 я бы просто пусть программа растут вверх, чтобы 0xffff (~ 32k). 32k для C не считая библиотек приличного размера.
Я использую автоматический перевод http://sprinter.winglion.ru/sp2000.pdf для информации, но она по-прежнему трудно выяснить.
Будет что-то нравится эта работа? Я представляю себе небольшую программу загрузчик, который бы ознакомиться с полным C Runtime в 0-16k области и загрузить программу C в 0x8300, прежде чем прыгать на ЭЛТ.
То, что я не знаю, если память утверждал на спринтера в гх режиме и является ли файлы на диске (в частности, HDD) можно прочитать в виде файлов. Функции BIOS документально выше, только говорить о чтении и записи абсолютных секторах на диске.
Там также нет слова на действительно ли спринтер дос-либо буферизации. Большинство дисков ОС на Z80 машин очень просты и не буфер все данные так, чтобы они трэш, когда типовые программы C у файловый ввод / вывод. Например, если вы читаете один символ в то время, из файла вот так:
в то время как ((с = fgetc (в))! = EOF)
do_something (с);
на большинстве z80 дисковых операционных систем, читал, что один символ может привести весь сектор для чтения, а затем выбросить. Есть также проблемы с имеющих более одного открытого файла или с открытого файла для обновления ("+", где есть две файловые указатели, работающие на файле).
Информация о спринтер DOS, кажется, очень мало. Если спринтер DOS не делает эти вещи, которые мы должны поставить код, чтобы сделать это, но мы не имеем, что готов.
Sayman, the crts you are showing here for pps all have code starting at 0x8100 and the stack at 0xc000. This region (~16k) is quite small for a compiled C program.
Have you considered other memory maps?
For a pps-zx target I would like to put ram in the 0-16k area and fill that with library code. The area between the end of the display file and 0x8000 I might use for stdio disk buffers and malloc region. At 0x8000 - 0x8300 I'd put the stack and im2 block. After 0x8300 I would just let the program grow upward to 0xffff (~32k). 32k for C not counting the libraries is a decent size.
I'm using the an automatic translation of http://sprinter.winglion.ru/sp2000.pdf for information but it's still hard to figure out.
Would something like this work? I imagine a small loader program that would read a complete c runtime into the 0-16k area and load the C program at 0x8300 before jumping to the crt.
What I don't know is if memory is contended on the sprinter in zx mode and whether files on disk (particularly hdd) can be read as files. The bios functions documented above only talk about reading and writing to absolute sectors on disk.
There's also no word on whether the sprinter dos does any buffering. Most disk oses on z80 machines are very simple and do not buffer any data so that they thrash when typical C programs do file i/o. Eg, if you read one char at a time from a file like so:
while ((c = fgetc(in)) != EOF)
do_something(c);
on most z80 disk operating systems, reading that one char will cause the entire sector to be read and then thrown away. There are also issues with having more than one file open or having a file open for update ("a+" where there are two file pointers operating on the file).
Information on the sprinter dos seems very sparse. If the sprinter dos does not do these things we have to supply the code to do it but we don't have that ready yet.
Error404
24.03.2015, 11:12
сделал иначе:
#define _sync() asm(" ei"); asm(" defb 76h");
на это макросе компилятор выдаёт несколько ошибок:
: asm(" ei"); asm(" defb 76h");
) expected ^
; expected ^
( expected ^
expression syntax ^
) expected ^
) expected ^
; expected ^
( expected ^
expression syntax ^
) expected ^
но при этом всё собирается, и халт на месте.
если засовывать в либу, тогда конструкция выростает до:
_sync: pop de ; return address
push de
ei
halt
ret
т.е. лишние телодвижения.
Не понял зачем там pop/push
у V3.09 какие-то проблемы с пониманием конструкции asm("ор"), я ее заменял на #asm #endasm
Если тебе надо вставить всего лишь 2 команды которые не понимает оптимизатор и избежать лишнего call/ret, как вариант можно использовать опкоды
#asm
defb
defb
#endasm
В моем случае были объемные процедуры на голом ASM, я их выносил в отдельный модуль.
Не понял зачем там pop/push
при написании какой то процедуры на асме, чтобы прога не тупанула, нужно вести для хайтеха стек. при входе нужно дёрнуть адрес возврата и все аргументы.
в данном случае я скорей всего тупанул, т.к. для процедуры нет аргументов. но если они есть, то делать нужно как уже сказал. можно пушами и попами, можно через ld hl,2 add hl,sp или через ix. но тогда при выходе ix обязательно нужно восстановить, иначе всё дохнет.
Если тебе надо вставить всего лишь 2 команды которые не понимает оптимизатор и избежать лишнего call/ret, как вариант можно использовать опкоды
не хотелось бы пихать в основное тело (типа в main()) всякие куски с #asm #endasm. потому пихаю макрос. выдаёт варнинг, да, но зато работает и меньше байтов и тактов тратится.
---------- Post added at 14:34 ---------- Previous post was at 14:33 ----------
Alcoholics Anonymous, I answer to you in z88dk forum, soon.
Error404
24.03.2015, 13:57
при написании какой то процедуры на асме, чтобы прога не тупанула, нужно вести для хайтеха стек. при входе нужно дёрнуть адрес возврата и все аргументы.
в данном случае я скорей всего тупанул, т.к. для процедуры нет аргументов. но если они есть, то делать нужно как уже сказал. можно пушами и попами, можно через ld hl,2 add hl,sp или через ix. но тогда при выходе ix обязательно нужно восстановить, иначе всё дохнет.
Манипулировать стеком надо только если нужно прочитать передаваемые параметры (т.к. они лежат выше по стеку чем адрес возврата). В остальных случаях достаточно просто не портить стек - компилятор после возврата из твоей функции всегда подымает стек на нужную величину чтобы скомпенсировать им же ранее загруженные на стек параметры функции.
Sergey, расскажи, пожалуйста, как можно прикрутить к code::blocks компиляцию через bat файл? ты говорил, что умеешь с ним готовить всякие компиляторы...или я путаю?
Error404, ты не вкурсе, у хайтеха видать глюк или комплект стоковых библиотек не полный. в библиотеке libf.lib нет процедуры flxor (float xor). всю башку уже сломал над этой хренью...
Error404
26.03.2015, 21:41
Error404, ты не вкурсе, у хайтеха видать глюк или комплект стоковых библиотек не полный. в библиотеке libf.lib нет процедуры flxor (float xor). всю башку уже сломал над этой хренью...
Ну, наверное экзотики там может и не быть. Хor вообще-то битовая функция. Битовые функции над вещественными числами это какой-то особый вид извращений.
Sergey, расскажи, пожалуйста, как можно прикрутить к code::blocks компиляцию через bat файл? ты говорил, что умеешь с ним готовить всякие компиляторы...или я путаю?
Нет. С code::blocks я пока использую SDCC. И для постобработки (для получения SCL со скомпиленной в boot прогой) - скрипт на REXX.
Сборка CP/M-компиляторами осуществляется REXX-скриптом с помощью эмулятора CP/M, из командной строки. На выходе - SCL с boot`ом.
SCL - частность, - скрипт можно допилить и на другие форматы.
Конкретизируй, пожалуйста, что тебе нужно.
Короче, сони.
Прилагаю архив с дистрибутивом HiTech C v3.09, к которому добавлен эмулятор CP/M (cpm.exe) и два скрипта на REXX с интуитивнопонятными названиями. На выходе у обоих скриптов SCL-файл будет одинаковый (оптимизированный).
Разница в том, что скрипт "optim" выдаст еще два исходника на ассемблере, до и после оптимизации.
Использование:
HiTech2zx48scl.rex source_name.c [, *.lib... [*.obj...]]
библиотека "libc.lib" добавляется в линковку автоматически.
P.S.
Для оптимизации кода НЕ нужно вручную проделывать все шаги вместо компилятора. Достаточно указать последнему ключик "-O". И тот же результат достигается в одну строчку: "cpm.exe C.COM -Dz80 -C -O myprog.c".
Error404
04.04.2015, 16:25
Я не понял пост выше. Это таки для интеграции в GUI или просто что-то спектрумовое?
Что касается вызова компилятора, то вызов "по составляющим" дает +1.5к к буферам компилятора/оптимизатора/еtс, т.к. в противном случае сс сажает в верхушке TPA резидента ($EXEC), который уменьшает ТПА, а все что он делает - это вызов той самой кучки бинарей, которые можно вызвать самому и за счет этого собрать более крупные файлы не нарвавшись на "out of memory"
Я не понял пост выше. Это таки для интеграции в GUI или просто что-то спектрумовое?
Это не для GUI - я не настолько знаю code::blocks (правильнее сказать, вообще не знаю) чтобы прикрутить туда в качестве компилятора cp/m-программу. Приложенные скрипты предназначены для сборки из командной строки windows. Также там есть пример: cls.c.
по-пробуй (если у тебя установлен Regina REXX): optimHiTech2zx48scl.rexx cls.c
должны появиться файлы cls.asm, cls_opt.asm, cls.bin и cls.scl.
... вызов "по составляющим" дает +1.5к к буферам компилятора/оптимизатора/еtс..."
Вот это полезная информация. Спасибо.
Sayman, кстати, а ты, что, С-компилером для Спринтера не пользуешься?!
Sergey, не особо. для спринтера си мало пригоден в плане чего-то графического. объёмы данных слишком большие, чтобы на си с ними ворочать. и памяти мало (всего 64кб, а точнее, ТПА всего 48кб или даже меньше, если учесть, что вывод в одно окно графики, то и вовсе 32кб). утилиты под дос писать мало интереса, да и хватает как бы. да и ещё не удобно, что на си стэк фигово контролировать. есть риск, что код сишный залезет на область стэка. да и дальние вызовы там геморные.
Sergey, не особо.
Я имел ввиду использование нативного SolidC для SprinterDOS :)
для спринтера си мало пригоден в плане чего-то графического. объёмы данных слишком большие, чтобы на си с ними ворочать.
Да кто-же всё ЦЕЛИКОМ-то на Сях пишет?! Делай либы на асме и дёргай их из Сей. Низкоуровневые процедуры пишут только на асме. И как-то это не вяжется с твоими вопросами, как сделать crt0.s для сборки екзешников для Спринтера. ;)
что на си стэк фигово контролировать. есть риск, что код сишный залезет на область стэка. да и дальние вызовы там геморные.
Это невозможно. Стек может испортить только криво написанная подрограмма на асме, которая за стеком не следит.
использование нативного SolidC для SprinterDOS
не не, спасибо. такое я точно пользовать не буду. никаких 32 bit long, float, double, #asm/#endasm и других красивостей.
Да кто-же всё ЦЕЛИКОМ-то на Сях пишет?!
процедуры на асме тут не причём. тут только на фон нужно иметь 82кб буфер. про прочие спрайты, которые в среднем весят от 2.5кб до 5кб, а могут и больше. с такими данными шибко не удобно работать на сях. постоянно нужно следить за границами буферов. не удобно в общем.
как сделать crt0.s для сборки екзешников
вяжется это так, что хотел попробовать сдцц к спринтеру. попробовал. не понравилось. отложил.
Это невозможно.
для мелких проектов да, а когда ехешник выростает килобайт до 40, вот тут уже начинаются грабли с сями. что говорить. если банальный printf в среднем 2.7кб.
DI
DI/Gl.vars
Коэфф.
Ассемблер (эталон)
323
323
1,00
HiTech C v.7.50 (MS-DOS)
432
1814
0,74
Z88DK (Win32)
512
-
0,631
SDCC v.3.51 (Win32)
528
765
0,612
IAR (Win32)
803
858
0,4022
HiTech C v.3.09 (cp/m, z80)
979
856
0,3320/0,3773
Aztec C (cp/m, i8080)
1738
-
0,186
HiSoft-C v.1.35 (CP/M, Z80)
3660
0,0000/0,0882
MI-C v3.18I (CP/M, Z80)
4160
3760
0,0776/0,0859
WarpC 14.01 (TR-DOS, Z80)
4910
4640
0,0660/0,0696
MeSCC 1.08 (CP/M, i8080)
8370
4850
0,0386/0,0667
Поскольку меня торкнуло написать печаталку на Сях, и она, таки, заработала, решил устроить небольшое соревнование между компиляторами Си, позволяющими компилировать код для ZX-Spectrum.
Сам тест состоял в вызове 2560 (для очень медленных компиляторов - 256) раз процедуры печати текста. Текст был выбран случайно и оказался длиной 333 символа.
Время запуска и окончания цикла фиксировалось по встроенным CMOS-часам. В таблице результаты времени отработки цикла в секундах.
Изначально время замерялось при включенных прерываниях, что не совсем правильно. - В последующим данные для всех компиляторов будут дополнены.
Кроме того интересно было оценить, насколько на эффективность влияет "локальность" переменных.
Для процедуры на ассемблере ничего не дало - это естественно. Там можно было вынести в глобальные только переменную цикла. В Си-версии процедуры - их шесть. На примере Aztec C, разница заметно видна.
За эталон взята самописная процеура печати 64 сим./стр. на ассемблере. Шрифт используется "экономный" в левых тетрадах байта латинские символы, в правой - кириллица. Итого 1кб.
До кучи, сравнил эффективность кода Хайтек 3.09 до и после оптимизации (прерывания выключены): 483/472 секунд.
Вот сишный исходник:
#include "minifont.c"
#define LAT 0
#define RUS 1
char text[16];
void i2s(char*, int num);
unsigned int iBCD2int(unsigned int num);
unsigned int rd_cmos_minsec(void);
unsigned char atX,atY;
const unsigned char* ScreenTable[24] = {
0x4000,0x4020,0x4040,0x4060,0x4080,0x40A0,0x40C0,0 x40e0,
0x4800,0x4820,0x4840,0x4860,0x4880,0x48A0,0x48C0,0 x48e0,
0x5000,0x5020,0x5040,0x5060,0x5080,0x50A0,0x50C0,0 x50e0
};
unsigned int iBCD2int(unsigned int num) __naked
{ num;
__asm
pop af
pop de
push de
push af
ld hl,#0
ld a,d
rrca
rrca
rrca
rrca
and a,#0x0f
ld l,a
call 2$ ; x10
ld a,d
and a,#0x0f
ld b,h
ld c,a
add hl,bc
call 2$ ; x10
add hl,hl
ld c,l
ld b,h
add hl,hl
add hl,bc ; x6
ld a,e
rrca
rrca
rrca
rrca
and a,#0x0f
add a,a
ld c,a
add a,a
add a,a
add a,c
ld c,a ; x10
ld a,e
and a,#0x0f
add a,c
ld c,a
ld b,#0
add hl,bc
ret
2$: add hl,hl
ld c,l
ld b,h
add hl,hl
add hl,hl
add hl,bc
ret
__endasm;
}
unsigned int rd_cmos_minsec(void) __naked
{
__asm
ld bc,#0xeff7
ld a,#0x80
out (c),a
ld b,#0xdf
xor a
out (c),a
ld b,#0xbf
in l,(c)
ld b,#0xdf
ld a,#2
out (c),a
ld b,#0xbf
in h,(c)
ld b,#0xef
xor a
out (c),a
ret
__endasm;
}
void i2s(char* d, int num) __naked
{ d, num;
__asm
pop af
pop bc
ex (sp),hl
push bc
push af
xor a,a
ld de,#10000
call 2$
xor a,a
ld de,#1000
call 2$
xor a,a
ld de,#100
call 2$
xor a,a
ld de,#10
call 2$
ld a,#0x30
add a,l
ld (bc),a
inc bc
xor a,a
ld (bc),a
ret
2$: or a,a
sbc hl,de
jp c,1$
inc a
jp 2$
1$: add hl,de
; or a,a
; ret z
add a,#0x30
ld (bc),a
inc bc
ret
__endasm;
}
void put__ch(char sym)
{
unsigned char* dest;
unsigned char* src;
unsigned char lang,q,i;
unsigned int index;
dest = (unsigned char*)(ScreenTable[atY]+atX/2);
lang = LAT;
if(sym&0x80) lang = RUS;
sym = sym&0x7f;
index = sym*8;
src = (unsigned char*)(minifont + index);
if(lang==0) {
if(atX&0x01) {
for(i=0;i<8;i++)
{
q = (*dest)&0xf0;
*dest = q | ((*src++)/16&0x0f);
dest+=256;
}
}
else {
for(i=0;i<8;i++)
{
q = (*dest)&0x0f;
*dest = q | ((*src++)&0xf0);
dest+=256;
}
}
}
else {
if(atX&0x01) {
for(i=0;i<8;i++)
{
q = (*dest)&0xf0;
*dest = q | ((*src++)&0x0f);
dest+=256;
}
}
else {
for(i=0;i<8;i++)
{
q = (*dest)&0x0f;
*dest = q | ((*src++)*16)&0xf0;
dest+=256;
}
}
}
}
void print(char* str)
{
while(*str) {
put__ch(*str++);
atX++;
if(atX>63) {atX=0; atY++;};
}
}
void main(void)
{
unsigned int begin, end;
unsigned int i = 2560;
begin = rd_cmos_minsec();
while(i) {
atX=atY=0;
print("Привет, В форуме проскальзовали идеи о том, что дескать неплохо было бы с реального спектрума выходить в какой-никакой интернет. И даже якобы за рубежом изобрели какую-то хреновину, которая является чем-то типа модема для спектрума и вставляется в стандартный системный разъем фирменного спека. Только вот что было дальше я не понял.");
--i;
};
end = rd_cmos_minsec();
begin = iBCD2int(begin);
end = iBCD2int(end);
end = end - begin;
i2s(text,end);
atX =0;
atY +=2;
print("Печать вышерасположенного текста 2560 раз заняла ");
print(text);
print(" секунд");
}
Кстати, сишный исходник, наверняка, можно оптимизировать. Если знатоки, решат его поправить, - добавлю в таблицу соответствующие данные. Это тоже интересно, сколько может дать оптимизация на высоком уровне. Пока в глаза бросается, что можно было обойтись без вычисления промежуточной переменной index и return(dest).
Странный этот ваш sdcc какой-то. один и тот же исходник, а старый хайтех выдаёт 9.4кб, сдцц выдаёт 12.7кб. при этом после sdcc местами валят не верные данные при отработки бинарника.
perestoronin
10.12.2015, 12:35
Это не странность, а плата за мультиплатформенность.
sdcc никто и не тестирует для ретро-платформ, упор только на свои силы.
ДДаааа... столь мелкий кодик sdcc собирает медленнее древнющего HTC, да ещё и бинарник медленный оказывается. уж не знаю про выше указанные тесты, но что-то тут не так, sdcc даёт код более медленный, хотя стоит оптимизация по скорости. При чём HTC версии 3.09, под цпм.
Alcoholics Anonymous
11.12.2015, 20:48
Sergey, не могли бы вы предоставить ссылку, чтобы загрузить "minifont.c"?
Я хотел бы, чтобы скомпилировать пример. Hitech C v7.50 очень редко производит более быстрый код, чем z88dk/sdcc во всех испытаниях я сделал, так что я хотел бы, чтобы скомпилировать двоичный для вас попробовать.
Вы можете увидеть результаты некоторых тестах мы запускаем, в том числе Dhrystone 2.1 и Whetstone 1.2, здесь: http://www.z88dk.org/wiki/doku.php?id=temp:front#dhrystone_2.1
Sergey could you provide a link to download "minifont.c" ?
I would like to compile your example. Hitech C v7.50 very rarely produces faster code than z88dk/sdcc in all the testing I have done so I'd like to compile a binary for you to try.
You can see results of some benchmarks we've run, including Dhrystone 2.1 and Whetstone 1.2, here: http://www.z88dk.org/wiki/doku.php?id=temp:front#dhrystone_2.1
Hello, Alcoholics Anonymous!
I would be very grateful for your work. This is my sources adapted to z88dk.
Hitech C v7.50 очень редко производит более быстрый код
HiTech C постоянно выдаёт более быстрый код. Я перекопал форум msx, там довольно много кода сравнивали с z88dk, sdcc, msx-c и htc (как 3.09 так и 7.50/7.80). Почти всегда хайтех в лидерах.
вот пример странички
http://www.msx.org/forum/development/msx-development/c-compiler-comparison-part-two
а тут конкретно z88dk и htc
http://www.msx.org/forum/development/msx-development/c-compiler-comparison-part-two?page=2
6 пост сверху
HTC: 8/9 secs
z88dk: 21 secs.
Error404
12.12.2015, 10:31
HiTech C постоянно выдаёт более быстрый код. Я перекопал форум msx, там довольно много кода сравнивали с z88dk, sdcc, msx-c и htc (как 3.09 так и 7.50/7.80). Почти всегда хайтех в лидерах.
вот пример странички
http://www.msx.org/forum/development/msx-development/c-compiler-comparison-part-two
а тут конкретно z88dk и htc
http://www.msx.org/forum/development/msx-development/c-compiler-comparison-part-two?page=2
6 пост сверху
А я 7.50/7.80 так и не нашел нормально поломаный и чтобы запускать из командника, а не из экранных форм. Где его можно взять погонять? :rolleyes:
Alcoholics Anonymous
13.12.2015, 01:20
Hello, Alcoholics Anonymous!
I would be very grateful for your work. This is my sources adapted to z88dk.
Я думаю, что некоторые из наших инструментов есть проблемы с кириллицей, которые мне придется взять добычу в.
Но вот компиляции, что я надеюсь, что произведения. На эмуляторе я вижу выход, но, конечно, нет CMOS часы для измерения времени.
I think some of our tools have problems with the cyrillic alphabet which I will have to take a loot at.
But here's a compile that I hope works. On an emulator I can see the output but of course there's no cmos clock for time measurement.
https://drive.google.com/file/d/0B6XhJJ33xpOWMnRRaXd6bTBHbVk/view?usp=sharing
Если вы используете бинарный вместо крана, вы должны CLEAR 32768, а затем загрузить двоичный обратиться 32768 и, наконец, RAND USR 32768.
Позвольте мне знать, если он не работает.
Одна вещь, я не сделать, изменить программу, чтобы передавать параметры реестра или использовать вызываемого абонента связь, которая большинство других компиляторов не может сделать, чтобы получить более прямое сравнение.
If you use the binary instead of the tap, you must CLEAR 32768, then load the binary to address 32768 and finally RAND USR 32768.
Let me know if it doesn't work.
One thing I didn't do was change the program to pass parameters by register or use callee linkage which most of the other compilers cannot do to get a more direct comparison.
Alcoholics Anonymous
13.12.2015, 02:49
HiTech C постоянно выдаёт более быстрый код. Я перекопал форум msx, там довольно много кода сравнивали с z88dk, sdcc, msx-c и htc (как 3.09 так и 7.50/7.80). Почти всегда хайтех в лидерах.
вот пример странички
http://www.msx.org/forum/development/msx-development/c-compiler-comparison-part-two
а тут конкретно z88dk и htc
http://www.msx.org/forum/development/msx-development/c-compiler-comparison-part-two?page=2
6 пост сверху
Есть ли у вас ссылка на полной программе, чтобы проверить? Ни один из программ в этой дискуссии не будет полным - часть исходного кода была отрубили по некоторым причинам.
Do you have a link to a complete program to test? None of the programs in that discussion is complete -- some of the source code has been chopped off for some reason.
В общем, люди не используют компиляторы должным образом. Например, вы не должны использовать встраиваемые ASM с SDCC, потому что это мешает локальной оптимизации. Вы можете получить некоторые странные код из SDCC как статических нагрузок не избежать, если встроен ASM вставляется в C коде. С sccz80 (родной компилятор z88dk), а на самом деле со всеми компиляторами, лучше Код производительности должны использовать глобальные или локальные статику, если это разумно. Особенно с sccz80 это может сделать большую разницу в производительности. Оптимизация должна быть положить на макс, и многие люди не знают, как это сделать. С sccz80 Это -O3 и SDCC, который заходящего --max-allocs-per-node на что-то высокое (как 200000). Обычно вы можете получить лучший код из SDCC, запрещая использование слишком гу, добавив --reserve-regs-iy.
In general, people are not using the compilers properly. For example, you should not be using inlined asm with sdcc because it interferes with peephole optimization. You can get some weird code out of sdcc like dead loads not being eliminated if inlined asm is inserted into C code. With sccz80 (z88dk's native compiler) and actually with all the compilers, best performance code should be using globals or local statics if that is reasonable. Especially with sccz80 this can make a big difference in performance. Optimizations should be put on max and many people don't know how to do that. With sccz80 that's -O3 and with sdcc that's setting --max-allocs-per-node to something high (like 200000). You can usually get better code out of sdcc by forbidding use of iy too by adding --reserve-regs-iy.
sccz80-сгенерированный код никогда не будет самым быстрым. Причина он пытается реализовать компилятора операции, используя вызовы подпрограмм, чтобы быть наименьшим. При том, что в сочетании с языка ассемблера библиотеки, где производительность, как предполагается, пришли, результат маленький и быстрый код. sccz80 сгенерированный код, как правило, меньше, чем SDCC или HITECH, иногда с большим отрывом, но sccz80 требует программировать для компилятора, а не делать вид, что это 32-битная платформа с кодом. Вы можете видеть, что в некоторых крупных программ, составленных мы. Например, clisp.c - это Lisp interpretter> 1200 строк в C - компилирует 27000 байт под sccz80 и 32000 байт под HTCv7.50. startrek.c (> 2100 строк в C) доходит до 41000 байт под HTCv7.50 и 32600 байт под z88dk + SDCC. Последнее особенно связано в основном с более библиотек z88dk так размер кода похож на HTC и SDCC если код библиотеки исключены.
sccz80-generated code is never going to be the fastest. The reason is it's trying to implement compiler operations using subroutine calls in order to be the smallest. When that is combined with assembly language libraries, where the performance is supposed to come from, the result is small and fast code. sccz80 generated code is normally smaller than sdcc or hitech, sometimes by a large margin, but sccz80 requires you to program for the compiler rather than pretend it's a 32-bit platform with the code. You can see that in some of the large programs we compiled. Eg, clisp.c -- a lisp interpretter > 1200 lines in C -- compiles to 27000 bytes under sccz80 and 32000 bytes under HTCv7.50. startrek.c (> 2100 lines in C) comes to 41000 bytes under HTCv7.50 and 32600 bytes under z88dk+sdcc. The latter especially is due mainly to better libraries in z88dk since code size is similar for HTC and sdcc if library code is excluded.
Версия z88dk на sourceforge (1.10) не является текущей. Текущая версия может использовать SDCC, как компилятор, улучшить свой код несколько, и поставить на ассемблере библиотеки из z88dk. Это то, что, кажется, превосходит все остальное большую часть времени в скорости, размер кода и полноты. Я очень заинтересован в поиске, когда эта комбинация не так хорошо, другие компиляторы, чтобы увидеть, где некоторые очевидные улучшения могут быть сделаны.
The version of z88dk at sf (v1.10) is not current. The current version is able to use sdcc as compiler, improve its code somewhat, and supply assembly language libraries from z88dk. This is what seems to be outperforming everything else most of the time in speed, code size and completeness. I'm very interested in finding out when this combination does not perform as well as other compilers to see where some obvious improvements can be made.
Let me know if it doesn't work.
It works fine. 512 sec. Great!
Can You give "magic" command line options for ZCC? ;)
Alcoholics Anonymous
15.12.2015, 04:09
Can You give "magic" command line options for ZCC? ;)
You must have sdcc installed.
sdcc must be modified a little bit to be compatible with z88dk. If you are running on windows, copy zsdcc.exe from this zip file (http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/sdcc_z88dk_patch.zip) to sdcc's bin directory sdcc/bin. If you're not running on windows, check out http://www.z88dk.org/wiki/doku.php?id=temp:front#sdcc1 .
You must have a recent version of z88dk installed. I'd suggest waiting until the Dec 15 build is finished in about 3 hours from now. I put in a fix so the tools will not crash if the source contains Cyrillic letters. The nigthly build is here: http://nightly.z88dk.org/ Click on the latest win32 build and unzip where you like. You must set a few environment variables as described here: http://www.z88dk.org/wiki/doku.php?id=temp:front#windows sdcc should also be in the path.
z88dk compiles are very configurable so one compile line (and a set of pragmas in your source code) does not always fit. The library can also be rebuilt to make the compiled code faster or smaller by selecting different options. For example, you can opt out of individual printf/scanf converters to reduce size or you can enable the fast integer library if you are ok with an additional ~1k code. The latter makes z88dk's integer math several times faster than all other compilers. If you read through the links mentioned in this section: http://www.z88dk.org/wiki/doku.php?id=temp:front#compiling_with_sdcc you will have an idea of how things work.
A general magic compile line for the zx looks like one of these:
32 column stdin/stdout/stderr z88dk terminal drivers
zcc +zx -vn -SO3 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test
zcc +zx -vn -SO3 -clib=sdcc_iy --max-allocs-per-node200000 test.c -o test
64 column stdin/stdout/stderr z88dk terminal drivers
zcc +zx -vn -SO3 -startup=4 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test
zcc +zx -vn -SO3 -startup=4 -clib=sdcc_iy --max-allocs-per-node200000 test.c -o test
fzx proportional fonts stdin/stdout/stderr z88dk terminal drivers
zcc +zx -vn -SO3 -startup=8 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test
zcc +zx -vn -SO3 -startup=8 -clib=sdcc_iy --max-allocs-per-node200000 test.c -o test
Nothing on stdin/stdout/stderr
zcc +zx -vn -SO3 -startup=31 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test
zcc +zx -vn -SO3 -startup=31 -clib=sdcc_iy --max-allocs-per-node200000 test.c -o test
The "-clib=sdcc_iy" compile gives IX to sdcc and IY to the c library. This will be the smallest and fastest code. However, you must disable interrupts or have your own isr installed because the rom interrupt uses iy and if it runs, it will be poking random stuff into memory and eventually cause a crash.
The "-clib=sdcc_ix" option has sdcc and the c library sharing IX. The rom isr can continue to run.
You must add "-lm" if using floats. If you need to printf floats (%aefg) you must re-build the library because the default build has %aefg disabled. You can also use stdlib functions dtoa / ftoa, etc to render floats into text.
The default zx crt is doing something we call an "automatic malloc". It creates a heap between the end of the program and the bottom of the stack automatically when the program runs. If it finds the available space is 0 or less, the program will just exit without any indication. This can happen if you CLEAR before loading the program because CLEAR moves the stack underneath the executable. So by default the crt also moves the stack pointer underneath the UDGs. For someone new to C and just wanting to compile stuff, this is most often what is wanted. But for more complicated programs this is often not what you want. You can put pragams into the source to change the crt behaviour. These two may be helpful:
#pragma output REGISTER_SP = -1 // do not change the stack pointer
#pragma output CLIB_MALLOC_HEAP_SIZE = 0 // do not create a heap
z88dk's library and crts are very configurable so if you use it, take some time to learn these things in order to make best use of the compiler.
If you get things working, try compiling your program in the zip I posted a little further back. The compile line I used is listed at the top of the .c file. You can make the result a little bit faster by changing the function linkage of put__ch() and print() like this:
unsigned char* put__ch(char sym) __z88dk_fastcall
void print(char* str) __z88dk_fastcall
Adding "__z88dk_fastcall" will make sdcc pass a single parameter by register instead of by stack. This shaves another 10 seconds or so from running time.
There are a few example programs in z88dk/libsrc/_DEVELOPMENT/EXAMPLES
- - - Добавлено - - -
Когда пытался использовать sdcc и z88dk столкнулся с непониманием как разделить код по необходимости компиляции в медленную/быструю память. Как сделать ?
В z88dk пространство памяти делится на разделы. Раздел представляет собой контейнер, чем может удерживать код или данные и может иметь дополнительный Org. По умолчанию компилирует настроить карту памяти, которая будет производить один двоичный в разделе "CODE" (так выходные двоичные файлы из z88dk всегда будет под названием "name_CODE.bin"); это на самом деле содержит двоичный код традиционной / части DATA / BSS исполняемого все слиплись.
Это очень легко иметь код компилятора компиляции на 32768 и есть один раздел определяемые пользователем отображается на 23296, например, что вы положили данных или подпрограммы по сборке в. Просто создайте другой файл, как это:
In z88dk the memory space is divided into sections. A section is a container than can hold code or data and can have an optional ORG. The default compiles set up a memory map that will produce a single binary in the "CODE" section (so output binaries from z88dk will always be called "name_CODE.bin"); this binary actually contains the traditional CODE/DATA/BSS parts of an executable all stuck together.
It's very easy to have the compiler compile code at 32768 and have another user-defined section mapped to 23296, eg, that you put data or assembly routines into. Just create another file like this:
SECTION LOWMEM
org 23296
PUBLIC _map
_map: defs 100
...
И добавить его к линии компиляции. Тогда выход будет два бинарных файла: "name_CODE.bin", содержащий C код компилятора на 32768 и "name_LOWMEM.bin", содержащий другие вещи, которые должны быть загружены по адресу 23296.
Это, как большинство людей используют нижние области памяти, потому что это легко. Если вы действительно хотите, чтобы скомпилировать код там, вы должны сказать SDCC использовать другое имя раздел, и это делается по линии компиляции. Я никогда не делал этого, так что я не могу дать конкретные указания. В любом случае, если вы сообщите его скомпилировать в разделе "Lowmem", код будет поставить там. Но SDCC можно скомпилировать только одной секции с каждого исходного файла. Так что вам нужно сделать, это разделить ваш источник C, так что каждый С файла относится к собственной секции. Тогда ты скомпилировал бы каждый файл C объектный файл, а затем, наконец, положить все это вместе на последнем этапе компиляции. Затем выводе будет одним двоичным в разделе определенной которые вам придется загрузить в память.
Вот как это будет работать с z88dk но я никогда не делал этого раньше.
And add it to the compile line. Then the output will be two binaries: "name_CODE.bin" containing the C compiler code at 32768 and "name_LOWMEM.bin" containing the other stuff that should be loaded at address 23296.
This is how most people are using the lower areas of memory because it's easy. If you actually want to compile some code there, you have to tell sdcc to use a different section name and this is done on the compile line. I have never done this so I can't give specific instructions. Anyway if you tell it to compile into the "LOWMEM" section, code will be put there. But sdcc can only compile to one section with each source file. So what you need to do is divide up your C source so that each C file belongs to its own section. Then you would compile each C file to an object file and then finally put it all together in the last compile step. Then the ouput will be one binary per section defined which you will have to load into memory.
That's how it would work with z88dk but I have never done this before.
Добавил (http://zx-pk.ru/showthread.php?t=6844&p=841823&viewfull=1#post841823)в табличку информацию об эффективности WarpC: 0,066.
Добавил (http://zx-pk.ru/showthread.php?t=6844&p=841823&viewfull=1#post841823)в табличку информацию об эффективности WarpC: 0,066.
Как насчет измерения для BDS C и вот этого компилера (http://www.floppysoftware.es/mescc.html) раз пошла такая пьянка :)
С BDS не помню, почему до сих пор не потестил. А по второму, - вот:
Занятная штуковина этот Mescc. Подвид Small C Compiler, синтаксис K&R. Не умеет инициализированные массивы. Зато очень беспечен ко всему, что заключено между #asm/#endasm. Так массивы и впихнул :) Особенно порадовала работа с объявлением функций, написанных на асме. Главное, чтобы у неё была своя метка. Остальное - мало..учий факт: компилятор передаст ей столько аргументов, сколько захочешь, любых типов - сам отвечаешь, что у тебя подпрограмма из этого "скушает", не нужно каким-либо образом формально сообщать компилятору количество и тип аргументов, а также и тип возвращаемого значения и то, есть оно или нет. Анархия - мать порядка! :)
Интересная особенность: аргументы передаются в порядке, обратном обычному: первым со стека снимается последний аргумент, а не первый.
Выдаваемый код ужасен. По каждому чиху call на runtime-функции, состоящие из 3-х-4х комманд, а с локальными переменными какие пляски с бубном устраивает, - зрелище не для слабонервных. Хоть он и заявлен, что Z80, от Z80 у него только мнемоники в выходном ассемблерном файле, - локальные переменные используются через мудрёные спецпроцедуры, - про индексные регистры компилятор не в курсе :(. Итак: MeSCC: 0,0386/0,0667.
Но есть и положительные моменты: если использовать его как макроассемблер с Си-синтаксисом, ужасность его кода для конечного результата особого значения не имеет. И, учитывая, что есть исходники и компилятора и используемого им ассемблера, его возможно достаточно легко портировать в ТR-DOS. Нативный компилятор Си, выдающий верный код, на Спеке лишним не будет :)
Прилагаю архивчик с SCL, а также исходники теста, модифицированный mescc.h (обязательно инклюдить) и скрипт на REXX, который поможет интересующимся собирать на Mescc приложения для Спектрума. (Изменения внесены на скорую руку. Если кому-то интересно, - тогда уже отрехтую для серьёзной работы ).
BDS C так и не осилил - очень ограниченный. Трудновато слепить на нём печаталку.
Зато побаловался с MI-C. Результат таков: 0,0776/0,0859.
В процессе не удалось пока собрать всё штатными средствами - m80/l80. Поэтому поступил так:
Сгенерил компилятором ассемблерный файл и перенёс его в ALASM. То же самое сделал и с runtime библиотекой, которая хранится в ассемблерном файле.
Добавил служебных процедурок для замера времени, и всё. Ассемблится и запускается ручками в ALASM/STS. Результат можно посмотреть в дампе памяти по адресу #60BC ("PASSED:nnn"). Полуфабрикат, конечно, зато интересующиеся смогут посмотреть выдаваемый MI-C код. ТРДшник прилагаю.
Как компилятор K&R, MI-C, вполне, адекватный, каких-либо неудобств с точки зрения совместимости С-кода не ощутил. BDS C с ним не сравнить.
Однако, особенностей Z80 компилятор не использует, а лишь способен выдавать ассемблерный текст в соответствующих мнемониках. Ну, и, понятно, к локальным переменным обращается не через индексные регистры, а через HL, складывая указанное в ней смещение со значением SP.
а zds 3.68 от зилога не встречалось никому с невыпеленым компилятором С ?
Добавил в табличку сведения по HiSoft-C.
Вообще, я хотел проверить версию для TR-DOS, однако не вышло - компилятор почему-то ругается на нехватку памяти. Поэтому, чтобы получить представление о возможностях спектрумовского компилятора пришлось использовать его cp/m-ного собрата. Правда, на спектруме используется более старая версия: 1.1.
Для версии с глобальными переменными коэффициент относительно аналогичной программы на ассемблере составил 0,0882.
256 вызовов отработали за 366 секунд.
Этот компилятор генерит сразу машинный код, минуя стадию ассемблера, и не даёт возможности компиляции под произвольный адрес - только с 0x100.
Но, поскольку каких-либо функции, завязанных на CP/M я не использовал, то решил задачу в лоб: полученный com-файл CP/M запустил на Пентеве с адреса 0x100. И всё получилось.
HiSoft-C заточен именно на Z-80, обращается к локальным переменным через IX. Однако качество кода настолько низкое, что по эффективности, фактически, ничем не отличается от компиляторов для I8080.
Smalovsky
01.02.2016, 18:05
Установил SDCC и Codeblocks.
Настройку для среды делал по сайту http://www.ibm.com/developerworks/ru/library/l-codeblocks_and_sdcc
В Compilier settings установил флаги [CPU]Zilog Z80[-mz80] и [Z80]When lincing, skip stsndard crt0.o object file[--no-std-crt0]
В Linker settings добавил флаги в поле Other linker options:
--code-loc 0x7530
--data-loc 0xA530
Создап проект. В настройках проекта на вкладке Build targets для Debug и Release выбрал Type не Console Applications, а Native, при этом убрал флажок Auto-generate filename extension и вручную прописал расширение HEX.
Правильно ли я сделал настройки? Сделал пробную пробную сборку. Как делать ассемблерные вставки и как передаются параметры для ассемблерной процедуры?
Alex Rider
01.02.2016, 18:36
Вот тут (http://forum.tslabs.info/viewtopic.php?f=28&t=442) есть почитать про настройку Code::Blocks + SDCC, там есть примеры ассемблерных вставок, но, вроде, ничего не увидел про передачу параметров. Много примеров исзодников для SDCC (в том числе, и с ассемблерными вставками) есть в поставке Оберона.
Alcoholics Anonymous
01.02.2016, 19:28
Вот тут (http://forum.tslabs.info/viewtopic.php?f=28&t=442) есть почитать про настройку Code::Blocks + SDCC, там есть примеры ассемблерных вставок, но, вроде, ничего не увидел про передачу параметров.
Во всех случаях возвращается значение в подгруппе DEHL. Если возвращаемое значение 32 бита это в DEHL, если это 16-бит Это в HL, если это 8-бит это в L. Кроме того, во всех случаях ваш подпрограмма не должна изменять IX или IY.
Есть три связи:
In all cases the return value is in a subset of DEHL. If the return value is 32-bits it's in DEHL, if it's 16-bits it's in HL, if it's 8-bits it's in L. Also in all cases your subroutine must not modify IX or IY.
There are three linkages:
1. Normal
Параметры помещаются в стек в правом левом порядке. Стек не должен быть изменен вызываемой функции. Интс 2 байта, Лонги и поплавков 4 байта. Чар выталкивается в 1 байт, но если функция va_arg, символы продвигаются в целое перед толкнул. Возвращаемое значение находится в подгруппе DEHL.
Parameters are pushed onto the stack in right to left order. The stack must not be altered by the called function. Ints are 2-bytes, Longs and Floats are 4-bytes. Char is pushed as 1-byte but if the function is vararg, chars are promoted to int before being pushed. Return value is in a subset DEHL.
extern char *strcpy(char *dst, const char *src);
_strcpy:
pop af ;; return address
pop de ;; de = char *dst
pop hl ;; hl = char *src
push hl
push de
push af
..
;; return value in HL
ret
2. Fastcall
Реализованные на совместимость z88dk в 3.5.5 купить исправления были применены после этого релиза. Использовать текущий SDCC для обеспечения он работает правильно.
Один параметр передается в регистре в подгруппе DEHL и возвращаемое значение в подгруппе DEHL.
Implemented for z88dk compatibility in 3.5.5 but bugfixes were applied after that release. Use the current sdcc to ensure it works properly.
A single parameter is passed by register in a subset of DEHL and the return value is in a subset of DEHL.
extern int strlen(char *s) __z88dk_fastcall;
_strlen:
;; hl = char *s
...
;; return value in HL
ret
SDCC не в состоянии генерировать звонки на быстрых функций обработки вызовов с помощью указателей функций, если он не имеет права использовать регистр IY. В z88dk мы делаем функция указатели другой способ, чтобы они всегда работать.
sdcc is unable to generate calls to fastcall functions through function pointers unless it is allowed to use the IY register. In z88dk we do function pointers a different way so that they always work.
3. Callee
Реализованные на совместимость z88dk в 3.5.5 купить исправления были применены после этого релиза. Использовать текущий SDCC для обеспечения он работает правильно.
Параметры помещаются в стек в справа налево для того, как в 1. Normal [/ B], но называется функция отвечает за ремонт стек. Преимуществом является абонент не должен очистить стек после вызова функции каждого. Возвращаемое значение находится в подгруппе DEHL.
Implemented for z88dk compatibility in 3.5.5 but bugfixes were applied after that release. Use the current sdcc to ensure it works properly.
Parameters are pushed onto the stack in right to left order as in [B]1.Normal but the called function is responsible for repairing the stack. The advantage is the caller does not have to clear the stack after every function call. The return value is in a subset of DEHL.
extern char *strcpy(char *dst, const char *src) __z88dk_callee;
_strcpy:
pop hl ;; hl = return address
pop de ;; de = char *dst
ex (sp),hl ;; hl = char *src, ret address onto stack
..
;; return value in HL
ret
Я не уверен, что если SDCC может генерировать указатель функции звонки на вызываемого абонента функций. Если он может, они будут по-разному набрали, так что указатели на функции не вызываемого абонента может быть назначен указателей на обычные функции. В z88dk мы делаем функция указатели другой способ, так что все работает прозрачно.
I'm not sure if sdcc can generate function pointer calls to callee functions. If it can, they will be typed differently so that pointers to callee functions cannot be assigned to pointers to regular functions. In z88dk we do function pointers a different way so everything works transparently.
В дополнение к этому есть новые __preserves_regs () атрибут, который может сказать, что компилятор регистрирует функцию АНМ не меняется. На данный момент SDCC использует только информацию о нашей BC и DE, но я включаю все регистры главного набора в только в случае, SDCC расширяет это в будущем:
In addition to this there is a new __preserves_regs() attribute that can tell the compiler what registers the asm function does not change. At the moment sdcc only uses information about BC and DE but I include all registers of the main set in just in case sdcc expands this in the future:
extern int strlen(char *s) __preserves_regs(d,e) __z88dk_fastcall;
Собрать среда для SDCC немного болезненные так много людей встроить свои функции ASM внутри C функций, которые вы можете сделать, но это не самый лучший способ делать вещи. Самый лучший способ, чтобы полностью отдельных ASM функции из кода C. Если вы сделаете это вы будете иметь больше контроля над тем, где ASM код находится в памяти, имея свободу, чтобы присвоить код АНМ в конкретной области или раздела. Также помните, что встроенный монтаж мешает глазок оптимизатора SDCC в:
The assemble environment for sdcc is a little bit painful so many people inline their asm functions inside C functions, which you can do, but it is not the best way to do things. The best way is to completely separate asm functions from the C code. If you do this you will have more control over where asm code is placed in memory by having the freedom to assign the asm code to a specific area or section. Also be aware that inlined assembly interferes with sdcc's peephole optimizer:
void myfunc(void)
{
.....
// sdcc peepholer can't look into the asm block so it assumes all registers are modified by the "di"
__asm
di
__endasm;
...
}
В z88dk мы ввели встроенные функции, так что общие одиночные инструкции, как ди Е.И. остановке, и т.д. могут быть встроены, не влияя на глазок слишком много:
In z88dk we introduced intrinsics so that common single instructions like di, ei, halt, etc can be inlined without impacting the peepholer too much:
void myfunc(void)
{
.....
intrinsic_di();
.....
}
Призыв к intrinsic_di() заменяется на "di", прежде чем глазок видит. Функция объявлена как сохранение всех регистров, так что компилятор может сохраняться регистры по вызову.
The call to intrinsic_di() is replaced by "di" before the peepholer sees it. The function is declared as preserving all registers so that the compiler is able to persist registers across the call.
Smalovsky
02.02.2016, 03:02
Кто-нибудь сделайте и выложите небольшой проект с двумя-тремя функциями и ассемблерными вставками. У меня чего-то выдаёт ошибку - <a> неправильное размещение в памяти.
- - - Добавлено - - -
Нашёл ошибку. Написал ld a, 2 ,а надо было ld a, #2.
Какой файл crt0.s нужен для спекки?
Oleg N. Cher
02.02.2016, 15:40
У меня такой:
.module crt0
.globl _main
jp _mainПросто переход на ф-цию main. Может не работать инициализация неконстантных массивов. Могут быть другие проблемы.
Если прога стартует с самого начала - юзаем ключик --no-std-crt0
s_kosorev
02.02.2016, 20:27
for (i=16384;i<22528;i++){
p=(char*)i;
*p=(char)0xf;
}
на memset замени и еще быстрее будет
Smalovsky
02.02.2016, 21:04
Oleg N. Cher, скипнул crt0.s, но опциях линкера поставил -
--code-loc 35000
--stack-loc 55000
Набросал пробную программу:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i=0;
char *p;
__asm
call 3435
ld a, #2
call 5633
ld a, #22
rst 16
ld a, #10
rst 16
ld a, #10
rst 16
ld bc, #12345
call 11563
call 11747
__endasm;
for (i=16384;i<22528;i++){
p=(char*)i;
*p=(char)0xf;
}
return 0;
}
Собрал, прогнал через hex2bin и bin2tap. Всё работает - экран очищается, быстро выводится число 12345 и рисуется "зебра". Правда всё очень быстро происходит - скорость отличная!
s_kosorev
02.02.2016, 21:12
вот только зачем тут си?
Smalovsky
02.02.2016, 21:32
вот только зачем тут си?
Специфика программирования для спекки подразумевает использования ассемблерных вставок, поэтому я потренировался совместить ассемблерный код и код Си. Еще предстоит написать графические процедуры с использованием ассемблера, а логика программы будет на Си.
Если есть у кого готовые библиотеки, то выкладывайте.
s_kosorev
02.02.2016, 23:14
Специфика программирования для спекки подразумевает использования ассемблерных вставок, поэтому я потренировался совместить ассемблерный код и код Си
тут ассемблер с вставками на си :)
Smalovsky, возьми за правило скидывать весь асмовый код в отдельные модули/библиотеки которые потом просто вызываешь в основном коде. когда ты кидаешь и сишный код и асм в один скроллинг, код становится громоздким и нечитаемым. ты сам начнёшь косяки пороть и думать в чём проблема. и вызывать бейсиковые процедуры тоже не есть гут. они медленные. напиши сам их замену или возьми из того, что уже было до тебя написано. В библиотеках сдцц и z88dk многое есть в открытом виде, можно подсмотреть или использовать то, что уже скомпилино в библиотеки.
и кстати, большая часть ответов на твои вопросы по сдцц есть в его родном мануале. Несколькими страницами назад есть даже модифицированный crt0.s...
Alcoholics Anonymous
03.02.2016, 09:50
Несколькими страницами назад есть даже модифицированный crt0.s...
SDCC изменилось, как куча инициализируется так ЭЛТ размещены там должен быть изменен немного. Лучше начать с того, что обеспечивает SDCC и устранить то, что вам не нужно:
sdcc has changed how the heap is initialized so the crt posted there should be changed a little bit. It's best to start with what sdcc provides and eliminate what you don't need:
.globl _main
.area _HEADER (ABS)
.org 0x0000 ;--code-loc 0x0006
init:
;; Set stack pointer directly above top of memory.
ld sp,#0x0000
;; Initialise global variables
call gsinit
call _main
jp _exit
;; Ordering of segments for the linker.
.area _HOME
.area _CODE
.area _INITIALIZER
.area _GSINIT
.area _GSFINAL
.area _DATA
.area _INITIALIZED
.area _BSEG
.area _BSS
.area _HEAP
.area _CODE
_exit::
di
halt
.area _GSINIT
gsinit::
ld bc, #l__INITIALIZER
ld a, b
or a, c
jr Z, gsinit_next
ld de, #s__INITIALIZED
ld hl, #s__INITIALIZER
ldir
gsinit_next:
.area _GSFINAL
ret
Многие люди путают ЭЛТ, потому что они не знают, как современная работать монтажники. Код Монтаж и данные помещаются в контейнеры, здесь называют ".area" s по SDCC. Код и данные могут быть помещены в эти контейнеры из любой точки исходного кода. Ссылка должна быть рассказана, где эти контейнеры помещают в памяти. В этом ЭЛТ, существует список зон, которые просто указывает компоновщику порядок, в котором эти контейнеры должны появиться в памяти. Так как эти контейнеры не имеют ORG адреса, связанные с ними, они будут появляться один за другим в памяти.
Площадь _GSINIT требуется, потому что без него программу C статические данные не будут установлены по умолчанию. SDCC также разместить код здесь к нулю сегмент BSS и инициализировать кучу, если программа использует кучу.
CRT размещенные лезвие (я думаю) немного путь обратно теперь немного неправильно, потому что куча инициализируется по-разному. Если вы посмотрите в библиотеку z80 вы найдете "heap.s":
Many people are confused by the crt because they don't know how modern assemblers work. Assembly code and data are placed into containers, here called ".area"s by sdcc. Code and data can be placed into these containers from anywhere in the source code. The linker needs to be told where these containers are placed in memory. In this crt, there is a list of areas that simply tells the linker the order that those containers should appear in memory. Since these containers do not have ORG addresses associated with them, they will appear one after the other in memory.
The _GSINIT area is required because without it the C program's static data will not be initialized. SDCC will also place code here to zero the BSS segment and to initialize the heap if the program uses the heap.
The crt posted by Blade (I think) a little way back is now a little bit wrong because the heap is initialized differently. If you look into the z80 library you will find "heap.s":
;; Stubs that hook the heap in
.globl ___sdcc_heap_init
.area _GSINIT
call ___sdcc_heap_init
.area _HEAP
___sdcc_heap::
;; For now just allocate 1k of heap.
.ds 1023
.area _HEAP_END
___sdcc_heap_end::
.ds 1
Здесь можно увидеть SDCC будет размещать код инициализации в _GSINIT и он будет размещать 1k кучи в области _HEAP. Лезвие имеет отдельный код, который инициализирует кучу, что больше не требуется. Это изменение произошло после выхода 3.5.5, но SDCC готовится к отпуску 3.6 в ближайшее время.
where you can see SDCC will place initialization code into _GSINIT and it will place 1k of heap into the _HEAP area. Blade has separate code that initializes the heap that is no longer required. This change came after the 3.5.5 release but SDCC is preparing for a 3.6 release soon.
В библиотеках сдцц и z88dk многое есть в открытом виде, можно подсмотреть или использовать то, что уже скомпилино в библиотеки.
Да, вы должны отделить каждую функцию в своем собственном файле. Встроены в сборе никогда не должны быть использованы для библиотеки, кроме как быстрый метод для программиста C размещать код ассемблера в программу C. В SDCC это было сделано таким образом, потому что SDCC Бэкэнд не проста в использовании.
Для библиотеки, прототип функции в заголовочном файле сообщает компилятору, как вызвать библиотечную функцию ASM. Тогда фактическая функция Библиотека написана в собственном файле АНМ. Все АНМ файлы, составляющие библиотеку затем собраны в библиотеке. В этой форме компоновщик сможет выделить только те функции, программа пользователя использует. Когда код ASM существует независимо, как это, он должен быть назначен в область так, чтобы компоновщик знал, куда его в выходной двоичный. Когда асмовый встроены в коде C, компилятор Си управляет в данный момент активную область.
Вы можете увидеть, как мы делаем это в z88dk - есть библиотека тысяч ASM функции там. Простой пример может быть string.h с его sdcc Файл заголовка (http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/include/_DEVELOPMENT/sdcc/string.h?revision=1.6&content-type=text%2Fplain) и его осуществления ASM (http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/string/).
z88dk не использовать бэкенд SDCC в. Он использует z80asm качестве ассемблера, так что все ASM использует стандартный Zilog обозначения. Если вы используете базовую программу SDCC в необходимо использовать специальный синтаксис asz80. Кроме того, мы делаем много вещей, чтобы исправить несколько небольших проблем в SDCC и генерировать в оптимальный код, как это возможно, что не делается в SDCC, так заголовки и реализация будет немного странно.
Пример из заголовка файла:
Yes you must separate each function into its own file. Inlined assembly should never be used for a library except as a quick method for a C programmer to place asm code into a C program. In sdcc it's been done this way because the sdcc backend is not easy to use.
For a library, the function prototype in the header file tells the compiler how to call the asm library function. Then the actual library function is written in its own asm file. All the asm files making up the library are then compiled into a library. In this form the linker will be able to pick out only those functions the user program uses. When your asm code exists independently like this, it must be assigned to an area so that the linker knows where to place it in the output binary. When asm is inlined in C code, the C compiler is managing the currently active area.
You can see how we do it in z88dk -- there are a thousand asm library functions there. An easy example might be string.h with its sdcc header file (http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/include/_DEVELOPMENT/sdcc/string.h?revision=1.6&content-type=text%2Fplain) and its asm implementation (http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/string/).
z88dk does not use sdcc's backend. It uses z80asm as assembler so all asm uses standard Zilog notation. If you are using sdcc's backend you must use the special asz80 syntax. Also, we do many things to fix several small problems in sdcc and to generate as optimal code as possible that is not done in sdcc, so the headers and implementation will be a little bit strange.
An example from the header file:
extern size_t strlen(char *s) __preserves_regs(d,e);
extern size_t strlen_fastcall(char *s) __preserves_regs(d,e) __z88dk_fastcall;
#define strlen(a) strlen_fastcall(a)
Это для функции STRLEN (). #define Вы видите, чтобы исправить трудности SDCC с генерации указателя функции вызовов азЬсаИ функции. Простой прототип будет просто первая линия:
This for function strlen(). The #define you see is to fix sdcc's difficulties with generating function pointer calls to fastcall functions. A simple prototype would just be the first line:
extern size_t strlen(char *s) __preserves_regs(d,e);
который будет использовать стандартную связь и заходит так далеко, чтобы сказать компиляции, которая регистрирует D и Е являются неизменными функцией.
Реализация ASM делится a z80 часть (http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/string/z80/asm_strlen.asm?revision=1.6&content-type=text%2Fplain) с чистым интерфейсом реестра и C Интерфейс (http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/string/c/sdcc_iy/strlen.asm?revision=1.7&content-type=text%2Fplain). Здесь я только показывать интерфейс C для стандартной связи. АзЬсаИ связь не имеет накладных расходов. Директивы ассемблера приведены для z80asm. Для asz80 вы должны использовать ".globl" и ".area".
Мы отделить интерфейс C от z80 для нескольким причинам. Одним из них является мы хотим поддержать любую компилятор, а другой мы хотим интерфейс АНМ для ассемблерщиков без накладных расходов C. Это также влияет на саму библиотеку, потому что это программа на языке ассемблера, что вызывает функции, определенные в себе. Программа на самом деле сделал меньше, обеспечивая использовать библиотеку по собственным кодом не приносит в накладных C.
Существует немного кривой обучения, но как только вы его, это все довольно легко.
which will use standard linkage and goes so far as to tell the compile that registers D and E are unchanged by the function.
The asm implementation is divided into a z80 part (http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/string/z80/asm_strlen.asm?revision=1.6&content-type=text%2Fplain) with pure register interface and a C interface (http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/_DEVELOPMENT/string/c/sdcc_iy/strlen.asm?revision=1.7&content-type=text%2Fplain). Here I am only showing the C interface for standard linkage. The fastcall linkage has no overhead. The assembler directives shown are for z80asm. For asz80 you would use ".globl" and ".area".
We separate the C interface from the z80 for a couple of reasons. One is we want to support any C compiler and the other is we want an asm interface for assembly language programmers without C overhead. This also affects the library itself because it is an assembly language program that calls functions defined in itself. The program is actually made smaller by ensuring the library's use of its own code does not bring in the C overhead.
There is a little bit of learning curve but once you have it, it's all fairly easy.
Кто-нибудь сделайте и выложите небольшой проект с двумя-тремя функциями и ассемблерными вставками.
Прилагаю исходник одной игрушки (http://forum.tslabs.info/download/file.php?id=1111)
Писалось в качестве примера разработки программ для zx48 на SDCC.
Весь проект не даю, т.к. без установленного интерпретатора REXX, всё равно, не соберёшь.
http://www.softools.com/zilogdownload.htm
говорят 30 дней бесплатно.
на страничке там все подробно, что может.
не очень популярный компилятор да ещё и дорогой. ломанных, кажется, в природе нет...
Error404
03.03.2016, 10:24
Нашёл ошибку. Написал ld a, 2 ,а надо было ld a, #2.
Решеточки, какая прелесть. Вот как ни зайду в ветку про SDCC крайние лет n-дцать, все время одна и та же мысль - если автор папуас, как можно на выходе ждать шыдевр? Годами ждать, все это время перебиваясь на костылях.
не очень популярный компилятор да ещё и дорогой. ломанных, кажется, в природе нет...
30 дней полный функционал, наверное можно оценить качество кода z80 non banked? он просто заточен под это
http://www.zilog.com/force_download.php?filepath=YUhSMGNEb3ZMM2QzZHk1Nm FXeHZaeTVqYjIwdlpHOWpjeTk2TVRnd0wzTnZablJ2YjJ4ekxu QmtaZz09
можно и на виртуалку поставить, правда каждый месяц :)
это изврат. смысл оценивать, если покупать не будешь? а каждый месяц сносить и переставлять, зачем такое счастье? да и засирать свой комп домашний всякими виртуалками желания нет.
Изврат,изврат... :v2_dizzy_fisher:
Решеточки, какая прелесть. Вот как ни зайду в ветку про SDCC крайние лет n-дцать, все время одна и та же мысль - если автор папуас, как можно на выходе ждать шыдевр? Годами ждать, все это время перебиваясь на костылях.
"В огороде бузина а в Киеве дядька" - какое отношение синтаксис ассемблера имеет отношение к компилятору Си?!
Кстати, а где твой Си-компилятор?
Представляешь, а в многих ассемблерах шестнадцатиричное число обозначается символом доллара, а решётка означает непосредственную адресацию. SDCC - многоцелевой компилятор, - с чего бы ему заморачиваться на привычный спектрумистам синтаксис?!
К слову, сейчас можно альтернативный ассемблер использовать.
Поливать чужой труд грязью много ума не надо - любое быдло справится. А на сегодняшний день SDCC - объективно, лучший бесплатный Си-компилятор для Z80. Если сам не способен на что-то лучшее, хотя бы имей уважение к тем, кто что-то полезное делает. Делает в меру своих способностей, а не хабалит на форумах, о "кривости" чужих рук. Не "папуас", лять, - неосилятор "решётки".
"В огороде бузина а в Киеве дядька" - какое отношение синтаксис ассемблера имеет отношение к компилятору Си?!
Кстати, а где твой Си-компилятор?
Представляешь, а в многих ассемблерах шестнадцатиричное число обозначается символом доллара, а решётка означает непосредственную адресацию. SDCC - многоцелевой компилятор, - с чего бы ему заморачиваться на привычный спектрумистам синтаксис?!
К слову, сейчас можно альтернативный ассемблер использовать.
Поливать чужой труд грязью много ума не надо - любое быдло справится. А на сегодняшний день SDCC - объективно, лучший бесплатный Си-компилятор для Z80. Если сам не способен на что-то лучшее, хотя бы имей уважение к тем, кто что-то полезное делает. Делает в меру своих способностей, а не хабалит на форумах, о "кривости" чужих рук. Не "папуас", лять, - неосилятор "решётки".
Очень интересное замечание, только ассемблер отдельно взятых си компиляторов, к сожалению. только к ним и относятся и никакими другими не заменить. Не припоминаю чтобы к сдцц можно было бы прикрутить тот же sjasm для генерации z80 кода. Опять таки, довольно справедливое замечание про решётку. Похоже, что асм от сдцц вообще десятичные числа не воспринимает, точнее воспринимает но, только с этой пресловутой решёточкой. сдцц, как и z88dk, базируется на древнем цпм компиляторе small-c. Только вот z88dk по части асма более близок к пользователю, а в sdcc всё сильно извратили. К слову говоря о бесплатности и "лучшести" - не совсем близкие значения. Может для всяких pic`ов и подобных он и лучший, но для z80 не фонтан, откровенно говоря. Даже твои тесты показывают, что sdcc уступает древнему и бесплатному htc (кстати, ты табличку так и не подправил).
s_kosorev
08.03.2016, 11:36
Кодогенерацию в универсальном компиляторе гораздо сложнее сделать чем специализированном
Smalovsky
08.03.2016, 16:31
Как, кстати, получить доступ к локальным переменным функции в SDCC со стороны ассемблера ?
Как, кстати, получить доступ к локальным переменным функции в SDCC со стороны ассемблера ?
По честному - никак.
С включённым оптимизатором (по умолчанию), sdcc может размещать локальные переменные в регистрах и/или на стеке.
Т.е. оптимизатор сам решает какие локальные переменные, он разместит в регистрах, а какие положит на стек.
(Обычно берутся не более 4 байт в регистры, а остальное всё на стеке. Но этот порядок, естественно, может меняться в будущих версиях.)
Если пишите, нечто очень критичное по скорости (игру), то рекомендую не использовать локальные переменные вообще.
Просто пишите static перед всеми переменными. Тогда sdcc будет генерить код для "локальных переменных" , который будет работать гораздо быстрее.
Но минусы есть:
- про рекурсию можно забыть
- прога будет хавать памяти чуть поболее,
(т.к. все локальные переменные будут висеть в сегменте данных, а не динамически распределятся на стеке)
Oleg N. Cher
09.03.2016, 03:10
Как, кстати, получить доступ к локальным переменным функции в SDCC со стороны ассемблера ?Смысл функции в инкапсуляции того, что она делает внутри, и выдвигании наружу только интерфейса вызова. То есть то, что ф-ция скрывает механизмы и детали её реализации, гарантирует безболезненную её доработку и т.п. И иметь доступ к локальным переменным ф-ции в этом смысле не есть правильно. Если вызываешь кусок на асме, оформь его как другую ф-цию и вызывай из первой сишной, передавая локальные переменные ей как параметры. Это и будет правильно.
P.S. Регистровых параметров в SDCC нет, знаю. z88dk тогда.
Alcoholics Anonymous
10.03.2016, 02:07
Очень интересное замечание, только ассемблер отдельно взятых си компиляторов, к сожалению. только к ним и относятся и никакими другими не заменить.
z88dk заменяет задний конец SDCC с его собственным. Выход SDCC переводится в стандартный Zilog нотации, а затем собрана z80asm, ассемблере z88dk в. Все ассемблере в проекте написано для z80asm.
Вот некоторые из SDCC выход при использовании через z88dk, где вы можете увидеть стандартные обозначения для индексированной адресации регистра:
z88dk replaces sdcc's back end with its own. sdcc's output is translated to standard zilog notation and then is assembled by z80asm, z88dk's assembler. All assembly language in a project is written for z80asm.
Here's some output from sdcc when used through z88dk where you can see standard notation for indexed register addressing:
ld hl,0x0006
push hl
push bc
call __divsint_callee
ex de,hl
ld hl,0x0001
add hl,sp
ld (ix-2),l
ld (ix-1),h
Там ничто не мешает никому делать то же самое для любого другого сборщика, но вы должны иметь достаточно способный ассемблер действовать в качестве замены. Ассемблер должен иметь связывающую способность и она должна реализовать секции кода. Есть только несколько свободных Z80 монтажников, доступных, которые реализуют эти возможности. (Sjasm не является одним из них)
There is nothing stopping anyone from doing the same for any other assembler but you have to have a sufficiently capable assembler to act as replacement. The assembler needs to have linking ability and it must implement code sections. There are only a handful of free z80 assemblers available that implement these capabilities. (sjasm is not one of them)
Не припоминаю чтобы к сдцц можно было бы прикрутить тот же sjasm для генерации z80 кода. Опять таки, довольно справедливое замечание про решётку. Похоже, что асм от сдцц вообще десятичные числа не воспринимает, точнее воспринимает но, только с этой пресловутой решёточкой. сдцц, как и z88dk, базируется на древнем цпм компиляторе small-c. Только вот z88dk по части асма более близок к пользователю, а в sdcc всё сильно извратили. К слову говоря о бесплатности и "лучшести" - не совсем близкие значения. Может для всяких pic`ов и подобных он и лучший, но для z80 не фонтан, откровенно говоря.
Когда SDCC используется через z88dk, он получает доступ к библиотекам z88dk ассемблере в. Ассемблере снова близко к пользователю.
When sdcc is used through z88dk, it gains access to z88dk's assembly language libraries. The assembly language is again close to the user.
Даже твои тесты показывают, что sdcc уступает древнему и бесплатному htc (кстати, ты табличку так и не подправил).
Вы не можете судить на основе выборки из очень короткой подпрограммы, написанной на C. Вам нужно больше и большие примеры, чтобы сделать общие выводы. SDCC иногда не генерирует код, но нам удалось улучшить, что, когда SDCC используется через z88dk. Вот результаты некоторых тестов мы запускаем с использованием больших программ и стандартных эталонных тестов:
You can't judge based on a sample of a very short subroutine written in C. You need more and larger examples to draw general conclusions. sdcc does sometimes generate bad code but we have managed to improve on that when sdcc is used through z88dk. Here are the results of some tests we've run using large programs and standard benchmarks:
* Dhrystone 2.1 (common integer benchmark)
z88dk+sdcc: 7136 bytes, 310.29 dhrystones / second
sdcc: 7223 bytes, 250.12 dhrystones / second
htc 7.50: 7040 bytes, 265.11 dhrystones / second
Almost the same size, htc is 17% slower.
* Whetstone 1.2 (common floating point benchmark)
z88dk+sdcc: 5914 bytes, 4.351 kwips
sdcc: 14463 bytes, 1.418 kwips
htc 7.50: 6872 bytes, crashes ( htc 3.50 for cpm 6.276 kwips )
С плавающей запятой часто выходит из строя и генерирует неправильные ответы с 7.50 HTC. Я не знаю, если HTC 7.80 зафиксировано, что. Время вместо взято из 3.50 для HTC имп и быстрее, чем z88dk + SDCC. Это потому, что z88dk реализует 48-битный с плавающей точкой, тогда как реализует HTC 32-битной плавающей точкой.
Floating point frequently crashes and generates wrong answers with htc 7.50. I don't know if htc 7.80 fixed that. The time is instead taken from htc 3.50 for cpm and is faster than z88dk+sdcc. This is because z88dk implements a 48-bit float whereas htc implements a 32-bit float.
* Pi (tests long integer arithmetic)
z88dk+sdcc: 6165 bytes, 15 min 47 sec
sdcc: 6805 bytes, 37 mins 3 sec
htc 7.50: 6332 bytes, 23 mins 0 sec
Есть несколько вариантов для z88dk + SDCC, самый быстрый из которых 5 мин 40 сек и 7500 байтов. Это в четыре раза быстрее, чем HTC.
There are several variations for z88dk+sdcc, the fastest of which is 5 mins 40 sec and 7500 bytes. That's four times faster than htc.
* clisp (large program 1279 lines, lisp interpretter many longs) compiled for cpm
z88dk+sdcc: 30155 bytes
sdcc: missing library functions
htc 7.50: 32186 bytes
* startrek (large program 2153 lines, some float math) compiled for cpm
z88dk+sdcc: 32053 bytes
sdcc: missing library functions
htc 7.50: 41038 bytes
* eliza (352 lines, uses several stdio functions on input and output sides) compiled for cpm
z88dk+sdcc: 8324 bytes
sdcc: missing library functions
htc 7.50: 15193 bytes
Это всё понятно и хорошо выглядит "на картинках". мне не понятно, зачем применять такие извращённые методы сборки, как совмещение двух разных компиляторов? если уж на то пошло, почему просто не дизасемблировать тот же htc 3.09 for cp/m, который бесплатный и не применить кодогенерацию по его образу и подобию+свои оптимизации. Сильно не удобно, если честно, использовать длинные конструкции для сборки одного кода из двух разных компиляторов, пусть и в обном bat файле. Запоминать гору ключей, библиотек. Это всё заморочки не нужные. Куда проще взять эмулятор cpm для windows, взять бесплатный htc и спокойно мелким батником это собирать. Хотя и make хорошо прикручивается.
Опять таки, сидел ставил эксперименты по тематике ray casting`а понял, что sdcc всё ровно выдаёт более тяжёлый код, даже на фоне старого htc. А уж применять замудрённые конструкции из z88dk и sdcc в одном флаконе, я даже и думать не собирался. сделайте нормальную кодогенерацию z88dk без применения жёстких танцев с бубном, тогда и интерес появится. Кстати, во всех этих извратных манипуляциях и библиотеках, поддержки спринтера так и нет.
s_kosorev
10.03.2016, 10:09
если уж на то пошло, почему просто не дизасемблировать тот же htc 3.09 for cp/m, который бесплатный и не применить кодогенерацию по его образу и подобию
а смысл? проще использовать эмулятор cp/m и ничего не дизассемблировать, даже можно собрать эмулятор с образом, переадресацию аргументов сделать и будет 1 файл, хотя смысла особого нет.
а смысл? проще использовать эмулятор cp/m и ничего не дизассемблировать, даже можно собрать эмулятор с образом, переадресацию аргументов сделать и будет 1 файл, хотя смысла особого нет.
очень хочется иметь всё тот же htc, но именно виндовый, чтобы каталоги понимал, нормальные пути и файлы генерил с точностью до байта, а не до 128 байт как cp/m`ный. Если бы его разобрать и создать компилятор под винду с уровенм качества кода как у htc, было бы здорово. но sdcc как и z88dk пока не дотягивают. Кроме того, у асма для htc есть серия ошибок и не доработок как, например, нет поддержки недокументированных регистров типа ixh, ixl и подобных, нет макросов, нет разных прочих интресных и удобных конструкций. Можно было бы применять htc 7.80, но он для ms-dos`а, т.е. его употребление ещё более геморное, т.к. требует запуска dosbox`а.
Lethargeek
10.03.2016, 12:31
Смысл функции в инкапсуляции того, что она делает внутри, и выдвигании наружу только интерфейса вызова. То есть то, что ф-ция скрывает механизмы и детали её реализации, гарантирует безболезненную её доработку и т.п. И иметь доступ к локальным переменным ф-ции в этом смысле не есть правильно. Если вызываешь кусок на асме, оформь его как другую ф-цию и вызывай из первой сишной, передавая локальные переменные ей как параметры. Это и будет правильно.
Ну так речь о части той же функции на ассемблере, с тем же автором, никаких инкапсуляций не нарушается. Смысл вставки в ускорении этой функции, и неправильно - городить для этого лишний вызов. Оптимизацию, конечно, надо блокировать, в идеале - только для данной функции (помнится, на песюках в лохматые времена компилятор, встретив ассемблерную вставку, нафиг отключал оптимизацию всего модуля и перезапускал компиляцию, не знаю как выкручиваются сейчас)
s_kosorev
10.03.2016, 15:48
можно несколько inline функций сделать, которые будут разные регистры устанавливать, это если речь идет о функционале а не оптимизации
ldA, ldBC, ldBCDE итд
Alcoholics Anonymous
11.03.2016, 03:20
мне не понятно, зачем применять такие извращённые методы сборки, как совмещение двух разных компиляторов?
Я не уверен, почему вы думаете об этом как извращенное? Набор компилятор состоит из трех независимых частей: (1) язык переводчик, переводит с C (например) ASM, (2) библиотеки функций, и (3) ассемблер / линкера / библиотекаря, который может построить двоичные файлы. Это не редкость, чтобы иметь возможность поменять детали, особенно библиотеку. Есть несколько библиотек C, доступных для загрузки, которые можно использовать в комбинации с любым компилятором, который соответствует замена из (2). Многие современные компиляторы могут составлять для нескольких языков, что соответствует замена из (1). Visual Studio может скомпилировать C, C ++, C #, Fortran, .... все, используя один и тот же код .NET и компоновщик. Существует даже пример старого компилятора с 1980-х годов под названием Kit Amsterdam Compiler, который может скомпилировать C, Pascal, Fortran и предназначается для нескольких процессоров. Все одни и те же библиотеки кода и ассемблер но язык переводчик выгружена в зависимости от языка.
I'm not sure why you think of it as perverse? A compiler kit is composed of three independent parts: (1) a language translator that translates from C (for example) to asm, (2) a library of functions, and (3) an assembler / linker / librarian that can build binaries. It's not unusual to be able to swap out parts, especially the library. There are several C libraries available for download that can be used in combination with any C compiler which corresponds to swapping out (2). Many modern compilers can compile for several languages which corresponds to swapping out (1). Visual Studio can compile C, C++, C#, Fortran, .... all using the same .NET code and linker. There is even an example of an old compiler from the 1980s called the Amsterdam Compiler Kit that can compile C, Pascal, Fortran and targets multiple CPUs. All share the same library code and assembler but the language translator is swapped out depending on the language.
Это ничем не отличается в z88dk. Вы можете выбрать, какой компилятор C для использования (есть два варианта сейчас), и вы можете выбрать, какую библиотеку использовать (есть также два варианта). В будущем очень хорошо могут быть и другие варианты для C компилятора или компиляторы для других языков. Пределы только до доступного времени и интересов вкладчиков.
This is no different in z88dk. You can choose which C compiler to use (there are two choices now) and you can choose which library to use (there are also two choices). In the future there very well may be other choices for C compiler or compilers for other languages. The limits are only down to available time and interests of contributors.
если уж на то пошло, почему просто не дизасемблировать тот же htc 3.09 for cp/m, который бесплатный и не применить кодогенерацию по его образу и подобию+свои оптимизации.
HTC 3.09 для имп не был бы лучшим выбором, но, как вы читали, я не неблагоприятных для добавления других переводчиков :)
HTC 3.09 for cpm wouldn't be the best choice but as you've read I'm not adverse to adding other translators :)
Сильно не удобно, если честно, использовать длинные конструкции для сборки одного кода из двух разных компиляторов, пусть и в обном bat файле. Запоминать гору ключей, библиотек. Это всё заморочки не нужные.
Я не знаю, почему вы думаете, что это трудно построить двоичные файлы. Это, как я скомпилировать программу для CP / M с помощью SDCC:
I'm not sure why you think it's difficult to build binaries. This is how I compile a program for cp/m using sdcc:
zcc +cpm -vn -SO3 -clib=sdcc_iy --max-allocs-per-node200000 test.c -o test
Это все. Выход "test_CODE.bin", который может быть переименована в "test.com". Это файл ком запуске в CP / M
Эта же программа составлена для гх с использованием SDCC:
That's all. The output is "test_CODE.bin" which can be renamed "test.com". That's the com file you run in cp/m
The same program compiled for zx using sdcc:
zcc +zx -vn -SO3 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test
Это все. Выход "test_CODE.bin", который может быть загружен по адресу 32768 и RAND USR 32768, чтобы запустить его. Если вы хотите, чтобы сделать водопроводную файл, который вы можете запустить appmake на нем (appmake является инструментом в z88dk).
Если ваш проект содержит несколько исходные файлы Си и несколько ASM файлы, которые вы можете собрать его так:
That's all. The output is "test_CODE.bin" which can be loaded at address 32768 and RAND USR 32768 to run it. If you want to make a tap file you can run appmake on it (appmake is a tool in z88dk).
If your project contains several C source files and several asm files you can compile it like this:
zcc +zx -vn -SO3 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test1.c test2.c test3.c m1.asm m2.asm -o test
Это все. Выходной сигнал будет "test_CODE.bin"
Там нет сложных пакетных файлов - только одна строка компиляции. Если вам нужна более сложная обработка файлов или вы хотите индивидуально компилировать C Источник, вы можете использовать пакетный файл или Makefile конечно.
Я не думаю, что это можно сделать проще. Вы могли бы думать о SDCC, которая требует от вас индивидуально компиляции исходных файлов, связать их вместе, а затем запустить ihx2bin, чтобы сгенерировать двоичный файл.
That's all. The output will be "test_CODE.bin"
There are no complicated batch files -- just one compile line. If you need more complicated processing of your files or you want to individually compile c source, you can use a batch file or makefile of course.
I don't think it's possible to be made simpler. You might be thinking of sdcc which requires you to individually compile source files, link them together and then run ihx2bin to generate a binary.
Куда проще взять эмулятор cpm для windows, взять бесплатный htc и спокойно мелким батником это собирать. Хотя и make хорошо прикручивается.
Опять таки, сидел ставил эксперименты по тематике ray casting`а понял, что sdcc всё ровно выдаёт более тяжёлый код, даже на фоне старого htc.
SDCC код может быть улучшена, и мы работаем над этим все время. Я был бы заинтересован в том, что некоторые из исходного кода, чтобы мы могли увидеть, если мы могли бы улучшить выход, если он уже не улучшается z88dk. Мы можем исправить многое, но не все, так как мы только пытаемся улучшить код после того, как он уже был создан компилятором. Код выхода из SDCC, когда используется z88dk не то же самое, как то, что выходит из SDCC сам по себе.
Иногда вы должны помочь компилятор генерировать лучший код, сделав некоторые статические переменные, или разбивать большие функции на множество мелких.
sdcc's code can be improved and we work on this all the time. I would be interested in seeing some of that source code so we could see if we could improve output, if it isn't already improved by z88dk. We can fix many things but not everything since we are only trying to improve code after it has already been generated by the compiler. The code coming out of sdcc when used by z88dk is not the same as what comes out of sdcc by itself.
Sometimes you have to help the compiler generate better code by making some variables static or by breaking large functions into many smaller ones.
Кстати, во всех этих извратных манипуляциях и библиотеках, поддержки спринтера так и нет.
Еще нет. Новая библиотека C имеет только три цели в данный момент: Zx СРМ и внедренные. Мы концентрируясь на добивании модель драйвера и дискового ввода / вывода, прежде чем мы начнем перенос на новые цели.
Классическая библиотека C действительно имеет экспериментальную поддержку спринтер, включая файл ввода / вывода, но это не представляется возможным использовать SDCC для компиляции для классической библиотеки C пока. Вот над этим работают в настоящее время.
http://www.z88dk.org/wiki/doku.php?id=targets
Not yet. The new c library only has three targets currently: zx, cpm and embedded. We're concentrating on finishing the driver model and disk i/o before we start porting to new targets.
The classic C library does have experimental support for the sprinter including file i/o but it is not possible to use sdcc to compile for the classic c library yet. That's being worked on now.
http://www.z88dk.org/wiki/doku.php?id=targets
http://nightly.z88dk.org/
ассемблер отдельно взятых си компиляторов, к сожалению. только к ним и относятся и никакими другими не заменить.
Не припоминаю чтобы к сдцц можно было бы прикрутить тот же sjasm для генерации z80 кода.
Во-первых, функции для библиотек можешь писать на чём хочешь, главное, обеспечь их сборку в rel или lib.
Во-вторых, с ключиком --asm= можно заставить SDCC генерировать ассемблерный текст для других ассемблеров - пожалуйста, можешь редактировать и компилить отдельно любимым асмом.
справедливое замечание про решётку. Похоже, что асм от сдцц вообще десятичные числа не воспринимает, точнее воспринимает но, только с этой пресловутой решёточкой.
Снова здорова! :v2_dizzy_facepalm: Да вы чем читате?! Даже если ты шестнадцатиричное число без неё наберёшь, асм это тоже не поёмет. Решётка - обозначение непосредственной адресации. Для Z80 такой синтаксис, конечно, избыточен, это издержки унификации.
сдцц, как и z88dk, базируется на древнем цпм компиляторе small-c. Только вот z88dk по части асма более близок к пользователю, а в sdcc всё сильно извратили.
Как говорится, одни ищут возможности, другие - причины. Если уж так решётки не нравятся - что, нельзя скриптик написать для их "выкусывания"?
ТАКАЯ БОЛЬШАЯ проблема! Самому-то не смешно? ;)
Лично, я, вообще, никаких проблем с переходом на этот синтаксис не заметил - даже мысли не возникло претензии по этому поводу предъявлять.
К слову говоря о бесплатности и "лучшести" - не совсем близкие значения.
Боюсь, ты будешь шокирован, но эти значения ещё дальше друг от друга, чем тёплое и мягкое. :)
Может для всяких pic`ов и подобных он и лучший, но для z80 не фонтан, откровенно говоря. Даже твои тесты показывают, что sdcc уступает древнему и бесплатному htc (кстати, ты табличку так и не подправил).
Таблички все поправлены. Лучше SDCC код дали только HTC 7.50 и z88dk, использующий пропатченый (ВНЕЗАПНО) sdcc. Что касается htc то, боюсь, если ты решётку в sdcc не осилил, то танцы с бубном в компании DosBOX, htc7.50, cp/m эмулятора и htc3.09, чтобы собрать файл для спека, и подавно.
HTC7.50 можно использовать в случае, если не жалко усилий ради конечного результата.
- - - Добавлено - - -
Как, кстати, получить доступ к локальным переменным функции в SDCC со стороны ассемблера ?
Если функция написана тобой на ассемблере и, стало быть, ты точно знаешь смещение переменных относительно начала подпрограммы, то
можно взять указатель на эту функцию и прибавить к нему смещение переменной.
Если тебе это понадобилось, значит, 99,99% ты что-то делаешь не правильно. Если эта переменная требуется где-то ещё, объяви её ГЛОБАЛЬНОЙ.
не понравилась мне прошлая писанина. переписал слегка...
во1х, у нас речь про sdcc, так? какие из существующих, например, ассемблеров, умеют генрировать rel/lib, тем более совместимый с sdcc? таких нет. даже древнющие m80, zmac и подобные не смотря на наличие rel, они не совместимы с sdcc.
во2х, на кой чёрт мне использовать ни с чем не совместимый синтаксис асма sdcc? к какому компилятору мне его потом прикладывать? таких тоже нет.
в3х, в sdcc на асме решётка применяется для обозначения 10тичного числа. для 16тиричных чисел используется 0x. Если перенесёшь числа с решёткой в тот же sjasm, то кроме ошибок в своём проекте ничего не получишь.
в4х, htc 3.09 в паре с эмулятором cpm под виндой (консольный эмулятор) прекрасно генерит у меня код и для cpm и для профи (не дописал библиотеку) и для спринтера. не вижу тут сильного гемора, хотя есть некоторые выбешивающие моменты.
в5х, по твоей таблице htc 3.09 с включённым оптимизатором выдаёт результат в 483/472 секунд, а sdcc (в табличке 3.51, видимо правленый) выдаёт 528 765, т.е. медленнее. я потому и спросил, почему табличку не исправляешь.
мне вот только одного не ясно, в чём заключается смысл защищать продукт, который по качеству генерируемого кода хуже, чем доистрический htc?
во1х, у нас речь про sdcc, так? какие из существующих, например, ассемблеров, умеют генрировать rel/lib, тем более совместимый с sdcc? таких нет. даже древнющие m80, zmac и подобные не смотря на наличие rel, они не совместимы с sdcc.
Это частности, которые к делу не относятся. Нету? - не ной, напиши конвертер! Мне это не надо знать - меня и так всё устраивает, как и большинство, пишущих на Си для z80.
Прелесть sdcc в том, что можно Сишный текст и функции на асме держать в одном исходнике, и можно по ходу дела, в них что-то поправить, а затем в один клик скомпилить готовый результат.
В HTC 3.09 так нельзя, потому что, хоть он и допускает такое размещение, после оптимизатора твоя асмовая функция может быть изменена до неузнаваемости. Поэтому приходится держать в разных исходниках, изменять отдельный исходник, потом ассемблировать ручками в объетник, а уже ПОТОМ собирать весь проект и оценивать результат.
Если по сравнению с этим вы решётку считаете неудобством, то увольте. ;)
во2х, на кой чёрт мне использовать ни с чем не совместимый синтаксис асма sdcc? к какому компилятору мне его потом прикладывать? таких тоже нет.
Прекрасно компилится, например, sdasz80.exe.
в3х, в sdcc на асме решётка применяется для обозначения 10тичного числа. для 16тиричных чисел используется 0x.
Нет, ну хватит уже вводить общественность в заблуждение. Чего пишешь, если мат.части не знаешь?
А ваш любимый SJasm вообще не умеет из консоли бинарники выдавать - я ж молчу.
в4х, htc 3.09 в паре с эмулятором cpm под виндой (консольный эмулятор) прекрасно генерит у меня код и для cpm и для профи (не дописал библиотеку) и для спринтера. не вижу тут сильного гемора, хотя есть некоторые выбешивающие моменты.
7.50, 7.50, семь-пятьдесят, СЕМЬ-ПЯТЬДЕСЯТ! - "Танцы с бубном" касаются только версии СЕМЬ-ПЯТЬДЕСЯТ ДЛЯ MS-DOS.
1) Запускаешь DOS-BOX
2) Запускаешь HTC_7.50,
3) Открываешь в его IDE файл на Си
4) Генеришь ассемблерный файл.
5) Выходишь из DOS-BOX
6) Правишь полученный исходник под формат HTC_3.09.
7) Запускаешь скрипт, применяющий к исходнику ассемблер и линкер из комплекта HTC_3.09.
8) Радуешься жизни.
в5х, по твоей таблице htc 3.09 с включённым оптимизатором выдаёт результат в 483/472 секунд, а sdcc (в табличке 3.51, видимо правленый) выдаёт 528 765, т.е. медленнее. я потому и спросил, почему табличку не исправляешь.
мне вот только одного не ясно, в чём заключается смысл защищать продукт, который по качеству генерируемого кода хуже, чем доистрический htc?
В адвокаты SDCC я не записывался, - просто, я за всё хорошее против всего плохого.
Ты зачем перевираешь данные из моей таблицы?! Не 483/472, а 432/1814 принадлежит HTC 7.50, а не 3.09. Так что, определённо, лучше, чем SDCC, - только HTC 7.50.
DI
DI/Gl.vars
Коэфф.
HiTech C v.7.50 (MS-DOS)
432
1814
0,74
SDCC v.3.51 (Win32)
528
765
0,612
HiTech C v.3.09 (cp/m, z80)
979
856
0,3320/0,3773
На мой взгляд, серьёзных бесплатных компиляторов сейчас доступно 4: sdcc, z88dk и HTC 3.09/7.50. Какой использовать - дело вкуса.
Нету? - не ной, напиши конвертер!
ну да, мне заняться больше не чем же)))
Прелесть sdcc в том, что можно Сишный текст и функции на асме держать в одном исходнике,
это очень сомнительное удовольствие. я не готов платить производительностью и памятью за столь мелкое удовольствие.
Если по сравнению с этим вы решётку считаете неудобством, то увольте
если мне нужны асмовые вставки, то я выношу асм в отдельный файл в виде отдельных процедур/функций. это совершенно не мешает. Решётка которой почему то разрабы решили обозначить адресацию и 10чные числа вводит в заблуждение тех, кто впервые пришёл к коду на sdcc и пытается перенести этот код в свои проекты на других компиляторах. надеюсь понимаешь. что когда ты пишешь 10 и #10 это два разных числа и результаты у программы будет разными. Вариант при котором ты предлагаешь сидеть и пилить 100500 конверторов, скриптов и других фигнов для переноса текста sdcc является не корректным. может тебе, в меру своей любопытности или может у тебя времени свободного полно, интересно сидеть за такими делами, а большинству нужен рабочий и исправный инструмент. желательно применяющий общеизвестные стандарты. не видно что-то армий и полчищ поклонников sdcc, которым нравятся все его извраты.
Ты зачем перевираешь данные из моей таблицы?!
извиняй, а это тогда что?
http://savepic.ru/8950364.png
7.50, 7.50, семь-пятьдесят, СЕМЬ-ПЯТЬДЕСЯТ! - "Танцы с бубном" касаются только версии СЕМЬ-ПЯТЬДЕСЯТ ДЛЯ MS-DOS.
1) Запускаешь DOS-BOX
2) Запускаешь HTC_7.50,
3) Открываешь в его IDE файл на Си
ВНЕЗАПНО, IDE тут вообще не нужен.
А ваш любимый SJasm вообще не умеет из консоли бинарники выдавать
ОПА, sdcc не выдаёт с ходу бинарник, он выдаёт в формате ihx, который потом нужно конвертить в бинарник. а что значит не выдаёт из консоли бинарник? ты про это:
..\..\asm\sjasm.exe -L %1.asm %1.exe %1.lst
??
Oleg N. Cher
13.03.2016, 08:20
это очень сомнительное удовольствие. я не готов платить производительностью и памятью за столь мелкое удовольствие.Пустая программа void main(void){ return; } занимает после компиляции SDCC 1 байт - RET. Это весь оверхед. Бери и сшивай асм код прямо из Си:
LD(a,10);
LD(b,7); // Макросы
Func1();
LD(c,1);
Func2();О каких потерях производительности и памяти вообще идёт речь?
Пустая программа void main(void){ return; } занимает после компиляции SDCC 1 байт - RET
вы ещё crt0 забыли приписать сюда. и для чего мне использовать пустой код для сшивания асма, если я и так на асме могу писать? зачем тогда си? что-то не понял я этого прикола. одно дело, когда логика описывается на сях, а тяжёлые процедуры на асме и другое дело пилить пустой си файл ради...собственно говоря чего? логики не вижу что-то...
О каких потерях производительности и памяти вообще идёт речь?
даже не знаю что сказать. типа, код генерируется совершенно ресурсонезависимый. даже не знаю что тут можно сказать. табличка описанная Сергеем показывает какой компилятор выдаёт лучший по производительности код. потеря по памяти - один и тот же код sdcc и htc 3.09 выдают разной длинны. sdcc примерно на 2 - 4 килобайта больше. и это ещё небольшая разница. у меня htc на одном исходнике выдал около 8кб бинарника, а sdcc почти 15кб. т.е. почти в 2 раза разница. на кой чёрт оно такое счастье нужно?
прямо сейчас попытался засунуть ещё один код в sdcc, но он упорно не желает принимать стандартные вещи для всех известных компиляторов.
подсовывал как-то ради интереса в sdcc код на си, который любая версия htc сжирает с потрохами и выдаёт рабочий на 146% бинарник. sdcc от этого исходника плюётся по сей день. могу скинуть ради интереса (letteral code так называемый или просто демка aes256).
sdcc варится сам в себе со своими собственными какими-то приблудами которые понимают только разве что сам разраб и ещё с десяток фанатов. в общем, эту тему пора прикрыть. кому нравится извращаться, ну, продолжайте дальше. Только вот я про табличку так и не понял, данные есть, но они вынесены за пределы. в чём прикол то?
denpopov
14.03.2016, 09:35
народ, давайте поищем приличный Паскаль для з80.
народ, давайте поищем приличный Паскаль для з80.
все известные паскали выдающие код в z80:
http://www.z80.eu/pas-compiler.html
про кросс средства ничего не слышал. кажется, таких нет. под трдос ещё что-то было. ну, ещё оберон какой-то в соседних темах предлагают...
s_kosorev
14.03.2016, 10:59
На форуме рассматривался Oberon, можно сказать Pascal с нюансами
denpopov
14.03.2016, 14:56
про кросс средства ничего не слышал. кажется, таких нет. под трдос ещё что-то было. ну, ещё оберон какой-то в соседних темах предлагают
Не, оберон в топку. cp/m похоже гонит бинарники, а не листинг. Видел некое кросс-средство под msx, это уже интереснее.
DI
DI/Gl.vars
Коэфф.
Ассемблер (эталон)
323
323
1,00
HiTech C v.7.50 (MS-DOS)
432
1814
0,74
Z88DK (Win32)
512
-
0,631
SDCC v.3.51 (Win32)
528
765
0,612
IAR (Win32)
803
858
0,4022
HiTech C v.3.09 (cp/m, z80)
979
856
0,3320/0,3773
Aztec C (cp/m, i8080)
1738
-
0,186
HiSoft-C v.1.35 (CP/M, Z80)
3660
0,0000/0,0882
MI-C v3.18I (CP/M, Z80)
4160
3760
0,0776/0,0859
WarpC 14.01 (TR-DOS, Z80)
4910
4640
0,0660/0,0696
MeSCC 1.08 (CP/M, i8080)
8370
4850
0,0386/0,0667
Тут поступило ценное предложение, мопед не мой потому просто процитирую:
Исправить тест и перетестировать iar, hitech 7.50 и sdcc (iar не умеет оптимизировать деление на степень двойки, вызывает библиотечную функцию деления)
заменить
dest = (unsigned char*)(ScreenTable[atY]+atX/2);
на
dest = (unsigned char*)(ScreenTable[atY]+(atX>>1));
заменить
*dest = q | ((*src++)/16&0x0f);
на
*dest = q | (((*src++)>>4)&0x0f);
компилировать iar'ом с опциями
iccz80.exe -K -T -e -uua -g -s9 -q
Тут поступило ценное предложение...
Увы, пока некогда. Позже.
Но то, что ИАР так с делением на степени двойки обходится - слов нет... Это уже минус - т.к. придётся вручную править исходник при портировании.
- - - Добавлено - - -
1. Найди CP/M паскаль, который может генерить код под произвольный адрес, поставишь REXX, и будет тебе счастье.
2. Найди конвертер исходников, и тоже будет тебе счастье. ;)
perestoronin
13.05.2016, 17:29
Еще один компилятор Small C version C3.0R1.1 (SCC3) Chris Lewis (https://github.com/ncb85/SmallC-85/tree/master/smallC) (пока лишь для 8080, 8085 и 6809)
Все из категории СПО.
А также и сам кросс-ассемблер, последнюю версию которого планируют полностью включить в sdcc 3.6.0
http://shop-pdp.net/ashtml/asxxxx.htm
Если кто Linux Gentoo пользует, то будет полезной ссылка (http://portage.perestoroniny.ru/dev-embedded/), не все там рабочее, но я работаю над тем, чтобы все работало.
Еще один компилятор Small C version C3.0R1.1 (SCC3) Chris Lewis (https://github.com/ncb85/SmallC-85/tree/master/smallC) (пока лишь для 8080, 8085 и 6809)
crt0 (т.е. cret.asm) у них там какой-то неправильный, не взлетит.
Первая команда д.б не sphl, а lxi h,0 / dad sp
Перед вызовом Xarglist надо положить в стек адрес DMA по-умолчанию (где будут аргументы, в CP/M это 80h), т.е. lxi h,128 / push h
perestoronin
14.05.2016, 06:55
какой-то неправильный
У них все "неправильное", например System14 (a CP/M look alike / replacement for Z80 based systems) (http://panteltje.com/panteltje/z80/system14/), кстати в исходниках на ассемблере Z80.
А руки на что? Чтобы под себя править, исходники то есть, а это главное условие, чтобы править и совершенствовать инструменты, а не писать эмуляторы и трансляторы нативные для запуска проприетарных непотребностей.
Smalovsky
08.09.2016, 23:24
Скажите почему функция курсор не работает? Должна менять позицию вывода. Правильно ли я получаю параметры в ассемблерных вставках?
#include <stdio.h>
#include <stdlib.h>
int print(char* string, unsigned int length );
void cursor(char x, char y);
void cls();
void pause (unsigned int delay);
int main()
{
int i=0;
cls();
print("TEST", 4);
pause(0);
cls();
for(i=0;i<11;i++){
cursor(i, 10);
print("TEST2", 5);
}
return 0;
}
int print(char* string, unsigned int length ){
__asm
ld hl, #2
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
inc hl
ld c, (hl)
inc hl
ld b, (hl)
call 8252
ret
__endasm;
}
void cursor(char x, char y){
__asm
ld hl, #2
add hl, sp
ld a, #2
call 5633
ld b, (hl)
inc hl
inc hl
ld c, (hl)
ld a,#22
rst 16
ld a, c
rst 16
ld a, b
rst 16
ret
__endasm;
}
void cls(){
__asm
call 3435
ld a, #2
call 5633
ret
__endasm;
}
void pause (unsigned int delay){
__asm
ld hl, #2
add hl, sp
ld c, (hl)
inc hl
ld b, (hl)
call 7997
ret
__endasm;
}
OrionExt
08.09.2016, 23:30
:v2_blink:Какой компилятор использовался Си? Для начала хотя бы. С какими параметрами компиляции? Какая платформа? Что это за вызовы внутри ассемблерный вставок?
Smalovsky
08.09.2016, 23:41
Ощепринятый компилятор среди спектрумистов - SDCC. Параметры компиляции - -mz80, --no-std-crt0. Платформа - спекки48. Параметры линкера - --code-loc 0x7530, --data-loc 0xA530. Файл хекс прогнал через хекс2бин и бин2тап.
В функции курсор, сначала устанавливается поток 2( экран), затем вывадятся в поток управляющие символы - 22( позиция курсора) и переданые координаты вывода на экране. Результат - выводится TEST, пауза до нажатия клавиши, очистка экрана, вывод десять раз TEST2 в одно и тоже место на экране без смены позиции вывода. Позиция вывода должна меняться в цикле, но на экране изменения нет.
OrionExt
08.09.2016, 23:51
SDCC, меня аж дергает. Тут нужен специалист, который познал инь и ян:D А если серьезно посмотрите на выходе компилятора, что у вас получилось на ассемблере. У меня SDCC эти вставки (кусочки) иногда съедал без следа, и все это называлось оптимизацией.
И версию SDCC? От этого много зависит)
Smalovsky
09.09.2016, 00:49
Версия компилятора - 3.5.0. Функция понастоящему нужна. Иначе меню на экран даже не выведешь...
- - - Добавлено - - -
Я, наверно, ошибся. Нельзя чередовать посимвольный вывод и вывод последовательности символов. Буду делать новую функцию - всё через последовательность символов.
Я решил параметры брать не через восстановление стека, а через чтение памяти по базе указатель стека+2 (два байта занимает адрес возврата).
OrionExt
09.09.2016, 01:00
Пути SDCC неисповедимы в работе. Лишь бы у вас сил хватило, понять:)
Почти свежак. 3.6.0 уже на дворе.
От версии к версии исходники не компилируются (часто) на SDCC. Лучше тут разобраться, в чем причина. Так с на скоку тяжело понять. Я Пас. Вы исходные данные написали, может, кто поможет.
Smalovsky
09.09.2016, 13:56
Разобрался в чём причина. Компилятор две переменных типа char сохранил в стеке как одну пару байтов, а я думал что каждую переменную сохранит в отдельной паре.
Исправленная функция.
void cursor(char x, char y){
__asm
//call 3405 - лучше сброс временных атрибутов вынести в отдельную функцию
ld hl, #2
add hl, sp
ld b, (hl)
inc hl
ld c, (hl)
ld a,#22
rst 16
ld a, c
rst 16
ld a, b
rst 16
ret
__endasm;
}
Oleg N. Cher
09.09.2016, 15:31
void Basic_AT_ROM_stdcall (unsigned char x, unsigned char y) __naked {
__asm
;LD IY,#0x5C3A
;LD A,#2
;CALL 0x1601 // IX-safe
LD A,#22
RST 16
POP HL
POP BC
PUSH BC
LD A,B // x
RST 16
LD A,C // y
RST 16
JP (HL)
__endasm;
} //Basic_AT_ROM_stdcall
Smalovsky
09.09.2016, 23:22
Написал меню на Си. Размер кодового блока 353 байта. Меню совсем простое, можно на бейсике такое сделать. Сколько в памяти будет занимать аналогичная программа на бейсике?
Непонятно, почему при очистке экрана не закрашивается область системных сообщений? Хотя вроде нормальную функцию очистки экрана написал.
void cls(){
__asm
call 3435
ld a, #2
call 5633
ret
__endasm;
}
ld a, #2
call 5633
почитай про каналы, для системных сообщений применяется другой номер
Alcoholics Anonymous
10.09.2016, 02:37
Здравствуй,
void cursor(char x, char y){
__asm
ld hl, #2
add hl, sp
ld a, #2
call 5633
ld b, (hl)
inc hl
inc hl
ld c, (hl)
....
Вы уверены, что "call 5633" не изменяет HL?
SDCC толкает символов в виде одного байта в стек. Так оно и должно быть "ld b,(hl); inc hl; ld c,(hl)"
Еще одна проблема связана с регистром IY.
1. Если у вас есть обработчик прерываний на 0x38 ром работает, ваша программа не может изменять IY.
2. Если вы используете Rom подпрограммы для выполнения таких задач, как печать, IY должен быть установлен на значение, ожидаемое РОМ.
Чтобы предотвратить SDCC от модификации IY вы должны компилировать с флагом "--reserve-regs-iy". Однако это не остановит SDCC от использования IY, если кадр стека становится большим.
Лучший способ на гх, чтобы обойти эту проблему, чтобы отключить прерывания или заменить РОМ ISR и убедитесь, что IY устанавливается на ожидаемое значение, прежде чем сделать Rom вызовы, которые зависят от него. Если вы не сделаете это, вы будете испытывать странные сбои.
Hi,
void cursor(char x, char y){
__asm
ld hl, #2
add hl, sp
ld a, #2
call 5633
ld b, (hl)
inc hl
inc hl
ld c, (hl)
....
You're sure "call 5633" does not modify HL?
sdcc pushes characters as single bytes onto the stack. So it should be "ld b,(hl); inc hl; ld c,(hl)"
Another problem has to do with the IY register.
1. If you have the rom interrupt routine at 0x38 running, your program cannot modify IY.
2. If you use rom subroutines to carry out tasks like printing, IY must be set to the value expected by the rom.
To prevent sdcc from modifying IY you must compile with the "--reserve-regs-iy" flag. However this will not stop sdcc from using IY if the stack frame becomes large.
The best way on the zx to get around this problem is to disable interrupts or replace the rom isr and make sure IY is set to the expected value before you make rom calls that depend on it. If you don't do this you will experience odd crashes.
Smalovsky
10.09.2016, 23:47
Что бы экран очищался правильно, нужно атрибуты устанавливать не только для основного экрана, но и для окна системных сообщений.
void setattr(char attrib){
__asm
ld hl, #2
add hl, sp
ld a, (hl)
ld (23693), a
ld (23624),a
__endasm;
}
Alex Rider
12.09.2016, 20:20
Вы уверены, что "call 5633" не изменяет HL?
5633 точно изменяет hl. Координаты возьмутся из космоса.
Error404
12.09.2016, 22:31
Общепринятый. :)
Powered by vBulletin® Version 4.2.5 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot