Shaos wrote:Shaos wrote:Вопрос возник - нужно добавить в RW1P2 файловые операции. Я за эти годы несколько подходов окучил - пока ни один не понравился (каналы, спец-команды, ассемблерные вставки). Вобщем думается сделать на нижнем уровне передачу файлов блоками по 256 байт (как на CP/M-80), а на строки или на байты уже будет делить библиотека, написанная на RW1.
Weberta-интерпретатор байткода RW0
(который теперь входит в состав Rgrid.js) имеет следующую реализацию файловых операций:
Shaos wrote:Файлы читаются так - получателю -4 (@filesystem) посылается пакет с именем файла (одна буква на ячейку), далее ждём евента от @filesystem - в нём будет размер прочитанного файла, далее обращаемся (через указатели A/B/C) в отрицательную область памяти переменных (ячейки с адресами от -32K до -1) за телом файла.
Аналогичным образом можно сделать запись - добавив к имени файла какой-то суффикс, например !, что будет обозначать запись из отрицательной области памяти переменных в файл с указанным именем (длину записи можно указать следом за !)...
P.S. На самом деле ячейки с адресами от -32768 до -257 (т.е. 32512 слов или 65024 байта) потому что -256 и выше идут коды "регистров"
Переосмысливая
идеи 2014 года можно предложить следующее
Пакет с именем файла - это массив слов, в первом слове которого указано количество следующих далее букв и сейчас поддерживается только чтение (например в
Circuits.CC):
"filename" - прочитать текст из файла с именем filename, разместив его начиная с адреса #8000 по одной букве на слово, причём количество скопированных букв приходит в ответе от @filesystem
По аналогии добавляем:
"filename!" - записать буфер в файл с именем filename, причём пишем только младшие байты и останавливаемся, когда встретили ноль
"filename%" - прочитать двоичный файл, упаковав байты по 2 в слово (от системы придет прочитанный размер в байтах)
"filename%hhh" - записать двоичный файл с байтовым размером hhh (шестнадцатиричное число) пользуясь словами из буфера (если размер нечётный, то из последнего слова возьмется только младший байт)
"filename+" - дополнить текстовый файл строкой из буфера (буква на слово, писать до нуля) - хотя может быть проще say перенаправить в файл...
Работу с произвольным адресом пока можно отложить на будущее, но уже можно считать, что там в систему будут передаваться не строки, а структуры - с адресом, длиной, смещением внутри файла и т.д.
P.S. Скелет программы (вырезка из TERNARO.R):
Code: Select all
robot "Test"
author "Shaos"
+INC/ROBBY
main()
{
def tmp[17] = "START" // тут хранится пакет - в ячейке 0 будет 5, что есть длина слова, и далее 5 ячеек с буквами
sendp tmp[0] @filesystem // хотим файл с именем START
while(TRUE) // вечный цикл в котором мы будем обрабатывать приходящие сообщения
{
code = 0
recv code // принять сообщение и записать его в переменную code
if(N==0) continue // буфер принятых сообщений пуст
if(N==@mouse) // это сообщение от мыши
{
...
}
if(N==@filesystem) // это сообщение от файловой системы, сообщающее, что файл записан в буфер (в регистре K будет размер)
{
A = @filebuffer // начинаем читать с адреса #8000
while(A[0]) // пока не встретили ноль (либо любой другой маркер окончания полезной информации - этот символ должен быть в файле)
{
// что-то делаем с очередной буквой A[0]
A = A + 1 // сдвигаем указатель на 1
}
}
}
}
P.P.S. На самом деле просто имя файла это чтение текстового файла где через запятую идут целые числа со знаком (обычно 16-битные т.е. signed short) и именно эти значения записываются в память при чтении из файла - одно значение на ячейку. Соответственно чтобы читать произвольный текстовый файл надо вводить спец.символ - например $ т.е. запросив чтение из файла filename$ мы читаем его как текстовый по одной букве на ячейку (по идее так можно и UTF8 читать, разворачивая его в полноценный 16-битный Unicode)...