Оберон-клуб «ВЄДАsoft» https://zx.oberon.org/forum/ |
|
Что за SYSTEM_HALT() в макросах SYSTEM.H? https://zx.oberon.org/forum/viewtopic.php?f=10&t=230 |
Страница 1 из 1 |
Автор: | Saferoll [ 30 ноя 2014, 20:51 ] |
Заголовок сообщения: | Что за SYSTEM_HALT() в макросах SYSTEM.H? |
Насколько я понял, SDCC до сих пор не понимает оператор присваивания для всей записи целиком (проблема Feature cannot assign values to aggregates). Пока пробирался в дебрях Ofront, вроде бы нашёл идею, как вместо присваивания генерировать макрос, который потом можно заменять на memcpy или что-то подобное. Но тут вылезла другая ошибка, связанная с охраной типов. Программа Код: "OBERON"
Код: "C" /* Ofront 1.2 -xtspkaem */ Код: "TEXT" AsgnRec.c:37: error 101: too many parameters Удалось выяснить, что _GUARDEQP (и прочие "охранники") задаются в SYSTEM.H макросами вида Код: "C" #define __GUARDEQP(p, typ) if(__TYPEOF(p)!=typ##__typ)__HALT(-6);*(p) в которых __HALT сводится строчкой Код: "C" #define __HALT(x) SYSTEM_HALT(x) Код: "C" extern void SYSTEM_HALT(); Что же это за процедура SYSTEM_HALT и сколько у ней должно быть параметров? |
Автор: | geniepro [ 30 ноя 2014, 22:28 ] |
Заголовок сообщения: | Что за SYSTEM_HALT() в макросах SYSTEM.H? |
Saferoll писал(а): Код: "C" extern void SYSTEM_HALT(); Что же это за процедура SYSTEM_HALT и сколько у ней должно быть параметров? Насколько я помню, в сях такое объявление означает, что функция SYSTEM_HALT не возвращает результата и имеет неопределённое на данном этапе количество параметров... |
Автор: | Saferoll [ 30 ноя 2014, 22:41 ] |
Заголовок сообщения: | Re: Что за SYSTEM_HALT() в макросах SYSTEM.H? |
geniepro писал(а): Насколько я помню, в сях такое объявление означает, что функция SYSTEM_HALT не возвращает результата и имеет неопределённое на данном этапе количество параметров... Мне тоже что-то такое вспоминается (А если extern void SYSTEM_HALT(void);, то это явно функция без параметров), но что тогда значит ошибка "too many parameters"? И где тогда, задаётся конкретная функция SYSTEM_HALT с конкретным числом параметров?Кстати, в конце файла SYSTEM.H есть /* ANSI prototypes; not used so far ... void SYSTEM_HALT(int n); */ Может быть раскомментировать? Если эта функция объявлена, она где-то должна быть "в натуре" - в той среде, в которой скомпилированная программа должна выполняться. |
Автор: | Saferoll [ 01 дек 2014, 09:11 ] |
Заголовок сообщения: | Re: Что за SYSTEM_HALT() в макросах SYSTEM.H? |
Эта же проблема возникает, если использовать в транслируемой программе ASSERT. Вывод - Ofront не просто транслирует синтаксис Оберона в синтаксис Си, как это делает Oberon Script для javascript. Ofront старается перенести и положительные runtime-свойства. Но для этого в среде выполнения должны быть процедуры system_halt и прочие, а макросы в файлах конфигурации должны на них указывать. И мы должны с этим разобраться и либо всё это верно настроить, чтобы действовало, либо отключить, чтобы не выдавало непонятных ошибок. Либо описать в документации, что такое-то средство Оберона применять нельзя, потому что оно еще не реализовано и выдаёт ошибки при компиляции Си-программы. |
Автор: | Zorko [ 01 дек 2014, 10:34 ] |
Заголовок сообщения: | Re: Что за SYSTEM_HALT() в макросах SYSTEM.H? |
Saferoll писал(а): Насколько я понял, SDCC до сих пор не понимает оператор присваивания для всей записи целиком (проблема Feature cannot assign values to aggregates). Да, пока не спешат исправить. У них там специализация. Филипп Краузе, с которым налажен контакт, по бэку Z80, во фронт-энд не лезет. А Эрик Петрич, или кто у них там по фронту, задвинул это дело в долгий ящик.Я пока что делаю так: Код: "OBERON"
Код: "OBERON"
Saferoll писал(а): Но тут вылезла другая ошибка, связанная с охраной типов. Это ошибка отсутствия реализации процедуры SYSTEM_HALT в ZXDev. Я собрал твой код (убрав импорт) в WinDev, всё скомпилиорвалось.Код: "TEXT" AsgnRec.c:37: error 101: too many parameters Saferoll писал(а): SYSTEM_HALT, которая в этом же файле SYSTEM.H определена как процедура без параметров Всё не так просто. Это объявление в "старом стиле", где сначала объявляется процедура с пустыми скобочками, а потом дальше набор параметров. Ведь void внутри скобок нет. Не знаю есть ли смысл поддерживать этот старый стиль, я не встречал компиляторов, которые не понимают нового.Код: "C" extern void SYSTEM_HALT(); Saferoll писал(а): Что же это за процедура SYSTEM_HALT и сколько у ней должно быть параметров? Макрос __HALT, он же процедура SYSTEM_HALT имеет один параметр (код возврата) и превращается (должна превращаться) в сишный exit(n); для WinDev так и есть; а вот в ZXDev я так и не придумал как правильно выйти в бейсик (особенно с учётом режима прерываний и необходимого для этого вызова Basic.Quit).Пока не реализована SYSTEM_HALT можно реализовать __GUARDEQR и __GUARDEQP (охрана типов) как "пустышки", просто игнорирующие проверку типа (и не вызывающие __HALT). Опция "игнорировать охрану типа" может быть добавлена в XDevCfg.h. Впрочем, в данном конкретном случае это мало что даст, потому что раздельное присваивание полей работает и так. Код: "OBERON"
|
Автор: | Zorko [ 01 дек 2014, 14:33 ] |
Заголовок сообщения: | Re: Что за SYSTEM_HALT() в макросах SYSTEM.H? |
Есть решение проблемы SYSTEM_HALT. Пожалуй, не следует мудрить с Basic.Quit. Останется работать обработчик прерываний IM 2 или режим DI (можно разрешить). Но выход по HALT(не 0) всё равно аварийный. Здесь максимум что нужно — чтобы пользователь увидел код ошибки. А вызвать Basic.Quit перед HALT(0) можно и ручками. Я вспомнил про RST 8, потестировал. Такой вариант нам вполне сгодится: Код: "C" #define SYSTEM_HALT(n) __asm RST 8 \ |
Автор: | Zorko [ 01 дек 2014, 16:59 ] |
Заголовок сообщения: | Re: Что за SYSTEM_HALT() в макросах SYSTEM.H? |
Тестирование показывает, что вариант нужно усовершенствовать. При возврате по HALT() регистры IY и HL' не всегда содержат значения, нужные для корректной работы бейсика. Ну и режим прерываний не должен быть DI, иначе всё просто зависнет. Так что предлагаю такую реализацию SYSTEM_HALT: Код: "C" void SYSTEM_HALT_A (void /* Register A */) __naked { Код: "C" #define __SYSTEM_hash__ # |
Автор: | Zorko [ 01 дек 2014, 19:48 ] |
Заголовок сообщения: | Re: Что за SYSTEM_HALT() в макросах SYSTEM.H? |
Оптимизировал на пару байт. |
Автор: | Saferoll [ 08 янв 2016, 20:20 ] |
Заголовок сообщения: | Re: Что за SYSTEM_HALT() в макросах SYSTEM.H? |
Итак, HALT(n) вызывает SYSTEM_HALT(n) в силу макроса ZXDev\Lib\C\SYSTEM.h: Код: "C" #define __HALT(x) SYSTEM_HALT(x) А это через макроопределения Код: "C" extern void SYSTEM_HALT_N (void); превращается в вызов функций Код: "C" SYSTEM_HALT_N (void); И вот здесь возможна проблема! Дело в том, что __HALT(x) вызывается из runtime-проверок, например из охранников типа. Причем в некоторых местах это происходит из середины выражения. Например, Код: "C" #define __SHORT(x, y) ((int)((unsigned long)(x)+(y)<(y)+(y)?(x):(__HALT(-8),0))) Но "SYSTEM_HALT_N();" является отдельным оператором, а не выражением, поэтому нельзя вычислить (__HALT(-5),p) - возникает ошибка из-за символа ";". Попробуем задать Код: "C" extern void SYSTEM_HALT_N (void); При этом будет выходить не сообщение с заданным кодом n, а какое-то неопределенное сообщение, зависящее от того, какой байт компилятор поместит в код после вызова функции. Но зато теперь можно задать макрос вида Код: "C" #define __GUARDEQP(p, typ) *((__TYPEOF(p)!=typ##__typ)?__HALT(-6):p) К сожалению, так просто создать сообщение с нужным кодом не получается. Если задать Код: "C" #define SYSTEM_HALT(n) __asm call _SYSTEM_HALT_N \ Похоже вызов функции является выражением, а асм-вставка – нет. Наверно, единственный выход – написать ассемблерную процедуру, которая поместит в какое-то место байт (номер сообщения), запишет в стек адрес этого места, а затем выполнит все действия SYSTEM_HALT_N. |
Автор: | Zorko [ 09 янв 2016, 13:39 ] |
Заголовок сообщения: | Re: Что за SYSTEM_HALT() в макросах SYSTEM.H? |
Да, ты совершенно прав. Нужно возвратиться к предыдущему варианту. Потестил и закоммитил такой код: Код: "C" // Оптимизация: пусть n-1 вычисляется во время компиляции, ведь n всегда константа Другое дело, что такие проверки в рантайме для ZX, видимо, следует опционально отключать для эффективности. Кое-что уже в этом плане реализовано, например, см. опции SYSTEM_NoASSERT, SYSTEM_NoCheck_X, SYSTEM_NoCheck_CASE. |
Страница 1 из 1 | Часовой пояс: UTC + 2 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |