Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Пн июл 23, 2018 19:28

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 13 ] 
Автор Сообщение
 Заголовок сообщения: ВМ на SPF для отработки системы команд и коротких программ
СообщениеДобавлено: Сб май 19, 2007 21:29 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Код:
\ ForthCPU/VM emulator by WingLion

\ сначала доопределение Форта
~day\common\console.f

HEX
CLS 0 0 AT-XY

\ закройте глаза и не читайте следующие 3-4 строчки!
\ почему в SPF нет слова H. - не знаю

: H. BASE @ SWAP HEX
  S>D <# # # # # # # # # #> TYPE SPACE
  BASE !
;

: FALSE! FALSE SWAP ! ;
: TRUE! TRUE SWAP ! ;
\ : 1+! 1 +! ; \ эта команда и так есть
: 1-! -1 +! ; \ а этой в SPF не оказалось

\ по подсказке ygrek-a (нужно для многострочного определения таблицы )
: NEXT-NAME BEGIN PARSE-NAME DUP 0= WHILE 2DROP REFILL 0= THROW REPEAT ;

\ ********************
\ тиснутое у ~profit-a и перековырянное определениe для таблиц
: нифига  \ вспоможитель
." Команда выполнила невыполнимую операцию и будет отшлепана по заднице! " CR ;
: таблица ( число-случаев "имя" -- )
CREATE
DUP 1+ , \ кол-во случаев плюс один
\ HERE TO текущее-состояние
0 DO NEXT-NAME ['] ' EVALUATE-WITH , LOOP
\ 0 DO ' , LOOP \ сразу скомпилировать все слова в таблицу
\ если слов при определении таблицы окажется меньше - полезут глюки
['] нифига DUP , ,  \ действие по-умолчанию,
\ для случаев номера которых превышают кол-во состояний
\ два раза потому что с одним вылазит accec violation :-\
DOES> DUP @ ROT MIN 1+ CELLS + @ EXECUTE ;

\ тупая проверка
: действие0 ." действие0" CR ;
: действие1 ." действие1" CR ;
: действие2 ." действие2" CR ;
5 таблица тупая-проверка
   действие0 действие1
   действие2 действие2 
   нифига

0 DUP . тупая-проверка
1 DUP . тупая-проверка
2 DUP . тупая-проверка
3 DUP . тупая-проверка
4 DUP . тупая-проверка
F DUP . тупая-проверка

\ остановиться и поглядеть
KEY \ BYE


\ 5 таблица TEST TRUE FALSE TRUE FALSE TRUE FALSE
\ 1 TEST . CR \ должно напечатать 2
\ 5 TEST . CR \ должно напечатать 11
\ KEY \ ждать клавишу
\ BYE




\ *********************** ну, привык я юзать звездюлины как разделители
\ теперь определения для ВМ

\ глобальные параметры
1000 CONSTANT MemSize \ размер памяти ВМ (в байтах)
10 CONSTANT DStS \ глубина стека данных  (в словах)
10 CONSTANT RStS \ глубина стека возвратов (в словах)

\ блоки ВМ
VARIABLE PC  \ счетчик команд
VARIABLE RAD \ регистр адреса/данных
VARIABLE CMD \ регистр команды
VARIABLE RADF \ флаг входного мультиплексора для RAD
\ TRUE - RStack -> RAD
\ FALSE - DStack ->RAD
VARIABLE RStF \ флаг входного мультиплексора для RStack
\ TRUE - PC+1 ->RStack
\ FALSE - RAD ->RStack

VARIABLE DStP \ поинтер D-стека
CREATE DStack DStS CELLS ALLOT \ стек данных
VARIABLE DStDO \ текущая вершина стека данных (вых. регистр стека)

VARIABLE RStP \ поинтер R-стека
CREATE RStack RStS CELLS ALLOT \ стек возвратов
VARIABLE RStDO \ текущая вершина стека возвратов (вых. регистр стека)

CREATE MEM MemSize ALLOT  \ память ВМ
MemSize 1- CONSTANT MASK \ ограничитель памяти ВМ

\ ****************************

: -1OO! 1- OVER OVER C! NIP ;
: init_MEM
MEM MemSize ERASE

\ микро-DUMP памяти ВМ

00 00 00 00  \ nop nop
01 10 00 00 00 \ call 0010
03 55 AA 00 00 \ lit AA55
00 00  \ nop nop
01 08 00 00 00 \ call 0008

MEM 15 +
15 0 DO -1OO! LOOP

\ 10 0 DO I DUP MEM + C! LOOP
;

: reset PC 0! DStP 0! RStP 0! RADF FALSE! RStF TRUE! ;

reset init_MEM

\ ****************************

: OUTMST \ вывод состояния стеков и памяти
   CR ." DataStack:" DStP @ H.
   DStack 8 DUMP
   CR ." RetStack:" RStP @ H.
   RStack 8 DUMP CR
   \ память
   CR ." Memory:" CR
   MEM 40 DUMP
;

: OUTSTR \ вывод состояния регистров
   \ регистры
   \   0 0 AT-XY
   CR
   ."  PC: " PC @ H.    \ счетчик команд
   ."  RAD " RAD @ H.   \ регистр адреса/данных
   ."  CMD " CMD @ H.   \ регистр команды
   ."  DSt " DStDO @ H. \ Вершина стека данных
   ."  RSt " RStDO @ H. \ Вершина стека возвратов
;

: OUTST \ вывод состояния ВМ
\    0 0 AT-XY
    OUTSTR
\    OUTMST
;

\ ****************************
\ Работа ВМ
\ ****************************
\ вспоможители
: PC++ PC 1+! ;
: MPC@ MEM PC @ MASK AND + @ ;
\ читать данные из памяти ВМ по адресу PC -- МЕМ(PC)
: MPC! MEM PC @ MASK AND + RAD @ SWAP ! ;
\ записать данные из RAD по адресу в PC
\ тут еще разбираться с шириной данных ВМ

: GetLit MPC@ PC @ 4 + PC ! ; \ получить литерал
: RdCMD MPC@ CMD C! PC++ ; \ читать команду
\ тут может быть и какая-нибудь распаковка и доп. чтение-вперед

\ ****************************
\ работа со стеком возвратов
\ ****************************

: RStA RStP @ RStS 1- AND CELLS RStack + ; \ реальный адрес вершины

: RNOP RStA @ RStDO ! RStF TRUE! ; \ прочитать вершину стека возвратов

: RSWAP RNOP RStF @ IF PC @ 1+ ELSE RAD @ THEN RStA ! ;
\ записать значение PC+1 или RAD в стек возвратов и счит. стар.вершину

: RPUSH RStP 1+! RSWAP RNOP ;
\ записать новое значение в стек возвратов и считать новую вершину

: RPOP RStP 1-! RNOP ; \ снять со стека возвратов одно значение

\ ****************************
\ работа со стеком данных
\ ****************************

: DStA RStP @ DStS 1- AND CELLS DStack + ; \ реальный адрес вершины

: DNOP DStA @ DUP DStDO ! ; \ прочитать вершину стека возвратов

: DSWAP DNOP RAD @ DStA ! ;
\ записать значение RAD в стек возвратов и считать старую вершину

: DPUSH DStP 1+! DSWAP DNOP ;
\ записать значение RAD в стек возвратов и считать новую вершину

: DPOP DStP 1-! DNOP ; \ снять со стека возвратов одно значение

\ ****************************
\ работа с RAD

: >RAD RADF @ IF RStDO ELSE DStDO THEN @ RAD ! RADF FALSE! ;
: ALU>RAD ; \ ALU-операция
: nRAD ; \ ничего не делать с RAD

\ ****************************
\ команды-команды-команды
\ ****************************

\ 0 - nop
: nop RdCMD RNOP DNOP nRAD ;
\ 1 - call
: call MPC@ PC++ RPUSH PC ! nop ;
\ 2 - if
: if GetLit RAD @ IF PC ! ELSE PC++ THEN nop ;
\ 3 - lit
: lit DPUSH GetLit RAD ! nop ;
\ 4 - >R
: >r RStF FALSE! RPUSH DPOP RADF FALSE! >RAD nop ;
\ 5 - R>
: r> RPOP DPUSH RADF TRUE! >RAD nop ;
\ 6 - ret
: ret RPOP RStDO @ PC ! nop ;
\ 7 - dup
: dup DPUSH >RAD nop ;
\ 8 - drop
: drop DPOP >RAD nop ;
\ 9 - over
: over DPOP DSWAP >RAD DPUSH DSWAP >RAD nop ;
\ A - swap
: swap DSWAP >RAD nop ;
\ B - pre:
: pre: nop ;
\ C - user:
: user: nop ;
\ D - sys:
: sys: nop ;
\ E - fetch ( @ )
: fetch
  RPUSH RAD @ PC ! MPC@ RAD ! ret ;
\ F - store ( ! )
: store
  RPUSH RAD @ PC ! DPOP >RAD MPC! ret ;

\ ******************************

: CMD@  CMD @ 0F AND ;  \ читать регистр команды


\ переопределение дешифрации команд через таблицу
10 таблица CMD-TAB
   nop call if lit
   >r r> ret dup
   drop over swap pre:
   user: sys: fetch store


: STEP CMD@ CMD-TAB ;

\ рабочий цикл
: pp CLS
  0 0 AT-XY  S" [ESC] - выход" TYPE
  OUTMST CR
  BEGIN 100 PAUSE  OUTST STEP KEY? IF KEY 1B = IF EXIT THEN THEN AGAIN ;


pp

\ 1000 PAUSE

\ BYE


Сюда буду сливать последний вариант кода,
пока он помещается в форумный формат

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Последний раз редактировалось WingLion Пн май 21, 2007 17:12, всего редактировалось 4 раз(а).

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс май 20, 2007 22:11 
Не в сети

Зарегистрирован: Вт май 09, 2006 12:31
Сообщения: 3438
Благодарил (а): 5 раз.
Поблагодарили: 16 раз.
И что сейчас она может? ( Я не могу пока понять). На СИ будет значительно больший исходник.

_________________
понимаю некоторую бестолковость некоторых вопросов


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс май 20, 2007 22:38 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
В данный момент почти ничего не может. Т.к. кода для команд нет - НОПы на все коды команд стоят, кроме одной. На этой одной, где нет НОПа программа и зацикливается, потому что PC меняется НОПом

В рабочем цикле (слово pp) выводится состояние регистров (OUTST) , стеков и памяти ВМ, исполняется одна команда (слово STEP) и цикл повторяется, пока не нажата клавиша ESC.

100 PAUSE - чтобы успеть увидеть, что делается
меняется PC и CMD. на CMD = 0F ВМ зацикливается на одном месте.
Чтобы увидеть это, надо код скопировать и ввести в SPF (у меня 4.18)

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пн май 21, 2007 02:16 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Так, показываю, что получилось теперь :

Последний вариант кода в первом посте этого топика


Добавился вариант 4-хбитных команд
(пока не всех, но тех, что получились)

проверял еще далеко не все, поэтому могут быть глюки

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Последний раз редактировалось WingLion Пн май 21, 2007 13:15, всего редактировалось 1 раз.

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пн май 21, 2007 02:47 
Не в сети

Зарегистрирован: Сб май 06, 2006 12:01
Сообщения: 959
Откуда: Украина, Харьков
Благодарил (а): 2 раз.
Поблагодарили: 7 раз.
WingLion писал(а):
: H. BASE @ >R HEX
S>D <# # # # # # # # # #> TYPE SPACE
R> BASE !
;

Код:
: H. BASE @ SWAP HEX
  S>D <# # # # # # # # # #> TYPE SPACE
  BASE !
;

А про таблицу мне подумать надо... поискать в готовых утилитах... ;)

_________________
With best wishes, in4.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пн май 21, 2007 03:02 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
таблицу рановато делать... я еще с префиксами думаю, как лучше сделать, чтобы их можно было подключать/отключать

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пн май 21, 2007 12:33 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
рано или не рано, но сделал через таблицу :)

