PDA

Просмотр полной версии : Спектрум-бейсик, где почитать?



Dr.Potapov
25.02.2019, 17:33
День добрый.
Подскажите пожалуйста, где на русском почитать о том, как работает спектрум-бейсик?
Выполнение команд интересует прежде всего, в частности - каков алгоритм команды GOTO, каким образом вычисляется адрес строки для перехода в процессе интерпретации?

Shiny
25.02.2019, 18:42
Наверху, в шапке есть ссылка zxpress.ru это твой шанс, наверное.
Для более углубленного изучения механизмов работы есть The Complete SPECTRUM ROM DISASSEMBLY на инглише.

- - - Добавлено - - -

Кстати,, не знаю, где книга мелькала, но кое-что на русском.
обработка GO TO по адресу $1E67
http://rgho.st/6LZffj8Wf

zebest
25.02.2019, 19:16
ну елси дело только в диз-асме, то вот коллективное творчество сознательной части форума:)
https://zx-pk.ru/threads/14994-kniga-quot-polnyj-dizassembler-pzu-zx-spectrum-quot-na-russkom.html
Давнооооооо это было (с)

Dr.Potapov
25.02.2019, 20:51
ну елси дело только в диз-асме, то вот коллективное творчество сознательной части форума:)
https://zx-pk.ru/threads/14994-kniga-quot-polnyj-dizassembler-pzu-zx-spectrum-quot-na-russkom.html
Давнооооооо это было (с)
Спасибо большое )
А то кроме как воткнутся в первую по счету строку и пропрыгать до нужной (используя длину каждой строки) больше ничего на ум не приходит из дешевых вариантов (что бы не хранить в памяти адреса каждой строки и не маяться с ними при вставке строки куда-нибудь посередине). Надо умных людей почитать, как у них это сделано было ))

Shiny
25.02.2019, 22:18
танцы отсюда:
https://skoolkid.github.io/rom/asm/1E67.html

выведут сюда:
https://skoolkid.github.io/rom/asm/196E.html

но это навскидку, нужно проверить.

По идее вряд ли адреса хранятся, токены не просто так придуманы.

Dr.Potapov
26.02.2019, 10:50
танцы отсюда, выведут сюда
но это навскидку, нужно проверить.
Да, вижу, они тоже не особо парились:
"Now enter a loop to test the line number of each line of the program against the given line number until the line number is matched or exceeded"
Заходим в цикл и сверяем номер каждой строки программы с искомым номером строки, пока номер строки не совпадет или не будет превышен.

goodboy
26.02.2019, 13:47
в описании `надстройки` BetaBasic прямо сказано что goto/gosub/return работают гораздо быстрее

Dr.Potapov
26.02.2019, 14:34
в описании `надстройки` BetaBasic прямо сказано что goto/gosub/return работают гораздо быстрее
Всмысле?

Есть еще одна мысль - закешировать последние 5-10 гоутушек и искать прежде всего в кеше. Там получается 2 байта на номер строки и 3 байта на адрес для интерпретатора (у меня тут 24бит адресация), итого 5 байт на запись или 50 байт на кешик из десяти последних гоутушек. Не нашел строку в кеше - переберем все.

Bolt
26.02.2019, 15:06
В кэше "10 последних" искать долго и сложно, в цикле. Номера, кстати, можно не хранить, просто перебрать адреса и брать номера строк оттуда.

16 (32, 64...) элементов по 3 байта (только адрес).
Нужна строка N. Берём из кэша элемент "(N+(N shr 8)) and 15", если по этому адресу нужная строка - ок, если другая - ищем нужную и заносим в этот элемент кэша.

null_device
26.02.2019, 18:29
Dr.Potapov, цимес в том, что команды прехода в SOS могут использовать, как непосредственно числовые значения в качестве параметров, так и переменные, либо логически-математические выражения.


кроме как воткнутся в первую по счету строку и пропрыгать до нужной (используя длину каждой строки) больше ничего на ум не приходит из дешевых вариантов

Чем плох такой вариант? Самое, главное, зачем изобретать велосипед?!
Попытайтесь внятно формализовать задачу - зачем вам это надо. Возможно проще будет написать программку, для формирования где-нибудь в ячейках паямяти массива адресов переходов команд GOTO перед финальным сохранением программы?

- - - Добавлено - - -


Нужна строка N. Берём из кэша элемент "(N+(N shr 8)) and 15", если по этому адресу нужная строка - ок, если другая - ищем нужную и заносим в этот элемент кэша.

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

Shiny
26.02.2019, 19:04
хорошо что нет конструкции ON VAR GOTO N1,N2

Bolt
26.02.2019, 19:34
Прикол в том, что аргумент перехода на строку может ссылаться на строку с номером, которого нет. При этом будет выполнен переход к следующей ближайшей за ней.

Да без проблем.

Пошагово. Начинаем с пустого кэша.
Переход на строку 100. Ячейка кэша пустая. Ищем строку, адрес заносим в ячейку кэша, соответствующую строке 100.
Переход на строку 100. Ячейка кэша содержит адрес строки 100, проверяем номер - всё ок.
Переход на строку 321. Ячейка кэша пустая. Ищем строку, находим строку 330, адрес заносим в ячейку кэша, соответствующую строке 321.
Переход на строку 321. Ячейка кэша содержит адрес строки 330, проверяем номер - не совпадает. Ищем строку, находим строку 330, адрес заносим в ячейку кэша, соответствующую строке 321.

