Sinclair Club #05
31 декабря 2001

Программирование - очень эффективный способ повысить производительность интерпретатора бейсика (48 Basic), встроенного в ZX-Spectrum, при обработке больших массивов данных.

<b>Программирование</b> - очень эффективный способ повысить производительность интерпретатора бейсика (48 Basic), встроенного в ZX-Spectrum, при обработке больших массивов данных.
   ┌──────────────────────────────────┐
   │	    Бейсик-48К	    │
   └──────────────────────────────────┘

──────────────────────────────────────────

	   (с) Alone Coder/Any

──────────────────────────────────────────

   Сегодня я собираюсь рассказать об одном
очень  эффективном способе повысить произ-
водительность  интерпретатора  бейсика (48
Basic), встроенного в ZX-Spectrum, при об-
работке больших массивов данных.
   Известно, что классическим способом пе-
ремещения блоков данных в памяти при прог-
раммировании в машинных кодах (ассемблере)
является  команда  LDIR, а также её родная
сестра - команда LDDR. На бейсике же ниче-
го  подобного не предусмотрено, и поэтому,
скажем,  "ZX-Ревю"  советует  использовать
для  таких случаев подгружаемые или созда-
ваемые  через READ-DATA-POKE машинно-кодо-
вые процедуры.
   Но я - за чистоту родного бейсика! ;)
   Можно закрутить цикл,перебирающий адре-
са  и перемещающий по одному байту за про-
ход,но такой вариант будет выполняться как
минимум в сотни раз медленнее,чем машинный
код - это очень медленно.
   Но мы вспомним, что в языковом аппарате
"бейсика" заложена функция, которая выпол-
няется со скоростью LDIR.Функция эта - ко-
пирование строковых переменных и их участ-
ков!
   К сожалению,в бейсике нельзя задать пе-
ременную,проходящую через экранную область
(а нам именно это и нужно, так как копиро-
вание  больших блоков чаще всего требуется
для обработки экрана: его сдвига, сохране-
ния в памяти, восстановления и т.п.)
   Поэтому попробуем создать фиктивную пе-
ременную, пересекающую экран,своими средс-
твами.
   Как  известно, двухбайтный адрес начала
переменных  бейсика  хранится  в системной
переменной  VARS (23627-23628). Переменные
в этой области следуют одна за другой,ука-
зывая  друг на друга по цепочке. Несколько
форматов переменных отличаются тремя стар-
шими  битами  в первом символе имени пере-
менной.
   Строковые переменные имеют формат:

%010aaaaa <мл.байт длины> <ст.байт длины>
 <символы ("длина" штук)>

   Где  aaaaa - младшие  пять  бит символа
имени  переменной (у  строковых переменных
односимвольные  имена),  а "длина" - длина
содержательной части строки, т. е. сколько
в этой строке символов.
   Получается,что достаточно заполнить три
первых байта формата переменной,и мы можем
заполучить строку произвольной длины с во-
зможностью копирования внутри неё, т. е. с
возможностью быстрого перемещения блоков.
   Но задача осложняется тем,что последняя
обрабатываемая строковая переменная всегда
пересылается  бейсик-интерпретатором в на-
чало  области переменных (по крайней мере,
мне  так  показалось), да ещё и адрес этой
области  нефиксирован - зависит  от  длины
программы  и конфигурации компьютера, да и
вдобавок,создав такую переменную,мы теряем
все  другие переменные бейсика, ибо на них
уже  больше  ни одна предыдущая переменная
не  указывает. (Ведь предыдущих переменных
у нас всего одна штука - больше мы создать
не можем, потому что см. начало абзаца :))
   Значит, единственный правильный выход -
переместить область переменных по фиксиро-
ванному адресу в памяти, создать идентифи-
катор фиктивной строковой переменной, про-
извести  с помощью неё нужные операции ко-
пирования, а  после этого восстановить ис-
ходный адрес области переменных.

┌────────────────────────────────────────┐
│ BASIC program	Length: #01A8=424 │
└────────────────────────────────────────┘

   1 LIST :
     POKE VAL "23627", CODE " CLEAR ":
     POKE 23628, NOT PI
