openMSX
NinjaTap.cc
Go to the documentation of this file.
1#include "NinjaTap.hh"
2#include "JoystickPort.hh"
3#include "enumerate.hh"
4#include "ranges.hh"
5#include "serialize.hh"
6
7namespace openmsx {
8
9NinjaTap::NinjaTap(PluggingController& pluggingController_, std::string name_)
10 : JoyTap(pluggingController_, std::move(name_))
11 , status(0x3F) // TODO check initial value
12 , previous(0)
13{
14 ranges::fill(buf, 0xFF);
15}
16
17std::string_view NinjaTap::getDescription() const
18{
19 return "MSX Ninja Tap device";
20}
21
22
23void NinjaTap::plugHelper(Connector& /*connector*/, EmuTime::param time)
24{
25 createPorts("Ninja Tap port", time);
26}
27
28byte NinjaTap::read(EmuTime::param /*time*/)
29{
30 return status;
31}
32
33void NinjaTap::write(byte value, EmuTime::param time)
34{
35 // bit 0 -> pin 6
36 // bit 1 -> pin 7
37 // bit 2 -> pin 8
38 if (value & 2) {
39 // pin7 = 1 : read mode
40 if (!(value & 1) && (previous & 1)) {
41 // pin 6 1->0 : query joysticks
42 // TODO does output change?
43 for (auto [i, slave] : enumerate(slaves)) {
44 byte t = slave->read(time);
45 buf[i] = ((t & 0x0F) << 4) |
46 ((t & 0x30) >> 4) |
47 0x0C;
48 }
49 }
50 if (!(value & 4) && (previous & 4)) {
51 // pin 8 1->0 : shift values
52 // TODO what about b4 and b5?
53 byte t = 0;
54 for (auto [i, b] : enumerate(buf)) {
55 if (b & 1) t |= (1 << i);
56 b >>= 1;
57 }
58 status = (status & ~0x0F) | t;
59 }
60 } else {
61 // pin 7 = 0 : detect mode, b5 is inverse of pin8
62 // TODO what happens with other bits?
63 if (value & 4) {
64 status &= ~0x20;
65 } else {
66 status |= 0x20;
67 }
68 }
69 previous = value;
70}
71
72
73template<typename Archive>
74void NinjaTap::serialize(Archive& ar, unsigned /*version*/)
75{
76 ar.template serializeBase<JoyTap>(*this);
77 ar.serialize("status", status,
78 "previous", previous,
79 "buf", buf);
80}
83
84} // namespace openmsx
TclObject t
Represents something you can plug devices into.
Definition: Connector.hh:21
This device is plugged in into the joyports and consolidates several other joysticks plugged into it.
Definition: JoyTap.hh:22
std::optional< JoystickPort > slaves[4]
Definition: JoyTap.hh:43
void createPorts(static_string_view description, EmuTime::param time)
Definition: JoyTap.cc:16
void plugHelper(Connector &connector, EmuTime::param time) override
Definition: NinjaTap.cc:23
void serialize(Archive &ar, unsigned version)
Definition: NinjaTap.cc:74
std::string_view getDescription() const override
Description for this pluggable.
Definition: NinjaTap.cc:17
NinjaTap(PluggingController &pluggingController, std::string name)
Definition: NinjaTap.cc:9
byte read(EmuTime::param time) override
Read from the joystick device.
Definition: NinjaTap.cc:28
void write(byte value, EmuTime::param time) override
Write a value to the joystick device.
Definition: NinjaTap.cc:33
Central administration of Connectors and Pluggables.
constexpr auto enumerate(Iterable &&iterable)
Heavily inspired by Nathan Reed's blog post: Python-Like enumerate() In C++17 http://reedbeta....
Definition: enumerate.hh:28
This file implemented 3 utility functions:
Definition: Autofire.cc:9
REGISTER_POLYMORPHIC_INITIALIZER(Pluggable, CassettePlayer, "CassettePlayer")
constexpr void fill(ForwardRange &&range, const T &value)
Definition: ranges.hh:256
STL namespace.
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1009