Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Пт мар 29, 2024 03:18

...
Google Search
Forth-FAQ Spy Grafic

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




Ответить
Имя пользователя:
Заголовок:
Текст сообщения:
Введите текст вашего сообщения. Длина сообщения в символах не более: 60000

Размер шрифта:
Цвет шрифта
Настройки:
BBCode ВКЛЮЧЕН
[img] ВЫКЛЮЧЕН
[flash] ВЫКЛЮЧЕН
[url] ВКЛЮЧЕН
Смайлики ВЫКЛЮЧЕНЫ
Отключить в этом сообщении BBCode
Не преобразовывать адреса URL в ссылки
Вопрос
Теперь гостю придется вводить здесь пароль. Не от своей учетной записи, а ПАРОЛЬ ДЛЯ ГОСТЯ, получить который можно после регистрации на форуме через ЛС.:
Этот вопрос предназначен для выявления и предотвращения автоматических регистраций.
   

Обзор темы - И снова - 16 Minimal instructions.
Автор Сообщение
  Заголовок сообщения:   Ответить с цитатой
Вчерашний код процессора отредактирован (новая версия - два поста выше).

Добавлены:
1. автомат ожидания - вставляет нужное количество тактов в циклы чтения памяти (минимум - два такта).
2. схема быстрого исполнения для команд, не требующих обащения к памяти - исполняются за один такт без тактов ожидания.
3. коды команд приведены в соответствие со списком в начале исходника
4. удалены левые коментарии
Сообщение Добавлено: Пн апр 12, 2010 20:51
  Заголовок сообщения:   Ответить с цитатой
Немного поигрался с компилятором...
EP2C20F484C7 -- 16 bit вариант - 180MHz - 710 LCELLs
EP2C20F484C7 -- 32 bit вариант - 148MHz - 1383 LCELLs
EP2AGX45CU17C4 -- 16 bit вариант - 418MHz - 318 ALUTs
EP2AGX45DF25C4 -- 32 bit вариант - 362MHz - 739 ALUTs

Добавка через день (компилировано на работе, на лицензионном квартусе)

EP3SE50F484C2 - 16 бит - 393ALUTs - 470MHz
EP4CGX22CF19C6 - 16 bit - 732LCELLs - 277MHz
EP3C16Q240C8 - 16 bit - 730LCELLs - 198MHz
Сообщение Добавлено: Вс апр 11, 2010 18:28
  Заголовок сообщения:   Ответить с цитатой
Прикидка на VHDL, которая у меня получилась:
Код:
-- version of 12 april 2010
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;

--Minimal instruction Forth Computer
--
--MIFC16
--
--0 NOP выборка следующей команды (нет операции)
--1 ?BRANCH (IFNZ) переход, если на стеке не ноль
--2 LIT загрузка непосредственного литерала на стек ( --> data )
--3 @ извлечь данное по адресу из стека ( addr --> data=mem[addr])
--4 ! сохранить даное в памяти по адресу ( data, addr --> )
--5 CALL вызов попрограммы ( вызов адресного интерпретатора)
--6 RET возврат из подпрограммы
--7 DUP дублирование данного с вершины стека ( d --> d d)
--8 DROP удаление данного с вершины стека ( d --> )
--9 SWAP перестановка двух элементов на вершине стека ( d1 d2 --> d2 d1)
--10 OVER копирование второго элемента стека ( d1 d2 --> d2 d1 d2)
--11 AR> переместить данное со стека данных на стек возвратов ( adr --> )
--12 A>R переместить данное со стека возвратов на стек данных ( --> adr)
--13 NAND поразрядное логическое "И-НЕ" двух верхних элементов стека ( d1 d1 --> d1 nand d2)
--: NOT DUP NAND ; поразрядное логическое инвертирование верхнего элемента стека (d --> not d)
--: OR NOT SWAP NOT NAND ; поразрядное логическое "ИЛИ" двух верхних элементов стека ( d1 d1 --> d1 or d2 )
--: AND NAND DUP NAND ; поразрядное логическое "И" ( d1 d1 --> d1 and d2 )
--: XOR OVER OVER NAND DUP >R NAND SWAP R> NAND NAND ; поразрядное "Исключающее ИЛИ" ( d1 d1 --> d1 xor d2)
--14 ADD сложить два верхних элемента стека (d1 d1 --> d1+d2)
--15 2/ разделить верхний элемент стека на 2 ( d --> d/2)
--: 2* DUP ADD ;

