(c) Давыдов В.М.,
Нижегородская обл., с.Запрудное.
По материалам,
опубликованным в ZX РЕВЮ.
НЕКОТОРЫЕ ВОПРОСЫ, СВЯЗАННЫЕ С
АВТОСТАРТОМ БЕЙСИК-ПРОГРАММЫ.
(ZX РЕВЮ 94/5, стр.29).
Корреспондент задавал вопрос
о запуске из машинного кода BA-
SIC-программ. По приведенным ре-
комендациям сделать это не сос-
тавит труда, но нужно иметь в
виду одну тонкость.
Хотя, в основном, на BASIC
пишутся загрузчики длиной 1-2
сектора, программировать на BA-
SIC никто не запрещал, и может
встретиться программа, занимаю-
щая всю память. Запустить ее из
машинного кода не удастся. При
загрузке она затрет процедуру
запуска. А boot, для которого
это все и предназначалось, дол-
жен запускать любую программу.
Кроме того, при использовании
BASIC для загрузки и запуска
программы, в машинном коде пот-
ребуется только перенести имя
файла в строку BASIC типа:
CLEAR VAL "65535":
RANDOMIZE USR VAL "15619":
REM: RUN "ANY NAME"
на место ANY NAME и поставить
RET для возврата в BASIC, а все
остальное сделает интерпретатор
TR-DOS. Размер программы при
этом сократится.
Кстати, те же ограничения
относятся к размещению в памяти
релоцируемой процедуры "LOAD-
MERGE" (ZX РЕВЮ 96/4-5, стр.80).
Резюме: boots с промежуточ-
ным выходом в BASIC пишутся не
от скудоумия, а для универсаль-
ности.
REDEFINE KEYS
(ZX РЕВЮ 96/4-5, стр.79).
Увидев в трех местах маску
%11111, очень сильно захотелось
сократить процедуру. Исходный
вариант сократился всего на два
байта. Одновременно повысилось
быстродействие на шесть тактов,
хотя быстродействие здесь не
требуется. Все равно перед опро-
сом следующей клавиши придется
ставить замедляющий цикл или
процедуру ожидания отпускания
клавиши, иначе, не желая того,
можно назначить одну клавишу на
все функции.
В конце процедуры добавлены
несколько строк для ожидания от-
пускания клавиши. Они помечены
комментарием ;***
1410.
REDEF LD BC,#7FFE
LD H,#1F
KEY_L IN A,(C)
AND H
CP H
JR NZ,KEY_PR
RRC B
JR C,KEY_L
JR REDEF
KEY_PR XOR H
LD L,A
LD H,B
WAIT_L IN A,(C) ;***
AND L ;***
JR Z,WAIT_L ;***
RET
2
Если бы от процедуры требо-
валось быстродействие, повысить
его на один такт процессора мож-
но было бы, если вместо последо-
вательности
CP H
JR NZ,KEY_PR
использовать
JP PE,KEY_PR
В дополнение к предыдущей
предлагаю свой вариант процеду-
ры определения кода нажатой кла-
виши. На входе в процедуру в ре-
гистре H - старший байт адреса
порта, в L - маска бита нажатой
клавиши. На выходе в A - код на-
жатой клавиши. Изменяет регис-
тры HL и DE. HL - адрес в ПЗУ из
которого взят код в аккумулятор;
DE - смещение от начала таблицы,
находящейся по адресу #0205.
140.
TRANSF XOR A
LOOP_1 ADD A,#08
RL L
JR NC,LOOP_1
LOOP_2 INC A
RL H
JR C,LOOP_2
SUB #21
LD E,A
JP #0347
Примечание. По адресу #0347
в ПЗУ расположен следующий фраг-
мент:
LD HL,#0205
LD D,#00
ADD HL,DE
LD A,(HL)
RET
Управляющим клавишам в таб-
лице по адресу #0205 соответ-
ствуют следующие коды:
#0D - ENTER
#0E - SYMBOL SHIFT
#E3 - CAPS SHIFT
2
ПРОЦЕДУРА ПЕЧАТИ
42 СИМВОЛОВ В СТРОКЕ.
В ZX РЕВЮ 95/5 была опубли-
кована процедура печати 42 сим-
волов в строке (Дмитрий Серге-
ев). В ZX РЕВЮ 96/4-5 приведена
ее упрощенная модификация (Матю-
шев Александр).
Поскольку они используют
один алгоритм, им присущи общие
ограничения.
Во-первых, не совсем коррек-
тно отрабатывается печать с ис-
пользованием цветовых атрибутов.
Расчет адреса атрибутов произво-
дится для левого угла знакомес-
та 6х8 и, если символ занимает
два знакоместа 8х8, в нужный
цвет окрашивается только левая
часть символа.
Устранить это можно, напри-
мер, таким способом. Для листин-
га в ZX 96/4-5, стр. 102 между
строками 0870 и 0880 вставить
следующий фрагмент:
140.
LD A,(XTXT)
AND 3
JP PE,NO_INCX ; переход к
;3 строке 0880
INC HL
LD A,(23659)
LD (HL),A
2
Для листинга из ZX 95/5,
стр.30 аналогичный фрагмент нуж-
но вставить между строками 0133
и 0134.
Второе ограничение связано с
алгоритмом печати. Так как ис-
пользуется скроллинг в экранной
памяти с очисткой соседнего зна-
коместа, пользоваться данной
процедурой можно только для пе-
чати на чистом экране слева нап-
раво и сверху вниз. Для этих це-
лей процедура достаточно компак-
тна.
Для придания процедуре уни-
версальности потребуется изме-
нить процедуру PRSYM.
Алгоритм может быть, напри-
мер, таким. Он понятен из поби-
товой раскладки знакомест 8х8 и
6х8 пикселов.
┌─────────────────────────────┐
│ Знакоместа 8х8 │
├─────────┬─────────┬─────────┤
│ 1 │ 2 │ 3 │
├─────────┼─────────┼─────────┤
│765432 10│7654 3210│76 543210│
╞══════╤══╧════╤════╧══╤══════╡
│765432│76 5432│7654 32│765432│
├──────┼───────┼───────┼──────┤
│ 1 │ 2 │ 3 │ 4 │
├──────┴───────┴───────┴──────┤
│ Знакоместа 6х8 │
└─────────────────────────────┘
Для печати первого знакомес-
та 6х8 нужно взять байт экрана,
соответствующий первому знако-
месту 8х8, наложить по AND маску
%00000011,
к полученному результату доба-
вить по OR байт из знакогенера-
тора и окончательный результат
переслать на экран в первое зна-
коместо 8х8.
Для печати второго знакомес-
та 6х8:
1. Взять байт знакогенератора.
2. Циклическим сдвигом полу-
чить следующее расположение би-
тов:
54321076
3. На значение, полученное в
п.2, наложить по AND маску:
%00000011
4. Взять байт экрана, соответ-
ствующий первому знакоместу 8х8,
и наложить по AND маску
%11111100
5. Объединить по OR результа-
ты п.3 и п.4 и полученное значе-
ние переслать на экран в первое
знакоместо 8х8.
6. На значение, полученное в
п.2, наложить по AND маску
%11110000
7. Взять байт экрана, соответ-
ствующий второму знакоместу 8х8,
и наложить по AND маску
%00001111
8. Объединить по OR результа-
ты п.6 и п.7 и полученное значе-
ние переслать на экран во вто-
рое знакоместо 8х8.
Для печати третьего знако-
места 6х8:
1. Взять байт знакогенератора.
2. Циклическим сдвигом полу-
чить следующее расположение би-
тов:
32107654
3. На значение, полученное в
п.2, наложить по AND маску:
%00001111
4. Взять байт экрана, соот-
ветствующий второму знакоместу
8х8, и наложить по AND маску
%11110000
5. Объединить по OR результа-
ты п.3 и п.4 и полученное значе-
ние переслать на экран во вто-
рое знакоместо 8х8.
6. на значение, полученное в
п.2, наложить по AND маску
%11000000
7. Взять байт экрана, соот-
ветствующий третьему знакоместу
8х8, и наложить по AND маску
%00111111
8. Объединить по OR результа-
ты п.6 и п.7 и полученное значе-
ние переслать на экран в третье
знакоместо 8х8.
Для печати четвертого знако-
места 6х8:
1. Взять байт знакогенератора.
2. Циклическим сдвигом полу-
чить следующее расположение би-
тов:
10765432
3. На значение, полученное в
п.2, наложить по AND маску:
%00111111
4. Взять байт экрана, соот-
ветствующий третьему знакоместу
8х8, и наложить по AND маску
%11000000
5. Объединить по OR результа-
ты п.3 и п.4 и полученное значе-
ние переслать на экран в третье
знакоместо 8х8.
На этом и закончу. Будет те-
ма для соревнований в разделе
"ЭТЮДЫ". Дойдя до этой стадии, я
решил посмотреть, как делается
печать 42 символов в строке в
серьезных программах и обнару-
жил подобный алгоритм в редакто-
ре ассемблера XAS ((c) Max Pet-
rov) и в текстовом редакторе ZX/
IBM EDITOR ((c) Олег Хохлов).
Желание изобретать велосипед
пропало, а приводить фрагменты
чужих программ не считаю возмож-
ным по этическим соображениям.
ПРОЦЕДУРА УМНОЖЕНИЯ HL=B*C.
(ZX РЕВЮ 96/4-5, стр.69).
Предлагаю вариант процедуры,
который имеет большую длину, но
работает быстрее при умножении
больших чисел (B>15) и не имеет
синдрома нулевой ошибки.
Числа в комментариях озна-
чают: числитель - длина (байт),
знаменатель - время (тактов).
LD L,C; 1/4
LD D,B; 1/4
LD H,0; 2/7
LD E,0; 2/7
LD B,8; 2/7
; ---------
; 8/29
;-----------------------------
LOOP LD A,1; 2/7
AND L; 1/4
JR Z,PASS; 2/7
ADD HL,DE; 1/11
PASS RR H; 2/8
RR L; 2/8
DJNZ LOOP; 2/13+8
; ----------
; 12/472
; или (58*8+8)
;------------------------------
RET ; 1/10
; ==============================
; ИТОГО: 21/511
При значении регистра B от 1
до 15 процедура умножения спосо-
бом многократного сложения (ZX
96/4-5, стр.69) выполняется быс-
трее.
Алгоритм умножения способом
сложений со сдвигами подробно
описан в книге Р.Токхейм "Осно-
вы цифровой электроники", МИР,
1988г., стр. 238-240.
Практическое применение про-
цедры умножения могут найти,
например, при расчете адреса на-
чала строки двумерного массива.
ДОРАБОТКА ПОСЕКТОРНЫХ
ЗАГРУЗЧИКОВ.
(О.Литвинов, ZX РЕВЮ 96/4-5,
стр. 88).
Описан очень досадный эф-
фект при использовании функции 5
интерпретатора TR-DOS, о кото-
ром все знали, но не говорили. Я
с ним столкнулся в 1994 г., ког-
да занимался адаптацией под диск
накопившихся магнитофонных вер-
сий программ. Не обращал на не-
го особого внимания, пока слу-
чайно не увидел при снятой крыш-
ке компьютера, что при этом
происходит с дисководом. Голов-
ка начинает искать неизвестно
что, но, судя по ее поведению,
где-то около 255 дорожки. Голов-
ка упирается в ограничитель, а
шаговый двигатель упорно пытает-
ся двинуть ее еще дальше. Так
можно и юстировку сбить. Борол-
ся я с этим эффектом менее изящ-
ным и быстрым способом, позицио-
нируя головку дисковода на нуле-
вую дорожку перед чтением оче-
редного блока. При этом устра-
няется следствие, но хотелось бы
знать причину.
Может, кто-то из читателей
нашел причину нарушения позицио-
нирования? Насколько я заметил,
проявляется этот эффект в основ-
ном при загрузке программ, име-
ющих следующую структуру: упако-
ванный экран, затем основной ко-
довый блок. После распаковки эк-
рана в 50% случаев происходит
нарушение позиционирования.
А применение загрузчиков,
использующих функцию 5 интерпре-
татора TR-DOS, с объединением
блоков в одном файле, представ-
ляется наиболее удобным для
программистов, думающих об инте-
ресах пользователей. Загрузчик
наиболее компактен и работает на
любой версии TR-DOS. Программу,
построенную таким образом, всег-
да можно восстановить при разру-
шении каталога. BASIC-часть
программы легко найти по байтам
#80,#AA, а рассчитать общее ко-
личество секторов, просмотрев
загрузчик при помощи дискового
монитора типа ADM, не составит
труда даже для начинающих.
МИНИ-ДРАЙВЕР ДИСКОВЫХ ОПЕРАЦИЙ
(ZX РЕВЮ 95/4, стр. 10).
Этот драйвер имеет один ма-
ленький недостаток, приводящий к
большим неудобствам для пользо-
вателей. Работает он только с
дисководом "A", хотя больше по-
ловины пользователей имеют по
крайней мере два дисковода. Если
с его использованием создать
процедуру отгрузки на диск отло-
женного состояния, которая перед
записью не будет выдавать пре-
дупреждения типа "INSERT DISK
INTO DRIVE 'A'", а пользователь
решит немного отдохнуть и загру-
зит игру с дисковода "B", оста-
вив системный диск с результа-
том своего труда в дисководе
"A", то его мысли о разработчи-
ке такой дисковой версии вряд ли
можно будет выразить литератур-
ным языком. Даже если найти мес-
то для размещения сообщений и
заставить пользователя перестав-
лять диски, выглядеть это будет
не очень профессионально.
К тому же драйвер имеет до-
вольно большую длину и требует
для своего размещения неразрыв-
ного участка в памяти. В ре-
зультате оказывается проще адап-
тировать магнитофонную версию
программы с использованием фун-
кций 5 и 6 интерпретатора TR-
DOS. Да и работать она будет на
любом дисководе при любой версии
TR-DOS.
ЧТЕНИЕ ДОРОЖКИ
(ZX РЕВЮ 95/4, стр.56).
Корреспондент упоминает за-
щиту "MICROPROTECTOR", использу-
ющую команду ВГ-93 "чтение до-
рожки". Если при пошаговом про-
хождении Микропротектора посмот-
реть память с адреса загрузки
после ее выполнения, заметно на-
рушение информации. Поэтому в
MICROPROTECTOR'е после чтения
дорожки используется довольно
длинный цикл поиска нужной пос-
ледовательности байтов, располо-
женной на свободном месте в кон-
це дорожки.
А в программе FDU при чтении
дорожки также легко обнаружить
искажение информации через 20-30
байт после начала поля данных.
Использовать напрямую коман-
ду "чтение дорожки" действи-
тельно затруднительно. В книге
А.Ларченко и Н.Родионова "ZX-
SPECTRUM & TR-DOS...", издатель-
ство "ПИТЕР", 1994 г., стр.209,
написано: "В силу некоторых ап-
паратных особенностей Beta
Disk'а при выполнении этой ко-
манды происходит потеря синхро-
низации данных микроконтролле-
ром".
Может, кто нибудь знает, что
нужно исправить в BETA DISK для
того, чтобы не происходило нару-
шение синхронизации?
О ПРЯМОМ ПРОГРАММИРОВАНИИ
КР1818ВГ93
(ZX РЕВЮ 95/2, стр.12)
Интересная идея о прямом
доступе к регистрам ВГ93 путем
отключения ПЗУ. Если это нужно
для личного пользования, можно
просто установить тумблер, от-
ключающий ПЗУ. А информации о
ВГ93 было опубликовано достаточ-
но для написания хоть потреково-
го копировщика, хоть программмы
просмотра и переноса файлов на
дисках разных форматов.
Можно также отключать селек-
тор адреса в дисковом интерфей-
се. При этом появится доступ к
портам контроллера из любого ад-
реса в памяти.