К процессору может быть подключено сколько угодно устройств (ограничено только кол-вом портов).
Любое устройство можно отключить "на ходу".
Предполагается что с устройством можно обменивваться байтами: считывать один байт, записывать один байт, узнавать можно ли считать байт.
Устройство может не обладать какими-то из этих возможностей.
Если устройство не может записывать байт то при записи ничего не происходит (считается что она прошла успешно), процессор продолжает работу.
Если устройство не может дать ответ на запрос о возможности считать байт - то считается что считать нельзя.
Если же мы хотим считать байт, то процессор будет ждать получение байта в любом случае, соотв. если устройство дало сбой, то процессор будет ждать до выключения.
Основной регистр - регистр который может использоваться для вычислений.
Текущий основной регистр - регистр который используется в текущий момент для вычислений.
Соотв. вычислительные операции (с 0x07 по 0x0E) применяются к текущему основному регистру.
В текущей реализации основных регистров две штуки, в принципе может быть скольк угодно.
Для изменения текущего основного регистра используется команда SWAP которая циклически меняет ТОР.
Например:
- если у нас есть 2 ОР то SWAP меняет их местами в смысле ТОР.
- если у нас 5 ОР и ТОР - 4-ый то после SWAP ТОР станет 5-ым, а после еще одного SWAP станет 1-ым.
Изначально все ОР обнулены.
! Не путать с портами, портов куда больше.
Портовый регистр - регистр хранящий в себе номер порта.
Текущий портовый регистр - портовый регистр который используется в текущий момент.
Текущий же порт - порт на который указывает текущий портовый регистр.
Портовые операции TEST, SET, READ, WR приминяются к текущему порту.
Команда CUR[X] меняет текущий портовый регистр на портовый регистр с номером X.
В текущей реализации их 5 штук - пользовательский, CEM, COM, WIN, Console.
При компиляции bf-ext от пользователя скрыты все кроме первого.
Но этого вполне достаточно - любой портовый регистр можно установить в любое значение и соотв. обратиться к любому устройству.
Изначально инициализируются портовый регистр ответственный за CEM и за COM.
Это надо в силу того что для использования любой команды нужно ее откуда-то получить (т.е. COM),
а для того чтоюы установить какой-либо портовый регистр также нужен CEM (см. SET).
Остальные могут никогда и не инециализироваться.
Портовые регистры для CEM и COM тоже можно сменить "на ходу".
| имя операции* | посл. байтов** | описние |
|---|---|---|
| PASS | 0x00 | Ничего не делает |
| TEST | 0x01 | Проверяет есть ли байт для считывания из тек. порта |
| CUR[SE] | 0x02:SE | В качестве текущего портового регистра используется портовый регистр с порядковым номером SE |
| SET | COM: 0x03 CEM: SE | Устанавливает тек. порт в std_se_dec(SE) |
| READ | 0x04 | Считывает из тек. порта байт и записывает его в ТОР. Выполнение программы прекращается до считывания байта |
| WR | 0x05 | Передает в тек. порт байт - значение ТОР |
| SWAP | 0x06 | циклически меняет ТОР. |
| ! TZ | 0x07 | Если значение ТОР было 0 то не оказывает эффекта, иначе его значение становится равным 1 |
| INC | 0x08 | Увеличивает значение ТОР на 1 |
| DEC | 0x09 | Уменьшает значение ТОР на 1 |
| ! LSH | 0x0A | Битовый сдвиг ТОР влево на 1. Иначе, умножение на 2 |
| ! RSH | 0x0B | Битовый сдвиг ТОР вправо на 1. Иначе, целочисленное деление на 2. |
| ! AND | 0x0C | Значение ТОР = ТОР & 0x01 |
| ! BND | 0x0D | Значение ТОР = ТОР & 0x80 |
| ! ZER | 0x0E | Обнуляет значение ТОР |
* Если перед именем стоит ! значит убрав все такие операции(не по отдельности а вместе, т.е. одновременно убрав все LSH, RSH, ZER, CL, ...) мы все еще можем их реализовать используя оставшиеся(см. examples/proof_of_sugarity_some_cmds/) таким образом данные команды нужны только для ускорения и удобства.
- бинарная операция A:B означает что после A (или любого элемента из множества A) идет B (любой элемент из множества B)
- S : Small byte, байт имеющий значение от 0 до 127 включительно [0x00; 0x7F]
- B : Big byte, байт имеющий значение от 128 до 255 включительно [0x80; 0xFF]
- SE : Set of byte sequences - множество последовательностей байтов таких что S in SE, B:SE in SE
std_se_dec(X): стандартное декодирование SE посл. байтов:
sh = 0;
result = 0;
loop
{
byte = get_next_byte();
result += (byte & max(S)) << sh;
if byte > max(S) { sh += 7; }
else { break; }
}
return result;