nedoPC.org

Community for electronics hobbyists, established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 06 Oct 2024 21:22



Reply to topic  [ 34 posts ]  Go to page 1, 2, 3  Next
Robby - расширение языка Robot Warfare 1 (RW1) 
Author Message
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23357
Location: Silicon Valley
Reply with quote
Пришло время с нуля писать новую быструю виртуальную машину RW0 на голом C...

P.S. Это в том числе и для RW3D будет использовано

P.P.S. Использование слова "Robby" в качестве нового варианта названия языка RW1 началось с мая 2016,
соответственно теперь виртуальную машину можно обозвать RobbyVM


P.P.P.S. Исходники старых виртуальные машин RW0 можно посмотреть вот в этих репах:
https://gitlab.com/shaos/rw1o (версия байткода 1.99)
https://gitlab.com/shaos/rw2d (версия байткода 2.0)
И ещё был простой интерпретатор на PocketC

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


17 Apr 2011 09:48
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23357
Location: Silicon Valley
Reply with quote
Post 
Придётся поддержать в том числе и старую систему команд (см. про версию 1.99 тут):

Code:
 Robot Warfare 1
 RW0 bytecode description
 Version 1.99

 Alexander A. Shabarshin (shaos@mail.ru)
 http://robots.ural.net

 November 1998 - January 2000

 Header:
 -------

0x0000: 0x00..0x02 // Version (0x00 for 1.*, 0x01 for 1.99)
0x0001: 2 bytes // CheckSum (simple adding of the bytes starting from 0x0005)
0x0003: 2 bytes // Offset to bytecode start point (in bytes)
0x0005: 1 byte  // Length of the robot name (strlen)
0x0006: N bytes // Robot name
0x????: 0x00    // Terminal character for robot name
0x????: 2 bytes // Number of variables (plus arrays length)
0x????: 2 bytes // Code length in bytes (beginning from start point)
0x????: 3 bytes // Robot color (R,G,B)
0x????: 4 bytes // Equipments on the FRONT,RIGHT,BACK,LEFT (0-empty,1-eye,2-gun)
0x????: 1 byte  // Image flag (0x00-image is absent, 0x20-image is present)
// if image present, then next 32 bytes describe the robot image (2pix/byte)
// after that follows bytecode (after start point)
0x????: N bytes // Author nickname
0x????: 0x00    // Terminal character for author nickname
0x????: ?? ...  // reserved for additional data
START:

-----------------------------------------------------------------
 B - byte (1 byte)
 W - word (2 bytes - low byte + high byte)
 M - variable or constant (3-5 bytes):
     0x00 W - signed integer (-32K..+32K)
     0x01 W - variable in W cell (array[constant] is compiled to it too)
     0x02 W1 W2 - array element (W1-begin of array, W2-variables with offset)
 Registers are variables (0x01 0x?? 0xFF) with the addresses:
 0xFF00 - X // register for relative X value
 0xFF01 - Y // register for relative Y value
 0xFF02 - D // register for distance value
 0xFF03 - N // register for object value
 0xFF04 - K // register for additional value
 0xFF05 - R // register for random value
 0xFF06 - T // register for timer value
 0xFF07 - E // register for our energy value
 0xFF08 - M // register for our missiles number
 0xFF09 - I // register for order number of robot
 0xFF0F - S // register for stack length

 labW - label with address W
