basic psp snd + cz80

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@280 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2007-10-26 20:08:13 +00:00
parent 8ab3e3c1cf
commit a4221917e1
16 changed files with 5127 additions and 62 deletions

View file

@ -684,14 +684,11 @@ end:
return ret;
}
PICO_INTERNAL unsigned short z80_read16(unsigned short a)
{
//dprintf("z80_read16");
return (u16) ( (u16)z80_read(a) | ((u16)z80_read((u16)(a+1))<<8) );
}
#ifndef _USE_CZ80
PICO_INTERNAL_ASM void z80_write(unsigned char data, unsigned short a)
#else
PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data)
#endif
{
//if (a<0x4000)
// dprintf("z80 w8 : %06x, %02x @%04x", a, data, mz80GetRegisterValue(NULL, 0));
@ -732,6 +729,14 @@ PICO_INTERNAL_ASM void z80_write(unsigned char data, unsigned short a)
elprintf(EL_ANOMALY, "z80 invalid w8 [%06x] %02x", a, data);
}
#ifndef _USE_CZ80
PICO_INTERNAL unsigned short z80_read16(unsigned short a)
{
//dprintf("z80_read16");
return (u16) ( (u16)z80_read(a) | ((u16)z80_read((u16)(a+1))<<8) );
}
PICO_INTERNAL void z80_write16(unsigned short data, unsigned short a)
{
//dprintf("z80_write16");
@ -739,4 +744,5 @@ PICO_INTERNAL void z80_write16(unsigned short data, unsigned short a)
z80_write((unsigned char) data,a);
z80_write((unsigned char)(data>>8),(u16)(a+1));
}
#endif

View file

@ -318,9 +318,13 @@ PICO_INTERNAL void PicoMemSetup(void);
PICO_INTERNAL_ASM void PicoMemReset(void);
PICO_INTERNAL int PadRead(int i);
PICO_INTERNAL unsigned char z80_read(unsigned short a);
PICO_INTERNAL unsigned short z80_read16(unsigned short a);
#ifndef _USE_CZ80
PICO_INTERNAL_ASM void z80_write(unsigned char data, unsigned short a);
PICO_INTERNAL void z80_write16(unsigned short data, unsigned short a);
PICO_INTERNAL unsigned short z80_read16(unsigned short a);
#else
PICO_INTERNAL_ASM void z80_write(unsigned int a, unsigned char data);
#endif
// cd/Memory.c
PICO_INTERNAL void PicoMemSetupCD(void);

View file

@ -15,6 +15,8 @@
#include "../../cpu/mz80/mz80.h"
#elif defined(_USE_DRZ80)
#include "../../cpu/DrZ80/drz80.h"
#elif defined(_USE_CZ80)
#include "../../cpu/cz80/cz80.h"
#endif
#include "../PicoInt.h"
@ -329,7 +331,6 @@ static void DrZ80_irq_callback()
{
drZ80.Z80_IRQ = 0; // lower irq when accepted
}
#endif
// z80 functionality wrappers
@ -353,7 +354,6 @@ PICO_INTERNAL void z80_init(void)
mz80SetContext(&z80);
#elif defined(_USE_DRZ80)
memset(&drZ80, 0, sizeof(struct DrZ80));
drZ80.z80_rebasePC=DrZ80_rebasePC;
drZ80.z80_rebaseSP=DrZ80_rebaseSP;
@ -364,6 +364,14 @@ PICO_INTERNAL void z80_init(void)
drZ80.z80_in =DrZ80_in;
drZ80.z80_out =DrZ80_out;
drZ80.z80_irq_callback=DrZ80_irq_callback;
#elif defined(_USE_CZ80)
memset(&CZ80, 0, sizeof(CZ80));
Cz80_Init(&CZ80);
Cz80_Set_Fetch(&CZ80, 0x0000, 0x1fff, (UINT32)Pico.zram); // main RAM
Cz80_Set_Fetch(&CZ80, 0x2000, 0x3fff, (UINT32)Pico.zram - 0x2000); // mirror
Cz80_Set_ReadB(&CZ80, (UINT8 (*)(UINT32 address))z80_read);
Cz80_Set_WriteB(&CZ80, z80_write);
#endif
}
@ -380,6 +388,8 @@ PICO_INTERNAL void z80_reset(void)
drZ80.Z80IM = 0; // 1?
drZ80.Z80PC = drZ80.z80_rebasePC(0);
drZ80.Z80SP = drZ80.z80_rebaseSP(0x2000); // 0xf000 ?
#elif defined(_USE_CZ80)
Cz80_Reset(&CZ80);
#endif
Pico.m.z80_fakeval = 0; // for faking when Z80 is disabled
}
@ -398,6 +408,8 @@ PICO_INTERNAL void z80_int(void)
#elif defined(_USE_DRZ80)
drZ80.z80irqvector = 0xFF; // default IRQ vector RST opcode
drZ80.Z80_IRQ = 1;
#elif defined(_USE_CZ80)
Cz80_Set_IRQ(&CZ80, 0, HOLD_LINE);
#endif
}
@ -410,6 +422,8 @@ PICO_INTERNAL int z80_run(int cycles)
return mz80GetElapsedTicks(0) - ticks_pre;
#elif defined(_USE_DRZ80)
return cycles - DrZ80Run(&drZ80, cycles);
#elif defined(_USE_CZ80)
return Cz80_Exec(&CZ80, cycles);
#else
return cycles;
#endif
@ -427,6 +441,10 @@ PICO_INTERNAL void z80_pack(unsigned char *data)
drZ80.Z80PC = drZ80.z80_rebasePC(drZ80.Z80PC-drZ80.Z80PC_BASE);
drZ80.Z80SP = drZ80.z80_rebaseSP(drZ80.Z80SP-drZ80.Z80SP_BASE);
memcpy(data+4, &drZ80, 0x54);
#elif defined(_USE_CZ80)
*(int *)data = 0x00007a43; // "Cz"
memcpy(data+4, &CZ80, (INT32)&CZ80.BasePC - (INT32)&CZ80);
printf("size: %i (%x)\n", (INT32)&CZ80.BasePC - (INT32)&CZ80, (INT32)&CZ80.BasePC - (INT32)&CZ80); // FIXME rm
#endif
}
@ -453,6 +471,13 @@ PICO_INTERNAL void z80_unpack(unsigned char *data)
drZ80.Z80IM = 1;
z80_int(); // try to goto int handler, maybe we won't execute trash there?
}
#elif defined(_USE_CZ80)
if (*(int *)data == 0x00007a43) // "Cz" save?
memcpy(&CZ80, data+4, (INT32)&CZ80.BasePC - (INT32)&CZ80);
else {
z80_reset();
z80_int();
}
#endif
}
@ -468,6 +493,8 @@ PICO_INTERNAL void z80_debug(char *dstr)
{
#if defined(_USE_DRZ80)
sprintf(dstr, "Z80 state: PC: %04x SP: %04x\n", drZ80.Z80PC-drZ80.Z80PC_BASE, drZ80.Z80SP-drZ80.Z80SP_BASE);
#elif defined(_USE_CZ80)
sprintf(dstr, "Z80 state: PC: %04x SP: %04x\n", CZ80.PC - CZ80.BasePC, CZ80.SP.W);
#endif
}
#endif

460
cpu/cz80/cz80.c Normal file
View file

@ -0,0 +1,460 @@
/******************************************************************************
*
* CZ80 (Z80 CPU emulator) version 0.9
* Compiled with Dev-C++
* Copyright 2004-2005 St駱hane Dallongeville
*
* (Modified by NJ)
*
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cz80.h"
#ifndef ALIGN_DATA
#define ALIGN_DATA __attribute__((aligned(4)))
#endif
#define CF 0x01
#define NF 0x02
#define PF 0x04
#define VF PF
#define XF 0x08
#define HF 0x10
#define YF 0x20
#define ZF 0x40
#define SF 0x80
/******************************************************************************
******************************************************************************/
#include "cz80macro.h"
/******************************************************************************
******************************************************************************/
cz80_struc ALIGN_DATA CZ80;
/******************************************************************************
******************************************************************************/
static UINT8 ALIGN_DATA cz80_bad_address[1 << CZ80_FETCH_SFT];
static UINT8 ALIGN_DATA SZ[256];
static UINT8 ALIGN_DATA SZP[256];
static UINT8 ALIGN_DATA SZ_BIT[256];
static UINT8 ALIGN_DATA SZHV_inc[256];
static UINT8 ALIGN_DATA SZHV_dec[256];
#if CZ80_BIG_FLAGS_ARRAY
static UINT8 ALIGN_DATA SZHVC_add[2*256*256];
static UINT8 ALIGN_DATA SZHVC_sub[2*256*256];
#endif
/******************************************************************************
******************************************************************************/
/*--------------------------------------------------------
--------------------------------------------------------*/
static INT32 Cz80_Interrupt_Callback(INT32 line)
{
return 0xff;
}
/******************************************************************************
CZ80インタフェース関数
******************************************************************************/
/*--------------------------------------------------------
CPU初期化
--------------------------------------------------------*/
void Cz80_Init(cz80_struc *CPU)
{
UINT32 i, j, p;
#if CZ80_BIG_FLAGS_ARRAY
int oldval, newval, val;
UINT8 *padd, *padc, *psub, *psbc;
#endif
memset(CPU, 0, sizeof(cz80_struc));
memset(cz80_bad_address, 0xff, sizeof(cz80_bad_address));
for (i = 0; i < CZ80_FETCH_BANK; i++)
{
CPU->Fetch[i] = (UINT32)cz80_bad_address;
#if CZ80_ENCRYPTED_ROM
CPU->OPFetch[i] = 0;
#endif
}
// flags tables initialisation
for (i = 0; i < 256; i++)
{
SZ[i] = i & (SF | YF | XF);
if (!i) SZ[i] |= ZF;
SZ_BIT[i] = i & (SF | YF | XF);
if (!i) SZ_BIT[i] |= ZF | PF;
for (j = 0, p = 0; j < 8; j++) if (i & (1 << j)) p++;
SZP[i] = SZ[i];
if (!(p & 1)) SZP[i] |= PF;
SZHV_inc[i] = SZ[i];
if(i == 0x80) SZHV_inc[i] |= VF;
if((i & 0x0f) == 0x00) SZHV_inc[i] |= HF;
SZHV_dec[i] = SZ[i] | NF;
if (i == 0x7f) SZHV_dec[i] |= VF;
if ((i & 0x0f) == 0x0f) SZHV_dec[i] |= HF;
}
#if CZ80_BIG_FLAGS_ARRAY
padd = &SZHVC_add[ 0*256];
padc = &SZHVC_add[256*256];
psub = &SZHVC_sub[ 0*256];
psbc = &SZHVC_sub[256*256];
for (oldval = 0; oldval < 256; oldval++)
{
for (newval = 0; newval < 256; newval++)
{
/* add or adc w/o carry set */
val = newval - oldval;
*padd = (newval) ? ((newval & 0x80) ? SF : 0) : ZF;
*padd |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */
if ((newval & 0x0f) < (oldval & 0x0f)) *padd |= HF;
if (newval < oldval ) *padd |= CF;
if ((val ^ oldval ^ 0x80) & (val ^ newval) & 0x80) *padd |= VF;
padd++;
/* adc with carry set */
val = newval - oldval - 1;
*padc = (newval) ? ((newval & 0x80) ? SF : 0) : ZF;
*padc |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */
if ((newval & 0x0f) <= (oldval & 0x0f)) *padc |= HF;
if (newval <= oldval) *padc |= CF;
if ((val ^ oldval ^ 0x80) & (val ^ newval) & 0x80) *padc |= VF;
padc++;
/* cp, sub or sbc w/o carry set */
val = oldval - newval;
*psub = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF);
*psub |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */
if ((newval & 0x0f) > (oldval & 0x0f)) *psub |= HF;
if (newval > oldval) *psub |= CF;
if ((val^oldval) & (oldval^newval) & 0x80) *psub |= VF;
psub++;
/* sbc with carry set */
val = oldval - newval - 1;
*psbc = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF);
*psbc |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */
if ((newval & 0x0f) >= (oldval & 0x0f)) *psbc |= HF;
if (newval >= oldval) *psbc |= CF;
if ((val ^ oldval) & (oldval^newval) & 0x80) *psbc |= VF;
psbc++;
}
}
#endif
CPU->pzR8[0] = &zB;
CPU->pzR8[1] = &zC;
CPU->pzR8[2] = &zD;
CPU->pzR8[3] = &zE;
CPU->pzR8[4] = &zH;
CPU->pzR8[5] = &zL;
CPU->pzR8[6] = &zF; // 処理の都合上、Aと入れ替え
CPU->pzR8[7] = &zA; // 処理の都合上、Fと入れ替え
CPU->pzR16[0] = pzBC;
CPU->pzR16[1] = pzDE;
CPU->pzR16[2] = pzHL;
CPU->pzR16[3] = pzAF;
zIX = zIY = 0xffff;
zF = ZF;
CPU->Interrupt_Callback = Cz80_Interrupt_Callback;
}
/*--------------------------------------------------------
CPUリセット
--------------------------------------------------------*/
void Cz80_Reset(cz80_struc *CPU)
{
memset(CPU, 0, (INT32)&CPU->BasePC - (INT32)CPU);
Cz80_Set_Reg(CPU, CZ80_PC, 0);
}
/*--------------------------------------------------------
CPU実行
--------------------------------------------------------*/
INT32 Cz80_Exec(cz80_struc *CPU, INT32 cycles)
{
#if CZ80_USE_JUMPTABLE
#include "cz80jmp.c"
#endif
UINT32 PC;
#if CZ80_ENCRYPTED_ROM
INT32 OPBase;
#endif
UINT32 Opcode;
UINT32 adr = 0;
UINT32 res;
UINT32 val;
int afterEI = 0;
PC = CPU->PC;
#if CZ80_ENCRYPTED_ROM
OPBase = CPU->OPBase;
#endif
CPU->ICount = cycles - CPU->ExtraCycles;
CPU->ExtraCycles = 0;
if (!CPU->HaltState)
{
Cz80_Exec:
if (CPU->ICount > 0)
{
union16 *data = pzHL;
Opcode = READ_OP();
#if CZ80_EMULATE_R_EXACTLY
zR++;
#endif
#include "cz80_op.c"
}
if (afterEI)
{
afterEI = 0;
Cz80_Check_Interrupt:
CHECK_INT
goto Cz80_Exec;
}
}
else CPU->ICount = 0;
Cz80_Exec_End:
CPU->PC = PC;
#if CZ80_ENCRYPTED_ROM
CPU->OPBase = OPBase;
#endif
cycles -= CPU->ICount;
#if !CZ80_EMULATE_R_EXACTLY
zR = (zR + (cycles >> 2)) & 0x7f;
#endif
return cycles;
}
/*--------------------------------------------------------
--------------------------------------------------------*/
void Cz80_Set_IRQ(cz80_struc *CPU, INT32 line, INT32 state)
{
if (line == IRQ_LINE_NMI)
{
zIFF1 = 0;
CPU->ExtraCycles += 11;
CPU->HaltState = 0;
PUSH_16(CPU->PC - CPU->BasePC)
Cz80_Set_Reg(CPU, CZ80_PC, 0x66);
}
else
{
CPU->IRQState = state;
if (state != CLEAR_LINE)
{
UINT32 PC = CPU->PC;
#if CZ80_ENCRYPTED_ROM
INT32 OPBase = CPU->OPBase;
#endif
CPU->IRQLine = line;
CHECK_INT
CPU->PC = PC;
#if CZ80_ENCRYPTED_ROM
CPU->OPBase = OPBase;
#endif
}
}
}
/*--------------------------------------------------------
--------------------------------------------------------*/
UINT32 Cz80_Get_Reg(cz80_struc *CPU, INT32 regnum)
{
switch (regnum)
{
case CZ80_PC: return (CPU->PC - CPU->BasePC);
case CZ80_SP: return zSP;
case CZ80_AF: return zAF;
case CZ80_BC: return zBC;
case CZ80_DE: return zDE;
case CZ80_HL: return zHL;
case CZ80_IX: return zIX;
case CZ80_IY: return zIY;
case CZ80_AF2: return zAF2;
case CZ80_BC2: return zBC2;
case CZ80_DE2: return zDE2;
case CZ80_HL2: return zHL2;
case CZ80_R: return zR;
case CZ80_I: return zI;
case CZ80_IM: return zIM;
case CZ80_IFF1: return zIFF1;
case CZ80_IFF2: return zIFF2;
case CZ80_HALT: return CPU->HaltState;
case CZ80_IRQ: return CPU->IRQState;
default: return 0;
}
}
/*--------------------------------------------------------
--------------------------------------------------------*/
void Cz80_Set_Reg(cz80_struc *CPU, INT32 regnum, UINT32 val)
{
switch (regnum)
{
case CZ80_PC:
CPU->BasePC = CPU->Fetch[val >> CZ80_FETCH_SFT];
#if CZ80_ENCRYPTED_ROM
CPU->OPBase = CPU->OPFetch[val >> CZ80_FETCH_SFT];
#endif
CPU->PC = val + CPU->BasePC;
break;
case CZ80_SP: zSP = val; break;
case CZ80_AF: zAF = val; break;
case CZ80_BC: zBC = val; break;
case CZ80_DE: zDE = val; break;
case CZ80_HL: zHL = val; break;
case CZ80_IX: zIX = val; break;
case CZ80_IY: zIY = val; break;
case CZ80_AF2: zAF2 = val; break;
case CZ80_BC2: zBC2 = val; break;
case CZ80_DE2: zDE2 = val; break;
case CZ80_HL2: zHL2 = val; break;
case CZ80_R: zR = val; break;
case CZ80_I: zI = val; break;
case CZ80_IM: zIM = val; break;
case CZ80_IFF1: zIFF1 = val; break;
case CZ80_IFF2: zIFF2 = val; break;
case CZ80_HALT: CPU->HaltState = val; break;
case CZ80_IRQ: CPU->IRQState = val; break;
default: break;
}
}
/*--------------------------------------------------------
--------------------------------------------------------*/
void Cz80_Set_Fetch(cz80_struc *CPU, UINT32 low_adr, UINT32 high_adr, UINT32 fetch_adr)
{
int i, j;
i = low_adr >> CZ80_FETCH_SFT;
j = high_adr >> CZ80_FETCH_SFT;
fetch_adr -= i << CZ80_FETCH_SFT;
while (i <= j)
{
CPU->Fetch[i] = fetch_adr;
#if CZ80_ENCRYPTED_ROM
CPU->OPFetch[i] = 0;
#endif
i++;
}
}
/*--------------------------------------------------------
(ROM対応)
--------------------------------------------------------*/
#if CZ80_ENCRYPTED_ROM
void Cz80_Set_Encrypt_Range(cz80_struc *CPU, UINT32 low_adr, UINT32 high_adr, UINT32 decrypted_rom)
{
int i, j;
i = low_adr >> CZ80_FETCH_SFT;
j = high_adr >> CZ80_FETCH_SFT;
decrypted_rom -= i << CZ80_FETCH_SFT;
while (i <= j)
{
CPU->OPFetch[i] = (INT32)decrypted_rom - (INT32)CPU->Fetch[i];
i++;
}
}
#endif
/*--------------------------------------------------------
/
--------------------------------------------------------*/
void Cz80_Set_ReadB(cz80_struc *CPU, UINT8 (*Func)(UINT32 address))
{
CPU->Read_Byte = Func;
}
void Cz80_Set_WriteB(cz80_struc *CPU, void (*Func)(UINT32 address, UINT8 data))
{
CPU->Write_Byte = Func;
}
/*--------------------------------------------------------
/
--------------------------------------------------------*/
void Cz80_Set_INPort(cz80_struc *CPU, UINT8 (*Func)(UINT16 port))
{
CPU->IN_Port = Func;
}
void Cz80_Set_OUTPort(cz80_struc *CPU, void (*Func)(UINT16 port, UINT8 value))
{
CPU->OUT_Port = Func;
}
/*--------------------------------------------------------
--------------------------------------------------------*/
void Cz80_Set_IRQ_Callback(cz80_struc *CPU, INT32 (*Func)(INT32 irqline))
{
CPU->Interrupt_Callback = Func;
}