entity mifc16 is
GENERIC ( widtX : integer :=16 );

   Port(
   clk   : in std_logic;
   ready    : in std_logic := '1';
   reset   : in std_logic := '1';
   di  : in std_logic_vector (WidtX-1 downto 0);
   adr : out std_logic_vector (WidtX-1 downto 0);
   do   : out std_logic_vector (WidtX-1 downto 0);
   
   test_Cmd   : out std_logic_vector (3 downto 0);
   test_Trigg   : out std_logic;
   
   test_DStDo   : out std_logic_vector (WidtX-1 downto 0);
   test_RStDo  : out std_logic_vector (WidtX-1 downto 0);
   
   cs_RAM,wr_RAM,rd_RAM,Out_ena   :     out std_logic

   );

   
END mifc16;
   
ARCHITECTURE RTL OF mifc16 IS

   type wait_mashine is (Work1, Wait1, Wait2);
   
   subtype T_data is std_logic_vector (WidtX-1 downto 0);
   
   signal RStcmd    : std_logic_vector (1 downto 0);
   signal RStDi   : T_data; -- std_logic_vector (WidtX-1 downto 0);
   signal RStDo   : T_data; -- std_logic_vector (WidtX-1 downto 0);
   signal DStcmd    : std_logic_vector (1 downto 0);
   signal DStDi   : T_data; -- std_logic_vector (WidtX-1 downto 0);
   signal DStDo   : T_data; -- std_logic_vector (WidtX-1 downto 0);   

constant STnop : std_logic_vector (1 downto 0) := "00";
constant STpush : std_logic_vector (1 downto 0) := "01";
constant STpop : std_logic_vector (1 downto 0) := "10";
constant STswap : std_logic_vector (1 downto 0) := "11";


   signal STM   : wait_mashine;
   signal ENA      : std_logic;
   signal stw      : std_logic_vector (3 downto 0);
   signal rst1      : std_logic;

   signal cmdS      : std_logic_vector (3 downto 0);
   
   
   signal cmdr      : T_data;
   signal NEWcmdr   : T_data;
   signal zero      : T_data;
   signal CMD4shr   : T_data;

   signal WrRAM : std_logic;
   signal RdRAM : std_logic;
   signal CsRAM : std_logic;
   
   signal PC      : T_data; -- std_logic_vector (WidtX-1 downto 0);
   signal newPC   : T_data; -- std_logic_vector (WidtX-1 downto 0);
   
   signal TR      : T_data; -- std_logic_vector (WidtX-1 downto 0);
   signal newTR   : T_data; -- std_logic_vector (WidtX-1 downto 0);
   signal alux      : T_data; -- std_logic_vector (WidtX-1 downto 0);
   
   signal mul_res   : std_logic_vector (WidtX+WidtX-1 downto 0);
   signal Trigg,NewTrigg   : std_logic;

   -- внутренний WAIT - '0' - команда исполняется за один такт, иначе - не меньше 3-х
   signal IntWait   : std_logic;
   
COMPONENT Stack IS
GENERIC ( WidtX : integer :=16; depth : integer :=3);
Port (   clk   : in std_logic;
      cmd   : in std_logic_vector (1 downto 0);
      di   : in std_logic_vector (widtX-1 downto 0);
      do   : out std_logic_vector (widtX-1 downto 0);
      ena : in std_logic
);
END COMPONENT;   
   
