rockbox/apps/plugins/zxbox/z80_op1.c

376 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"