303
cpu/cz80/cz80.h Normal file
View file

@ -0,0 +1,303 @@
/******************************************************************************
*
* CZ80 (Z80 CPU emulator) version 0.9
* Compiled with Dev-C++
* Copyright 2004-2005 Stéphane Dallongeville
*
* (Modified by NJ)
*
*****************************************************************************/
#ifndef CZ80_H
#define CZ80_H
#ifdef __cplusplus
extern "C" {
#endif
/******************************/
/* Compiler dependant defines */
/******************************/
#ifndef UINT8
#define UINT8 unsigned char
#endif
#ifndef INT8
#define INT8 char
#endif
#ifndef UINT16
#define UINT16 unsigned short
#endif
#ifndef INT16
#define INT16 short
#endif
#ifndef UINT32
#define UINT32 unsigned int
#endif
#ifndef INT32
#define INT32 int
#endif
/*************************************/
/* Z80 core Structures & definitions */
/*************************************/
#define CZ80_FETCH_BITS 4 // [4-12] default = 8
#define CZ80_FETCH_SFT (16 - CZ80_FETCH_BITS)
#define CZ80_FETCH_BANK (1 << CZ80_FETCH_BITS)
#define CZ80_LITTLE_ENDIAN 1
#define CZ80_USE_JUMPTABLE 1
#define CZ80_BIG_FLAGS_ARRAY 1
//#ifdef BUILD_CPS1PSP
//#define CZ80_ENCRYPTED_ROM 1
//#else
#define CZ80_ENCRYPTED_ROM 0
//#endif
#define CZ80_EMULATE_R_EXACTLY 0
#define zR8(A) (*CPU->pzR8[A])
#define zR16(A) (CPU->pzR16[A]->W)
#define pzAF &(CPU->AF)
#define zAF CPU->AF.W
#define zlAF CPU->AF.B.L
#define zhAF CPU->AF.B.H
#define zA zhAF
#define zF zlAF
#define pzBC &(CPU->BC)
#define zBC CPU->BC.W
#define zlBC CPU->BC.B.L
#define zhBC CPU->BC.B.H
#define zB zhBC
#define zC zlBC
#define pzDE &(CPU->DE)
#define zDE CPU->DE.W
#define zlDE CPU->DE.B.L
#define zhDE CPU->DE.B.H
#define zD zhDE
#define zE zlDE
#define pzHL &(CPU->HL)
#define zHL CPU->HL.W
#define zlHL CPU->HL.B.L
#define zhHL CPU->HL.B.H
#define zH zhHL
#define zL zlHL
#define zAF2 CPU->AF2.W
#define zlAF2 CPU->AF2.B.L
#define zhAF2 CPU->AF2.B.H
#define zA2 zhAF2
#define zF2 zlAF2
#define zBC2 CPU->BC2.W
#define zDE2 CPU->DE2.W
#define zHL2 CPU->HL2.W
#define pzIX &(CPU->IX)
#define zIX CPU->IX.W
#define zlIX CPU->IX.B.L
#define zhIX CPU->IX.B.H
#define pzIY &(CPU->IY)
#define zIY CPU->IY.W
#define zlIY CPU->IY.B.L
#define zhIY CPU->IY.B.H
#define pzSP &(CPU->SP)
#define zSP CPU->SP.W
#define zlSP CPU->SP.B.L
#define zhSP CPU->SP.B.H
#define zRealPC (PC - CPU->BasePC)
#define zPC PC
#define zI CPU->I
#define zIM CPU->IM
#define zwR CPU->R.W
#define zR1 CPU->R.B.L
#define zR2 CPU->R.B.H
#define zR zR1
#define zIFF CPU->IFF.W
#define zIFF1 CPU->IFF.B.L
#define zIFF2 CPU->IFF.B.H
#define CZ80_SF_SFT 7
#define CZ80_ZF_SFT 6
#define CZ80_YF_SFT 5
#define CZ80_HF_SFT 4
#define CZ80_XF_SFT 3
#define CZ80_PF_SFT 2
#define CZ80_VF_SFT 2
#define CZ80_NF_SFT 1
#define CZ80_CF_SFT 0
#define CZ80_SF (1 << CZ80_SF_SFT)
#define CZ80_ZF (1 << CZ80_ZF_SFT)
#define CZ80_YF (1 << CZ80_YF_SFT)
#define CZ80_HF (1 << CZ80_HF_SFT)
#define CZ80_XF (1 << CZ80_XF_SFT)
#define CZ80_PF (1 << CZ80_PF_SFT)
#define CZ80_VF (1 << CZ80_VF_SFT)
#define CZ80_NF (1 << CZ80_NF_SFT)
#define CZ80_CF (1 << CZ80_CF_SFT)
#define CZ80_IFF_SFT CZ80_PF_SFT
#define CZ80_IFF CZ80_PF
#ifndef IRQ_LINE_STATE
#define IRQ_LINE_STATE
#define CLEAR_LINE 0 /* clear (a fired, held or pulsed) line */
#define ASSERT_LINE 1 /* assert an interrupt immediately */
#define HOLD_LINE 2 /* hold interrupt line until acknowledged */
#define PULSE_LINE 3 /* pulse interrupt line for one instruction */
#define IRQ_LINE_NMI 127 /* IRQ line for NMIs */
#endif
enum
{
CZ80_PC = 1,
CZ80_SP,
CZ80_AF,
CZ80_BC,
CZ80_DE,
CZ80_HL,
CZ80_IX,
CZ80_IY,
CZ80_AF2,
CZ80_BC2,
CZ80_DE2,
CZ80_HL2,
CZ80_R,
CZ80_I,
CZ80_IM,
CZ80_IFF1,
CZ80_IFF2,
CZ80_HALT,
CZ80_IRQ
};
typedef union
{
struct
{
#if CZ80_LITTLE_ENDIAN
UINT8 L;
UINT8 H;
#else
UINT8 H;
UINT8 L;
#endif
} B;
UINT16 W;
} union16;
typedef struct cz80_t
{
union
{
UINT8 r8[8];
union16 r16[4];
struct
{
union16 BC;
union16 DE;
union16 HL;
union16 AF;
};
};
union16 IX;
union16 IY;
union16 SP;
UINT32 PC;
union16 BC2;
union16 DE2;
union16 HL2;
union16 AF2;
union16 R;
union16 IFF;
UINT8 I;
UINT8 IM;
UINT8 HaltState;
UINT8 dummy;
INT32 IRQLine;
INT32 IRQState;
INT32 ICount;
INT32 ExtraCycles;
UINT32 BasePC;
UINT32 Fetch[CZ80_FETCH_BANK];
#if CZ80_ENCRYPTED_ROM
INT32 OPBase;
INT32 OPFetch[CZ80_FETCH_BANK];
#endif
UINT8 *pzR8[8];
union16 *pzR16[4];
UINT8 (*Read_Byte)(UINT32 address);
void (*Write_Byte)(UINT32 address, UINT8 data);
UINT8 (*IN_Port)(UINT16 port);
void (*OUT_Port)(UINT16 port, UINT8 value);
INT32 (*Interrupt_Callback)(INT32 irqline);
} cz80_struc;
/*************************/
/* Publics Z80 variables */
/*************************/
extern cz80_struc CZ80;
/*************************/
/* Publics Z80 functions */
/*************************/
void Cz80_Init(cz80_struc *CPU);
void Cz80_Reset(cz80_struc *CPU);
INT32 Cz80_Exec(cz80_struc *CPU, INT32 cycles);
void Cz80_Set_IRQ(cz80_struc *CPU, INT32 line, INT32 state);
UINT32 Cz80_Get_Reg(cz80_struc *CPU, INT32 regnum);
void Cz80_Set_Reg(cz80_struc *CPU, INT32 regnum, UINT32 value);
void Cz80_Set_Fetch(cz80_struc *CPU, UINT32 low_adr, UINT32 high_adr, UINT32 fetch_adr);
#if CZ80_ENCRYPTED_ROM
void Cz80_Set_Encrypt_Range(cz80_struc *CPU, UINT32 low_adr, UINT32 high_adr, UINT32 decrypted_rom);
#endif
void Cz80_Set_ReadB(cz80_struc *CPU, UINT8 (*Func)(UINT32 address));
void Cz80_Set_WriteB(cz80_struc *CPU, void (*Func)(UINT32 address, UINT8 data));
void Cz80_Set_INPort(cz80_struc *CPU, UINT8 (*Func)(UINT16 port));
void Cz80_Set_OUTPort(cz80_struc *CPU, void (*Func)(UINT16 port, UINT8 value));
void Cz80_Set_IRQ_Callback(cz80_struc *CPU, INT32 (*Func)(INT32 irqline));
#ifdef __cplusplus
};
#endif
#endif /* CZ80_H */

1145
cpu/cz80/cz80_op.c Normal file

File diff suppressed because it is too large Load diff

470
cpu/cz80/cz80_opCB.c Normal file
View file

@ -0,0 +1,470 @@
/******************************************************************************
*
* CZ80 CB opcode include source file
* CZ80 emulator version 0.9
* Copyright 2004-2005 Stéphane Dallongeville
*
* (Modified by NJ)
*
*****************************************************************************/
#if CZ80_USE_JUMPTABLE
goto *JumpTableCB[Opcode];
#else
switch (Opcode)
{
#endif
/*-----------------------------------------
RLC
-----------------------------------------*/
OPCB(0x00): // RLC B
OPCB(0x01): // RLC C
OPCB(0x02): // RLC D
OPCB(0x03): // RLC E
OPCB(0x04): // RLC H
OPCB(0x05): // RLC L
OPCB(0x07): // RLC A
src = zR8(Opcode);
res = (src << 1) | (src >> 7);
zF = SZP[res] | (src >> 7);
zR8(Opcode) = res;
RET(8)
OPCB(0x06): // RLC (HL)
adr = zHL;
src = READ_MEM8(adr);
res = (src << 1) | (src >> 7);
zF = SZP[res] | (src >> 7);
WRITE_MEM8(adr, res);
RET(15)
/*-----------------------------------------
RRC
-----------------------------------------*/
OPCB(0x08): // RRC B
OPCB(0x09): // RRC C
OPCB(0x0a): // RRC D
OPCB(0x0b): // RRC E
OPCB(0x0c): // RRC H
OPCB(0x0d): // RRC L
OPCB(0x0f): // RRC A
src = zR8(Opcode & 7);
res = (src >> 1) | (src << 7);
zF = SZP[res] | (src & CF);
zR8(Opcode & 7) = res;
RET(8)
OPCB(0x0e): // RRC (HL)
adr = zHL;
src = READ_MEM8(adr);
res = (src >> 1) | (src << 7);
zF = SZP[res] | (src & CF);
WRITE_MEM8(adr, res);
RET(15)
/*-----------------------------------------
RL
-----------------------------------------*/
OPCB(0x10): // RL B
OPCB(0x11): // RL C
OPCB(0x12): // RL D
OPCB(0x13): // RL E
OPCB(0x14): // RL H
OPCB(0x15): // RL L
OPCB(0x17): // RL A
src = zR8(Opcode & 7);
res = (src << 1) | (zF & CF);
zF = SZP[res] | (src >> 7);
zR8(Opcode & 7) = res;
RET(8)
OPCB(0x16): // RL (HL)
adr = zHL;
src = READ_MEM8(adr);
res = (src << 1) | (zF & CF);
zF = SZP[res] | (src >> 7);
WRITE_MEM8(adr, res);
RET(15)
/*-----------------------------------------
RR
-----------------------------------------*/
OPCB(0x18): // RR B
OPCB(0x19): // RR C
OPCB(0x1a): // RR D
OPCB(0x1b): // RR E
OPCB(0x1c): // RR H
OPCB(0x1d): // RR L
OPCB(0x1f): // RR A
src = zR8(Opcode & 7);
res = (src >> 1) | (zF << 7);
zF = SZP[res] | (src & CF);
zR8(Opcode & 7) = res;
RET(8)
OPCB(0x1e): // RR (HL)
adr = zHL;
src = READ_MEM8(adr);
res = (src >> 1) | (zF << 7);
zF = SZP[res] | (src & CF);
WRITE_MEM8(adr, res);
RET(15)
/*-----------------------------------------
SLA
-----------------------------------------*/
OPCB(0x20): // SLA B
OPCB(0x21): // SLA C
OPCB(0x22): // SLA D
OPCB(0x23): // SLA E
OPCB(0x24): // SLA H
OPCB(0x25): // SLA L
OPCB(0x27): // SLA A
src = zR8(Opcode & 7);
res = src << 1;
zF = SZP[res] | (src >> 7);
zR8(Opcode & 7) = res;
RET(8)
OPCB(0x26): // SLA (HL)
adr = zHL;
src = READ_MEM8(adr);
res = src << 1;
zF = SZP[res] | (src >> 7);
WRITE_MEM8(adr, res);
RET(15)
/*-----------------------------------------
SRA
-----------------------------------------*/
OPCB(0x28): // SRA B
OPCB(0x29): // SRA C
OPCB(0x2a): // SRA D
OPCB(0x2b): // SRA E
OPCB(0x2c): // SRA H
OPCB(0x2d): // SRA L
OPCB(0x2f): // SRA A
src = zR8(Opcode & 7);
res = (src >> 1) | (src & 0x80);
zF = SZP[res] | (src & CF);
zR8(Opcode & 7) = res;
RET(8)
OPCB(0x2e): // SRA (HL)
adr = zHL;
src = READ_MEM8(adr);
res = (src >> 1) | (src & 0x80);
zF = SZP[res] | (src & CF);
WRITE_MEM8(adr, res);
RET(15)
/*-----------------------------------------
SLL
-----------------------------------------*/
OPCB(0x30): // SLL B
OPCB(0x31): // SLL C
OPCB(0x32): // SLL D
OPCB(0x33): // SLL E
OPCB(0x34): // SLL H
OPCB(0x35): // SLL L
OPCB(0x37): // SLL A
src = zR8(Opcode & 7);
res = (src << 1) | 0x01;
zF = SZP[res] | (src >> 7);
zR8(Opcode & 7) = res;
RET(8)
OPCB(0x36): // SLL (HL)
adr = zHL;
src = READ_MEM8(adr);
res = (src << 1) | 0x01;
zF = SZP[res] | (src >> 7);
WRITE_MEM8(adr, res);
RET(15)
/*-----------------------------------------
SRL
-----------------------------------------*/
OPCB(0x38): // SRL B
OPCB(0x39): // SRL C
OPCB(0x3a): // SRL D
OPCB(0x3b): // SRL E
OPCB(0x3c): // SRL H
OPCB(0x3d): // SRL L
OPCB(0x3f): // SRL A
src = zR8(Opcode & 7);
res = src >> 1;
zF = SZP[res] | (src & CF);
zR8(Opcode & 7) = res;
RET(8)
OPCB(0x3e): // SRL (HL)
adr = zHL;
src = READ_MEM8(adr);
res = src >> 1;
zF = SZP[res] | (src & CF);
WRITE_MEM8(adr, res);
RET(15)
/*-----------------------------------------
BIT
-----------------------------------------*/
OPCB(0x40): // BIT 0,B
OPCB(0x41): // BIT 0,C
OPCB(0x42): // BIT 0,D
OPCB(0x43): // BIT 0,E
OPCB(0x44): // BIT 0,H
OPCB(0x45): // BIT 0,L
OPCB(0x47): // BIT 0,A
OPCB(0x48): // BIT 1,B
OPCB(0x49): // BIT 1,C
OPCB(0x4a): // BIT 1,D
OPCB(0x4b): // BIT 1,E
OPCB(0x4c): // BIT 1,H
OPCB(0x4d): // BIT 1,L
OPCB(0x4f): // BIT 1,A
OPCB(0x50): // BIT 2,B
OPCB(0x51): // BIT 2,C
OPCB(0x52): // BIT 2,D
OPCB(0x53): // BIT 2,E
OPCB(0x54): // BIT 2,H
OPCB(0x55): // BIT 2,L
OPCB(0x57): // BIT 2,A
OPCB(0x58): // BIT 3,B
OPCB(0x59): // BIT 3,C
OPCB(0x5a): // BIT 3,D
OPCB(0x5b): // BIT 3,E
OPCB(0x5c): // BIT 3,H
OPCB(0x5d): // BIT 3,L
OPCB(0x5f): // BIT 3,A
OPCB(0x60): // BIT 4,B
OPCB(0x61): // BIT 4,C
OPCB(0x62): // BIT 4,D
OPCB(0x63): // BIT 4,E
OPCB(0x64): // BIT 4,H
OPCB(0x65): // BIT 4,L
OPCB(0x67): // BIT 4,A
OPCB(0x68): // BIT 5,B
OPCB(0x69): // BIT 5,C
OPCB(0x6a): // BIT 5,D
OPCB(0x6b): // BIT 5,E
OPCB(0x6c): // BIT 5,H
OPCB(0x6d): // BIT 5,L
OPCB(0x6f): // BIT 5,A
OPCB(0x70): // BIT 6,B
OPCB(0x71): // BIT 6,C
OPCB(0x72): // BIT 6,D
OPCB(0x73): // BIT 6,E
OPCB(0x74): // BIT 6,H
OPCB(0x75): // BIT 6,L
OPCB(0x77): // BIT 6,A
OPCB(0x78): // BIT 7,B
OPCB(0x79): // BIT 7,C
OPCB(0x7a): // BIT 7,D
OPCB(0x7b): // BIT 7,E
OPCB(0x7c): // BIT 7,H
OPCB(0x7d): // BIT 7,L
OPCB(0x7f): // BIT 7,A
zF = (zF & CF) | HF | SZ_BIT[zR8(Opcode & 7) & (1 << ((Opcode >> 3) & 7))];
RET(8)
OPCB(0x46): // BIT 0,(HL)
OPCB(0x4e): // BIT 1,(HL)
OPCB(0x56): // BIT 2,(HL)
OPCB(0x5e): // BIT 3,(HL)
OPCB(0x66): // BIT 4,(HL)
OPCB(0x6e): // BIT 5,(HL)
OPCB(0x76): // BIT 6,(HL)
OPCB(0x7e): // BIT 7,(HL)
src = READ_MEM8(zHL);
zF = (zF & CF) | HF | SZ_BIT[src & (1 << ((Opcode >> 3) & 7))];
RET(12)
/*-----------------------------------------
RES
-----------------------------------------*/
OPCB(0x80): // RES 0,B
OPCB(0x81): // RES 0,C
OPCB(0x82): // RES 0,D
OPCB(0x83): // RES 0,E
OPCB(0x84): // RES 0,H
OPCB(0x85): // RES 0,L
OPCB(0x87): // RES 0,A
OPCB(0x88): // RES 1,B
OPCB(0x89): // RES 1,C
OPCB(0x8a): // RES 1,D
OPCB(0x8b): // RES 1,E
OPCB(0x8c): // RES 1,H
OPCB(0x8d): // RES 1,L
OPCB(0x8f): // RES 1,A
OPCB(0x90): // RES 2,B
OPCB(0x91): // RES 2,C
OPCB(0x92): // RES 2,D
OPCB(0x93): // RES 2,E
OPCB(0x94): // RES 2,H
OPCB(0x95): // RES 2,L
OPCB(0x97): // RES 2,A
OPCB(0x98): // RES 3,B
OPCB(0x99): // RES 3,C
OPCB(0x9a): // RES 3,D
OPCB(0x9b): // RES 3,E
OPCB(0x9c): // RES 3,H
OPCB(0x9d): // RES 3,L
OPCB(0x9f): // RES 3,A
OPCB(0xa0): // RES 4,B
OPCB(0xa1): // RES 4,C
OPCB(0xa2): // RES 4,D
OPCB(0xa3): // RES 4,E
OPCB(0xa4): // RES 4,H
OPCB(0xa5): // RES 4,L
OPCB(0xa7): // RES 4,A
OPCB(0xa8): // RES 5,B
OPCB(0xa9): // RES 5,C
OPCB(0xaa): // RES 5,D
OPCB(0xab): // RES 5,E
OPCB(0xac): // RES 5,H
OPCB(0xad): // RES 5,L
OPCB(0xaf): // RES 5,A
OPCB(0xb0): // RES 6,B
OPCB(0xb1): // RES 6,C
OPCB(0xb2): // RES 6,D
OPCB(0xb3): // RES 6,E
OPCB(0xb4): // RES 6,H
OPCB(0xb5): // RES 6,L
OPCB(0xb7): // RES 6,A
OPCB(0xb8): // RES 7,B
OPCB(0xb9): // RES 7,C
OPCB(0xba): // RES 7,D
OPCB(0xbb): // RES 7,E
OPCB(0xbc): // RES 7,H
OPCB(0xbd): // RES 7,L
OPCB(0xbf): // RES 7,A
zR8(Opcode & 7) &= ~(1 << ((Opcode >> 3) & 7));
RET(8)
OPCB(0x86): // RES 0,(HL)
OPCB(0x8e): // RES 1,(HL)
OPCB(0x96): // RES 2,(HL)
OPCB(0x9e): // RES 3,(HL)
OPCB(0xa6): // RES 4,(HL)
OPCB(0xae): // RES 5,(HL)
OPCB(0xb6): // RES 6,(HL)
OPCB(0xbe): // RES 7,(HL)
adr = zHL;
res = READ_MEM8(adr);
res &= ~(1 << ((Opcode >> 3) & 7));
WRITE_MEM8(adr, res);
RET(15)
/*-----------------------------------------
SET
-----------------------------------------*/
OPCB(0xc0): // SET 0,B
OPCB(0xc1): // SET 0,C
OPCB(0xc2): // SET 0,D
OPCB(0xc3): // SET 0,E
OPCB(0xc4): // SET 0,H
OPCB(0xc5): // SET 0,L
OPCB(0xc7): // SET 0,A
OPCB(0xc8): // SET 1,B
OPCB(0xc9): // SET 1,C
OPCB(0xca): // SET 1,D
OPCB(0xcb): // SET 1,E
OPCB(0xcc): // SET 1,H
OPCB(0xcd): // SET 1,L
OPCB(0xcf): // SET 1,A
OPCB(0xd0): // SET 2,B
OPCB(0xd1): // SET 2,C
OPCB(0xd2): // SET 2,D
OPCB(0xd3): // SET 2,E
OPCB(0xd4): // SET 2,H
OPCB(0xd5): // SET 2,L
OPCB(0xd7): // SET 2,A
OPCB(0xd8): // SET 3,B
OPCB(0xd9): // SET 3,C
OPCB(0xda): // SET 3,D
OPCB(0xdb): // SET 3,E
OPCB(0xdc): // SET 3,H
OPCB(0xdd): // SET 3,L
OPCB(0xdf): // SET 3,A
OPCB(0xe0): // SET 4,B
OPCB(0xe1): // SET 4,C
OPCB(0xe2): // SET 4,D
OPCB(0xe3): // SET 4,E
OPCB(0xe4): // SET 4,H
OPCB(0xe5): // SET 4,L
OPCB(0xe7): // SET 4,A
OPCB(0xe8): // SET 5,B
OPCB(0xe9): // SET 5,C
OPCB(0xea): // SET 5,D
OPCB(0xeb): // SET 5,E
OPCB(0xec): // SET 5,H
OPCB(0xed): // SET 5,L
OPCB(0xef): // SET 5,A
OPCB(0xf0): // SET 6,B
OPCB(0xf1): // SET 6,C
OPCB(0xf2): // SET 6,D
OPCB(0xf3): // SET 6,E
OPCB(0xf4): // SET 6,H
OPCB(0xf5): // SET 6,L
OPCB(0xf7): // SET 6,A
OPCB(0xf8): // SET 7,B
OPCB(0xf9): // SET 7,C
OPCB(0xfa): // SET 7,D
OPCB(0xfb): // SET 7,E
OPCB(0xfc): // SET 7,H
OPCB(0xfd): // SET 7,L
OPCB(0xff): // SET 7,A
zR8(Opcode & 7) |= 1 << ((Opcode >> 3) & 7);
RET(8)
OPCB(0xc6): // SET 0,(HL)
OPCB(0xce): // SET 1,(HL)
OPCB(0xd6): // SET 2,(HL)
OPCB(0xde): // SET 3,(HL)
OPCB(0xe6): // SET 4,(HL)
OPCB(0xee): // SET 5,(HL)
OPCB(0xf6): // SET 6,(HL)
OPCB(0xfe): // SET 7,(HL)
adr = zHL;
res = READ_MEM8(adr);
res |= 1 << ((Opcode >> 3) & 7);
WRITE_MEM8(adr, res);
RET(15)
#if !CZ80_USE_JUMPTABLE
}
#endif

