Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: А вот бы на FORTH написать...
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры
Страницы: 1, 2, 3, 4, 5
Kopa
Цитата(forever failure @ May 28 2009, 10:36) *
Уважаемые участники, а приведите плз., кто владеет этим языком, так, хотя бы ради интереса, код вычисления контрольной суммы CRC16 на форте ?
Просто интересно сравнить с привычными решениями на Ц.


Один из вариантов ( поиск "crc16 forth" )
алгоритм с номером #44

P.S. Можно и найти другие реализации и замерить скорость после компиляции
и посмотреть asm код, например, на PC для разных Форт системsmile.gif
Си варианты
forever failure
Если честно, не впечатлило. Букаф зело много. В сравнении с сишным
Код
static void word_checksum (uint8_t * cs, const uint8_t * s, uint8_t size, const uint16_t poly)
   {
   uint16_t * crc = (uint16_t *)cs;

   for (;size--;)
      {
      register uint8_t i = 8;
      *crc ^= *s++;
      do
         {
         uint8_t f = *crc & 1;
         *crc >>= 1;

         if (f)
            *crc ^= poly;
         }
      while (--i);
      }
   }

пресловутого лаконизма исходного кода не замечено.
MrYuran
Вот если бы ввести слова для работы с предпоследним и пред-предпоследним элементом стека (вместо ротов и свопов), гораздо быстрее было бы.
В МСП, кстати, без проблем.

Хотя бы что-то типа Inc_Prev (инкремент предпоследнего) и Dec_Prev
Можно было бы менять счётчик "через голову" верхнего значения (CRC)
Правда, проверять его тоже также нужно
forever failure
Не, я вовсе не к тому, что Forth vs C, а просто хотелось бы какой-нить пример, который реально показывает преимущества форта, чтоб понять его мощь.
Kopa
Цитата(forever failure @ May 28 2009, 13:19) *
Если честно, не впечатлило. Букаф зело много. В сравнении с сишным.
...
пресловутого лаконизма исходного кода не замечено.


Вопрос, в этом случае, был поставлен некоректноsmile.gif

В Форте можно написать полный аналог приведённого Вами кода.
используя локальные именованные переменные или другие варианты с неменьшей поонимаемостью кода .


P.S. Расчёт CRC ещё для увеличения скорости алгоритма часто реализовывают на asm
( как это будет по впечатлениям?
Нужно ехать или смотреть на автомобиль? )

Одна из ловушек Форта - это желание оптимально создавать кодsmile.gif
MrYuran
Цитата(forever failure @ May 28 2009, 14:19) *
Если честно, не впечатлило. Букаф зело много. В сравнении с сишным
пресловутого лаконизма исходного кода не замечено.

Ну почему же, вот:
Код
: crc ( n ch--n)  >< XOR
                  8 0 DO  DUP 8000 AND  
                          IF  2* FFFF AND  crc-polynomial XOR
                        ELSE  2*
                        THEN
                    LOOP;

Может, на более мелкие слова разбить можно.
Kopa
Цитата(forever failure @ May 28 2009, 13:26) *
Не, я вовсе не к тому, что Forth vs C, а просто хотелось бы какой-нить пример, который реально показывает преимущества форта, чтоб понять его мощь.


Вспоминается ситуация со слепыми мудрецами и слономsmile.gif
Rst7
Цитата
P.S. Расчёт CRC ещё для увеличения скорости алгоритма часто реализовывают на asm


Для увеличения скорости сначала крепко думают над алгоритмом. Например, для фиксированного полинома от Modbus все делается так (пардон за непортабельный код)
CODE

__z UREG CRC16stage2(UINT8 uchCRCLo, UINT8 uchCRCHi, UREG l, UREG write, UINT8 *puchMsg, UREG i128,UREG i1, UREG i192);

UREG CRC16(UINT8 *puchMsg, UREG usDataLen, UREG write )
{
return CRC16stage2(0xFF,0xFF,usDataLen,write,puchMsg,128,1,192);
}

#pragma optimize=no_inline
__z UREG CRC16stage2(UINT8 uchCRCLo, UINT8 uchCRCHi, UREG l, UREG write, UINT8 *puchMsg, UREG i128, UREG i1, UREG i192)
{
if (l)
do
{
UINT8 parity;
UINT16 tmp16;
parity=*puchMsg++;
parity^=uchCRCLo;
uchCRCLo=uchCRCHi;
tmp16=__multiply_unsigned(parity,i128);
uchCRCHi=tmp16>>8;
uchCRCLo^=tmp16;
//tmp16=__multiply_unsigned(parity,i64);
tmp16>>=1;
uchCRCHi^=tmp16>>8;
uchCRCLo^=tmp16;
parity^=tmp16>>8;
parity^=parity>>1;
parity^=__swap_nibbles(parity);
if (parity&1)
{
uchCRCLo^=i1;
uchCRCHi^=i192;
}
}
while(--l);
if (write)
{
*puchMsg++=uchCRCLo;
*puchMsg++=uchCRCHi;
}
else
{
UREG k;
if ((k=*puchMsg++-uchCRCLo)) return k;
return *puchMsg++-uchCRCHi;
}
return 0;
}


или для полинома 0x11021
CODE

//Полный подсчет за один раз
void PGMCRC(void)
{
unsigned long p;
char h12=0;
char h0=0;
char h1;
char hl5;
char hh5;

p=0;
do
{
h1=h12; //F E D C B A 9 8
h12=__swap_nibbles(h12); //B A 9 8 F E D C
hh5=h12; //B A 9 8 F E D C
h12^=h1; //FB EA D9 C8 BF AE 9D 8C
h12&=0xF0; //FB EA D9 C8 _ _ _ _
hh5&=0x0F; //_ _ _ _ F E D C
h1^=hh5; //F E D C FB EA D9 C8
hl5=h12; //FB EA D9 C8 _ _ _ _
{
unsigned int i=(hh5<<8)|hl5; //_ _ _ _ F E D C FB EA D9 C8 _ _ _ _
i<<=1;
hh5=i>>8; //_ _ _ F E D C FB
hl5=(char)i; // EA D9 C8 _ _ _ _ _
}
h1^=hl5; //crclo // FEA ED9 DC8 C FB EA D9 C8
h12^=hh5; //crchi //FB EA D9 FC8 E D C FB

h12^=h0;
#pragma diag_suppress=Pe1053
h0=h1^(p<0x1FFFE?(*(char __farflash *)p):0);
#pragma diag_default=Pe1053
p++;
#ifdef PUA1
if (!((char)p))
{
if (PORTA&8) PORTA&=~8; else PORTA|=8;
}
#endif
}
while(p<0x20000);
#pragma diag_suppress=Pe1053
if(((h12<<8)|h0)!=*(unsigned int __farflash *)0x1FFFE)
{
//Ошибка контрольной суммы
__disable_interrupt();
__watchdog_reset();
WDTCR=0x08;
WDTCR=0x18;
WDTCR=0x0A; //Разрешаем сторожевой таймер
__watchdog_reset();
for(;;);
}
#pragma diag_default=Pe1053
}


