Update to v100r01 release.

[This version, with the internal version number changed back to "v100",
replaced the original v100 source archive on byuu.org soon after v100's
release, because it fixes important bugs in that version. --Ed]

byuu says:

Changelog:
- fixed default paths for Sufami Turbo slotted games
- moved WonderSwan orientation controls to the port rather than the device
  - I do like hex_usr's idea here; but that'll need more consideration;
    so this is a temporary fix
- added new debugger interface (see the public topic for more on that)
This commit is contained in:
Tim Allen 2016-07-08 22:23:46 +10:00
parent 07995c05a5
commit 88c79e56a0
17 changed files with 108 additions and 49 deletions

View File

@ -0,0 +1,13 @@
#pragma once
namespace Emulator {
#if defined(DEBUGGER)
#define debug(id, ...) if(debugger.id) debugger.id(__VA_ARGS__)
#define privileged public
#else
#define debug(id, ...)
#define privileged private
#endif
}

View File

@ -11,7 +11,7 @@ using namespace nall;
namespace Emulator {
static const string Name = "higan";
static const string Version = "100";
static const string Version = "100.01";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "http://byuu.org/";
@ -21,9 +21,4 @@ namespace Emulator {
}
#include "interface.hpp"
#if defined(DEBUGGER)
#define privileged public
#else
#define privileged private
#endif
#include "debugger.hpp"

View File

@ -53,7 +53,7 @@ auto V30MZ::opGroup3MemImm(Size size) {
auto mem = getMem(size);
switch(modrm.reg) {
case 0: alAnd(size, mem, fetch(size)); break;
case 1: debug("[V30MZ] GRP3.1"); break;
case 1: warning("[V30MZ] GRP3.1"); break;
case 2: wait(2); setMem(size, alNot(size, mem)); break;
case 3: wait(2); setMem(size, alNeg(size, mem)); break;
case 4: wait(2); setAcc(size * 2, alMul(size, getAcc(size), mem)); break;
@ -77,13 +77,13 @@ auto V30MZ::opGroup4MemImm(Size size) {
setMem(size, alDec(size, getMem(size)));
break;
case 2:
if(size == Byte) { debug("[V30MZ] GRP4.2"); break; }
if(size == Byte) { warning("[V30MZ] GRP4.2"); break; }
wait(5);
push(r.ip);
r.ip = getMem(Word);
break;
case 3:
if(size == Byte) { debug("[V30MZ] GRP4.3"); break; }
if(size == Byte) { warning("[V30MZ] GRP4.3"); break; }
wait(11);
push(r.cs);
push(r.ip);
@ -91,23 +91,23 @@ auto V30MZ::opGroup4MemImm(Size size) {
r.cs = getMem(Word, 2);
break;
case 4:
if(size == Byte) { debug("[V30MZ] GRP4.4"); break; }
if(size == Byte) { warning("[V30MZ] GRP4.4"); break; }
wait(4);
r.ip = getMem(Word);
break;
case 5:
if(size == Byte) { debug("[V30MZ] GRP4.5"); break; }
if(size == Byte) { warning("[V30MZ] GRP4.5"); break; }
wait(9);
r.ip = getMem(Word, 0);
r.cs = getMem(Word, 2);
break;
case 6:
if(size == Byte) { debug("[V30MZ] GRP4.6"); break; }
if(size == Byte) { warning("[V30MZ] GRP4.6"); break; }
wait(1);
push(getMem(Word));
break;
case 7:
debug("[V30MZ] GRP4.7");
warning("[V30MZ] GRP4.7");
break;
}
}

View File

@ -18,7 +18,7 @@ namespace Processor {
#include "serialization.cpp"
#include "disassembler.cpp"
auto V30MZ::debug(string text) -> void {
auto V30MZ::warning(string text) -> void {
//print(text, "\n");
}

View File

@ -23,7 +23,7 @@ struct V30MZ {
virtual auto in(uint16 port) -> uint8 = 0;
virtual auto out(uint16 port, uint8 data) -> void = 0;
auto debug(string text) -> void;
auto warning(string text) -> void;
auto power() -> void;
auto exec() -> void;
auto interrupt(uint8 vector) -> void;

View File

@ -10,7 +10,7 @@ auto Cartridge::loadCartridge(Markup::Node node) -> void {
}
}
if(board["sufamiturbo"]) {
if(auto pathID = interface->load(ID::SufamiTurboA, "Sufami Turbo - Slot A", "st")) {
if(auto pathID = interface->load(ID::SufamiTurboA, "Sufami Turbo", "st")) {
sufamiturboA.pathID = pathID();
loadSufamiTurboA();
}
@ -55,7 +55,7 @@ auto Cartridge::loadSufamiTurboA(Markup::Node node) -> void {
loadMemory(sufamiturboA.ram, node["board/ram"], File::Optional, sufamiturboA.pathID);
if(node["board/linkable"]) {
if(auto pathID = interface->load(ID::SufamiTurboB, "Sufami Turbo - Slot B", "st")) {
if(auto pathID = interface->load(ID::SufamiTurboB, "Sufami Turbo", "st")) {
sufamiturboB.pathID = pathID();
loadSufamiTurboB();
}

View File

@ -50,10 +50,12 @@ auto CPU::main() -> void {
status.nmiPending = false;
r.vector = r.e ? 0xfffa : 0xffea;
interrupt();
debug(cpu.nmi);
} else if(status.irqPending) {
status.irqPending = false;
r.vector = r.e ? 0xfffe : 0xffee;
interrupt();
debug(cpu.irq);
} else if(status.resetPending) {
status.resetPending = false;
step(132);
@ -67,6 +69,7 @@ auto CPU::main() -> void {
}
}
debug(cpu.execute, r.pc);
instruction();
}

View File

@ -20,6 +20,7 @@ auto CPU::read(uint24 addr) -> uint8 {
r.mdr = bus.read(addr, r.mdr);
step(4);
aluEdge();
debug(cpu.read, addr, r.mdr);
return r.mdr;
}
@ -29,6 +30,7 @@ auto CPU::write(uint24 addr, uint8 data) -> void {
dmaEdge();
step(status.clockCount);
bus.write(addr, r.mdr = data);
debug(cpu.write, addr, r.mdr);
}
auto CPU::speed(uint24 addr) const -> uint {

40
higan/sfc/debugger.hpp Normal file
View File

@ -0,0 +1,40 @@
#pragma once
namespace SuperFamicom {
struct Debugger {
struct CPU {
function<void (uint24, uint8)> read;
function<void (uint24, uint8)> write;
function<void (uint24)> execute;
function<void ()> nmi;
function<void ()> irq;
} cpu;
struct SMP {
function<void (uint16, uint8)> read;
function<void (uint16, uint8)> write;
function<void (uint16)> execute;
} smp;
struct PPU {
struct VRAM {
function<void (uint17, uint8)> read;
function<void (uint17, uint8)> write;
} vram;
struct OAM {
function<void (uint10, uint8)> read;
function<void (uint10, uint8)> write;
} oam;
struct CGRAM {
function<void (uint9, uint8)> read;
function<void (uint9, uint8)> write;
} cgram;
} ppu;
};
extern Debugger debugger;
}

View File

@ -4,6 +4,7 @@ namespace SuperFamicom {
Interface* interface = nullptr;
Settings settings;
Debugger debugger;
Interface::Interface() {
interface = this;

View File

@ -1,3 +1,5 @@
#include <sfc/debugger.hpp>
namespace SuperFamicom {
struct ID {

View File

@ -11,22 +11,31 @@ auto PPU::addressVRAM() const -> uint16 {
auto PPU::readVRAM() -> uint16 {
if(!io.displayDisable && vcounter() < vdisp()) return 0x0000;
return vram[addressVRAM()];
auto addr = addressVRAM();
auto data = vram[addr];
debug(ppu.vram.read, addr << 1 | 0, data.byte(0));
debug(ppu.vram.read, addr << 1 | 1, data.byte(1));
return data;
}
auto PPU::writeVRAM(bool byte, uint8 data) -> void {
if(!io.displayDisable && vcounter() < vdisp()) return;
vram[addressVRAM()].byte(byte) = data;
auto addr = addressVRAM();
vram[addr].byte(byte) = data;
debug(ppu.vram.write, addr << 1 | byte, data);
}
auto PPU::readOAM(uint10 addr) -> uint8 {
if(!io.displayDisable && vcounter() < vdisp()) addr = latch.oamAddress;
return obj.oam.read(addr);
auto data = obj.oam.read(addr);
debug(ppu.oam.read, addr, data);
return data;
}
auto PPU::writeOAM(uint10 addr, uint8 data) -> void {
if(!io.displayDisable && vcounter() < vdisp()) addr = latch.oamAddress;
obj.oam.write(addr, data);
debug(ppu.oam.write, addr, data);
}
auto PPU::readCGRAM(bool byte, uint8 addr) -> uint8 {
@ -34,7 +43,9 @@ auto PPU::readCGRAM(bool byte, uint8 addr) -> uint8 {
&& vcounter() > 0 && vcounter() < vdisp()
&& hcounter() >= 88 && hcounter() < 1096
) addr = latch.cgramAddress;
return screen.cgram[addr].byte(byte);
auto data = screen.cgram[addr].byte(byte);
debug(ppu.cgram.read, addr << 1 | byte, data);
return data;
}
auto PPU::writeCGRAM(uint8 addr, uint15 data) -> void {
@ -43,6 +54,8 @@ auto PPU::writeCGRAM(uint8 addr, uint15 data) -> void {
&& hcounter() >= 88 && hcounter() < 1096
) addr = latch.cgramAddress;
screen.cgram[addr] = data;
debug(ppu.cgram.write, addr << 1 | 0, data.byte(0));
debug(ppu.cgram.write, addr << 1 | 1, data.byte(1));
}
auto PPU::readIO(uint24 addr, uint8 data) -> uint8 {

View File

@ -183,6 +183,7 @@ auto SMP::read(uint16 addr) -> uint8 {
uint8 data = readBus(addr);
step(12);
cycleEdge();
debug(smp.read, addr, data);
return data;
}
@ -190,6 +191,7 @@ auto SMP::write(uint16 addr, uint8 data) -> void {
step(24);
writeBus(addr, data);
cycleEdge();
debug(smp.write, addr, data);
}
auto SMP::readDisassembler(uint16 addr) -> uint8 {

View File

@ -21,6 +21,7 @@ auto SMP::Enter() -> void {
}
auto SMP::main() -> void {
debug(smp.execute, regs.pc);
instruction();
}

View File

@ -22,9 +22,10 @@ Interface::Interface() {
media.append({ID::WonderSwan, "WonderSwan", "ws" });
media.append({ID::WonderSwanColor, "WonderSwan Color", "wsc"});
Port hardwarePort{ID::Port::Hardware, "Hardware"};
Port hardwareHorizontalPort{ID::Port::HardwareHorizontal, "Hardware - Horizontal"};
Port hardwareVerticalPort{ID::Port::HardwareVertical, "Hardware - Vertical"};
{ Device device{ID::Device::HorizontalControls, "Horizontal Controls"};
{ Device device{ID::Device::Controls, "Controls"};
device.inputs.append({0, "Y1"});
device.inputs.append({0, "Y2"});
device.inputs.append({0, "Y3"});
@ -37,26 +38,12 @@ Interface::Interface() {
device.inputs.append({0, "A"});
device.inputs.append({0, "Start"});
device.inputs.append({0, "Rotate"});
hardwarePort.devices.append(device);
hardwareHorizontalPort.devices.append(device);
hardwareVerticalPort.devices.append(device);
}
{ Device device{ID::Device::VerticalControls, "Vertical Controls"};
device.inputs.append({0, "Y1"});
device.inputs.append({0, "Y2"});
device.inputs.append({0, "Y3"});
device.inputs.append({0, "Y4"});
device.inputs.append({0, "X1"});
device.inputs.append({0, "X2"});
device.inputs.append({0, "X3"});
device.inputs.append({0, "X4"});
device.inputs.append({0, "B"});
device.inputs.append({0, "A"});
device.inputs.append({0, "Start"});
device.inputs.append({0, "Rotate"});
hardwarePort.devices.append(device);
}
ports.append(move(hardwarePort));
ports.append(move(hardwareHorizontalPort));
ports.append(move(hardwareVerticalPort));
}
auto Interface::manifest() -> string {

View File

@ -7,13 +7,13 @@ struct ID {
WonderSwanColor,
};
struct Device { enum : uint {
HorizontalControls,
VerticalControls,
struct Port { enum : uint {
HardwareHorizontal,
HardwareVertical,
};};
struct Port { enum : uint {
Hardware,
struct Device { enum : uint {
Controls,
};};
};

View File

@ -98,8 +98,8 @@ auto System::runToSave() -> void {
}
auto System::pollKeypad() -> void {
uint port = ID::Port::Hardware;
uint device = !_orientation ? ID::Device::HorizontalControls : ID::Device::VerticalControls;
uint port = !_orientation ? ID::Port::HardwareHorizontal : ID::Port::HardwareVertical;
uint device = ID::Device::Controls;
bool rotate = keypad.rotate;
keypad.y1 = interface->inputPoll(port, device, 0);