0

我正在编写(又一个)Z80 模拟器。我正在使用z80.info 站点上的解码页面

在查找/分解表的部分中,它说对于索引 1 和 5,中断模式是 IM0/1。该表参照 IM 指令 (ED) X=1, Z=6。

IM0/1 到底是什么意思?

我知道这不是官方说明,但我也在努力支持无证说明。

4

2 回答 2

2

如此所见,引用 Gerton Lunter 的话:

指令 ED 4E 和 ED 6E 相当于 IM 0:当 FF 在中断时(物理上)放在总线上时,Spectrum 继续正常执行,而当 EF(RST 28h)放在总线上时它崩溃了,只是就像 Z80 处于官方中断模式 0 时那样。在 IM 1 中,Z80 只执行 RST 38h(操作码 FF),无论总线上有什么。

所以它几乎意味着IM 0,我不确定常见的/1来自哪里。

于 2016-09-11T13:08:37.330 回答
0

IM0/1/2 是设置Z80 CPU int中断模式的指令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/1IM0的副本,所以我猜它们不在原始文档中,只是在后来才被发现......在创建表时没有确切的行为知识......有很多最初没有记录的(秘密) 说明,因此如果您的信息来源未准确包含它们,也许您不应该使用它并转向更好的文档以避免将来出现问题和不兼容性......

于 2020-02-13T16:34:25.447 回答