nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 28 Mar 2024 16:33



Reply to topic  [ 8 posts ] 
RISC процессор с интуитивно понятным машинным кодом 
Author Message
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
Давнo волновала мысль о реализации процессора с интуитивно прозрачной системой команд.
Так, x80 задумывался мною как нечто среднее между z80 и i8086. Но CISC довольно сложна в освоении реализации и там я наткнулся на множество подводных камней, хотя первые шаги и сделал.

Решил наконец перешагнуть через некоторые свои принципы и заняться RISC всерьёз.
А именно, сделать набросок простого (не простейшего) процессора, но с оригинальной системой команд и интуитивно ясным байт-кодом, чтобы не нужно было зубрить таблицу системы команд.
И я нашёл достаточно оригинальный вариант…

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

Code:
Bytes|Assm | Краткое описание
----- ----- ------------------
00    HALT - Куда без неё?
01…99 1…99 - Шестнадцатиричные цифры используются как десятичные
0A…0F ALU  - 0xA:Add; 0xB:suB; 0xC:Conjunction (AND); 0xD:Disjunction (OR); 0xE:Eor; 0xF:Flags (CMP)
A1…A9 A1…9 - Выбор одного из девяти регистров A
B1…B9 B1…9 - Выбор одного из девяти регистров B
C1…C9 C1…9 - Выбор одного из девяти регистров C
AA…CC R,T  - Выбор пары приёмник-источник (Receiver,Translator pair)
AD    ADDR - Фиксация значений приёмника-транслятора в регистре адреса
BE    BE   - Чтение из буфера памяти (Buffer Extract)
BF    BF   - Запись в буфер памяти (Buffer Flush)
DA…DF DA…F - Skip 1 Instruction by: Amount; Bigger; Carry; Dis-Carry; Equal; False
EB    EB   - Execute Buffer (Jump to Buffer Address)

С помощью ПЗУ объёмом в 256 байтов с асинхронным доступом можно легко прошить всю таблицу дешифратора команд, в которую также входят 99 ячеек перевода двоично-десятичных представлений кодов.

Сначала схему я строил в Atanua, но потом перешёл в Logisim, так как он удобнее в работе с шинами. За неделю мне удалось набросать более-менее приличную схему, если сравнивать с предыдущим безобразием из путаницы проводников и логики по всему экрану. Сейчас выглядит схема более приличнее и многое расположено гораздо ровнее, чем было в первых вариантах.
А главное - это работает.
Самым сложным моментом было разработка узла чтения/записи памяти, так как первый вариант был аналогичным Гарвадскому. Теперь набор вентилей и сдвиговый регистр выполняют нормальный Принстонский функционал, на отладку которого ушло несколько ночей. Думаю, опыт пригодится в моём x80, когда руки дойдут до него.

Как это работает…
Можно из схемы заметить, что значительную часть составляет регистровый файл.
Конечно, можно было использовать готовый элемент памяти, но схему я разрабатывал так, чтобы можно было на ТТЛ всё собрать при возможности.
В Logisim все дешифраторы выдают активную логическую единицу, тогда как подавляющее большинство физических микросхем активным используют логический ноль.

Всего данный процессор способен выполнить пока 140 инструкций.
И на данный момент АЛУ имеет только функцию сумматора под кодом операции 0A, так как пока нет нужды во всех операциях. Хотя, как и в x80, операции будут те же…
(0A:Add, 0B:suB, 0C:Conjunction/AND, 0D:Disjunction/OR, 0E:Eor, 0F:diFference/CMP)

Например:
Code:
0000 BA ; Выбор пары B,A
0001 B9 ; Выбор регистра B9
0002 64 ; Загрузить десятичное 64 (0x40) в регистр B9
0003 CB ; Выбор пары C,B
0004 C8 ; Выбор регистра C8
0005 30 ; Загрузить десятичное 30 (0x1E) в регистр C8
0006 AD ; Поместить в указатель адреса значения C8 и B9: Addr = (C8 << 8) | B9
0007 A1 ; Выбор регистра A1
0008 AB ; Выбор пары AB
0009 BE ; Прочитать память и сохранить данные: A1 = [Addr] или A1 = [0x1E40]
000A 00 ; Останов
Если вдуматься, то реализация процессора получилась почти полной по Тьюрингу.
Реализовать стек программно теоретически возможно уже сейчас.

Code:
0000 A9 ;     A9  ; Чтобы организовать цикл, нужно настроить указатель
0001 B9 ;     B9  ; Выбираем регистры A9 B9
0002 AA ;     A,A ; Эти аргументы помогут очистить регистр A9
0003 0E ; EOR     ; (EOR A9,A9) посредством Исключающего ИЛИ
0004 BA ;     B,A ; Теперь загрузим адрес единственной метки
0005 16 ;      16 ; Сейчас B9,A9 имеют значения 0x10,0x00
0006 AB ;     A,B ; Формируем корректный адрес: 0x00,0x10
0007 AD ; ADDRESS ; Загружаем в указатель буфера 0x0010 из A9,B9
0008 A8 ;     A8  ; Теперь настроим регистры для циклического счёта
0009 B8 ;     B8  ; A8 будет счётчиком, а B8 будет хранить предел
000A AA ;     A,A ; Очистим будущий счётчик
000B 0E ; EOR     ; (EOR A8,A8) традиционным способом
000C BA ;     B,A ; Чтобы загрузить B8, нужно выбрать аргументы
000D 99 ;      99 ; (MOV B8,99) Теперь B8 == 0x63
000E B1 ;     B1  ; Здесь будет храниться шаг инкремента
000F 01 ;      1  ; (MOV B1,1)
0010 ;;;;         ; Этот адрес мы указали в начале программы - прошло 32 такта
0010 AB ;     A,B ; Указываем порядок аргументов
0011 A8 ;     A8  ; Чтобы обеспечить инкремент
0012 B1 ;     B1  ; как A8 += B1
0013 0A ; ADD     ; (ADD A8,B1)
0014 B8 ;     B8  ; Регистр предела
0015 0F ; CMP     ; (CMP A8,B8) Операция сравнения
0016 DC ; DC      ; (Do if Carry) Операция проверки флага переноса
0017 EB ;  EB     ; Если переноса нет, эта команда (Execute Buffer) будет пропущена - 16 тактов + 2
0018 00 ; HLT     ; Останов - всегда 2 такта
В этой программе на каждую инструкцию уходит по 2 такта (4 полупериода ручным кликом), за исключением условной DC, которая требует 4 такта для холостого инкремента указателя инструкций при завершении цикла. Тем самым, на всю программу потребуется 2*16+99*(2*8)+2+2


Attachments:
File comment: Текущий вариант процессора с программой Hello World!
cpu_risc.png
cpu_risc.png [ 93.7 KiB | Viewed 10940 times ]
logisim-risc_cpu.zip [13.21 KiB]
Downloaded 415 times


Last edited by Paguo-86PK on 25 May 2020 09:27, edited 3 times in total.

14 Mar 2019 04:10
Profile WWW
Doomed

Joined: 01 Oct 2007 10:30
Posts: 665
Location: Ukraine
Reply with quote
Ничего не понял (надо думать). Это вам надо R800 (MSX) курить? на базе Z80(Z280).

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


14 Mar 2019 06:34
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22412
Location: Silicon Valley
Reply with quote
Логисим не глючит от такой большой схемы?

_________________
:dj: https://mastodon.social/@Shaos


14 Mar 2019 13:32
Profile WWW
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
Первопoст обновил…
Добавил в схему все 6 операций АЛУ, флаговый регистр и инструкции условного исполнения.
Теперь есть операция загрузки указателя инструкций.

Очень любопытно, смогу ли я написать что-нибудь практическое?
Типа, Тетриса или простейшую BIOS-заставку…
Shaos wrote:
Логисим не глючит от такой большой схемы?
Когдa пытался сделать большой экран 320x192, симуляция часто подвисала и приходилось LogiSim закрывать через диспетчер задач.
Если развёртку делать последовательно по всем панелям, то период их обновления очень велик.
Потому я на каждую панель выделил отдельное ОЗУ и устал разводить шины плексеров.
Отдельное ПЗУ отвечает за линейный доступ к ячейкам всего дисплея, чтобы все 7680 ячеек не имели всяких фокусов с дешифрацией при доступе к ним.