BEGIN

   stack_dd: stack
   GENERIC MAP ( widtX => WidtX, depth => 8 )
   PORT MAP (clk,DSTcmd,DSTdo,DSTdi,ENA);
   
   stack_rr: stack
   GENERIC MAP ( widtX => WidtX, depth => 8 )
   PORT MAP (clk,RSTcmd,RSTdo,RSTdi,ENA);
   

   zero <= (others => '0');
   -- command register 4-bit shifted
   CMD4shr(widtX-5 downto 0) <= (cmdr(widtX-1 downto 4));
   CMD4shr(widtX-1 downto widtX-4)<=zero(widtX-1 downto widtX-4);

   -- REGISTERS and RESET SHEME
   process (clk,ena) begin
      if (CLK'event and CLK='1' and ENA='1' ) then
      
         if rst1 = '0' then
            cmdr <= zero;
            PC <= zero;
            TR <= newTR;
            Trigg <= '0';
         else
            cmdr <= NEWcmdr;
            PC <= newPC;
            TR <= newTR;
            Trigg <= NewTrigg;
         end if;
      end if;
   end process;

   -- !!! WAIT MACHINE !!!
   process (clk,STM) begin
      if (CLK'event and CLK='1' ) then
         if reset = '0' then
            STM <= Work1; ENA <= '1'; stw <= (others => '0');
            rst1 <= '0';
         else
            rst1 <= '1';
            case STM is
               when Work1 => if (IntWait = '1') then STM <= Wait1; ENA <= '0'; stw <= zero (3 downto 0) + 1; else
                  STM <= Work1; ENA <= '1'; stw <= zero (3 downto 0);  end if;
               when Wait1 => if (stw = 1) then stw <= zero (3 downto 0) + 1; else stw <= stw - 1; end if; ENA <= '0';
                  if ((stw = 1) and ready = '1') then STM <= Wait2; else STM <= Wait1;  end if;
               when Wait2 => STM <= Work1; ENA <= '1'; stw <= (others => '0');
            end case;
         end if;
      end if;
   end process;
   
   CmdS <= cmdr (3 downto 0);

   -- MAIN COMMAND CASE
   
   process (NEWcmdr(3 downto 0)) begin
      case conv_integer(NEWcmdr(3 downto 0)) is
         when 0 => IntWait <= '1';
         when 1 => IntWait <= '1';
         when 2 => IntWait <= '1';
         when 5 => IntWait <= '1';
         when 3 => intWait <= Trigg;
         when 4 => intWait <= Trigg;
         when others => IntWait <= '0';
      end case;
   end process;
   

   process (cmdr (3 downto 0)) begin
   
      case conv_integer(cmdr (1 downto 0)) is
         when 1 => alux <= TR nand DSTdi;
         when 2 => alux <= TR + DSTdi;
         when 3 => alux <= TR(WidtX-1)&TR(WidtX-1 downto 1);
         when others => alux <= TR;
      end case;
   
      case conv_integer(cmdr (3 downto 0)) is
         -- NOP
         when 0 => NEWcmdr <= di; newPC <= PC + 1; RStcmd <= STnop;
            NewTrigg <= '0';
            RStdo <= RStdi; newTR <= TR; DStcmd <= STnop; DStdo <= DStdi;
            CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0';
         -- LIT
         when 1 => NEWcmdr <= cmd4shr;  newPC <= PC + 1; RStcmd <= STnop;
            NewTrigg <= '0';
            DStdo <= TR; newTR <= di; DStcmd <= STpush; RStdo <= RStdi;
            CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0';
         -- CALL
         when 2 => NEWcmdr <= cmd4shr;
            NewTrigg <= '0';
            newPC <= di; RStDo <= PC + 1; RStcmd <= STpush;
            newTR <= TR; DStcmd <= STnop; DStdo <= DStdi;
            CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0';
         -- @
         when 3 =>
            newTrigg <= not Trigg;
            if Trigg = '0' then
               
               CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
               NEWcmdr <= cmdr;
               RStcmd <= STpush; newPC <= TR; RStdo <= PC;
               newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi;
            else
               
               CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0';
               NEWcmdr <= cmd4shr;
               RStcmd <= STpop;    newPC <= RSTdi; RStdo <= RStdi;
               newTR <= di;    DStcmd <= STpush; DStdo <= TR;
            end if;
         -- !
         when 4 =>
            newTrigg <= not Trigg;
            if Trigg = '0' then
               
               CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
               NEWcmdr <= cmdr;
               RStcmd <= STpush; newPC <= TR; RStdo <= PC;
               DStcmd <= STpop; newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi;
            else
               
               CsRAM <= '0'; WrRAM <= '0'; RdRAM <= '1';
               NEWcmdr <= cmd4shr;
               RStcmd <= STpop; newPC <= RSTdi; RStdo <= RStdi;
               DStcmd <= STpop; newTR <= DStdi; DStcmd <= STpop; DStdo <= DStdi;
            end if;
            
         -- ?BRANCH
         when 5 => NEWcmdr <= cmd4shr; RStdo <= RStdi;
            
            NewTrigg <= '0';
            newTR <= TR; DStcmd <= STnop; DStdo <= DStdi;
            CsRAM <= '0'; WrRAM <= '1'; RdRAM <= '0';
            if (TR = 0) then
               newPC <= PC + 1; RStcmd <= STnop;
            else
               newPC <= di; RStcmd <= STnop;
            end if;            
         -- RET
         when 6 => NEWcmdr <= cmd4shr; 
            
            NewTrigg <= '0';
            newPC <= RStDi; RStcmd <= STpop;
            RStdo <= RStdi; newTR <= TR; DStcmd <= STnop; DStdo <= DStdi;
            CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
         -- DUP
         when 7 => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC;
            
         CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
            NewTrigg <= '0';
            RStdo <= RStdi;
            newTR <= TR;
            DStcmd <= STpush;
            DStdo <= TR;
         -- DROP            
         when 8 => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC;
            
            CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
            NewTrigg <= '0';
            RStdo <= RStdi;
            newTR <= DSTdi;
            DStcmd <= STpop;
            DStdo <= TR;            
         -- SWAP
         when 9 => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC;
            
            CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
            NewTrigg <= '0';
            RStdo <= RStdi;
            -- swap*
            newTR <= DSTdi;
            DStcmd <= STswap;
            DStdo <= TR;         
         -- OVER   
         when 10 => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC;
            
            CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
            NewTrigg <= '0';
            RStdo <= RStdi;
            -- dup*
            newTR <= DSTdi;
            DStcmd <= STpush;
            DStdo <= TR;
         -- R>
         when 11 => NEWcmdr <= cmd4shr; RStcmd <= STpop; newPC <= PC;
            
            CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
            NewTrigg <= '0';
            RStdo <= RStdi; newTR <= RStdi; DStcmd <= STpush; DStdo <= TR;            
         -- >R
         when 12 => NEWcmdr <= cmd4shr; RStcmd <= STpush; newPC <= PC;
            
            CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
            NewTrigg <= '0';
            RStdo <= TR; newTR <= DStdi; DStcmd <= STpop;
            DStdo <= DStdi;
         -- NAND
         when 13 =>
            
            CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
            NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC;
            NewTrigg <= '0';
            RStdo <= RStdi;
            newTR <= alux; -- TR nand DSTdi;
            DStcmd <= STpush;
            DStdo <= TR;
         -- ADD
         when 14 =>
            
            CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
            NewTrigg <= '0';   
            NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC;
            RStdo <= RStdi;
            -- dup*
            newTR <= alux; -- TR + DSTdi;
            DStcmd <= STpush;
            DStdo <= TR;
         -- 2/
         when 15 =>
            
            CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
            NewTrigg <= '0';
            NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC;
            RStdo <= RStdi;
            newTR <= alux; -- TR(WidtX-1)&TR(WidtX-1 downto 1);
            DStcmd <= STpush;
            DStdo <= TR;

         when others => NEWcmdr <= cmd4shr; RStcmd <= STnop; newPC <= PC;
            
            CsRAM <= '1'; WrRAM <= '1'; RdRAM <= '1';
            NewTrigg <= '0';
            RStdo <= RStdi; DStdo <= DStdi; DStcmd <= STnop; DStdo <= DStdi;
            newTR <= TR;

      end case;
   
   end process;

   do <= TR;
   adr <= PC;
   test_cmd <= CmdS;
   Out_ena <= ENA;
   
   cs_RAM <= csRAM or ENA;
   rd_RAM <= rdRAM or ENA;
   wr_RAM <= wrRAM or ENA;
   test_Trigg <= Trigg;
   test_RStDo <= RSTdo;
   test_DStDo <= DSTdo;
   

END RTL;

--   

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;

ENTITY   stack IS

GENERIC ( WidtX : integer := 16;
      depth : integer := 3
      );
      
      Port (
         
         clk   : in std_logic;
         cmd   : in std_logic_vector (1 downto 0);
         di   : in std_logic_vector (WidtX-1 downto 0);
         do   : out std_logic_vector (WidtX-1 downto 0);
         ena   : in std_logic
      );

END stack;

ARCHITECTURE SRTL OF stack IS
   
attribute altera_attribute : string;
attribute altera_attribute of SRTL: architecture is "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF";   

TYPE Tstack IS array (depth-1 downto 0) OF std_logic_vector (WidtX-1 downto 0);

constant nop : std_logic_vector (1 downto 0) := "00";
constant push : std_logic_vector (1 downto 0) := "01";
constant pop : std_logic_vector (1 downto 0) := "10";
constant swap : std_logic_vector (1 downto 0) := "11";
   
   signal st : Tstack;
   
BEGIN

   process (clk,cmd) begin
      if (clk'event and clk='1' and ena = '1') then
         case cmd is
            when nop => st <= st;
            when pop => st(depth-2 downto 0) <= st(depth-1 downto 1); st(depth-1) <= (others => '0');
            when push => st(depth-1 downto 1) <= st(depth-2 downto 0); st(0) <= di;
            when swap => st(depth-1 downto 1) <= st(depth-1 downto 1); st(0) <= di;
         end case;
      end if;      
   end process;
   do   <= st(0);
   
END ARCHITECTURE;


На CYCLONE-II эта штучка вытягивает до 180MHz
При условии, что обращение к внутренней памяти занимает 3 такта - получается 60MIPS
Сообщение Добавлено: Вс апр 11, 2010 17:49
  Заголовок сообщения:   Ответить с цитатой
А что с командным конвейером? Какая ширина команд? Я тут уже готов на VHDL прикинуть.
Сообщение Добавлено: Вс апр 11, 2010 16:52
  Заголовок сообщения:   Ответить с цитатой
вопрос писал(а):
это плохо для призводительности, если не сделать какую-либо более хитрую оптимизацию


Интересное это дело! - Оптимизировать шкуру неубитого медведя!.. :))
Сообщение Добавлено: Сб апр 10, 2010 15:20
  Заголовок сообщения:   Ответить с цитатой
наименее редко используемые операции, чтобы потом по возможности вынести ==
наиболее часто вынести
Сообщение Добавлено: Сб апр 10, 2010 14:02
  Заголовок сообщения:   Ответить с цитатой
Хищник писал(а):
PC и embedded программы достаточно существенно отличаются

я это понимаю, поэтому и спрашивал статистику посмотреть, на которую ссылался Хищник ;)
Более того, то, что у меня есть собиралось совсем для другой вещи - я смотрел наименее редко используемые операции, чтобы потом по возможности вынести их из ядра во внешние библиотеки.
Сообщение Добавлено: Сб апр 10, 2010 13:55
  Заголовок сообщения:   Ответить с цитатой
