Ну вот эти, действительно незадокументированы.
А клоны команд по кодам ED XX - я не считаю недок. Это издержки неполной дешифрации, а в Z-180 280 по кодам "двойников" появились новые команды. И ED 00-3F задействовали.
Вид для печати
http://freestuff.grok.co.uk/rom-dis/csrd-rtf.zip
:)
То-то я смотрю, что мне IX понадобился когда я писал 42-символьный редактор, а оказывается, я не сообразил просто - если есть редактор, значит я уже пишу язык высокого уровня! Все гениальное просто. :)
Предложенная процедура весьма специфична.
Во-первых ПЗУ. Здесь применить мета-программирование не получится. Плюс афаик, совсем не приветствуется использование ячеек памяти ОЗУ для хранения каких-либо данных. Завуалированный переход от фон-неймана к гарварду..
Во-вторых, загрузка и запись на ленту не требуют быстродействия. Например задержка LD-DELAY может, IIRC, варьиороваться ~ от 70 до 500 тактов. В связи с этим оптимизировать тут можно только память. А судя по объединению LOAD и VERIFY память очень даже экономили. Несмотря на то, что в конце 16к осталось много места.
Для оптимизации в любом случае придется переписать процедуру.
Однако это есть еще один пример подходящей для использования индексных регистров задачи, которая не есть язык высокого уровня и не использует шлобальное пространство имен. В LB-BYTES/SA-BYTES IX используется как альтернатива HL - указатель текущей ячейки памяти, а сам HL - как пара обычных 8-битных РОН. А вот в SAVE-ETC IX используется как полноценный индексный регистр в динамической памяти, и используется грамотно и красиво. Так что IX нужен, кто не умеет использовать - подтягивайтесь, учитесь. Меня он сильно выручает когда не хватает регистров и не хочется писать в стек.
Гм... Чего это я завелся-то... Никто никому же не запрещает считать, что по-настоящему IX и IY нужны только для поддержки ЯВУ, а использование их в других целях - изврат, непрофессионализм, непотребный расход памяти и/или тактов и признак лоха.
Индексная адресация - мощное средство для поддержки объектно-ориентированного программирования. Да, объектно-ориентированно можно программировать и на ассемблере. Тут уже говорили о структурах - это частный случай объектов.
Когда программа должна обслуживать одновременно много однотипных объектов - тогда и нужна индексная адресация. Например, она часто используется в музыкальных плеерах. Почти все AY-, биперные и цифровые плееры ее используют. В музыкальном плеере объект - это состояние канала. Поскольку каналы однотипные, то логично их обслуживать одной программой. А поскольку состояние каждого канала занимает несколько байт - то естественно использование индексной адресации. Подпрограммам обслуживания канала в одном из индексных регистров передается адрес в памяти, где хранится состояние этого канала. Подпрограммы обращаются к состоянию канала только посредством индексной адресации. При изменении логики работы плеера нужно менять меньше кода, чем если бы подпрограммы обслуживания каналов не использовали индексной адресации, а дублировались для каждого канала. Также достигается универсальность: одни и те же подпрограммы могут обслуживать любое количество каналов, ограниченное только объемом памяти под состояние.
В играх тоже часто возникает необходимость обслуживать одновременно несколько однотипных объектов. Например, это могут быть монстры и другие независимые персонажи. Если состояние каждого объекта занимает больше, чем два-три байта - то и здесь естественным и выгодным в плане скорости является использование индексной адресации.
Операционные системы работают с объектами. Если одновременно открыто несколько файлов - то состояние каждого файла (FCB) должно храниться где-то в памяти, а подпрограммы работы с этим состояниям естественно используют индексную адресацию. Кроме файлов, операционные системы работают со многими другими объектами, такими как потоки (Threads), объекты синхронизации (Event, Mutex, Semaphor) и др.
Менеджеры окон работают с окнами - это тоже объекты. И даже когда я писал свой первый менеджер окон - то использовал в нем индексную адресацию, хоть я тогда и не знал точно, что это такое - "объектно-ориентированное программирование".
Современная тенденция такова, что индексная адресация добавляется в те микроконтроллеры, где ее раньше не было. Например, новые 8-битные микроконтроллеры семейства PIC16 и даже "маленькие" PIC12 в последние годы получили новые команды индексной адресации, что существенно расширяет возможности этих контроллеров.
В этом свете удалять индексную адресацию оттуда, где она уже была - верх безумия.
Наличие двух индексных регистров тоже важно, так как позволяет работать одновременно с двумя объектами. Это важно в тех случаях, когда происходит взаимодействие объектов. Если бы был только один индексный регистр - то для реализации взаимодействия объектов его либо приходилось бы постоянно переключать с одного объекта на другой, либо копировать состояние одного из объектов. Обе названные альтернативы вызывают лишние затраты процессорного времени.
Вопрос не о полезности индексной адресации, она безусловно полезна и без всякого ООП (которое я, кстати, очень не люблю, но это дело вкуса). Вопрос о корявости индексной адресации и ее тормознутости в Z80. Понятно, что добавлена она была в процессор, как надстройка, посему ни с точки зрения экономии места, ни с точки зрения скорости не дает особых преимуществ относительно ее реализации несколькими командами.
В том же процессоре 6502, она заложена изначално и очень быстра и экономична.
Вот.
Тут дело не во вкусе, а в необходимости. Вот представь себе: игра, в ней враги, их много, и у каждого свое состояние. Как писать код, обслуживающий врагов, без ООП (в явном или неявном виде)?
Какие другие парадигмы программирования ты используешь? Вот, например, из этого списка:
http://ru.wikipedia.org/wiki/%D0%9F%...BD%D0%B8%D1%8F
Позволь не согласиться. Если твоя программа работает с некоторой структурой данных, причем доступ к ее членам происходит не последовательно - то индексная адресация существенно быстрее, чем ее замена косвенной адресацией. Так, например, команда:
LD A,(IX+n) занимает 3 байта и выполняется за 19 тактов, тогда как ее замена в общем случае (без ограничений на расположение структуры в памяти) требует двухбайтового сложения:
LD BC,n ; 10 тактов
ADD HL,BC ; 11 тактов
LD A,(HL) ; 7 тактов
Всего 5 байт и 28 тактов, места больше на 67%, по времени дольше на 47%, к тому же, требуются две хорошие регистровые пары (HL,BC), тогда как при использовании индексной адресации они свободны.
Можно ли было сделать лучше? Да, но ненамного. Сохраняя общую структуру Z80, теоретически можно убрать только префикс (DD/FD) и связанные с ним 4 такта. Остальные 19-4=15 тактов неизбежно останутся: они нужны для выборки кода команды, смещения, 16-битного сложения и обращения в нужную ячейку памяти.
Быстра и экономична? Это смотря с чем сравнивать. Учитывая, что у 6502 нет 16-битных регистров и 16-битного сложения, затраты на "обход" косвенной адресации очень значительны. А по машинным циклам, думаю, получается примерно то же самое. В самом деле, для выполнения команды 6502:
LDA (0x36),Y
требуется:
1) считать код команды (1 байт)
2) считать адрес косвенного обращения (1 байт)
3) считать байт по адресу 0x36 (младший байт базового адреса обращения)
4) считать байт по адресу 0x37 (старший байт базового адреса обращения)
5) 16-битное сложение базового адреса обращения и индексного регистра (как правило, 2 машинных цикла)
6) считать содержимое памяти по адресу обращения.
Итого 7 машинных циклов - против 5 у Z80. Ну или ладно, зачтем Z80 6 циклов, потому что один из них длинный (5 тактов). Что-то не вижу большого выигрыша.
---------- Post added at 18:29 ---------- Previous post was at 18:21 ----------
Добавлю. Приведенная выше косвенно-индексная адресация требует, при обращении к элементам структуры в произвольном порядке, установки регистра Y каждый раз перед обращением, что еще больше повышает затраты.
Если же вести речь о простой индексной адресации вида:
LDA addr,X
то такая индексная адресация не совсем полноценная, потому что индексный регистр однобайтовый. Это не позволяет хранить структуру в произвольном месте памяти: подпрограммы ее обслуживания должны хотя бы приблизительно знать ее местонахождение.
Я видел хитрые приемы построения программ для организации массива структур с использованием простой индексной адресации. Эти приемы накладывают на программу существенные ограничения. Универсальность кода страдает очень сильно. Впрочем, для игр Atari или NES этого было вполне достаточно. Я анализировал атариевский плеер музыки - именно там использовались эти приемы. Музыка, 4 канала - и известно, что больше не будет. Тогда, конечно, ограничения индексной адресации не играют большой роли.