kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
603 wiersze
14 KiB
C
Executable File
603 wiersze
14 KiB
C
Executable File
/*====================================================================
|
|
opcodes_ed.c -> This file executes the ED opcodes.
|
|
|
|
Another prefix that "creates" new instructions. This prefix also
|
|
introduces some undocumented opcodes that we've tried to include
|
|
here. Maybe their implementation it's wrong: if you can find any
|
|
mistake about how we have implemented/interpreted them, please
|
|
let us know.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
Copyright (c) 2000 Santiago Romero Iglesias.
|
|
Email: sromero@escomposlinux.org
|
|
=====================================================================*/
|
|
|
|
/* 8 clock cycles minimum = ED opcode = 4 + 4 */
|
|
|
|
opcode = Z80ReadMem (r_PC);
|
|
r_PC++;
|
|
|
|
switch (opcode)
|
|
{
|
|
case LD_BC_xNNe:
|
|
LOAD_rr_nn (r_BC);
|
|
AddCycles (4 + 4 + 12);
|
|
break;
|
|
case LD_DE_xNNe:
|
|
LOAD_rr_nn (r_DE);
|
|
AddCycles (4 + 4 + 12);
|
|
break;
|
|
case LD_HL_xNNe:
|
|
LOAD_rr_nn (r_HL);
|
|
AddCycles (4 + 4 + 12);
|
|
break;
|
|
case LD_SP_xNNe:
|
|
LOAD_rr_nn (r_SP);
|
|
AddCycles (4 + 4 + 12);
|
|
break;
|
|
|
|
case LD_xNNe_BC:
|
|
STORE_nn_rr (r_BC);
|
|
AddCycles (4 + 4 + 12);
|
|
break;
|
|
case LD_xNNe_DE:
|
|
STORE_nn_rr (r_DE);
|
|
AddCycles (4 + 4 + 12);
|
|
break;
|
|
case LD_xNNe_HL:
|
|
STORE_nn_rr (r_HL);
|
|
AddCycles (4 + 4 + 12);
|
|
break;
|
|
case LD_xNNe_SP:
|
|
STORE_nn_rr (r_SP);
|
|
AddCycles (4 + 4 + 12);
|
|
break;
|
|
|
|
case NEG:
|
|
case ED_5C:
|
|
case ED_74:
|
|
case ED_7C:
|
|
case ED_6C:
|
|
case ED_54:
|
|
case ED_4C:
|
|
case ED_64:
|
|
NEG_A ();
|
|
AddCycles (4 + 4);
|
|
break;
|
|
|
|
case RETI:
|
|
case RETN:
|
|
case ED_65:
|
|
case ED_6D:
|
|
case ED_75:
|
|
case ED_7D:
|
|
case ED_5D:
|
|
case ED_55:
|
|
r_IFF1 = r_IFF2;
|
|
RET_nn ();
|
|
AddCycles (4 + 4 + 6);
|
|
break;
|
|
|
|
case IM_0:
|
|
case ED_4E: /* * IM 0/1 */
|
|
case ED_6E:
|
|
case ED_66:
|
|
regs->IM = 0;
|
|
AddCycles (4 + 4);
|
|
break; /* * IM 0 */
|
|
|
|
|
|
case IM_1:
|
|
case ED_76:
|
|
regs->IM = 1;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
|
|
case IM_2:
|
|
case ED_7E:
|
|
regs->IM = 2;
|
|
AddCycles (4 + 4);
|
|
break;
|
|
|
|
case ED_77:
|
|
case ED_7F:
|
|
AddCycles (4 + 4);
|
|
break; /* * NOP */
|
|
|
|
case OUT_xC_B:
|
|
Z80OutPort (regs, r_BC, r_B);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case OUT_xC_C:
|
|
Z80OutPort (regs, r_BC, r_C);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case OUT_xC_D:
|
|
Z80OutPort (regs, r_BC, r_D);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case OUT_xC_E:
|
|
Z80OutPort (regs, r_BC, r_E);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case OUT_xC_H:
|
|
Z80OutPort (regs, r_BC, r_H);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case OUT_xC_L:
|
|
Z80OutPort (regs, r_BC, r_L);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case OUT_xC_A:
|
|
Z80OutPort (regs, r_BC, r_A);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
/* * OUT (C), 0 */
|
|
case ED_71:
|
|
Z80OutPort (regs, r_BC, 0);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
|
|
case IN_B_xC:
|
|
IN_PORT (r_B, r_BC);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case IN_C_xC:
|
|
IN_PORT (r_C, r_BC);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case IN_D_xC:
|
|
IN_PORT (r_D, r_BC);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case IN_E_xC:
|
|
IN_PORT (r_E, r_BC);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case IN_L_xC:
|
|
IN_PORT (r_L, r_BC);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case IN_H_xC:
|
|
IN_PORT (r_H, r_BC);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case IN_A_xC:
|
|
IN_PORT (r_A, r_BC);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
case IN_F_xC:
|
|
IN_PORT (r_meml, r_BC);
|
|
AddCycles (4 + 4 + 4);
|
|
break;
|
|
|
|
case LD_A_I:
|
|
r_A = regs->I;
|
|
r_F = (r_F & FLAG_C) | sz53_table[r_A] | (regs->IFF2 ? FLAG_V : 0);
|
|
AddCycles (4 + 4 + 1);
|
|
break;
|
|
|
|
case LD_I_A:
|
|
regs->I = r_A;
|
|
AddCycles (4 + 4 + 1);
|
|
break;
|
|
|
|
|
|
case LD_A_R:
|
|
r_A = (regs->R.W & 0x7f) | (regs->R.W & 0x80);
|
|
r_F = (r_F & FLAG_C) | sz53_table[r_A] | (regs->IFF2 ? FLAG_V : 0);
|
|
AddCycles (4 + 4 + 1);
|
|
break;
|
|
|
|
case LD_R_A:
|
|
regs->R.W = r_A;
|
|
AddCycles (4 + 4 + 1);
|
|
break;
|
|
|
|
|
|
case ADC_HL_BC:
|
|
ADC_WORD (r_BC);
|
|
AddCycles (4 + 4 + 4 + 1 + 2);
|
|
break;
|
|
case ADC_HL_DE:
|
|
ADC_WORD (r_DE);
|
|
AddCycles (4 + 4 + 4 + 1 + 2);
|
|
break;
|
|
case ADC_HL_HL:
|
|
ADC_WORD (r_HL);
|
|
AddCycles (4 + 4 + 4 + 1 + 2);
|
|
break;
|
|
case ADC_HL_SP:
|
|
ADC_WORD (r_SP);
|
|
AddCycles (4 + 4 + 4 + 1 + 2);
|
|
break;
|
|
|
|
case SBC_HL_BC:
|
|
SBC_WORD (r_BC);
|
|
AddCycles (4 + 4 + 4 + 1 + 2);
|
|
break;
|
|
case SBC_HL_DE:
|
|
SBC_WORD (r_DE);
|
|
AddCycles (4 + 4 + 4 + 1 + 2);
|
|
break;
|
|
case SBC_HL_HL:
|
|
SBC_WORD (r_HL);
|
|
AddCycles (4 + 4 + 4 + 1 + 2);
|
|
break;
|
|
case SBC_HL_SP:
|
|
SBC_WORD (r_SP);
|
|
AddCycles (4 + 4 + 4 + 1 + 2);
|
|
break;
|
|
|
|
case RRD:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
Z80WriteMem (r_HL, (r_A << 4) | (r_meml >> 4), regs);
|
|
r_A = (r_A & 0xf0) | (r_meml & 0x0f);
|
|
r_F = (r_F & FLAG_C) | sz53p_table[r_A];
|
|
AddCycles (4 + 4 + 10);
|
|
break;
|
|
|
|
case RLD:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
Z80WriteMem (r_HL, (r_meml << 4) | (r_A & 0x0f), regs);
|
|
r_A = (r_A & 0xf0) | (r_meml >> 4);
|
|
r_F = (r_F & FLAG_C) | sz53p_table[r_A];
|
|
AddCycles (4 + 4 + 10);
|
|
break;
|
|
|
|
case LDI:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
r_HL++;
|
|
Z80WriteMem (r_DE, r_meml, regs);
|
|
r_DE++;
|
|
r_BC--;
|
|
r_meml += r_A;
|
|
r_F = (r_F & (FLAG_C | FLAG_Z | FLAG_S)) |
|
|
(r_BC ? FLAG_V : 0) | (r_meml & FLAG_3) |
|
|
((r_meml & 0x02) ? FLAG_5 : 0);
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
case LDIR:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
r_HL++;
|
|
Z80WriteMem (r_DE, r_meml, regs);
|
|
r_DE++;
|
|
r_BC--;
|
|
r_meml += r_A;
|
|
r_F = (r_F & (FLAG_C | FLAG_Z | FLAG_S))
|
|
| (r_meml & FLAG_3) | ((r_meml & 0x02) ? FLAG_5 : 0) ;
|
|
// | (r_BC ? FLAG_V : 0) ;
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
if (r_BC)
|
|
{
|
|
r_PC -= 2;
|
|
AddCycles (5);
|
|
}
|
|
break;
|
|
case LDD:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
r_HL--;
|
|
Z80WriteMem (r_DE, r_meml, regs);
|
|
r_DE--;
|
|
r_BC--;
|
|
r_meml += r_A;
|
|
r_F = (r_F & (FLAG_C | FLAG_Z | FLAG_S)) |
|
|
(r_BC ? FLAG_V : 0) | (r_meml & FLAG_3) |
|
|
((r_meml & 0x02) ? FLAG_5 : 0);
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
|
|
case LDDR:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
Z80WriteMem (r_DE, r_meml, regs);
|
|
r_HL--;
|
|
r_DE--;
|
|
r_BC--;
|
|
r_meml += r_A;
|
|
r_F = (r_F & (FLAG_C | FLAG_Z | FLAG_S))
|
|
| (r_meml & FLAG_3) | ((r_meml & 0x02) ? FLAG_5 : 0) ;
|
|
// | (r_BC ? FLAG_V : 0) ;
|
|
AddCycles (4 + 4 + 4 + 4 + 1);
|
|
if (r_BC)
|
|
{
|
|
r_PC -= 2;
|
|
AddCycles (4);
|
|
}
|
|
break;
|
|
|
|
// I had lots of problems with CPI, INI, CPD, IND, OUTI, OUTD and so...
|
|
// Thanks a lot to Philip Kendall for letting me to take a look to his
|
|
// fuse emulator and allowing me to use their flag routines :-)
|
|
case CPI:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
r_memh = r_A - r_meml;
|
|
r_opl = ((r_A & 0x08) >> 3) |
|
|
(((r_meml) & 0x08) >> 2) | ((r_meml & 0x08) >> 1);
|
|
r_HL++;
|
|
r_BC--;
|
|
r_F = (r_F & FLAG_C) |
|
|
(r_BC ? (FLAG_V | FLAG_N) : FLAG_N) |
|
|
halfcarry_sub_table[r_opl] | (r_memh ? 0 : FLAG_Z) | (r_memh & FLAG_S);
|
|
if (r_F & FLAG_H)
|
|
r_memh--;
|
|
r_F |= (r_memh & FLAG_3) | ((r_memh & 0x02) ? FLAG_5 : 0);
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
case CPIR:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
r_memh = r_A - r_meml;
|
|
r_opl = ((r_A & 0x08) >> 3) |
|
|
(((r_meml) & 0x08) >> 2) | ((r_meml & 0x08) >> 1);
|
|
r_HL++;
|
|
r_BC--;
|
|
r_F = (r_F & FLAG_C) |
|
|
(r_BC ? (FLAG_V | FLAG_N) : FLAG_N) |
|
|
halfcarry_sub_table[r_opl] | (r_memh ? 0 : FLAG_Z) | (r_memh & FLAG_S);
|
|
if (r_F & FLAG_H)
|
|
r_memh--;
|
|
r_F |= (r_memh & FLAG_3) | ((r_memh & 0x02) ? FLAG_5 : 0);
|
|
if ((r_F & (FLAG_V | FLAG_Z)) == FLAG_V)
|
|
{
|
|
AddCycles (5);
|
|
r_PC -= 2;
|
|
}
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
case CPD:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
r_memh = r_A - r_meml;
|
|
r_opl = ((r_A & 0x08) >> 3) |
|
|
(((r_meml) & 0x08) >> 2) | ((r_memh & 0x08) >> 1);
|
|
r_HL--;
|
|
r_BC--;
|
|
r_F = (r_F & FLAG_C) |
|
|
(r_BC ? (FLAG_V | FLAG_N) : FLAG_N) |
|
|
halfcarry_sub_table[r_opl] | (r_memh ? 0 : FLAG_Z) | (r_memh & FLAG_S);
|
|
if (r_F & FLAG_H)
|
|
r_memh--;
|
|
r_F |= (r_memh & FLAG_3) | ((r_memh & 0x02) ? FLAG_5 : 0);
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
case CPDR:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
r_memh = r_A - r_meml;
|
|
r_opl = ((r_A & 0x08) >> 3) |
|
|
(((r_meml) & 0x08) >> 2) | ((r_memh & 0x08) >> 1);
|
|
r_HL--;
|
|
r_BC--;
|
|
r_F = (r_F & FLAG_C) |
|
|
(r_BC ? (FLAG_V | FLAG_N) : FLAG_N) |
|
|
halfcarry_sub_table[r_opl] | (r_memh ? 0 : FLAG_Z) | (r_memh & FLAG_S);
|
|
if (r_F & FLAG_H)
|
|
r_memh--;
|
|
r_F |= (r_memh & FLAG_3) | ((r_memh & 0x02) ? FLAG_5 : 0);
|
|
if ((r_F & (FLAG_V | FLAG_Z)) == FLAG_V)
|
|
{
|
|
AddCycles (5);
|
|
r_PC -= 2;
|
|
}
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
// I/O block instructions by Metalbrain - 14-5-2001
|
|
case IND:
|
|
r_meml = Z80InPort (regs, (r_BC));
|
|
r_memh = 0;
|
|
r_F = (r_F & FLAG_C) | ((r_B) & 0x0f ? 0 : FLAG_H) | FLAG_N;
|
|
(r_B)--;
|
|
r_F |= ((r_B) == 0x7f ? FLAG_V : 0) | sz53_table[(r_B)];
|
|
r_F &= 0xE8;
|
|
Z80WriteMem (r_HL, r_meml, regs);
|
|
r_F |= ((r_meml & 0x80) >> 6);
|
|
r_opl = r_C;
|
|
r_oph = 0;
|
|
r_opl--;
|
|
r_op += r_mem;
|
|
r_oph += (r_oph << 4);
|
|
r_F |= r_oph;
|
|
r_opl = (r_meml & 7) + ((r_C & 7) << 3);
|
|
r_F |= (ioblock_2_table[(r_B)] ^ ioblock_dec1_table[(r_opl)]);
|
|
r_HL--;
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
case INDR:
|
|
r_meml = Z80InPort (regs, (r_BC));
|
|
r_memh = 0;
|
|
r_F = (r_F & FLAG_C) | ((r_B) & 0x0f ? 0 : FLAG_H) | FLAG_N;
|
|
(r_B)--;
|
|
r_F |= ((r_B) == 0x7f ? FLAG_V : 0) | sz53_table[(r_B)];
|
|
r_F &= 0xE8;
|
|
Z80WriteMem (r_HL, r_meml, regs);
|
|
r_F |= ((r_meml & 0x80) >> 6);
|
|
r_opl = r_C;
|
|
r_oph = 0;
|
|
r_opl--;
|
|
r_op += r_mem;
|
|
r_oph += (r_oph << 4);
|
|
r_F |= r_oph;
|
|
r_opl = (r_meml & 7) + ((r_C & 7) << 3);
|
|
r_F |= (ioblock_2_table[(r_B)] ^ ioblock_dec1_table[(r_opl)]);
|
|
r_HL--;
|
|
if (r_B)
|
|
{
|
|
r_PC -= 2;
|
|
AddCycles (5);
|
|
}
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
case INI:
|
|
r_meml = Z80InPort (regs, (r_BC));
|
|
r_memh = 0;
|
|
r_F = (r_F & FLAG_C) | ((r_B) & 0x0f ? 0 : FLAG_H) | FLAG_N;
|
|
(r_B)--;
|
|
r_F |= ((r_B) == 0x7f ? FLAG_V : 0) | sz53_table[(r_B)];
|
|
r_F &= 0xE8;
|
|
Z80WriteMem (r_HL, r_meml, regs);
|
|
r_F |= ((r_meml & 0x80) >> 6);
|
|
r_opl = r_C;
|
|
r_oph = 0;
|
|
r_opl++;
|
|
r_op += r_mem;
|
|
r_oph += (r_oph << 4);
|
|
r_F |= r_oph;
|
|
r_opl = (r_meml & 7) + ((r_C & 7) << 3);
|
|
r_F |= (ioblock_2_table[(r_B)] ^ ioblock_inc1_table[(r_opl)]);
|
|
r_HL++;
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
|
|
case INIR:
|
|
r_meml = Z80InPort (regs, (r_BC));
|
|
r_memh = 0;
|
|
r_F = (r_F & FLAG_C) | ((r_B) & 0x0f ? 0 : FLAG_H) | FLAG_N;
|
|
(r_B)--;
|
|
r_F |= ((r_B) == 0x7f ? FLAG_V : 0) | sz53_table[(r_B)];
|
|
r_F &= 0xE8;
|
|
Z80WriteMem (r_HL, r_meml, regs);
|
|
r_F |= ((r_meml & 0x80) >> 6);
|
|
r_opl = r_C;
|
|
r_oph = 0;
|
|
r_opl++;
|
|
r_op += r_mem;
|
|
r_oph += (r_oph << 4);
|
|
r_F |= r_oph;
|
|
r_opl = (r_meml & 7) + ((r_C & 7) << 3);
|
|
r_F |= (ioblock_2_table[(r_B)] ^ ioblock_inc1_table[(r_opl)]);
|
|
r_HL++;
|
|
if (r_B)
|
|
{
|
|
r_PC -= 2;
|
|
AddCycles (5);
|
|
}
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
case OUTI:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
r_memh = 0;
|
|
r_F = (r_F & FLAG_C) | ((r_B) & 0x0f ? 0 : FLAG_H) | FLAG_N;
|
|
(r_B)--;
|
|
r_F |= ((r_B) == 0x7f ? FLAG_V : 0) | sz53_table[(r_B)];
|
|
r_F &= 0xE8;
|
|
Z80OutPort (regs, r_BC, r_meml);
|
|
r_F |= ((r_meml & 0x80) >> 6);
|
|
r_opl = r_C;
|
|
r_oph = 0;
|
|
r_opl++;
|
|
r_op += r_mem;
|
|
r_oph += (r_oph << 4);
|
|
r_F |= r_oph;
|
|
r_opl = (r_meml & 7) + ((r_C & 7) << 3);
|
|
r_F |= (ioblock_2_table[(r_B)] ^ ioblock_inc1_table[(r_opl)]);
|
|
r_HL++;
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
case OTIR:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
r_memh = 0;
|
|
r_F = (r_F & FLAG_C) | ((r_B) & 0x0f ? 0 : FLAG_H) | FLAG_N;
|
|
(r_B)--;
|
|
r_F |= ((r_B) == 0x7f ? FLAG_V : 0) | sz53_table[(r_B)];
|
|
r_F &= 0xE8;
|
|
Z80OutPort (regs, r_BC, r_meml);
|
|
r_F |= ((r_meml & 0x80) >> 6);
|
|
r_opl = r_C;
|
|
r_oph = 0;
|
|
r_opl++;
|
|
r_op += r_mem;
|
|
r_oph += (r_oph << 4);
|
|
r_F |= r_oph;
|
|
r_opl = (r_meml & 7) + ((r_C & 7) << 3);
|
|
r_F |= (ioblock_2_table[(r_B)] ^ ioblock_inc1_table[(r_opl)]);
|
|
r_HL++;
|
|
if (r_B)
|
|
{
|
|
r_PC -= 2;
|
|
AddCycles (5);
|
|
}
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
|
|
case OUTD:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
r_memh = 0;
|
|
r_F = (r_F & FLAG_C) | ((r_B) & 0x0f ? 0 : FLAG_H) | FLAG_N;
|
|
(r_B)--;
|
|
r_F |= ((r_B) == 0x7f ? FLAG_V : 0) | sz53_table[(r_B)];
|
|
r_F &= 0xE8;
|
|
Z80OutPort (regs, r_BC, r_meml);
|
|
r_F |= ((r_meml & 0x80) >> 6);
|
|
r_opl = r_C;
|
|
r_oph = 0;
|
|
r_opl--;
|
|
r_op += r_mem;
|
|
r_oph += (r_oph << 4);
|
|
r_F |= r_oph;
|
|
r_opl = (r_meml & 7) + ((r_C & 7) << 3);
|
|
r_F |= (ioblock_2_table[(r_B)] ^ ioblock_dec1_table[(r_opl)]);
|
|
r_HL--;
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
case OTDR:
|
|
r_meml = Z80ReadMem (r_HL);
|
|
r_memh = 0;
|
|
r_F = (r_F & FLAG_C) | ((r_B) & 0x0f ? 0 : FLAG_H) | FLAG_N;
|
|
(r_B)--;
|
|
r_F |= ((r_B) == 0x7f ? FLAG_V : 0) | sz53_table[(r_B)];
|
|
r_F &= 0xE8;
|
|
Z80OutPort (regs, r_BC, r_meml);
|
|
r_F |= ((r_meml & 0x80) >> 6);
|
|
r_opl = r_C;
|
|
r_oph = 0;
|
|
r_opl--;
|
|
r_op += r_mem;
|
|
r_oph += (r_oph << 4);
|
|
r_F |= r_oph;
|
|
r_opl = (r_meml & 7) + ((r_C & 7) << 3);
|
|
r_F |= (ioblock_2_table[(r_B)] ^ ioblock_dec1_table[(r_opl)]);
|
|
r_HL--;
|
|
if (r_B)
|
|
{
|
|
r_PC -= 2;
|
|
AddCycles (5);
|
|
}
|
|
AddCycles (4 + 4 + 4 + 4);
|
|
break;
|
|
|
|
// End of Metalbrain's contribution
|
|
|
|
case PREFIX_ED:
|
|
AddCycles (4); /* ED ED xx = 12 cycles min = 4+8 */
|
|
r_PC--;
|
|
break;
|
|
|
|
default:
|
|
// exit(1);
|
|
AddCycles (4 + 4); /* Just a NOP */
|
|
break;
|
|
}
|