А потом уже фалосоизмерением занимаются biggrin.gif

Это я так, мысли вслух. Не подумайте, ничего личного smile.gif
Kopa
Цитата(Rst7 @ May 28 2009, 13:43) *
Для увеличения скорости сначала крепко думают над алгоритмом.
Например, для фиксированного полинома от Modbus все делается так (пардон за непортабельный код)


Можно и так:
CODE
//***************************************************************************
// Расчёт CRC16
//***************************************************************************
static const unsigned int wCRCTable[] = {
0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440,
0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40,
0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841,
0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40,
0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41,
0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641,
0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040,
0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240,
0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441,
0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41,
0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840,
0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41,
0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40,
0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640,
0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041,
0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240,
0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441,
0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41,
0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840,
0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41,
0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40,
0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640,
0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041,
0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241,
0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440,
0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40,
0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841,
0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40,
0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41,
0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641,
0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 };

unsigned int CRC16 ( unsigned char *nData, unsigned int wLength)
{
unsigned char nTemp;
unsigned int wCRCWord = 0xFFFF;

while (wLength--)
{
nTemp = *nData++ ^ wCRCWord;
wCRCWord >>= 8;
wCRCWord ^= wCRCTable[nTemp];
}
return wCRCWord;
}


unsigned int U_CRC16 (unsigned int lngth)
{
unsigned char *item=&UART_RxBuf[0];//Я убрал (было в передаваемых параметрах)
unsigned int CRC = 0xFFFF;
unsigned char i;

while (lngth--)
{
CRC ^= *item++;

for (i=8;i>0;i--)
if (CRC & 1) { CRC >>= 1; CRC ^= 0xA001; }
else { CRC >>= 1; }


}

return (CRC);
}


P.S. Скорость, при использовании, не измерялsmile.gif
forever failure
Цитата(Kopa @ May 28 2009, 16:36) *
Вспоминается ситуация со слепыми мудрецами и слономsmile.gif

О, умудрённый, скажите, в каком месте нужно смеяццо ?
То что CRC можно посчитать миллион сто одним способом, на асме, С, паскале, чём угодно - это и так ясно, и опять таки алгоритм и средство его реализации выбирается исходя из конкретных условий.
Я то что хочу увидеть - для какой практической задачи решение на форте реально красиво настолько, насколько его (форт) тут расписывают.
А Вы всё про шашечки и рюшечки. CRC на асме я и сам напишу, - невелика наука.

всё, про форт, похоже забыли, началась фаллометрия на Ц.
Kopa
Цитата(Rst7 @ May 28 2009, 13:43) *
А потом уже фалосоизмерением занимаются biggrin.gif
Это я так, мысли вслух. Не подумайте, ничего личного smile.gif


Самое неблагодарное занятие.
Rst7
Цитата
Самое неблагодарное занятие.


А я и не занимаюсь. Я так, намекаю...
Kopa
Цитата(forever failure @ May 28 2009, 13:53) *
всё, про форт, похоже забыли, началась фаллометрия на Ц.


Согласен.

Но красиво или нет то или иное решение - это уже субъективная точка зренияsmile.gif
и в реализации на выбранном языке уже присутствует опосредованоsmile.gif
ukpyr
ого, какие простыни...
вот еще короче :
Код
#define inc_crc16_modbus_upd(data, crc_prev) { \
    U8 cnt_bits, flag_xor; \
    crc_prev ^= data; \
    for (cnt_bits = 8; cnt_bits; cnt_bits--) { \
        flag_xor = crc_prev & 1; \
        crc_prev >>= 1; \
        if (flag_xor) crc_prev ^= CRC16_MODBUS_POLY_VALUE; \
    } \
}


в принципе кусок на Форте, приведенный выше, при использовании оптимизирующего компилятора может развернуться во что-то подобное куску на С. но согласитесь, если алгоритм более сложный (напр.какие-то расчеты и т.д.), разобраться в нем с первого взгляда на порядок сложнее чем в С.

я думаю основное преимущество Форта - в режиме интерпретатора, например как более эффективная альтернатива обучающим средствам типа Bascom-AVR. Когда работу юзера можно организовать в консоли терминала, подключенной к посл.пору контроллера.
forever failure
Всё, всё, хватит про CRC. Будем считать, что на форте получается не хуже, в любом смысле.
Kopa
Цитата(forever failure @ May 28 2009, 13:53) *
Я то что хочу увидеть - для какой практической задачи решение на форте реально красиво настолько,
насколько его (форт) тут расписывают.


Возможно это самый трудно объяснимый феномен Форта,
( и понимание может быть своё и даже иррациональное )

но например имеется проект AI на Форте
и небольшое обсуждение
Forth vs Python
частного проекта "Вырастим искусственный интеллект"

P.S. Главное понятие в языке - это слово!

Цитата(ukpyr @ May 28 2009, 14:14) *
но согласитесь, если алгоритм более сложный (напр.какие-то расчеты и т.д.), разобраться в нем с первого взгляда на порядок сложнее чем в С.


Для этого расширяют язык обычной формой записи арифметических выраженийsmile.gif
А с пониманием произвольного алгоритма по реализации могут быть проблемы.

P.S. Разбираться в алгоритме не сложно, если оно требуется
( ищется именно то место где возникли определённые проблемы по использованию )
Много кода даже и не рассматривается.
Форт - это "айсберг" о существовании которого многие даже и не догадываютсяsmile.gif

Пока.
MrYuran
Цитата(Kopa @ May 27 2009, 16:29) *
На данном форуме тем, полезных для прочтения по Форту, не присутствует.
Эта, наверное, первое хорошее обсуждение.smile.gif

Уже оживил обсуждение данного топика, хотя гуру или нет не знаю.
Ждёмс появления интереса?
smile3046.gif