Последний вариант кода в первом посте этого топика


Мысли вслух, чтобы не посеять:

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

2. lit сделать префиксом, чтобы определять литералы разной длины,
одно, двух, трех, и т.д. до восьмибайтовых(?) плюс
8 предопределенных литералов 0, -1, 1, 2, 4...
(разберемся каких надо больше)

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср май 23, 2007 17:38 
Выдался свободный часок, от совсем нечего делать поковырял тут код. Просто хочу помочь.

Шаг номер раз (список по мере важности):
http://files.myopera.com/profiT/forth/fcpu-table.f

1. Правильное включение библиотек (~day\common\console.f и ~profit\lib\chartable.f)
2. Использование таблиц, тех что из библиотеки (без выдираловки с мясом и мышцами отдельных функций)
3. Сохранение и восстановление системы счисления

Шаг номер два (рефакторизация nop в advance):
http://files.myopera.com/profiT/forth/fcpu-advance.f

1. nop , как оно и по логике вроде должно быть, сделано пустым
2. Действия по переходу к следующей команде (бывшие раньше в nop) обозначены как слово advance и это слово вызывается не в каждой команде отдельно, а централизировано вызывается в STEP.

Шаг номер три (переход с таблиц на состояния конечного автомата и демонстрация возможностей их, придуманы от фонаря полностью, чиста для демонстрации действия для пока незадействованных префиксов):
http://files.myopera.com/profiT/forth/fcpu-automata.f