Но весь труд себя не оправдал - симуляция через какое-то время зависает…


Attachments:
File comment: Большой экран
BigScreen.png
BigScreen.png [ 138 KiB | Viewed 10978 times ]
14 Mar 2019 16:55
Profile WWW
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
Рeшил набросать схему контекстного файла - Logisim сильно тормозить стал.
Да и тактовый вход забыл вывести, как потом заметил…

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


Attachments:
File comment: Модуль файла контекста
Context.gif
Context.gif [ 76.27 KiB | Viewed 10871 times ]
File comment: Регистровый файл:
Порт #1 - 8-битовый операнд R(eceiver) и аккумулятор
Порт #2 - 8-битовый операнд T(ranslator)
Порт #3 - 2 8-битовых регистра (в том числе IP/BX/CX/DX/SP/BP/SI/DI)
Порт #4 - 2 8-битовых регистра страницы памяти

x80_context.png
x80_context.png [ 424.55 KiB | Viewed 10872 times ]
21 Mar 2019 15:35
Profile WWW
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
Всe эти дни я усердно скрипел мозгами и дорабатывал схему процессора собственной RISC-архитектуры. Полностью перерисовывал её несколько раз и она в малом масштабе выглядит достаточно симпатично. Правда, из-за не совсем удачного расположения блоков АЛУ и Выборки довольно много проводов и шин опоясывает всю схемы. Потому, можно добиться в перспективе более аккуратного вида.

Упростил процессор до предела в рамках выбранной концепции, упразднив некоторые инструкции и упростив доступ к памяти. Появилась возможность расширения системы команд программными процедурами по адресам E000…FF00.
Теперь основных групп команд сократилось до девяти, включая группу АЛУ. Тем самым, если операции АЛУ вынести напрямую к дешифратору, то потребуется всего один типа ИД3…

Вся схема выполнена в строгом синхронном стиле и легко должна ровно лечь в Verilog и FPGA.

Регистровый файл расширен с трёх до четырёх групп регистров общего назначения.
Четвёртая D-группа представляется внешними устройствами - Devices, что позволяет обращаться к устройствам типа клавиатура или джойстик непосредственно и в скором порядке, как кэш-периферия первого уровня с мгновенным доступом. Более медленные устройства требуется проецировать в адресное пространство памяти.

Тем самым, процессор теоретически пригоден для построения любого автомата, типа «Ну, Погоди!», «Тетриса» или «Лунохода».

Конечно, демонстрационный код довольно прост и скуден. Но он демонстрирует базовые возможности процессора и взаимодействие с периферией.
В архиве имеется также HTML-файл дизассемблера, который поможет поверхностно вникнуть в принципы кодирования команд.
Code:
Система команд процессорного устройства разрабатывалась максимально прозрачной
для понимания на уровне машинного кода в своём шестнадцатеричном представлении
как есть визуальным сочетанием своих нибблов в форме элементарных аббревиатур.
Кодирование алгоритма малой степени сложности доступно пользователю с базовыми
навыками редактирования таблиц дампа и не представляет особой сложности в силу
максимально осмысленного кодирования всех инструкций в шестнадцатеричном виде.

------------------------------------------------------------------------------
|Код команд / диапазоны|Группа    |Описания, замечания, комментарий
-----------------------|----------|-------------------------------------------
00                     |HLT       |Прекращение счёта указателем команд IP
01-99                  |ADD Ri,BCD|Двоично-десятичное накопление в регистр
0A-9F                  |ALU Ri,Tk |Операция АЛУ с комбинацией аргументов
A0-A9 B0-B9 C0-C9 D0-D9|REG Rn    |Установка индекса активного регистра группы
AA-AD BA-BD CA-CD DA-DD|ARG Ri,Tj |Выбор комбинации аргументов операциям АЛУ
AE    BE    CE    DE   |EXT Ri    |Экстракция данных из внешнего ОЗУ в регистр
AF    BF    CF    DF   |FIX Ri    |Фиксация значения регистра во внешнее ОЗУ
E0-E7                  |EX0-7     |Переход на адрес 0xE000-0xE700
E8-EF                  |Ecnd      |Выполнение следующей команды по условию
F0                     |FIN       |Завершение с переходом на адрес Базы:Счёта
F1-FF                  |FN1-15    |Переход на адрес 0xF000-0xFF00
------------------------------------------------------------------------------
(n - устанавливаемый индекс, указанный битами команды)
(i или j - индекс, установленный раннее)
(k - индекс регистра временно берётся из старшего ниббла кода команды)