Я думаю по этому поводу вот что:
Нужно, чтобы была готовая система по принципу "включил и работай".
И продвигать среди людей, не испорченных разными сями.
Наверняка начинающие оценят такой синтаксис:
Код
АЦП Запустить
BEGIN
    Подождать
    АЦП ?Готово
UNTIL
АЦП Считать
Температуру Вычислить


Особенно, если каждое слово можно выдать с терминала и тут же получить результат.
Rst7
Цитата
Наверняка начинающие оценят такой синтаксис:


Я так понимаю, Вы о Domain Specific Language. На больших братьях - в полный рост применяется.
Kopa
Цитата(MrYuran @ May 29 2009, 10:11) *
Наверняка начинающие оценят такой синтаксис:
Код
АЦП Запустить
BEGIN
    Подождать
    АЦП ?Готово
UNTIL
АЦП Считать
Температуру Вычислить


Особенно, если каждое слово можно выдать с терминала и тут же получить результат.


Существует дипломный проект браузера здесь
почти всё в нём в русских словах, но не всё выглядит однозначно.

1. Требуется более тщательное продумывание способов этого использования.
( например по оформлению кода )
2. Использование длинных слов плохо сказывается на восприятии программы.
3. Если не принять дополнительных мер по различению слов из разных
семантических групп, то это тоже влияет на восприятие.
...





Цитата(Rst7 @ May 29 2009, 13:32) *
Я так понимаю, Вы о Domain Specific Language. На больших братьях - в полный рост применяется.


И какие ещё есть общеупотребительные DSL если исключить из списка SQL?

P.S. Реализации в Форте разных концепций зачастую и есть DSL, но с
чертами Форт направленности.
Rst7
Цитата
И какие ещё есть общеупотребительные DSL если исключить из списка SQL?


Ну я бы не ставил язык запросов в один ряд с DSL. Все-таки DSL - это язык, делающийся под конкретную систему (программную или программно-аппаратную). На то он и Domain Specific. Форт обладает хорошими возможностями для упрощения построения таких языков. Хотя, я бы еще поспорил, где проще. Вот, например, обожаемый в современном функциональном программировании Хаскель