То есть всё зашибись, просто при переходе на несуществующую строку работать будет "с обычной скоростью".
Чтобы не засорять кэш можно не записывать в него адрес найденной строки, если её номер не совпадает с требуемым.

Усложняем алгоритм...
1. Вычислить номер ячейки кэша, прочитать из кэша адрес.
2. Если номер строки по этому адресу меньше, а номер следующей строки больше или равен требуемому - берём следующую.
3. Иначе - ищем строку с самого начала, но в кэш пишем адрес предыдущей. Для первой строки ничего не пишем.

Пошагово. Начинаем с пустого кэша.
Переход на строку 100. Ячейка кэша пустая. Ищем строку, адрес предыдущей (90) заносим в ячейку кэша, соответствующую строке 100.
Переход на строку 100. Ячейка кэша содержит адрес строки 90, номер меньше, следующий равен - берём следующую.
Переход на строку 321. Ячейка кэша пустая. Ищем строку, находим строку 330, адрес предыдущей (320) заносим в ячейку кэша, соответствующую строке 321.
Переход на строку 321. Ячейка кэша содержит адрес строки 320, номер меньше, следующий больше - берём следующую.
...
Переход на строку 1234. Ячейка кэша содержит адрес строки 2000, номер больше - ищем с начала, пишем в кэш предыдущую.
Переход на строку 2345. Ячейка кэша содержит адрес строки 500, номер меньше, номер следующей тоже меньше - ищем с начала, пишем в кэш предыдущую.

Вроде ничего не забыл.

- - - Добавлено - - -


хорошо что нет конструкции ON VAR GOTO N1,N2
Пофиг. Потому что в итоге, даже если N1 и N2 - выражения, всё в итоге сведётся к номеру строки, который будет обработан кэшем.

Интересно, а как происходит переход в for ... next? По номеру строки или по адресу строки?

Shiny
26.02.2019, 20:08
Интересно, а как происходит переход в for ... next? По номеру строки или по адресу строки?
Если шибко интересует, то можно покопаться в дизассемблированном тексте с комментариями.
Вангую, что вопрос снимется (:

- - - Добавлено - - -


Пофиг. Потому что в итоге, даже если N1 и N2 - выражения
не выражения, а номера строк.

null_device
26.02.2019, 20:57
Bolt, возникает вопрос: зачем вся эта эквилибристика с дублированием данных в кэш? Спектрум-бейсик и так довольно прожорлив в плане хранения данных.

Если ТС, нужно вычислить конкретные значения строк в листинге полученной программы, эту узкоспециализированную задачу, можно решить без написания очередной надстройки на ЯВУ. :)

Bolt
26.02.2019, 21:09
ТС хочет сэкономить время на переходах ценой ещё бОльшего расхода памяти и некоторого количества эквилибристики. Почему бы не помочь человеку идеей?

Dr.Potapov
26.02.2019, 21:43
Bolt, возникает вопрос: зачем вся эта эквилибристика с дублированием данных в кэш? Спектрум-бейсик и так довольно прожорлив в плане хранения данных.
Все гораздо прозаичней, у меня тут новодел спектрум-подобный на столе поселился. На Atmega32a с 128к SPI RAM, 256к извлекаемой флешки (иммитация дискеты) и экраном 480х320. Понимаете, SPI RAM не очень быстрая, поэтому закешировать что либо в памяти МК всегда рад. Там же не оригинальный бейсик, скорее некая разновидность 128к бейсика, поэтому есть немного свободы действий в реализации.

- - - Добавлено - - -


Чем плох такой вариант?
Да как основной рабочий он и был с самого начала, это я уже чуть позже с кешем замудрил )) Потом, я совершенно не помню уже как работает оригинальный бейсик, поэтому засомневался и полез читать с помощью форумчан - как там все устроено.

Shiny
27.02.2019, 06:58
Суть Бейсика в том, что не очень быстрый xD

Dr.Potapov
27.02.2019, 07:05
Суть Бейсика в том, что не очень быстрый xD
Микроконтроллеру все равно что разгребать - токены бейсика или опкод Z80 ) Будут с одинаковой скоростью работать. Была мысль сделать очередной эмуль Z80, но решил остановиться на бейсике.

jerri
27.02.2019, 08:04
Dr.Potapov, а чего сразу спектрумский басик. я бы предложил бейсик с BBC микро. он шустрее и страшнее.

Dr.Potapov
27.02.2019, 10:00
Dr.Potapov, а чего сразу спектрумский басик. я бы предложил бейсик с BBC микро. он шустрее и страшнее.
Он действительно страшнее )) Я такой не осилю, атмега32 скорей всего тоже ))
Да и разницы между
LD A,10
LD HL,32768
LD (HL),A
и
LET A=10
POKE 32768,A
с точки зрения микроконтроллера нет, смысл плодить сущности поддерживая "ужасы" BBC BASIC (включая ассемблерные вставки, процедуры, функции, IF-THEN-ELSE и прочие навороты)? )) Спектрум бейсик по крайней мере мне понятен, вполне удобен и прост.

Shiny
27.02.2019, 10:54
Реализаций найдется. Вроде есть RCBASIC, но я не сравнивал по быстродействию.
есть под 6502 Enhanced Basic. Да и под cp/m найдется немало, но они тормозные донельзя.