1. "Префикс" sys допустим переключает способ работы lit (именно переключает, чтобы вернуть назад, нужно указать "префикс" sys ещё раз). В "обычном" режиме lit кладёт число на новый элемент стека, а в "режиме перекрывающего lit" эта команда не будет изменять глубину стека а будет пихать число сразу в аккумулятор, затирая старое значение.
2. Префикс user например говорит что допустим следующие три команды (число команда, взято оттуда, с потолка) выводить с отладочной печатью.
3. pre представляет собой условный префикс. Если на стеке стоит TRUE следом идущая команда обрабатывается, если FALSE -- игнорируется ("режим-пропускаемой-команды").

PS. Я там код правил вообще не смотря, не читая, и не понимая. Будут глюки -- звиняюсь.


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июл 29, 2007 15:36 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Ковырял я тут свой коде и понял, что доковырялся до того, что сам перестал понимать, что и где делается.

Короче, проблемы следующие.
1. В железе все делается параллельно, т.е. нет таких ситуаций, что часть операции исполнилась, часть нет, и при исполнении следующей части цикла в качестве данных появились новые данные от исполненной первой части. В программе на такое сплошь и рядом натыкаешься, и начинается такая путаница и свалка, что перестаешь понимать, что и когда делать.
Поэтому буду переделывать ВМ с иным принципом тактирования.
Суть примерно такая же, как в железе в тригерах типа "мастер-помощник".
Для каждого регистра завидутся не одна, а две переменные. Одна из них - истиное значение, вторая - значение, которое будет присвоено на следующем такте работы ВМ. Вычисляются вторые значения из первых, а, когда они вычислены, тогда и производится ТАКТ - все вычисленные значения значения вписываются в регистры.
Такая программа будет ужасно тормозить, просто потому, что все действия будут исполняться последовательно, плюс дополнительная операция по копированию вычисленных значений.
Однако, она будет более точно отражать железо и, соответственно, в железе все 'должно' будет работать сразу же, как только будут реализованы регистры и логика.

