Merged from Ken's branch (for CP/M card support)

This commit is contained in:
tomch 2008-08-19 21:36:31 +00:00
parent 028b4aa338
commit 6a2c6b6363
23 changed files with 5409 additions and 11 deletions

View File

@ -525,6 +525,42 @@
>
</File>
</Filter>
<Filter
Name="Z80"
>
<File
RelativePath=".\source\Z80\z80codes.h"
>
</File>
<File
RelativePath=".\source\Z80\z80cpu.cpp"
>
</File>
<File
RelativePath=".\source\Z80\z80cpu.h"
>
</File>
<File
RelativePath=".\source\Z80\z80daa.h"
>
</File>
<File
RelativePath=".\source\Z80\z80emu.cpp"
>
</File>
<File
RelativePath=".\source\Z80\z80emu.h"
>
</File>
<File
RelativePath=".\source\Z80\z80io.cpp"
>
</File>
<File
RelativePath=".\source\Z80\z80io.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="Docs"

Binary file not shown.

View File

@ -112,7 +112,7 @@ STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_CAPTION | WS_SYSMENU
CAPTION "Input"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
PUSHBUTTON "Paste from clipboard",IDC_PASTE_FROM_CLIPBOARD,5,179,75,14
PUSHBUTTON "Paste from clipboard",IDC_PASTE_FROM_CLIPBOARD,5,193,75,14
GROUPBOX "Joystick Control",IDC_STATIC,5,20,200,80
LTEXT "&Joystick1:",IDC_STATIC,12,33,40,8
COMBOBOX IDC_JOYSTICK0,52,31,100,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
@ -126,12 +126,14 @@ BEGIN
CONTROL "Spin1",IDC_SPIN_YTRIM,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNLEFT | UDS_AUTOBUDDY,161,69,10,14
CONTROL "Scroll Lock acts as toggle for full-speed CPU",IDC_SCROLLLOCK_TOGGLE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,114,166,10
LTEXT "(Shift+Insert during emulation)",IDC_STATIC,89,182,94,8
LTEXT "(Shift+Insert during emulation)",IDC_STATIC,89,196,94,8
CONTROL "Mouse interface in slot 4",IDC_MOUSE_IN_SLOT4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,128,106,10
CONTROL "Show crosshairs in window's frame",IDC_MOUSE_CROSSHAIR,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,142,159,10
CONTROL "Restrict mouse to Apple window",IDC_MOUSE_RESTRICT_TO_WINDOW,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,156,159,10
CONTROL "Microsoft CP/M SoftCard in slot 5",IDC_Z80_IN_SLOT5,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,171,122,10
END
IDD_PROPPAGE_SOUND DIALOGEX 0, 0, 210, 221

View File

