Интегральная схема IC10

# Текст после # будет игнорироваться до конца строки. # Количество пробелов между аргументами не важно, но новые строки начинают новую команду.

## **Регистры**

IC10 содержит 16 регистров, пронумерованных r0-r15. Думайте об этом как о переменных в других языках программирования. Фактически, вы можете назвать их с помощью команды alias (см. ниже).

Чтобы установить регистр напрямую (например, r0=2), используйте команду ***MOVE*** . Чтобы прочитать значение с устройства, используйте **l** (загрузить). Чтобы записать значение обратно на устройство, используйте **s** (set). Обратите внимание, что, как и в большинстве машинных языков, то куда будем записывать идет первым, поэтому инструкции всегда выглядят так: источник назначения действия.

Вот несколько примеров установки регистра, чтения значения с устройства и записи значения на устройство:

`move r0 10`

Устанавливает регистр r0 в значение 10

`move r0 r1`

Копирует значение регистра r1 в регистр r0.

`l r0 d0 Temperature`

Считывает параметр температуры с устройства d0 и помещает значение в регистр r0. Примечание: не все устройства имеют параметр Температура, проверьте игровую wiki.

Чтобы установить конкретное значение устройства (например, «Вкл»), вы можете записать это значение.

`s d0 On r0`

Записывает значение из регистра **r0** в параметр **On** устройства **d0** . В этом примере устройство будет включено, если вентиль регистра r0 равен 1, в противном случае (регистр r0 равен 0) он будет выключен. Смотри раздел Device Variables .

Рекомендуется использовать метки (например: *someVariable* ) вместо прямой ссылки на регистр. См. **псевдоним** в разделе Инструкции .

Есть еще два регистра. Один называется **ra** (обратный адрес), а другой — **sp** (указатель стека). ra используется некоторыми инструкциями перехода и ветвления (оканчивающимися на **-al )** , чтобы запомнить, к какой строке сценария следует вернуться. **sp** отслеживает следующий индекс в стеке (памяти, в которой может храниться до 512 значений), который будет помещен (записан) или извлечен (прочтен) из него. Ни **ra** , ни **sp** не защищены, их значения могут быть изменены инструкциями, как и любой другой регистр.

## Порты устройств

Микросхемы могут взаимодействовать с 6 другими устройствами через d0 - d5, а также с устройством, к которому они подключены, через db. Чтобы изменить или настроить устройство, используйте отвертку и отрегулируйте устройство в корпусе IC10. Вы можете прочитать или установить любые свойства устройства, поэтому можно делать такие вещи, как чтение давления или содержания кислорода в комнате на том же порту устройства.

Инструкции **l** (загрузить) или **s** (установить) вы должны прочитать или установить эти значения на вашем устройстве. Примеры:

`l r0 d0 Temperature`# Считывает **температуру** с датчика атмосферы на порту устройства **d0** в регистр **r0** .

`s d1 Setting r0` # Записываем значение регистра **r0** на устройство на порт **d1** в переменную **Setting** .

## Метки

Метки используются для облегчения перехода между строками в сценарии. Метка будет иметь числовое значение, совпадающее с номером строки. Несмотря на то, что можно использовать значение меток для вычислений, это плохая идея, поскольку любые изменения в коде могут привести к изменению номеров строк меток.

`main:`# определить метку перехода с меткой **main**

`j main` # перейти на метку `main:`

## Константы

Вместо использования регистра для хранения фиксированного значения можно создать константу. Использование этого имени будет ссылаться на назначенное значение. С помощью Констант вы можете сохранять места регистров.

`define pi 3.14159`# определяет константу с именем **pi** и устанавливает ее значение равным 3,14159

Вы можете использовать эти константы, как и любые другие переменные (см. псевдоним в разделе Инструкции ). Пример:

`move r0 pi`# установить значение регистра **r0** равным значению константы с именем **pi** .

## Косвенная ссылка

Это способ доступа к регистру с использованием другого регистра в качестве указателя. Добавление дополнительного r перед регистром включает это поведение. Значение, хранящееся в регистре, используемом в качестве указателя, должно быть от 0 до 15, тогда оно будет указывать на регистр от r0 до r15, более высокие или более низкие значения вызовут ошибку.

`move r0 5 #`сохраняет значение 5 в r0

`move rr0 10 #`теперь то же самое, что и `move r5 10` поскольку r0 имеет значение 5, rr0 указывает на регистр r5

Дополнительные r могут быть добавлены для косвенной ссылки несколько раз подряд.

`move r1 2`

`move r2 3`

`move rrr1 #4` теперь то же самое, что и `move r3 4`поскольку r1 указывает на r2, который указывает на r3

