1 // license:LGPL-2.1+
2 // copyright-holders:Michael Zapf
3 /****************************************************************************
4 
5     Joystick port
6 
7     Now explicitly implemented as a slot device
8     A joystick port allows for plugging in digital devices like joysticks or
9     a Mechatronics mouse, and the TI-99/4 (prototype) also offered IR handsets
10     driven over this port. The 99/4 had an additional line for triggering an
11     interrupt.
12 
13     +-----------+
14     | 1 2 3 4 5 |
15      \ 6 7 8 9 /
16       +-------+
17 
18     Getting the joystick directions and button is pretty simple: The TMS9901 in
19     the TI console lowers the select line, and the joystick shorts a line for
20     the respective action. The lines go back to the inputs of the TMS9901.
21 
22     pin 1   nc
23         2   select joystick 2
24         3   up
25         4   button
26         5   left
27         6   nc
28         7   select joystick 1
29         8   down
30         9   right
31 
32     Michael Zapf
33 
34     June 2012
35 
36 *****************************************************************************/
37 
38 #include "emu.h"
39 #include "joyport.h"
40 #include "handset.h"
41 #include "mecmouse.h"
42 
43 DEFINE_DEVICE_TYPE_NS(TI99_JOYPORT, bus::ti99::joyport, joyport_device, "ti99_joyport", "TI-99 Joystick port")
44 
45 namespace bus { namespace ti99 { namespace joyport {
46 
device_ti99_joyport_interface(const machine_config & config,device_t & device)47 device_ti99_joyport_interface::device_ti99_joyport_interface(const machine_config &config, device_t &device)
48 	:   device_interface(device, "ti99joyport"),
49 		m_joyport(nullptr)
50 {
51 }
52 
joyport_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)53 joyport_device::joyport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
54 	:   device_t(mconfig, TI99_JOYPORT, tag, owner, clock),
55 		device_single_card_slot_interface<device_ti99_joyport_interface>(mconfig, *this),
56 		m_interrupt(*this),
57 		m_connected(nullptr)
58 {
59 }
60 
61 /*
62     Reads a value from the port.
63 */
read_port()64 uint8_t joyport_device::read_port()
65 {
66 	return m_connected->read_dev();
67 }
68 
69 /*
70     This is used to select the device at the port. The device should keep this
71     value until read() is called.
72 */
write_port(int data)73 void joyport_device::write_port(int data)
74 {
75 	m_connected->write_dev(data);
76 }
77 
78 /*
79     This is only used for the handset device of the TI-99/4. It is driven by the VDP interrupt.
80 */
pulse_clock()81 void joyport_device::pulse_clock()
82 {
83 	m_connected->pulse_clock();
84 }
85 
86 /*
87     Propagate the interrupt to the defined target. Only used for the handset
88     at the prototype 99/4.
89 */
WRITE_LINE_MEMBER(joyport_device::set_interrupt)90 WRITE_LINE_MEMBER( joyport_device::set_interrupt )
91 {
92 	m_interrupt(state);
93 }
94 
device_start()95 void joyport_device::device_start()
96 {
97 	m_interrupt.resolve();
98 }
99 
device_config_complete()100 void joyport_device::device_config_complete()
101 {
102 	m_connected = dynamic_cast<device_ti99_joyport_interface*>(subdevices().first());
103 }
104 
105 /*****************************************************************************/
106 
interface_config_complete()107 void device_ti99_joyport_interface::interface_config_complete()
108 {
109 	m_joyport = dynamic_cast<joyport_device*>(device().owner());
110 }
111 
112 } } } // end namespace bus::ti99::joyport
113 
ti99_joyport_options_plain(device_slot_interface & device)114 void ti99_joyport_options_plain(device_slot_interface &device)
115 {
116 	device.option_add("twinjoy", TI99_JOYSTICK);
117 }
118 
ti99_joyport_options_mouse(device_slot_interface & device)119 void ti99_joyport_options_mouse(device_slot_interface &device)
120 {
121 	device.option_add("twinjoy", TI99_JOYSTICK);
122 	device.option_add("mecmouse", TI99_MECMOUSE);
123 }
124 
ti99_joyport_options_994(device_slot_interface & device)125 void ti99_joyport_options_994(device_slot_interface &device)
126 {
127 	device.option_add("twinjoy", TI99_JOYSTICK);
128 	device.option_add("handset", TI99_HANDSET);
129 	device.option_add("mecmouse", TI99_MECMOUSE);
130 }
131 
132