Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Super Famicom, Super Game Boy, Game Boy, Game Boy Color, Game Boy Advance,
Game Boy Player, SG-1000, SC-3000, Master System, Game Gear, Mega Drive,
Mega CD, PC Engine, SuperGrafx, MSX, MSX2, ColecoVision, Neo Geo Pocket,
Neo Geo Pocket Color, WonderSwan, WonderSwan Color, SwanCrystal,
Pocket Challenge V2.
Pocket Challenge V2, ZX Spectrum 48k, ZX Spectrum 128.

Links
-----
Expand Down
2 changes: 1 addition & 1 deletion higan-ui/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ hiro.resource := resource/higan-ui.rc
include $(hiro.path)/GNUmakefile

profile := accuracy
cores := fc sfc n64 sg ms md ps1 pce msx cv gb gba ws ngp
cores := fc sfc n64 sg ms md ps1 pce msx cv gb gba ws ngp spec

higan.path := ../higan
include $(higan.path)/GNUmakefile
Expand Down
6 changes: 6 additions & 0 deletions higan-ui/higan-ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Input inputInstance;
#include <sfc/interface/interface.hpp>
#include <sg/interface/interface.hpp>
#include <ws/interface/interface.hpp>
#include <spec/interface/interface.hpp>

#include <nall/main.hpp>
auto nall::main(Arguments arguments) -> void {
Expand Down Expand Up @@ -159,6 +160,11 @@ auto nall::main(Arguments arguments) -> void {
interfaces.append(new higan::WonderSwan::WonderSwanColorInterface);
#endif

#ifdef CORE_SPEC
interfaces.append(new higan::Spectrum::Spectrum48kInterface);
interfaces.append(new higan::Spectrum::Spectrum128Interface);
#endif

higan::platform = &emulator;

Instances::program.construct();
Expand Down
4 changes: 4 additions & 0 deletions higan/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ ifneq ($(filter $(cores),ngp),)
include $(higan.path)/ngp/GNUmakefile
endif

ifneq ($(filter $(cores),spec),)
include $(higan.path)/spec/GNUmakefile
endif

include $(higan.path)/component/GNUmakefile

flags += $(foreach c,$(call strupper,$(cores)),-DCORE_$c)
Expand Down
Empty file.
Empty file.
Empty file.
43 changes: 43 additions & 0 deletions higan/System/ZX Spectrum 128/Keyboard/Original/layout.bml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
layout
name: Original

key: 1
key: 2
key: 3
key: 4
key: 5
key: 6
key: 7
key: 8
key: 9
key: 0
key: Q
key: W
key: E
key: R
key: T
key: Y
key: U
key: I
key: O
key: P
key: A
key: S
key: D
key: F
key: G
key: H
key: J
key: K
key: L
key: Z
key: X
key: C
key: V
key: B
key: N
key: M
key: ENTER
key: SPACE BREAK
key: CAPS SHIFT
key: SYMBOL SHIFT
Binary file added higan/System/ZX Spectrum 128/bios.rom
Binary file not shown.
Binary file added higan/System/ZX Spectrum 128/sub.rom
Binary file not shown.
Empty file.
Empty file.
Empty file.
43 changes: 43 additions & 0 deletions higan/System/ZX Spectrum 48k/Keyboard/Original/layout.bml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
layout
name: Original

key: 1
key: 2
key: 3
key: 4
key: 5
key: 6
key: 7
key: 8
key: 9
key: 0
key: Q
key: W
key: E
key: R
key: T
key: Y
key: U
key: I
key: O
key: P
key: A
key: S
key: D
key: F
key: G
key: H
key: J
key: K
key: L
key: Z
key: X
key: C
key: V
key: B
key: N
key: M
key: ENTER
key: SPACE BREAK
key: CAPS SHIFT
key: SYMBOL SHIFT
Binary file added higan/System/ZX Spectrum 48k/bios.rom
Binary file not shown.
14 changes: 14 additions & 0 deletions higan/spec/GNUmakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
higan.components += z80

higan.objects += higan-spec-interface higan-spec-keyboard higan-spec-expansion higan-spec-system
higan.objects += higan-spec-cpu higan-spec-ula higan-spec-psg
higan.objects += higan-spec-tape

$(object.path)/higan-spec-interface.o: $(higan.path)/spec/interface/interface.cpp
$(object.path)/higan-spec-keyboard.o: $(higan.path)/spec/keyboard/keyboard.cpp
$(object.path)/higan-spec-expansion.o: $(higan.path)/spec/expansion/expansion.cpp
$(object.path)/higan-spec-system.o: $(higan.path)/spec/system/system.cpp
$(object.path)/higan-spec-cpu.o: $(higan.path)/spec/cpu/cpu.cpp
$(object.path)/higan-spec-ula.o: $(higan.path)/spec/ula/ula.cpp
$(object.path)/higan-spec-psg.o: $(higan.path)/spec/psg/psg.cpp
$(object.path)/higan-spec-tape.o: $(higan.path)/spec/tape/tape.cpp
55 changes: 55 additions & 0 deletions higan/spec/cpu/cpu.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <spec/spec.hpp>

namespace higan::Spectrum {

CPU cpu;
#include "memory.cpp"
#include "debugger.cpp"
#include "serialization.cpp"

auto CPU::load(Node::Object parent) -> void {
if(Model::Spectrum48k()) ram.allocate(48_KiB);
if(Model::Spectrum128()) ram.allocate(128_KiB);

ram.fill(0x00);
node = parent->append<Node::Component>("CPU");

debugger.load(node);
}

auto CPU::unload() -> void {
ram.reset();
node = {};
debugger = {};
}

auto CPU::main() -> void {
if(irqLine) {
debugger.interrupt("IRQ");
irq(1, 0x0038, 0xff);
}

debugger.instruction();
instruction();
}

auto CPU::step(uint clocks) -> void {
Thread::step(clocks);
Thread::synchronize();
}

auto CPU::power() -> void {
Z80::bus = this;
Z80::power();
Thread::create(system.frequency(), {&CPU::main, this});

r.pc = 0x0000; //reset vector address

irqLine = false;
}

auto CPU::setIrq(bool line) -> void {
irqLine = line;
}

}
49 changes: 49 additions & 0 deletions higan/spec/cpu/cpu.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
struct CPU : Z80, Z80::Bus, Thread {
Node::Component node;
Memory::Writable<uint8> ram;

struct Debugger {
//debugger.cpp
auto load(Node::Object) -> void;
auto instruction() -> void;
auto interrupt(string_view) -> void;

struct Memory {
Node::Memory ram;
} memory;

struct Tracer {
Node::Instruction instruction;
Node::Notification interrupt;
} tracer;
} debugger;

auto synchronizing() const -> bool override { return scheduler.synchronizing(); }

//cpu.cpp
auto load(Node::Object) -> void;
auto unload() -> void;

auto main() -> void;
auto step(uint clocks) -> void override;

auto power() -> void;
auto setIrq(bool line) -> void;

//memory.cpp
auto read(uint16 address) -> uint8 override;
auto write(uint16 address, uint8 data) -> void override;
auto readBanked(uint3 bank, uint16 address) -> uint8;
auto writeBanked(uint3 bank, uint16 address, uint8 data) -> void;

auto in(uint16 address) -> uint8 override;
auto out(uint16 address, uint8 data) -> void override;

//serialization.cpp
auto serialize(serializer&) -> void;

private:
uint1 irqLine;
};

extern CPU cpu;
27 changes: 27 additions & 0 deletions higan/spec/cpu/debugger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
auto CPU::Debugger::load(Node::Object parent) -> void {
memory.ram = parent->append<Node::Memory>("CPU RAM");
memory.ram->setSize(cpu.ram.size());
memory.ram->setRead([&](uint32 address) -> uint8 {
return cpu.ram[address];
});
memory.ram->setWrite([&](uint32 address, uint8 data) -> void {
cpu.ram[address] = data;
});

tracer.instruction = parent->append<Node::Instruction>("Instruction", "CPU");
tracer.instruction->setAddressBits(16);

tracer.interrupt = parent->append<Node::Notification>("Interrupt", "CPU");
}

auto CPU::Debugger::instruction() -> void {
if(tracer.instruction->enabled() && tracer.instruction->address(cpu.r.pc)) {
tracer.instruction->notify(cpu.disassembleInstruction(), cpu.disassembleContext());
}
}

auto CPU::Debugger::interrupt(string_view type) -> void {
if(tracer.interrupt->enabled()) {
tracer.interrupt->notify(type);
}
}
Loading