Put in SIO2 data fifo.

This commit is contained in:
Marco Satti 2018-01-07 15:12:25 +08:00
parent 33b3ebb6bd
commit 280fb1669a
12 changed files with 165 additions and 67 deletions

View file

@ -66,6 +66,7 @@ set(COMMON_SRC_FILES
src/Resources/Iop/Dmac/RIopDmac.cpp
src/Resources/Iop/Intc/IopIntcRegisters.cpp
src/Resources/Iop/RIop.cpp
src/Resources/Iop/Sio2/RSio2.cpp
src/Resources/Iop/Sio2/Sio2Registers.cpp
src/Resources/Iop/Timers/IopTimersUnitRegisters.cpp
src/Resources/Iop/Timers/IopTimersUnits.cpp

View file

@ -44,6 +44,16 @@ struct Bitfield
return cleaned_value | cleaned_field_value;
}
constexpr bool operator==(const Bitfield & rhs) const
{
return (start == rhs.start) && (length == rhs.length);
}
constexpr bool operator!=(const Bitfield & rhs) const
{
return !operator==(rhs);
}
const int start;
const int length;
};

View file

@ -79,7 +79,7 @@ int CCrtc::time_step(const int ticks_available) const
// Send VBlank end.
r.ee.intc.stat.insert_field(EeIntcRegister_Stat::VBOF, 1);
r.iop.intc.stat.insert_field(IopIntcRegister_Stat::EVBLANK, 1);
BOOST_LOG(Core::get_logger()) << "EVBLANK fired!";
//BOOST_LOG(Core::get_logger()) << "EVBLANK fired!";
}
row++;
@ -91,7 +91,7 @@ int CCrtc::time_step(const int ticks_available) const
// Send VBlank start.
r.ee.intc.stat.insert_field(EeIntcRegister_Stat::VBON, 1);
r.iop.intc.stat.insert_field(IopIntcRegister_Stat::VBLANK, 1);
BOOST_LOG(Core::get_logger()) << "VBLANK fired!";
//BOOST_LOG(Core::get_logger()) << "VBLANK fired!";
// Tell core to render frame.
// core->render_frame();

View file