@ -31,8 +31,6 @@
#define IDR_APPLE2_PLUS_ROM 127
#define IDR_APPLE2E_ROM 128
#define IDR_APPLE2E_ENHANCED_ROM 129
#define IDR_PRAVETS_82_ROM 149
#define IDR_PRAVETS_8C_ROM 150
#define IDC_MB_ENABLE 130
#define IDD_TFE_SETTINGS_DIALOG 131
#define IDR_PRINTDRVR_FW 132
@ -42,6 +40,8 @@
#define IDR_MOCKINGBOARD_D_FW 135
#define IDR_MOUSEINTERFACE_FW 136
#define IDR_FREEZES_F8_ROM 137
#define IDR_PRAVETS_82_ROM 138
#define IDR_PRAVETS_8C_ROM 139
#define IDC_KEYB_BUFFER_ENABLE 1005
#define IDC_SAVESTATE 1006
#define IDC_SAVESTATE_ON_EXIT 1007
@ -84,23 +84,23 @@
#define IDC_MOUSE_RESTRICT_TO_WINDOW 1048
#define IDC_CIDERPRESS_BROWSE 1049
#define IDC_CIDERPRESS_FILENAME 1050
#define IDC_Z80_IN_SLOT5 1051
#define IDM_EXIT 40001
#define IDM_HELP 40002
#define IDM_ABOUT 40003
#define ID_DISKMENU_EJECT 40004
#define ID_DISKMENU_WRITEPROTECTION_ON 40005
#define ID_DISKMENU_WRITEPROTECTION_OFF 40006
#define ID_DISKMENU_SENDTO_CIDERPRESS 40007
#define ID_DISKMENU_SENDTO_CIDERPRESS 40007
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 137
#define _APS_NEXT_COMMAND_VALUE 40007
#define _APS_NEXT_CONTROL_VALUE 1047
#define _APS_NEXT_RESOURCE_VALUE 140
#define _APS_NEXT_COMMAND_VALUE 40008
#define _APS_NEXT_CONTROL_VALUE 1052
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#pragma hdrstop
#include <objbase.h>
#include "MouseInterface.h"
#include "z80\z80cpu.h"
char VERSIONSTRING[] = "xx.yy.zz.ww";
@ -74,7 +75,13 @@ bool g_bDisableDirectSound = false;
CSuperSerialCard sg_SSC;
CMouseInterface sg_Mouse;
#ifdef SUPPORT_CPM
UINT g_Slot4 = CT_Empty;
#else
UINT g_Slot4 = CT_Mockingboard; // CT_Mockingboard or CT_MouseInterface
#endif
eCPU g_ActiveCPU = CPU_6502;
HANDLE g_hCustomRomF8 = INVALID_HANDLE_VALUE; // Cmd-line specified custom ROM at $F800..$FFFF
static bool g_bCustomRomF8Failed = false; // Set if custom ROM file failed
@ -471,7 +478,20 @@ void LoadConfiguration ()
g_uMouseShowCrosshair = dwTmp;
if(LOAD(TEXT(REGVALUE_MOUSE_RESTRICT_TO_WINDOW), &dwTmp))
g_uMouseRestrictToWindow = dwTmp;
#ifdef SUPPORT_CPM
if(LOAD(TEXT(REGVALUE_Z80_IN_SLOT5), &dwTmp))
g_uZ80InSlot5 = dwTmp;
if (g_uZ80InSlot5)
MB_SetSoundcardType(SC_NONE);
g_Slot4 = g_uMouseInSlot4 ? CT_MouseInterface
: g_uZ80InSlot5 ? CT_Empty
: CT_Mockingboard;
#else
g_Slot4 = g_uMouseInSlot4 ? CT_MouseInterface : CT_Mockingboard;
#endif
//
@ -547,7 +567,7 @@ void RegisterExtensions ()
//===========================================================================
void ApppleWin_RegisterHotKeys()
{
bool bStatus = RegisterHotKey(
BOOL bStatus = RegisterHotKey(
g_hFrameWindow , // HWND hWnd
VK_SNAPSHOT , // int id (user/custom id)
0 , // UINT fsModifiers

View File

@ -45,3 +45,7 @@ extern bool g_bDisableDirectSound; // Cmd line switch: don't init DS (so n
extern UINT g_Slot4; // Mockingboard or Mouse in slot4
extern HANDLE g_hCustomRomF8; // NULL if no custom rom
enum eCPU {CPU_6502=1, CPU_Z80};
extern eCPU g_ActiveCPU;

View File

@ -88,6 +88,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#pragma hdrstop
#include "MouseInterface.h"
#ifdef SUPPORT_CPM
#include "z80\z80cpu.h"
#include "z80\z80emu.h"
#include "z80\z80io.h"
#endif
#define AF_SIGN 0x80
#define AF_OVERFLOW 0x40
#define AF_RESERVED 0x20
@ -823,6 +829,18 @@ static __forceinline void DoIrqProfiling(DWORD uCycles)
//===========================================================================
BYTE CpuRead(USHORT addr, ULONG uExecutedCycles)
{
return READ;
}
void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles)
{
WRITE(a);
}
//===========================================================================
static __forceinline int Fetch(BYTE& iOpcode, ULONG uExecutedCycles)
{
//g_uInternalExecutedCycles = uExecutedCycles;
@ -911,6 +929,14 @@ static DWORD Cpu65C02 (DWORD uTotalCycles)
UINT uExtraCycles = 0;
BYTE iOpcode;
#ifdef SUPPORT_CPM
if (g_ActiveCPU == CPU_Z80)
{
const UINT uZ80Cycles = InternalZ80Execute(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
}
else
#endif
{
if (!Fetch(iOpcode, uExecutedCycles))
break;
@ -1173,7 +1199,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles)
case 0xFE: ABSX INC_CMOS CYC(6) break;
case 0xFF: INV NOP CYC(2) break;
}
}
CheckInterruptSources(uExecutedCycles);
NMI(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
@ -1211,6 +1237,14 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
UINT uExtraCycles = 0;
BYTE iOpcode;
#ifdef SUPPORT_CPM
if (g_ActiveCPU == CPU_Z80)
{
const UINT uZ80Cycles = InternalZ80Execute(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
}
else
#endif
{
if (!Fetch(iOpcode, uExecutedCycles))
break;
@ -1473,6 +1507,7 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
case 0xFE: ABSX INC_NMOS CYC(6) break;
case 0xFF: INV ABSX INS CYC(7) break;
}
}
CheckInterruptSources(uExecutedCycles);
NMI(uExecutedCycles, uExtraCycles, flagc, flagn, flagv, flagz);
@ -1593,6 +1628,12 @@ void CpuInitialize ()
g_bCritSectionValid = true;
CpuIrqReset();
CpuNmiReset();
#ifdef SUPPORT_CPM
// Z80
InitTables();
Z80_Reset();
#endif
}
//===========================================================================
@ -1694,6 +1735,11 @@ void CpuReset()
regs.sp = 0x0100 | ((regs.sp - 3) & 0xFF);
regs.bJammed = 0;
#ifdef SUPPORT_CPM
g_ActiveCPU = CPU_6502;
Z80_Reset();
#endif
}
//===========================================================================

View File

@ -28,3 +28,6 @@ void CpuNmiDeassert(eIRQSRC Device);
void CpuReset ();
DWORD CpuGetSnapshot(SS_CPU6502* pSS);
DWORD CpuSetSnapshot(SS_CPU6502* pSS);
BYTE CpuRead(USHORT addr, ULONG uExecutedCycles);
void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles);

