Этюды
1. Инкремент 32-разрядного числа
Делается так:
INC (HL),HL
JR Z,$-2
...и всё :) Причём, как видите, процедура
универсальна - для 16/32/64/nn..-разрядных
чисел - если переход через ноль гарантиро-
ванно не происходит. (Именно в таком виде
фрагмент удобен для подсчёта проходов не-
коего куска программы.)
Декремент при тех же условиях реализуе-
тся сложнее:
XOR A
CP (HL)
DEC (HL)
INC HL
JR NC,$-3
Или, если вероятен переход через ноль:
SCF
LD B,4 ;количество байт в числе
LD A,(HL)
SBC A,0
LD (HL),A
INC HL
DJNZ $-5
И инкремент для того же случая:
SCF
LD B,4 ;количество байт в числе
LD A,0
ADC A,(HL)
LD (HL),A
INC HL
DJNZ $-5
Ноль можно занести в C, если его нет в
других регистрах. INC HL в частных случаях
можно заменять на INC L или INC H.
В регистрах же, как вы сами понимаете,
обе операции выглядят ещё проще:
инкремент: декремент:
INC HL LD A,H
LD A,H OR L
OR L DEC HL
JR NZ,$+3 JR NZ,$+3
INC DE DEC DE
2. Как избежать лишних INCBIN'ов
Знаете, как можно в аласме подгрузить
файл одним INCBIN'ом в два разных места? А
то и больше? ;) Мне такое как раз требова-
лось для Pro Tracker'а: плейер у меня на
диске лежит целый, но в памяти он должен
быть разрезан.А делается это с помощью ко-
пирования памяти через фигурные скобки:
ORG куда_копировать,стр_куда_откуда
DISP откуда_копировать
DUP длина/16
DW {$}
DW {$}
DW {$}
DW {$}
DW {$}
DW {$}
DW {$}
DW {$}
EDUP
ENT
Страница памяти "откуда_копировать" и
страница "куда_копировать" должны быть од-
ной и той же страницей "стр_куда_откуда".
Я пробовал все варианты группировки DW:
через DUP&REPEAT/UNTIL, через перечисление
{$},{$+2} и т.д., пробовал менять $ на пе-
ременную, но оказалось,что приведенный ва-
риант самый быстрый. К тому же, он короче,
чем {$},{$+2} ... :) Скорость на 3.5 MHz -
около 1.5 кбайт/с. Для сравнения, скорость
DS - около 8 кбайт/с.
3. Одно важное замечание
Оказалось, способы выравнивания на гра-
ницу параграфа (256 байт),которые я описы-
вал в ZX-Guide, устарели. В новых аласмах
допустима еще более короткая конструкция:
DS .(-$)
Вся её хитрость в том, что DS 0 ничего
не делает :)
Выравнивание на чётный байт в этом слу-
чае записывается так:
DS -$&1
А выравнивание на байт, кратный 8:
DS -$&7
и т.п.
А вот выравнивание на ближайший адрес,
младший байт которого равен #F0:
ORG $+15/256<8+#F0
или
ORG $+15&#FF00+#F0
(в общем случае $+a&#FF00+b, где a=255-b )
4. Контроль памяти при ассемблировании
Вам никогда не приходилось делать в ис-
ходнике контроль переполнения памяти для
программы? Чтобы при превышении размера
программы компиляция выводила на экран ка-
кое-то сообщение? Обычно это делают через
IF, в котором присутствует сравнение. А
сравнение в синтаксисе аласма - это вычи-
тание и проверка старшего бита. Но не
ὀ, как можно было бы подумать, а...
<1&1. Значительно короче :) Автор - Capry.
Теперь, когда наше условие в IF выпол-
нилось (проверить его работоспособность
можно,искусственно удлинив программу каки-
ми-нибудь DS'ами),нужно вывести сообщение.
Это делает DISPLAY. А потом можно (но не
обязательно) и прервать компиляцию - это
сделает директива INCBIN с каким-нибудь
диким названием файла.
А. Кодер 08.03.04