Это также работает с устройствами ,

`move r0 # 2` хранящими значение 2 в r0

`s dr0 On 1`, теперь такое же, как `s d2 On 1`, r0 имеет значение 2, поэтому dr0 указывает на d2.

## Советы по отладке

Значение, хранящееся в регистре или переменной, можно легко отобразить, записав его в параметр Setting Сокет. Это не имеет побочных эффектов. Чтобы увидеть значение, просто встаньте рядом с Сокетом и посмотрите прямо на корпус.

`s db Setting r0`. # устанавливает/записывает значение регистра **r0** в параметр **Setting** ( **db** )

Чтобы проверить, выполняется ли определенный блок кода, используйте описанный выше прием, но со случайным числом, которое вы выберете.

В этом примере на корпусе микросхемы будет отображаться число 137.

`s db Setting 137`# устанавливает/записывает число 137 в параметр **Setting** Socet( **db** )

Всегда используйте уникальные имена для меток. Когда метка названа в честь ключевого слова MIPS, такого как «Температура:» или «Настройка:», исходное значение ключевого слова перезаписывается, поэтому, когда инструкция пытается его использовать, возникает ошибка.

Картридж конфигурации, установленный на планшете , можно использовать для просмотра всех доступных значений и параметров конфигурации для всех устройств, на которых вы работаете.

## Изучение языка

с ним может быть сложно начать работу. Итак, вот список инструкций, полезных для новичков. Их можно использовать для написания множества различных сценариев.

Общий:

* alias (псевдоним) (упростите чтение сценария, назначив имя регистру или устройству, например: `alias r0 Temperature r15`)
* метка: (где «метка» может быть заменена практически любым словом, инструкции перехода и ветвления будут идти к ним, например: `start:`)
* `yield` (пауза на 1 тик и затем возобновление, если скрипт не используется, скрипт автоматически сделает паузу на 1 тик после 128 строк)

Прыжки:

* `j someLabelName`# перейти на строку с **someLabelName**

* `jal someLabelName`# сохраняет номер следующей строки в регистре ra (адрес возврата) и затем переходит к **someLabelName** )
* `j ra`# перейти к регистру ra (обратный адрес)

Ветвление (переход, если):

```
beq (branch if equal) (ветвь, если равно)
bne (branch if not-equal) (ветвь, если не равно)
bgt (branch if greater than) (ветвь, если больше)
blt (branch if greater than) (ветвь, если меньше)
К каждому из них (пример: beqal) можно добавить суффикс -al, чтобы сохранить номер следующей строки в реестр "обратный адрес"

```

Взаимодействие с устройствами:

```
l (load) (загрузка)
lb (load batch) (загрузка партии, требуется одно из следующих действий: Среднее/Сумма/Минимум/Максимум)
ls (load slot) (загрузочный слот)
s (set) (сохранение)
sb (set batch) (сохранение партии)

```

Логика и математика:

```
seqz (общий NOT-gate: превращает 0 в 1, а все остальные значения в 0)
move присвоение
add (сложение)
sub (вычитание)
mul (умножение)
div (деление)

```

Общие переменные устройства:

```
On - Включен (1 включен, 0 выключен)
Open - Открыт (1 открыт, 0 закрыт)
Setting - Настройка (значение зависит от устройства, например: светодиодный дисплей (консоль) покажет это значение)
Activate - Активировать (1 обычно означает, что работает, пример: Датчик дневного света равен 1, когда на него светит солнце)
Temperature - Температура (в градусах Кельвина, Цельсия + 273,15)
Pressure - Давление (в кПа)

```

Примечания:

-Все инструкции и переменные можно увидеть в игре в окне редактора MIPS, нажав кнопки «f», «x» и «s(x)» в правом верхнем углу.

- Stationpedia — лучший источник информации о том, какие переменные доступны для каждого устройства.

- Большинство скриптов представляют собой циклы, они заканчиваются инструкцией перехода, которая ведет обратно к началу. В противном случае они просто запустятся один раз, а затем остановятся.

Два практических сценария:

Автоматический ночной свет: загрузка «Активировать» с датчика дневного света, переворачивание значения с помощью NOT-gate, сохранение значения в переменной "On"«Вкл» одного или нескольких источников света.

Автоматический настенный охладитель: Считайте «Температуру» с газового датчика. Ветвь, если значение больше X, включить кулер. Ветвь, если значение меньше Y, выключите кулер. (Для настенных охладителей требуется минимальное давление 12,5 кПа в присоединяемой трубе)

# инструкции

alias псевдоним
alias str r? d? # метки регистрируют или ссылаются на устройство с именем. Когда псевдоним применяется к устройству, это повлияет на то, что отображается на винтах в основании Сокета
`alias vTemperature r0`