731
cpu/cz80/cz80_opED.c Normal file
View file

@ -0,0 +1,731 @@
/******************************************************************************
*
* CZ80 ED opcode include source file
* CZ80 emulator version 0.9
* Copyright 2004-2005 Stéphane Dallongeville
*
* (Modified by NJ)
*
*****************************************************************************/
#if CZ80_USE_JUMPTABLE
goto *JumpTableED[Opcode];
#else
switch (Opcode)
{
#endif
/*-----------------------------------------
ILLEGAL
-----------------------------------------*/
OPED(0x00):
OPED(0x01):
OPED(0x02):
OPED(0x03):
OPED(0x04):
OPED(0x05):
OPED(0x06):
OPED(0x07):
OPED(0x08):
OPED(0x09):
OPED(0x0a):
OPED(0x0b):
OPED(0x0c):
OPED(0x0d):
OPED(0x0e):
OPED(0x0f):
OPED(0x10):
OPED(0x11):
OPED(0x12):
OPED(0x13):
OPED(0x14):
OPED(0x15):
OPED(0x16):
OPED(0x17):
OPED(0x18):
OPED(0x19):
OPED(0x1a):
OPED(0x1b):
OPED(0x1c):
OPED(0x1d):
OPED(0x1e):
OPED(0x1f):
OPED(0x20):
OPED(0x21):
OPED(0x22):
OPED(0x23):
OPED(0x24):
OPED(0x25):
OPED(0x26):
OPED(0x27):
OPED(0x28):
OPED(0x29):
OPED(0x2a):
OPED(0x2b):
OPED(0x2c):
OPED(0x2d):
OPED(0x2e):
OPED(0x2f):
OPED(0x30):
OPED(0x31):
OPED(0x32):
OPED(0x33):
OPED(0x34):
OPED(0x35):
OPED(0x36):
OPED(0x37):
OPED(0x38):
OPED(0x39):
OPED(0x3a):
OPED(0x3b):
OPED(0x3c):
OPED(0x3d):
OPED(0x3e):
OPED(0x3f):
OPED(0x77):
OPED(0x7f):
OPED(0x80):
OPED(0x81):
OPED(0x82):
OPED(0x83):
OPED(0x84):
OPED(0x85):
OPED(0x86):
OPED(0x87):
OPED(0x88):
OPED(0x89):
OPED(0x8a):
OPED(0x8b):
OPED(0x8c):
OPED(0x8d):
OPED(0x8e):
OPED(0x8f):
OPED(0x90):
OPED(0x91):
OPED(0x92):
OPED(0x93):
OPED(0x94):
OPED(0x95):
OPED(0x96):
OPED(0x97):
OPED(0x98):
OPED(0x99):
OPED(0x9a):
OPED(0x9b):
OPED(0x9c):
OPED(0x9d):
OPED(0x9e):
OPED(0x9f):
OPED(0xa4):
OPED(0xa5):
OPED(0xa6):
OPED(0xa7):
OPED(0xac):
OPED(0xad):
OPED(0xae):
OPED(0xaf):
OPED(0xb4):
OPED(0xb5):
OPED(0xb6):
OPED(0xb7):
OPED(0xbc):
OPED(0xbd):
OPED(0xbe):
OPED(0xbf):
OPED(0xc0):
OPED(0xc1):
OPED(0xc2):
OPED(0xc3):
OPED(0xc4):
OPED(0xc5):
OPED(0xc6):
OPED(0xc7):
OPED(0xc8):
OPED(0xc9):
OPED(0xca):
OPED(0xcb):
OPED(0xcc):
OPED(0xcd):
OPED(0xce):
OPED(0xcf):
OPED(0xd0):
OPED(0xd1):
OPED(0xd2):
OPED(0xd3):
OPED(0xd4):
OPED(0xd5):
OPED(0xd6):
OPED(0xd7):
OPED(0xd8):
OPED(0xd9):
OPED(0xda):
OPED(0xdb):
OPED(0xdc):
OPED(0xdd):
OPED(0xde):
OPED(0xdf):
OPED(0xe0):
OPED(0xe1):
OPED(0xe2):
OPED(0xe3):
OPED(0xe4):
OPED(0xe5):
OPED(0xe6):
OPED(0xe7):
OPED(0xe8):
OPED(0xe9):
OPED(0xea):
OPED(0xeb):
OPED(0xec):
OPED(0xed):
OPED(0xee):
OPED(0xef):
OPED(0xf0):
OPED(0xf1):
OPED(0xf2):
OPED(0xf3):
OPED(0xf4):
OPED(0xf5):
OPED(0xf6):
OPED(0xf7):
OPED(0xf8):
OPED(0xf9):
OPED(0xfa):
OPED(0xfb):
OPED(0xfc):
OPED(0xfd):
OPED(0xfe):
OPED(0xff):
RET(4)
/*-----------------------------------------
LD r8
-----------------------------------------*/
OPED(0x47): // LD I,A
zI = zA;
RET(5)
OPED(0x4f): // LD R,A
#if CZ80_EMULATE_R_EXACTLY
zR = zA;
#else
zR = zA - ((cycles - CPU->ICount) >> 2);
#endif
zR2 = zA & 0x80;
RET(5)
OPED(0x57): // LD A,I
zA = zI;
zF = (zF & CF) | SZ[zA] | zIFF2;
RET(5)
OPED(0x5f): // LD A,R
#if CZ80_EMULATE_R_EXACTLY
zA = (zR & 0x7f) | zR2;
#else
zA = ((zR + ((cycles - CPU->ICount) >> 2)) & 0x7f) | zR2;
#endif
zF = (zF & CF) | SZ[zA] | zIFF2;
RET(5)
/*-----------------------------------------
LD r16
-----------------------------------------*/
OPED(0x43): // LD (w),BC
data = pzBC;
goto OP_LD_mNN_xx;
OPED(0x53): // LD (w),DE
data = pzDE;
goto OP_LD_mNN_xx;
OPED(0x63): // LD (w),HL
data = pzHL;
goto OP_LD_mNN_xx;
OPED(0x73): // LD (w),SP
data = pzSP;
goto OP_LD_mNN_xx;
OPED(0x4b): // LD BC,(w)
data = pzBC;
goto OP_LD_xx_mNN;
OPED(0x5b): // LD DE,(w)
data = pzDE;
goto OP_LD_xx_mNN;
OPED(0x6b): // LD HL,(w)
data = pzHL;
goto OP_LD_xx_mNN;
OPED(0x7b): // LD SP,(w)
data = pzSP;
goto OP_LD_xx_mNN;
/*-----------------------------------------
NEG
-----------------------------------------*/
OPED(0x44): // NEG
OPED(0x4c): // NEG
OPED(0x54): // NEG
OPED(0x5c): // NEG
OPED(0x64): // NEG
OPED(0x6c): // NEG
OPED(0x74): // NEG
OPED(0x7c): // NEG
val = zA;
zA = 0;
goto OP_SUB;
/*-----------------------------------------
RRD
-----------------------------------------*/
OPED(0x67): // RRD (HL)
adr = zHL;
val = READ_MEM8(adr);
WRITE_MEM8(adr, (val >> 4) | (zA << 4));
zA = (zA & 0xf0) | (val & 0x0f);
zF = (zF & CF) | SZP[zA];
RET(14)
/*-----------------------------------------
RLD
-----------------------------------------*/
OPED(0x6f): // RLD (HL)
adr = zHL;
val = READ_MEM8(adr);
WRITE_MEM8(adr, (val << 4) | (zA & 0x0f));
zA = (zA & 0xf0) | (val >> 4);
zF = (zF & CF) | SZP[zA];
RET(14)
/*-----------------------------------------
ADC 16
-----------------------------------------*/
OPED(0x7a): // ADC HL,SP
val = zSP;
goto OP_ADC16;
OPED(0x4a): // ADC HL,BC
OPED(0x5a): // ADC HL,DE
OPED(0x6a): // ADC HL,HL
val = zR16((Opcode >> 4) & 3);
OP_ADC16:
res = zHL + val + (zF & CF);
zF = (((zHL ^ res ^ val) >> 8) & HF) |
((res >> 16) & CF) |
((res >> 8) & (SF | YF | XF)) |
((res & 0xffff) ? 0 : ZF) |
(((val ^ zHL ^ 0x8000) & (val ^ res) & 0x8000) >> 13);
zHL = (UINT16)res;
RET(11)
/*-----------------------------------------
SBC 16
-----------------------------------------*/
OPED(0x72): // SBC HL,SP
val = zSP;
goto OP_SBC16;
OPED(0x42): // SBC HL,BC
OPED(0x52): // SBC HL,DE
OPED(0x62): // SBC HL,HL
val = zR16((Opcode >> 4) & 3);
OP_SBC16:
res = zHL - val - (zF & CF);
zF = (((zHL ^ res ^ val) >> 8) & HF) | NF |
((res >> 16) & CF) |
((res >> 8) & (SF | YF | XF)) |
((res & 0xffff) ? 0 : ZF) |
(((val ^ zHL) & (zHL ^ res) & 0x8000) >> 13);
zHL = (UINT16)res;
RET(11)
/*-----------------------------------------
IN
-----------------------------------------*/
OPED(0x40): // IN B,(C)
OPED(0x48): // IN C,(C)
OPED(0x50): // IN D,(C)
OPED(0x58): // IN E,(C)
OPED(0x60): // IN H,(C)
OPED(0x68): // IN L,(C)
OPED(0x78): // IN E,(C)
res = IN(zBC);
zR8((Opcode >> 3) & 7) = res;
zF = (zF & CF) | SZP[res];
RET(8)
OPED(0x70): // IN 0,(C)
res = IN(zBC);
zF = (zF & CF) | SZP[res];
RET(8)
/*-----------------------------------------
OUT
-----------------------------------------*/
OPED(0x51): // OUT (C),D
OPED(0x41): // OUT (C),B
OPED(0x49): // OUT (C),C
OPED(0x59): // OUT (C),E
OPED(0x61): // OUT (C),H
OPED(0x69): // OUT (C),L
OPED(0x79): // OUT (C),E
res = zR8((Opcode >> 3) & 7);
OUT(zBC, res);
RET(8)
OPED(0x71): // OUT (C),0
OUT(zBC, 0);
RET(8)
/*-----------------------------------------
RETN
-----------------------------------------*/
OPED(0x45): // RETN;
OPED(0x55): // RETN;
OPED(0x65): // RETN;
OPED(0x75): // RETN;
POP_16(res);
SET_PC(res);
if (!zIFF1 && zIFF2)
{
zIFF1 = (1 << 2);
if (CPU->IRQState)
{
USE_CYCLES(10)
goto Cz80_Check_Interrupt;
}
}
else zIFF1 = zIFF2;
RET(10)
/*-----------------------------------------
RETI
-----------------------------------------*/
OPED(0x4d): // RETI
OPED(0x5d): // RETI
OPED(0x6d): // RETI
OPED(0x7d): // RETI
POP_16(res);
SET_PC(res);
RET(10)
/*-----------------------------------------
IM
-----------------------------------------*/
OPED(0x46): // IM 0
OPED(0x4e): // IM 0
OPED(0x66): // IM 0
OPED(0x6e): // IM 0
zIM = 0;
RET(4)
OPED(0x56): // IM 1
OPED(0x76): // IM 1
zIM = 1;
RET(4)
OPED(0x5e): // IM 2
OPED(0x7e): // IM 2
zIM = 2;
RET(4)
{
UINT8 val;
UINT8 res;
UINT8 F;
/*-----------------------------------------
LDI/LDD
-----------------------------------------*/
OPED(0xa0): // LDI
val = READ_MEM8(zHL++);
WRITE_MEM8(zDE++, val);
goto OP_LDX;
OPED(0xa8): // LDD
val = READ_MEM8(zHL--);
WRITE_MEM8(zDE--, val);
OP_LDX:
F = zF & (SF | ZF | CF);
if ((zA + val) & 0x02) F |= YF;
if ((zA + val) & 0x08) F |= XF;
if (--zBC) F |= VF;
zF = F;
RET(12)
/*-----------------------------------------
LDIR/LDDR
-----------------------------------------*/
OPED(0xb0): // LDIR
do
{
val = READ_MEM8(zHL++);
WRITE_MEM8(zDE++, val);
zBC--;
USE_CYCLES(17)
} while (zBC && (CPU->ICount > 0));
goto OP_LDXR;
OPED(0xb8): // LDDR
do
{
val = READ_MEM8(zHL--);
WRITE_MEM8(zDE--, val);
zBC--;
USE_CYCLES(17)
} while (zBC && (CPU->ICount > 0));
OP_LDXR:
F = zF & (SF | ZF | CF);
if ((zA + val) & 0x02) F |= YF;
if ((zA + val) & 0x08) F |= XF;
if (zBC)
{
zF = F | VF;
PC -= 2;
#if CZ80_EMULATE_R_EXACTLY
zR--;
#endif
goto Cz80_Exec_End;
}
zF = F;
ADD_CYCLES(5)
goto Cz80_Exec;
/*-----------------------------------------
CPI/CPD
-----------------------------------------*/
OPED(0xa1): // CPI
val = READ_MEM8(zHL++);
goto OP_CPX;
OPED(0xa9): // CPD
val = READ_MEM8(zHL--);
OP_CPX:
res = zA - val;
F = (zF & CF) | (SZ[res] & ~(YF | XF)) | ((zA ^ val ^ res) & HF) | NF;
if (F & HF) res--;
if (res & 0x02) F |= YF;
if (res & 0x08) F |= XF;
if (--zBC) F |= VF;
zF = F;
RET(12)
/*-----------------------------------------
CPIR/CPDR
-----------------------------------------*/
OPED(0xb1): // CPIR
do
{
val = READ_MEM8(zHL++);
res = zA - val;
zBC--;
F = (zF & CF) | (SZ[res] & ~(YF | XF)) | ((zA ^ val ^ res) & HF) | NF;
if (F & HF) res--;
if (res & 0x02) F |= YF;
if (res & 0x08) F |= XF;
if (zBC) F |= VF;
zF = F;
USE_CYCLES(17)
} while (zBC && !(F & ZF) && (CPU->ICount > 0));
goto OP_CPXR;
OPED(0xb9): // CPDR
do
{
val = READ_MEM8(zHL--);
res = zA - val;
zBC--;
F = (zF & CF) | (SZ[res] & ~(YF | XF)) | ((zA ^ val ^ res) & HF) | NF;
if (F & HF) res--;
if (res & 0x02) F |= YF;
if (res & 0x08) F |= XF;
if (zBC) F |= VF;
zF = F;
USE_CYCLES(17)
} while (zBC && !(F & ZF) && (CPU->ICount > 0));
OP_CPXR:
if (zBC && !(F & ZF))
{
PC -= 2;
#if CZ80_EMULATE_R_EXACTLY
zR--;
#endif
goto Cz80_Exec_End;
}
ADD_CYCLES(5)
goto Cz80_Exec;
/*-----------------------------------------
INI/IND
-----------------------------------------*/
OPED(0xa2): // INI
val = IN(zBC);
zB--;
WRITE_MEM8(zHL++, val);
goto OP_INX;
OPED(0xaa): // IND
val = IN(zBC);
zB--;
WRITE_MEM8(zHL--, val);
OP_INX:
F = SZ[zB];
res = ((UINT32)(zC - 1) & 0xff) + (UINT32)val;
if (val & SF) F |= NF;
if (res & 0x100) F |= HF | CF;
F |= SZP[(UINT8)(res & 0x07) ^ zB] & PF;
zF = F;
RET(12)
/*-----------------------------------------
INIR/INDR
-----------------------------------------*/
OPED(0xb2): // INIR
do
{
val = IN(zBC);
zB--;
WRITE_MEM8(zHL++, val);
USE_CYCLES(17)
} while (zB && (CPU->ICount > 0));
goto OP_INXR;
OPED(0xba): // INDR
do
{
val = IN(zBC);
zB--;
WRITE_MEM8(zHL--, val);
USE_CYCLES(17)
} while (zB && (CPU->ICount > 0));
OP_INXR:
F = SZ[zB];
res = ((UINT32)(zC - 1) & 0xff) + (UINT32)val;
if (val & SF) F |= NF;
if (res & 0x100) F |= HF | CF;
F |= SZP[(UINT8)(res & 0x07) ^ zB] & PF;
zF = F;
if (zB)
{
PC -= 2;
#if CZ80_EMULATE_R_EXACTLY
zR--;
#endif
goto Cz80_Exec_End;
}
ADD_CYCLES(5);
goto Cz80_Exec;
/*-----------------------------------------
OUTI/OUTD
-----------------------------------------*/
OPED(0xa3): // OUTI
val = READ_MEM8(zHL++);
zB--;
OUT(zBC, val);
goto OP_OUTX;
OPED(0xab): // OUTD
val = READ_MEM8(zHL--);
zB--;
OUT(zBC, val);
OP_OUTX:
F = SZ[zB];
res = (UINT32)zL + (UINT32)val;
if (val & SF) F |= NF;
if (res & 0x100) F |= HF | CF;
F |= SZP[(UINT8)(res & 0x07) - zB] & PF;
zF = F;
RET(12)
/*-----------------------------------------
OTIR/OTDR
-----------------------------------------*/
OPED(0xb3): // OTIR
do
{
val = READ_MEM8(zHL++);
zB--;
OUT(zBC, val);
USE_CYCLES(17)
} while (zB && (CPU->ICount > 0));
goto OP_OTXR;
OPED(0xbb): // OTDR
do
{
val = READ_MEM8(zHL--);
zB--;
OUT(zBC, val);
USE_CYCLES(17)
} while (zB && (CPU->ICount > 0));
OP_OTXR:
F = SZ[zB];
res = (UINT32)zL + (UINT32)val;
if (val & SF) F |= NF;
if (res & 0x100) F |= HF | CF;
F |= SZP[(UINT8)(res & 0x07) - zB] & PF;
zF = F;
if (zB)
{
PC -= 2;
#if CZ80_EMULATE_R_EXACTLY
zR--;
#endif
goto Cz80_Exec_End;
}
ADD_CYCLES(5)
goto Cz80_Exec;
}
#if !CZ80_USE_JUMPTABLE
}
#endif

786
cpu/cz80/cz80_opXY.c Normal file
View file

@ -0,0 +1,786 @@
/******************************************************************************
*
* CZ80 XY opcode include source file
* CZ80 emulator version 0.9
* Copyright 2004-2005 Stéphane Dallongeville
*
* (Modified by NJ)
*
*****************************************************************************/
#if CZ80_USE_JUMPTABLE
goto *JumpTableXY[Opcode];
#else
switch (Opcode)
{
#endif
/*-----------------------------------------
NOP
-----------------------------------------*/
OPXY(0x00): // NOP
/*-----------------------------------------
LD r8 (same register)
-----------------------------------------*/
OPXY(0x40): // LD B,B
OPXY(0x49): // LD C,C
OPXY(0x52): // LD D,D
OPXY(0x5b): // LD E,E
OPXY(0x64): // LD H,H
OPXY(0x6d): // LD L,L
OPXY(0x7f): // LD A,A
RET(4)
/*-----------------------------------------
LD r8
-----------------------------------------*/
OPXY(0x41): // LD B,C
OPXY(0x42): // LD B,D
OPXY(0x43): // LD B,E
OPXY(0x47): // LD B,A
OPXY(0x48): // LD C,B
OPXY(0x4a): // LD C,D
OPXY(0x4b): // LD C,E
OPXY(0x4f): // LD C,A
OPXY(0x50): // LD D,B
OPXY(0x51): // LD D,C
OPXY(0x53): // LD D,E
OPXY(0x57): // LD D,A
OPXY(0x58): // LD E,B
OPXY(0x59): // LD E,C
OPXY(0x5a): // LD E,D
OPXY(0x5f): // LD E,A
OPXY(0x78): // LD A,B
OPXY(0x79): // LD A,C
OPXY(0x7a): // LD A,D
OPXY(0x7b): // LD A,E
goto OP_LD_R_R;
OPXY(0x44): // LD B,HX
OPXY(0x4c): // LD C,HX
OPXY(0x54): // LD D,HX
OPXY(0x5c): // LD E,HX
OPXY(0x7c): // LD A,HX
zR8((Opcode >> 3) & 7) = data->B.H;
RET(5)
OPXY(0x45): // LD B,LX
OPXY(0x4d): // LD C,LX
OPXY(0x55): // LD D,LX
OPXY(0x5d): // LD E,LX
OPXY(0x7d): // LD A,LX
zR8((Opcode >> 3) & 7) = data->B.L;
RET(5)
OPXY(0x60): // LD HX,B
OPXY(0x61): // LD HX,C
OPXY(0x62): // LD HX,D
OPXY(0x63): // LD HX,E
OPXY(0x67): // LD HX,A
data->B.H = zR8(Opcode & 7);
RET(5)
OPXY(0x68): // LD LX,B
OPXY(0x69): // LD LX,C
OPXY(0x6a): // LD LX,D
OPXY(0x6b): // LD LX,E
OPXY(0x6f): // LD LX,A
data->B.L = zR8(Opcode & 7);
RET(5)
OPXY(0x65): // LD HX,LX
data->B.H = data->B.L;
RET(5)
OPXY(0x6c): // LD LX,HX
data->B.L = data->B.H;
RET(5)
OPXY(0x06): // LD B,#imm
OPXY(0x0e): // LD C,#imm
OPXY(0x16): // LD D,#imm
OPXY(0x1e): // LD E,#imm
OPXY(0x3e): // LD A,#imm
goto OP_LD_R_imm;
OPXY(0x26): // LD HX,#imm
data->B.H = READ_ARG();
RET(5)
OPXY(0x2e): // LD LX,#imm
data->B.L = READ_ARG();
RET(5)
OPXY(0x0a): // LD A,(BC)
goto OP_LOAD_A_mBC;
OPXY(0x1a): // LD A,(DE)
goto OP_LOAD_A_mDE;
OPXY(0x3a): // LD A,(nn)
goto OP_LOAD_A_mNN;
OPXY(0x02): // LD (BC),A
goto OP_LOAD_mBC_A;
OPXY(0x12): // LD (DE),A
goto OP_LOAD_mDE_A;
OPXY(0x32): // LD (nn),A
goto OP_LOAD_mNN_A;
OPXY(0x46): // LD B,(IX+o)
OPXY(0x4e): // LD C,(IX+o)
OPXY(0x56): // LD D,(IX+o)
OPXY(0x5e): // LD E,(IX+o)
OPXY(0x66): // LD H,(IX+o)
OPXY(0x6e): // LD L,(IX+o)
OPXY(0x7e): // LD A,(IX+o)
adr = data->W + (INT8)READ_ARG();
zR8((Opcode >> 3) & 7) = READ_MEM8(adr);
RET(15)
OPXY(0x70): // LD (IX+o),B
OPXY(0x71): // LD (IX+o),C
OPXY(0x72): // LD (IX+o),D
OPXY(0x73): // LD (IX+o),E
OPXY(0x74): // LD (IX+o),H
OPXY(0x75): // LD (IX+o),L
OPXY(0x77): // LD (IX+o),A
adr = data->W + (INT8)READ_ARG();
WRITE_MEM8(adr, zR8(Opcode & 7));
RET(15)
OPXY(0x36): // LD (IX+o),#imm
adr = data->W + (INT8)READ_ARG();
WRITE_MEM8(adr, READ_ARG());
RET(15)
/*-----------------------------------------
LD r16
-----------------------------------------*/
OPXY(0x01): // LD BC,nn
OPXY(0x11): // LD DE,nn
goto OP_LOAD_RR_imm16;
OPXY(0x21): // LD IX,nn
data->W = READ_ARG16();
RET(10)
OPXY(0x31): // LD SP,nn
goto OP_LOAD_SP_imm16;
OPXY(0x2a): // LD IX,(w)
goto OP_LD_xx_mNN;
OPXY(0x22): // LD (w),IX
goto OP_LD_mNN_xx;
OPXY(0xf9): // LD SP,IX
goto OP_LD_SP_xx;
/*-----------------------------------------
POP
-----------------------------------------*/
OPXY(0xc1): // POP BC
OPXY(0xd1): // POP DE
OPXY(0xf1): // POP AF
goto OP_POP_RR;
OPXY(0xe1): // POP IX
goto OP_POP;
/*-----------------------------------------
PUSH
-----------------------------------------*/
OPXY(0xc5): // PUSH BC
OPXY(0xd5): // PUSH DE
OPXY(0xf5): // PUSH AF
goto OP_PUSH_RR;
OPXY(0xe5): // PUSH IX
goto OP_PUSH;
/*-----------------------------------------
EX
-----------------------------------------*/
OPXY(0x08): // EX AF,AF'
goto OP_EX_AF_AF2;
OPXY(0xeb): // EX DE,HL
goto OP_EX_DE_HL;
OPXY(0xd9): // EXX
goto OP_EXX;
OPXY(0xe3): // EX (SP),IX
goto OP_EX_xx_mSP;
/*-----------------------------------------
INC r8
-----------------------------------------*/
OPXY(0x04): // INC B
OPXY(0x0c): // INC C
OPXY(0x14): // INC D
OPXY(0x1c): // INC E
OPXY(0x3c): // INC A
goto OP_INC_R;
OPXY(0x24): // INC HX
data->B.H++;
zF = (zF & CF) | SZHV_inc[data->B.H];
RET(5)
OPXY(0x2c): // INC LX
data->B.L++;
zF = (zF & CF) | SZHV_inc[data->B.L];
RET(5)
OPXY(0x34): // INC (IX+o)
adr = data->W + (INT8)READ_ARG();
USE_CYCLES(8)
goto OP_INC_m;
/*-----------------------------------------
DEC r8
-----------------------------------------*/
OPXY(0x05): // DEC B
OPXY(0x0d): // DEC C
OPXY(0x15): // DEC D
OPXY(0x1d): // DEC E
OPXY(0x3d): // DEC A
goto OP_DEC_R;
OPXY(0x25): // DEC HX
data->B.H--;
zF = (zF & CF) | SZHV_dec[data->B.H];
RET(5)
OPXY(0x2d): // DEC LX
data->B.L--;
zF = (zF & CF) | SZHV_dec[data->B.L];
RET(5)
OPXY(0x35): // DEC (IX+o)
adr = data->W + (INT8)READ_ARG();
USE_CYCLES(8)
goto OP_DEC_m;
/*-----------------------------------------
ADD r8
-----------------------------------------*/
OPXY(0x80): // ADD A,B
OPXY(0x81): // ADD A,C
OPXY(0x82): // ADD A,D
OPXY(0x83): // ADD A,E
OPXY(0x87): // ADD A,A
goto OP_ADD_R;
OPXY(0xc6): // ADD A,n
goto OP_ADD_imm;
OPXY(0x84): // ADD A,HX
val = data->B.H;
USE_CYCLES(1)
goto OP_ADD;
OPXY(0x85): // ADD A,LX
val = data->B.L;
USE_CYCLES(1)
goto OP_ADD;
OPXY(0x86): // ADD A,(IX+o)
adr = data->W + (INT8)READ_ARG();
val = READ_MEM8(adr);
USE_CYCLES(11)
goto OP_ADD;
/*-----------------------------------------
ADC r8
-----------------------------------------*/
OPXY(0x88): // ADC A,B
OPXY(0x89): // ADC A,C
OPXY(0x8a): // ADC A,D
OPXY(0x8b): // ADC A,E
OPXY(0x8f): // ADC A,A
goto OP_ADC_R;
OPXY(0xce): // ADC A,n
goto OP_ADC_imm;
OPXY(0x8c): // ADC A,HX
val = data->B.H;
USE_CYCLES(1)
goto OP_ADC;
OPXY(0x8d): // ADC A,LX
val = data->B.L;
USE_CYCLES(1)
goto OP_ADC;
OPXY(0x8e): // ADC A,(IX+o)
adr = data->W + (INT8)READ_ARG();
val = READ_MEM8(adr);
USE_CYCLES(11)
goto OP_ADC;
/*-----------------------------------------
SUB r8
-----------------------------------------*/
OPXY(0x90): // SUB B
OPXY(0x91): // SUB C
OPXY(0x92): // SUB D
OPXY(0x93): // SUB E
OPXY(0x97): // SUB A
goto OP_SUB_R;
OPXY(0xd6): // SUB A,n
goto OP_SUB_imm;
OPXY(0x94): // SUB HX
val = data->B.H;
USE_CYCLES(1)
goto OP_SUB;
OPXY(0x95): // SUB LX
val = data->B.L;
USE_CYCLES(1)
goto OP_SUB;
OPXY(0x96): // SUB (IX+o)
adr = data->W + (INT8)READ_ARG();
val = READ_MEM8(adr);
USE_CYCLES(11)
goto OP_SUB;
/*-----------------------------------------
SBC r8
-----------------------------------------*/
OPXY(0x98): // SBC A,B
OPXY(0x99): // SBC A,C
OPXY(0x9a): // SBC A,D
OPXY(0x9b): // SBC A,E
OPXY(0x9f): // SBC A,A
goto OP_SBC_R;
OPXY(0xde): // SBC A,n
goto OP_SBC_imm;
OPXY(0x9c): // SBC A,HX
val = data->B.H;
USE_CYCLES(1)
goto OP_SBC;
OPXY(0x9d): // SBC A,LX
val = data->B.L;
USE_CYCLES(1)
goto OP_SBC;
OPXY(0x9e): // SBC A,(IX+o)
adr = data->W + (INT8)READ_ARG();
val = READ_MEM8(adr);
USE_CYCLES(11)
goto OP_SBC;
/*-----------------------------------------
CP r8
-----------------------------------------*/
OPXY(0xb8): // CP B
OPXY(0xb9): // CP C
OPXY(0xba): // CP D
OPXY(0xbb): // CP E
OPXY(0xbf): // CP A
goto OP_CP_R;
OPXY(0xfe): // CP n
goto OP_CP_imm;
OPXY(0xbc): // CP HX
val = data->B.H;
USE_CYCLES(1)
goto OP_CP;
OPXY(0xbd): // CP LX
val = data->B.L;
USE_CYCLES(1)
goto OP_CP;
OPXY(0xbe): // CP (IX+o)
adr = data->W + (INT8)READ_ARG();
val = READ_MEM8(adr);
USE_CYCLES(11)
goto OP_CP;
/*-----------------------------------------
AND r8
-----------------------------------------*/
OPXY(0xa0): // AND B
OPXY(0xa1): // AND C
OPXY(0xa2): // AND D
OPXY(0xa3): // AND E
OPXY(0xa7): // AND A
goto OP_AND_R;
OPXY(0xe6): // AND A,n
goto OP_AND_imm;
OPXY(0xa4): // AND HX
val = data->B.H;
USE_CYCLES(1)
goto OP_AND;
OPXY(0xa5): // AND LX
val = data->B.L;
USE_CYCLES(1)
goto OP_AND;
OPXY(0xa6): // AND (IX+o)
adr = data->W + (INT8)READ_ARG();
val = READ_MEM8(adr);
USE_CYCLES(11)
goto OP_AND;
/*-----------------------------------------
XOR r8
-----------------------------------------*/
OPXY(0xa8): // XOR B
OPXY(0xa9): // XOR C
OPXY(0xaa): // XOR D
OPXY(0xab): // XOR E
OPXY(0xaf): // XOR A
goto OP_XOR_R;
OPXY(0xee): // XOR A,n
goto OP_XOR_imm;
OPXY(0xac): // XOR HX
val = data->B.H;
USE_CYCLES(1)
goto OP_XOR;
OPXY(0xad): // XOR LX
val = data->B.L;
USE_CYCLES(1)
goto OP_XOR;
OPXY(0xae): // XOR (IX+o)
adr = data->W + (INT8)READ_ARG();
val = READ_MEM8(adr);
USE_CYCLES(11)
goto OP_XOR;
/*-----------------------------------------
OR r8
-----------------------------------------*/
OPXY(0xb0): // OR B
OPXY(0xb1): // OR C
OPXY(0xb2): // OR D
OPXY(0xb3): // OR E
OPXY(0xb7): // OR A
goto OP_OR_R;
OPXY(0xf6): // OR A,n
goto OP_OR_imm;
OPXY(0xb4): // OR HX
val = data->B.H;
USE_CYCLES(1)
goto OP_OR;
OPXY(0xb5): // OR LX
val = data->B.L;
USE_CYCLES(1)
goto OP_OR;
OPXY(0xb6): // OR (IX+o)
adr = data->W + (INT8)READ_ARG();
val = READ_MEM8(adr);
USE_CYCLES(11)
goto OP_OR;
/*-----------------------------------------
MISC ARITHMETIC & CPU CONTROL
-----------------------------------------*/
OPXY(0x27): // DAA
goto OP_DAA;
OPXY(0x2f): // CPL
goto OP_CPL;
OPXY(0x37): // SCF
goto OP_SCF;
OPXY(0x3f): // CCF
goto OP_CCF;
OPXY(0x76): // HALT
goto OP_HALT;
OPXY(0xf3): // DI
goto OP_DI;
OPXY(0xfb): // EI
goto OP_EI;
/*-----------------------------------------
INC r16
-----------------------------------------*/
OPXY(0x03): // INC BC
goto OP_INC_BC;
OPXY(0x13): // INC DE
goto OP_INC_DE;
OPXY(0x23): // INC IX
goto OP_INC_xx;
OPXY(0x33): // INC SP
goto OP_INC_SP;
/*-----------------------------------------
DEC r16
-----------------------------------------*/
OPXY(0x0b): // DEC BC
goto OP_DEC_BC;
OPXY(0x1b): // DEC DE
goto OP_DEC_DE;
OPXY(0x2b): // DEC IX
goto OP_DEC_xx;
OPXY(0x3b): // DEC SP
goto OP_DEC_SP;
/*-----------------------------------------
ADD r16
-----------------------------------------*/
OPXY(0x09): // ADD IX,BC
goto OP_ADD16_xx_BC;
OPXY(0x19): // ADD IX,DE
goto OP_ADD16_xx_DE;
OPXY(0x29): // ADD IX,IX
goto OP_ADD16_xx_xx;
OPXY(0x39): // ADD IX,SP
goto OP_ADD16_xx_SP;
/*-----------------------------------------
ROTATE
-----------------------------------------*/
OPXY(0x07): // RLCA
goto OP_RLCA;
OPXY(0x0f): // RRCA
goto OP_RRCA;
OPXY(0x17): // RLA
goto OP_RLA;
OPXY(0x1f): // RRA
goto OP_RRA;
/*-----------------------------------------
JP
-----------------------------------------*/
OPXY(0xc3): // JP nn
goto OP_JP;
OPXY(0xe9): // JP (IX)
goto OP_JP_xx;
OPXY(0xc2): // JP NZ,nn
goto OP_JP_NZ;
OPXY(0xca): // JP Z,nn
goto OP_JP_Z;
OPXY(0xd2): // JP NC,nn
goto OP_JP_NC;
OPXY(0xda): // JP C,nn
goto OP_JP_C;
OPXY(0xe2): // JP PO,nn
goto OP_JP_PO;
OPXY(0xea): // JP PE,nn
goto OP_JP_PE;
OPXY(0xf2): // JP P,nn
goto OP_JP_P;
OPXY(0xfa): // JP M,nn
goto OP_JP_M;
/*-----------------------------------------
JR
-----------------------------------------*/
OPXY(0x10): // DJNZ n
goto OP_DJNZ;
OPXY(0x18): // JR n
goto OP_JR;
OPXY(0x20): // JR NZ,n
goto OP_JR_NZ;
OPXY(0x28): // JR Z,n
goto OP_JR_Z;
OPXY(0x30): // JR NC,n
goto OP_JR_NC;
OPXY(0x38): // JR C,n
goto OP_JR_C;
/*-----------------------------------------
CALL
-----------------------------------------*/
OPXY(0xcd): // CALL nn
goto OP_CALL;
OPXY(0xc4): // CALL NZ,nn
goto OP_CALL_NZ;
OPXY(0xcc): // CALL Z,nn
goto OP_CALL_Z;
OPXY(0xd4): // CALL NC,nn
goto OP_CALL_NC;
OPXY(0xdc): // CALL C,nn
goto OP_CALL_C;
OPXY(0xe4): // CALL PO,nn
goto OP_CALL_PO;
OPXY(0xec): // CALL PE,nn
goto OP_CALL_PE;
OPXY(0xf4): // CALL P,nn
goto OP_CALL_P;
OPXY(0xfc): // CALL M,nn
goto OP_CALL_M;
/*-----------------------------------------
RET
-----------------------------------------*/
OPXY(0xc9): // RET
goto OP_RET;
OPXY(0xc0): // RET NZ
goto OP_RET_NZ;
OPXY(0xc8): // RET Z
goto OP_RET_Z;
OPXY(0xd0): // RET NC
goto OP_RET_NC;
OPXY(0xd8): // RET C
goto OP_RET_C;
OPXY(0xe0): // RET PO
goto OP_RET_PO;
OPXY(0xe8): // RET PE
goto OP_RET_PE;
OPXY(0xf0): // RET P
goto OP_RET_P;
OPXY(0xf8): // RET M
goto OP_RET_M;
/*-----------------------------------------
RST
-----------------------------------------*/
OPXY(0xc7): // RST 0
OPXY(0xcf): // RST 1
OPXY(0xd7): // RST 2
OPXY(0xdf): // RST 3
OPXY(0xe7): // RST 4
OPXY(0xef): // RST 5
OPXY(0xf7): // RST 6
OPXY(0xff): // RST 7
goto OP_RST;
/*-----------------------------------------
OUT
-----------------------------------------*/
OPXY(0xd3): // OUT (n),A
goto OP_OUT_mN_A;
/*-----------------------------------------
IN
-----------------------------------------*/
OPXY(0xdb): // IN A,(n)
goto OP_IN_A_mN;
/*-----------------------------------------
PREFIX
-----------------------------------------*/
OPXY(0xcb): // XYCB prefix (BIT & SHIFT INSTRUCTIONS)
{
UINT8 src;
UINT8 res;
adr = data->W + (INT8)READ_ARG();
Opcode = READ_ARG();
#if CZ80_EMULATE_R_EXACTLY
zR++;
#endif
#include "cz80_opXYCB.c"
}
OPXY(0xed): // ED prefix
goto ED_PREFIX;
OPXY(0xdd): // DD prefix (IX)
goto DD_PREFIX;
OPXY(0xfd): // FD prefix (IY)
goto FD_PREFIX;
#if !CZ80_USE_JUMPTABLE
}
#endif

474
cpu/cz80/cz80_opXYCB.c Normal file
View file

@ -0,0 +1,474 @@
/******************************************************************************
*
* CZ80 XYCB opcode include source file
* CZ80 emulator version 0.9
* Copyright 2004-2005 Stéphane Dallongeville
*
* (Modified by NJ)
*
*****************************************************************************/
#if CZ80_USE_JUMPTABLE
goto *JumpTableXYCB[Opcode];
#else
switch (Opcode)
{
#endif
/*-----------------------------------------
RLC
-----------------------------------------*/
OPXYCB(0x00): // RLC (Ix+d), B
OPXYCB(0x01): // RLC (Ix+d), C
OPXYCB(0x02): // RLC (Ix+d), D
OPXYCB(0x03): // RLC (Ix+d), E
OPXYCB(0x04): // RLC (Ix+d), H
OPXYCB(0x05): // RLC (Ix+d), L
OPXYCB(0x07): // RLC (Ix+d), A
src = READ_MEM8(adr);
res = ((src << 1) | (src >> 7)) & 0xff;
zF = SZP[res] | (src >> 7);
zR8(Opcode) = res;
WRITE_MEM8(adr, res);
RET(19)
OPXYCB(0x06): // RLC (Ix+d)
src = READ_MEM8(adr);
res = ((src << 1) | (src >> 7)) & 0xff;
zF = SZP[res] | (src >> 7);
WRITE_MEM8(adr, res);
RET(19)
/*-----------------------------------------
RRC
-----------------------------------------*/
OPXYCB(0x08): // RRC (Ix+d), B
OPXYCB(0x09): // RRC (Ix+d), C
OPXYCB(0x0a): // RRC (Ix+d), D
OPXYCB(0x0b): // RRC (Ix+d), E
OPXYCB(0x0c): // RRC (Ix+d), H
OPXYCB(0x0d): // RRC (Ix+d), L
OPXYCB(0x0f): // RRC (Ix+d), A
src = READ_MEM8(adr);
res = ((src >> 1) | (src << 7)) & 0xff;
zF = SZP[res] | (src & CF);
zR8(Opcode & 7) = res;
WRITE_MEM8(adr, res);
RET(19)
OPXYCB(0x0e): // RRC (Ix+d)
src = READ_MEM8(adr);
res = ((src >> 1) | (src << 7)) & 0xff;
zF = SZP[res] | (src & CF);
WRITE_MEM8(adr, res);
RET(19)
/*-----------------------------------------
RL
-----------------------------------------*/
OPXYCB(0x10): // RL (Ix+d), B
OPXYCB(0x11): // RL (Ix+d), C
OPXYCB(0x12): // RL (Ix+d), D
OPXYCB(0x13): // RL (Ix+d), E
OPXYCB(0x14): // RL (Ix+d), H
OPXYCB(0x15): // RL (Ix+d), L
OPXYCB(0x17): // RL (Ix+d), A
src = READ_MEM8(adr);
res = ((src << 1) | (zF & CF)) & 0xff;
zF = SZP[res] | (src >> 7);
zR8(Opcode & 7) = res;
WRITE_MEM8(adr, res);
RET(19)
OPXYCB(0x16): // RL (Ix+d)
src = READ_MEM8(adr);
res = ((src << 1) | (zF & CF)) & 0xff;
zF = SZP[res] | (src >> 7);
WRITE_MEM8(adr, res);
RET(19)
/*-----------------------------------------
RR
-----------------------------------------*/
OPXYCB(0x18): // RR (Ix+d), B
OPXYCB(0x19): // RR (Ix+d), C
OPXYCB(0x1a): // RR (Ix+d), D
OPXYCB(0x1b): // RR (Ix+d), E
OPXYCB(0x1c): // RR (Ix+d), H
OPXYCB(0x1d): // RR (Ix+d), L
OPXYCB(0x1f): // RR (Ix+d), A
src = READ_MEM8(adr);
res = ((src >> 1) | (zF << 7)) & 0xff;
zF = SZP[res] | (src & CF);
zR8(Opcode & 7) = res;
WRITE_MEM8(adr, res);
RET(19)
OPXYCB(0x1e): // RR (Ix+d)
src = READ_MEM8(adr);
res = ((src >> 1) | (zF << 7)) & 0xff;
zF = SZP[res] | (src & CF);
WRITE_MEM8(adr, res);
RET(19)
/*-----------------------------------------
SLA
-----------------------------------------*/
OPXYCB(0x20): // SLA (Ix+d), B
OPXYCB(0x21): // SLA (Ix+d), C
OPXYCB(0x22): // SLA (Ix+d), D
OPXYCB(0x23): // SLA (Ix+d), E
OPXYCB(0x24): // SLA (Ix+d), H
OPXYCB(0x25): // SLA (Ix+d), L
OPXYCB(0x27): // SLA (Ix+d), A
src = READ_MEM8(adr);
res = (src << 1) & 0xff;
zF = SZP[res] | (src >> 7);
zR8(Opcode & 7) = res;
WRITE_MEM8(adr, res);
RET(19)
OPXYCB(0x26): // SLA (Ix+d)
src = READ_MEM8(adr);
res = (src << 1) & 0xff;
zF = SZP[res] | (src >> 7);
WRITE_MEM8(adr, res);
RET(19)
/*-----------------------------------------
SRA
-----------------------------------------*/
OPXYCB(0x28): // SRA (Ix+d), B
OPXYCB(0x29): // SRA (Ix+d), C
OPXYCB(0x2a): // SRA (Ix+d), D
OPXYCB(0x2b): // SRA (Ix+d), E
OPXYCB(0x2c): // SRA (Ix+d), H
OPXYCB(0x2d): // SRA (Ix+d), L
OPXYCB(0x2f): // SRA (Ix+d), A
src = READ_MEM8(adr);
res = ((src >> 1) | (src & 0x80)) & 0xff;
zF = SZP[res] | (src & CF);
zR8(Opcode & 7) = res;
WRITE_MEM8(adr, res);
RET(19)
OPXYCB(0x2e): // SRA (Ix+d)
src = READ_MEM8(adr);
res = ((src >> 1) | (src & 0x80)) & 0xff;
zF = SZP[res] | (src & CF);
WRITE_MEM8(adr, res);
RET(19)
/*-----------------------------------------
SLL
-----------------------------------------*/
OPXYCB(0x30): // SLL (Ix+d), B
OPXYCB(0x31): // SLL (Ix+d), C
OPXYCB(0x32): // SLL (Ix+d), D
OPXYCB(0x33): // SLL (Ix+d), E
OPXYCB(0x34): // SLL (Ix+d), H
OPXYCB(0x35): // SLL (Ix+d), L
OPXYCB(0x37): // SLL (Ix+d), A
src = READ_MEM8(adr);
res = ((src << 1) | 0x01) & 0xff;
zF = SZP[res] | (src >> 7);
zR8(Opcode & 7) = res;
WRITE_MEM8(adr, res);
RET(19)
OPXYCB(0x36): // SLL (Ix+d)
src = READ_MEM8(adr);
res = ((src << 1) | 0x01) & 0xff;
zF = SZP[res] | (src >> 7);
WRITE_MEM8(adr, res);
RET(19)
/*-----------------------------------------
SRL
-----------------------------------------*/
OPXYCB(0x38): // SRL (Ix+d), B
OPXYCB(0x39): // SRL (Ix+d), C
OPXYCB(0x3a): // SRL (Ix+d), D
OPXYCB(0x3b): // SRL (Ix+d), E
OPXYCB(0x3c): // SRL (Ix+d), H
OPXYCB(0x3d): // SRL (Ix+d), L
OPXYCB(0x3f): // SRL (Ix+d), A
src = READ_MEM8(adr);
res = (src >> 1) & 0xff;
zF = SZP[res] | (src & CF);
zR8(Opcode & 7) = res;
WRITE_MEM8(adr, res);
RET(19)
OPXYCB(0x3e): // SRL (Ix+d)
src = READ_MEM8(adr);
res = (src >> 1) & 0xff;
zF = SZP[res] | (src & CF);
WRITE_MEM8(adr, res);
RET(19)
/*-----------------------------------------
BIT
-----------------------------------------*/
OPXYCB(0x40): // BIT 0,(Ix+d)
OPXYCB(0x41): // BIT 0,(Ix+d)
OPXYCB(0x42): // BIT 0,(Ix+d)
OPXYCB(0x43): // BIT 0,(Ix+d)
OPXYCB(0x44): // BIT 0,(Ix+d)
OPXYCB(0x45): // BIT 0,(Ix+d)
OPXYCB(0x47): // BIT 0,(Ix+d)
OPXYCB(0x48): // BIT 1,(Ix+d)
OPXYCB(0x49): // BIT 1,(Ix+d)
OPXYCB(0x4a): // BIT 1,(Ix+d)
OPXYCB(0x4b): // BIT 1,(Ix+d)
OPXYCB(0x4c): // BIT 1,(Ix+d)
OPXYCB(0x4d): // BIT 1,(Ix+d)
OPXYCB(0x4f): // BIT 1,(Ix+d)
OPXYCB(0x50): // BIT 2,(Ix+d)
OPXYCB(0x51): // BIT 2,(Ix+d)
OPXYCB(0x52): // BIT 2,(Ix+d)
OPXYCB(0x53): // BIT 2,(Ix+d)
OPXYCB(0x54): // BIT 2,(Ix+d)
OPXYCB(0x55): // BIT 2,(Ix+d)
OPXYCB(0x57): // BIT 2,(Ix+d)
OPXYCB(0x58): // BIT 3,(Ix+d)
OPXYCB(0x59): // BIT 3,(Ix+d)
OPXYCB(0x5a): // BIT 3,(Ix+d)
OPXYCB(0x5b): // BIT 3,(Ix+d)
OPXYCB(0x5c): // BIT 3,(Ix+d)
OPXYCB(0x5d): // BIT 3,(Ix+d)
OPXYCB(0x5f): // BIT 3,(Ix+d)
OPXYCB(0x60): // BIT 4,(Ix+d)
OPXYCB(0x61): // BIT 4,(Ix+d)
OPXYCB(0x62): // BIT 4,(Ix+d)
OPXYCB(0x63): // BIT 4,(Ix+d)
OPXYCB(0x64): // BIT 4,(Ix+d)
OPXYCB(0x65): // BIT 4,(Ix+d)
OPXYCB(0x67): // BIT 4,(Ix+d)
OPXYCB(0x68): // BIT 5,(Ix+d)
OPXYCB(0x69): // BIT 5,(Ix+d)
OPXYCB(0x6a): // BIT 5,(Ix+d)
OPXYCB(0x6b): // BIT 5,(Ix+d)
OPXYCB(0x6c): // BIT 5,(Ix+d)
OPXYCB(0x6d): // BIT 5,(Ix+d)
OPXYCB(0x6f): // BIT 5,(Ix+d)
OPXYCB(0x70): // BIT 6,(Ix+d)
OPXYCB(0x71): // BIT 6,(Ix+d)
OPXYCB(0x72): // BIT 6,(Ix+d)
OPXYCB(0x73): // BIT 6,(Ix+d)
OPXYCB(0x74): // BIT 6,(Ix+d)
OPXYCB(0x75): // BIT 6,(Ix+d)
OPXYCB(0x77): // BIT 6,(Ix+d)
OPXYCB(0x78): // BIT 7,(Ix+d)
OPXYCB(0x79): // BIT 7,(Ix+d)
OPXYCB(0x7a): // BIT 7,(Ix+d)
OPXYCB(0x7b): // BIT 7,(Ix+d)
OPXYCB(0x7c): // BIT 7,(Ix+d)
OPXYCB(0x7d): // BIT 7,(Ix+d)
OPXYCB(0x7f): // BIT 7,(Ix+d)
OPXYCB(0x46): // BIT 0,(Ix+d)
OPXYCB(0x4e): // BIT 1,(Ix+d)
OPXYCB(0x56): // BIT 2,(Ix+d)
OPXYCB(0x5e): // BIT 3,(Ix+d)
OPXYCB(0x66): // BIT 4,(Ix+d)
OPXYCB(0x6e): // BIT 5,(Ix+d)
OPXYCB(0x76): // BIT 6,(Ix+d)
OPXYCB(0x7e): // BIT 7,(Ix+d)
src = READ_MEM8(adr);
zF = (zF & CF) | HF |
(SZ_BIT[src & (1 << ((Opcode >> 3) & 7))] & ~(YF | XF)) |
((adr >> 8) & (YF | XF));
RET(16)
/*-----------------------------------------
RES
-----------------------------------------*/
OPXYCB(0x80): // RES 0,(Ix+d),B
OPXYCB(0x81): // RES 0,(Ix+d),C
OPXYCB(0x82): // RES 0,(Ix+d),D
OPXYCB(0x83): // RES 0,(Ix+d),E
OPXYCB(0x84): // RES 0,(Ix+d),H
OPXYCB(0x85): // RES 0,(Ix+d),L
OPXYCB(0x87): // RES 0,(Ix+d),A
OPXYCB(0x88): // RES 1,(Ix+d),B
OPXYCB(0x89): // RES 1,(Ix+d),C
OPXYCB(0x8a): // RES 1,(Ix+d),D
OPXYCB(0x8b): // RES 1,(Ix+d),E
OPXYCB(0x8c): // RES 1,(Ix+d),H
OPXYCB(0x8d): // RES 1,(Ix+d),L
OPXYCB(0x8f): // RES 1,(Ix+d),A
OPXYCB(0x90): // RES 2,(Ix+d),B
OPXYCB(0x91): // RES 2,(Ix+d),C
OPXYCB(0x92): // RES 2,(Ix+d),D
OPXYCB(0x93): // RES 2,(Ix+d),E
OPXYCB(0x94): // RES 2,(Ix+d),H
OPXYCB(0x95): // RES 2,(Ix+d),L
OPXYCB(0x97): // RES 2,(Ix+d),A
OPXYCB(0x98): // RES 3,(Ix+d),B
OPXYCB(0x99): // RES 3,(Ix+d),C
OPXYCB(0x9a): // RES 3,(Ix+d),D
OPXYCB(0x9b): // RES 3,(Ix+d),E
OPXYCB(0x9c): // RES 3,(Ix+d),H
OPXYCB(0x9d): // RES 3,(Ix+d),L
OPXYCB(0x9f): // RES 3,(Ix+d),A
OPXYCB(0xa0): // RES 4,(Ix+d),B
OPXYCB(0xa1): // RES 4,(Ix+d),C
OPXYCB(0xa2): // RES 4,(Ix+d),D
OPXYCB(0xa3): // RES 4,(Ix+d),E
OPXYCB(0xa4): // RES 4,(Ix+d),H
OPXYCB(0xa5): // RES 4,(Ix+d),L
OPXYCB(0xa7): // RES 4,(Ix+d),A
OPXYCB(0xa8): // RES 5,(Ix+d),B
OPXYCB(0xa9): // RES 5,(Ix+d),C
OPXYCB(0xaa): // RES 5,(Ix+d),D
OPXYCB(0xab): // RES 5,(Ix+d),E
OPXYCB(0xac): // RES 5,(Ix+d),H
OPXYCB(0xad): // RES 5,(Ix+d),L
OPXYCB(0xaf): // RES 5,(Ix+d),A
OPXYCB(0xb0): // RES 6,(Ix+d),B
OPXYCB(0xb1): // RES 6,(Ix+d),C
OPXYCB(0xb2): // RES 6,(Ix+d),D
OPXYCB(0xb3): // RES 6,(Ix+d),E
OPXYCB(0xb4): // RES 6,(Ix+d),H
OPXYCB(0xb5): // RES 6,(Ix+d),L
OPXYCB(0xb7): // RES 6,(Ix+d),A
OPXYCB(0xb8): // RES 7,(Ix+d),B
OPXYCB(0xb9): // RES 7,(Ix+d),C
OPXYCB(0xba): // RES 7,(Ix+d),D
OPXYCB(0xbb): // RES 7,(Ix+d),E
OPXYCB(0xbc): // RES 7,(Ix+d),H
OPXYCB(0xbd): // RES 7,(Ix+d),L
OPXYCB(0xbf): // RES 7,(Ix+d),A
res = READ_MEM8(adr);
res &= ~(1 << ((Opcode >> 3) & 7));
zR8(Opcode & 7) = res;
WRITE_MEM8(adr, res);
RET(19)
OPXYCB(0x86): // RES 0,(Ix+d)
OPXYCB(0x8e): // RES 1,(Ix+d)
OPXYCB(0x96): // RES 2,(Ix+d)
OPXYCB(0x9e): // RES 3,(Ix+d)
OPXYCB(0xa6): // RES 4,(Ix+d)
OPXYCB(0xae): // RES 5,(Ix+d)
OPXYCB(0xb6): // RES 6,(Ix+d)
OPXYCB(0xbe): // RES 7,(Ix+d)
res = READ_MEM8(adr);
res &= ~(1 << ((Opcode >> 3) & 7));
WRITE_MEM8(adr, res);
RET(19)
/*-----------------------------------------
SET
-----------------------------------------*/
OPXYCB(0xc0): // SET 0,(Ix+d),B
OPXYCB(0xc1): // SET 0,(Ix+d),C
OPXYCB(0xc2): // SET 0,(Ix+d),D
OPXYCB(0xc3): // SET 0,(Ix+d),E
OPXYCB(0xc4): // SET 0,(Ix+d),H
OPXYCB(0xc5): // SET 0,(Ix+d),L
OPXYCB(0xc7): // SET 0,(Ix+d),A
OPXYCB(0xc8): // SET 1,(Ix+d),B
OPXYCB(0xc9): // SET 1,(Ix+d),C
OPXYCB(0xca): // SET 1,(Ix+d),D
OPXYCB(0xcb): // SET 1,(Ix+d),E
OPXYCB(0xcc): // SET 1,(Ix+d),H
OPXYCB(0xcd): // SET 1,(Ix+d),L
OPXYCB(0xcf): // SET 1,(Ix+d),A
OPXYCB(0xd0): // SET 2,(Ix+d),B
OPXYCB(0xd1): // SET 2,(Ix+d),C
OPXYCB(0xd2): // SET 2,(Ix+d),D
OPXYCB(0xd3): // SET 2,(Ix+d),E
OPXYCB(0xd4): // SET 2,(Ix+d),H
OPXYCB(0xd5): // SET 2,(Ix+d),L
OPXYCB(0xd7): // SET 2,(Ix+d),A
OPXYCB(0xd8): // SET 3,(Ix+d),B
OPXYCB(0xd9): // SET 3,(Ix+d),C
OPXYCB(0xda): // SET 3,(Ix+d),D
OPXYCB(0xdb): // SET 3,(Ix+d),E
OPXYCB(0xdc): // SET 3,(Ix+d),H
OPXYCB(0xdd): // SET 3,(Ix+d),L
OPXYCB(0xdf): // SET 3,(Ix+d),A
OPXYCB(0xe0): // SET 4,(Ix+d),B
OPXYCB(0xe1): // SET 4,(Ix+d),C
OPXYCB(0xe2): // SET 4,(Ix+d),D
OPXYCB(0xe3): // SET 4,(Ix+d),E
OPXYCB(0xe4): // SET 4,(Ix+d),H
OPXYCB(0xe5): // SET 4,(Ix+d),L
OPXYCB(0xe7): // SET 4,(Ix+d),A
OPXYCB(0xe8): // SET 5,(Ix+d),B
OPXYCB(0xe9): // SET 5,(Ix+d),C
OPXYCB(0xea): // SET 5,(Ix+d),D
OPXYCB(0xeb): // SET 5,(Ix+d),E
OPXYCB(0xec): // SET 5,(Ix+d),H
OPXYCB(0xed): // SET 5,(Ix+d),L
OPXYCB(0xef): // SET 5,(Ix+d),A
OPXYCB(0xf0): // SET 6,(Ix+d),B
OPXYCB(0xf1): // SET 6,(Ix+d),C
OPXYCB(0xf2): // SET 6,(Ix+d),D
OPXYCB(0xf3): // SET 6,(Ix+d),E
OPXYCB(0xf4): // SET 6,(Ix+d),H
OPXYCB(0xf5): // SET 6,(Ix+d),L
OPXYCB(0xf7): // SET 6,(Ix+d),A
OPXYCB(0xf8): // SET 7,(Ix+d),B
OPXYCB(0xf9): // SET 7,(Ix+d),C
OPXYCB(0xfa): // SET 7,(Ix+d),D
OPXYCB(0xfb): // SET 7,(Ix+d),E
OPXYCB(0xfc): // SET 7,(Ix+d),H
OPXYCB(0xfd): // SET 7,(Ix+d),L
OPXYCB(0xff): // SET 7,(Ix+d),A
res = READ_MEM8(adr);
res |= 1 << ((Opcode >> 3) & 7);
zR8(Opcode & 7) = res;
WRITE_MEM8(adr, res);
RET(19)
OPXYCB(0xc6): // SET 0,(Ix+d)
OPXYCB(0xce): // SET 1,(Ix+d)
OPXYCB(0xd6): // SET 2,(Ix+d)
OPXYCB(0xde): // SET 3,(Ix+d)
OPXYCB(0xe6): // SET 4,(Ix+d)
OPXYCB(0xee): // SET 5,(Ix+d)
OPXYCB(0xf6): // SET 6,(Ix+d)
OPXYCB(0xfe): // SET 7,(Ix+d)
res = READ_MEM8(adr);
res |= 1 << ((Opcode >> 3) & 7);
WRITE_MEM8(adr, res);
RET(19)
#if !CZ80_USE_JUMPTABLE
}
#endif

422
cpu/cz80/cz80jmp.c Normal file
View file

@ -0,0 +1,422 @@
/******************************************************************************
cz80jmp.c
CZ80 opcodeƒWƒƒƒƒvƒe<EFBFBD>[ƒ
******************************************************************************/
static const void ALIGN_DATA *JumpTable[0x100] =
{
&&OP0x00, &&OP0x01, &&OP0x02, &&OP0x03,
&&OP0x04, &&OP0x05, &&OP0x06, &&OP0x07,
&&OP0x08, &&OP0x09, &&OP0x0a, &&OP0x0b,
&&OP0x0c, &&OP0x0d, &&OP0x0e, &&OP0x0f,
&&OP0x10, &&OP0x11, &&OP0x12, &&OP0x13,
&&OP0x14, &&OP0x15, &&OP0x16, &&OP0x17,
&&OP0x18, &&OP0x19, &&OP0x1a, &&OP0x1b,
&&OP0x1c, &&OP0x1d, &&OP0x1e, &&OP0x1f,
&&OP0x20, &&OP0x21, &&OP0x22, &&OP0x23,
&&OP0x24, &&OP0x25, &&OP0x26, &&OP0x27,
&&OP0x28, &&OP0x29, &&OP0x2a, &&OP0x2b,
&&OP0x2c, &&OP0x2d, &&OP0x2e, &&OP0x2f,
&&OP0x30, &&OP0x31, &&OP0x32, &&OP0x33,
&&OP0x34, &&OP0x35, &&OP0x36, &&OP0x37,
&&OP0x38, &&OP0x39, &&OP0x3a, &&OP0x3b,
&&OP0x3c, &&OP0x3d, &&OP0x3e, &&OP0x3f,
&&OP0x40, &&OP0x41, &&OP0x42, &&OP0x43,
&&OP0x44, &&OP0x45, &&OP0x46, &&OP0x47,
&&OP0x48, &&OP0x49, &&OP0x4a, &&OP0x4b,
&&OP0x4c, &&OP0x4d, &&OP0x4e, &&OP0x4f,
&&OP0x50, &&OP0x51, &&OP0x52, &&OP0x53,
&&OP0x54, &&OP0x55, &&OP0x56, &&OP0x57,
&&OP0x58, &&OP0x59, &&OP0x5a, &&OP0x5b,
&&OP0x5c, &&OP0x5d, &&OP0x5e, &&OP0x5f,
&&OP0x60, &&OP0x61, &&OP0x62, &&OP0x63,
&&OP0x64, &&OP0x65, &&OP0x66, &&OP0x67,
&&OP0x68, &&OP0x69, &&OP0x6a, &&OP0x6b,
&&OP0x6c, &&OP0x6d, &&OP0x6e, &&OP0x6f,
&&OP0x70, &&OP0x71, &&OP0x72, &&OP0x73,
&&OP0x74, &&OP0x75, &&OP0x76, &&OP0x77,
&&OP0x78, &&OP0x79, &&OP0x7a, &&OP0x7b,
&&OP0x7c, &&OP0x7d, &&OP0x7e, &&OP0x7f,
&&OP0x80, &&OP0x81, &&OP0x82, &&OP0x83,
&&OP0x84, &&OP0x85, &&OP0x86, &&OP0x87,
&&OP0x88, &&OP0x89, &&OP0x8a, &&OP0x8b,
&&OP0x8c, &&OP0x8d, &&OP0x8e, &&OP0x8f,
&&OP0x90, &&OP0x91, &&OP0x92, &&OP0x93,
&&OP0x94, &&OP0x95, &&OP0x96, &&OP0x97,
&&OP0x98, &&OP0x99, &&OP0x9a, &&OP0x9b,
&&OP0x9c, &&OP0x9d, &&OP0x9e, &&OP0x9f,
&&OP0xa0, &&OP0xa1, &&OP0xa2, &&OP0xa3,
&&OP0xa4, &&OP0xa5, &&OP0xa6, &&OP0xa7,
&&OP0xa8, &&OP0xa9, &&OP0xaa, &&OP0xab,
&&OP0xac, &&OP0xad, &&OP0xae, &&OP0xaf,
&&OP0xb0, &&OP0xb1, &&OP0xb2, &&OP0xb3,
&&OP0xb4, &&OP0xb5, &&OP0xb6, &&OP0xb7,
&&OP0xb8, &&OP0xb9, &&OP0xba, &&OP0xbb,
&&OP0xbc, &&OP0xbd, &&OP0xbe, &&OP0xbf,
&&OP0xc0, &&OP0xc1, &&OP0xc2, &&OP0xc3,
&&OP0xc4, &&OP0xc5, &&OP0xc6, &&OP0xc7,
&&OP0xc8, &&OP0xc9, &&OP0xca, &&OP0xcb,
&&OP0xcc, &&OP0xcd, &&OP0xce, &&OP0xcf,
&&OP0xd0, &&OP0xd1, &&OP0xd2, &&OP0xd3,
&&OP0xd4, &&OP0xd5, &&OP0xd6, &&OP0xd7,
&&OP0xd8, &&OP0xd9, &&OP0xda, &&OP0xdb,
&&OP0xdc, &&OP0xdd, &&OP0xde, &&OP0xdf,
&&OP0xe0, &&OP0xe1, &&OP0xe2, &&OP0xe3,
&&OP0xe4, &&OP0xe5, &&OP0xe6, &&OP0xe7,
&&OP0xe8, &&OP0xe9, &&OP0xea, &&OP0xeb,
&&OP0xec, &&OP0xed, &&OP0xee, &&OP0xef,
&&OP0xf0, &&OP0xf1, &&OP0xf2, &&OP0xf3,
&&OP0xf4, &&OP0xf5, &&OP0xf6, &&OP0xf7,
&&OP0xf8, &&OP0xf9, &&OP0xfa, &&OP0xfb,
&&OP0xfc, &&OP0xfd, &&OP0xfe, &&OP0xff
};
static const void ALIGN_DATA *JumpTableCB[0x100] =
{
&&OPCB0x00, &&OPCB0x01, &&OPCB0x02, &&OPCB0x03,
&&OPCB0x04, &&OPCB0x05, &&OPCB0x06, &&OPCB0x07,
&&OPCB0x08, &&OPCB0x09, &&OPCB0x0a, &&OPCB0x0b,
&&OPCB0x0c, &&OPCB0x0d, &&OPCB0x0e, &&OPCB0x0f,
&&OPCB0x10, &&OPCB0x11, &&OPCB0x12, &&OPCB0x13,
&&OPCB0x14, &&OPCB0x15, &&OPCB0x16, &&OPCB0x17,
&&OPCB0x18, &&OPCB0x19, &&OPCB0x1a, &&OPCB0x1b,
&&OPCB0x1c, &&OPCB0x1d, &&OPCB0x1e, &&OPCB0x1f,
&&OPCB0x20, &&OPCB0x21, &&OPCB0x22, &&OPCB0x23,
&&OPCB0x24, &&OPCB0x25, &&OPCB0x26, &&OPCB0x27,
&&OPCB0x28, &&OPCB0x29, &&OPCB0x2a, &&OPCB0x2b,
&&OPCB0x2c, &&OPCB0x2d, &&OPCB0x2e, &&OPCB0x2f,
&&OPCB0x30, &&OPCB0x31, &&OPCB0x32, &&OPCB0x33,
&&OPCB0x34, &&OPCB0x35, &&OPCB0x36, &&OPCB0x37,
&&OPCB0x38, &&OPCB0x39, &&OPCB0x3a, &&OPCB0x3b,
&&OPCB0x3c, &&OPCB0x3d, &&OPCB0x3e, &&OPCB0x3f,
&&OPCB0x40, &&OPCB0x41, &&OPCB0x42, &&OPCB0x43,
&&OPCB0x44, &&OPCB0x45, &&OPCB0x46, &&OPCB0x47,
&&OPCB0x48, &&OPCB0x49, &&OPCB0x4a, &&OPCB0x4b,
&&OPCB0x4c, &&OPCB0x4d, &&OPCB0x4e, &&OPCB0x4f,
&&OPCB0x50, &&OPCB0x51, &&OPCB0x52, &&OPCB0x53,
&&OPCB0x54, &&OPCB0x55, &&OPCB0x56, &&OPCB0x57,
&&OPCB0x58, &&OPCB0x59, &&OPCB0x5a, &&OPCB0x5b,
&&OPCB0x5c, &&OPCB0x5d, &&OPCB0x5e, &&OPCB0x5f,
&&OPCB0x60, &&OPCB0x61, &&OPCB0x62, &&OPCB0x63,
&&OPCB0x64, &&OPCB0x65, &&OPCB0x66, &&OPCB0x67,
&&OPCB0x68, &&OPCB0x69, &&OPCB0x6a, &&OPCB0x6b,
&&OPCB0x6c, &&OPCB0x6d, &&OPCB0x6e, &&OPCB0x6f,
&&OPCB0x70, &&OPCB0x71, &&OPCB0x72, &&OPCB0x73,
&&OPCB0x74, &&OPCB0x75, &&OPCB0x76, &&OPCB0x77,
&&OPCB0x78, &&OPCB0x79, &&OPCB0x7a, &&OPCB0x7b,
&&OPCB0x7c, &&OPCB0x7d, &&OPCB0x7e, &&OPCB0x7f,
&&OPCB0x80, &&OPCB0x81, &&OPCB0x82, &&OPCB0x83,
&&OPCB0x84, &&OPCB0x85, &&OPCB0x86, &&OPCB0x87,
&&OPCB0x88, &&OPCB0x89, &&OPCB0x8a, &&OPCB0x8b,
&&OPCB0x8c, &&OPCB0x8d, &&OPCB0x8e, &&OPCB0x8f,
&&OPCB0x90, &&OPCB0x91, &&OPCB0x92, &&OPCB0x93,
&&OPCB0x94, &&OPCB0x95, &&OPCB0x96, &&OPCB0x97,
&&OPCB0x98, &&OPCB0x99, &&OPCB0x9a, &&OPCB0x9b,
&&OPCB0x9c, &&OPCB0x9d, &&OPCB0x9e, &&OPCB0x9f,
&&OPCB0xa0, &&OPCB0xa1, &&OPCB0xa2, &&OPCB0xa3,
&&OPCB0xa4, &&OPCB0xa5, &&OPCB0xa6, &&OPCB0xa7,
&&OPCB0xa8, &&OPCB0xa9, &&OPCB0xaa, &&OPCB0xab,
&&OPCB0xac, &&OPCB0xad, &&OPCB0xae, &&OPCB0xaf,
&&OPCB0xb0, &&OPCB0xb1, &&OPCB0xb2, &&OPCB0xb3,
&&OPCB0xb4, &&OPCB0xb5, &&OPCB0xb6, &&OPCB0xb7,
&&OPCB0xb8, &&OPCB0xb9, &&OPCB0xba, &&OPCB0xbb,
&&OPCB0xbc, &&OPCB0xbd, &&OPCB0xbe, &&OPCB0xbf,
&&OPCB0xc0, &&OPCB0xc1, &&OPCB0xc2, &&OPCB0xc3,
&&OPCB0xc4, &&OPCB0xc5, &&OPCB0xc6, &&OPCB0xc7,
&&OPCB0xc8, &&OPCB0xc9, &&OPCB0xca, &&OPCB0xcb,
&&OPCB0xcc, &&OPCB0xcd, &&OPCB0xce, &&OPCB0xcf,
&&OPCB0xd0, &&OPCB0xd1, &&OPCB0xd2, &&OPCB0xd3,
&&OPCB0xd4, &&OPCB0xd5, &&OPCB0xd6, &&OPCB0xd7,
&&OPCB0xd8, &&OPCB0xd9, &&OPCB0xda, &&OPCB0xdb,
&&OPCB0xdc, &&OPCB0xdd, &&OPCB0xde, &&OPCB0xdf,
&&OPCB0xe0, &&OPCB0xe1, &&OPCB0xe2, &&OPCB0xe3,
&&OPCB0xe4, &&OPCB0xe5, &&OPCB0xe6, &&OPCB0xe7,
&&OPCB0xe8, &&OPCB0xe9, &&OPCB0xea, &&OPCB0xeb,
&&OPCB0xec, &&OPCB0xed, &&OPCB0xee, &&OPCB0xef,
&&OPCB0xf0, &&OPCB0xf1, &&OPCB0xf2, &&OPCB0xf3,
&&OPCB0xf4, &&OPCB0xf5, &&OPCB0xf6, &&OPCB0xf7,
&&OPCB0xf8, &&OPCB0xf9, &&OPCB0xfa, &&OPCB0xfb,
&&OPCB0xfc, &&OPCB0xfd, &&OPCB0xfe, &&OPCB0xff
};
static const void ALIGN_DATA *JumpTableED[0x100] =
{
&&OPED0x00, &&OPED0x01, &&OPED0x02, &&OPED0x03,
&&OPED0x04, &&OPED0x05, &&OPED0x06, &&OPED0x07,
&&OPED0x08, &&OPED0x09, &&OPED0x0a, &&OPED0x0b,
&&OPED0x0c, &&OPED0x0d, &&OPED0x0e, &&OPED0x0f,
&&OPED0x10, &&OPED0x11, &&OPED0x12, &&OPED0x13,
&&OPED0x14, &&OPED0x15, &&OPED0x16, &&OPED0x17,
&&OPED0x18, &&OPED0x19, &&OPED0x1a, &&OPED0x1b,
&&OPED0x1c, &&OPED0x1d, &&OPED0x1e, &&OPED0x1f,
&&OPED0x20, &&OPED0x21, &&OPED0x22, &&OPED0x23,
&&OPED0x24, &&OPED0x25, &&OPED0x26, &&OPED0x27,
&&OPED0x28, &&OPED0x29, &&OPED0x2a, &&OPED0x2b,
&&OPED0x2c, &&OPED0x2d, &&OPED0x2e, &&OPED0x2f,
&&OPED0x30, &&OPED0x31, &&OPED0x32, &&OPED0x33,
&&OPED0x34, &&OPED0x35, &&OPED0x36, &&OPED0x37,
&&OPED0x38, &&OPED0x39, &&OPED0x3a, &&OPED0x3b,
&&OPED0x3c, &&OPED0x3d, &&OPED0x3e, &&OPED0x3f,
&&OPED0x40, &&OPED0x41, &&OPED0x42, &&OPED0x43,
&&OPED0x44, &&OPED0x45, &&OPED0x46, &&OPED0x47,
&&OPED0x48, &&OPED0x49, &&OPED0x4a, &&OPED0x4b,
&&OPED0x4c, &&OPED0x4d, &&OPED0x4e, &&OPED0x4f,
&&OPED0x50, &&OPED0x51, &&OPED0x52, &&OPED0x53,
&&OPED0x54, &&OPED0x55, &&OPED0x56, &&OPED0x57,
&&OPED0x58, &&OPED0x59, &&OPED0x5a, &&OPED0x5b,
&&OPED0x5c, &&OPED0x5d, &&OPED0x5e, &&OPED0x5f,
&&OPED0x60, &&OPED0x61, &&OPED0x62, &&OPED0x63,
&&OPED0x64, &&OPED0x65, &&OPED0x66, &&OPED0x67,
&&OPED0x68, &&OPED0x69, &&OPED0x6a, &&OPED0x6b,
&&OPED0x6c, &&OPED0x6d, &&OPED0x6e, &&OPED0x6f,
&&OPED0x70, &&OPED0x71, &&OPED0x72, &&OPED0x73,
&&OPED0x74, &&OPED0x75, &&OPED0x76, &&OPED0x77,
&&OPED0x78, &&OPED0x79, &&OPED0x7a, &&OPED0x7b,
&&OPED0x7c, &&OPED0x7d, &&OPED0x7e, &&OPED0x7f,
&&OPED0x80, &&OPED0x81, &&OPED0x82, &&OPED0x83,
&&OPED0x84, &&OPED0x85, &&OPED0x86, &&OPED0x87,
&&OPED0x88, &&OPED0x89, &&OPED0x8a, &&OPED0x8b,
&&OPED0x8c, &&OPED0x8d, &&OPED0x8e, &&OPED0x8f,
&&OPED0x90, &&OPED0x91, &&OPED0x92, &&OPED0x93,
&&OPED0x94, &&OPED0x95, &&OPED0x96, &&OPED0x97,
&&OPED0x98, &&OPED0x99, &&OPED0x9a, &&OPED0x9b,
&&OPED0x9c, &&OPED0x9d, &&OPED0x9e, &&OPED0x9f,
&&OPED0xa0, &&OPED0xa1, &&OPED0xa2, &&OPED0xa3,
&&OPED0xa4, &&OPED0xa5, &&OPED0xa6, &&OPED0xa7,
&&OPED0xa8, &&OPED0xa9, &&OPED0xaa, &&OPED0xab,
&&OPED0xac, &&OPED0xad, &&OPED0xae, &&OPED0xaf,
&&OPED0xb0, &&OPED0xb1, &&OPED0xb2, &&OPED0xb3,
&&OPED0xb4, &&OPED0xb5, &&OPED0xb6, &&OPED0xb7,
&&OPED0xb8, &&OPED0xb9, &&OPED0xba, &&OPED0xbb,
&&OPED0xbc, &&OPED0xbd, &&OPED0xbe, &&OPED0xbf,
&&OPED0xc0, &&OPED0xc1, &&OPED0xc2, &&OPED0xc3,
&&OPED0xc4, &&OPED0xc5, &&OPED0xc6, &&OPED0xc7,
&&OPED0xc8, &&OPED0xc9, &&OPED0xca, &&OPED0xcb,
&&OPED0xcc, &&OPED0xcd, &&OPED0xce, &&OPED0xcf,
&&OPED0xd0, &&OPED0xd1, &&OPED0xd2, &&OPED0xd3,
&&OPED0xd4, &&OPED0xd5, &&OPED0xd6, &&OPED0xd7,
&&OPED0xd8, &&OPED0xd9, &&OPED0xda, &&OPED0xdb,
&&OPED0xdc, &&OPED0xdd, &&OPED0xde, &&OPED0xdf,
&&OPED0xe0, &&OPED0xe1, &&OPED0xe2, &&OPED0xe3,
&&OPED0xe4, &&OPED0xe5, &&OPED0xe6, &&OPED0xe7,
&&OPED0xe8, &&OPED0xe9, &&OPED0xea, &&OPED0xeb,
&&OPED0xec, &&OPED0xed, &&OPED0xee, &&OPED0xef,
&&OPED0xf0, &&OPED0xf1, &&OPED0xf2, &&OPED0xf3,
&&OPED0xf4, &&OPED0xf5, &&OPED0xf6, &&OPED0xf7,
&&OPED0xf8, &&OPED0xf9, &&OPED0xfa, &&OPED0xfb,
&&OPED0xfc, &&OPED0xfd, &&OPED0xfe, &&OPED0xff
};
static const void ALIGN_DATA *JumpTableXY[0x100] =
{
&&OPXY0x00, &&OPXY0x01, &&OPXY0x02, &&OPXY0x03,
&&OPXY0x04, &&OPXY0x05, &&OPXY0x06, &&OPXY0x07,
&&OPXY0x08, &&OPXY0x09, &&OPXY0x0a, &&OPXY0x0b,
&&OPXY0x0c, &&OPXY0x0d, &&OPXY0x0e, &&OPXY0x0f,
&&OPXY0x10, &&OPXY0x11, &&OPXY0x12, &&OPXY0x13,
&&OPXY0x14, &&OPXY0x15, &&OPXY0x16, &&OPXY0x17,
&&OPXY0x18, &&OPXY0x19, &&OPXY0x1a, &&OPXY0x1b,
&&OPXY0x1c, &&OPXY0x1d, &&OPXY0x1e, &&OPXY0x1f,
&&OPXY0x20, &&OPXY0x21, &&OPXY0x22, &&OPXY0x23,
&&OPXY0x24, &&OPXY0x25, &&OPXY0x26, &&OPXY0x27,
&&OPXY0x28, &&OPXY0x29, &&OPXY0x2a, &&OPXY0x2b,
&&OPXY0x2c, &&OPXY0x2d, &&OPXY0x2e, &&OPXY0x2f,
&&OPXY0x30, &&OPXY0x31, &&OPXY0x32, &&OPXY0x33,
&&OPXY0x34, &&OPXY0x35, &&OPXY0x36, &&OPXY0x37,
&&OPXY0x38, &&OPXY0x39, &&OPXY0x3a, &&OPXY0x3b,
&&OPXY0x3c, &&OPXY0x3d, &&OPXY0x3e, &&OPXY0x3f,
&&OPXY0x40, &&OPXY0x41, &&OPXY0x42, &&OPXY0x43,
&&OPXY0x44, &&OPXY0x45, &&OPXY0x46, &&OPXY0x47,
&&OPXY0x48, &&OPXY0x49, &&OPXY0x4a, &&OPXY0x4b,
&&OPXY0x4c, &&OPXY0x4d, &&OPXY0x4e, &&OPXY0x4f,
&&OPXY0x50, &&OPXY0x51, &&OPXY0x52, &&OPXY0x53,
&&OPXY0x54, &&OPXY0x55, &&OPXY0x56, &&OPXY0x57,
&&OPXY0x58, &&OPXY0x59, &&OPXY0x5a, &&OPXY0x5b,
&&OPXY0x5c, &&OPXY0x5d, &&OPXY0x5e, &&OPXY0x5f,
&&OPXY0x60, &&OPXY0x61, &&OPXY0x62, &&OPXY0x63,
&&OPXY0x64, &&OPXY0x65, &&OPXY0x66, &&OPXY0x67,
&&OPXY0x68, &&OPXY0x69, &&OPXY0x6a, &&OPXY0x6b,
&&OPXY0x6c, &&OPXY0x6d, &&OPXY0x6e, &&OPXY0x6f,
&&OPXY0x70, &&OPXY0x71, &&OPXY0x72, &&OPXY0x73,
&&OPXY0x74, &&OPXY0x75, &&OPXY0x76, &&OPXY0x77,
&&OPXY0x78, &&OPXY0x79, &&OPXY0x7a, &&OPXY0x7b,
&&OPXY0x7c, &&OPXY0x7d, &&OPXY0x7e, &&OPXY0x7f,
&&OPXY0x80, &&OPXY0x81, &&OPXY0x82, &&OPXY0x83,
&&OPXY0x84, &&OPXY0x85, &&OPXY0x86, &&OPXY0x87,
&&OPXY0x88, &&OPXY0x89, &&OPXY0x8a, &&OPXY0x8b,
&&OPXY0x8c, &&OPXY0x8d, &&OPXY0x8e, &&OPXY0x8f,
&&OPXY0x90, &&OPXY0x91, &&OPXY0x92, &&OPXY0x93,
&&OPXY0x94, &&OPXY0x95, &&OPXY0x96, &&OPXY0x97,
&&OPXY0x98, &&OPXY0x99, &&OPXY0x9a, &&OPXY0x9b,
&&OPXY0x9c, &&OPXY0x9d, &&OPXY0x9e, &&OPXY0x9f,
&&OPXY0xa0, &&OPXY0xa1, &&OPXY0xa2, &&OPXY0xa3,
&&OPXY0xa4, &&OPXY0xa5, &&OPXY0xa6, &&OPXY0xa7,
&&OPXY0xa8, &&OPXY0xa9, &&OPXY0xaa, &&OPXY0xab,
&&OPXY0xac, &&OPXY0xad, &&OPXY0xae, &&OPXY0xaf,
&&OPXY0xb0, &&OPXY0xb1, &&OPXY0xb2, &&OPXY0xb3,
&&OPXY0xb4, &&OPXY0xb5, &&OPXY0xb6, &&OPXY0xb7,
&&OPXY0xb8, &&OPXY0xb9, &&OPXY0xba, &&OPXY0xbb,
&&OPXY0xbc, &&OPXY0xbd, &&OPXY0xbe, &&OPXY0xbf,
&&OPXY0xc0, &&OPXY0xc1, &&OPXY0xc2, &&OPXY0xc3,
&&OPXY0xc4, &&OPXY0xc5, &&OPXY0xc6, &&OPXY0xc7,
&&OPXY0xc8, &&OPXY0xc9, &&OPXY0xca, &&OPXY0xcb,
&&OPXY0xcc, &&OPXY0xcd, &&OPXY0xce, &&OPXY0xcf,
&&OPXY0xd0, &&OPXY0xd1, &&OPXY0xd2, &&OPXY0xd3,
&&OPXY0xd4, &&OPXY0xd5, &&OPXY0xd6, &&OPXY0xd7,
&&OPXY0xd8, &&OPXY0xd9, &&OPXY0xda, &&OPXY0xdb,
&&OPXY0xdc, &&OPXY0xdd, &&OPXY0xde, &&OPXY0xdf,
&&OPXY0xe0, &&OPXY0xe1, &&OPXY0xe2, &&OPXY0xe3,
&&OPXY0xe4, &&OPXY0xe5, &&OPXY0xe6, &&OPXY0xe7,
&&OPXY0xe8, &&OPXY0xe9, &&OPXY0xea, &&OPXY0xeb,
&&OPXY0xec, &&OPXY0xed, &&OPXY0xee, &&OPXY0xef,
&&OPXY0xf0, &&OPXY0xf1, &&OPXY0xf2, &&OPXY0xf3,
&&OPXY0xf4, &&OPXY0xf5, &&OPXY0xf6, &&OPXY0xf7,
&&OPXY0xf8, &&OPXY0xf9, &&OPXY0xfa, &&OPXY0xfb,
&&OPXY0xfc, &&OPXY0xfd, &&OPXY0xfe, &&OPXY0xff
};
static const void ALIGN_DATA *JumpTableXYCB[0x100] =
{
&&OPXYCB0x00, &&OPXYCB0x01, &&OPXYCB0x02, &&OPXYCB0x03,
&&OPXYCB0x04, &&OPXYCB0x05, &&OPXYCB0x06, &&OPXYCB0x07,
&&OPXYCB0x08, &&OPXYCB0x09, &&OPXYCB0x0a, &&OPXYCB0x0b,
&&OPXYCB0x0c, &&OPXYCB0x0d, &&OPXYCB0x0e, &&OPXYCB0x0f,
&&OPXYCB0x10, &&OPXYCB0x11, &&OPXYCB0x12, &&OPXYCB0x13,
&&OPXYCB0x14, &&OPXYCB0x15, &&OPXYCB0x16, &&OPXYCB0x17,
&&OPXYCB0x18, &&OPXYCB0x19, &&OPXYCB0x1a, &&OPXYCB0x1b,
&&OPXYCB0x1c, &&OPXYCB0x1d, &&OPXYCB0x1e, &&OPXYCB0x1f,
&&OPXYCB0x20, &&OPXYCB0x21, &&OPXYCB0x22, &&OPXYCB0x23,
&&OPXYCB0x24, &&OPXYCB0x25, &&OPXYCB0x26, &&OPXYCB0x27,
&&OPXYCB0x28, &&OPXYCB0x29, &&OPXYCB0x2a, &&OPXYCB0x2b,
&&OPXYCB0x2c, &&OPXYCB0x2d, &&OPXYCB0x2e, &&OPXYCB0x2f,
&&OPXYCB0x30, &&OPXYCB0x31, &&OPXYCB0x32, &&OPXYCB0x33,
&&OPXYCB0x34, &&OPXYCB0x35, &&OPXYCB0x36, &&OPXYCB0x37,
&&OPXYCB0x38, &&OPXYCB0x39, &&OPXYCB0x3a, &&OPXYCB0x3b,
&&OPXYCB0x3c, &&OPXYCB0x3d, &&OPXYCB0x3e, &&OPXYCB0x3f,
&&OPXYCB0x40, &&OPXYCB0x41, &&OPXYCB0x42, &&OPXYCB0x43,
&&OPXYCB0x44, &&OPXYCB0x45, &&OPXYCB0x46, &&OPXYCB0x47,
&&OPXYCB0x48, &&OPXYCB0x49, &&OPXYCB0x4a, &&OPXYCB0x4b,
&&OPXYCB0x4c, &&OPXYCB0x4d, &&OPXYCB0x4e, &&OPXYCB0x4f,
&&OPXYCB0x50, &&OPXYCB0x51, &&OPXYCB0x52, &&OPXYCB0x53,
&&OPXYCB0x54, &&OPXYCB0x55, &&OPXYCB0x56, &&OPXYCB0x57,
&&OPXYCB0x58, &&OPXYCB0x59, &&OPXYCB0x5a, &&OPXYCB0x5b,
&&OPXYCB0x5c, &&OPXYCB0x5d, &&OPXYCB0x5e, &&OPXYCB0x5f,
&&OPXYCB0x60, &&OPXYCB0x61, &&OPXYCB0x62, &&OPXYCB0x63,
&&OPXYCB0x64, &&OPXYCB0x65, &&OPXYCB0x66, &&OPXYCB0x67,
&&OPXYCB0x68, &&OPXYCB0x69, &&OPXYCB0x6a, &&OPXYCB0x6b,
&&OPXYCB0x6c, &&OPXYCB0x6d, &&OPXYCB0x6e, &&OPXYCB0x6f,
&&OPXYCB0x70, &&OPXYCB0x71, &&OPXYCB0x72, &&OPXYCB0x73,
&&OPXYCB0x74, &&OPXYCB0x75, &&OPXYCB0x76, &&OPXYCB0x77,
&&OPXYCB0x78, &&OPXYCB0x79, &&OPXYCB0x7a, &&OPXYCB0x7b,
&&OPXYCB0x7c, &&OPXYCB0x7d, &&OPXYCB0x7e, &&OPXYCB0x7f,
&&OPXYCB0x80, &&OPXYCB0x81, &&OPXYCB0x82, &&OPXYCB0x83,
&&OPXYCB0x84, &&OPXYCB0x85, &&OPXYCB0x86, &&OPXYCB0x87,
&&OPXYCB0x88, &&OPXYCB0x89, &&OPXYCB0x8a, &&OPXYCB0x8b,
&&OPXYCB0x8c, &&OPXYCB0x8d, &&OPXYCB0x8e, &&OPXYCB0x8f,
&&OPXYCB0x90, &&OPXYCB0x91, &&OPXYCB0x92, &&OPXYCB0x93,
&&OPXYCB0x94, &&OPXYCB0x95, &&OPXYCB0x96, &&OPXYCB0x97,
&&OPXYCB0x98, &&OPXYCB0x99, &&OPXYCB0x9a, &&OPXYCB0x9b,
&&OPXYCB0x9c, &&OPXYCB0x9d, &&OPXYCB0x9e, &&OPXYCB0x9f,
&&OPXYCB0xa0, &&OPXYCB0xa1, &&OPXYCB0xa2, &&OPXYCB0xa3,
&&OPXYCB0xa4, &&OPXYCB0xa5, &&OPXYCB0xa6, &&OPXYCB0xa7,
&&OPXYCB0xa8, &&OPXYCB0xa9, &&OPXYCB0xaa, &&OPXYCB0xab,
&&OPXYCB0xac, &&OPXYCB0xad, &&OPXYCB0xae, &&OPXYCB0xaf,
&&OPXYCB0xb0, &&OPXYCB0xb1, &&OPXYCB0xb2, &&OPXYCB0xb3,
&&OPXYCB0xb4, &&OPXYCB0xb5, &&OPXYCB0xb6, &&OPXYCB0xb7,
&&OPXYCB0xb8, &&OPXYCB0xb9, &&OPXYCB0xba, &&OPXYCB0xbb,
&&OPXYCB0xbc, &&OPXYCB0xbd, &&OPXYCB0xbe, &&OPXYCB0xbf,
&&OPXYCB0xc0, &&OPXYCB0xc1, &&OPXYCB0xc2, &&OPXYCB0xc3,
&&OPXYCB0xc4, &&OPXYCB0xc5, &&OPXYCB0xc6, &&OPXYCB0xc7,
&&OPXYCB0xc8, &&OPXYCB0xc9, &&OPXYCB0xca, &&OPXYCB0xcb,
&&OPXYCB0xcc, &&OPXYCB0xcd, &&OPXYCB0xce, &&OPXYCB0xcf,
&&OPXYCB0xd0, &&OPXYCB0xd1, &&OPXYCB0xd2, &&OPXYCB0xd3,
&&OPXYCB0xd4, &&OPXYCB0xd5, &&OPXYCB0xd6, &&OPXYCB0xd7,
&&OPXYCB0xd8, &&OPXYCB0xd9, &&OPXYCB0xda, &&OPXYCB0xdb,
&&OPXYCB0xdc, &&OPXYCB0xdd, &&OPXYCB0xde, &&OPXYCB0xdf,
&&OPXYCB0xe0, &&OPXYCB0xe1, &&OPXYCB0xe2, &&OPXYCB0xe3,
&&OPXYCB0xe4, &&OPXYCB0xe5, &&OPXYCB0xe6, &&OPXYCB0xe7,
&&OPXYCB0xe8, &&OPXYCB0xe9, &&OPXYCB0xea, &&OPXYCB0xeb,
&&OPXYCB0xec, &&OPXYCB0xed, &&OPXYCB0xee, &&OPXYCB0xef,
&&OPXYCB0xf0, &&OPXYCB0xf1, &&OPXYCB0xf2, &&OPXYCB0xf3,
&&OPXYCB0xf4, &&OPXYCB0xf5, &&OPXYCB0xf6, &&OPXYCB0xf7,
&&OPXYCB0xf8, &&OPXYCB0xf9, &&OPXYCB0xfa, &&OPXYCB0xfb,
&&OPXYCB0xfc, &&OPXYCB0xfd, &&OPXYCB0xfe, &&OPXYCB0xff
};

113
cpu/cz80/cz80macro.h Normal file
View file

@ -0,0 +1,113 @@
/******************************************************************************
cz80macro.h
CZ80 ŠeŽíƒ}ƒ<EFBFBD>
******************************************************************************/
#if CZ80_USE_JUMPTABLE
#define _SSOP(A,B) A##B
#define OP(A) _SSOP(OP,A)
#define OPCB(A) _SSOP(OPCB,A)
#define OPED(A) _SSOP(OPED,A)
#define OPXY(A) _SSOP(OPXY,A)
#define OPXYCB(A) _SSOP(OPXYCB,A)
#else
#define OP(A) case A
#define OPCB(A) case A
#define OPED(A) case A
#define OPXY(A) case A
#define OPXYCB(A) case A
#endif
#define USE_CYCLES(A) CPU->ICount -= (A);
#define ADD_CYCLES(A) CPU->ICount += (A);
#define RET(A) { USE_CYCLES(A) goto Cz80_Exec; }
#if CZ80_ENCRYPTED_ROM
#define SET_PC(A) \
CPU->BasePC = CPU->Fetch[(A) >> CZ80_FETCH_SFT]; \
OPBase = CPU->OPFetch[(A) >> CZ80_FETCH_SFT]; \
PC = (A) + CPU->BasePC;
#define GET_OP() (*(UINT8 *)(OPBase + PC))
#else
#define SET_PC(A) \
CPU->BasePC = CPU->Fetch[(A) >> CZ80_FETCH_SFT]; \
PC = (A) + CPU->BasePC;
#define GET_OP() (*(UINT8 *)PC)
#endif
#define READ_OP() GET_OP(); PC++
#define READ_ARG() (*(UINT8 *)PC++)
#if CZ80_LITTLE_ENDIAN
#define READ_ARG16() (*(UINT8 *)PC | (*(UINT8 *)(PC + 1) << 8)); PC += 2
#else
#define READ_ARG16() (*(UINT8 *)(PC + 1) | (*(UINT8 *)PC << 8)); PC += 2
#endif
//#ifndef BUILD_CPS1PSP
//#define READ_MEM8(A) memory_region_cpu2[(A)]
//#else
#define READ_MEM8(A) CPU->Read_Byte(A)
//#endif
#if CZ80_LITTLE_ENDIAN
#define READ_MEM16(A) (READ_MEM8(A) | (READ_MEM8((A) + 1) << 8))
#else
#define READ_MEM16(A) ((READ_MEM8(A) << 8) | READ_MEM8((A) + 1))
#endif
#define WRITE_MEM8(A, D) CPU->Write_Byte(A, D);
#if CZ80_LITTLE_ENDIAN
#define WRITE_MEM16(A, D) { WRITE_MEM8(A, D); WRITE_MEM8((A) + 1, (D) >> 8); }
#else
#define WRITE_MEM16(A, D) { WRITE_MEM8((A) + 1, D); WRITE_MEM8(A, (D) >> 8); }
#endif
#define PUSH_16(A) { UINT32 sp; zSP -= 2; sp = zSP; WRITE_MEM16(sp, A); }
#define POP_16(A) { UINT32 sp; sp = zSP; A = READ_MEM16(sp); zSP = sp + 2; }
#define IN(A) CPU->IN_Port(A)
#define OUT(A, D) CPU->OUT_Port(A, D)
#define CHECK_INT \
if (zIFF1) \
{ \
UINT32 IntVect; \
\
if (CPU->IRQState == HOLD_LINE) \
CPU->IRQState = CLEAR_LINE; \
\
CPU->HaltState = 0; \
zIFF1 = zIFF2 = 0; \
IntVect = CPU->Interrupt_Callback(CPU->IRQLine); \
\
PUSH_16(zRealPC) \
\
if (zIM == 2) \
{ \
IntVect = (IntVect & 0xff) | (zI << 8); \
PC = READ_MEM16(IntVect); \
CPU->ExtraCycles += 17; \
} \
else if (zIM == 1) \
{ \
PC = 0x38; \
CPU->ExtraCycles += 13; \
} \
else \
{ \
PC = IntVect & 0x38; \
CPU->ExtraCycles += 13; \
} \
\
SET_PC(PC) \
}