Группы регистров A0-A9, B0-B9 и C0-C9 составляют внутренний регистровый файл с
безусловным доступом к ним на программном уровне. Регистры B0-B9 хранят "Базу"
для обращения к памяти блоком в 256 байт, а регистры C0-C9 - счёт байта блока.
Инструкция с кодом F0 помещает текущий адрес указателя инструкций из IP в B0 и
C0, а значения из Bi и Cj помещает в IP, производя переход на адрес Bi:Cj. Тем
самым, можно обращаться к коду подпрограмм и знать адрес возврата через B0:C0.

Группу регистров D0-D9 составляют внешние Device-устройства с непосредственным
использованием в качестве операндов. Не рекомендуется активно использовать эту
группу в любых вычислительных действиях, так как нет гарантии работы программ.
Тем самым, как любитель Hex-кода, разработал вполне работоспособную архитектуру, которая не требует даже ассемблера и позволяет в голом дампе набивать машинный код, визуально прозрачный к пониманию.

Есть соблазн упразднить ПЗУ разметки карты команд и заменить его на комбинаторику. Правда, не уверен, оправдает ли это себя…

P.S.: Пожалуй, это - самый удачный из всех моих проектов данного класса.


Attachments:
File comment: Снимок схемы для ознакомления
x80_RISC.png
x80_RISC.png [ 166.82 KiB | Viewed 9618 times ]
File comment: LogiSim-схема и HTML-дизассемблер
x80_RISC_20200525.zip [25.34 KiB]
Downloaded 353 times
25 May 2020 09:25
Profile WWW
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
Пo мере своих возможностей, перерабатываю схему процессора.
Теперь она более чётче разбита на отдельные блоки.
Если пытаться собирать вариант схемы с буферами в регистровом файле, потребуется ≈250 корпусов.
Если же рассматривать вариант с мультиплексорами в регистровом файле, потребуется ≈110 корпусов.
Если, однако, использовать две штуки К1533ИР39, то число микросхем сократится до ≈30 корпусов…

Если ориентироваться на Gigatron, Pico-8 или MegaProcessor, то получилась простая и открытая архитектура с байт-кодом, который можно без ассемблера кодировать подобными переключателями, если их добыть 512 штук и собрать в нормальный электромеханический дамп на 256 байт…

Набросок графика работы машинных циклов

Перевёл в Verilog и попытался синтезировать в Quartus.

В данный момент занялся эмулятором, чтобы было удобнее писать и отлаживать код.
Пока эмулятор выполнен в духе «очень дёшево и крайне сердито», но работает…

P.S.: Никакой отладочной платы не имею и приходится всё программно симулировать…


Attachments:
File comment: Крайне спартанский набросок HTML-эмулятора
И Verilog-модель архитектуры

KISK_emu.zip [7.31 KiB]
Downloaded 359 times
File comment: Разрабатываемая схема с комбинаторным декодером команд и с регистровым файлом на мультиплексорах
KISC_cpu.png
KISC_cpu.png [ 148.52 KiB | Viewed 9159 times ]
File comment: Исходные файлы симуляции
KISK_cpu - стабильный вариант с ПЗУ декодера команд и с буферным регистровым файлом
KISK_mux - новый вариант с комбинаторным декодером команд и с регистровым файлом на мультиплексорах

KISC_cpu.zip [50.24 KiB]
Downloaded 351 times
17 Jul 2020 07:31
Profile WWW
Maniac
User avatar