@ -1,3 +1,5 @@
#include <utility>
#include <algorithm>
#include <boost/format.hpp>
#include "Core.hpp"
@ -154,8 +156,18 @@ void CIopCoreInterpreter::debug_print_interrupt_info() const
// Check the INTC.
for (auto& irq_field : IopIntcRegister_Stat::IRQ_KEYS)
{
const Bitfield DEBUG_LOG_INTC_FILTER[] =
{
IopIntcRegister_Stat::VBLANK,
IopIntcRegister_Stat::EVBLANK
};
if (std::end(DEBUG_LOG_INTC_FILTER) != std::find(std::begin(DEBUG_LOG_INTC_FILTER), std::end(DEBUG_LOG_INTC_FILTER), irq_field))
continue;
if (stat.extract_field(irq_field) & mask.extract_field(irq_field))
{
BOOST_LOG(Core::get_logger()) << boost::format("INTC source %d") % irq_field.start;
}
}
// Print DMAC sources if it was a source.
@ -317,16 +329,23 @@ bool CIopCoreInterpreter::translate_vaddress(const uptr virtual_address, const M
auto& cop0 = r.iop.core.cop0;
#if defined(BUILD_DEBUG)
static uword DEBUG_VA_BREAKPOINT_LO = 0xFFFFFFFF;
static uword DEBUG_VA_BREAKPOINT_HI = 0xFFFFFFFF;
if (virtual_address >= DEBUG_VA_BREAKPOINT_LO && virtual_address <= DEBUG_VA_BREAKPOINT_HI)
static const std::pair<uword, uword> DEBUG_VA_BREAKPOINT_RANGES[] =
{
BOOST_LOG(Core::get_logger()) <<
boost::format("IOP MMU breakpoint hit @ cycle = 0x%llX, PC = 0x%08X, VA = 0x%08X (%s).")
% DEBUG_LOOP_COUNTER
% r.iop.core.r3000.pc.read_uword()
% virtual_address
% ((access == READ) ? "READ" : "WRITE");
std::make_pair(0xBF801040, 0xBF801050),
std::make_pair(0xBF808200, 0xBF808300)
};
for (const auto& range : DEBUG_VA_BREAKPOINT_RANGES)
{
if (virtual_address >= range.first && virtual_address <= range.second)
{
BOOST_LOG(Core::get_logger()) <<
boost::format("IOP MMU breakpoint hit @ cycle = 0x%llX, PC = 0x%08X, VA = 0x%08X (%s).")
% DEBUG_LOOP_COUNTER
% r.iop.core.r3000.pc.read_uword()
% virtual_address
% ((access == READ) ? "READ" : "WRITE");
}
}
#endif

View file

@ -1,3 +1,4 @@
#include <boost/format.hpp>
#include "Core.hpp"
#include "Controller/Iop/Sio2/CSio2.hpp"
@ -47,26 +48,37 @@ int CSio2::time_to_ticks(const double time_us) const
int CSio2::time_step(const int ticks_available) const
{
auto& r = core->get_resources();
auto& ctrl = r.iop.sio2.ctrl;
auto& intc_stat = r.iop.intc.stat;
auto _ctrl_lock = r.iop.sio2.ctrl.scope_lock();
auto _ctrl_lock = ctrl.scope_lock();
if (r.iop.sio2.ctrl.write_latch)
if (ctrl.write_latch)
{
/*
if (r.iop.sio2.ctrl.extract_field(SIO2Register_CTRL_t::Reset) > 0)
if (ctrl.extract_field(Sio2Register_Ctrl::RESET_DIR) > 0)
{
// Receive packet (?).
// Receive packet. Value should be 0x3BD.
if (ctrl.read_uword() != 0x3BD)
BOOST_LOG(Core::get_logger()) <<
boost::format("Careful, SIO2 ctrl recv value not normal: 0x%08X")
% ctrl.read_uword();
// Raise IOP IRQ.
//r.iop.intc.stat.insert_field(IopIntcRegister_Stat::SIO2, 1);
intc_stat.insert_field(IopIntcRegister_Stat::SIO2, 1);
// Clear the direction bit (no idea why... seems to be required).
ctrl.insert_field(Sio2Register_Ctrl::RESET_DIR, 0);
}
else
{
// Send packet (?).
// Send packet. Value should be 0x3BC.
if (ctrl.read_uword() != 0x3BC)
BOOST_LOG(Core::get_logger()) <<
boost::format("Careful, SIO2 ctrl send value not normal: 0x%08X")
% ctrl.read_uword();
}
*/
r.iop.sio2.ctrl.write_latch = false;
ctrl.write_latch = false;
}
return 1;

View file

@ -1,8 +1,8 @@
#include "Resources/Iop/Dmac/RIopDmac.hpp"
RIopDmac::RIopDmac() :
channel_frommdec(0),
channel_tomdec(1),
channel_tomdec(0),
channel_frommdec(1),
channel_sif2(2),
channel_cdvd(3),
channel_spu2c0(4),
@ -12,7 +12,7 @@ RIopDmac::RIopDmac() :
channel_dev9(8),
channel_sif0(9),
channel_sif1(10),
channel_fromsio2(11),
channel_tosio2(12)
channel_tosio2(11),
channel_fromsio2(12)
{
}

View file

@ -23,8 +23,8 @@ struct RIopDmac
SizedWordRegister gctrl;
/// DMAC Channels.
IopDmacChannel_Base<IopDmacChannelRegister_Chcr> channel_frommdec; // CH 0
IopDmacChannel_Base<IopDmacChannelRegister_Chcr> channel_tomdec; // CH 1
IopDmacChannel_Base<IopDmacChannelRegister_Chcr> channel_tomdec; // CH 0
IopDmacChannel_Base<IopDmacChannelRegister_Chcr> channel_frommdec; // CH 1
IopDmacChannel_Base<IopDmacChannelRegister_Chcr_Sif2> channel_sif2; // CH 2 bidirectional w/ EE
IopDmacChannel_Base<IopDmacChannelRegister_Chcr> channel_cdvd; // CH 3
IopDmacChannel_Tadr<IopDmacChannelRegister_Chcr> channel_spu2c0; // CH 4
@ -34,8 +34,8 @@ struct RIopDmac
IopDmacChannel_Base<IopDmacChannelRegister_Chcr> channel_dev9; // CH 8
IopDmacChannel_Tadr<IopDmacChannelRegister_Chcr_Sif0> channel_sif0; // CH 9 to EE
IopDmacChannel_Base<IopDmacChannelRegister_Chcr_Sif1> channel_sif1; // CH 10 from EE
IopDmacChannel_Base<IopDmacChannelRegister_Chcr> channel_fromsio2; // CH 11
IopDmacChannel_Base<IopDmacChannelRegister_Chcr> channel_tosio2; // CH 12
IopDmacChannel_Base<IopDmacChannelRegister_Chcr> channel_tosio2; // CH 11
IopDmacChannel_Base<IopDmacChannelRegister_Chcr> channel_fromsio2; // CH 12
/// IOP DMA channel abstrations.
/// There are 14 channels in total (to make it even), with the last one being undefined.

View file

@ -0,0 +1,6 @@
#include "Resources/Iop/Sio2/RSio2.hpp"
RSio2::RSio2() :
recv2(0xF, true)
{
}

View file

@ -1,5 +1,6 @@
#pragma once
#include "Common/Types/FifoQueue/DmaFifoQueue.hpp"
#include "Common/Types/Register/SizedWordRegister.hpp"
#include "Resources/Iop/Sio2/Sio2Registers.hpp"
@ -10,6 +11,10 @@
/// A lot of information can be found through the PS2SDK too: https://github.com/ps2dev/ps2sdk/tree/master/iop/system/sio2log/src.
struct RSio2
{
RSio2();
DmaFifoQueue<> data_fifo; // Fifo queue used for sending and receiving data (can change direction).
SizedWordRegister port0_ctrl3; // TODO: figure out these names properly.
SizedWordRegister port1_ctrl3;
SizedWordRegister port2_ctrl3;
@ -35,11 +40,11 @@ struct RSio2
SizedWordRegister port2_ctrl2;
SizedWordRegister port3_ctrl1;
SizedWordRegister port3_ctrl2;
SizedWordRegister data_out;
SizedWordRegister data_in;
Sio2Register_Data data_in;
Sio2Register_Data data_out;
Sio2Register_Ctrl ctrl;
SizedWordRegister recv1;
SizedWordRegister recv2;
SizedWordRegister recv2; // Constant 0xF value.
SizedWordRegister recv3;
SizedWordRegister register_8278;
SizedWordRegister register_827c;

View file

@ -17,4 +17,24 @@ void Sio2Register_Ctrl::byte_bus_write_uword(const BusContext context, const usi
write_uword(value);
write_latch = true;
}
}
Sio2Register_Data::Sio2Register_Data() :
data_fifo(nullptr)
{
}
void Sio2Register_Data::initialise()
{
data_fifo->initialise();
}
ubyte Sio2Register_Data::read_ubyte()
{
return data_fifo->read_ubyte();
}
void Sio2Register_Data::write_ubyte(const ubyte value)
{
data_fifo->write_ubyte(value);
}

View file

@ -1,14 +1,15 @@
#pragma once
#include "Common/Types/ScopeLock.hpp"
#include "Common/Types/FifoQueue/DmaFifoQueue.hpp"
#include "Common/Types/Register/SizedWordRegister.hpp"
#include "Common/Types/Register/ByteRegister.hpp"
/// SIO2 CTRL Register.
///
/// TODO: notes so far:
/// Bit 0 is a reset SIO2 or SIO flag in TX/RX direction (?). Cleared once reset complete???
/// PCSX2 probably not proper - doesn't seem right that things like this exist: "sio2.ctrl &= ~1;"
/// Fuck it, its magic.
/// RESET_DIR is a reset SIO2 or SIO flag in TX/RX direction (?).
/// This seems like a bit of magic to me, no documentation really.
/// Looking into the bios, it changes between OR'ing 0xC or 0x1 with 0x3BC, which works with what PCSX2 says.
/// (ie: 0xC OR'd has no effect, 0x1 OR'd makes it 0x3BD.)
class Sio2Register_Ctrl : public SizedWordRegister, public ScopeLock
{
public:
@ -24,3 +25,20 @@ public:
/// Set to true on write, cleared by the system logic when the command has been processed.
bool write_latch;
};
/// Data fifo port register.
/// Used as an interface by the SIO2 to transmit data.
class Sio2Register_Data : public ByteRegister
{
public:
Sio2Register_Data();
void initialise() override;
/// Reads and writes to the data fifo queue.
ubyte read_ubyte() override;
void write_ubyte(const ubyte value) override;
/// Reference to the data fifo queue.
DmaFifoQueue<> * data_fifo;
};

View file

@ -232,14 +232,14 @@ void initialise_iop_dmac(RResources * r)
r->iop.dmac.channel_sif2.chcr.sbus_f240 = &r->sbus_f240;
// Init channel abstrations.
r->iop.dmac.channels[0].channel_id = &r->iop.dmac.channel_frommdec.channel_id;
r->iop.dmac.channels[0].madr = &r->iop.dmac.channel_frommdec.madr;
r->iop.dmac.channels[0].bcr = &r->iop.dmac.channel_frommdec.bcr;
r->iop.dmac.channels[0].chcr = &r->iop.dmac.channel_frommdec.chcr;
r->iop.dmac.channels[1].channel_id = &r->iop.dmac.channel_tomdec.channel_id;
r->iop.dmac.channels[1].madr = &r->iop.dmac.channel_tomdec.madr;
r->iop.dmac.channels[1].bcr = &r->iop.dmac.channel_tomdec.bcr;
r->iop.dmac.channels[1].chcr = &r->iop.dmac.channel_tomdec.chcr;
r->iop.dmac.channels[0].channel_id = &r->iop.dmac.channel_tomdec.channel_id;
r->iop.dmac.channels[0].madr = &r->iop.dmac.channel_tomdec.madr;
r->iop.dmac.channels[0].bcr = &r->iop.dmac.channel_tomdec.bcr;
r->iop.dmac.channels[0].chcr = &r->iop.dmac.channel_tomdec.chcr;
r->iop.dmac.channels[1].channel_id = &r->iop.dmac.channel_frommdec.channel_id;
r->iop.dmac.channels[1].madr = &r->iop.dmac.channel_frommdec.madr;
r->iop.dmac.channels[1].bcr = &r->iop.dmac.channel_frommdec.bcr;
r->iop.dmac.channels[1].chcr = &r->iop.dmac.channel_frommdec.chcr;
r->iop.dmac.channels[2].channel_id = &r->iop.dmac.channel_sif2.channel_id;
r->iop.dmac.channels[2].madr = &r->iop.dmac.channel_sif2.madr;
r->iop.dmac.channels[2].bcr = &r->iop.dmac.channel_sif2.bcr;
@ -278,14 +278,14 @@ void initialise_iop_dmac(RResources * r)
r->iop.dmac.channels[10].madr = &r->iop.dmac.channel_sif1.madr;
r->iop.dmac.channels[10].bcr = &r->iop.dmac.channel_sif1.bcr;
r->iop.dmac.channels[10].chcr = &r->iop.dmac.channel_sif1.chcr;
r->iop.dmac.channels[11].channel_id = &r->iop.dmac.channel_fromsio2.channel_id;
r->iop.dmac.channels[11].madr = &r->iop.dmac.channel_fromsio2.madr;
r->iop.dmac.channels[11].bcr = &r->iop.dmac.channel_fromsio2.bcr;
r->iop.dmac.channels[11].chcr = &r->iop.dmac.channel_fromsio2.chcr;
r->iop.dmac.channels[12].channel_id = &r->iop.dmac.channel_tosio2.channel_id;
r->iop.dmac.channels[12].madr = &r->iop.dmac.channel_tosio2.madr;
r->iop.dmac.channels[12].bcr = &r->iop.dmac.channel_tosio2.bcr;
r->iop.dmac.channels[12].chcr = &r->iop.dmac.channel_tosio2.chcr;
r->iop.dmac.channels[11].channel_id = &r->iop.dmac.channel_tosio2.channel_id;
r->iop.dmac.channels[11].madr = &r->iop.dmac.channel_tosio2.madr;
r->iop.dmac.channels[11].bcr = &r->iop.dmac.channel_tosio2.bcr;
r->iop.dmac.channels[11].chcr = &r->iop.dmac.channel_tosio2.chcr;
r->iop.dmac.channels[12].channel_id = &r->iop.dmac.channel_fromsio2.channel_id;
r->iop.dmac.channels[12].madr = &r->iop.dmac.channel_fromsio2.madr;
r->iop.dmac.channels[12].bcr = &r->iop.dmac.channel_fromsio2.bcr;
r->iop.dmac.channels[12].chcr = &r->iop.dmac.channel_fromsio2.chcr;
// Init DMA FIFO queues.
r->iop.dmac.channels[0].dma_fifo_queue = &r->fifo_frommdec;
@ -612,12 +612,12 @@ void initialise_iop(RResources * r)
r->iop.bus.map(0x1F802070, &r->iop.register_2070);
// DMAC Registers.
r->iop.bus.map(0x1F801080, &r->iop.dmac.channel_frommdec.madr);
r->iop.bus.map(0x1F801084, &r->iop.dmac.channel_frommdec.bcr);
r->iop.bus.map(0x1F801088, &r->iop.dmac.channel_frommdec.chcr);
r->iop.bus.map(0x1F801090, &r->iop.dmac.channel_tomdec.madr);
r->iop.bus.map(0x1F801094, &r->iop.dmac.channel_tomdec.bcr);
r->iop.bus.map(0x1F801098, &r->iop.dmac.channel_tomdec.chcr);
r->iop.bus.map(0x1F801080, &r->iop.dmac.channel_tomdec.madr);
r->iop.bus.map(0x1F801084, &r->iop.dmac.channel_tomdec.bcr);
r->iop.bus.map(0x1F801088, &r->iop.dmac.channel_tomdec.chcr);
r->iop.bus.map(0x1F801090, &r->iop.dmac.channel_frommdec.madr);
r->iop.bus.map(0x1F801094, &r->iop.dmac.channel_frommdec.bcr);
r->iop.bus.map(0x1F801098, &r->iop.dmac.channel_frommdec.chcr);
r->iop.bus.map(0x1F8010A0, &r->iop.dmac.channel_sif2.madr);
r->iop.bus.map(0x1F8010A4, &r->iop.dmac.channel_sif2.bcr);
r->iop.bus.map(0x1F8010A8, &r->iop.dmac.channel_sif2.chcr);
@ -647,12 +647,12 @@ void initialise_iop(RResources * r)
r->iop.bus.map(0x1F801530, &r->iop.dmac.channel_sif1.madr);
r->iop.bus.map(0x1F801534, &r->iop.dmac.channel_sif1.bcr);
r->iop.bus.map(0x1F801538, &r->iop.dmac.channel_sif1.chcr);
r->iop.bus.map(0x1F801540, &r->iop.dmac.channel_fromsio2.madr);
r->iop.bus.map(0x1F801544, &r->iop.dmac.channel_fromsio2.bcr);
r->iop.bus.map(0x1F801548, &r->iop.dmac.channel_fromsio2.chcr);
r->iop.bus.map(0x1F801550, &r->iop.dmac.channel_tosio2.madr);
r->iop.bus.map(0x1F801554, &r->iop.dmac.channel_tosio2.bcr);
r->iop.bus.map(0x1F801558, &r->iop.dmac.channel_tosio2.chcr);
r->iop.bus.map(0x1F801540, &r->iop.dmac.channel_tosio2.madr);
r->iop.bus.map(0x1F801544, &r->iop.dmac.channel_tosio2.bcr);
r->iop.bus.map(0x1F801548, &r->iop.dmac.channel_tosio2.chcr);
r->iop.bus.map(0x1F801550, &r->iop.dmac.channel_fromsio2.madr);
r->iop.bus.map(0x1F801554, &r->iop.dmac.channel_fromsio2.bcr);
r->iop.bus.map(0x1F801558, &r->iop.dmac.channel_fromsio2.chcr);
r->iop.bus.map(0x1F8010F0, &r->iop.dmac.pcr0);
r->iop.bus.map(0x1F8010F4, &r->iop.dmac.icr0);
r->iop.bus.map(0x1F801570, &r->iop.dmac.pcr1);
@ -1632,8 +1632,8 @@ void initialise_iop(RResources * r)
r->iop.bus.map(0x1F808254, &r->iop.sio2.port2_ctrl2);
r->iop.bus.map(0x1F808258, &r->iop.sio2.port3_ctrl1);
r->iop.bus.map(0x1F80825C, &r->iop.sio2.port3_ctrl2);
r->iop.bus.map(0x1F808260, &r->iop.sio2.data_out);
r->iop.bus.map(0x1F808264, &r->iop.sio2.data_in);
r->iop.bus.map(0x1F808260, &r->iop.sio2.data_in);
r->iop.bus.map(0x1F808264, &r->iop.sio2.data_out);
r->iop.bus.map(0x1F808268, &r->iop.sio2.ctrl);
r->iop.bus.map(0x1F80826C, &r->iop.sio2.recv1);
r->iop.bus.map(0x1F808270, &r->iop.sio2.recv2);
@ -1692,6 +1692,12 @@ void initialise_iop_timers(RResources * r)
r->iop.timers.units[5] = &r->iop.timers.unit_5;
}
void initialise_iop_sio2(RResources * r)
{
r->iop.sio2.data_in.data_fifo = &r->iop.sio2.data_fifo;
r->iop.sio2.data_out.data_fifo = &r->iop.sio2.data_fifo;
}
void initialise_ee_core(RResources * r)
{
// R5900.
@ -1761,6 +1767,7 @@ void initialise_resources(const std::unique_ptr<RResources> & r)
initialise_iop_core(r.get());
initialise_iop_dmac(r.get());
initialise_iop_timers(r.get());
initialise_iop_sio2(r.get());
initialise_cdvd(r.get());