Форум - Время выполнения недокументированных команд процессора Z80.

ZX Review #7-8-9-10
(c) Иван Рощин, г.Москва, 1997

        Время выполнения
   недокументированных команд
         процессора Z80

   В "ZX-РЕВЮ" уже был опублико-
ван ряд статей, посвященных  не-
документированным командам  Z80,
но ни в одной из них я  не  смог
найти упоминания о  времени  вы-
полнения этих команд. Не секрет,
что их  часто  используют  имен-
но для повышения  быстродействия
программы (а также для  уменьше-
ния ее размера и затруднения от-
ладки). Поэтому я решил  опреде-
лить  время  выполнения  опытным
путем, для  чего  была  написана
следующая программа:140.

        ORG     #6000

;Устанавливаем 2-й режим прерываний,
;обработчик будет по адресу #6262:

        DI
        LD      A,#80    ;таблица будет
        LD      I,A      ;по адресу #8000
        LD      HL,#8000 ;заполняем
        LD      (HL),#62 ;таблицу...
        LD      DE,#8001
        LD      BC,#100
        LDIR
        IM      2
        LD      A,#C9    ;заносим код RET,
        LD      (#6262),A;чтобы проц. обр.
                         ;прерываний
                         ;ничего не делала
        LD      HL,0     ;обнулили счетчик
        EI
        HALT             ;ждем прерывания

;Поступил сигнал прерывания, происходит
;следующее:
; - процессор запоминает адрес следующей
;   команды программы в стеке;
; - просматривает ячейку, указанную
;   шиной данных +256, умноженное на
;   содержимое регистра I;
; - передает управление по адресу,
;   содержащемуся в этой ячейке (в данном
;   случае - по адресу #6262).
;
; На это тратится 18 тактов.
;
; - по адресу #6262 сейчас находится
;   команда RET, ее выполнение занимает
;   10 тактов.

;Заменяем эту команду RET на NOP:

        XOR     A          ; 4 такта
        LD      (#6262),A  ; 13
        NOP                ; 4
        NOP  ;задержка     ; 4
        NOP  ;во избежание ; 4
        NOP  ;повторного   ; 4
        NOP  ;захвата      ; 4
        NOP  ;прерывания   ; 4
        NOP                ; 4
        NOP                ; 4
        EI                 ; 4

;Итак, с момента получения сигнала
;прерывания прошел уже 81 такт.
;Теперь начинаем выполнять в цикле
;последовательность команд,
;при каждом выполнении цикла содержимое
;HL увеличивается на 1.

LOOP1   INC     HL         ; 6 тактов

;Здесь находится анализируемая команда:

        NOP

;Если команда влияет на HL, вместо нее
;можно записать последовательность
;PUSH HL: КОМАНДА :POP HL.

        JR      LOOP1      ; 12 тактов

;Таким образом, на каждое выполнение
;цикла будет затрачено 18+t тактов,
;где t - время выполнения анализируемой
;команды.

;Сюда будет передано управление, как
;только поступит следующий импульс
;прерывания.
;В HL будет кол-во выполнений цикла.

END     RET

;**************************************
;Обработчик прерывания:

        ORG     #6262

        NOP

;В процессе выполнения сюда сначала
;ставится RET, а потом NOP. Если выходить
;из обработчика с помощью RET, снова
;попадем в цикл, что совсем не нужно.

        INC     SP
        INC     SP
        IM      1
        EI
        JP      END
2
   Чтобы определить время выпол-
нения какой-либо команды процес-
сора с помощью  этой  программы,
необходимо  подставить   команду
вместо NOP, скомпилировать прог-
рамму и запустить ее из отладчи-
ка STS  с  помощью  команды  [C]
#6000. После  этого  нужно  рас-
смотреть содержимое регистра  HL
(естественно, сама анализируемая
команда не должна влиять на этот
регистр).  Из  текста  программы
ясно, что существует такое соот-
ношение:

        81+(18+t)*x = T

Здесь t - время выполнения  ана-
    лизируемой команды в тактах;
x - число выполнений цикла  (со-
    держимое HL);
T - число тактов между  прерыва-
    ниями.

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

         T = 81+22*x

   Для моего "Пентагона-128" x =
#CB7. После подстановки в форму-
лу получим T = 71691 такт.  Хотя
при таком способе измерения быс-
тродействия  погрешность   может
достигать   времени   выполнения
цикла (в данном случае  22  так-
та), на дальнейшие  расчеты  это
мало повлияет.

   Теперь   попробуем   измерить
время  выполнения   какой-нибудь
команды,  например, LD  IX,#1234
(истинное  время  выполнения  14
тактов). Подставляем  ее  вместо
команды NOP и запускаем програм-
му, как и в  предыдущем  случае.
После этого время выполнения на-
ходится по формуле:

             T-81
        t = ────── - 18
              x

   Для моего компьютера x =#8BE,
тогда  t = 13,9973.  Как  видим,
при таком способе измерений дос-
тигается неплохая точность.
   Теперь  я  приведу  найденные
этим способом оценки времени вы-
полнения некоторых  недокументи-
рованных команд:

    ┌──────────────┬──────────┬─────────────┬──────────────┐
    │Мнемоника     │Код       │Содержимое HL│Время в тактах│
    ├──────────────┼──────────┼─────────────┼──────────────┤
    │LD HX,N       │DD 26 N   │ #9A5        │11            │
    │LD LY,N       │FD 2E N   │ #9A5        │11            │
    │LD HX,A       │DD 67     │ #AC2        │8             │
    │LD LX,LX      │DD 6D     │ #AC2        │8             │
    │ADD A,HX      │DD 84     │ #AC2        │8             │
    │SLI A         │CB 37     │ #AC2        │8             │
    │SLI (HL)      │CB 36     │ #87A        │15            │
    │SLI A,(IX+S)  │DD CB S 37│ #6D3        │23            │
    │SRL A,(IX+S)  │DD CB S 3F│ #6D3        │23            │
    │SET 0,A,(IX+S)│DD CB S C7│ #6D3        │23            │
    │INF           │ED 70     │ #953        │12            │
    │OUT (C),*     │ED 71     │ #953        │12            │
    └──────────────┴──────────┴─────────────┴──────────────┘

   Все команды, которые  получа-
ются с помощью  добавления  пре-
фиксов #DD и #FD, в том числе  и
недокументированные, выполняются
на 4 такта дольше, чем те же ко-
манды без префикса, а регистр  R
при их выполнении  дополнительно
увеличивается на 1. Это не каса-
ется команд с индексной  адреса-
цией, таких как LD A,(IX+S).
   Команда SLI выполняется с та-
кой  же  скоростью, как  команды
SRL, SRA и SLA.
   Выполнение команд, помещающих
результат кроме  ячейки  памяти,
адресуемой IX или IY, в регистр,
занимает  столько  же   времени,
сколько и для  обычных вариантов
этих команд.
   Команды INF и  OUT (C),*  вы-
полняются  так же быстро, как  и
другие   команды   ввода/вывода,
т.е. 12 тактов.

          *   *   *