Что означает IM0/1 в декодировании z80.info?

Я сейчас пишу (еще один) симулятор Z80. Я использую страницу декодирования на сайте z80.info.

В разделе с таблицами поиска/разборки написано, что для индексов 1 и 5 режим прерывания - IM0/1. На эту таблицу ссылаются из инструкции IM (ED) X=1, Z=6.

Что именно означает IM0/1?

Я знаю, что это не официальная инструкция, но я также пытаюсь поддерживать недокументированные инструкции.


person obiwanjacobi    schedule 11.09.2016    source источник


Ответы (2)


Как найдено здесь, цитата из Gerton Lunter:

Инструкции ED 4E и ED 6E являются эквивалентами IM 0: когда FF была помещена на шину (физически) во время прерывания, Спектрум продолжал нормально работать, тогда как когда на шину была помещена EF (RST 28h), он просто разбился. как это происходит в том случае, когда Z80 находится в официальном режиме прерывания 0. В IM 1 Z80 просто выполняет RST 38h (код операции FF), независимо от того, что находится на шине.

Так что это в значительной степени означает IM 0, и я не уверен, откуда взялось часто встречающееся /1.

person harold    schedule 11.09.2016
comment
/1 указывает, что это может быть либо IM 0, либо IM 1. - person Ignacio Vazquez-Abrams; 11.09.2016
comment
@ IgnacioVazquez-Abrams, ну, это то, что я раньше думал, но это не то, как на самом деле ведет себя эта инструкция, согласно всему, что я действительно могу найти об этом. - person harold; 11.09.2016
comment
Я предполагаю, что это означает: изначально был протестирован кем-то с машиной, которая не загружала шину. Поэтому тестер не мог определить, в какой режим прерывания он вошел, и обязательно должен был неопределенно документировать операцию, и это широко распространялось. Гертон, кажется, обнаружил, что они определенно являются IM 0. Таким образом, они IM 0, но все еще могут быть задокументированы как 1/0, потому что долгое время мода была неизвестна. - person Tommy; 12.09.2016
comment
Насколько надежной будет проверка этого на спектре? Я имею в виду, может ли ULA спектра вмешиваться в поведение приема и обработки прерывания и, следовательно, вызывать его сбой? - person obiwanjacobi; 14.09.2016
comment
@Tommy Думаю, я согласен, поскольку IM0/1 являются дубликатами IM0, поэтому я предполагаю, что их не было в исходной документации, и они были обнаружены только позже ... без точного знания поведения в то время ... - person Spektre; 13.02.2020

IM0/1/2 — это инструкции, устанавливающие ЦП Z80 в режим прерывания 0/1/2. Каждый режим обрабатывает маскируемые прерывания по-разному. В свои годы я использую те, но IIRC:

  1. IM0

    выполняет opc, размещенный на шине данных внешним аппаратным обеспечением

  2. IM1

    вызывает фиксированный ISR на 38h

  3. IM2

    вызывает ISR из таблицы точек входа ISR, которая находится там, где i точки регистра

Вот соответствующий код прерывания C++, извлеченный из моего эмулятора:

//---------------------------------------------------------------------------
void Z80::_reset()
    {
    im=0;
    iff1=0;
    iff2=0;
    reg.r16.pc =0x0000;
    reg.r16.af =0xFFFF;
    reg.r16.bc =0xFFFF;
    reg.r16.de =0xFFFF;
    reg.r16.hl =0xFFFF;
    reg.r16.ix =0xFFFF;
    reg.r16.iy =0xFFFF;
    reg.r16.ir =0xFFFF;
    reg.r16.sp =0xFFFF;
    reg.r16._af=0xFFFF;
    reg.r16._bc=0xFFFF;
    reg.r16._de=0xFFFF;
    reg.r16._hl=0xFFFF;
    reg.r16.alu=0xFFFF;
    reg.r16.mem=0xFFFF;
    reg.r16.io =0xFFFF;
    reg.r16.nn =0xFFFF;
    time=0; time0=0; dtime=0;
    busrq=false;
    busack=false;
    }
