Автор |
Сообщение |
|
|
Заголовок сообщения: |
Re: EQUINOX: Целевой компилятор |
|
|
A вот и получившийся "крокодил" с метками: \ \ \ определения для работы с метками \ \ описание слов \ 1. NEW-LABEL - определяет имя для новой метки \ USE: NEW-LABEL label-name \ каждая новая метка получает уникальный идентификатор, и для нее заводится запись в таблице определенных меток \ для слова label-name определяется действие, по которому на стек кладется идентфикатор метки \ 2. COMPILE-LABEL ( id-label --> ) метка компилируется в целевую память и ссылка на место, \ куда она компилируется, помещается в таблицу неопределенных меток \ 3. SET-LABEL (id-label, addr --> ) в таблицу определенных меток для указанной метки записывается адрес \ 4. RESOLVE-LABELS - производится разрешение всех меток - \ по таблице неопределенных меток находятся адреса, куда надо размещать метки, \ а сами метки берутся из таблицы определнных меток \ если используемая метка оказалась неопределена - выдается *** ERROR *** \ если же не используется некая объявленная метка, то \ ( выдается только слабый --- warning --- ) не выдается! \ в коде все метки оказываются неопределенными \ к концу исходника программы всех их надо определить и вызвать RESOLVE-LABELS
\ настроечные константы 10 CONSTANT MAX-LABELS-NUM \ максимальное число использованных меток 100 CONSTANT MAX-LINK-NUM \ максимальное число ссылок на метки
\ размеры таблиц меток \ MAX-LABELS-NUM CELLS CONSTANT DEF-TABLE-SIZE \ определенных \ MAX-LINK-NUM CELLS CONSTANT UDEF-TABLE-SIZE \ неопределенных
\ создание таблиц CREATE DEF-LABEL-TABLE MAX-LABELS-NUM CELLS ALLOT \ определенных меток CREATE UDEF-LABEL-TABLE MAX-LINK-NUM CELLS ALLOT \ неопределенных меток
\ value переменные с числом использованных позиций в таблицах VALUE UDEF-LABELS 0 TO UDEF-LABELS \ неопределенных ссылок VALUE DEF-LABELS 0 TO DEF-LABELS \ определeнных меток
\ организация новой записи в таблице неопределенных меток : NEXT-UDEF \ --> addr - на выходе адрес для записи данных в таблицу UDEF-LABELS DUP 1+ TO UDEF-LABELS DUP MAX-LINK-NUM = IF ." --- ERROR! достигнут предел количества использованных ссылок на метки --- " CR THEN CELLS UDEF-LABEL-TABLE + \ полученный адрес выдается наружу --> PLACE-IN-TABLE ;
\ организация записи в таблице определенных меток и выдача ее номера как id-label : NEXT-ID \ -- id-label - на выходе номер новой определенной метки DEF-LABEL-TABLE DEF-LABELS CELLS + \ место для размещения записи -1 SWAP ! \ положить значение -1 в запись - означает, что метка не определена DEF-LABELS \ id-label DUP 1+ TO DEF-LABELS \ подготовка для следующей метки DUP MAX-LABELS-NUM = IF ." --- ERROR! достигнут предел количества используемых меток --- " CR THEN ; \ объявление новой метки - создание константы со следующим номером id-label : NEW-LABEL NEXT-ID CONSTANT ;
\ установить значение метки по id-label : SET-LABEL \ data,id_label --> CELLS DEF-LABEL-TABLE + \ адрес размещения метки в таблице DUP @ -1 <> IF ." --- ERROR! метка уже была определена --- " CR THEN SWAP 0FFFF AND SWAP ! \ установить! ;
\ компилировать метку в целевую память - компилируется id-label \ а в таблицу неопределенных меток заносится адрес, куда надо вписывать метку и ее id : COMPILE-LABEL \ id_label --> THERE OVER T, \ компиляция метки в целевую память 10000 * + \ вычисляется значение для записи в таблицу - (id_label * 65536) + addr NEXT-UDEF \ новый адрес в таблице неопределенных меток ! \ запись в таблицу неопределенных меток ;
\ разрешение всех меток : RESOLVE-LABELS UDEF-LABELS 0 DO \ цикл по всем записям ссылок на метки I CELLS UDEF-LABEL-TABLE + @ 10000 / \ получить id_label для метки \ получить запись определенной метки CELLS DEF-LABEL-TABLE + @ DUP -1 = IF ." --- ERROR! используемая метка не определена ---" THEN 0FFFF AND \ выделить значение метки
\ получить адрес для размещения метки I CELLS UDEF-LABEL-TABLE + @ 0FFFF AND 2 * TW! \ поместить метку в целевую память LOOP ; Сначала объявляются все метки... Вернее, они объявляются в процессе их появления в исходнике. В исходнике они используются независимо от того, где определены, в начале или в конце, перед реальным использованием или после. Когда исходник завершен, вызывается слово, разрешающее сразу все метки. Получается компиляция один проход, во время которого "собирается" таблица ссылок, по которой затем в скомпилированный код вписываются нужные адреса... Установкой двух констант регулируется количество используемых меток и ссылок на них. Формально, можно вписать в эти константы большие числа, но тогда... э... ну, почти ничего не произойдет, пока компилятор работает на компьютере "с бесконечной память", если компилятор потом на самой встроенной системе с EQUINOX запускать, то регулировка количества используемых меток очень даже нужна. п.с. ...код отлажен лишь частично...
A вот и получившийся "крокодил" с метками:
[pre]\ [color=#40BF00]\ \ определения для работы с метками \ \ описание слов \ 1. NEW-LABEL - определяет имя для новой метки \ USE: NEW-LABEL label-name \ каждая новая метка получает уникальный идентификатор, и для нее заводится запись в таблице определенных меток \ для слова label-name определяется действие, по которому на стек кладется идентфикатор метки \ 2. COMPILE-LABEL ( id-label --> ) метка компилируется в целевую память и ссылка на место, \ куда она компилируется, помещается в таблицу неопределенных меток \ 3. SET-LABEL (id-label, addr --> ) в таблицу определенных меток для указанной метки записывается адрес \ 4. RESOLVE-LABELS - производится разрешение всех меток - \ по таблице неопределенных меток находятся адреса, куда надо размещать метки, \ а сами метки берутся из таблицы определнных меток \ если используемая метка оказалась неопределена - выдается *** ERROR *** \ если же не используется некая объявленная метка, то \ ( выдается только слабый --- warning --- ) не выдается! \ в коде все метки оказываются неопределенными \ к концу исходника программы всех их надо определить и вызвать RESOLVE-LABELS
\ настроечные константы [/color] 10 CONSTANT MAX-LABELS-NUM \ максимальное число использованных меток 100 CONSTANT MAX-LINK-NUM \ максимальное число ссылок на метки
\ размеры таблиц меток \ MAX-LABELS-NUM CELLS CONSTANT DEF-TABLE-SIZE \ определенных \ MAX-LINK-NUM CELLS CONSTANT UDEF-TABLE-SIZE \ неопределенных
\ создание таблиц CREATE DEF-LABEL-TABLE MAX-LABELS-NUM CELLS ALLOT \ определенных меток CREATE UDEF-LABEL-TABLE MAX-LINK-NUM CELLS ALLOT \ неопределенных меток
\ value переменные с числом использованных позиций в таблицах VALUE UDEF-LABELS 0 TO UDEF-LABELS \ неопределенных ссылок VALUE DEF-LABELS 0 TO DEF-LABELS \ определeнных меток
[color=#00BF00]\ организация новой записи в таблице неопределенных меток[/color] : NEXT-UDEF \ --> addr - на выходе адрес для записи данных в таблицу UDEF-LABELS DUP 1+ TO UDEF-LABELS DUP MAX-LINK-NUM = IF ." --- ERROR! достигнут предел количества использованных ссылок на метки --- " CR THEN CELLS UDEF-LABEL-TABLE + \ полученный адрес выдается наружу --> PLACE-IN-TABLE ;
[color=#00BF00]\ организация записи в таблице определенных меток и выдача ее номера как id-label[/color] : NEXT-ID \ -- id-label - на выходе номер новой определенной метки DEF-LABEL-TABLE DEF-LABELS CELLS + \ место для размещения записи -1 SWAP ! \ положить значение -1 в запись - означает, что метка не определена DEF-LABELS \ id-label DUP 1+ TO DEF-LABELS \ подготовка для следующей метки DUP MAX-LABELS-NUM = IF ." --- ERROR! достигнут предел количества используемых меток --- " CR THEN ; [color=#00BF00]\ объявление новой метки - создание константы со следующим номером id-label[/color] : NEW-LABEL NEXT-ID CONSTANT ;
[color=#00BF00]\ установить значение метки по id-label[/color] : SET-LABEL \ data,id_label --> CELLS DEF-LABEL-TABLE + \ адрес размещения метки в таблице DUP @ -1 <> IF ." --- ERROR! метка уже была определена --- " CR THEN SWAP 0FFFF AND SWAP ! \ установить! ;
[color=#00BF00]\ компилировать метку в целевую память - компилируется id-label \ а в таблицу неопределенных меток заносится адрес, куда надо вписывать метку и ее id[/color] : COMPILE-LABEL \ id_label --> THERE OVER T, \ компиляция метки в целевую память 10000 * + \ вычисляется значение для записи в таблицу - (id_label * 65536) + addr NEXT-UDEF \ новый адрес в таблице неопределенных меток ! \ запись в таблицу неопределенных меток ;
[color=#00BF00]\ разрешение всех меток[/color] : RESOLVE-LABELS UDEF-LABELS 0 DO \ цикл по всем записям ссылок на метки I CELLS UDEF-LABEL-TABLE + @ 10000 / \ получить id_label для метки \ получить запись определенной метки CELLS DEF-LABEL-TABLE + @ DUP -1 = IF ." --- ERROR! используемая метка не определена ---" THEN 0FFFF AND \ выделить значение метки
\ получить адрес для размещения метки I CELLS UDEF-LABEL-TABLE + @ 0FFFF AND 2 * TW! \ поместить метку в целевую память LOOP ;[/pre]
Сначала объявляются все метки... Вернее, они объявляются в процессе их появления в исходнике. В исходнике они используются независимо от того, где определены, в начале или в конце, перед реальным использованием или после.
Когда исходник завершен, вызывается слово, разрешающее сразу все метки.
Получается компиляция один проход, во время которого "собирается" таблица ссылок, по которой затем в скомпилированный код вписываются нужные адреса...
Установкой двух констант регулируется количество используемых меток и ссылок на них. Формально, можно вписать в эти константы большие числа, но тогда... э... ну, почти ничего не произойдет, пока компилятор работает на компьютере "с бесконечной память", если компилятор потом на самой встроенной системе с EQUINOX запускать, то регулировка количества используемых меток очень даже нужна.
п.с. ...код отлажен лишь частично...
|
|
|
|
Добавлено: Пт апр 13, 2012 14:41 |
|
|
|
|
|
Заголовок сообщения: |
Re: EQUINOX: Целевой компилятор |
|
|
С литералами может помочь DISPATCH-NUMBER (в сочетании с переменной CAN-DISPATCH).
С литералами может помочь DISPATCH-NUMBER (в сочетании с переменной CAN-DISPATCH).
|
|
|
|
Добавлено: Чт апр 12, 2012 14:53 |
|
|
|
|
|
Заголовок сообщения: |
Re: EQUINOX: Целевой компилятор |
|
|
Хищник писал(а): Так, идею понял, буду пытаться сегодня реализовывать... Предвидятся некоторые сложности, надеюсь, они не помешают...
[quote="Хищник"]Вот тут есть про метки. http://fforum.winglion.ru/viewtopic.php?f=34&t=373 [/quote]
Так, идею понял, буду пытаться сегодня реализовывать...
Предвидятся некоторые сложности, надеюсь, они не помешают...
|
|
|
|
Добавлено: Чт апр 12, 2012 06:26 |
|
|
|
|
|
Заголовок сообщения: |
Re: EQUINOX: Целевой компилятор |
|
|
Вот тут есть про метки. [url]http://fforum.winglion.ru/viewtopic.php?f=34&t=373[/url]
|
|
|
|
Добавлено: Ср апр 11, 2012 19:43 |
|
|
|
|
|
Заголовок сообщения: |
Re: EQUINOX: Целевой компилятор |
|
|
Что еще надо сделать...
1. Организация меток для ссылок как вперед, так и назад. Назад - не сложно. А вперед надо еще думать, не забыв, что ссылки вперед могут использоваться несколько раз до того, как определены. Выход1: писать все метки в отдельный файл, который подгружать на втором проходе.
2. Организация компиляции строк. Наиболее подходящими считаю строки, заканчивающиеся нулем. СДЕЛАНО
3. Организация переменных и констант в целевой памяти.
Константа - по сути компиляция литерала. Переменная - компиляция адреса.
И для VALUE переменной - компиляция адреса с немедленным разыменованием, что в четырехбитной системе позволяет уложить такую команду в одно слово.
4. -- ой, много еще чего надо --
[b]Что еще надо сделать...[/b]
1. Организация меток для ссылок как вперед, так и назад. Назад - не сложно. А вперед надо еще думать, не забыв, что ссылки вперед могут использоваться несколько раз до того, как определены. Выход1: писать все метки в отдельный файл, который подгружать на втором проходе.
[color=#BFBFBF]2. Организация компиляции строк. Наиболее подходящими считаю строки, заканчивающиеся нулем.[/color] [b]СДЕЛАНО[/b]
3. Организация переменных и констант в целевой памяти.
Константа - по сути компиляция литерала. Переменная - компиляция адреса.
И для VALUE переменной - компиляция адреса с немедленным разыменованием, что в четырехбитной системе позволяет уложить такую команду в одно слово.
4. -- ой, много еще чего надо --
|
|
|
|
Добавлено: Ср апр 11, 2012 19:32 |
|
|
|
|
|
Заголовок сообщения: |
EQUINOX: Целевой компилятор |
|
|
файл первый - target.f формирует буфер образа целевой памяти и слова для работы с ним: // целевой компилятор для процессора EQUINOX-16 // используется Quark 1.0.11 build 30
." - target2.f загружен" CR
HEX \ всегда в HEX-е
\ параметры целевой системы
2 CONSTANT TARGET_WIDTH \ ширина целевой памяти в байтах 4000 CONSTANT TARGET_LEN \ длина целевой памяти 16KB CREATE BUFER TARGET_LEN ALLOT \ буфер под целевую память TARGET_LEN 2/ 1 - CONSTANT WMASK \ маска адреса слова в целевой памяти
\ все целевые адреса только по словам
\ получить реальный адрес для слова целевой памяти : MAKE_ADRW WMASK AND 2* BUFER + ;
VALUE THERE 0 TO THERE \ определить адрес компиляции в целевой памяти
\ работа с целевой памятью \ адресация пословная!
: TW@ MAKE_ADRW W@ ; : TW! MAKE_ADRW W! ;
\ установка адреса компиляции : TORG DUP TO THERE ;
\ компилировать слово в целевую память по адресу THERE \ адресация пословная! : T, \ data --> THERE TW! 1 +TO THERE ;
: TS, \ компилировать строку, заканчивающуюся нулем в целевую память BEGIN DUP C@ OVER 1+ C@ 100 * + \ формирование слова из двух байтов DUP T, 0 <> WHILE 2 + REPEAT ;
\ string, color : TCS, \ компилировать строку, заканчивающуюся нулем в целевую память \ в формате дисплейных данных (с цветом) >R BEGIN DUP C@ DUP R@ OR T, 0 <> WHILE 1+ REPEAT R> DROP ;
0 VALUE handle1
\ сохранение блока данных в файл : SAVE_BIN_FILE \ addr,len,string --> NEWFILE TO handle1 \ открывaем новый файл handle1 -ROT WRITEFILE \ сохраняем в него бинарный образ handle1 CLOSE ; \ закрываем файл
\ сохранение образа целевой памяти в файл \ STRING --> : SAVE_TARGET BUFER TARGET_LEN ROT SAVE_BIN_FILE ;
\ пример использования \ " __tt.bin" SAVE_TARGET
: TYPE 0 DO DUP I + C@ EMIT LOOP DROP ;
: TDUMP DO I H. ." : " I 10 0 DO DUP I + TW@ H. 20 EMIT LOOP ." | " I MAKE_ADRW 20 TYPE CR 10 +LOOP ; \ TDUMP
: align10 THERE 0F + FFF0 AND ; Файл второй equinox.f: ." - equinox2.f загружен" CR
VALUE CDA THERE TO CDA \ место для расположения командных нибблов VALUE NN 0 TO NN \ количество скомпилированных нибблов в текущем слове
: CW-I THERE TO CDA 0 TO NN ; : CW-INIT CW-I 0 T, \ инициализировать новое командное слово ;
\ новый ORG : TORG TO THERE CW-INIT ;
: NIBBLE 0F AND \ выделить ниббл CDA TW@ 10 * \ сдвинуть скомпилированные нибблы OR CDA TW! \ записать в целевую память 1 +TO NN \ считать нибблы \ если достигло 4-х инициализировать новое командное слово NN 4 = IF CW-INIT THEN ;
: TLIT T, ;
: XDUP 0A NIBBLE NIBBLE ; \ вспомогательное слово : XSWAP 0B NIBBLE NIBBLE ; \ вспомогательное слов : XDROP 0C NIBBLE NIBBLE ; \ вспомогательное слов
\ если следующий ниббл последний, забить его NOP-ом : notLAST NN 3 = IF 0 NIBBLE THEN ;
\ компилировать префикс с последующим нулем \ если попадает на конец слова - нуль пропускается : NIBBLE_and0 NN 3 = IF NIBBLE ELSE NIBBLE 0 NIBBLE THEN ;
: NZ NN IF 0 NIBBLE THEN ;
\ компилировать нули до конца слова : _compile_ NZ NZ NZ NZ ;
VOCABULARY .E16 .E16 DEFINITIONS
" target/equinox_commands.f" L
\ определение для метки назад : LABEL< CDA CONSTANT ; \ определение для метки вперед : LABEL> CONSTANT ;
: :: _compile_ CDA CONSTANT ;
\ новый ORG : TORG _compile_ TO THERE CW-INIT ;
: ;; THERE TORG ;
: variable CDA TW! LABEL< CDA 1+ TO THERE CW-INIT ;
: stops _compile_ stop stop stop stop _compile_ ; И Третий файл с собственно системой команд процессора equinox_commands.f: ." - equinox_commands.f загружен" CR
// -------------------------------------- // 10.04.2012 vers 1.03 // Oпределения для форт-процессора EQUINOX 16 // (c) 2012 WingLion // для использования с Quark 1.0.10 build 28 // -------------------------------------- // Справка: система команд процессора EQUINOX (март 2012 года) // команда код описание // NOP - 0 - нет операции - загрузка следующего командного слова // RET - 1 - возврат из подпрограммы // CALL - 2 L - вызов подпрограммы // BRAN - 3 L - условный переход по нулю в стеке данных // LIT - 4 L - загрузка литерала // @ - 5 - стандартное фортовое "присвоить" // ! - 6 - стандартное фортовое "разыменовать" // STOP - 7 - остановить процесс исполнения (HALT) // >R - 8 - переместить число со стека данных на стек возвратов // R> - 9 - переместить число со стека возвратов на стек данных // XDUP - А p - АЛУ операция с уменьшением глубины стека // XSWAP B p - АЛУ операция с неизменной глубиной стека // XDROP C p - АЛУ операьия с увеличением глубины стека // NOP13 D - оперция не определена // NOP14 E - оперция не определена // NOP15 F - оперция не определена // // - L - требует литерала // - p - префиксная команда
VOCABULARY .E16 DEFINITIONS
: nop 0 NIBBLE ; // нет операции (загрузка команды) : ret 1 NIBBLE ; // возврат из подпрограммы : call TLIT 2 NIBBLE _compile_ ; // вызов подпрограммы USE: addr CALL : ?bran TLIT 3 NIBBLE ; // условный переход по нулю на стеке USE: addr ?BRAN : lit TLIT 4 NIBBLE ; // загрузить литерал USE: data LIT : @ 5 NIBBLE ; // разыменовать : ! 6 NIBBLE ; // присвоить : stop 7 NIBBLE ; // остановить исполнение программы : >r 8 NIBBLE ; \ переместить данное из стека данных на стек возвратов : r> 9 NIBBLE ; \ переместить данное из стека возвратов на стек данных
: dup A NIBBLE_and0 ; : over notLAST 1 XDUP ; : zero notLAST 2 XDUP ; : mone notLAST 3 XDUP ;
: swap B NIBBLE_and0 ; : inc notLAST 1 XSWAP ; : dec notLAST 2 XSWAP ; : neg notLAST 3 XSWAP ; : inv notLAST 4 XSWAP ; : * notLAST 5 XSWAP ; : lconv notLAST 6 XSWAP ; : bswap notLAST 7 XSWAP ; : lshift notLAST 8 XSWAP ; : rshift notLAST 9 XSWAP ;
: drop C NIBBLE_and0 ;
: nip notLAST 1 XDROP ; : + notLAST 2 XDROP ; : - notLAST 3 XDROP ; : and notLAST 4 XDROP ; : or notLAST 5 XDROP ; : xor notLAST 6 XDROP ; : nand notLAST 7 XDROP ; \ : adc notLAST 8 XDROP ; \ : sbc notLAST 9 XDROP ;
// USE: addr JMP : jmp lit >r ret _compile_ ;
// USE: addr JZ : jnz _compile_ lconv notLAST ?bran drop _compile_ ;
// USE: addr JNZ : jz notLAST ?bran drop _compile_ ;
: r@ r> dup >r ;
: rdrop r> drop ;
: r++ r> inc >r ;
: r-- r> dec >r ;
: _and_ lit and ; : _nand_ lit nand ; : _or_ lit or ; : _xor_ lit xor ; : _add_ lit + ; : _sub_ lit - ; : _mul_ lit * nip ;
файл первый - target.f формирует буфер образа целевой памяти и слова для работы с ним:
[b][pre]// целевой компилятор для процессора EQUINOX-16 // используется Quark 1.0.11 build 30
." - target2.f загружен" CR
HEX \ всегда в HEX-е
\ параметры целевой системы
2 CONSTANT TARGET_WIDTH \ ширина целевой памяти в байтах 4000 CONSTANT TARGET_LEN \ длина целевой памяти 16KB CREATE BUFER TARGET_LEN ALLOT \ буфер под целевую память TARGET_LEN 2/ 1 - CONSTANT WMASK \ маска адреса слова в целевой памяти
\ все целевые адреса только по словам
\ получить реальный адрес для слова целевой памяти : MAKE_ADRW WMASK AND 2* BUFER + ;
VALUE THERE 0 TO THERE \ определить адрес компиляции в целевой памяти
\ работа с целевой памятью \ адресация пословная!
: TW@ MAKE_ADRW W@ ; : TW! MAKE_ADRW W! ;
\ установка адреса компиляции : TORG DUP TO THERE ;
\ компилировать слово в целевую память по адресу THERE \ адресация пословная! : T, \ data --> THERE TW! 1 +TO THERE ;
: TS, \ компилировать строку, заканчивающуюся нулем в целевую память BEGIN DUP C@ OVER 1+ C@ 100 * + \ формирование слова из двух байтов DUP T, 0 <> WHILE 2 + REPEAT ;
\ string, color : TCS, \ компилировать строку, заканчивающуюся нулем в целевую память \ в формате дисплейных данных (с цветом) >R BEGIN DUP C@ DUP R@ OR T, 0 <> WHILE 1+ REPEAT R> DROP ;
0 VALUE handle1
\ сохранение блока данных в файл : SAVE_BIN_FILE \ addr,len,string --> NEWFILE TO handle1 \ открывaем новый файл handle1 -ROT WRITEFILE \ сохраняем в него бинарный образ handle1 CLOSE ; \ закрываем файл
\ сохранение образа целевой памяти в файл \ STRING --> : SAVE_TARGET BUFER TARGET_LEN ROT SAVE_BIN_FILE ;
\ пример использования \ " __tt.bin" SAVE_TARGET
: TYPE 0 DO DUP I + C@ EMIT LOOP DROP ;
: TDUMP DO I H. ." : " I 10 0 DO DUP I + TW@ H. 20 EMIT LOOP ." | " I MAKE_ADRW 20 TYPE CR 10 +LOOP ; \ TDUMP
: align10 THERE 0F + FFF0 AND ;[/pre][/b]
Файл второй equinox.f:
[b][pre]." - equinox2.f загружен" CR
VALUE CDA THERE TO CDA \ место для расположения командных нибблов VALUE NN 0 TO NN \ количество скомпилированных нибблов в текущем слове
: CW-I THERE TO CDA 0 TO NN ; : CW-INIT CW-I 0 T, \ инициализировать новое командное слово ;
\ новый ORG : TORG TO THERE CW-INIT ;
: NIBBLE 0F AND \ выделить ниббл CDA TW@ 10 * \ сдвинуть скомпилированные нибблы OR CDA TW! \ записать в целевую память 1 +TO NN \ считать нибблы \ если достигло 4-х инициализировать новое командное слово NN 4 = IF CW-INIT THEN ;
: TLIT T, ;
: XDUP 0A NIBBLE NIBBLE ; \ вспомогательное слово : XSWAP 0B NIBBLE NIBBLE ; \ вспомогательное слов : XDROP 0C NIBBLE NIBBLE ; \ вспомогательное слов
\ если следующий ниббл последний, забить его NOP-ом : notLAST NN 3 = IF 0 NIBBLE THEN ;
\ компилировать префикс с последующим нулем \ если попадает на конец слова - нуль пропускается : NIBBLE_and0 NN 3 = IF NIBBLE ELSE NIBBLE 0 NIBBLE THEN ;
: NZ NN IF 0 NIBBLE THEN ;
\ компилировать нули до конца слова : _compile_ NZ NZ NZ NZ ;
VOCABULARY .E16 .E16 DEFINITIONS
" target/equinox_commands.f" L
\ определение для метки назад : LABEL< CDA CONSTANT ; \ определение для метки вперед : LABEL> CONSTANT ;
: :: _compile_ CDA CONSTANT ;
\ новый ORG : TORG _compile_ TO THERE CW-INIT ;
: ;; THERE TORG ;
: variable CDA TW! LABEL< CDA 1+ TO THERE CW-INIT ;
: stops _compile_ stop stop stop stop _compile_ ;[/pre][/b]
И Третий файл с собственно системой команд процессора equinox_commands.f:
[b][pre]." - equinox_commands.f загружен" CR
// -------------------------------------- // 10.04.2012 vers 1.03 // Oпределения для форт-процессора EQUINOX 16 // (c) 2012 WingLion // для использования с Quark 1.0.10 build 28 // -------------------------------------- // Справка: система команд процессора EQUINOX (март 2012 года) // команда код описание // NOP - 0 - нет операции - загрузка следующего командного слова // RET - 1 - возврат из подпрограммы // CALL - 2 L - вызов подпрограммы // BRAN - 3 L - условный переход по нулю в стеке данных // LIT - 4 L - загрузка литерала // @ - 5 - стандартное фортовое "присвоить" // ! - 6 - стандартное фортовое "разыменовать" // STOP - 7 - остановить процесс исполнения (HALT) // >R - 8 - переместить число со стека данных на стек возвратов // R> - 9 - переместить число со стека возвратов на стек данных // XDUP - А p - АЛУ операция с уменьшением глубины стека // XSWAP B p - АЛУ операция с неизменной глубиной стека // XDROP C p - АЛУ операьия с увеличением глубины стека // NOP13 D - оперция не определена // NOP14 E - оперция не определена // NOP15 F - оперция не определена // // - L - требует литерала // - p - префиксная команда
VOCABULARY .E16 DEFINITIONS
: nop 0 NIBBLE ; // нет операции (загрузка команды) : ret 1 NIBBLE ; // возврат из подпрограммы : call TLIT 2 NIBBLE _compile_ ; // вызов подпрограммы USE: addr CALL : ?bran TLIT 3 NIBBLE ; // условный переход по нулю на стеке USE: addr ?BRAN : lit TLIT 4 NIBBLE ; // загрузить литерал USE: data LIT : @ 5 NIBBLE ; // разыменовать : ! 6 NIBBLE ; // присвоить : stop 7 NIBBLE ; // остановить исполнение программы : >r 8 NIBBLE ; \ переместить данное из стека данных на стек возвратов : r> 9 NIBBLE ; \ переместить данное из стека возвратов на стек данных
: dup A NIBBLE_and0 ; : over notLAST 1 XDUP ; : zero notLAST 2 XDUP ; : mone notLAST 3 XDUP ;
: swap B NIBBLE_and0 ; : inc notLAST 1 XSWAP ; : dec notLAST 2 XSWAP ; : neg notLAST 3 XSWAP ; : inv notLAST 4 XSWAP ; : * notLAST 5 XSWAP ; : lconv notLAST 6 XSWAP ; : bswap notLAST 7 XSWAP ; : lshift notLAST 8 XSWAP ; : rshift notLAST 9 XSWAP ;
: drop C NIBBLE_and0 ;
: nip notLAST 1 XDROP ; : + notLAST 2 XDROP ; : - notLAST 3 XDROP ; : and notLAST 4 XDROP ; : or notLAST 5 XDROP ; : xor notLAST 6 XDROP ; : nand notLAST 7 XDROP ; \ : adc notLAST 8 XDROP ; \ : sbc notLAST 9 XDROP ;
// USE: addr JMP : jmp lit >r ret _compile_ ;
// USE: addr JZ : jnz _compile_ lconv notLAST ?bran drop _compile_ ;
// USE: addr JNZ : jz notLAST ?bran drop _compile_ ;
: r@ r> dup >r ;
: rdrop r> drop ;
: r++ r> inc >r ;
: r-- r> dec >r ;
: _and_ lit and ; : _nand_ lit nand ; : _or_ lit or ; : _xor_ lit xor ; : _add_ lit + ; : _sub_ lit - ; : _mul_ lit * nip ;[/pre][/b]
|
|
|
|
Добавлено: Ср апр 11, 2012 19:19 |
|
|
|
|