1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#ifndef COMPUMATE_HXX
19#define COMPUMATE_HXX
20
21#include "bspf.hxx"
22#include "CartCM.hxx"
23#include "Control.hxx"
24#include "Event.hxx"
25#include "Console.hxx"
26
27/**
28 Handler for SpectraVideo CompuMate bankswitched games.
29
30 The specifics of the CompuMate format can be found in both the Cart side
31 (CartCM) and the Controller side (CMControl). The CompuMate device is
32 unique for the 2600 in that it requires close co-operation between the
33 cartridge and the left and right controllers.
34
35 This class acts as a 'parent' for cartridge and both the left and right
36 CMControl's, taking care of their creation and communication between them.
37 It also allows to enable/disable the users actual keyboard when required.
38
39 @author Stephen Anthony
40*/
41class CompuMate
42{
43 public:
44 /**
45 Create a new CompuMate handler for both left and right ports.
46 Note that this class creates CMControl controllers for both ports,
47 but does not take responsibility for their deletion.
48
49 @param console The console that owns the controller
50 @param event The event object to use for events
51 @param system The system using this controller
52 */
53 CompuMate(const Console& console, const Event& event, const System& system);
54 virtual ~CompuMate() = default; // Controllers are deleted outside this class
55
56 /**
57 Return the left and right CompuMate controllers
58 */
59 unique_ptr<Controller>& leftController() { return myLeftController; }
60 unique_ptr<Controller>& rightController() { return myRightController; }
61
62
63 /** Needed for communication with CartCM class */
64 uInt8& column() { return myColumn; }
65
66 private:
67 /**
68 Called by the controller(s) when all pins have been written
69 This method keeps track of consecutive calls, and only updates once
70 */
71 void update();
72
73 // The actual CompuMate controller
74 // More information about these scheme can be found in CartCM.hxx
75 class CMControl : public Controller
76 {
77 public:
78 /**
79 Create a new CMControl controller plugged into the specified jack
80
81 @param handler Class which coordinates between left & right controllers
82 @param jack The jack the controller is plugged into
83 @param event The event object to use for events
84 @param system The system using this controller
85 */
86 CMControl(class CompuMate& handler, Controller::Jack jack, const Event& event,
87 const System& system)
88 : Controller(jack, event, system, Controller::Type::CompuMate),
89 myHandler(handler) { }
90 virtual ~CMControl() = default;
91
92 public:
93 /**
94 Called after *all* digital pins have been written on Port A.
95 Only update on the left controller; the right controller will
96 happen at the same cycle and is redundant.
97 */
98 void controlWrite(uInt8) override {
99 if(myJack == Controller::Jack::Left) myHandler.update();
100 }
101
102 /**
103 Update the entire digital and analog pin state according to the
104 events currently set.
105 */
106 void update() override { }
107
108 /**
109 Returns the name of this controller.
110 */
111 string name() const override { return "CompuMate"; }
112
113 private:
114 class CompuMate& myHandler;
115
116 // Following constructors and assignment operators not supported
117 CMControl() = delete;
118 CMControl(const CMControl&) = delete;
119 CMControl(CMControl&&) = delete;
120 CMControl& operator=(const CMControl&) = delete;
121 CMControl& operator=(CMControl&&) = delete;
122 };
123
124 private:
125 // Console and Event objects
126 const Console& myConsole;
127
128 // Left and right controllers
129 unique_ptr<Controller> myLeftController, myRightController;
130
131 // Column currently active
132 uInt8 myColumn;
133
134 /// Reference to the event object this controller uses
135 const Event& myEvent;
136
137 private:
138 // Following constructors and assignment operators not supported
139 CompuMate() = delete;
140 CompuMate(const CompuMate&) = delete;
141 CompuMate(CompuMate&&) = delete;
142 CompuMate& operator=(const CompuMate&) = delete;
143 CompuMate& operator=(CompuMate&&) = delete;
144};
145
146#endif
147