вопрос писал(а):
это плохо для призводительности, если не сделать какую-либо более хитрую оптимизацию

А какую же оптимизацию тут еще можно сделать, если объем операций может быть обусловлен требованиями ТЗ? Если надо посчитать c = a + b, то это будет a @ + b @ + c !. При этом a b c представляют собой литералы - адреса переменных.
Сообщение Добавлено: Сб апр 10, 2010 13:40
  Заголовок сообщения:   Ответить с цитатой
mOleg писал(а):
всеравно картина по частоте использования есть.
видно, что чаще всего литералы встречаются, потом DUP DROP SWAP @ + OVER ! и удивительно часто NOOP

PC и embedded программы достаточно существенно отличаются. Для embedded характерен больший удельный вес операций работы с памятью и портами, потому что монитор и файловая система как-то нечасто встречаются в таких системах. И если для PC нет-нет да и проскакивает DUP . , то для embedded такая отладочная печать может быть либо невозможна (по причине отсутствия устройства, поддерживающего символьный вывод), либо малоосмысленна (экран 16x2, который мгновенно забьется этой отладочной печатью).
Сообщение Добавлено: Сб апр 10, 2010 13:37
  Заголовок сообщения:   Ответить с цитатой
mOleg писал(а):
Хищник писал(а):
Где форк и где ПЛИС?

