[CPCHawk] Trying a new z80 implementation

This commit is contained in:
Asnivor 2024-10-06 22:00:57 +01:00
parent 9e0cfb117b
commit c644ed19ef
19 changed files with 6084 additions and 25 deletions

1
.gitignore vendored
View File

@ -48,3 +48,4 @@ UpgradeLog.htm
/packages
launchSettings.json
/ExternalProjects/FlooohZ80/x64

BIN
Assets/dll/FlooohZ80.dll Normal file

Binary file not shown.

View File

@ -0,0 +1,174 @@
#define CHIPS_IMPL
#include "FlooohZ80.h"
#include <stdlib.h> // Include for malloc and free
LibFz80::LibFz80() {
z80Instance = new z80_t();
z80_init(z80Instance);
}
LibFz80::~LibFz80() {
delete z80Instance;
}
uint64_t LibFz80::Initialize() {
return z80_init(z80Instance);
}
uint64_t LibFz80::Reset() {
return z80_reset(z80Instance);
}
uint64_t LibFz80::Tick(uint64_t pins) {
return z80_tick(z80Instance, pins);
}
uint64_t LibFz80::Prefetch(uint16_t new_pc) {
return z80_prefetch(z80Instance, new_pc);
}
bool LibFz80::InstructionDone() {
return z80_opdone(z80Instance);
}
// Getter methods for z80_t members
uint16_t LibFz80::GET_step() { return z80Instance->step; }
uint16_t LibFz80::GET_addr() { return z80Instance->addr; }
uint8_t LibFz80::GET_dlatch() { return z80Instance->dlatch; }
uint8_t LibFz80::GET_opcode() { return z80Instance->opcode; }
uint8_t LibFz80::GET_hlx_idx() { return z80Instance->hlx_idx; }
bool LibFz80::GET_prefix_active() { return z80Instance->prefix_active; }
uint64_t LibFz80::GET_pins() { return z80Instance->pins; }
uint64_t LibFz80::GET_int_bits() { return z80Instance->int_bits; }
uint16_t LibFz80::GET_pc() { return z80Instance->pc; }
uint16_t LibFz80::GET_af() { return z80Instance->af; }
uint16_t LibFz80::GET_bc() { return z80Instance->bc; }
uint16_t LibFz80::GET_de() { return z80Instance->de; }
uint16_t LibFz80::GET_hl() { return z80Instance->hl; }
uint16_t LibFz80::GET_ix() { return z80Instance->ix; }
uint16_t LibFz80::GET_iy() { return z80Instance->iy; }
uint16_t LibFz80::GET_wz() { return z80Instance->wz; }
uint16_t LibFz80::GET_sp() { return z80Instance->sp; }
uint16_t LibFz80::GET_ir() { return z80Instance->ir; }
uint16_t LibFz80::GET_af2() { return z80Instance->af2; }
uint16_t LibFz80::GET_bc2() { return z80Instance->bc2; }
uint16_t LibFz80::GET_de2() { return z80Instance->de2; }
uint16_t LibFz80::GET_hl2() { return z80Instance->hl2; }
uint8_t LibFz80::GET_im() { return z80Instance->im; }
bool LibFz80::GET_iff1() { return z80Instance->iff1; }
bool LibFz80::GET_iff2() { return z80Instance->iff2; }
// Setter methods for z80_t members
void LibFz80::SET_step(uint16_t value) { z80Instance->step = value; }
void LibFz80::SET_addr(uint16_t value) { z80Instance->addr = value; }
void LibFz80::SET_dlatch(uint8_t value) { z80Instance->dlatch = value; }
void LibFz80::SET_opcode(uint8_t value) { z80Instance->opcode = value; }
void LibFz80::SET_hlx_idx(uint8_t value) { z80Instance->hlx_idx = value; }
void LibFz80::SET_prefix_active(bool value) { z80Instance->prefix_active = value; }
void LibFz80::SET_pins(uint64_t value) { z80Instance->pins = value; }
void LibFz80::SET_int_bits(uint64_t value) { z80Instance->int_bits = value; }
void LibFz80::SET_pc(uint16_t value) { z80Instance->pc = value; }
void LibFz80::SET_af(uint16_t value) { z80Instance->af = value; }
void LibFz80::SET_bc(uint16_t value) { z80Instance->bc = value; }
void LibFz80::SET_de(uint16_t value) { z80Instance->de = value; }
void LibFz80::SET_hl(uint16_t value) { z80Instance->hl = value; }
void LibFz80::SET_ix(uint16_t value) { z80Instance->ix = value; }
void LibFz80::SET_iy(uint16_t value) { z80Instance->iy = value; }
void LibFz80::SET_wz(uint16_t value) { z80Instance->wz = value; }
void LibFz80::SET_sp(uint16_t value) { z80Instance->sp = value; }
void LibFz80::SET_ir(uint16_t value) { z80Instance->ir = value; }
void LibFz80::SET_af2(uint16_t value) { z80Instance->af2 = value; }
void LibFz80::SET_bc2(uint16_t value) { z80Instance->bc2 = value; }
void LibFz80::SET_de2(uint16_t value) { z80Instance->de2 = value; }
void LibFz80::SET_hl2(uint16_t value) { z80Instance->hl2 = value; }
void LibFz80::SET_im(uint8_t value) { z80Instance->im = value; }
void LibFz80::SET_iff1(bool value) { z80Instance->iff1 = value; }
void LibFz80::SET_iff2(bool value) { z80Instance->iff2 = value; }
// Expose the functions for C# interoperability
extern "C" {
__declspec(dllexport) LibFz80* CreateLibFz80() {
return new LibFz80();
}
__declspec(dllexport) void DestroyLibFz80(LibFz80* instance) {
delete instance;
}
__declspec(dllexport) uint64_t LibFz80_Initialize(LibFz80* instance) {
return instance->Initialize();
}
__declspec(dllexport) uint64_t LibFz80_Reset(LibFz80* instance) {
return instance->Reset();
}
__declspec(dllexport) uint64_t LibFz80_Tick(LibFz80* instance, uint64_t pins) {
return instance->Tick(pins);
}
__declspec(dllexport) uint64_t LibFz80_Prefetch(LibFz80* instance, uint16_t new_pc) {
return instance->Prefetch(new_pc);
}
__declspec(dllexport) bool LibFz80_InstructionDone(LibFz80* instance) {
return instance->InstructionDone();
}
// Getter functions
__declspec(dllexport) uint16_t LibFz80_GET_step(LibFz80* instance) { return instance->GET_step(); }
__declspec(dllexport) uint16_t LibFz80_GET_addr(LibFz80* instance) { return instance->GET_addr(); }
__declspec(dllexport) uint8_t LibFz80_GET_dlatch(LibFz80* instance) { return instance->GET_dlatch(); }
__declspec(dllexport) uint8_t LibFz80_GET_opcode(LibFz80* instance) { return instance->GET_opcode(); }
__declspec(dllexport) uint8_t LibFz80_GET_hlx_idx(LibFz80* instance) { return instance->GET_hlx_idx(); }
__declspec(dllexport) bool LibFz80_GET_prefix_active(LibFz80* instance) { return instance->GET_prefix_active(); }
__declspec(dllexport) uint64_t LibFz80_GET_pins(LibFz80* instance) { return instance->GET_pins(); }
__declspec(dllexport) uint64_t LibFz80_GET_int_bits(LibFz80* instance) { return instance->GET_int_bits(); }
__declspec(dllexport) uint16_t LibFz80_GET_pc(LibFz80* instance) { return instance->GET_pc(); }
__declspec(dllexport) uint16_t LibFz80_GET_af(LibFz80* instance) { return instance->GET_af(); }
__declspec(dllexport) uint16_t LibFz80_GET_bc(LibFz80* instance) { return instance->GET_bc(); }
__declspec(dllexport) uint16_t LibFz80_GET_de(LibFz80* instance) { return instance->GET_de(); }
__declspec(dllexport) uint16_t LibFz80_GET_hl(LibFz80* instance) { return instance->GET_hl(); }
__declspec(dllexport) uint16_t LibFz80_GET_ix(LibFz80* instance) { return instance->GET_ix(); }
__declspec(dllexport) uint16_t LibFz80_GET_iy(LibFz80* instance) { return instance->GET_iy(); }
__declspec(dllexport) uint16_t LibFz80_GET_wz(LibFz80* instance) { return instance->GET_wz(); }
__declspec(dllexport) uint16_t LibFz80_GET_sp(LibFz80* instance) { return instance->GET_sp(); }
__declspec(dllexport) uint16_t LibFz80_GET_ir(LibFz80* instance) { return instance->GET_ir(); }
__declspec(dllexport) uint16_t LibFz80_GET_af2(LibFz80* instance) { return instance->GET_af2(); }
__declspec(dllexport) uint16_t LibFz80_GET_bc2(LibFz80* instance) { return instance->GET_bc2(); }
__declspec(dllexport) uint16_t LibFz80_GET_de2(LibFz80* instance) { return instance->GET_de2(); }
__declspec(dllexport) uint16_t LibFz80_GET_hl2(LibFz80* instance) { return instance->GET_hl2(); }
__declspec(dllexport) uint8_t LibFz80_GET_im(LibFz80* instance) { return instance->GET_im(); }
__declspec(dllexport) bool LibFz80_GET_iff1(LibFz80* instance) { return instance->GET_iff1(); }
__declspec(dllexport) bool LibFz80_GET_iff2(LibFz80* instance) { return instance->GET_iff2(); }
// Setter functions
__declspec(dllexport) void LibFz80_SET_step(LibFz80* instance, uint16_t value) { instance->SET_step(value); }
__declspec(dllexport) void LibFz80_SET_addr(LibFz80* instance, uint16_t value) { instance->SET_addr(value); }
__declspec(dllexport) void LibFz80_SET_dlatch(LibFz80* instance, uint8_t value) { instance->SET_dlatch(value); }
__declspec(dllexport) void LibFz80_SET_opcode(LibFz80* instance, uint8_t value) { instance->SET_opcode(value); }
__declspec(dllexport) void LibFz80_SET_hlx_idx(LibFz80* instance, uint8_t value) { instance->SET_hlx_idx(value); }
__declspec(dllexport) void LibFz80_SET_prefix_active(LibFz80* instance, bool value) { instance->SET_prefix_active(value); }
__declspec(dllexport) void LibFz80_SET_pins(LibFz80* instance, uint64_t value) { instance->SET_pins(value); }
__declspec(dllexport) void LibFz80_SET_int_bits(LibFz80* instance, uint64_t value) { instance->SET_int_bits(value); }
__declspec(dllexport) void LibFz80_SET_pc(LibFz80* instance, uint16_t value) { instance->SET_pc(value); }
__declspec(dllexport) void LibFz80_SET_af(LibFz80* instance, uint16_t value) { instance->SET_af(value); }
__declspec(dllexport) void LibFz80_SET_bc(LibFz80* instance, uint16_t value) { instance->SET_bc(value); }
__declspec(dllexport) void LibFz80_SET_de(LibFz80* instance, uint16_t value) { instance->SET_de(value); }
__declspec(dllexport) void LibFz80_SET_hl(LibFz80* instance, uint16_t value) { instance->SET_hl(value); }
__declspec(dllexport) void LibFz80_SET_ix(LibFz80* instance, uint16_t value) { instance->SET_ix(value); }
__declspec(dllexport) void LibFz80_SET_iy(LibFz80* instance, uint16_t value) { instance->SET_iy(value); }
__declspec(dllexport) void LibFz80_SET_wz(LibFz80* instance, uint16_t value) { instance->SET_wz(value); }
__declspec(dllexport) void LibFz80_SET_sp(LibFz80* instance, uint16_t value) { instance->SET_sp(value); }
__declspec(dllexport) void LibFz80_SET_ir(LibFz80* instance, uint16_t value) { instance->SET_ir(value); }
__declspec(dllexport) void LibFz80_SET_af2(LibFz80* instance, uint16_t value) { instance->SET_af2(value); }
__declspec(dllexport) void LibFz80_SET_bc2(LibFz80* instance, uint16_t value) { instance->SET_bc2(value); }
__declspec(dllexport) void LibFz80_SET_de2(LibFz80* instance, uint16_t value) { instance->SET_de2(value); }
__declspec(dllexport) void LibFz80_SET_hl2(LibFz80* instance, uint16_t value) { instance->SET_hl2(value); }
__declspec(dllexport) void LibFz80_SET_im(LibFz80* instance, uint8_t value) { instance->SET_im(value); }
__declspec(dllexport) void LibFz80_SET_iff1(LibFz80* instance, bool value) { instance->SET_iff1(value); }
__declspec(dllexport) void LibFz80_SET_iff2(LibFz80* instance, bool value) { instance->SET_iff2(value); }
}