1000 LET b$(39968 TO 40223)=b$(16129 TO ):
     LET b$(16129 TO 17920)=b$(16385 TO ):
     LET b$(17921 TO 18144)=b$(4e4 TO )
1010 LET b$(18145 TO 18176)=b$(18177 TO )
1020 LET b$(4e4 TO 40223)=b$(18209 TO ):
     LET b$(18177 TO 19968)=b$(18433 TO ):
     LET b$(19969 TO 20192)=b$(4e4 TO )
1030 LET b$(20193 TO 20224)=b$(39968 TO ):
     GO TO 9


   Эта  программа (см. также  приложение к
газете) задаёт переменную b$, начинающуюся
с адреса 253 (CODE " CLEAR "=253).По этому
адресу  во  ВСЕХ версиях бейсика находится
участок таблицы токенов, который и опреде-
ляет  переменную  с  этим  именем и длиной
около 50 килобайт.
   Поскольку  идентификатор переменной на-
чинается  с  адреса  253, то первый символ
( b$(1) ) этой  переменной хранится по ад-
ресу 256,второй - по адресу 257 и т.д. Так
что  все указанные в программе числа - это
экранные адреса минус 255.
   Программа скроллирует две экранных тре-
ти. Это упрощённый вариант программы,пред-
назначенный только для иллюстрации метода.
Поэтому выход из неё не предусмотрен. Если
вы во время её выполнения нажмёте BREAK,то
даже не сможете выполнить RUN,т.к. область
переменных  была перемещена и не вернулась
обратно.
   Практический  способ  сохранить  и пра-
вильно  восстановить  системную переменную
VARS в условиях отсутствия доступа к пере-
менным  состоит  в копировании содержимого
ячеек  23627 и 23628 по некоему известному
адресу в памяти и восстановлении этого со-
держимого  сразу после выполнения "нечест-
ного" участка программы.
   Конечно,наша созданная переменная может
и  указывать  на последующие, но для этого
она должна кончаться там, где они начинаю-
тся.Такая переменная получится очень коро-
ткой, создай мы её в первой половине памя-
ти, но  если  она  будет  начинаться  выше
25000,то она сможет захватить в себя и эк-
ран, и  верхние области памяти, и при этом
ещё  может указывать на другие переменные.
Разумеется, в этом случае программа не до-
лжна  использовать  другие строковые пере-
менные,или,по меньшей мере,должна переклю-
чать VARS перед их использованием.
   Кстати, если бы переменная была создана
по  адресу 65534, то нумерация её символов
совпадала бы с адресами,по которым эти си-
мволы хранятся. У меня большое подозрение,
что так работает функция "MEMORY$()" в Бе-
та-Бейсике, но  она написана с помощью ма-
шинного кода, а у нас - чистый бейсик!

	  Spectrum Basic rulez!
	  & it's not portable :)



Другие статьи номера:

От авторов - "Читайте наше издание и ваша Spectrum'овская душа будет кристально чистой."

Демопати - анонс ASCII'2002.

Программирование - очень эффективный способ повысить производительность интерпретатора бейсика (48 Basic), встроенного в ZX-Spectrum, при обработке больших массивов данных.

Железо - Sprinter? Вопросы и ответы!

Конкурс - Внимание конкурс "Твоя игра"!!!

Софт - Странности системных программ: STS 5.1, ALASM 4.1.

Chaos Constructions'2001 - Касик делится впечатлениями об очередном фестивале компьютерного искусства.

Софт - описание новой версии GFX UTILITY v0.5.

phONOmania - база данных по телефонным номерам активных ZX сценеров.

Обьявления - реклама и обьявления.

Авторы - Редакция газеты.


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Итоги конкурса "Твоя игра 2002" - о местах, призах и победителях.
ZX-OСЬ ? - Вoт ужe дoлгoe врeмя вoпрoс o пoбeдe Дырявoгo Дoсa нa Спeктрумe плaвнo пeрeплывaл из oднoгo издaния в другoe.
Интервью - Новгородская группа Digital Reality.
Outro
Железо - Много функций на одном теле (об АОН'ах).

В этот день...   21 ноября