всеравно картина по частоте использования есть.
видно, что чаще всего литералы встречаются

это плохо для призводительности, если не сделать какую-либо более хитрую оптимизацию
Сообщение Добавлено: Сб апр 10, 2010 13:23
  Заголовок сообщения:   Ответить с цитатой
Хищник писал(а):
rupor "Тиграаааааааааа!".....


хм, а он сюда заглядывает? :shuffle;
Сообщение Добавлено: Сб апр 10, 2010 12:45
  Заголовок сообщения:   Ответить с цитатой
Хищник писал(а):
Где форк и где ПЛИС?

всеравно картина по частоте использования есть.
видно, что чаще всего литералы встречаются, потом DUP DROP SWAP @ + OVER ! и удивительно часто NOOP
Сообщение Добавлено: Сб апр 10, 2010 11:43
  Заголовок сообщения:   Ответить с цитатой
mOleg писал(а):
вот статистика по частоте использования слов в ядре форка, т.е. речь не о примитивах, а вообще о любом слове, которое искалось и компилировалось во время сборки ядра:

Где форк и где ПЛИС?
Сообщение Добавлено: Сб апр 10, 2010 11:34
  Заголовок сообщения:   Ответить с цитатой
Хищник писал(а):
mOleg писал(а): очень хотелось бы увидеть результирующую статистику (в смысле, по примитивам)
"Тиграаааааааааа!".....

вот статистика по частоте использования слов в ядре форка, т.е. речь не о примитивах, а вообще о любом слове, которое искалось и компилировалось во время сборки ядра:

117 DUP
073 0
072 DROP
067 SWAP
067 A@
066 @
065 +
064 OVER
055 A!
054 -
054 L>
052 >L
044 THROW
038 NOOP
035 !
035 DDROP
034 HERE
034 L@
034 COMPILE,
032 COUNT
032 =
024 FALSE
023 TYPE
020 R>
020 DDUP
019 TRUE
019 NIP
019 TUCK
019 >STDERR
018 GET-CURRENT
017 LDROP
017 CATCH
017 +!
016 >R
Сообщение Добавлено: Сб апр 10, 2010 10:34
  Заголовок сообщения:   Ответить с цитатой
WingLion писал(а):
Но, это еще вопрос, надо ли так делать?.. И даст ли оно реальный выигрыш?

Я тут на днях именно так и сделал. То есть JMP по сути есть EXECUTE, и все команды перехода (jmp/if/call) берут адрес со стека. Хотя можно адрес и после команды тянуть, тоже вариант.
Сообщение Добавлено: Сб апр 10, 2010 00:04

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


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