-----------------------------------------------------------------

 DEF commands - array definition (minimal length is 5 bytes)
 ------------

 0x01 W1 W2 // DEF arr[len]  (W1-offset to array start, W2-len)
 0x02 W1 W2 W3 ... // DEF arr[len]={list}  (W3-number of words)

 IF commands - maximal length is 13 bytes
 -----------

 0x10 W M1 M2 // IF M1<M2 : labW
 0x11 W M1 M2 // IF M1>M2 : labW
 0x12 W M1 M2 // IF M1<=M2 : labW
 0x13 W M1 M2 // IF M1>=M2 : labW
 0x14 W M1 M2 // IF M1==M2 : labW
 0x15 W M1 M2 // IF M1!=M2 : labW
           // or IF M1<>M2 : labW

 Expressions - maximal length is 11-16 bytes
 -----------

 0x20 M1 M2 // M1=M2
 0x21 M1 M2 // M1=-M2
 0x22 M1 M2 M3 // M1=M2+M3
 0x23 M1 M2 M3 // M1=M2-M3
 0x24 M1 M2 M3 // M1=M2/M3
 0x25 M1 M2 M3 // M1=M2*M3
 0x26 M1 M2 M3 // M1=M2%M3
 0x27 M1 M2 M3 // M1=M2&M3 - binary AND
 0x28 M1 M2 M3 // M1=M2|M3 - binary OR
 0x29 M1 M2 M3 // M1=M2^M3 - binary XOR
 0x2A M1 M2 // M1=~M2 - binary NOT

 Simple commands - 1-5 bytes
 ---------------

 0x30 W // GOTO labW
 0x31 W // CALL labW
 0x33 // RET
 0x34 // STEP
 0x35 // LEFT
 0x36 // RIGHT
 0x37 string 0x00 // SAY "string"
 0x38 M // print M
 0x3A M // ACT M (FRONT=0,RIGHT=1,BACK=2,LEFT=3)
 0x3B   // SPY
 0x3C M // RADAR M
 0x3F 0x00 B // DUMP variables in the B columns  (3 bytes)

 0x51 W wildcard-string 0x00 // TEST "wildcard" : label

 0x60 M // SHOT var
 0x61 M1 M2 // SEND var1 var2 - send code var1 to robot var2
 0x62 M // RECV var - receive code and save it to var
 0x63   // POP

 0xFF // END - end of bytecode

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


18 Apr 2011 19:47
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23357
Location: Silicon Valley
Reply with quote
Post 
Предполагается, что код виртуальной машины будет собираться в большинстве существующих компиляторов C, как 32-битных:
- GCC 4
- DJGPP (GCC 2.81)
- Open Watcom C/C++ 1.9
- Borland C++Builder 5.5
- Visual C++ ?
- LCC 4.2 ?
- TCC 0.9.25 ?

так и 16-битных:
- Borland C++ 3.1
- Turbo C 2.01
- Pacific C 7.51
- SDCC 3.0.0 ?
- GCC for AVR ?
- GCC for HC11 ?

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


18 Apr 2011 20:09
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23357
Location: Silicon Valley
Reply with quote
Post 
Надо компилятор RW1C улучшать - добавить возможность использовать локальные переменные (через ключевое слово LOCAL, а не через задницу) и функции поддержать внутри выражений, причём байткод при этом не изменится - всё будет работать на старых виртуальных машинах, если сделать так, как я предположил в ноябре 2004:
Shaos wrote:
Появится регистр H, означающий старшие 16 бит результата L (может оказаться полезным например при умножении).

Также появится возможность использовать функции - они будут преобразовываться в вызов подпрограмм препроцессором. Например:

res=2+fun1(2,3)/fun2(4)

преобразуется препроцессором в

A=2;B=3;CALL fun1;_1=L
A=4;CALL fun2;_2=L
res=2+_1/_2
Кстати регистр H был поддержан на уровне компилятора ещё в версии 2.1.3 (29 ноября 2005), а вот функций до сих пор нет :oops:

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


23 Nov 2013 17:09
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23357
Location: Silicon Valley
Reply with quote
Post 
Shaos wrote:
Надо компилятор RW1C улучшать - добавить возможность использовать локальные переменные (через ключевое слово LOCAL, а не через задницу) и функции поддержать внутри выражений, причём байткод при этом не изменится - всё будет работать на старых виртуальных машинах...

инкремент-декремент через ++ и -- (оба префикс и постфикс) тоже можно на уровне препроцессора реализовать (без изменения байткода)

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


11 Nov 2014 10:23
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23357
Location: Silicon Valley
Reply with quote
Post 
По идее перейти с 16-битной арифметики на 32-битную в RW0-байткоде ничего не мешает т.к. мы просто все регистры и все ячейки памяти объявляем 32-битными и всё - разве что можно ещё инструкций добавить для непосредственного ввода в стек и копирования в переменные больших 32-битных чисел (а заодно 8-битных и 24-битных):
Code:
 M - variable or constant (2-9 bytes):
     0x00 W - signed integer (-32768...+32767)
     0x01 W - variable in W cell (array[constant] is also compiled to this)
     0x02 W1 W2 - array element (W1-begin of array, W2-variables with offset)
============== NEW if memory is still small (<64K)
     0x03 B - byte (0...255)
     0x04 BL BM BH - signed 24-bit integer (-8 millions ... +8 millions)
     0x05 WL WH - signed 32-bit integer (-2 billions ... +2 billions)
============== NEW if memory is bigger (>=64K)
     0x06 B - variable with tiny offset (<256)
     0x07 BL BM BH - variable with 3-byte offset (< 16 millions)
     0x08 WL WH - variable with long offset (< 4 billions)
     0x09 W0 W2 WL WH - long array with long offset
.....

 Expressions
 -----------
 
.....

     0xF5 W // PUSH W   . -> W
     0xF6 // []         A,B -> A[B]
============== NEW to push signed 32-bit integer
     0xF7 W1 W2 // PUSH L  . -> L

Пару слов лучше наверное размещать по традиции как little-endian, т.е. младшие байты идут первыми...

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


10 Dec 2014 08:46
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23357
Location: Silicon Valley
Reply with quote
Вот наиболее полный список байткодов Robby VM версии 2.2:

Code:
 Robot Warfare 1
 RW0 bytecode description
 Version 2.2

 Alexander A. Shabarshin (shaos@mail.ru)
 http://rwar.net

 November 1998 - December 2012

 Header:
 -------

0x0000: 0x00..0x02 // Version (0 for v1.*, 1 for v1.99, 2 for v2.*)
0x0001: 2 bytes // CheckSum (sum of bytes from 0x0005 to the end)
0x0003: 2 bytes // Offset to bytecode entry point (in bytes)
0x0005: 1 byte  // Length of the robot name (strlen)
0x0006: N bytes // Robot name
0x????: 0x00    // Terminal character for robot name
0x????: 2 bytes // Number of variables (plus arrays length)
0x????: 2 bytes // Code length in bytes (beginning from start point)
0x????: 3 bytes // Robot color (R,G,B)
0x????: 4 bytes // Equipments on the FRONT,RIGHT,BACK,LEFT (0-empty,1-eye,2-gun)
0x????: 1 byte  // Image flag (0x00-image is absent, 0x20-image is present)
// if image present, then next 32 bytes describe the robot image (2pix/byte)
0x????: N bytes // Author nickname
0x????: 0x00    // Terminal character for author nickname
0x????: ?? ...  // Reserved for additional data
// after that follows bytecode
START: // Entry point

 Bytecode:
 -----------------------------------------------------------------
 B - byte (1 byte)
 W - word (2 bytes - low byte + high byte)
 M - variable or constant (3-5 bytes):
     0x00 W - signed integer (-32768...+32767)
     0x01 W - variable in W cell (array[constant] is also compiled to this)
     0x02 W1 W2 - array element (W1-begin of array, W2-variables with offset)
 Registers are variables (0x01 0x?? 0xFF) with the addresses:
 0xFF00 (-256) X // register for relative X value
 0xFF01 (-255) Y // register for relative Y value
 0xFF02 (-254) D // register for distance value
 0xFF03 (-253) N // register for object value
 0xFF04 (-252) K // register for additional value
 0xFF05 (-251) R // register for random value
 0xFF06 (-250) T // register for timer value
 0xFF07 (-249) E // register for our energy value
 0xFF08 (-248) M // register for our missiles number
 0xFF09 (-247) I // register for order number of robot
 0xFF0A (-246) A // A-register for read/write
 0xFF0B (-245) B // B-register for read/write
 0xFF0C (-244) C // C-register for read/write
 0xFF0D (-243) P // register for command pointer
 0xFF0E (-242) L // register for the last value
 0xFF0F (-241) S // register for stack length
 0xFF16 (-234) U // register for higher word of timer value
 0xFF1E (-226) H // register for higher word of the last value

 labW - label with address W
 *    - old commands - supported by interpreter only
 -    - free time commands during interpretation
-----------------------------------------------------------------

 0x01 W1 W2        // DEF arr[len]  (W1-offset to array start, W2-len)
 0x02 W1 W2 W3 ... // DEF arr[len]={list}  (W3-number of words)

*0x10 W M1 M2 // IF M1<M2 : labW
*0x11 W M1 M2 // IF M1>M2 : labW
*0x12 W M1 M2 // IF M1<=M2 : labW
*0x13 W M1 M2 // IF M1>=M2 : labW
*0x14 W M1 M2 // IF M1==M2 : labW
*0x15 W M1 M2 // IF M1!=M2 : labW

-0x20 M1 M2 // M1=M2
*0x21 M1 M2 // M1=-M2
*0x22 M1 M2 M3 // M1=M2+M3
*0x23 M1 M2 M3 // M1=M2-M3
*0x24 M1 M2 M3 // M1=M2/M3
*0x25 M1 M2 M3 // M1=M2*M3
*0x26 M1 M2 M3 // M1=M2%M3
*0x27 M1 M2 M3 // M1=M2&M3 - binary AND
*0x28 M1 M2 M3 // M1=M2|M3 - binary OR
*0x29 M1 M2 M3 // M1=M2^M3 - binary XOR
*0x2A M1 M2 // M1=~M2 - binary NOT

*0x30 W // GOTO labW
*0x31 W // CALL labW
-0x33 // RET
 0x34 // STEP
 0x35 // LEFT
 0x36 // RIGHT
 0x37 ... 0x00 // SAY "string and/or &var"
 0x38 M // PRINT var
 0x3A M // ACT var (FRONT=0,RIGHT=1,BACK=2,LEFT=3)
 0x3B   // SPY
 0x3C M // RADAR var
 0x3F 0x00 B // DUMP B (Dump variables in B columns)

 0x40 B ...  // var=expr (B bytes)
-0x41 M1 M2  // IFY var1 var2
-0x42 M1 M2  // IFN var1 var2
-0x43 M      // GOTO var
-0x44 M      // CALL var

*0x51 W ... 0x00 // TEST "wildcard" label
 0x52 ... 0x00   // TEST "wildcard" // result in L register

 0x60 M // SHOT avar // copy 16 registers values to [avar]
 0x61 M1 M2 // SEND var1 var2 // send code var1 to robot var2
 0x62 M // RECV avar // receive code and save it to [avar]
-0x63   // POP // pop value from the stack and store it to register L
 0x64 M1 M2 // PIXEL varx vary // draw a pixel by foreground color
 0x65 M1 M2 // FILL vardx vardy // from last PIXEL with COLOR
 0x66 ... 00 // TEXT "string" // from last PIXEL with COLOR
 0x67 M // PLANE varn // set current plane for drawing (0 - default)
 0x68 M // COLOR varn // set current color
 0x69 M1 M2 // SELECT varx vary // select cell to draw
 0x6A M1 M2 // SET var_plane [var_side] // draw tile to selected sell (default var_side=0)
 0x6B M // GET [var_side] // get identifier of the drawn tile (default var_side=0)
 0x6C ... 00 // ASM "string" // send some string directly to the asm output (RW1P2)

 0x70 M1 M2 // COPYP avar1 avar2 // copy packet [avar2] to [avar1]
 0x71 M1 M2 // SENDP avar var // send packet [avar] to robot var
 0x72 M // RECVP avar // receive packet and save it to [avar]
 0x73   // PUSH // push value from register L to the stack
 0x74 M1 M2 // CLEAR varx vary // draw a pixel by background color
 0x7F M // COMMAND var // high-level command

 0xFF // END - end of bytecode


 Expressions
 -----------

 expr uses var,label,(,),?:,+,-,*,/,%,&,|,^,~,!,&&,||,=,==,>,<,>=,<=,!=,<<,>>

 0x80 // &&  A,B -> A&&B
 0x81 // ||  A,B -> A||B
 0x90 // ==  A,B -> A==B
 0x91 // !=  A,B -> A!=B
 0x92 // >   A,B -> A>B
 0x93 // <   A,B -> A<B
 0x94 // >=  A,B -> A>=B
 0x95 // <=  A,B -> A<=B
 0xA0 // +   A,B -> A+B
 0xA1 // -   A,B -> A-B
 0xB0 // *   A,B -> A*B
 0xB1 // /   A,B -> A/B
 0xB2 // %   A,B -> A%B
 0xC0 // &   A,B -> A&B
 0xC1 // |   A,B -> A|B
 0xC2 // ^   A,B -> A^B
 0xD0 // >>  A,B -> A>>B
 0xD1 // <<  A,B -> A<<B
 0xE0 // -   A -> -A (negative)
 0xE1 // ~   A -> ~A (bit inverse)
 0xE2 // !   A -> !A (logic NOT)
 0xF0 // ?:         A,B,C -> A?B:C
 0xF1 // DUP        A -> A,A
 0xF2 // ROL        A,B -> B,A
 0xF3 // LOAD       A -> mem[A]
 0xF4 // SAVE       A,B -> .  (mem[A]=B)
 0xF5 W // PUSH W   . -> W
 0xF6 // []         A,B -> A[B]


 Debug info
 ----------

 Debug info is added to RW0-file by option -d in RW1C v2.1 or above.
 After code compiler writes zero-terminated word "DEBUG" and list
 of source files in form zero-terminated names. Two zero bytes
 identify end of the list. Then we have list of variables:

 ? bytes - NAME,0
 2 bytes - size of variable in words
 2 bytes - index of variable

 Then we have a number of 5-bytes structures:

 1 byte - index of source file
 2 bytes - number of line in the source file
 2 bytes - address in code

 End of structures is #FF byte.


P.S. Байткод 0x39 затерялся где-то в анналах истории - не могу нигде найти его реализацию и даже описание...

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


12 May 2016 17:44
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23357
Location: Silicon Valley
Reply with quote
Post Re:
Shaos wrote:
Надо компилятор RW1C улучшать - добавить возможность использовать локальные переменные (через ключевое слово LOCAL, а не через задницу) и функции поддержать внутри выражений, причём байткод при этом не изменится - всё будет работать на старых виртуальных машинах...

А можно и без ключевого слова LOCAL обойтись - локальные переменные можно особым образом помечать, например если переменная начинается с подчеркивания, то компилятор с ней работает как с локальной переменной живущей только в пределах своего блока {} - для этого можно наделить команду DEF возможностью динамически аллоцировать массив в месте вызова (тогда надо будет еще завести команду UNDEF чтобы такой динамический массив освобождать) и компилятор будет вставлять DEF на соответствующее количество переменных в начале блока, где появляются локальные переменные.

Еще можно сделать переменные типа беззнаковый байт, добавляя к имени суффикс $ - внутри такие однобайтовые переменные будут представлены как половинки обычных переменных, соответственно надо будет добавить 2 постфиксных спецоператора, которые могут выделять младший байт переменной ' и старший байт переменной " - препроцессор будет их вставлять в выражения вместо вызова соответствующих байтовых переменных

Еще одна мысль - поддержать наряду с сишным for еще и более модный вариант for(var in 1..10), а также for(var in array) где array - объявленный ранее массив (и все это можно сделать на уровне препроцессора)

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


17 Feb 2017 19:58
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23357
Location: Silicon Valley
Reply with quote
с суффиксом $ всё-таки логичнее объявлять строки т.к. сейчас
DEF ARR1[10]="abcd" // ARR1[0]=длина пакета ARR1[1]='a' ARR1[2]='b' и т.д.
DEF ARR2[10]='abcd' // ARR2[0]=длина пакета ARR2[1]='a'|('b'<<8| ARR2[2]='c'|('d'<<8)
то теперь вместо второго варианта можно будет просто писать
DEF ARR$="abcd" // размер массива будет вычисляться автоматически и $ будет означать что инициализирующая последовательность описывает байты, а не слова
в этом случае апострофы вновь будут только для обозначения символов использоваться

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


17 Feb 2017 20:41
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23357
Location: Silicon Valley
Reply with quote
В первую очередь надо поддержать вышепредложенный вариант DEF STRING$="aaa" (даже без квадратных скобок т.к. необходимый размер массива в словах будет вычисляться компилятором).
Во вторую очередь надо реализовать расширение for: for(A in 1..10) (как в аде или руби) и for(A in array) (как в джаваскрипте), причём на уровне препроцессора!
Также хочу количество регистров увеличить до 26, дабы охватить все буквы алфавита, а вот с локальнымм переменными надо подумать...

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


29 May 2018 09:31
Profile WWW
Doomed

Joined: 01 Oct 2007 10:30
Posts: 665
Location: Ukraine
Reply with quote
Вы придумали язык. А зачем? Столько уж кривых языков не придумали только. А Си, Паскаль, Бейсик и конечно Ява (новый язык) рулит.

_________________
Эмулятор OrionEXT:
http://www.orion-ext.narod.ru


29 May 2018 11:35
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23357
Location: Silicon Valley
Reply with quote
Alekcandr wrote:
Вы придумали язык. А зачем? Столько уж кривых языков не придумали только. А Си, Паскаль, Бейсик и конечно Ява (новый язык) рулит.

О - дайте две явы для Intel 8080 пжалста :idea:

А вообще язык я придумал ещё в 1998 (т.е. он моложе этой вашей "новой" явы) и расширил в 2000 - с тех пор и тащу его везде ;)

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


29 May 2018 15:16
Profile WWW
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Shaos wrote:
...для Intel 8080 пжалста :idea:
А вообще язык я придумал ещё в 1998 (т.е. он моложе этой вашей "новой" явы)
и расширил в 2000 - с тех пор и тащу его везде ;)

А насколько эффективный код генерирует твой язык для Intel 8080 ?

_________________
iLavr


30 May 2018 07:53
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 23357
Location: Silicon Valley
Reply with quote
Lavr wrote:
Shaos wrote:
...для Intel 8080 пжалста :idea:
А вообще язык я придумал ещё в 1998 (т.е. он моложе этой вашей "новой" явы)
и расширил в 2000 - с тех пор и тащу его везде ;)

А насколько эффективный код генерирует твой язык для Intel 8080 ?

Ну по любому побыстрее бейсика будет ;)

_________________
https://mastodon.social/@Shaos :dj:
https://www.youtube.com/@Shaos1973


30 May 2018 13:34
Profile WWW
Supreme God
User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия
Reply with quote
Shaos wrote:
Lavr wrote:
А насколько эффективный код генерирует твой язык для Intel 8080 ?
Ну по любому побыстрее бейсика будет ;)

А супротив С ?

_________________
iLavr


30 May 2018 13:52
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 34 posts ]  Go to page 1, 2, 3  Next

Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.