Joined: 12 Apr 2011 20:43
Posts: 267
Location: Tashkent
Reply with quote
K моему великому огорчению, хотя я и брался сделать RISC, но получился CISC.
С одной стороны, он действительно за 1 такт выполняет 1 операцию. Но большинство операций не выполняет каких-либо вычислительных действий и просто изменяют архитектурное состояние.

Если в i8080/z80 команда АЛУ «ADC A,B» сама выбирает регистр B в качестве второго операнда, то у меня аналогичное действие производится в три инструкции:
Code:
1234 A1      |REG A1    ; Активируем регистр A1 в группе A₀…₉
1235    AB   |ARG A,B   ; Выбираем группу A₀…₉ за аккумуляторы, а группу B₀…₉ вторым операндом
1236       3E|EOR A1,B3 ; Здесь A1 выбран в REG и указан ARG, а B3 выбирается по старшей тетраде
1237       4E|EOR A1,B4 ; Здесь A1 выбран, а индексы B₀…₉ выбирается старшей тетрадью кода команды
1238    AC   |ARG A,C   ; Выбираем группу A₀…₉ за аккумуляторы, а группу C₀…₉ вторым операндом
1239       5E|EOR A1,C5 ; Здесь A1 выбран, а индексы C₀…₉ выбирается старшей тетрадью кода команды
123A A2      |REG A2    ; Активируем регистр A2 в группе A₀…₉
123B       6E|EOR A2,C6 ; Теперь приёмником результата стал регистр A2
123C    87 ++|BCD 87    ; BCD - это Byte-Code-Data: Префикс для расширения действия команды
123D    ++ 6E|EOR A2,C6+BC8+7 ; Из-за префикса данные берутся не из C₆, а из ОЗУ по вектору [B₈C₈+C₆+7]
Здесь действительно на одну инструкцию затрачивается 1 байт и 1 такт, но эффективности заметно меньше и код слишком жидкий.
Если же код представить более плотно и всегда заканчивать строку именно эффективной инструкцией, получится примерно следующее:
Code:
1234 A1 AB 3E|EOR A1,B3
1237       4E|EOR A1,B4
1238    AC 5E|EOR A1,C5
123A A2    6E|EOR A2,C6
123C    87 6E|EOR A2,C6+BC8+7
Откуда и получается, что от лёгкой MISC/RISC технологии мало чего осталось и проявляется вновь CISC с разной длиной инструкций.
(Сейчас я работаю над схемой в Logisim/Verilog, которая читает слово на все 4 байта и разбирает его по столбикам, как я специально и указал. Тем самым, за 1 такт обрабатывается ровно одна инструкция из 1…4 байтов. Сложно и требует 4 дешифратора команд, но это - работает.)

Естественно, ссылку на Verilog-модель не дам пока, так как она работает крайне медленно, используя до 8 машинных циклов и до 24 тактов на команду!
Вот графики:
Attachment:
File comment: Verilog модель процессора в действии
cpu_graph.png
cpu_graph.png [ 41.57 KiB | Viewed 7658 times ]


Эмулятор
Однако, предлагаю Вашему вниманию эмулятор, который разрабатываю вторую неделю и добился более-менее стабильного результата.
Attachment:
File comment: Эмулятор моего RISC-процессора с понятным WYSIWYG-кодом
Emulator.zip [1.34 KiB]
Downloaded 270 times

Эмулятор написан для процессоров i8080/z80 и запуститься должен практически на всех машинах:
  • 3700…37C6: Оболочка («РАДИО-86РК¹» / «СПЕЦИАЛИСТ²» / «ОРИОН-128³»)
  • 3838…3863: Сам псевдо-код моего процессора для эмулятора
  • 3870…38FF: Поддержка совместимости между разными ПК (¹-²-³ и «ZX-Spectrum» 48Kb) для печати символа и ввода с клавиатуры
  • 3900…3A99: Собственно, код самой эмуляции (поддерживаются практически все инструкции)
  • 3ADA…3C7F: Дизассемблер (декодирует практически все команды)
  • 3C80…3CFF: Заглушка портов УВВ (вывод сообщений о попытках доступа к портам)
Оболочка в первую очередь разрабатывалась под РАДИО-86РК, где и отлаживалось всё. Гарантировать не буду, но «Специалист» и «Орион» тоже должны нормально работать под её управлением.

С «ZX-Spectrum» всё несколько сложнее.
В его области ПЗУ в пространстве 386E…3CFF имеются резервные ячейки с кодом FF. Именно поэтому я весь код эмулятора/дизассемблера (3900…3C7F) расположил именно так (чтобы включив ZX «Ленинград-48» физически, наряду с Бейсиком сразу иметь свой эмулятор без возни с загрузкой)…
В общем, можно обойтись лишь эмулятором (3900…3A99).
Но, так как «РАДИО-86РК» имеет регион непосредственно отображаемой текстом памяти, крайне удобно было отлаживать дизассемблер, так как он напрямую всё пишет в экранную память без всяких подпрограмм.
В случае же с ПК «Специалист», «Орион» или «ZX-Spectrum» требуется просто после вызова дизассемблера напечатать строку с адреса 0x76D0.
(Как инструментальная ЭВМ в комфортных условиях XXI века именно эмулятор «РАДИО-86РК» предоставляет наибольшие удобства.)

Естественно, бо́льшего от данного эмулятора ожидать нечего: Он просто исполняет код.
Так как хоть для каких-то эффектов (звука/графики) требуется ещё наработать виртуальную периферию…

Периферия / УВВ
Первоначальный эскиз процессора в Logisim разрабатывался как прикол, где командой «MOV D0,D1» можно было данные из порта D₁ напрямую отправить в порт D₀ - из клавиатуры на терминал (эхо).
Однако, служившую для этого инструкцию «ARG D,D» с машинным кодом DD₁₆ я на днях исключил как вредную. И теперь 0xDD работает как отдельная инструкция «DBG» для отладки: Просто как «CALL 0xDD00»…

В добавок, искусственно внеслись новые ограничения, где нельзя регистры УВВ D₀…₉ использовать в АЛУ-операциях - только «MOV».
Из-за чего вместо «ADD»/«SUB»/«AND»/«OR»/«XOR» образовались резервные «EXA»/«EXB»/«EXC»/«EXD»/«EXE», логику работы которых ещё предстоит придумать (допустим, «SHR» или даже «MUL»).
Если раньше можно было кодировать так, используя порт УВВ в качестве смещения в адресации ячейки:
Code:
1234 A1 AD 23 4E|EOR A1,[BC2+3+D4]
То сейчас всё намного строже и формально так делать нельзя, так как это будет работать как:
Code:
1234 A5 AD 87 0E|EOR A5,BC8+7
1238       87 1E|EOR A5,BC8+7+1+ ++D9
123A       87 2E|EOR A5,BC8+7+ ++D9
123C       87 3E|EOR A5,BC8+7+ D9++
123E       87 4E|EOR A5,BC8+7-1+ D9++
1240       87 5E|EOR A5,BC8+7-2+ --D9
1242       87 6E|EOR A5,BC8+7-1+ --D9
1244       87 7E|EOR A5,BC8+7+ --D9
1246       87 8E|EOR A5,BC8+7+ D9--
1248       87 9E|EOR A5,BC8+7+D9
Довольно сложно и не стабильно (концептуально), хотя в эмуляторе - работает.

Карта периферии будет примерно такой:
Code:
switch(D9) { // D₉ - Селектор страницы УВВ
    case 0x53:      // D0…D3 - i8253
    case 0x55:      // D0…D3 - i8255
    case 0x57:      // D0…D8 - i8257
    case 0x75:      // D0…D1 - i8275
    ... ... ...
}

P.S.: Многое ещё предстоит придумывать…
Так как саму мечту детства (придумать свой процессор) со скрипом, но только начал практически нарабатывать.
А вот вторую мечту детства (придумать свой компьютер на своём процессоре) ещё толком в эскизах не имею…


26 Feb 2021 15:12
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 8 posts ] 

Who is online

Users browsing this forum: No registered users and 24 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.