377 lines
6.7 KiB
C
377 lines
6.7 KiB
C
|
/*
|
||
|
* Copyright (C) 1996-1998 Szeredi Miklos
|
||
|
* Email: mszeredi@inf.bme.hu
|
||
|
*
|
||
|
* 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. See the file COPYING.
|
||
|
*
|
||
|
* 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.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#ifndef NO_OPDEF
|
||
|
#include "z80_def.h"
|
||
|
#include "z80_op1.h"
|
||
|
#endif
|
||
|
|
||
|
OPDEF(nop, 0x00)
|
||
|
{
|
||
|
ENTIME(4);
|
||
|
}
|
||
|
|
||
|
OPDEF(ex_af_afb, 0x08)
|
||
|
{
|
||
|
register byte *ptmp;
|
||
|
|
||
|
ptmp = DANM(br)[ZI_AF].p;
|
||
|
DANM(br)[ZI_AF].p = DANM(nr)[ZI_AF].p;
|
||
|
DANM(nr)[ZI_AF].p = ptmp;
|
||
|
|
||
|
ENTIME(4);
|
||
|
}
|
||
|
|
||
|
OPDEF(djnz_e, 0x10)
|
||
|
{
|
||
|
if(!--RB) {
|
||
|
PC++;
|
||
|
ENTIME(8);
|
||
|
}
|
||
|
else {
|
||
|
PC += IPCS; PC++;
|
||
|
ENTIME(13);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
OPDEF(jr_e, 0x18)
|
||
|
{
|
||
|
PC += IPCS; PC++;
|
||
|
ENTIME(12);
|
||
|
}
|
||
|
|
||
|
#define JR_CC_E(ccn, cc, n) \
|
||
|
OPDEF(jr_ ## ccn ## _e, 0x20+n*8) \
|
||
|
{ \
|
||
|
if(!(cc)) { \
|
||
|
PC++; \
|
||
|
ENTIME(7); \
|
||
|
} \
|
||
|
else { \
|
||
|
PC += IPCS; PC++; \
|
||
|
ENTIME(12); \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
JR_CC_E(nz, !TESTZF, 0)
|
||
|
JR_CC_E(z, TESTZF, 1)
|
||
|
JR_CC_E(nc, !TESTCF, 2)
|
||
|
JR_CC_E(c, TESTCF, 3)
|
||
|
|
||
|
|
||
|
#define LD_RR_NN(rrn, rr, n) \
|
||
|
OPDEF(ld_ ## rrn ## _nn, 0x01+n*0x10) \
|
||
|
{ \
|
||
|
FETCHD(rr); \
|
||
|
ENTIME(10); \
|
||
|
}
|
||
|
|
||
|
LD_RR_NN(bc, BC, 0)
|
||
|
LD_RR_NN(de, DE, 1)
|
||
|
LD_RR_NN(hl, HL, 2)
|
||
|
LD_RR_NN(sp, SP, 3)
|
||
|
|
||
|
#define DADD(rr1, rr2) \
|
||
|
register dbyte dtmp; \
|
||
|
register int idx; \
|
||
|
dtmp = rr1; \
|
||
|
rr1 = dtmp + rr2; \
|
||
|
idx = DIDXCALC(dtmp, rr2, rr1); \
|
||
|
SETFLAGS(CF | NF | HF, TAB(addf_tbl)[idx] & (CF | HF))
|
||
|
|
||
|
|
||
|
#define ADD_RR_RR(rrn1, rr1, rrn2, rr2, n) \
|
||
|
OPDEF(add_## rrn1 ## _ ## rrn2, 0x09+n*0x10) \
|
||
|
{ \
|
||
|
DADD(rr1, rr2); \
|
||
|
ENTIME(11); \
|
||
|
}
|
||
|
|
||
|
ADD_RR_RR(hl, HL, bc, BC, 0)
|
||
|
ADD_RR_RR(hl, HL, de, DE, 1)
|
||
|
ADD_RR_RR(hl, HL, hl, HL, 2)
|
||
|
ADD_RR_RR(hl, HL, sp, SP, 3)
|
||
|
|
||
|
#define INC_RR(rrn, rr, n) \
|
||
|
OPDEF(inc_ ## rrn, 0x03+n*0x10) \
|
||
|
{ \
|
||
|
rr++; \
|
||
|
ENTIME(6); \
|
||
|
}
|
||
|
|
||
|
INC_RR(bc, BC, 0)
|
||
|
INC_RR(de, DE, 1)
|
||
|
INC_RR(hl, HL, 2)
|
||
|
INC_RR(sp, SP, 3)
|
||
|
|
||
|
#define DEC_RR(rrn, rr, n) \
|
||
|
OPDEF(dec_ ## rrn, 0x0B+n*0x10) \
|
||
|
{ \
|
||
|
rr--; \
|
||
|
ENTIME(6); \
|
||
|
}
|
||
|
|
||
|
DEC_RR(bc, BC, 0)
|
||
|
DEC_RR(de, DE, 1)
|
||
|
DEC_RR(hl, HL, 2)
|
||
|
DEC_RR(sp, SP, 3)
|
||
|
|
||
|
OPDEF(ld_ibc_a, 0x02)
|
||
|
{
|
||
|
PUTMEM(BC, BCP, RA);
|
||
|
ENTIME(7);
|
||
|
}
|
||
|
|
||
|
OPDEF(ld_ide_a, 0x12)
|
||
|
{
|
||
|
PUTMEM(DE, DEP, RA);
|
||
|
ENTIME(7);
|
||
|
}
|
||
|
|
||
|
#define LD_INN_RR(rrn, rr) \
|
||
|
OPDEF(ld_inn_ ## rrn, 0x22) \
|
||
|
{ \
|
||
|
register dbyte dtmp; \
|
||
|
FETCHD(dtmp); \
|
||
|
DWRITE(dtmp, rr); \
|
||
|
ENTIME(16); \
|
||
|
}
|
||
|
|
||
|
LD_INN_RR(hl, HL)
|
||
|
|
||
|
|
||
|
OPDEF(ld_inn_a, 0x32)
|
||
|
{
|
||
|
register dbyte dtmp;
|
||
|
FETCHD(dtmp);
|
||
|
WRITE(dtmp, RA);
|
||
|
ENTIME(13);
|
||
|
}
|
||
|
|
||
|
OPDEF(ld_a_ibc, 0x0A)
|
||
|
{
|
||
|
RA = *BCP;
|
||
|
ENTIME(7);
|
||
|
}
|
||
|
|
||
|
OPDEF(ld_a_ide, 0x1A)
|
||
|
{
|
||
|
RA = *DEP;
|
||
|
ENTIME(7);
|
||
|
}
|
||
|
|
||
|
|
||
|
#define LD_RR_INN(rrn, rr) \
|
||
|
OPDEF(ld_ ## rrn ## _inn, 0x2A) \
|
||
|
{ \
|
||
|
register dbyte dtmp; \
|
||
|
FETCHD(dtmp); \
|
||
|
rr = DREAD(dtmp); \
|
||
|
ENTIME(16); \
|
||
|
}
|
||
|
|
||
|
LD_RR_INN(hl, HL)
|
||
|
|
||
|
|
||
|
OPDEF(ld_a_inn, 0x3A)
|
||
|
{
|
||
|
register dbyte dtmp;
|
||
|
FETCHD(dtmp);
|
||
|
RA = READ(dtmp);
|
||
|
ENTIME(13);
|
||
|
}
|
||
|
|
||
|
|
||
|
#define INC(r) \
|
||
|
r++; \
|
||
|
SETFLAGS(SF | ZF | PVF | B3F | B5F, TAB(incf_tbl)[r])
|
||
|
|
||
|
|
||
|
|
||
|
#define INC_R(rn, r, n) \
|
||
|
OPDEF(inc_ ## rn, 0x04+n*8) \
|
||
|
{ \
|
||
|
INC(r); \
|
||
|
ENTIME(4); \
|
||
|
}
|
||
|
|
||
|
INC_R(b, RB, 0)
|
||
|
INC_R(c, RC, 1)
|
||
|
INC_R(d, RD, 2)
|
||
|
INC_R(e, RE, 3)
|
||
|
INC_R(h, RH, 4)
|
||
|
INC_R(l, RL, 5)
|
||
|
INC_R(a, RA, 7)
|
||
|
|
||
|
|
||
|
OPDEF(inc_ihl, 0x34)
|
||
|
{
|
||
|
MODMEM(INC);
|
||
|
ENTIME(11);
|
||
|
}
|
||
|
|
||
|
|
||
|
#define DEC(r) \
|
||
|
r--; \
|
||
|
SETFLAGS(SF | ZF | PVF | B3F | B5F, TAB(decf_tbl)[r])
|
||
|
|
||
|
|
||
|
#define DEC_R(rn, r, n) \
|
||
|
OPDEF(dec_ ## rn, 0x05+n*8) \
|
||
|
{ \
|
||
|
DEC(r); \
|
||
|
ENTIME(4); \
|
||
|
}
|
||
|
|
||
|
DEC_R(b, RB, 0)
|
||
|
DEC_R(c, RC, 1)
|
||
|
DEC_R(d, RD, 2)
|
||
|
DEC_R(e, RE, 3)
|
||
|
DEC_R(h, RH, 4)
|
||
|
DEC_R(l, RL, 5)
|
||
|
DEC_R(a, RA, 7)
|
||
|
|
||
|
|
||
|
OPDEF(dec_ihl, 0x35)
|
||
|
{
|
||
|
MODMEM(DEC);
|
||
|
ENTIME(11);
|
||
|
}
|
||
|
|
||
|
#define LD_R_N(rn, r, n) \
|
||
|
OPDEF(ld_ ## rn ## _n, 0x06+n*8) \
|
||
|
{ \
|
||
|
r = *PCP; \
|
||
|
PC++; \
|
||
|
ENTIME(7); \
|
||
|
}
|
||
|
|
||
|
LD_R_N(b, RB, 0)
|
||
|
LD_R_N(c, RC, 1)
|
||
|
LD_R_N(d, RD, 2)
|
||
|
LD_R_N(e, RE, 3)
|
||
|
LD_R_N(h, RH, 4)
|
||
|
LD_R_N(l, RL, 5)
|
||
|
LD_R_N(a, RA, 7)
|
||
|
|
||
|
|
||
|
OPDEF(ld_ihl_n, 0x36)
|
||
|
{
|
||
|
PUTMEM(HL, HLP, *PCP);
|
||
|
PC++;
|
||
|
ENTIME(10);
|
||
|
}
|
||
|
|
||
|
OPDEF(rlca, 0x07)
|
||
|
{
|
||
|
register byte btmp;
|
||
|
btmp = (RA & 0x80) >> 7;
|
||
|
SETFLAGS(HF | NF | CF, btmp);
|
||
|
RA = (RA << 1) | btmp;
|
||
|
ENTIME(4);
|
||
|
}
|
||
|
|
||
|
OPDEF(rrca, 0x0F)
|
||
|
{
|
||
|
register byte btmp;
|
||
|
btmp = (RA & 0x01);
|
||
|
SETFLAGS(HF | NF | CF, btmp);
|
||
|
if(btmp) {
|
||
|
RA = (RA >> 1) | 0x80;
|
||
|
ENTIME(4);
|
||
|
}
|
||
|
else {
|
||
|
RA >>= 1;
|
||
|
ENTIME(4);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
OPDEF(rla, 0x17)
|
||
|
{
|
||
|
register byte btmp;
|
||
|
btmp = RA & 0x80;
|
||
|
RA = (RA << 1) | (RF & CF);
|
||
|
SETFLAGS(HF | NF | CF, btmp >> 7);
|
||
|
ENTIME(4);
|
||
|
}
|
||
|
|
||
|
OPDEF(rra, 0x1F)
|
||
|
{
|
||
|
register byte btmp;
|
||
|
btmp = TESTCF;
|
||
|
SETFLAGS(HF | NF | CF, RA & 0x01);
|
||
|
if(btmp) {
|
||
|
RA = (RA >> 1) | 0x80;
|
||
|
ENTIME(4);
|
||
|
}
|
||
|
else {
|
||
|
RA >>= 1;
|
||
|
ENTIME(4);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
OPDEF(daa, 0x27)
|
||
|
{
|
||
|
register int flag;
|
||
|
flag = RF;
|
||
|
|
||
|
if(!TESTNF) {
|
||
|
if(flag & CF) RA += 0x60;
|
||
|
else if(RA > 0x99) RA += 0x60, flag |= CF;
|
||
|
|
||
|
if(flag & HF) RA += 0x06;
|
||
|
else if((RA & 0x0F) > 9) RA += 0x06, flag |= HF;
|
||
|
}
|
||
|
else {
|
||
|
if(flag & CF) RA -= 0x60;
|
||
|
else if(RA > 0x99) RA -= 0x60, flag |= CF;
|
||
|
|
||
|
if(flag & HF) RA -= 0x06;
|
||
|
else if((RA & 0x0F) > 9) RA -= 0x06, flag |= HF;
|
||
|
}
|
||
|
flag = (flag & ~(SF | ZF | PVF | B3F | B5F)) | TAB(orf_tbl)[RA];
|
||
|
RF = flag;
|
||
|
|
||
|
ENTIME(4);
|
||
|
}
|
||
|
|
||
|
OPDEF(cpl, 0x2F)
|
||
|
{
|
||
|
RA = ~RA;
|
||
|
SET_FL(HF | NF);
|
||
|
ENTIME(4);
|
||
|
}
|
||
|
|
||
|
OPDEF(scf, 0x37)
|
||
|
{
|
||
|
SETFLAGS(HF | NF, CF);
|
||
|
ENTIME(4);
|
||
|
}
|
||
|
|
||
|
OPDEF(ccf, 0x3F)
|
||
|
{
|
||
|
RF = (RF ^ CF) & ~(NF);
|
||
|
/* HF undefined */
|
||
|
ENTIME(4);
|
||
|
}
|
||
|
|
||
|
#include "z80_op1x.c"
|