Код:
\ Emulator Forth-CPU version-2
\ Пока только заглушка

: H. BASE @ SWAP HEX
  S>D <# # # # # # # # # #> TYPE SPACE
  BASE !
;

HEX 20 CONSTANT NRs
CREATE R-OUTS NRs CELLS ALLOT ( выходы всех регистров )
CREATE R-INS NRs CELLS ALLOT ( входы всех регистров )

: Visuale ( отображение состояния R-OUTS ) H. CR ;
: TAKT R-INS R-OUTS NRs CELLS MOVE ; ( копирование данных со входов на выходы )

: LOGIC ; ( заглушка. тут вычисляются R-INS из R-OUTS )

: RESET ( начальная установка R-INS ) ;

: Работай-падла! RESET TAKT 10 0 DO LOGIC TAKT I Visuale LOOP KEY BYE ; ( исполнить 10 тактов)

Работай-падла!


_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Последний раз редактировалось WingLion Вс июл 29, 2007 15:52, всего редактировалось 1 раз.

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июл 29, 2007 15:39 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 6344
Благодарил (а): 14 раз.
Поблагодарили: 99 раз.
Интересная идея!!

А для ускорения можно так. Заводим struct (aka record), распихиваем по полям все переменные состояния. Объявляем два экземпляра (1 и 2) и два указателя (current, new). В процессе работы просто меняем местами указатели - новое автоматически становится текущим.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июл 29, 2007 15:58 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
Аха, а потом, можно и две и три структуры сделать, эмулируя тем самым конвейерную структуру :)
Вот только сейчас уже ясно, что вскоре слово TAKT будет исполняться намного быстрее чем LOGIC, Т.е. существенного ускорения с переключением структур не будет.

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вс июл 29, 2007 16:05 
Не в сети

Зарегистрирован: Вт май 09, 2006 12:31
Сообщения: 3438
Благодарил (а): 5 раз.
Поблагодарили: 16 раз.
Цитата:
нет таких ситуаций, что часть операции исполнилась, часть нет, и при исполнении следующей части цикла в качестве данных появились новые данные от исполненной первой части. В программе на такое сплошь и рядом натыкаешься, и начинается такая путаница и свалка, что перестаешь понимать, что и когда делать.
Поэтому буду переделывать

Как это получалос?

_________________
понимаю некоторую бестолковость некоторых вопросов


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пт сен 21, 2007 11:32 
---


Вернуться к началу
  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 13 ] 

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB