RedPower 2/Программирование
В модификации Red Power 2 существуют программируемые компьютеры. Они используют MineOS v1.2 и язык программирования FORTH.
Основная задача компьютера — это замена ваших редстоун цепей с применением логических элементов. Несмотря на это, компьютер остался собой и сохранил полную функциональность.
Сборка
Компьютер в Red Power 2, состоит из четырех основных деталей-монитор, центральный процессор, дисковод, декодер IO, так же как дополнение существуют объединительная плата, на которую ставится 8K RAM модуль, служащий для расширения памяти компьютера, изначально у компьютера 600 байт памяти. Память напрямую влияет на количество программ, которые вы сможете использовать на компьютере. Части компьютера можно ставить как вплотную, так и раздельно, соединив их плоским кабелем. Важно! Объединительные платы надо ставить непосредственно за центральным процессором.
Немного о декодере IO, это устройство используется для перевода сигналов компьютера в сигналы красного камня, к нему сзади ставится связка проводов, на которую он и подает сигналы.
Запуск
Что бы первый раз запустить компьютер, нам потребуется дискета с операционной системой — Загрузочный диск FORTH, ее необходимо вставить в дисковод, нажатием ПКМ. Затем, нажав ПКМ на центральный процессор, нажать на кнопку Start. Теперь нажмем ПКМ на монитор и, немного подождав, увидим надпись вида
"MineOS V1.2 Initialized 600 bytes free."
Всё, мы запустили компьютер и теперь можем приступить к его программированию.
Программирование
Элементарная часть
Основная идея программирования на языке FORTH — это интерпретация новому слову, какой-то последовательности уже известных команд.
Узнать, какие команды сейчас доступны для использования можно, введя "WORDS
" без кавычек. Завершение ввода любой команды производится нажатием ↵ Enter.
Определение нового слова выполнятся вводом ": *слово*
", затем вводятся команды, примечание после ввода на этой команды каждая последующая строка будет начинаться так "compile:
", и завершается определение вводом ";
".
Пример определения слова Hi при вводе которого на экран будет выводится "Hello world"
>: Hi
compile: ." Hello world"
compile: ;
Внимание! compile: вводить не надо, оно автоматически появится у вас на экране, после ввода ": Hi
"
Теперь просто введя Hi на экран выведется "Hello world". В программе ."
— это команда вывода строки, конец которой обозначается вторым символом "
.
Если теперь ввести "WORDS
", то мы увидим, что сразу после только что введенного WORDS идет наша команда Hi, т.е. мы определили новую команду для нашего компьютера и можем теперь ее использовать наравне с остальными.
Создадим еще одну программу.
>: five
compile: 2 3 + .
compile: ;
Теперь, введя five, на экране появится цифра 5. О команде "2 3 + .
", как только наш компьютер встречает ни с чем не связанное число, он помещает его в стек. Встретив "+
", компьютер сложит два значения лежащих на вершине стека, для любого другого знака арифметической операции он сделает тоже самое. Встретив ".
", компьютер выведет на экран число, лежащие в вершине стека.
Если нам больше не будет требоваться какая-либо команда и необходимо ее удалить, надо ввести "FORGET *команда*
", FORGET — стандартная команда, которая удаляет другие команды. Например, введя "FORGET five
", а затем WORDS, мы больше не увидим five в списке команд. Внимание! Будьте осторожны, удаляя команду, вы так же удаляете все команды, в которых она использовалась.
Перейдем к непосредственному взаимодействию с декодером IO.
Когда он устанавливается в мире, ему присваивается ID 3, его можно сменить отверткой. К компьютеру может быть подключено несколько декодеров, чтобы сменить декодер, на который посылается сигнал, необходимо ввести "*ID декодера* IOXADDR !
".
Для взаимодействия с декодером существуют 4 основных команды:
IOX!
— берет из стека значение и посылает на него сигнал. Если ввести
1 IOX!
— будет послан сигнал по белому проводу, т.к. он соответствует значению.
В RedPower 2 определено кодирование цветов по битам (значениям от 0 до 15 в соответствие с цветами), для определения можно пользоваться таблицей:
Col | Bit | Dec | Hex | Цвет |
---|---|---|---|---|
0 | 1 | 0х0001 | Белый / White | |
1 | 2 | 0х0002 | Оранжевый / Orange | |
2 | 4 | 0х0004 | Пурпурный / Magenta | |
3 | 8 | 0х0008 | Светло-синий / Light blue | |
4 | 16 | 0х0010 | Жёлтый / Yellow | |
5 | 32 | 0х0020 | Светло-зелёный / Lime | |
6 | 64 | 0х0040 | Розовый / Pink | |
7 | 128 | 0х0080 | Серый / Grey | |
8 | 256 | 0х0100 | Светло-серый / Light grey | |
9 | 512 | 0х0200 | Голубой / Cyan | |
10 | 1024 | 0х0400 | Фиолетовый / Purple | |
11 | 2048 | 0х0800 | Синий / Blue | |
12 | 4096 | 0х1000 | Коричневый / Brown | |
13 | 8192 | 0х2000 | Зелёный / Green | |
14 | 16384 | 0х4000 | Красный / Red | |
15 | 32768 | 0х8000 | Чёрный / Black |
Здесь Bit — это бит который соответствует проводу и Dec — значение, которое необходимо вводить перед IOX! для активации провода. Для активации сразу нескольких проводов надо ввести сумму значений Dec соответствующих проводов.
IOX@
— помещает в стек значение соответствующее включенным проводам. Если ввести IOX@ .
— на экран будет выведено значение соответствующее включенным проводам.
IOXSET
— берет из стека число и подает сигнал на провода соответствующие этому числу. Если ввести 4 IOXSET
— к текущим сигналам прибавится сигнал на пурпурный провод.
IOXRST
— берет из стека число и убирает сигнал с провода соответствующие этому числу. Если ввести 4 IOXRST
— из текущих сигналов уберется сигнал на пурпурный провод.
Это основные команды взаимодействия. Создадим простейшую команду, которая подаст сигнал на оранжевый провод на 10 тактов.
>: sign1
compile: 2 IOXSET
compile: 10 TICKS
compile: 2 IOXRST
compile: ;
Возможен иной вариант.
>: sign2
compile: 2 IOX!
compile: 10 TICKS
compile: 0 IOX!
compile: ;
Этого достаточно для простого управления различными системами: фермы, двери, лифты...
И последнее, допустим, есть компьютер, в котором мы создали множество команд и хотим их перенести на другой компьютер, для этого можно воспользоваться пустой дискетой, вставив ее в привод и введя команду SAVE" *имя дискеты*"
, затем вытащив дискету, мы увидим, что она теперь называется так же, как мы написали в команде. Вставив ее в другой компьютер и перезагрузив его, мы получим тот же набор команд, какой имели на исходном.
Продвинутый уровень
Кроме команд взаимодействия с декодером есть множество других команд, которые можно использовать для усложнения и усовершенствования программ.
Переменные и константы
Переменную можно определить следующим образом "VARIABLE *имя переменной*
", изначально любая переменная имеет значение 0. Константу можно определить так "*значение* CONSTANT *имя константы*
", если не указать значение, оно возьмется из стека (по факту оно итак сначала помещается в стек а затем присваивается константе). Различие между переменной и константой в том, что значение переменной можно менять, а константы нет.
Для работы с переменной есть две операции @
— помещает в стек значение переменной, используется так "*имя переменной* @ .
" — выведет на экран значение переменной. Вторая это !
— присваивает переменной значение из стека, например "*значение* *имя переменной* !
" — задаст переменной заданное значение.
Массивы и строки
В языке FORTH нет явного способа задания массива, для этого используется создание константы большего размера чем обычно. Командой *размер* ALLOT CONSTANT *название*
создастся массив заданного размера, здесь ALLOT
— команда выделения указанного количества памяти. Чтобы получить нужный элемент массива, мы должны обратиться к памяти по адресу *начало массива*+i * *размер элемента*, i — номер нужного элемента.
Строки идентичны массивам, только каждый элемент — это символ, и строка всегда на один символ короче, чем создавалась, это связано с использованием особого символа — конец строки, он используется автоматически. Для строк определены следующие команды:
TYPE
— выводит строку на экран, используется — *имя строки* TYPE
ACCEPT
— используется для ввода строки, используется — *имя строки* *размер строки* ACCEPT [нажмите ↵ Enter] [Введите строку] [нажмите ↵ Enter]
STRLEN
— возвращает в стек длину строки, используется - *имя строки* STRLEN .
— выведет на экран размер
STRCMP
— сравнивает две строки, вернет в стек 1, если равны, иначе 0, используется *имя первой строки* *имя второй строки* STRCMP .
— выведет 1 или 0
ATOI
— преобразует строку в число со знаком и помещает в стек, используется *имя строки* ATOI
UATOI
— преобразует строку в число без знака и помещает в стек
UITOA
— преобразует число в строку и возвращает адрес строки
MOVE
— копирует одну строку в другую, используется *имя копируемой* *имя строки куда копируем* *размер строк* MOVE
Логические операции
В основном это операции проверки на истинность, все логические операции возвращают TRUE(1) или FALSE(0).
0=
— сравнит значение из стека с 0, если оно 0, вернет в стек TRUE, иначе FALSE
0<>
— сравнит значение из стека с 0, если оно НЕ 0, вернет в стек TRUE, иначе FALSE
0<
— сравнит значение из стека с 0, если оно меньше 0, вернет в стек TRUE, иначе FALSE
<>
— сравнит два значения из стека, если они НЕ равны, вернет в стек TRUE, иначе FALSE
<
— сравнит два значения из стека, если первое меньше, вернет в стек TRUE, иначе FALSE
>
— сравнит два значения из стека, если первое больше, вернет в стек TRUE, иначе FALSE
=<
— сравнит два значения из стека, если первое меньше либо равно второму, вернет в стек TRUE, иначе FALSE
>=
— сравнит два значения из стека, если первое больше либо равно второму, вернет в стек TRUE, иначе FALSE
=
— сравнит два значения из стека, если первое равно второму, вернет в стек TRUE, иначе FALSE
KEY?
— возвращает TRUE, если была нажата клавиша.
Условия
Полезны, когда необходимо выполнить различные действия при разных значениях чего-либо (например переменной). Условие реализуется 2 основными командами и одной не обязательной. Первая команда — это IF
, она берет значение из стека, и если оно TRUE (логическая 1), начинает выполнять команды, при этом возможна дополнительная команда ELSE
, указывающая, что необходимо выполнить, если условие не верно. Общая структура такова
IF (команды, если условие верно) ELSE (команды, если условие не верно) THEN
THEN
— обозначает конец блока IF
. Внимание! ELSE
не обязателен, но THEN
обязателен после каждого IF
.
Циклы
Полезны, когда требуется повторить одни и те же команды несколько раз. В языке FORTH много различных циклов, по этому по порядку:
DO (команды внутри цикла) LOOP
— вытаскивает из стека два значения и работает, прибавляя ко второму по 1, пока числа не будут равны. Используется так *до скольки* *от скольки* DO (команды в цикле) LOOP
, например 5 0 DO ." Hello world" LOOP
— выведет Hello world 5 раз.
Возможны варианты: вместо DO
использовать ?DO
— тогда цикл не запустится, если значения равны, вместо LOOP
использовать *значение* +LOOP
— каждый раз прибавляет к счетчику не 1, а указанное значение.
Существует команда принудительного выхода из цикла LEAVE
.
Существуют 2 команды, что бы узнать значение счетчика цикла. I
— вернет значение текущего счетчика цикла DO
, J
— вернет значение счетчика цикла на уровень выше.
BEGIN
— общая команда для начала 3 разных циклов: UNTIL
, REPEAT
, AGAIN
UNTIL
— выйдет из цикла если логическое значение в стеке TRUE, иначе повторит цикл
REPEAT
— особая конструкция вида BEGIN (команды 1) WHILE (команды 2) REPEAT
, сначала выполняются команды 1, затем, если логическое значение в стеке TRUE, выполняются команды 2 и цикл повторяется, иначе выходит за REPEAT
AGAIN
— создает бесконечный цикл, выйти можно 3 командами EXIT
- выходит из текущей команды, QUIT
— завершение выполнения всех команд, ABORT
— то же, что и QUIT, только с очисткой стека.
Остальные различные команды
Тут приведен перечень команд, которые ни к чему особо не относятся, но могут оказаться полезными.
PAGE
— отчистит экран и поместит курсор в левый верхний угол.
SCROLL
— перемещает содержимое экрана на 1 строку вверх.
AT-XY
— возьмет из стека два значения и поместит туда курсор.
CR
— конец строки и переход на следующую.
HEX
— перейдет в 16-ричную систему счисления.
DECIMAL
— перейдет в 10-ричную систему счисления.
TIMES
— возьмет из стека значение и повторит следующую за собой команду это число раз.
CELL
— вернет размер ячейки памяти в байтах.
NEGATE
— возьмет из стека значение и поменяет ему знак.
MAX
или MIN
— возьмут из стека два значения и вернет наибольшее\наименьшее соответственно.