Код
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
{-# LANGUAGE ExtendedDefaultRules, OverloadedStrings #-}
module Hello where
import Language.BASIC

main :: IO ()
main = runBASIC $ do

    10 PRINT "Hello BASIC World!"
ukpyr
Цитата
АЦП Запустить
BEGIN
Подождать
АЦП ?Готово
UNTIL
АЦП Считать
Температуру Вычислить

дык и в современных компиляторах С можно использовать Unicode - идентификаторы, нет ?

а по DSL - есть более продвинутые языки, основанные на Форте :
http://www.bluishcoder.co.nz/2008/04/factor-parsing-dsl.html
http://www.bluishcoder.co.nz/2008/06/parsi...ith-factor.html
Kopa
Цитата(Rst7 @ May 29 2009, 14:01) *
Форт обладает хорошими возможностями для упрощения построения таких языков.
Хотя, я бы еще поспорил, где проще.


." Hello World "

Куда уж прощеsmile.gif
Или минимальный код выводящий себя в консоль на Форте

Код
  SOURCE TYPE


Цитата(Rst7 @ May 29 2009, 14:01) *
Вот, например, обожаемый в современном функциональном программировании Хаскель
...


Не менее любимая Scheme используется в проекте Staapl
для компилирования Форт программ для PIC18

Код
Staapl is a collection of abstractions for (meta)programming
microcontrollers from within PLT Scheme. The core of the system is a
programmable code generator structured around a functional
concatenative macro language. On top of this it includes a syntax
frontend for creating Forth-style languages, a backend code generator
for Microchip's PIC18 microcontroller architecture, and interaction
tools for shortening the edit-compile-test cycle.


P.S. Просто примеры. Получается сам Форт в этом случае DSL?smile.gif
Rst7
Цитата
Куда уж проще


Не совсем понятно, к чему это. Я пример привел в том смысле, что реализация DSL на Хаскеле возможна вообще на этапе компиляции, не то что в рантайме (в рантайме любой лох при помощи yacc/lexx за три часа езыг сляпает smile.gif ). В примере в качестве DSL выступает Бейсик smile.gif

Цитата
Получается сам Форт в этом случае DSL?


Почему бы и нет.

Цитата
Предметно-ориентированный язык программирования (англ. domain-specific programming language, domain-specific language, DSL) — язык программирования, специально разработанный для решения определённого круга задач, в отличие от языков программирования общего назначения...

В рамках Forth языка всегда существовала, но не всегда использовалась возможность создания DSL языков.
Kopa
Цитата(Rst7 @ May 29 2009, 14:26) *
Не совсем понятно, к чему это. Я пример привел в том смысле, что реализация DSL на Хаскеле возможна вообще на этапе компиляции, не то что в рантайме (


Наверное и я не понял.smile.gif
В Форте на этапе трансляции кода или после уже созданного exe
Можно подгружать необходимые DSL расширения.





Цитата(ukpyr @ May 29 2009, 14:05) *
а по DSL - есть более продвинутые языки, основанные на Форте :
http://www.bluishcoder.co.nz/2008/04/factor-parsing-dsl.html
http://www.bluishcoder.co.nz/2008/06/parsi...ith-factor.html


Если интересна тема BNF парсинга на Форте
одна из реализацийsmile.gif

P.S. Приводить ссылки в данном топике возможно мало смысла?
т.к. много ссылок по Форт тематике можно найти просматривая
Русский Форт Форум
Пока до понедельникаsmile.gif
MrYuran
Начал я таки колупать КэмелФорт.
Тяжело даётся асм изнеженному сями организму!
Попутно рождаются вопросы.

Например, как символически обозначить регистры, биты и прочие константы?
которые обычно назначаются дефайнами и подставляются препроцессором?

Думаю, константами назначить.

Эх, прям руки чешутся быстрее что-нибудь сварганить...
А у меня как назло все железки без иллюминации и спецэффектов, тупая измериловка.
Ну хоть через терминал пообщаться.



Ну чё, в первом приближении что-то заработало!
Нажмите для просмотра прикрепленного файла

Копаем дальше... smile3046.gif

Кстати, я передумал. Регистры, наверно, правильнее переменными задавать.
Щас подумаю ещё немного и попробую ногами помахать.
Kopa
Цитата(MrYuran @ Jun 3 2009, 16:35) *
Ну хоть через терминал пообщаться.

Ну чё, в первом приближении что-то заработало!


Поздравляю с первыми результатами!

Цитата(MrYuran @ Jun 3 2009, 16:35) *
Копаем дальше... smile3046.gif

Кстати, я передумал. Регистры, наверно, правильнее переменными задавать.
Щас подумаю ещё немного и попробую ногами помахать.


В реализации Форта на родном трансляторе ассемблера есть некоторые
"несуразности" ( высокоуровневый код представлен через директивы данных
для формирования адресных ссылок )
Возможно придётся использовать небольшой генератор кода при этом.


Если есть в реализации поддержка режима самопрограммирования или
bootloader-а, то тоже неплохо.

P.S. Начал тоже небольшие раскопки "трупика" Форта для MSP:) ( Рассматриваю возможные варианты).
Да, для регистров это наверное правильно.
chu
Цитата(MrYuran @ Jun 3 2009, 19:35) *
Ну чё, в первом приближении что-то заработало!


Поздравляю! Кстати, камень - MSP430F1611 ?
MrYuran
Да, впечатлений на целый вечер хватило.
С помощью цепочки дупов, ротов и какой-то матери через час таки реализовал сишные конструкции
P1OUT |= mask;
и P1OUT &= ~mask;
и таки махнул ногой туда-обратно!

Но это, конечно, от незнания основ.
Например, дублирование пары аргументов на стеке наверно удобнее делать через стек возвратов, а не кручением-верчением, как я.

Ещё очень нужен инлайн-ассемблер.
Буду копать пока в этом направлении.
Книжку вот доделываю, черновой вариант почти готов (7 глав, осталось 8-ю и эпилог). Думаю, выложить лучше на ФТП. Правда, за инет надо сначала заплатить, всё не соберусь никак. А на работе сисадмин все "лишние" порты позакрывал.

Разобрался, как товарищ Джей Родригес предлагает проводить целевую компиляцию:
There are TWO WAYS to write programs in CamelForth:

Цитата
1. If you have CamelForth running on your MSP430 board, you can download Forth code directly to CamelForth. ...

Ну это понятно, как я вчера делал. В терминале набивал буковки, потом ждал "ок". По умолчанию компилирует в ОЗУ. Хорошо для тестирования, флешь зазря не трёт.

Цитата
2. You can add your code to the assembler source files. This requires you to convert your Forth code to assembler code. To show how this is done, every high-level Forth word in the file is shown with its equivalent Forth code in a comment. Be especially careful with control structures (IF..ELSE..THEN, BEGIN..UNTIL, DO..LOOP, and the like), and with the Forth word headers. For this option it is recommended that you create a new .s43 assembler file, and INCLUDE it at the end of core430.s43. This is necessary to preserve the dictionary linking between your new definitions and the kernel definitions. Reassemble core430.s43, and download to the MSP430 board, then test. This is a much slower process, and is best saved for the final stage when you have a tested & debugged program that you want to put in PROM.

А вот это поинтереснее. Предлагается переписать фортовый исходник в виде ассемблерных макросов (весьма близко к исходному тексту), а затем скомпилировать ИАРом. В этом случае наверняка и оптимизация выполняется, выкидываются неиспользованные слова.
Можно ещё подумать над тем, как выкидывать из конечной прошивки названия слов. (Если не предусматривается возможность интерактивной работы с конечным кодом)

Сегодня попробую замерить скорость "ногодрыгания" при использовании стандартных средств. Вообще, пока главное преимущество форта вижу в потенциальной возможности "впихать невпихуемое". (при правильном подходе wink.gif )

Цитата(chu @ Jun 4 2009, 08:15) *
Поздравляю! Кстати, камень - MSP430F1611 ?

Нет, 149.
Но это без разницы, ибо
Цитата
System Requirements
As distributed, CamelForth/430 will assemble to run on the New Micros Tini430 board, which uses the MSP430F1611 processor. It assumes an 8 MHz crystal for XT2, and USART0 at 9600 baud (8,N,1) for terminal I/O.

CamelForth should be usable with any MSP430 device having at least 512 bytes of RAM, 8K of ROM, and one USART.

CamelForth/430 is written to be assembled with the IAR Systems MSP430 Workbench "Kickstart", which can be downloaded from the TI web page.

Кварц у меня тоже не 8М, а 2.
Пришлось поменять коэффициент деления для контроллера флеши (кстати, неправильно, я его в 2 раза понизил, а надо в 4), и обмен вместо 9600 на 2400.
chu
Цитата(MrYuran @ Jun 4 2009, 11:19) *
Да, впечатлений на целый вечер хватило.


Есть еще SwiftX MSP430 от Forth, inc. Весьма любопытная ( и удобная система ) Pro версия стоит $1095,
Evaluation - бесплатна, но ограничена по обьему кода, и не имеет исходников кросс-компилера...
Рекомендую ознакомиться. http://www.forth.com/embedded/index.html
Kopa
Цитата(MrYuran @ Jun 4 2009, 07:19) *
Да, впечатлений на целый вечер хватило.
С помощью цепочки дупов, ротов и какой-то матери через час таки реализовал сишные конструкции
P1OUT |= mask;
и P1OUT &= ~mask;
и таки махнул ногой туда-обратно!

Но это, конечно, от незнания основ.


Это могло выглядеть например так:
Код
mask P1OUT OR!
mask INVERT P1OUT AND!


или даже так как написано в Си кодеsmile.gif

Цитата(MrYuran @ Jun 4 2009, 07:19) *
Например, дублирование пары аргументов на стеке наверно удобнее делать через стек возвратов, а не кручением-верчением, как я.


Если необходимо продублировать 2-а верхних значения то слово 2DUP
Часто используемый приём в Форте перенос верхнего значения стека данных
на стек возвратов >R и использование через R@
а убирание для последнего использования R>

Если есть поддержка локальных переменных, то используется они при сложных случаях.

Цитата(MrYuran @ Jun 4 2009, 07:19) *
Ещё очень нужен инлайн-ассемблер.
Буду копать пока в этом направлении.


Да необходим, чтобы использовать максимально возможности контроллераsmile.gif


Цитата(MrYuran @ Jun 4 2009, 07:19) *
Книжку вот доделываю, черновой вариант почти готов (7 глав, осталось 8-ю и эпилог). Думаю, выложить лучше на ФТП. Правда, за инет надо сначала заплатить, всё не соберусь никак. А на работе сисадмин все "лишние" порты позакрывал.


А если выложить где и расположен исходный материал ( на sf )

Цитата(MrYuran @ Jun 4 2009, 07:19) *
Разобрался, как товарищ Джей Родригес предлагает проводить целевую компиляцию:
А вот это поинтереснее. Предлагается переписать фортовый исходник в виде ассемблерных макросов (весьма близко к исходному тексту), а затем скомпилировать ИАРом. В этом случае наверняка и оптимизация выполняется, выкидываются неиспользованные слова.


Наверное, но соптимизировать сам Форт код IAR, скорее всего, не сможет.
( если разработчикам IAR не подсказать, как их компилятор могут и используют для Форт программированияsmile.gif
в GCC, возможно есть изменения в этом направлении, т.к. gforth показывает неплохие результаты при
benchmark тестировании.)

Цитата(MrYuran @ Jun 4 2009, 07:19) *
Можно ещё подумать над тем, как выкидывать из конечной прошивки названия слов. (Если не предусматривается возможность интерактивной работы с конечным кодом)


В данном варианте, скорее всего, используя возможности макро языка ассемблера MSP.

Цитата(MrYuran @ Jun 4 2009, 07:19) *
Сегодня попробую замерить скорость "ногодрыгания" при использовании стандартных средств.


Скорее всего не так быстроsmile.gif, если в реализации нет, например, макро-оптимизатора.

Цитата(MrYuran @ Jun 4 2009, 07:19) *
Вообще, пока главное преимущество форта вижу в потенциальной возможности "впихать невпихуемое". (при правильном подходе wink.gif )


Действительно - это неплохо сформулировано в книге Ноздрунова,Баранова . smile3046.gif


Цитата(MrYuran @ Jun 4 2009, 07:19) *
и обмен вместо 9600 на 2400.


В tinyboot комфортная скорость терминального канала ~38400
MrYuran
Цитата(Kopa @ Jun 4 2009, 10:18) *
А если выложить где и расположен исходный материал ( на sf )

Да не, туда в таком виде как-то стрёмно...
Вот если бы также оформить, как там, тогда уж...
Но это в обозримом будущем вряд ли...
Kopa
Цитата(chu @ Jun 4 2009, 07:27) *
Есть еще SwiftX MSP430 от Forth, inc. Весьма любопытная ( и удобная система ) Pro версия стоит $1095,
Evaluation - бесплатна, но ограничена по обьему кода, и не имеет исходников кросс-компилера...
Рекомендую ознакомиться. http://www.forth.com/embedded/index.html


Evaluation запускал, у SwiftX, в сравнении с VFX ( от MPE ) не такой хороший оптимизатор.
( если это критично )
стоимость VFX для MSP430 ( price list 384.65 / 777.15$ ) .

P.S. Но, как вариант, тоже можно рассматривать и использовать.smile.gif


Цитата(MrYuran @ Jun 4 2009, 09:42) *
Да не, туда в таком виде как-то стрёмно...
Вот если бы также оформить, как там, тогда уж...
Но это в обозримом будущем вряд ли...


Один из вариантов использовать ресурс хранения на forth.org.ru

P.S. Неполное дерево видовой эволюции Форт систем
Русского spf4 на этом дереве нетsmile.gif
MrYuran
Сейчас вот вырисовывается туманная перспектива колупания в ассемблерной прошивке старья на атмеловском AT89F8252...
cranky.gif
Если всё-таки придётся, (очень надеюсь, что нет) наверно попробую тинибут применить... Хотя бы в качестве макроассемблера
Kopa
Цитата(MrYuran @ Jun 4 2009, 11:08) *
Сейчас вот вырисовывается туманная перспектива колупания в ассемблерной прошивке старья на атмеловском AT89F8252...
cranky.gif
Если всё-таки придётся, (очень надеюсь, что нет) наверно попробую тинибут применить... Хотя бы в качестве макроассемблера


Для 51, кроме других, есть интересные варианты быстрого использования из недавних ( сделаны на spf4 )
1. исходный вариант
2. другое продолжение подхода выше
MrYuran
Вопрос пока не до конца понятный с прерываниями.
Насколько я понимаю, прерывание нужно организовать отдельным словом, а вектор кинуть на начало кодовой секции слова.
И вот тут как-то при входе и выходе нужно сохранять и восстанавливать контекст (насколько я понимаю, либо те регистры, которые мы портим, либо для простоты и надёжности все).
Как бы это дело оптимизировать.
То есть сохранять именно те регистры, которые мы собираемся испортить.
Или просто ограничить использование общих регистров в базовых словах и сохранять их все?
Kopa
Цитата(MrYuran @ Jun 4 2009, 12:32) *
Вопрос пока не до конца понятный с прерываниями.


Схемы при обработке прерываний могут иметь отличия.
И с ними всегда не всё однозначноsmile.gif

Цитата(MrYuran @ Jun 4 2009, 12:32) *
Как бы это дело оптимизировать.
То есть сохранять именно те регистры, которые мы собираемся испортить.
Или просто ограничить использование общих регистров в базовых словах и сохранять их все?


если реализация сделана через исполнитель ссылок слов ( байт-кодов),
то наверное, использовать последний описанный вариант,
Обычно вершина стека данных - это один регистр, остальная часть через указатель
+ 2-3 регистра ( оценочно) интенсивного использования в примитивах.

но при этом если
необходим базис ядра, то возможно придётся использовать указатель на
отдельную область обработчика и предусмотреть его ( их ) переключение.

1-й вариант, наверное, тоже можно использовать.

P.S. Если требуется мультизадачность, то простейший вариант - кооперативнаяsmile.gif
( в tinyboot она используется )
chu
Цитата(Kopa @ Jun 4 2009, 17:54) *
P.S. Если требуется мультизадачность, то простейший вариант - кооперативнаяsmile.gif



Еще раз об SWiftX/MSP430(Evaluation, канешнwink.gif) В комлекте есть подробные доки, где все доступно изложено. В частности прерывания и мультизадачность идут рука об руку.

SECTION 5: THE SWIFTOS MULTITASKING EXECUTIVE
5.2.2 Interrupts and Tasks
"Interrupt routines are often used to awaken tasks. A common way to perform complex,
non-critical interrupt servicing is to have the interrupt routine perform all
time-critical operations, and then store WAKE into a task’s STATUS."

PS. Moving Forth
MrYuran
Цитата
P.S. Если требуется мультизадачность, то простейший вариант - кооперативнаяsmile.gif
( в tinyboot она используется )

Да нет, хотелось бы рилтайм smile.gif
а что, если примитивы языка использовать в критических секциях? Ведь между словами в регистрах ничего не передаётся.
Конечно, будут затраты на EINT - DINT в каждом слове, зато переключение контекста практически мгновенное.
Kopa
Цитата(MrYuran @ Jun 4 2009, 14:25) *
Да нет, хотелось бы рилтайм smile.gif
а что, если примитивы языка использовать в критических секциях? Ведь между словами в регистрах ничего не передаётся.
Конечно, будут затраты на EINT - DINT в каждом слове, зато переключение контекста практически мгновенное.


Надо смотреть на использование регистров в примитивах. ( у нас же не стековый контроллерsmile.gif
и произвольное использование без чёткого контроля ( если ничего не сохранять, а
в прерывании использовать отдельные регистры) вряд ли получится.
А так мысль здравая, при начальном сохранении 2-3х требуемых регистров.



P.S. Реальная мультизадачность в Форт системе должна быть легче в реализации.
chu
Цитата(forever failure @ May 28 2009, 14:36) *
Уважаемые участники, а приведите плз., кто владеет этим языком, так, хотя бы ради интереса, код вычисления контрольной суммы CRC16 на форте ?
Просто интересно сравнить с привычными решениями на Ц.


Есть CRC8, делал для 1-wire, по документу AVR318 ATMEL Application Note.Rev.2579A-AVR-09/04 ( page_17).


0x18 VALUE POLYNOM

0x80 CONSTANT MSB#
0x01 CONSTANT LSB#

: LSB LSB# AND ;

: CRC8 8 0 DO
2DUP LSB SWAP LSB XOR
IF SWAP POLYNOM XOR
1 RSHIFT MSB# OR
ELSE SWAP 1 RSHIFT
THEN SWAP 1 RSHIFT
LOOP DROP ;

Если данные находятся в стеке:

\ ( ... d[n] d[n-1] ... d[1] 's n --- crc )

: CRC 0 ?DO SWAP CRC8 LOOP ;

где: d[] - байты данных; 's - ноль; n - количество данных в стеке

Если данные находятся в памяти:

: CRC ( 's addr n -- crc ) \ 's - seed=0 ; addr - адрес начала блока данных; n - количество байтов

OVER + SWAP ( 's addr2 addr1 )
DO I C@ CRC8 LOOP
;

А следующий фрагмент я использовал для построения таблицы ( табличный метод получения CRC8 )

\
\ построение таблицы crc8
\
: crc8tab ( -- )
CR ." crc8tab:" CR
0 0x100 0 DO DUP I CRC8 I 0x8 /MOD DROP 0=
IF CR 0x09 EMIT ." DB" 0x09 EMIT
THEN ." 0x" .XB ." , "
LOOP DROP ;

при котором входной байт используется как индекс в таблице значений контрольной суммы.

Вот, как-то так.

Да, забыл:

: .XB BASE @ >R HEX
0 <# # # #>
TYPE SPACE R> BASE ! ;

это печать байта в шестнадцатиричном виде.

Таблица напечаталась вот такая:

crc8tab:

DB 0x00 , 0x5E , 0xBC , 0xE2 , 0x61 , 0x3F , 0xDD , 0x83
DB 0xC2 , 0x9C , 0x7E , 0x20 , 0xA3 , 0xFD , 0x1F , 0x41
DB 0x9D , 0xC3 , 0x21 , 0x7F , 0xFC , 0xA2 , 0x40 , 0x1E
DB 0x5F , 0x01 , 0xE3 , 0xBD , 0x3E , 0x60 , 0x82 , 0xDC
DB 0x23 , 0x7D , 0x9F , 0xC1 , 0x42 , 0x1C , 0xFE , 0xA0
DB 0xE1 , 0xBF , 0x5D , 0x03 , 0x80 , 0xDE , 0x3C , 0x62
DB 0xBE , 0xE0 , 0x02 , 0x5C , 0xDF , 0x81 , 0x63 , 0x3D
DB 0x7C , 0x22 , 0xC0 , 0x9E , 0x1D , 0x43 , 0xA1 , 0xFF
DB 0x46 , 0x18 , 0xFA , 0xA4 , 0x27 , 0x79 , 0x9B , 0xC5
DB 0x84 , 0xDA , 0x38 , 0x66 , 0xE5 , 0xBB , 0x59 , 0x07
DB 0xDB , 0x85 , 0x67 , 0x39 , 0xBA , 0xE4 , 0x06 , 0x58
DB 0x19 , 0x47 , 0xA5 , 0xFB , 0x78 , 0x26 , 0xC4 , 0x9A
DB 0x65 , 0x3B , 0xD9 , 0x87 , 0x04 , 0x5A , 0xB8 , 0xE6
DB 0xA7 , 0xF9 , 0x1B , 0x45 , 0xC6 , 0x98 , 0x7A , 0x24
DB 0xF8 , 0xA6 , 0x44 , 0x1A , 0x99 , 0xC7 , 0x25 , 0x7B
DB 0x3A , 0x64 , 0x86 , 0xD8 , 0x5B , 0x05 , 0xE7 , 0xB9
DB 0x8C , 0xD2 , 0x30 , 0x6E , 0xED , 0xB3 , 0x51 , 0x0F
DB 0x4E , 0x10 , 0xF2 , 0xAC , 0x2F , 0x71 , 0x93 , 0xCD
DB 0x11 , 0x4F , 0xAD , 0xF3 , 0x70 , 0x2E , 0xCC , 0x92
DB 0xD3 , 0x8D , 0x6F , 0x31 , 0xB2 , 0xEC , 0x0E , 0x50
DB 0xAF , 0xF1 , 0x13 , 0x4D , 0xCE , 0x90 , 0x72 , 0x2C
DB 0x6D , 0x33 , 0xD1 , 0x8F , 0x0C , 0x52 , 0xB0 , 0xEE
DB 0x32 , 0x6C , 0x8E , 0xD0 , 0x53 , 0x0D , 0xEF , 0xB1
DB 0xF0 , 0xAE , 0x4C , 0x12 , 0x91 , 0xCF , 0x2D , 0x73
DB 0xCA , 0x94 , 0x76 , 0x28 , 0xAB , 0xF5 , 0x17 , 0x49
DB 0x08 , 0x56 , 0xB4 , 0xEA , 0x69 , 0x37 , 0xD5 , 0x8B
DB 0x57 , 0x09 , 0xEB , 0xB5 , 0x36 , 0x68 , 0x8A , 0xD4
DB 0x95 , 0xCB , 0x29 , 0x77 , 0xF4 , 0xAA , 0x48 , 0x16
DB 0xE9 , 0xB7 , 0x55 , 0x0B , 0x88 , 0xD6 , 0x34 , 0x6A
DB 0x2B , 0x75 , 0x97 , 0xC9 , 0x4A , 0x14 , 0xF6 , 0xA8
DB 0x74 , 0x2A , 0xC8 , 0x96 , 0x15 , 0x4B , 0xA9 , 0xF7
DB 0xB6 , 0xE8 , 0x0A , 0x54 , 0xD7 , 0x89 , 0x6B , 0x35


я ее тупо воткнул в исходник на асме.

\ Табличный метод CRC8:

: CRC ( c -- crc ) 0xFF AND crc8tab + C@ ;


Вот, собственно и все.
А CRC16 - аналогичным образом, только полином другой и сдвигов побольше...

PS. Примеры реальные, использовал российский SP-Forth4
MrYuran
Я от форта просто тащусь!
Весь процессор как на ладони, без никаких отладчиков и спецпакетов!
Голым терминалом через голый уарт!

Вопрос возник такого плана.
Как соорудить конструкцию типа сишного #ifndef и подобных директив препроцессора?
Поясняю.
Вчера написал слово OR! и AND!
Код
: AND! (Addr Mask --)
    >R DUP @ R> AND SWAP !;
: OR! (Addr Mask --)
    >R DUP @ R> OR SWAP !;
: ? @ .;

Работает, но логичнее написать на ассемблере.
так вот, как сделать, чтобы в системах, где эти слова определены, они не определялись, а где нет - вставлялись определения?
chu
Цитата(MrYuran @ Jun 5 2009, 12:08) *
как сделать, чтобы в системах, где эти слова определены, они не определялись, а где нет - вставлялись определения?



В разных системах по-разному, я думаю. В SPF4, например, можно так:

[DEFINED] AND! NOT [IF]

: AND! ... ;

[THEN]

Цитата(MrYuran @ Jun 5 2009, 12:08) *
Я от форта просто тащусь!


Уррраааа!!!
Фортеров прибыло 1111493779.gif

PS.Moving Forth
MrYuran
Цитата(chu @ Jun 5 2009, 09:44) *
В разных системах по-разному, я думаю. В SPF4, например, можно так:
[DEFINED] AND! NOT [IF]
: AND! ... ;
[THEN]

А как самому определить эти [DEFINED],[IF] и [THEN]?
а заодно и [ELSE]?
chu
Цитата(MrYuran @ Jun 5 2009, 12:50) *
А как самому определить эти [DEFINED],[IF] и [THEN]?
а заодно и [ELSE]?


А для этого надо свою форт-систему писать biggrin.gif , я думаю.

PS. Moving Forth.

Цитата(MrYuran @ Jun 5 2009, 12:08) *
Код
: AND! (Addr Mask --)
    >R DUP @ R> AND SWAP !;
: OR! (Addr Mask --)
    >R DUP @ R> OR SWAP !;
: ? @ .;

Работает, но логичнее написать на ассемблере.


Логичнее, конечно, но код типа:

and #mask,&address
...
or #mask,&address

генерит (для embedded) только кросс-компилер ( /оптимизатор).
А CamelForth' у такое не под силу crying.gif

ЗЫ. Двигаюсь Дальше.
Kopa
Цитата(MrYuran @ Jun 5 2009, 08:08) *
Я от форта просто тащусь!
Весь процессор как на ладони, без никаких отладчиков и спецпакетов!
Голым терминалом через голый уарт!


Супер!


Цитата(MrYuran @ Jun 5 2009, 08:08) *
Вопрос возник такого плана.
Как соорудить конструкцию типа сишного #ifndef и подобных директив препроцессора?


Соорудить используя возможности Форт языка,

но обычно те или иные решения существуют в разных Форт системах
для SPF4 - близкий аналог REQUIRED ... если нужное слово уже загружено, то повторно
из заданой библиотеки не грузить ( но тут могут возникнуть коллизиии если семантика
загруженного слова отличается от необходимой )
в других Форт системах, часто вводят в употребление слово [DEFINED] СЛОВО
оставляющее на стеке во время трансляции кода значение флага.





Цитата(MrYuran @ Jun 5 2009, 08:08) *
Поясняю.
Вчера написал слово OR! и AND!
Код
: AND! (Addr Mask --)
    >R DUP @ R> AND SWAP !;
: OR! (Addr Mask --)
    >R DUP @ R> OR SWAP !;
: ? @ .;

Работает, но логичнее написать на ассемблере.


Замечание:
последовательность параметров для AND! ( Mask Addr -- ) привычнее \ по аналогии со словами ! +!
например так:
Код
  : AND! (  Mask Addr -- )
    DUP >R @ AND R> !
;


и на ассемблере это слово логичнее сделатьsmile.gif
А если оптимизатору этот код дать, то не факт, что это превратится в одну команду процессора

Цитата(MrYuran @ Jun 5 2009, 08:08) *
так вот, как сделать, чтобы в системах, где эти слова определены, они не определялись, а где нет - вставлялись определения?


Можно воспользоваться, например, словом FIND при его наличии. ( комментарии из SPF4 и стандарта 94г.)
Код
  FIND ( addr u -- addr u 0 | xt 1 | xt -1 ) \ 94 SEARCH
\ Расширить семантику FIND следующим:
\ Искать определение с именем, заданным строкой addr u.
\ Если определение не найдено после просмотра всех списков в порядке поиска,
\ возвратить addr u и ноль. Если определение найдено, возвратить xt.
\ Если определение немедленного исполнения, вернуть также единицу (1);
\ иначе также вернуть минус единицу (-1). Для данной строки, значения,
\ возвращаемые FIND во время компиляции, могут отличаться от значений,
\ возвращаемых не в режиме компиляции.

А дальше используя [IF] ... [ELSE] ... [THEN]
MrYuran
Цитата
А для этого надо свою форт-систему писать biggrin.gif , я думаю.

Эх, с чужой бы разобраться...
В синтаксисе я пока что двоечник и чайник.
Вот кучу интересных слов обнаружил.
Опять же, всё на виду! Можно "открыть ящик" и посмотреть, какие в нём инструменты.
CODE

; STACK OPERATIONS

;C DUP x -- x x duplicate top of stack
HEADER DUP,3,'DUP',DOCODE
PUSHTOS: SUB #2,PSP ; 1 push old TOS..
MOV TOS,0(PSP) ; 4 ..onto stack
NEXT ; 4

;C ?DUP x -- 0 | x x DUP if nonzero
HEADER QDUP,4,'?DUP',DOCODE
CMP #0,TOS ; 1 test for TOS nonzero
JNZ PUSHTOS ; 2
NODUP: NEXT ; 4

;C DROP x -- drop top of stack
HEADER DROP,4,'DROP',DOCODE
MOV @PSP+,TOS ; 2
NEXT ; 4

;C SWAP x1 x2 -- x2 x1 swap top two items
HEADER SWAP,4,'SWAP',DOCODE
MOV @PSP,W ; 2
MOV TOS,0(PSP) ; 4
MOV W,TOS ; 1
NEXT ; 4

;C OVER x1 x2 -- x1 x2 x1 per stack diagram
HEADER OVER,4,'OVER',DOCODE
MOV @PSP,W ; 2
SUB #2,PSP ; 2
MOV TOS,0(PSP) ; 4
MOV W,TOS ; 1
NEXT ; 4

;C ROT x1 x2 x3 -- x2 x3 x1 per stack diagram
HEADER ROT,3,'ROT',DOCODE
MOV @PSP,W ; 2 fetch x2
MOV TOS,0(PSP) ; 4 store x3
MOV 2(PSP),TOS ; 3 fetch x1
MOV W,2(PSP) ; 4 store x2
NEXT ; 4

;X NIP x1 x2 -- x2 per stack diagram
HEADER NIP,3,'NIP',DOCODE
ADD #2,PSP ; 1
NEXT ; 4

;C >R x -- R: -- x push to return stack
HEADER TOR,2,'>R',DOCODE
PUSH TOS
MOV @PSP+,TOS
NEXT

;C R> -- x R: x -- pop from return stack
HEADER RFROM,2,'R>',DOCODE
SUB #2,PSP ; 2
MOV TOS,0(PSP) ; 4
MOV @RSP+,TOS
NEXT

;C R@ -- x R: x -- x fetch from rtn stk
HEADER RFETCH,2,'R@',DOCODE
SUB #2,PSP
MOV TOS,0(PSP)
MOV @RSP,TOS
NEXT

;Z SP@ -- a-addr get data stack pointer
HEADER SPFETCH,3,'SP@',DOCODE
SUB #2,PSP
MOV TOS,0(PSP)
MOV PSP,TOS
NEXT

;Z SP! a-addr -- set data stack pointer
HEADER SPSTORE,3,'SP!',DOCODE
MOV TOS,PSP
MOV @PSP+,TOS ; 2
NEXT

;Z RP@ -- a-addr get return stack pointer
HEADER RPFETCH,3,'RP@',DOCODE
SUB #2,PSP
MOV TOS,0(PSP)
MOV RSP,TOS
NEXT

;Z RP! a-addr -- set return stack pointer
HEADER RPSTORE,3,'RP!',DOCODE
MOV TOS,RSP
MOV @PSP+,TOS ; 2
NEXT

;X TUCK x1 x2 -- x2 x1 x2 per stack diagram
HEADER TUCK,4,'TUCK',DOCOLON
DC16 SWAP,OVER,EXIT
Kopa
Цитата(MrYuran @ Jun 5 2009, 08:50) *
А как самому определить эти [DEFINED],[IF] и [THEN]?
а заодно и [ELSE]?


В Форт системе существует доступ к входному потоку текущей транслируемой программы
( слова SOURCE TIB #TIB >IN ACCEPT и возможно другие )
и механизм IMMEDIATE слов и доступ к STATE переменной состояния системы.
не забываем также про [ и ]

P.S. Это достаточно мощные средства для создания Форт расширений.
Но это, часто, для небольших контроллеров лучше использовать в кросс системе
или наращивать внутреннюю программную память ( можно и оптимизатор туда поместить smile.gif
60Кб Flash для реализации полноценной Форт системы - это, впрочем, достаточно много.
( пример 32-разрядный spf4, с кучей возможностей, для Windows ~100Кб где половину занимает
оптимизатор )

Цитата(MrYuran @ Jun 5 2009, 09:36) *
Эх, с чужой бы разобраться...
В синтаксисе я пока что двоечник и чайник.


В Форте почти нет синтаксиса. В асме его гораздо большеsmile.gif

А с чужим кодом, в силу тех или иных ограничений при реализации и
индивидуальности разработки, воспринимаемость может ухудшитьсяsmile.gif

Цитата(MrYuran @ Jun 5 2009, 09:36) *
Вот кучу интересных слов обнаружил.
...


Эти слова стандартные примитивы Форт системsmile.gif
Слова сгруппированы по функциональности и можно порекомендовать составлять
словарик изученных словsmile.gif

Цитата(MrYuran @ Jun 5 2009, 09:36) *
Опять же, всё на виду! Можно "открыть ящик" и посмотреть, какие в нём инструменты.


Почти все Форт системы, исключая немногочисленное количество коммерческих,
имеют открытые исходникиsmile.gif
Да и в комерческих много открытого кода. ( вопрос только в лицензии использования )
chu
Цитата(MrYuran @ Jun 5 2009, 13:36) *
Эх, с чужой бы разобраться...


Этопуть, по которому проходит каждый фортер.

Цитата(MrYuran @ Jun 5 2009, 13:36) *
В синтаксисе я пока что двоечник и чайник.


Ну какой синтаксис в форте? Примитивнейший. И это есть плюс+плюс.

Цитата(MrYuran @ Jun 5 2009, 13:36) *
Опять же, всё на виду! Можно "открыть ящик" и посмотреть, какие в нём инструменты.


А простота и доступность понимания реализации форта - величайшее достижение человечества в технологии программирования. biggrin.gif


PS. Moving Forth
Kopa
Цитата(MrYuran @ Jun 5 2009, 08:08) *
Вчера написал слово OR! и AND!
Работает, но логичнее написать на ассемблере.


для Сamel по аналогии с !
Код
;C AND!   x a-addr --   and cell in memory
        HEADER  AND!,4,'AND!',DOCODE
        AND     @PSP+,0(TOS)
        MOV     @PSP+,TOS
        NEXT


Вроде должно работатьsmile.gif
MrYuran
: Pulse ( Addr Mask --)
2DUP OR! FFFF XOR AND! ;

Формирует импульс длительностью 23 мкс при тактировании от DCO (4.8МГц)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.