View File

@ -1,9 +1,15 @@
#pragma once
#define SUPPORT_CPM
const double _M14 = (157500000.0 / 11.0); // 14.3181818... * 10^6
const double CLK_6502 = ((_M14 * 65.0) / 912.0); // 65 cycles per 912 14M clocks
//const double CLK_6502 = 23 * 44100; // 1014300
// The effective Z-80 clock rate is 2.041MHz
// See: http://www.apple2info.net/hardware/softcard/SC-SWHW_a2in.pdf
const double CLK_Z80 = 2.041e6;
const UINT uCyclesPerLine = 65; // 25 cycles of HBL & 40 cycles of HBL'
const UINT uVisibleLinesPerFrame = 64*3; // 192
const UINT uLinesPerFrame = 262; // 64 in each third of the screen & 70 in VBL
@ -87,6 +93,7 @@ enum AppMode_e
#define REGVALUE_THE_FREEZES_F8_ROM "The Freeze's F8 Rom"
#define REGVALUE_CLONETYPE "Clone Type"
#define REGVALUE_CIDERPRESSLOC "CiderPress Location"
#define REGVALUE_Z80_IN_SLOT5 "Z80 in slot 5"
// Preferences
#define REGVALUE_PREF_START_DIR "Starting Directory"

View File

@ -1398,6 +1398,9 @@ void ResetMachineState () {
MB_Reset();
SpkrReset();
sg_Mouse.Reset();
#ifdef SUPPORT_CPM
g_ActiveCPU = CPU_6502;
#endif
SoundCore_SetFade(FADE_NONE);
}

View File

@ -29,6 +29,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "StdAfx.h"
#pragma hdrstop
#include "MouseInterface.h"
#ifdef SUPPORT_CPM
#include "z80\z80emu.h"
#include "z80\z80cpu.h"
#endif
#include "..\resource\resource.h"
#define MF_80STORE 0x00000001
@ -1050,6 +1054,9 @@ void MemInitialize()
sg_SSC.CommInitialize(pCxRomPeripheral, 2); // $C200 : SSC
if (g_Slot4 == CT_MouseInterface)
sg_Mouse.Initialize(pCxRomPeripheral, 4); // $C400 : Mouse f/w
#ifdef SUPPORT_CPM
ConfigureSoftcard(pCxRomPeripheral, 5, g_uZ80InSlot5); // $C500 ; Z80 card
#endif
DiskLoadRom(pCxRomPeripheral, 6); // $C600 : Disk][ f/w
HD_Load_Rom(pCxRomPeripheral, 7); // $C700 : HDD f/w
@ -1102,6 +1109,9 @@ void MemReset ()
CpuInitialize();
//Sets Caps Lock = false (Pravets 8A/C only)
#ifdef SUPPORT_CPM
Z80_Reset();
#endif
}
//===========================================================================

View File

@ -1308,6 +1308,16 @@ void MB_Initialize()
//
#ifdef SUPPORT_CPM
if (g_Slot4 == CT_Mockingboard)
{
const UINT uSlot4 = 4;
RegisterIoHandler(uSlot4, PhasorIO, PhasorIO, MB_Read, MB_Write, NULL, NULL);
const UINT uSlot5 = 5;
RegisterIoHandler(uSlot5, PhasorIO, PhasorIO, MB_Read, MB_Write, NULL, NULL);
}
#else
if (g_Slot4 == CT_Mockingboard)
{
const UINT uSlot4 = 4;
@ -1316,6 +1326,7 @@ void MB_Initialize()
const UINT uSlot5 = 5;
RegisterIoHandler(uSlot5, PhasorIO, PhasorIO, MB_Read, MB_Write, NULL, NULL);
#endif
}
//-----------------------------------------------------------------------------

View File