`alias dAutoHydro1 d0`

move (присвоение) ds # сохраняет значение s в d
`move r0 42 # сохраняет значение 42 r0`

l (load) lr? d? параметр
Читает с устройства (d?) и сохраняет значение в регистре (r?)

`l r0 d0 Setting`

Чтение с устройства на d0 в регистр r0

`l r1 d5 Pressure` Считать давление с датчика

Это также работает с псевдонимами. Например:

`alias Sensor d0`

`l r0 Sensor Temperature`

ls (чтение слота)
ls r? d? параметр slotNum
Читает из слота (slotNum) устройства (d?) и сохраняет значение в регистре (r?)

`ls r0 d0 2 Occupied`

Чтение из второго слота устройства на d0, сохранение 1 в r0, если оно занято, иначе 0.

А вот код для считывания заряда AIMeE:

`alias robot d0`

`alias charge r0`

`ls charge robot 0 Charge`

s (set) sd? параметр r?
Записывает настройку на устройство.

`s d0 Setting r0`

add добавлять
dst # вычисляет s + t и сохраняет результат в d
`add r0 r1 1 # add 1 to r1 and store the result as r0`

`add r0 r0 1 # increment r0 by one`

sub dst # вычисляет s - t и сохраняет результат в d
mul (умножение) dst # вычисляет s\*t и сохраняет результат в d
div (деление) dst # вычисляет s/t и сохраняет результат в d
mod d s t вычисляет s mod t и сохраняет результат в d. Обратите внимание на это не ведет себя как оператор % - результатом будет положительный, даже если любой из операндов отрицательный
slt dst # сохраняет 1 в d, если s < t, 0 в противном случае
sqrt ds # вычисляет sqrt(s) и сохраняет результат в d
round ds # находит округленное значение s и сохраняет результат в d
trunc ds # находит усеченное значение s и сохраняет результат в d
ceil ds # вычисляет потолок s и сохраняет результат в d
floor ds # вычисляет floor s и сохраняет результат в d
max dst # вычисляет максимум s и t и сохраняет результат в d
min dst # вычисляет минимум s и t и сохраняет результат в d
abs ds # вычисляет абсолютное значение s и сохраняет результат в d
log ds # вычисляет натуральный логарифм s и сохраняет результат в d
exp ds # вычисляет экспоненту s и сохраняет результат в d
rand d # равномерно случайным образом выбирает случайное число от 0 до 1 включительно и сохраняет результат в d, логическая арифметика использует соглашение C, согласно которому 0 является ложным, а любое ненулевое значение верно.
and dst # сохраняет 1 в d, если и s, и t имеют ненулевые значения, 0 иначе
or dst # сохраняет 1 в d, если s или t имеют ненулевые значения, 0 иначе
xor dst # сохраняет 1 в d, если ровно один из s и t отличен от нуля, 0 иначе
nor dst # сохраняет 1 в d, если и s, и t равны нулю, иначе 0 Строки нумеруются, начиная с нуля
j a # переходит к строке a.
bltz sa # переход к строке a, если s < 0
blez sa # переход к строке a, если s <= 0
bgez sa # переходит к строке a, если s >= 0
bgtz sa # переходит к строке a, если s > 0
beq sta # переходит на строку a, если s == t
bne sta # переход к строке a, если s != t
bdseal д? a(r?|num) # Перейти к строке a и сохранить текущий номер строки, если устройство d? установлен.
`bdseal d0 32 #Store line number and jump to line 32 if d0 is assigned.`

`bdseal dThisVictim HarvestCrop #Store line in ra and jump to sub HarvestCrop if device dThisVictim is assigned.`

yield # останавливает выполнение кода для этого тика питания
**lb** r? typeHash varbatchMode # Загружает var со всех выходных сетевых устройств с предоставленным typeHash, используя предоставленныйbatchMode
Average(0), Sum(1), Minimum(2),Maximum(3). Может использоваться слово или число. Результат хранить в r?
sb typeHash var r? # Сохранить регистр r? для var на всех выходных сетевых устройствах с предоставленным typeHash
# # Следующий текст будет проигнорирован при компиляции; используйте это для создания комментариев.
## Conditional functions cheatsheet

Все `b-`команды требуют целевой строки в качестве последнего аргумента, все `s-`команды требуют регистрации для сохранения результата в качестве первого аргумента. Все `br-`команды требуют числа для перехода относительно последнего аргумента. например `breq a b 3`, означает, что если a=b, то перейти на 3 строки после.