//---------------------------------------------------------------------------
void Z80::_int()
    {
    if (!_enable_int) return;
    if (!iff1) return;
    if (actual->ins==_z80_ins_HALT) reg.r16.pc+=actual->size;
    if ((actual->ins==_z80_ins_EI)||(actual->ins==_z80_ins_DI)) execute();

    iff1=0;
    iff2=0;

    if (im==0)
        {
        // execute instruction on databus db from peripherials
        mc=0;
        actual=&ins_int0;
        time+=actual->mc[mc]; mc++;     // fetch INT
        BYTE db[4];
        db[0]=db8;
        db[1]=db8;
        db[2]=db8;
        db[3]=db8;
        execute(db);
        }
    else if (im==1)
        {
        mc=0;
        actual=&ins_int1;
        time+=actual->mc[mc]; mc++;     // fetch INT
        _push(reg.r16.pc);
        reg.r16.pc=0x0038;              // fixed vector 38h
        }
    else if (im==2)
        {
        mc=0;
        actual=&ins_int2;
        time+=actual->mc[mc]; mc++;     // fetch INT
        _push(reg.r16.pc);

        union { BYTE db[2]; WORD dw; } ubw;
        ubw.db[1]=reg.r8.i;             // H
        ubw.db[0]=db8;                  // L
        reg.r16.pc=_readw(ubw.dw);      // vector from mem[i+db8]
        }
    }
//---------------------------------------------------------------------------
void Z80::_nmi()
    {
    if (actual->ins==_z80_ins_HALT) reg.r16.pc+=actual->size;
    if ((actual->ins==_z80_ins_EI)||(actual->ins==_z80_ins_DI)) execute();

    iff2=iff1;      // iff2 ide do flagov po ld a,i alebo ld a,r
    iff1=0;

    mc=0;
    actual=&ins_nmi;
    time+=actual->mc[mc]; mc++;     // fetch NMI
    _push(reg.r16.pc);
    reg.r16.pc=0x0066;              // fixed vector 66h
    }
//---------------------------------------------------------------------------

Вот все инструкции IM по порядку, извлеченные отсюда Какова правильная реализация аппаратной эмуляции?:

opc      T0 T1 MC1   MC2   MC3   MC4   MC5   MC6   MC7   mnemonic
ED46     08 00 M1R 4 M1R 4 ... 0 ... 0 ... 0 ... 0 ... 0 IM0
ED4E     08 00 M1R 4 M1R 4 ... 0 ... 0 ... 0 ... 0 ... 0 IM0
ED56     08 00 M1R 4 M1R 4 ... 0 ... 0 ... 0 ... 0 ... 0 IM1
ED5E     08 00 M1R 4 M1R 4 ... 0 ... 0 ... 0 ... 0 ... 0 IM2
ED66     08 00 M1R 4 M1R 4 ... 0 ... 0 ... 0 ... 0 ... 0 IM0
ED6E     08 00 M1R 4 M1R 4 ... 0 ... 0 ... 0 ... 0 ... 0 IM0
ED76     08 00 M1R 4 M1R 4 ... 0 ... 0 ... 0 ... 0 ... 0 IM1
ED7E     08 00 M1R 4 M1R 4 ... 0 ... 0 ... 0 ... 0 ... 0 IM2

Как видите, это:

IM value: 0  0  1 2 0  0  1 2

И ваша связанная страница:

IM value: 0 0/1 1 2 0 0/1 1 2

поэтому я ожидаю, что это просто означает, как кодируется opc, но вы правы, таблицы не очень очевидны.

IM0/1 являются дубликатами IM0, поэтому я предполагаю, что их не было в исходной документации, и они были обнаружены только позже ... без точного знания поведения в то время вашей таблицы был создан... Существует множество изначально недокументированных (секретных) инструкций, поэтому, если ваш источник информации не содержит их точно, возможно, вам не следует его использовать и перейти к более качественным документам, чтобы избежать проблем и несовместимостей в будущем...

person Spektre    schedule 13.02.2020