@ -111,6 +111,8 @@ UINT g_uMouseInSlot4 = 0;
UINT g_uMouseShowCrosshair = 0;
UINT g_uMouseRestrictToWindow = 0;
UINT g_uZ80InSlot5 = 0;
//
UINT g_uTheFreezesF8Rom = 0;
@ -513,6 +515,7 @@ static void InputDlg_OK(HWND window, UINT afterclose)
SAVE(TEXT(REGVALUE_MOUSE_IN_SLOT4),g_uMouseInSlot4);
SAVE(TEXT(REGVALUE_MOUSE_CROSSHAIR),g_uMouseShowCrosshair);
SAVE(TEXT(REGVALUE_MOUSE_RESTRICT_TO_WINDOW),g_uMouseRestrictToWindow);
SAVE(TEXT(REGVALUE_Z80_IN_SLOT5),g_uZ80InSlot5);
//
@ -638,6 +641,33 @@ static BOOL CALLBACK InputDlgProc (HWND window,
}
break;
case IDC_Z80_IN_SLOT5:
{
UINT uNewState = IsDlgButtonChecked(window, IDC_Z80_IN_SLOT5) ? 1 : 0;
LPCSTR pMsg = uNewState ?
TEXT("The emulator needs to restart as the slot configuration has changed.\n")
TEXT("Microsoft CP/M SoftCard will be placed in slot 5.\n\n")
TEXT("Would you like to restart the emulator now?")
:
TEXT("The emulator needs to restart as the slot configuration has changed.\n")
TEXT("Microsoft CP/M SoftCard will be removed from slot 5\n\n")
TEXT("Would you like to restart the emulator now?");
if (MessageBox(window,
pMsg,
TEXT("Configuration"),
MB_ICONQUESTION | MB_YESNO | MB_SETFOREGROUND) == IDYES)
{
g_uZ80InSlot5 = uNewState;
afterclose = WM_USER_RESTART;
PropSheet_PressButton(GetParent(window), PSBTN_OK);
}
else
{
CheckDlgButton(window, IDC_Z80_IN_SLOT5, g_uZ80InSlot5 ? BST_CHECKED : BST_UNCHECKED);
}
}
break;
case IDC_PASTE_FROM_CLIPBOARD:
ClipboardInitiatePaste();
break;
@ -663,6 +693,7 @@ static BOOL CALLBACK InputDlgProc (HWND window,
CheckDlgButton(window, IDC_MOUSE_RESTRICT_TO_WINDOW, g_uMouseRestrictToWindow ? BST_CHECKED : BST_UNCHECKED);
EnableWindow(GetDlgItem(window, IDC_MOUSE_CROSSHAIR), g_uMouseInSlot4 ? TRUE : FALSE);
EnableWindow(GetDlgItem(window, IDC_MOUSE_RESTRICT_TO_WINDOW), g_uMouseInSlot4 ? TRUE : FALSE);
CheckDlgButton(window, IDC_Z80_IN_SLOT5, g_uZ80InSlot5 ? BST_CHECKED : BST_UNCHECKED);
afterclose = 0;
break;
@ -796,6 +827,11 @@ static BOOL CALLBACK SoundDlgProc (HWND window,
{
EnableWindow(GetDlgItem(window, IDC_PHASOR_ENABLE), FALSE);
}
if (g_uZ80InSlot5)
{
EnableWindow(GetDlgItem(window, IDC_MB_ENABLE), FALSE);
}
afterclose = 0;
break;

View File

@ -16,3 +16,5 @@ extern UINT g_uTheFreezesF8Rom;
extern DWORD g_uCloneType;
extern HWND hwConfigTab;
extern HWND hwAdvancedTab;
extern UINT g_uZ80InSlot5;

View File

@ -148,6 +148,7 @@ enum SS_CARDTYPE
CT_GenericHDD, // Hard disk
CT_GenericClock,
CT_MouseInterface,
CT_Z80,
};
/////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,219 @@
/*** Z80Em: Portable Z80 emulator *******************************************/
/*** ***/
/*** Z80Codes.h ***/
/*** ***/
/*** This file contains various macros used by the emulation engine ***/
/*** ***/
/*** Copyright (C) Marcel de Kogel 1996,1997 ***/
/*** You are not allowed to distribute this software commercially ***/
/*** Please, notify me, if you make any changes to this file ***/
/****************************************************************************/
#define M_POP(Rg) \
R.Rg.D=M_RDSTACK(R.SP.D)+(M_RDSTACK((R.SP.D+1)&65535)<<8); \
R.SP.W.l+=2
#define M_PUSH(Rg) \
R.SP.W.l-=2; \
M_WRSTACK(R.SP.D,R.Rg.D); \
M_WRSTACK((R.SP.D+1)&65535,R.Rg.D>>8)
#define M_CALL \
{ \
int q; \
q=M_RDMEM_OPCODE_WORD(); \
M_PUSH(PC); \
R.PC.D=q; \
Z80_ICount-=7; \
}
#define M_JP \
R.PC.D=M_RDOP_ARG(R.PC.D)+((M_RDOP_ARG((R.PC.D+1)&65535))<<8)
#define M_JR \
R.PC.W.l+=((offset)M_RDOP_ARG(R.PC.D))+1; Z80_ICount-=5
#define M_RET M_POP(PC); Z80_ICount-=6
#define M_RST(Addr) M_PUSH(PC); R.PC.D=Addr
#define M_SET(Bit,Reg) Reg|=1<<Bit
#define M_RES(Bit,Reg) Reg&=~(1<<Bit)
#define M_BIT(Bit,Reg) \
R.AF.B.l=(R.AF.B.l&C_FLAG)|H_FLAG| \
((Reg&(1<<Bit))? ((Bit==7)?S_FLAG:0):Z_FLAG)
#define M_AND(Reg) R.AF.B.h&=Reg; R.AF.B.l=ZSPTable[R.AF.B.h]|H_FLAG
#define M_OR(Reg) R.AF.B.h|=Reg; R.AF.B.l=ZSPTable[R.AF.B.h]
#define M_XOR(Reg) R.AF.B.h^=Reg; R.AF.B.l=ZSPTable[R.AF.B.h]
#define M_IN(Reg) \
Reg=DoIn(R.BC.B.l,R.BC.B.h); \
R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSPTable[Reg]
#define M_RLCA \
R.AF.B.h=(R.AF.B.h<<1)|((R.AF.B.h&0x80)>>7); \
R.AF.B.l=(R.AF.B.l&0xEC)|(R.AF.B.h&C_FLAG)
#define M_RRCA \
R.AF.B.l=(R.AF.B.l&0xEC)|(R.AF.B.h&0x01); \
R.AF.B.h=(R.AF.B.h>>1)|(R.AF.B.h<<7)
#define M_RLA \
{ \
int i; \
i=R.AF.B.l&C_FLAG; \
R.AF.B.l=(R.AF.B.l&0xEC)|((R.AF.B.h&0x80)>>7); \
R.AF.B.h=(R.AF.B.h<<1)|i; \
}
#define M_RRA \
{ \
int i; \
i=R.AF.B.l&C_FLAG; \
R.AF.B.l=(R.AF.B.l&0xEC)|(R.AF.B.h&0x01); \
R.AF.B.h=(R.AF.B.h>>1)|(i<<7); \
}
#define M_RLC(Reg) \
{ \
int q; \
q=Reg>>7; \
Reg=(Reg<<1)|q; \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_RRC(Reg) \
{ \
int q; \
q=Reg&1; \
Reg=(Reg>>1)|(q<<7); \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_RL(Reg) \
{ \
int q; \
q=Reg>>7; \
Reg=(Reg<<1)|(R.AF.B.l&1); \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_RR(Reg) \
{ \
int q; \
q=Reg&1; \
Reg=(Reg>>1)|(R.AF.B.l<<7); \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_SLL(Reg) \
{ \
int q; \
q=Reg>>7; \
Reg=(Reg<<1)|1; \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_SLA(Reg) \
{ \
int q; \
q=Reg>>7; \
Reg<<=1; \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_SRL(Reg) \
{ \
int q; \
q=Reg&1; \
Reg>>=1; \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_SRA(Reg) \
{ \
int q; \
q=Reg&1; \
Reg=(Reg>>1)|(Reg&0x80); \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_INC(Reg) \
++Reg; \
R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSTable[Reg]| \
((Reg==0x80)?V_FLAG:0)|((Reg&0x0F)?0:H_FLAG)
#define M_DEC(Reg) \
R.AF.B.l=(R.AF.B.l&C_FLAG)|N_FLAG| \
((Reg==0x80)?V_FLAG:0)|((Reg&0x0F)?0:H_FLAG); \
R.AF.B.l|=ZSTable[--Reg]
#define M_ADD(Reg) \
{ \
int q; \
q=R.AF.B.h+Reg; \
R.AF.B.l=ZSTable[q&255]|((q&256)>>8)| \
((R.AF.B.h^q^Reg)&H_FLAG)| \
(((Reg^R.AF.B.h^0x80)&(Reg^q)&0x80)>>5); \
R.AF.B.h=q; \
}
#define M_ADC(Reg) \
{ \
int q; \
q=R.AF.B.h+Reg+(R.AF.B.l&1); \
R.AF.B.l=ZSTable[q&255]|((q&256)>>8)| \
((R.AF.B.h^q^Reg)&H_FLAG)| \
(((Reg^R.AF.B.h^0x80)&(Reg^q)&0x80)>>5); \
R.AF.B.h=q; \
}
#define M_SUB(Reg) \
{ \
int q; \
q=R.AF.B.h-Reg; \
R.AF.B.l=ZSTable[q&255]|((q&256)>>8)|N_FLAG| \
((R.AF.B.h^q^Reg)&H_FLAG)| \
(((Reg^R.AF.B.h)&(Reg^q)&0x80)>>5); \
R.AF.B.h=q; \
}
#define M_SBC(Reg) \
{ \
int q; \
q=R.AF.B.h-Reg-(R.AF.B.l&1); \
R.AF.B.l=ZSTable[q&255]|((q&256)>>8)|N_FLAG| \
((R.AF.B.h^q^Reg)&H_FLAG)| \
(((Reg^R.AF.B.h)&(Reg^q)&0x80)>>5); \
R.AF.B.h=q; \
}
#define M_CP(Reg) \
{ \
int q; \
q=R.AF.B.h-Reg; \
R.AF.B.l=ZSTable[q&255]|((q&256)>>8)|N_FLAG| \
((R.AF.B.h^q^Reg)&H_FLAG)| \
(((Reg^R.AF.B.h)&(Reg^q)&0x80)>>5); \
}
#define M_ADDW(Reg1,Reg2) \
{ \
int q; \
q=R.Reg1.D+R.Reg2.D; \
R.AF.B.l=(R.AF.B.l&(S_FLAG|Z_FLAG|V_FLAG))| \
(((R.Reg1.D^q^R.Reg2.D)&0x1000)>>8)| \
((q>>16)&1); \
R.Reg1.W.l=q; \
}
#define M_ADCW(Reg) \
{ \
int q; \
q=R.HL.D+R.Reg.D+(R.AF.D&1); \
R.AF.B.l=(((R.HL.D^q^R.Reg.D)&0x1000)>>8)| \
((q>>16)&1)| \
((q&0x8000)>>8)| \
((q&65535)?0:Z_FLAG)| \
(((R.Reg.D^R.HL.D^0x8000)&(R.Reg.D^q)&0x8000)>>13); \
R.HL.W.l=q; \
}
#define M_SBCW(Reg) \
{ \
int q; \
q=R.HL.D-R.Reg.D-(R.AF.D&1); \
R.AF.B.l=(((R.HL.D^q^R.Reg.D)&0x1000)>>8)| \
((q>>16)&1)| \
((q&0x8000)>>8)| \
((q&65535)?0:Z_FLAG)| \
(((R.Reg.D^R.HL.D)&(R.Reg.D^q)&0x8000)>>13)| \
N_FLAG; \
R.HL.W.l=q; \
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,182 @@
#pragma once
/* #define DEBUG */ /* Compile debugging version */
/* #define X86_ASM */ /* Compile optimised GCC/x86 version */
#define LSB_FIRST /* Compile for low-endian CPU */
/* #define __64BIT__ */ /* Compile for 64 bit machines */
/* #define __128BIT__ */ /* Compile for 128 bit machines */
#ifndef EMU_TYPES
#define EMU_TYPES
/****************************************************************************/
/* sizeof(byte)=1, sizeof(word)=2, sizeof(dword)>=4 */
/****************************************************************************/
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned dword;
typedef signed char offset;
/****************************************************************************/
/* Define a Z80 word. Upper bytes are always zero */
/****************************************************************************/
typedef union
{
#ifdef __128BIT__
#ifdef LSB_FIRST
struct { byte l,h,h2,h3,h4,h5,h6,h7,
h8,h9,h10,h11,h12,h13,h14,h15; } B;
struct { word l,h,h2,h3,h4,h5,h6,h7; } W;
dword D;
#else
struct { byte h15,h14,h13,h12,h11,h10,h9,h8,
h7,h6,h5,h4,h3,h2,h,l; } B;
struct { word h7,h6,h5,h4,h3,h2,h,l; } W;
dword D;
#endif
#elif __64BIT__
#ifdef LSB_FIRST
struct { byte l,h,h2,h3,h4,h5,h6,h7; } B;
struct { word l,h,h2,h3; } W;
dword D;
#else
struct { byte h7,h6,h5,h4,h3,h2,h,l; } B;
struct { word h3,h2,h,l; } W;
dword D;
#endif
#else
#ifdef LSB_FIRST
struct { byte l,h,h2,h3; } B;
struct { word l,h; } W;
dword D;
#else
struct { byte h3,h2,h,l; } B;
struct { word h,l; } W;
dword D;
#endif
#endif
} regpair;
#endif /* EMU_TYPES */
/****************************************************************************/
/*** End of machine dependent definitions ***/
/****************************************************************************/
#ifndef INLINE
#define INLINE static inline
#endif
/****************************************************************************/
/* The Z80 registers. HALT is set to 1 when the CPU is halted, the refresh */
/* register is calculated as follows: refresh=(Regs.R&127)|(Regs.R2&128) */
/****************************************************************************/
typedef struct
{
regpair AF,BC,DE,HL,IX,IY,PC,SP;
regpair AF2,BC2,DE2,HL2;
unsigned IFF1,IFF2,HALT,IM,I,R,R2;
} Z80_Regs;
/****************************************************************************/
/* Set Z80_Trace to 1 when PC==Z80_Trap. When trace is on, Z80_Debug() is */
/* called after every instruction */
/****************************************************************************/
#ifdef DEBUG
extern int Z80_Trace;
extern int Z80_Trap;
void Z80_Debug(Z80_Regs *R);
#endif
extern int Z80_Running; /* When 0, emulation terminates */
extern int Z80_IPeriod; /* Number of T-states per interrupt */
extern int Z80_ICount; /* T-state count */
extern int Z80_IRQ; /* Current IRQ status. Checked after EI occurs */
#define Z80_IGNORE_INT -1 /* Ignore interrupt */
#define Z80_NMI_INT -2 /* Execute NMI */
DWORD InternalZ80Execute (ULONG totalcycles, ULONG uExecutedCycles);
unsigned Z80_GetPC (void); /* Get program counter */
void InitTables (void);
void Z80_GetRegs (Z80_Regs *Regs); /* Get registers */
void Z80_SetRegs (Z80_Regs *Regs); /* Set registers */
void Z80_Reset (void); /* Reset registers to the initial values */
//int Z80_Execute (void); /* Execute IPeriod T-States */
word Z80 (void); /* Execute until Z80_Running==0 */
void Z80_RegisterDump (void); /* Prints a dump to stdout */
void Z80_SetWaitStates (int n); /* Set number of memory wait states. */
/* This only affects opcode fetching, so */
/* wait state adjustment is still */
/* necessary in Z80_RDMEM, Z80_RDOP_ARG, */
/* Z80_RDSTACK and Z80_WRSTACK */
void Z80_Patch (Z80_Regs *Regs); /* Called when ED FE occurs. Can be used */
/* to emulate disk access etc. */
int Z80_Interrupt(void); /* This is called after IPeriod T-States */
/* have been executed. It should return */
/* Z80_IGNORE_INT, Z80_NMI_INT or a byte */
/* identifying the device (most often */
/* 0xFF) */
void Z80_Reti (void); /* Called when RETI occurs */
void Z80_Retn (void); /* Called when RETN occurs */
/****************************************************************************/
/* Definitions of functions to read/write memory and I/O ports */
/* You can replace these with your own, inlined if necessary */
/****************************************************************************/
#include "Z80IO.h"
// ---------------------------------------------------------
#define M_RDMEM(A) Z80_RDMEM(A)
#define M_WRMEM(A,V) Z80_WRMEM(A,V)
#define M_RDOP(A) Z80_RDOP(A)
#define M_RDOP_ARG(A) Z80_RDOP_ARG(A)
#define M_RDSTACK(A) Z80_RDSTACK(A)
#define M_WRSTACK(A,V) Z80_WRSTACK(A,V)
#define DoIn(lo,hi) Z80_In((lo)+(((unsigned)(hi))<<8))
#define DoOut(lo,hi,v) Z80_Out((lo)+(((unsigned)(hi))<<8),v)
static void Interrupt(int j);
static void ei(void);
#define S_FLAG 0x80
#define Z_FLAG 0x40
#define H_FLAG 0x10
#define V_FLAG 0x04
#define N_FLAG 0x02
#define C_FLAG 0x01
#define M_SKIP_CALL R.PC.W.l+=2
#define M_SKIP_JP R.PC.W.l+=2
#define M_SKIP_JR R.PC.W.l+=1
#define M_SKIP_RET
static Z80_Regs R;
#ifdef DEBUG
int Z80_Trace=0;
int Z80_Trap=-1;
#endif
#ifdef TRACE
static unsigned pc_trace[256];
static unsigned pc_count=0;
#endif
static byte PTable[512];
static byte ZSTable[512];
static byte ZSPTable[512];
#include "Z80DAA.h"
typedef void (*opcode_fn) (void);
#define M_C (R.AF.B.l&C_FLAG)
#define M_NC (!M_C)
#define M_Z (R.AF.B.l&Z_FLAG)
#define M_NZ (!M_Z)
#define M_M (R.AF.B.l&S_FLAG)
#define M_P (!M_M)
#define M_PE (R.AF.B.l&V_FLAG)
#define M_PO (!M_PE)

2063
AppleWin/source/Z80/z80daa.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
/* Emulador do computador TK3000 //e (Microdigital)
* por Fábio Belavenuto - Copyright (C) 2004
*
* Adaptado do emulador Applewin por Michael O'Brien
* Part of code is Copyright (C) 2003-2004 Tom Charlesworth
*
* Este arquivo é distribuido pela Licença Pública Geral GNU.
* Veja o arquivo Licenca.txt distribuido com este software.
*
* ESTE SOFTWARE NÃO OFERECE NENHUMA GARANTIA
*
*/
// Emula a CPU Z80
#include "..\StdAfx.h"
#include "z80emu.h"
// Variaveis
int CPMZ80Slot = 0;
int Z80_IRQ = 0;
BYTE __stdcall CPMZ80_IONull(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
{
return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
}
BYTE __stdcall CPMZ80_IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
{
if ((uAddr & 0xFF00) == (0xC000 + (CPMZ80Slot << 8)))
{
g_ActiveCPU = (g_ActiveCPU == CPU_6502) ? CPU_Z80 : CPU_6502;
}
return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft);
}
//===========================================================================
void ConfigureSoftcard(LPBYTE pCxRomPeripheral, int Slot, UINT addOrRemove)
{
//LPBYTE pCxRomPeripheral = MemGetCxRomPeripheral();
//if (pCxRomPeripheral == NULL)
// return;
//UINT uOffset = (m_by6821B << 7) & 0x0700;
//memcpy(pCxRomPeripheral+m_uSlot*256, m_pSlotRom+uOffset, 256);
//if (mem)
// memcpy(mem+0xC000+m_uSlot*256, m_pSlotRom+uOffset, 256);
memset(pCxRomPeripheral + (Slot << 8), 0xFF, 256);
CPMZ80Slot = Slot;
RegisterIoHandler(Slot, CPMZ80_IONull, CPMZ80_IONull, CPMZ80_IONull, addOrRemove ? CPMZ80_IOWrite : NULL, NULL, NULL);
}
// EOF

View File

@ -0,0 +1,18 @@
/* Emulador do computador TK3000 //e (Microdigital)
* por Fábio Belavenuto - Copyright (C) 2004
*
* Adaptado do emulador Applewin por Michael O'Brien
*
* Este arquivo é distribuido pela Licença Pública Geral GNU.
* Veja o arquivo Licenca.txt distribuido com este software.
*
* ESTE SOFTWARE NÃO OFERECE NENHUMA GARANTIA
*
*/
// Emula a CPU Z80
// Protótipos
void ConfigureSoftcard(LPBYTE pCxRomPeripheral, int slot, UINT addOrRemove);
// EOF

View File

@ -0,0 +1,17 @@
/* Emulador do computador TK3000 //e (Microdigital)
* por Fábio Belavenuto - Copyright (C) 2004
*
* Adaptado do emulador Applewin por Michael O'Brien
*
* Este arquivo é distribuido pela Licença Pública Geral GNU.
* Veja o arquivo Licenca.txt distribuido com este software.
*
* ESTE SOFTWARE NÃO OFERECE NENHUMA GARANTIA
*
*/
// Emula a CPU Z80
#include "..\stdafx.h"
#include "Z80IO.h"

View File

@ -0,0 +1,70 @@
/*** Z80Em: Portable Z80 emulator *******************************************/
/*** ***/
/*** Z80IO.h ***/
/*** ***/
/*** This file contains the prototypes for the functions accessing memory ***/
/*** and I/O ***/
/*** ***/
/*** Copyright (C) Marcel de Kogel 1996,1997 ***/
/*** You are not allowed to distribute this software commercially ***/
/*** Please, notify me, if you make any changes to this file ***/
/****************************************************************************/
/****************************************************************************/
/* Input a byte from given I/O port */
/****************************************************************************/
byte Z80_In (BYTE Port);
/****************************************************************************/
/* Output a byte to given I/O port */
/****************************************************************************/
void Z80_Out (BYTE Port,BYTE Value);
/****************************************************************************/
/* Read a byte from given memory location */
/****************************************************************************/
unsigned Z80_RDMEM(DWORD A);
/****************************************************************************/
/* Write a byte to given memory location */
/****************************************************************************/
void Z80_WRMEM(DWORD A,BYTE V);
/****************************************************************************/
/* Just to show you can actually use macros as well */
/****************************************************************************/
/*
extern byte *ReadPage[256];
extern byte *WritePage[256];
#define Z80_RDMEM(a) ReadPage[(a)>>8][(a)&0xFF]
#define Z80_WRMEM(a,v) WritePage[(a)>>8][(a)&0xFF]=v
*/
/****************************************************************************/
/* Z80_RDOP() is identical to Z80_RDMEM() except it is used for reading */
/* opcodes. In case of system with memory mapped I/O, this function can be */
/* used to greatly speed up emulation */
/****************************************************************************/
#define Z80_RDOP(A) Z80_RDMEM(A)
/****************************************************************************/
/* Z80_RDOP_ARG() is identical to Z80_RDOP() except it is used for reading */
/* opcode arguments. This difference can be used to support systems that */
/* use different encoding mechanisms for opcodes and opcode arguments */
/****************************************************************************/
#define Z80_RDOP_ARG(A) Z80_RDOP(A)
/****************************************************************************/
/* Z80_RDSTACK() is identical to Z80_RDMEM() except it is used for reading */
/* stack variables. In case of system with memory mapped I/O, this function */
/* can be used to slightly speed up emulation */
/****************************************************************************/
#define Z80_RDSTACK(A) Z80_RDMEM(A)
/****************************************************************************/
/* Z80_WRSTACK() is identical to Z80_WRMEM() except it is used for writing */
/* stack variables. In case of system with memory mapped I/O, this function */
/* can be used to slightly speed up emulation */
/****************************************************************************/
#define Z80_WRSTACK(A,V) Z80_WRMEM(A,V)