BizHawk/waterbox/ngp/TLCS-900h/TLCS900h_interpret_single.cpp

429 lines
6.2 KiB
C++

//---------------------------------------------------------------------------
// NEOPOP : Emulator as in Dreamland
//
// Copyright (c) 2001-2002 by neopop_uk
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 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 also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
/*
//---------------------------------------------------------------------------
//=========================================================================
TLCS900h_interpret_single.c
//=========================================================================
//---------------------------------------------------------------------------
History of changes:
===================
20 JUL 2002 - neopop_uk
=======================================
- Cleaned and tidied up for the source release
22 JUL 2002 - neopop_uk
=======================================
- Removed setting the register file pointer to 3 in the SWI instruction
This has fixed "Metal Slug 2" and flash saving in many games.
26 JUL 2002 - neopop_uk
=======================================
- Prefixed all instruction functions with "sng" to avoid a repeat of the
the 'EX' fiasco.
30 JUL 2002 - neopop_uk
=======================================
- Um... SWI doesn't cause a problem if IFF is set to 3... why did
"Metal Slug 2" start working???
//---------------------------------------------------------------------------
*/
#include "../neopop.h"
#include "TLCS900h_interpret.h"
#include "TLCS900h_registers.h"
#include "../mem.h"
#include "../interrupt.h"
namespace TLCS900H
{
//=========================================================================
//===== NOP
void sngNOP()
{
cycles = 2;
}
//===== NORMAL
void sngNORMAL()
{
//Not supported
cycles = 4;
}
//===== PUSH SR
void sngPUSHSR()
{
push16(sr);
cycles = 4;
}
//===== POP SR
void sngPOPSR()
{
sr = pop16(); changedSP();
cycles = 6;
}
//===== MAX
void sngMAX()
{
//Not supported
cycles = 4;
}
//===== HALT
void sngHALT()
{
MDFN_printf("CPU halt requested and ignored.\nPlease send me a saved state.");
cycles = 8;
}
//===== EI #3
void sngEI()
{
setStatusIFF(FETCH8);
int_check_pending();
cycles = 5;
}
//===== RETI
void sngRETI()
{
uint16 temp = pop16();
pc = pop32();
sr = temp; changedSP();
cycles = 12;
}
//===== LD (n), n
void sngLD8_8()
{
uint8 dst = FETCH8;
uint8 src = FETCH8;
storeB(dst, src);
cycles = 5;
}
//===== PUSH n
void sngPUSH8()
{
uint8 data = FETCH8;
push8(data);
cycles = 4;
}
//===== LD (n), nn
void sngLD8_16()
{
uint8 dst = FETCH8;
uint16 src = fetch16();
storeW(dst, src);
cycles = 6;
}
//===== PUSH nn
void sngPUSH16()
{
push16(fetch16());
cycles = 5;
}
//===== INCF
void sngINCF()
{
setStatusRFP(((sr & 0x300) >> 8) + 1);
cycles = 2;
}
//===== DECF
void sngDECF()
{
setStatusRFP(((sr & 0x300) >> 8) - 1);
cycles = 2;
}
//===== RET condition
void sngRET()
{
pc = pop32();
cycles = 9;
}
//===== RETD dd
void sngRETD()
{
int16 d = (int16)fetch16();
pc = pop32();
REGXSP += d;
cycles = 9;
}
//===== RCF
void sngRCF()
{
SETFLAG_N0;
SETFLAG_V0;
SETFLAG_C0;
cycles = 2;
}
//===== SCF
void sngSCF()
{
SETFLAG_H0;
SETFLAG_N0;
SETFLAG_C1;
cycles = 2;
}
//===== CCF
void sngCCF()
{
SETFLAG_N0;
SETFLAG_C(!FLAG_C);
cycles = 2;
}
//===== ZCF
void sngZCF()
{
SETFLAG_N0;
SETFLAG_C(!FLAG_Z);
cycles = 2;
}
//===== PUSH A
void sngPUSHA()
{
push8(REGA);
cycles = 3;
}
//===== POP A
void sngPOPA()
{
REGA = pop8();
cycles = 4;
}
//===== EX F,F'
void sngEX()
{
uint8 f = sr & 0xFF;
sr = (sr & 0xFF00) | f_dash;
f_dash = f;
cycles = 2;
}
//===== LDF #3
void sngLDF()
{
setStatusRFP(FETCH8);
cycles = 2;
}
//===== PUSH F
void sngPUSHF()
{
push8(sr & 0xFF);
cycles = 3;
}
//===== POP F
void sngPOPF()
{
sr = (sr & 0xFF00) | pop8();
cycles = 4;
}
//===== JP nn
void sngJP16()
{
pc = fetch16();
cycles = 7;
}
//===== JP nnn
void sngJP24()
{
pc = fetch24();
cycles = 7;
}
//===== CALL #16
void sngCALL16()
{
uint32 target = fetch16();
push32(pc);
pc = target;
cycles = 12;
}
//===== CALL #24
void sngCALL24()
{
uint32 target = fetch24();
push32(pc);
pc = target;
cycles = 12;
}
//===== CALR $+3+d16
void sngCALR()
{
int16 displacement = (int16)fetch16();
uint32 target = pc + displacement;
push32(pc);
pc = target;
cycles = 12;
}
//===== LD R, n
void sngLDB()
{
regB(first & 7) = FETCH8;
cycles = 2;
}
//===== PUSH RR
void sngPUSHW()
{
push16(regW(first & 7));
cycles = 3;
}
//===== LD RR, nn
void sngLDW()
{
regW(first & 7) = fetch16();
cycles = 3;
}
//===== PUSH XRR
void sngPUSHL()
{
push32(regL(first & 7));
cycles = 5;
}
//===== LD XRR, nnnn
void sngLDL()
{
regL(first & 7) = fetch32();
cycles = 5;
}
//===== POP RR
void sngPOPW()
{
regW(first & 7) = pop16();
cycles = 4;
}
//===== POP XRR
void sngPOPL()
{
regL(first & 7) = pop32();
cycles = 6;
}
//===== JR cc,PC + d
void sngJR()
{
if (conditionCode(first & 0xF))
{
int8 displacement = (int8)FETCH8;
cycles = 8;
pc += displacement;
}
else
{
cycles = 4;
FETCH8;
}
}
//===== JR cc,PC + dd
void sngJRL()
{
if (conditionCode(first & 0xF))
{
int16 displacement = (int16)fetch16();
cycles = 8;
pc += displacement;
}
else
{
cycles = 4;
fetch16();
}
}
//===== LDX dst,src
void sngLDX()
{
uint8 dst, src;
FETCH8; //00
dst = FETCH8; //#8
FETCH8; //00
src = FETCH8; //#
FETCH8; //00
storeB(dst, src);
cycles = 9;
}
//===== SWI num
void sngSWI()
{
cycles = 16;
//printf("SWI: %02x\n", first & 0x7);
switch(first & 7)
{
//System Call
case 1: push32(pc);
pc = loadL(0xFFFE00 + ((rCodeB(0x31) & 0x1F) << 2));
break;
case 3: interrupt(0); //SWI 3
break;
case 4: interrupt(1); //SWI 4
break;
case 5: interrupt(2); //SWI 5
break;
case 6: interrupt(3); //SWI 6
break;
default: instruction_error("SWI %d is not valid.", first & 7);
break;
}
}
};
//=============================================================================