Все приближенные функции требуют дополнительного аргумента, указывающего, насколько близко два числа нужно считать равными. Например: `sap r0 100 101 0.01` 100 и 101 будут считаться почти равными (отличаются не более чем на 1% = 0,01) и установит r0 равным 1. Точная формула предназначена `if abs(a - b) <= max(c * max(abs(a), abs(b)), float.epsilon * 8)`for `-ap` других приближенных функций и аналогична им.

## Device Variables

Activate

1, если устройство активировано (обычно это означает, что оно работает), иначе 0
`l r0 d0 Activate # sets r0 to 1 if on or 0 if off`
AirRelease
Charge Текущий заряд устройства.
CLearMemory При значении 1 очищает память счетчика (например, ExportCount). Устанавливает себя обратно в 0 при срабатывании.
Color (Цвет)
0 (или ниже) = Синий
1 = серый
2 = зеленый
3 = оранжевый
4 = красный
5 = желтый
6 = белый
7 = черный
8 = коричневый
9 = хаки
10 = розовый
11 (или выше) = Фиолетовый
CompletionRatio
ElevatorLevel
ElevatorSpeed
Error 1, если устройство находится в состоянии ошибки, иначе 0
ExportCount Сколько элементов было экспортировано с момента последнего ClearMemory.
Filtration Фильтрация Текущее состояние системы фильтрации. Например, фильтрация = 1 для жесткого костюма, когда фильтрация включена.
Harvest Урожай Выполняет действие по сбору урожая для любой растительной техники.
`s d0 Harvest 1 # Performs 1 harvest action on device d0`
Horizontal
HorizontalRatio
Idle
ImportCount
Lock
Maximum
Mode
On
Open
Output
Plant Выполняет операцию посадки для любой техники
`s d0 Plant 1 # Plants one crop in device d0`
PositionX
PositionY
PositionZ
Power
PowerActual
PowerPotential
PowerRequired
Pressure
PressureExternal
PressureInteral
PressureSetting
Quantity Общее количество в устройстве.
Ratio Контекстное значение зависит от устройства, соотношение 0 к 1.
RatioCarbonDioxide
RatioNitrogen Соотношение азота в атмосфере устройства.
RatioOxygen Соотношение кислорода в атмосфере прибора.
RatioPollutant Соотношение загрязняющих веществ в атмосфере устройства.
RatioVolatiles Соотношение летучих в атмосфере устройства.
RatioWater Соотношение воды в атмосфере устройства.
Reagents
RecipeHash
RequestHash
RequiredPower
Setting
SolarAngle Солнечный угол
`l r0 d0 SolarAngle # Sets r0 to the solar angle of d0.`
Temperature
TemperatureSettings
TotalMoles
VelocityMagnitude
VelocityRelativeX
VelocityRelativeY
VelocityRelativeZ
Vertical Вертикальная установка устройства.
VerticalRatio Отношение вертикальной установки для устройства.
Volume Объем Возвращает объем атмосферы устройства
## Slot Variables Переменные слота

Обычно (всегда?) слоты распределяются следующим образом.

Слот 0: Импорт
Слот 1: Экспорт
Слот 2: внутри машины
Occupied Занято
`ls r0 d0 2 Occupied #Stores 1 in r0 if d0 has more seeds`
`ls vOccupied dThisVictim 2 Occupied #stores 1 in vOccupied if dThisVictim has more seeds`
OccupantHash
Quantity
Damage
Efficiency
Health
Growth Рост
`ls r0 d0 0 Growth # Store the numerical growth stage of d0 in r0`
Pressure
Temperature
Charge
ChargeRatio
Class
PressureWaste
PressureAir
MaxQuantity
Mature Зрелый
`ls r0 d0 0 Mature # Store 1 in r0 if d0 has a mature crop`
`ls vMature dThisVictim 0 Mature # Store 1 in vMature if dThisVictim has a mature crop`

### Пример эксперимента: сколько строк кода выполняется каждый тик?

`yield`Чтобы это определить, будет использован скрипт без . В нем должно быть как можно меньше строк (поэтому метки не используются, но потребуется значение сброса вверху) и подсчитывается количество строк, Сокетебудет использоваться для отображения результата.

```
move r0 1 # первая строка имеет номер 0
добавить r0 r0 3
с дб Параметр r0
j 1

```

Результат (цифры появляются каждые 0,5 секунды):

127

256 (+129)

385 (+129)

511 (+126)

640 (+129)

769 (+129)

895 (+126)

1024 (+129)

1153 (+129 ) )

Есть повторяющаяся последовательность +129, +129, +126, намек на то, что реальное значение равно 128. Это также количество строк в сценарии, что имеет смысл. Вариант этого эксперимента покажет, что пустые строки также учитываются в этом числе.