View file

@ -4,7 +4,7 @@ PSPSDK = $(shell psp-config --pspsdk-path)
# settings
#use_musashi = 1
use_mz80 = 1
#use_mz80 = 1
amalgamate = 0
#profile = 1
#up = 1
@ -69,13 +69,14 @@ ifeq "$(use_mz80)" "1"
CFLAGS += -D_USE_MZ80
OBJS += ../../cpu/mz80/mz80.o
else
$(error nothing here!)
CFLAGS += -D_USE_CZ80
OBJS += ../../cpu/cz80/cz80.o
endif
# bg images
OBJS += data/bg32.o data/bg40.o
LIBS += -lpng -lm -lpspgu -lpsppower -Wl,-Map=PicoDrive.map # -lpspaudio -lpsphprm
LIBS += -lpng -lm -lpspgu -lpsppower -Wl,-Map=PicoDrive.map -lpspaudio
# target
TARGET = PicoDrive

View file

@ -6,6 +6,7 @@
#include <pspdisplay.h>
#include <psputils.h>
#include <pspgu.h>
#include <pspaudio.h>
#include "psp.h"
#include "menu.h"
@ -20,6 +21,13 @@
#define OSD_FPS_X 420
#endif
// additional pspaudio imports, credits to crazyc
int sceAudio_38553111(unsigned short samples, unsigned short freq, char unknown); // play with conversion?
int sceAudio_5C37C0AE(void); // end play?
int sceAudio_E0727056(int volume, void *buffer); // blocking output
int sceAudioOutput2GetRestSample();
char romFileName[PATH_MAX];
unsigned char *PicoDraw2FB = (unsigned char *)VRAM_CACHED_STUFF + 8; // +8 to be able to skip border with 1 quadword..
int engineState;
@ -29,6 +37,8 @@ static unsigned int noticeMsgTime = 0;
int reset_timing = 0; // do we need this?
static void sound_init(void);
static void sound_deinit(void);
static void blit2(const char *fps, const char *notice);
static void clearArea(int full);
@ -82,6 +92,8 @@ void emu_Init(void)
mkdir("brm", 0777);
mkdir("cfg", 0777);
sound_init();
PicoInit();
PicoMessage = emu_msg_cb;
PicoMCDopenTray = emu_msg_tray_open;
@ -111,6 +123,7 @@ void emu_Deinit(void)
}
PicoExit();
sound_deinit();
}
void emu_setDefaultConfig(void)
@ -462,14 +475,147 @@ static void vidResetMode(void)
sceGuSync(0,0);
}
/*
static void updateSound(int len)
/* sound stuff */
#define SOUND_DEF_BLOCK_SIZE 1024 // 1152 // 1024
#define SOUND_BLOCK_COUNT 4
static short __attribute__((aligned(4))) sndBuffer[SOUND_DEF_BLOCK_SIZE*SOUND_BLOCK_COUNT*2 + 44100/50*2];
static short *snd_playptr = NULL;
static int samples_made = 0, samples_done = 0, samples_block = SOUND_DEF_BLOCK_SIZE;
static int sound_thread_exit = 0;
static SceUID sound_sem = -1;
static void writeSound(int len);
static int sound_thread(SceSize args, void *argp)
{
short *endptr = &sndBuffer[SOUND_DEF_BLOCK_SIZE*SOUND_BLOCK_COUNT*2];
int ret;
lprintf("sound_thread: started, priority %i\n", sceKernelGetThreadCurrentPriority());
while (!sound_thread_exit)
{
if (samples_made - samples_done < samples_block) {
// wait for data...
//lprintf("sthr: wait... (%i/%i)\n", samples_done, samples_made);
ret = sceKernelWaitSema(sound_sem, 1, 0);
//lprintf("sthr: sceKernelWaitSema: %i\n", ret);
continue;
}
//lprintf("sthr: got data: %i\n", samples_made - samples_done);
ret = sceAudio_E0727056(PSP_AUDIO_VOLUME_MAX, snd_playptr);
samples_done += samples_block;
snd_playptr += samples_block;
if (snd_playptr >= endptr)
snd_playptr = sndBuffer;
if (ret)
lprintf("sthr: outf: %i; pos %i/%i\n", ret, samples_done, samples_made);
}
lprintf("sthr: exit\n");
sceKernelExitDeleteThread(0);
return 0;
}
static void sound_init(void)
{
SceUID thid;
sound_sem = sceKernelCreateSema("sndsem", 0, 0, 1, NULL);
if (sound_sem < 0) lprintf("sceKernelCreateSema() failed: %i\n", sound_sem);
sound_thread_exit = 0;
thid = sceKernelCreateThread("sndthread", sound_thread, 0x12, 0x10000, 0, NULL);
if (thid >= 0)
{
sceKernelStartThread(thid, 0, 0);
}
else
lprintf("sceKernelCreateThread failed: %i\n", thid);
}
static void sound_prepare(void)
{
static int PsndRate_old = 0, PicoOpt_old = 0, pal_old = 0;
int ret, stereo;
samples_made = samples_done = 0;
if (PsndRate != PsndRate_old || (PicoOpt&0x0b) != (PicoOpt_old&0x0b) || Pico.m.pal != pal_old) {
sound_rerate(Pico.m.frame_count ? 1 : 0);
}
stereo=(PicoOpt&8)>>3;
samples_block = SOUND_DEF_BLOCK_SIZE;
if (PsndRate < 44100) samples_block = SOUND_DEF_BLOCK_SIZE / 2;
if (PsndRate < 22050) samples_block = SOUND_DEF_BLOCK_SIZE / 4;
lprintf("starting audio: %i, len: %i, stereo: %i, pal: %i, block samples: %i\n",
PsndRate, PsndLen, stereo, Pico.m.pal, samples_block);
while (sceAudioOutput2GetRestSample() > 0) psp_msleep(100);
sceAudio_5C37C0AE();
ret = sceAudio_38553111(samples_block/2, PsndRate, 2/*stereo ? 2 : 1*/);
lprintf("sceAudio_38553111() ret: %i\n", ret);
if (ret < 0) {
lprintf("sceAudio_38553111() failed: %i\n", ret);
sprintf(noticeMsg, "sound init failed (%i), snd disabled", ret);
noticeMsgTime = sceKernelGetSystemTimeLow();
currentConfig.EmuOpt &= ~4;
} else {
// int ret = sceAudioSetChannelDataLen(ret, PsndLen); // a try..
// lprintf("sceAudioSetChannelDataLen: %i\n", ret);
PicoWriteSound = writeSound;
memset32((int *)(void *)sndBuffer, 0, sizeof(sndBuffer)/4);
snd_playptr = sndBuffer;
PsndOut = sndBuffer;
PsndRate_old = PsndRate;
PicoOpt_old = PicoOpt;
pal_old = Pico.m.pal;
}
}
static void sound_end(void)
{
int ret;
while (sceAudioOutput2GetRestSample() > 0) psp_msleep(100);
ret = sceAudio_5C37C0AE();
lprintf("sound_end: sceAudio_5C37C0AE ret %i\n", ret);
}
static void sound_deinit(void)
{
sound_thread_exit = 1;
sceKernelSignalSema(sound_sem, 1);
}
static void writeSound(int len)
{
int ret;
short *endptr = &sndBuffer[SOUND_DEF_BLOCK_SIZE*SOUND_BLOCK_COUNT*2];
if (PicoOpt&8) len<<=1;
// TODO..
PsndOut += len;
if (PsndOut > endptr) {
memcpy32((int *)(void *)sndBuffer, (int *)endptr, (PsndOut - endptr + 1) / 2);
PsndOut = &sndBuffer[PsndOut - endptr];
}
*/
else if (PsndOut == endptr)
PsndOut = sndBuffer; // happy case
// signal the snd thread
samples_made += len;
if (samples_made - samples_done >= samples_block) {
if (!Pico.m.scanline) lprintf("signal, %i/%i\n", samples_done, samples_made);
ret = sceKernelSignalSema(sound_sem, 1);
if (!Pico.m.scanline) lprintf("signal ret %i\n", ret);
}
}
static void SkipFrame(void)
{
@ -490,6 +636,7 @@ void emu_forcedFrame(void)
vidResetMode();
memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*8/4); // borders
memset32((int *)VRAM_CACHED_STUFF + 512*232/4, 0xe0e0e0e0, 512*8/4);
memset32((int *)psp_screen + 512*264*2/4, 0, 512*8*2/4);
PicoDrawSetColorFormat(-1);
PicoScan = EmuScanSlow;
@ -676,7 +823,6 @@ static void simpleWait(unsigned int until)
void emu_Loop(void)
{
//static int PsndRate_old = 0, PicoOpt_old = 0, pal_old = 0;
char fpsbuff[24]; // fps count c string
unsigned int tval, tval_prev = 0, tval_thissec = 0; // timing
int frames_done = 0, frames_shown = 0, oldmodes = 0;
@ -711,36 +857,10 @@ void emu_Loop(void)
// prepare sound stuff
PsndOut = NULL;
#if 0 // TODO
if (currentConfig.EmuOpt & 4)
{
int ret, snd_excess_add, stereo;
if (PsndRate != PsndRate_old || (PicoOpt&0x0b) != (PicoOpt_old&0x0b) || Pico.m.pal != pal_old) {
sound_rerate(Pico.m.frame_count ? 1 : 0);
sound_prepare();
}
stereo=(PicoOpt&8)>>3;
snd_excess_add = ((PsndRate - PsndLen*target_fps)<<16) / target_fps;
snd_cbuf_samples = (PsndRate<<stereo) * 16 / target_fps;
lprintf("starting audio: %i len: %i (ex: %04x) stereo: %i, pal: %i\n",
PsndRate, PsndLen, snd_excess_add, stereo, Pico.m.pal);
ret = FrameworkAudio_Init(PsndRate, snd_cbuf_samples, stereo);
if (ret != 0) {
lprintf("FrameworkAudio_Init() failed: %i\n", ret);
sprintf(noticeMsg, "sound init failed (%i), snd disabled", ret);
noticeMsgTime = sceKernelGetSystemTimeLow();
currentConfig.EmuOpt &= ~4;
} else {
FrameworkAudio_SetVolume(currentConfig.volume, currentConfig.volume);
PicoWriteSound = updateSound;
snd_cbuff = FrameworkAudio_56448Buffer();
PsndOut = snd_cbuff + snd_cbuf_samples / 2; // start writing at the middle
snd_all_samples = 0;
PsndRate_old = PsndRate;
PicoOpt_old = PicoOpt;
pal_old = Pico.m.pal;
}
}
#endif
// loop?
while (engineState == PGS_Running)
@ -875,18 +995,21 @@ void emu_Loop(void)
if (PicoMCD & 1) PicoCDBufferFree();
/*
if (PsndOut != NULL) {
PsndOut = snd_cbuff = NULL;
FrameworkAudio_Close();
PsndOut = NULL;
sound_end();
}
*/
// save SRAM
if ((currentConfig.EmuOpt & 1) && SRam.changed) {
emu_msg_cb("Writing SRAM/BRAM..");
emu_SaveLoadGame(0, 1);
SRam.changed = 0;
}
// draw a frame for bg..
emu_forcedFrame();
}

View file

@ -43,7 +43,7 @@ static unsigned short bg_buffer[480*272] __attribute__((aligned(16)));
#define menu_screen psp_screen
static void menu_darken_bg(void *dst, const void *src, int pixels, int darker);
static void menu_prepare_bg(int use_game_bg, int use_back_buff);
static void menu_prepare_bg(int use_game_bg);
static unsigned int inp_prev = 0;
@ -552,7 +552,7 @@ static void draw_savestate_bg(int slot)
}
emu_forcedFrame();
menu_prepare_bg(1, 1);
menu_prepare_bg(1);
restore_oldstate(oldstate);
}
@ -1001,7 +1001,6 @@ static void menu_opt3_preview(int is_32col)
void *bgdata = is_32col ? bgdatac32_start : bgdatac40_start;
unsigned long insize = is_32col ? bgdatac32_size : bgdatac40_size, outsize = 65856;
int ret;
lprintf("%p %p %i %i (n %p)\n", bgdatac32_start, bgdatac40_start, bgdatac32_size, bgdatac40_size, &engineState);
ret = uncompress((Bytef *)bg_buffer, &outsize, bgdata, insize);
if (ret == 0)
{
@ -1017,7 +1016,7 @@ static void menu_opt3_preview(int is_32col)
memset32(psp_screen, 0, 512*272*2/4);
emu_forcedFrame();
menu_prepare_bg(1, 1);
menu_prepare_bg(1);
if (oldstate) restore_oldstate(oldstate);
}
@ -1165,7 +1164,6 @@ static void amenu_loop_options(void)
menu_entry opt_entries[] =
{
{ NULL, MB_NONE, MA_OPT_RENDERER, NULL, 0, 0, 0, 1 },
{ "Scale low res mode", MB_ONOFF, MA_OPT_SCALING, &currentConfig.scaling, 0x0001, 0, 3, 1 },
{ "Accurate timing (slower)", MB_ONOFF, MA_OPT_ACC_TIMING, &currentConfig.PicoOpt, 0x0040, 0, 0, 1 },
{ "Accurate sprites (slower)", MB_ONOFF, MA_OPT_ACC_SPRITES, &currentConfig.PicoOpt, 0x0080, 0, 0, 1 },
{ "Show FPS", MB_ONOFF, MA_OPT_SHOW_FPS, &currentConfig.EmuOpt, 0x0002, 0, 0, 1 },
@ -1672,13 +1670,13 @@ static void menu_darken_bg(void *dst, const void *src, int pixels, int darker)
}
}
static void menu_prepare_bg(int use_game_bg, int use_back_buff)
static void menu_prepare_bg(int use_game_bg)
{
if (use_game_bg)
{
// darken the active framebuffer
unsigned short *dst = bg_buffer;
unsigned short *src = use_back_buff ? psp_screen : psp_video_get_active_fb();
unsigned short *src = psp_screen;
int i;
for (i = 272; i > 0; i--, dst += 480, src += 512)
menu_darken_bg(dst, src, 480, 1);
@ -1695,7 +1693,7 @@ static void menu_prepare_bg(int use_game_bg, int use_back_buff)
static void menu_gfx_prepare(void)
{
menu_prepare_bg(rom_data != NULL, 0);
menu_prepare_bg(rom_data != NULL);
menu_draw_begin();
menu_draw_end();

View file

@ -32,7 +32,8 @@ static int callback_thread(SceSize args, void *argp)
{
int cbid;
lprintf("callback_thread started with id %i\n", sceKernelGetThreadId());
lprintf("callback_thread started with id %i, priority %i\n",
sceKernelGetThreadId(), sceKernelGetThreadCurrentPriority());
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
@ -44,9 +45,10 @@ static int callback_thread(SceSize args, void *argp)
void psp_init(void)
{
int thid;
SceUID thid;
lprintf("entered psp_init, threadId %i\n", sceKernelGetThreadId());
lprintf("entered psp_init, threadId %i, priority %i\n", sceKernelGetThreadId(),
sceKernelGetThreadCurrentPriority());
thid = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, 0, 0);
if (thid >= 0)