View File

@ -0,0 +1,142 @@
#ifndef FLOOOHZ80_H
#define FLOOOHZ80_H
#include <stdint.h>
#include <stdbool.h>
#include "z80.h"
class LibFz80 {
public:
LibFz80();
~LibFz80();
uint64_t Initialize();
uint64_t Reset();
uint64_t Tick(uint64_t pins);
uint64_t Prefetch(uint16_t new_pc);
bool InstructionDone();
// getter methods for the z80_t struct members
uint16_t GET_step();
uint16_t GET_addr();
uint8_t GET_dlatch();
uint8_t GET_opcode();
uint8_t GET_hlx_idx();
bool GET_prefix_active();
uint64_t GET_pins();
uint64_t GET_int_bits();
uint16_t GET_pc();
uint16_t GET_af();
uint16_t GET_bc();
uint16_t GET_de();
uint16_t GET_hl();
uint16_t GET_ix();
uint16_t GET_iy();
uint16_t GET_wz();
uint16_t GET_sp();
uint16_t GET_ir();
uint16_t GET_af2();
uint16_t GET_bc2();
uint16_t GET_de2();
uint16_t GET_hl2();
uint8_t GET_im();
bool GET_iff1();
bool GET_iff2();
// setter methods for the z80_t struct members
void SET_step(uint16_t value);
void SET_addr(uint16_t value);
void SET_dlatch(uint8_t value);
void SET_opcode(uint8_t value);
void SET_hlx_idx(uint8_t value);
void SET_prefix_active(bool value);
void SET_pins(uint64_t value);
void SET_int_bits(uint64_t value);
void SET_pc(uint16_t value);
void SET_af(uint16_t value);
void SET_bc(uint16_t value);
void SET_de(uint16_t value);
void SET_hl(uint16_t value);
void SET_ix(uint16_t value);
void SET_iy(uint16_t value);
void SET_wz(uint16_t value);
void SET_sp(uint16_t value);
void SET_ir(uint16_t value);
void SET_af2(uint16_t value);
void SET_bc2(uint16_t value);
void SET_de2(uint16_t value);
void SET_hl2(uint16_t value);
void SET_im(uint8_t value);
void SET_iff1(bool value);
void SET_iff2(bool value);
private:
z80_t* z80Instance;
};
// Expose the functions for C# interoperability
extern "C" {
__declspec(dllexport) LibFz80* CreateLibFz80();
__declspec(dllexport) void DestroyLibFz80(LibFz80* instance);
__declspec(dllexport) uint64_t LibFz80_Initialize(LibFz80* instance);
__declspec(dllexport) uint64_t LibFz80_Reset(LibFz80* instance);
__declspec(dllexport) uint64_t LibFz80_Tick(LibFz80* instance, uint64_t pins);
__declspec(dllexport) uint64_t LibFz80_Prefetch(LibFz80* instance, uint16_t new_pc);
__declspec(dllexport) bool LibFz80_InstructionDone(LibFz80* instance);
// expose struct field getters
__declspec(dllexport) uint16_t LibFz80_GET_step(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_addr(LibFz80* instance);
__declspec(dllexport) uint8_t LibFz80_GET_dlatch(LibFz80* instance);
__declspec(dllexport) uint8_t LibFz80_GET_opcode(LibFz80* instance);
__declspec(dllexport) uint8_t LibFz80_GET_hlx_idx(LibFz80* instance);
__declspec(dllexport) bool LibFz80_GET_prefix_active(LibFz80* instance);
__declspec(dllexport) uint64_t LibFz80_GET_pins(LibFz80* instance);
__declspec(dllexport) uint64_t LibFz80_GET_int_bits(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_pc(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_af(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_bc(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_de(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_hl(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_ix(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_iy(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_wz(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_sp(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_ir(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_af2(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_bc2(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_de2(LibFz80* instance);
__declspec(dllexport) uint16_t LibFz80_GET_hl2(LibFz80* instance);
__declspec(dllexport) uint8_t LibFz80_GET_im(LibFz80* instance);
__declspec(dllexport) bool LibFz80_GET_iff1(LibFz80* instance);
__declspec(dllexport) bool LibFz80_GET_iff2(LibFz80* instance);
// expose struct field setters
__declspec(dllexport) void LibFz80_SET_step(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_addr(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_dlatch(LibFz80* instance, uint8_t value);
__declspec(dllexport) void LibFz80_SET_opcode(LibFz80* instance, uint8_t value);
__declspec(dllexport) void LibFz80_SET_hlx_idx(LibFz80* instance, uint8_t value);
__declspec(dllexport) void LibFz80_SET_prefix_active(LibFz80* instance, bool value);
__declspec(dllexport) void LibFz80_SET_pins(LibFz80* instance, uint64_t value);
__declspec(dllexport) void LibFz80_SET_int_bits(LibFz80* instance, uint64_t value);
__declspec(dllexport) void LibFz80_SET_pc(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_af(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_bc(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_de(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_hl(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_ix(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_iy(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_wz(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_sp(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_ir(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_af2(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_bc2(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_de2(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_hl2(LibFz80* instance, uint16_t value);
__declspec(dllexport) void LibFz80_SET_im(LibFz80* instance, uint8_t value);
__declspec(dllexport) void LibFz80_SET_iff1(LibFz80* instance, bool value);
__declspec(dllexport) void LibFz80_SET_iff2(LibFz80* instance, bool value);
}
#endif // FLOOOHZ80_H

View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35312.102
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FlooohZ80", "FlooohZ80.vcxproj", "{E1CCFFD1-D23B-4507-88EA-0184A6CE99BF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E1CCFFD1-D23B-4507-88EA-0184A6CE99BF}.Debug|x64.ActiveCfg = Debug|x64
{E1CCFFD1-D23B-4507-88EA-0184A6CE99BF}.Debug|x64.Build.0 = Debug|x64
{E1CCFFD1-D23B-4507-88EA-0184A6CE99BF}.Debug|x86.ActiveCfg = Debug|Win32
{E1CCFFD1-D23B-4507-88EA-0184A6CE99BF}.Debug|x86.Build.0 = Debug|Win32
{E1CCFFD1-D23B-4507-88EA-0184A6CE99BF}.Release|x64.ActiveCfg = Release|x64
{E1CCFFD1-D23B-4507-88EA-0184A6CE99BF}.Release|x64.Build.0 = Release|x64
{E1CCFFD1-D23B-4507-88EA-0184A6CE99BF}.Release|x86.ActiveCfg = Release|Win32
{E1CCFFD1-D23B-4507-88EA-0184A6CE99BF}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {34D77329-729A-4192-A813-9163DDBEB85A}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{e1ccffd1-d23b-4507-88ea-0184a6ce99bf}</ProjectGuid>
<RootNamespace>FlooohZ80</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>..\..\Assets\dll</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>FlooohZ80</TargetName>
<TargetExt>.dll</TargetExt>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>..\..\Assets\dll</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>FlooohZ80</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;CHIPS_IMPL;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
<ShowProgress>LinkVerbose</ShowProgress>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="FlooohZ80.h" />
<ClInclude Include="z80.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="FlooohZ80.cpp">
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pch.h</PrecompiledHeaderFile>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Default</CompileAs>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="LICENSE.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,17 @@
zlib/libpng license
Copyright (c) 2018 Andre Weissflog
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the
use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software in a
product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
}
_isLag = true;
/*
if (_tracer.IsEnabled())
{
_cpu.TraceCallback = s => _tracer.Put(s);
@ -35,6 +35,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
{
_cpu.TraceCallback = null;
}
*/
_machine.ExecuteFrame(ren, renSound);

View File

@ -4,7 +4,7 @@ using System.Linq;
using BizHawk.Common;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Components.Z80A;
//using BizHawk.Emulation.Cores.Components.Z80A;
using BizHawk.Emulation.Cores.Properties;
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
@ -23,8 +23,9 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
ServiceProvider = ser;
CoreComm = lp.Comm;
_gameInfo = lp.Roms.Select(r => r.Game).ToList();
_cpu = new Z80A<CpuLink>(default);
_tracer = new TraceBuffer(_cpu.TraceHeader);
//_cpu = new Z80A<CpuLink>(default);
_cpu = new LibFz80Wrapper();
//_tracer = new TraceBuffer(_cpu.TraceHeader);
_files = lp.Roms.Select(r => r.RomData).ToList();
var settings = lp.Settings ?? new AmstradCPCSettings();
@ -53,11 +54,17 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
HardReset = _machine.HardReset;
SoftReset = _machine.SoftReset;
_cpu.SetCpuLink(new CpuLink(_machine));
//_cpu.SetCpuLink(new CpuLink(_machine));
ser.Register<ITraceable>(_tracer);
ser.Register<IDisassemblable>(_cpu);
//ser.Register<IVideoProvider>(_machine.GateArray);
_cpu.ReadMemory = _machine.ReadMemory;
_cpu.WriteMemory = _machine.WriteMemory;
_cpu.ReadPort = _machine.ReadPort;
_cpu.WritePort = _machine.WritePort;
//_cpu.OnExecFetch = _machine.OnExecFetch;
//ser.Register<ITraceable>(_tracer);
//ser.Register<IDisassemblable>(_cpu);
ser.Register<IVideoProvider>(_machine.CRTScreen);
ser.Register<IStatable>(new StateSerializer(SyncState));
@ -89,7 +96,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
public Action HardReset;
public Action SoftReset;
private readonly Z80A<CpuLink> _cpu;
//private readonly Z80A<CpuLink> _cpu;
private readonly LibFz80Wrapper _cpu;
private readonly TraceBuffer _tracer;
public IController _controller;
public CPCBase _machine;

View File

@ -1,5 +1,6 @@
using BizHawk.Common;
using BizHawk.Emulation.Cores.Components.Z80A;
//using BizHawk.Emulation.Cores.Components.Z80A;
using System.Collections.Generic;
using System.Linq;
@ -13,7 +14,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
public sealed class DatacorderDevice
{
private CPCBase _machine;
private Z80A<AmstradCPC.CpuLink> CPU => _machine.CPU;
//private Z80A<AmstradCPC.CpuLink> CPU => _machine.CPU;
private LibFz80Wrapper CPU => _machine.CPU;
private IBeeperDevice Buzzer => _machine.TapeBuzzer;
/// <summary>

View File

@ -1,7 +1,7 @@

using BizHawk.Common;
using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Cores.Components.Z80A;
//using BizHawk.Emulation.Cores.Components.Z80A;
using System.Linq;
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
@ -16,12 +16,13 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
public class GateArray : IPortIODevice
{
private readonly CPCBase _machine;
private Z80A<AmstradCPC.CpuLink> CPU => _machine.CPU;
//private Z80A<AmstradCPC.CpuLink> CPU => _machine.CPU;
private LibFz80Wrapper CPU => _machine.CPU;
private CRTC CRTC => _machine.CRTC;
private CRTScreen CRT => _machine.CRTScreen;
private IPSG PSG => _machine.AYDevice;
private ushort BUSRQ => CPU.MEMRQ[CPU.bus_pntr];
//private ushort BUSRQ => CPU.MEMRQ[CPU.bus_pntr];
private GateArrayType GateArrayType;
/// <summary>
@ -364,7 +365,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
if (_r52 == 0)
{
// The GATE ARRAY sends an interrupt request when R52=0
CPU.FlagI = true;
//CPU.FlagI = true;
CPU.INT = 1;
interruptsPerFrame++;
}
else if (GA_VSYNC && _r52 == 2)
@ -373,7 +375,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
if (_r52.Bit(5))
{
// An interrupt is requested by the GATE ARRAY from the Z80A only if bit 5 of R52 is 1
CPU.FlagI = true;
//CPU.FlagI = true;
CPU.INT = 1;
interruptsPerFrame++;
}
@ -455,6 +458,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
CRTC.AttachVSYNCOnCallback(OnVSYNCOn);
CRTC.AttachVSYNCOffCallback(OnVSYNCOff);
CPU.AttachIRQACKOnCallback(IORQA);
SetPalette(GateArrayType);
Reset();
@ -468,7 +473,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
// an armed (pending) interrupt is acknowledged/authorised by the CPU
// R52 Bit5 is reset
_r52 &= ~(1 << 5);
CPU.FlagI = false;
//CPU.FlagI = false;
CPU.INT = 0;
}
/// <summary>
@ -626,7 +632,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
OutputByte(0);
// READY HIGH (Z80 /WAIT is inactive)
CPU.FlagW = false;
//CPU.FlagW = false;
CPU.WAIT = 0;
// /RAS LOW
// /CCLK LOW
@ -658,7 +665,8 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
case 4:
// READY LOW (Z80 /WAIT is active)
CPU.FlagW = true;
//CPU.FlagW = true;
CPU.WAIT = 1;
// PHI HIGH (2)
CPU.ExecuteOne();

View File

@ -0,0 +1,660 @@
using BizHawk.Common;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Nintendo.NES;
using SDL2;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using static BizHawk.Common.Shell32Imports.BROWSEINFOW;
using System.Security.Cryptography;
using BizHawk.Common.NumberExtensions;
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
{
public class LibFz80Wrapper : IDisposable
{
public const int Z80_PIN_M1 = 24; // machine cycle 1
public const int Z80_PIN_MREQ = 25; // memory request
public const int Z80_PIN_IORQ = 26; // input/output request
public const int Z80_PIN_RD = 27; // read
public const int Z80_PIN_WR = 28; // write
public const int Z80_PIN_HALT = 29; // halt state
public const int Z80_PIN_RFSH = 34; // refresh
public const int Z80_PIN_INT = 30; // interrupt request
public const int Z80_PIN_RES = 31; // reset requested
public const int Z80_PIN_NMI = 32; // non-maskable interrupt
public const int Z80_PIN_WAIT = 33; // wait requested
/// <summary>
/// Z80 pin configuration
/// </summary>
public ulong Pins
{
get { return _pins; }
set { _pins = value; }
}
private ulong _pins;
// read only pins
public int M1 => GetPin(Z80_PIN_M1);
public int MREQ => GetPin(Z80_PIN_MREQ);
public int IORQ => GetPin(Z80_PIN_IORQ);
public int RD => GetPin(Z80_PIN_RD);
public int WR => GetPin(Z80_PIN_WR);
public int HALT => GetPin(Z80_PIN_HALT);
public int RFSH => GetPin(Z80_PIN_RFSH);
public ushort ADDR => (ushort)(_pins & 0xFFFF);
// write only pins
public int INT
{
get => GetPin(Z80_PIN_INT);
set => ChangePin(30, value);
}
public int RES
{
get => GetPin(Z80_PIN_RES);
set => Reset(); // the z80 implementation doesn't implement the RES pin properly
}
public int NMI
{
get => GetPin(Z80_PIN_NMI);
set => ChangePin(Z80_PIN_NMI, value);
}
public int WAIT
{
get => GetPin(Z80_PIN_WAIT);
set => ChangePin(Z80_PIN_WAIT, value);
}
// duplex
public byte DB
{
get => (byte)((_pins >> 16) & 0xFF);
set => _pins = (_pins & 0xFFFFFFFFFF00FFFF) | ((ulong)value << 16);
}
public long TotalExecutedCycles;
private int GetPin(int pin)
{
return (_pins & (1UL << pin)) != 0 ? 1 : 0;
}
private void ChangePin(int pin, int value)
{
if (value == 1)
{
_pins |= (1UL << pin);
}
else
{
_pins &= ~(1UL << pin);
}
}
private IntPtr instance;
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateLibFz80();
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void DestroyLibFz80(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern ulong LibFz80_Initialize(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern ulong LibFz80_Reset(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern ulong LibFz80_Tick(IntPtr instance, ulong pins);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern ulong LibFz80_Prefetch(IntPtr instance, ushort new_pc);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern bool LibFz80_InstructionDone(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_step(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_addr(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte LibFz80_GET_dlatch(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte LibFz80_GET_opcode(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte LibFz80_GET_hlx_idx(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LibFz80_GET_prefix_active(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ulong LibFz80_GET_pins(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ulong LibFz80_GET_int_bits(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_pc(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_af(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_bc(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_de(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_hl(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_ix(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_iy(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_wz(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_sp(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_ir(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_af2(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_bc2(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_de2(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern ushort LibFz80_GET_hl2(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte LibFz80_GET_im(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LibFz80_GET_iff1(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LibFz80_GET_iff2(IntPtr instance);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_step(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_addr(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_dlatch(IntPtr instance, byte value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_opcode(IntPtr instance, byte value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_hlx_idx(IntPtr instance, byte value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_prefix_active(IntPtr instance, bool value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_pins(IntPtr instance, ulong value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_addr(IntPtr instance, ulong value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_int_bits(IntPtr instance, ulong value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_pc(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_af(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_bc(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_de(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_hl(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_ix(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_iy(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_wz(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_sp(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_ir(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_af2(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_bc2(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_de2(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_hl2(IntPtr instance, ushort value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_im(IntPtr instance, byte value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_iff1(IntPtr instance, bool value);
[DllImport("FlooohZ80.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void LibFz80_SET_iff2(IntPtr instance, bool value);
/// <summary>
/// Public Delegate
/// </summary>
public delegate void CallBack();
/// <summary>
/// Fired when the CPU acknowledges an interrupt
/// </summary>
private CallBack IRQACK_Callbacks;
public void AttachIRQACKOnCallback(CallBack irqackCall) => IRQACK_Callbacks += irqackCall;
public Func<ushort, byte> ReadMemory;
public Action<ushort, byte> WriteMemory;
public Func<ushort, byte> PeekMemory;
public Func<ushort, byte> DummyReadMemory;
// Port Access
public Func<ushort, byte> ReadPort;
public Action<ushort, byte> WritePort;
//this only calls when the first byte of an instruction is fetched.
public Action<ushort> OnExecFetch;
public LibFz80Wrapper()
{
instance = CreateLibFz80();
_pins = Initialize();
//Z80State = new Z80();
}
public void ExecuteOne()
{
ushort step = GetStep();
if (MREQ == 1 && RD == 1)
{
DB = ReadMemory(ADDR);
}
if (MREQ == 1 && WR == 1)
{
WriteMemory(ADDR, DB);
}
if (IORQ == 1 && RD == 1)
{
DB = ReadPort(ADDR);
}
if (IORQ == 1 && WR == 1)
{
WritePort(ADDR, DB);
}
if (M1 == 1 && IORQ == 1)
{
IRQACK_Callbacks();
}
TotalExecutedCycles++;
_pins = Tick(_pins);
}
public ulong Reset()
{
return LibFz80_Reset(instance);
}
public void Dispose()
{
if (instance != IntPtr.Zero)
{
DestroyLibFz80(instance);
instance = IntPtr.Zero;
}
}
public bool InstructionDone()
{
return LibFz80_InstructionDone(instance);
}
private ulong Initialize()
{
return LibFz80_Initialize(instance);
}
private ulong Tick(ulong pins)
{
return LibFz80_Tick(instance, pins);
}
private ulong Prefetch(ushort new_pc)
{
return LibFz80_Prefetch(instance, new_pc);
}
private ushort GetStep()
{
return LibFz80_GET_step(instance);
}
private void SetStep(ushort value)
{
LibFz80_SET_step(instance, value);
}
ushort step;
ushort addr;
byte dlatch;
byte opcode;
byte hlx_idx;
bool prefix_active;
ulong pins;
ulong int_bits;
ushort pc;
ushort af;
ushort bc;
ushort de;
ushort hl;
ushort ix;
ushort iy;
ushort wz;
ushort sp;
ushort ir;
ushort af2;
ushort bc2;
ushort de2;
ushort hl2;
byte im;
bool iff1;
bool iff2;
private void GetStateFromCpu()
{
step = LibFz80_GET_step(instance);
addr = LibFz80_GET_addr(instance);
dlatch = LibFz80_GET_dlatch(instance);
opcode = LibFz80_GET_opcode(instance);
hlx_idx = LibFz80_GET_hlx_idx(instance);
prefix_active = LibFz80_GET_prefix_active(instance);
pins = LibFz80_GET_pins(instance);
int_bits = LibFz80_GET_int_bits(instance);
pc = LibFz80_GET_pc(instance);
af = LibFz80_GET_af(instance);
bc = LibFz80_GET_bc(instance);
de = LibFz80_GET_de(instance);
hl = LibFz80_GET_hl(instance);
ix = LibFz80_GET_ix(instance);
iy = LibFz80_GET_iy(instance);
wz = LibFz80_GET_wz(instance);
sp = LibFz80_GET_sp(instance);
ir = LibFz80_GET_ir(instance);
af2 = LibFz80_GET_af2(instance);
bc2 = LibFz80_GET_bc2(instance);
de2 = LibFz80_GET_de2(instance);
hl2 = LibFz80_GET_hl2(instance);
im = LibFz80_GET_im(instance);
iff1 = LibFz80_GET_iff1(instance);
iff2 = LibFz80_GET_iff2(instance);
}
private void PutStateToCpu()
{
LibFz80_SET_step(instance, step);
LibFz80_SET_addr(instance, addr);
LibFz80_SET_dlatch(instance, dlatch);
LibFz80_SET_opcode(instance, opcode);
LibFz80_SET_hlx_idx(instance, hlx_idx);
LibFz80_SET_prefix_active(instance, prefix_active);
LibFz80_SET_pins(instance, pins);
LibFz80_SET_int_bits(instance, int_bits);
LibFz80_SET_pc(instance, pc);
LibFz80_SET_af(instance, af);
LibFz80_SET_bc(instance, bc);
LibFz80_SET_de(instance, de);
LibFz80_SET_hl(instance, hl);
LibFz80_SET_ix(instance, ix);
LibFz80_SET_iy(instance, iy);
LibFz80_SET_wz(instance, wz);
LibFz80_SET_sp(instance, sp);
LibFz80_SET_ir(instance, ir);
LibFz80_SET_af2(instance, af2);
LibFz80_SET_bc2(instance, bc2);
LibFz80_SET_de2(instance, de2);
LibFz80_SET_hl2(instance, hl2);
LibFz80_SET_im(instance, im);
LibFz80_SET_iff1(instance, iff1);
LibFz80_SET_iff2(instance, iff2);
}
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
{
GetStateFromCpu();
return new Dictionary<string, RegisterValue>
{
["A"] = af >> 8,
["AF"] = af,
["B"] = bc >> 8,
["BC"] = bc,
["C"] = bc & 0xff,
["D"] = de >> 8,
["DE"] = de,
["E"] = de & 0xff,
["F"] = af * 0xff,
["H"] = hl >> 8,
["HL"] = hl,
["I"] = ir >> 8,
["IX"] = ix,
["IY"] = iy,
["L"] = hl & 0xff,
["PC"] = pc,
["R"] = ir & 0xff,
["Shadow AF"] = af2,
["Shadow BC"] = bc2,
["Shadow DE"] = de2,
["Shadow HL"] = hl2,
["SP"] = sp,
["Flag C"] = af.Bit(0),
["Flag N"] = af.Bit(1),
["Flag P/V"] = af.Bit(2),
["Flag 3rd"] = af.Bit(3),
["Flag H"] = af.Bit(4),
["Flag 5th"] = af.Bit(5),
["Flag Z"] = af.Bit(6),
["Flag S"] = af.Bit(7)
};
}
public void SetCpuRegister(string register, int value)
{
switch (register)
{
default:
throw new InvalidOperationException();
case "A":
af = LibFz80_GET_af(instance);
af |= (ushort)(value << 8);
LibFz80_SET_af(instance, af);
break;
case "AF":
af = (ushort)value;
LibFz80_SET_af(instance, af);
break;
case "B":
bc = LibFz80_GET_bc(instance);
bc |= (ushort)(value << 8);
LibFz80_SET_bc(instance, bc);
break;
case "BC":
bc = (ushort)value;
LibFz80_SET_bc(instance, bc);
break;
case "C":
bc = LibFz80_GET_bc(instance);
bc |= (ushort)(value & 0xff);
LibFz80_SET_bc(instance, bc);
break;
case "D":
de = LibFz80_GET_de(instance);
de |= (ushort)(value << 8);
LibFz80_SET_de(instance, de);
break;
case "DE":
de = (ushort)value;
LibFz80_SET_de(instance, de);
break;
case "E":
de = LibFz80_GET_de(instance);
de |= (ushort)(value & 0xff);
LibFz80_SET_de(instance, de);
break;
case "F":
af = LibFz80_GET_af(instance);
af |= (ushort)(value & 0xff);
LibFz80_SET_af(instance, af);
break;
case "H":
hl = LibFz80_GET_hl(instance);
hl |= (ushort)(value << 8);
LibFz80_SET_hl(instance, hl);
break;
case "HL":
hl = (ushort)value;
LibFz80_SET_hl(instance, hl);
break;
case "I":
ir = LibFz80_GET_ir(instance);
ir |= (ushort)(value << 8);
LibFz80_SET_ir(instance, ir);
break;
case "IX":
ix = (ushort)value;
LibFz80_SET_ix(instance, ix);
break;
case "IY":
iy = (ushort)value;
LibFz80_SET_iy(instance, iy);
break;
case "L":
hl = LibFz80_GET_hl(instance);
hl |= (ushort)(value & 0xff);
LibFz80_SET_hl(instance, hl);
break;
case "PC":
pc = (ushort)value;
LibFz80_SET_pc(instance, pc);
break;
case "R":
ir = LibFz80_GET_ir(instance);
ir |= (ushort)(value & 0xff);
LibFz80_SET_ir(instance, ir);
break;
case "Shadow AF":
af2 = (ushort)value;
LibFz80_SET_af2(instance, af2);
break;
case "Shadow BC":
bc2 = (ushort)value;
LibFz80_SET_bc2(instance, bc2);
break;
case "Shadow DE":
de2 = (ushort)value;
LibFz80_SET_de2(instance, de2);
break;
case "Shadow HL":
hl2 = (ushort)value;
LibFz80_SET_hl2(instance, hl2);
break;
case "SP":
sp = (ushort)value;
LibFz80_SET_sp(instance, sp);
break;
}
}
public void SyncState(Serializer ser)
{
ser.BeginSection("FlooohZ80");
if (ser.IsWriter)
{
GetStateFromCpu();
}
ser.Sync(nameof(step), ref step);
ser.Sync(nameof(addr), ref addr);
ser.Sync(nameof(dlatch), ref dlatch);
ser.Sync(nameof(opcode), ref opcode);
ser.Sync(nameof(hlx_idx), ref hlx_idx);
ser.Sync(nameof(prefix_active), ref prefix_active);
ser.Sync(nameof(pins), ref pins);
ser.Sync(nameof(int_bits), ref int_bits);
ser.Sync(nameof(pc), ref pc);
ser.Sync(nameof(af), ref af);
ser.Sync(nameof(bc), ref bc);
ser.Sync(nameof(de), ref de);
ser.Sync(nameof(hl), ref hl);
ser.Sync(nameof(ix), ref ix);
ser.Sync(nameof(iy), ref iy);
ser.Sync(nameof(wz), ref wz);
ser.Sync(nameof(sp), ref sp);
ser.Sync(nameof(ir), ref ir);
ser.Sync(nameof(af2), ref af2);
ser.Sync(nameof(bc2), ref bc2);
ser.Sync(nameof(de2), ref de2);
ser.Sync(nameof(hl2), ref hl2);
ser.Sync(nameof(im), ref im);
ser.Sync(nameof(iff1), ref iff1);
ser.Sync(nameof(iff2), ref iff2);
if (ser.IsReader)
{
PutStateToCpu();
}
ser.Sync(nameof(_pins), ref _pins);
ser.EndSection();
}
}
}

View File

@ -61,6 +61,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
if (d == PortDevice.CRCT)
{
/*
// ACCC 4.4.2
// However, the CRTCs are not connected to the Z80A's RD and WR pins, so there is no detection of the I/O direction.
// Consequently, if a read instruction is used on a write register of the CRTC, then a data is sent to the CRTC
@ -70,6 +71,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
if (!deviceResponse)
finalResult |= result;
*/
}
if (d == PortDevice.ROMSelect && !deviceResponse)

View File

@ -1,4 +1,5 @@
using BizHawk.Emulation.Cores.Components.Z80A;
//using BizHawk.Emulation.Cores.Components.Z80A;
using System.Collections.Generic;
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
@ -11,7 +12,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
/// <summary>
/// Main constructor
/// </summary>
public CPC464(AmstradCPC cpc, Z80A<AmstradCPC.CpuLink> cpu, List<byte[]> files, bool autoTape, AmstradCPC.BorderType borderType)
public CPC464(AmstradCPC cpc, LibFz80Wrapper cpu, List<byte[]> files, bool autoTape, AmstradCPC.BorderType borderType)
{
CPC = cpc;
CPU = cpu;

View File

@ -60,6 +60,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
if (d == PortDevice.CRCT)
{
/*
// ACCC 4.4.2
// However, the CRTCs are not connected to the Z80A's RD and WR pins, so there is no detection of the I/O direction.
// Consequently, if a read instruction is used on a write register of the CRTC, then a data is sent to the CRTC
@ -69,6 +70,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
if (!deviceResponse)
finalResult |= result;
*/
}
if (d == PortDevice.ROMSelect && !deviceResponse)

View File

@ -1,4 +1,4 @@
using BizHawk.Emulation.Cores.Components.Z80A;
//using BizHawk.Emulation.Cores.Components.Z80A;
using System.Collections.Generic;
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
@ -11,7 +11,7 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
/// <summary>
/// Main constructor
/// </summary>
public CPC6128(AmstradCPC cpc, Z80A<AmstradCPC.CpuLink> cpu, List<byte[]> files, bool autoTape, AmstradCPC.BorderType borderType)
public CPC6128(AmstradCPC cpc, LibFz80Wrapper cpu, List<byte[]> files, bool autoTape, AmstradCPC.BorderType borderType)
{
CPC = cpc;
CPU = cpu;

View File

@ -1,5 +1,5 @@
using BizHawk.Common;
using BizHawk.Emulation.Cores.Components.Z80A;
//using BizHawk.Emulation.Cores.Components.Z80A;
namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
{
@ -14,10 +14,14 @@ namespace BizHawk.Emulation.Cores.Computers.AmstradCPC
/// </summary>
public AmstradCPC CPC { get; set; }
/*
/// <summary>
/// Reference to the instantiated Z80 cpu (piped in via constructor)
/// </summary>
public Z80A<AmstradCPC.CpuLink> CPU { get; set; }
*/
public LibFz80Wrapper CPU { get; set; }
/// <summary>
/// ROM and extended info