Previous 199869 Revisions Next

r35311 Thursday 26th February, 2015 at 18:38:42 UTC by Couriersud
C++'d more of window.c (nw)
[src/emu/video]scn2674.c scn2674.h
[src/mess]mess.mak
[src/mess/drivers]amaztron.c* comp4.c* hh_tms1k.c pcd.c simon.c* tc4.c*
[src/mess/layout]amaztron.lay
[src/osd/windows]video.c window.c window.h

trunk/src/emu/video/scn2674.c
r243822r243823
694694
695695         for(int i = 0; i < m_IR5_character_per_row; i++)
696696         {
697            bool cursor_on = ((address & 0x3fff) == ((m_cursor_h << 8) | m_cursor_l));
697            if((address & 0x3fff) == ((m_cursor_h << 8) | m_cursor_l))
698               m_cursor_on = true;
698699
699700            if (!m_display_cb.isnull())
700701               m_display_cb(m_bitmap,
r243822r243823
703704                           tilerow,
704705                           space().read_byte(address),
705706                           address,
706                           (charrow >= m_IR6_cursor_first_scanline) && (charrow <= m_IR6_cursor_last_scanline) && cursor_on,
707                           (charrow >= m_IR6_cursor_first_scanline) && m_cursor_on,
707708                           dw != 0,
708709                           m_gfx_enabled != 0,
709710                           charrow == m_IR7_cursor_underline_position,
r243822r243823
714715               address = (m_IR9_display_buffer_first_address_MSB << 8) | m_IR8_display_buffer_first_address_LSB;
715716         }
716717
718         if(charrow == m_IR6_cursor_last_scanline)
719            m_cursor_on = false;
720
717721         if(m_gfx_enabled || (charrow == (m_IR0_scanline_per_char_row - 1)))
718722            m_address = address;
719723      }
trunk/src/emu/video/scn2674.h
r243822r243823
105105   UINT8 m_dbl1;
106106   int m_linecounter;
107107   UINT16 m_address;
108   bool m_cursor_on;
108109
109110   UINT8 m_irq_state;
110111
trunk/src/mess/drivers/amaztron.c
r0r243823
1// license:BSD-3-Clause
2// copyright-holders:hap
3/***************************************************************************
4
5  Coleco Amaze-A-Tron, by Ralph Baer
6  * TMS1100 MCU, labeled MP3405(die label too)
7
8  This is an electronic board game with a selection of 8 maze games,
9  most of them for 2 players. A 5x5 playing grid and four markers are
10  required to play. Refer to the official manual for more information.
11
12***************************************************************************/
13
14#include "emu.h"
15#include "cpu/tms0980/tms0980.h"
16#include "sound/speaker.h"
17
18#include "amaztron.lh"
19
20// master clock is a single stage RC oscillator: R=33K?, C=100pf,
21// according to the TMS 1000 series data manual this is around 350kHz
22#define MASTER_CLOCK (350000)
23
24
25class amaztron_state : public driver_device
26{
27public:
28   amaztron_state(const machine_config &mconfig, device_type type, const char *tag)
29      : driver_device(mconfig, type, tag),
30      m_maincpu(*this, "maincpu"),
31      m_button_matrix(*this, "IN"),
32      m_speaker(*this, "speaker")
33   { }
34
35   required_device<cpu_device> m_maincpu;
36   required_ioport_array<6> m_button_matrix;
37   required_device<speaker_sound_device> m_speaker;
38
39   UINT16 m_r;
40   UINT16 m_o;
41
42   DECLARE_READ8_MEMBER(read_k);
43   DECLARE_WRITE16_MEMBER(write_o);
44   DECLARE_WRITE16_MEMBER(write_r);
45
46   void leds_update();
47
48   virtual void machine_start();
49};
50
51
52
53/***************************************************************************
54
55  I/O
56
57***************************************************************************/
58
59void amaztron_state::leds_update()
60{
61   for (int i = 0; i < 2; i++)
62      if (m_r >> (i + 8) & 1)
63         output_set_digit_value(i, m_o);
64}
65
66READ8_MEMBER(amaztron_state::read_k)
67{
68   UINT8 k = 0;
69
70   // read selected button rows
71   for (int i = 0; i < 6; i++)
72   {
73      if (m_r >> i & 1)
74         k |= m_button_matrix[i]->read();
75   }
76
77   // the 5th row is tied to K4+K8
78   if (k & 0x10) k |= 0xc;
79   return k & 0xf;
80}
81
82WRITE16_MEMBER(amaztron_state::write_r)
83{
84   // R0-R5: input mux
85   // R6,R7: lamps
86   output_set_lamp_value(0, data >> 6 & 1);
87   output_set_lamp_value(1, data >> 7 & 1);
88
89   // R8,R9: select digit
90   m_r = data;
91   leds_update();
92
93   // R10: speaker out
94   m_speaker->level_w(data >> 10 & 1);
95}
96
97WRITE16_MEMBER(amaztron_state::write_o)
98{
99   // O0-O6: digit segments
100   // O7: N/C
101   m_o = data & 0x7f;
102   leds_update();
103}
104
105
106
107/***************************************************************************
108
109  Inputs
110
111***************************************************************************/
112
113static INPUT_PORTS_START( amaztron )
114   PORT_START("IN.0") // R0
115   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Button 1")
116   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_NAME("Button 6")
117   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Button 11")
118   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Button 16")
119   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Z) PORT_NAME("Button 21")
120
121   PORT_START("IN.1") // R1
122   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Button 2")
123   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_NAME("Button 7")
124   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Button 12")
125   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Button 17")
126   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_X) PORT_NAME("Button 22")
127
128   PORT_START("IN.2") // R2
129   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Button 3")
130   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Button 8")
131   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Button 13")
132   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_NAME("Button 18")
133   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_NAME("Button 23")
134
135   PORT_START("IN.3") // R3
136   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("Button 4")
137   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_9) PORT_NAME("Button 9")
138   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Button 14")
139   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("Button 19")
140   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_V) PORT_NAME("Button 24")
141
142   PORT_START("IN.4") // R4
143   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_NAME("Button 5")
144   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_0) PORT_NAME("Button 10")
145   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Button 15")
146   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_NAME("Button 20")
147   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_NAME("Button 25")
148
149   PORT_START("IN.5") // R5
150   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("Game Select")
151   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("Game Start")
152   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED)
153   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED)
154   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_UNUSED)
155INPUT_PORTS_END
156
157
158
159/***************************************************************************
160
161  Machine Config
162
163***************************************************************************/
164
165void amaztron_state::machine_start()
166{
167   m_r = 0;
168   m_o = 0;
169
170   save_item(NAME(m_r));
171   save_item(NAME(m_o));
172}
173
174
175static MACHINE_CONFIG_START( amaztron, amaztron_state )
176
177   /* basic machine hardware */
178   MCFG_CPU_ADD("maincpu", TMS1100, MASTER_CLOCK)
179   MCFG_TMS1XXX_READ_K_CB(READ8(amaztron_state, read_k))
180   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(amaztron_state, write_o))
181   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(amaztron_state, write_r))
182
183   MCFG_DEFAULT_LAYOUT(layout_amaztron)
184
185   /* no video! */
186
187   /* sound hardware */
188   MCFG_SPEAKER_STANDARD_MONO("mono")
189   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
190   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
191MACHINE_CONFIG_END
192
193
194
195/***************************************************************************
196
197  Game driver(s)
198
199***************************************************************************/
200
201ROM_START( amaztron )
202   ROM_REGION( 0x0800, "maincpu", 0 )
203   ROM_LOAD( "tms1100nll_mp3405", 0x0000, 0x0800, CRC(9cbc0009) SHA1(17772681271b59280687492f37fa0859998f041d) )
204
205   ROM_REGION( 867, "maincpu:mpla", 0 )
206   ROM_LOAD( "tms1100_amaztron_mpla.pla", 0, 867, CRC(03574895) SHA1(04407cabfb3adee2ee5e4218612cb06c12c540f4) )
207   ROM_REGION( 365, "maincpu:opla", 0 )
208   ROM_LOAD( "tms1100_amaztron_opla.pla", 0, 365, CRC(f3875384) SHA1(3c256a3db4f0aa9d93cf78124db39f4cbdc57e4a) )
209ROM_END
210
211
212CONS( 1979, amaztron, 0, 0, amaztron, amaztron, driver_device, 0, "Coleco", "Amaze-A-Tron", GAME_SUPPORTS_SAVE )
trunk/src/mess/drivers/comp4.c
r0r243823
1// license:BSD-3-Clause
2// copyright-holders:hap
3/***************************************************************************
4
5  Milton Bradley Comp IV
6  * TMC0904NL CP0904A (die labeled 4A0970D-04A)
7
8  This is small tabletop Mastermind game; a code-breaking game where the player
9  needs to find out the correct sequence of colours (numbers in our case).
10  It is known as Logic 5 in Europe, and as Pythaligoras in Japan.
11
12  Press the R key to start, followed by a set of unique numbers and E.
13  Refer to the official manual for more information.
14
15
16  TODO:
17  - MCU clock is unknown
18
19***************************************************************************/
20
21#include "emu.h"
22#include "cpu/tms0980/tms0980.h"
23
24#include "comp4.lh"
25
26// master clock is unknown, the value below is an approximation
27#define MASTER_CLOCK (250000)
28
29
30class comp4_state : public driver_device
31{
32public:
33   comp4_state(const machine_config &mconfig, device_type type, const char *tag)
34      : driver_device(mconfig, type, tag),
35      m_maincpu(*this, "maincpu"),
36      m_button_matrix(*this, "IN")
37   { }
38
39   required_device<cpu_device> m_maincpu;
40   required_ioport_array<3> m_button_matrix;
41
42   UINT16 m_o;
43
44   UINT16 m_display_state;
45   UINT8 m_display_decay[0x10];
46
47   DECLARE_READ8_MEMBER(read_k);
48   DECLARE_WRITE16_MEMBER(write_o);
49   DECLARE_WRITE16_MEMBER(write_r);
50
51   TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick);
52   void display_update();
53
54   virtual void machine_start();
55};
56
57
58/***************************************************************************
59
60  LED Display
61
62***************************************************************************/
63
64// The device strobes the outputs very fast, it is unnoticeable to the user.
65// To prevent flickering here, we need to simulate a decay.
66
67// decay time, in steps of 1ms
68#define DISPLAY_DECAY_TIME 25
69
70void comp4_state::display_update()
71{
72   for (int i = 0; i < 0x10; i++)
73   {
74      // turn on powered segments
75      if (m_display_state >> i & 1)
76         m_display_decay[i] = DISPLAY_DECAY_TIME;
77
78      // send to output
79      output_set_lamp_value(i, (m_display_decay[i] != 0) ? 1 : 0);
80   }
81}
82
83TIMER_DEVICE_CALLBACK_MEMBER(comp4_state::display_decay_tick)
84{
85   // slowly turn off unpowered segments
86   for (int i = 0; i < 0x10; i++)
87      if (!(m_display_state >> i & 1) && m_display_decay[i])
88         m_display_decay[i]--;
89
90   display_update();
91}
92
93
94
95/***************************************************************************
96
97  I/O
98
99***************************************************************************/
100
101READ8_MEMBER(comp4_state::read_k)
102{
103   UINT8 k = 0;
104
105   // read selected button rows
106   for (int i = 0; i < 3; i++)
107      if (m_o >> (i+1) & 1)
108         k |= m_button_matrix[i]->read();
109
110   return k;
111}
112
113WRITE16_MEMBER(comp4_state::write_r)
114{
115   // LEDs:
116   // R4    R9
117   // R10!  R8
118   // R2    R7
119   // R1    R6
120   // R0    R5
121   m_display_state = data;
122   display_update();
123}
124
125WRITE16_MEMBER(comp4_state::write_o)
126{
127   // O0: LEDs common (always writes 1)
128   // O1-O3: input mux
129   // other bits: N/C
130   m_o = data;
131}
132
133
134
135/***************************************************************************
136
137  Inputs
138
139***************************************************************************/
140
141static INPUT_PORTS_START( comp4 )
142   PORT_START("IN.0") // O1
143   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("R")
144   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1")
145   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4")
146   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7")
147
148   PORT_START("IN.1") // O2
149   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
150   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2")
151   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5")
152   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8")
153
154   PORT_START("IN.2") // O3
155   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("E")
156   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
157   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
158   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
159INPUT_PORTS_END
160
161
162
163/***************************************************************************
164
165  Machine Config
166
167***************************************************************************/
168
169void comp4_state::machine_start()
170{
171   // zerofill
172   m_display_state = 0;
173   memset(m_display_decay, 0, sizeof(m_display_decay));
174
175   m_o = 0;
176
177   // register for savestates
178   save_item(NAME(m_display_state));
179   save_item(NAME(m_display_decay));
180
181   save_item(NAME(m_o));
182}
183
184
185static MACHINE_CONFIG_START( comp4, comp4_state )
186
187   /* basic machine hardware */
188   MCFG_CPU_ADD("maincpu", TMS0970, MASTER_CLOCK)
189   MCFG_TMS1XXX_READ_K_CB(READ8(comp4_state, read_k))
190   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(comp4_state, write_o))
191   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(comp4_state, write_r))
192
193   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", comp4_state, display_decay_tick, attotime::from_msec(1))
194
195   MCFG_DEFAULT_LAYOUT(layout_comp4)
196
197   /* no video! */
198
199   /* no sound! */
200MACHINE_CONFIG_END
201
202
203
204/***************************************************************************
205
206  Game driver(s)
207
208***************************************************************************/
209
210ROM_START( comp4 )
211   ROM_REGION( 0x0400, "maincpu", 0 )
212   ROM_LOAD( "tmc0904nl_cp0904a", 0x0000, 0x0400, CRC(6233ee1b) SHA1(738e109b38c97804b4ec52bed80b00a8634ad453) )
213
214   ROM_REGION( 782, "maincpu:ipla", 0 )
215   ROM_LOAD( "tms0970_default_ipla.pla", 0, 782, CRC(e038fc44) SHA1(dfc280f6d0a5828d1bb14fcd59ac29caf2c2d981) )
216   ROM_REGION( 860, "maincpu:mpla", 0 )
217   ROM_LOAD( "tms0970_comp4_mpla.pla", 0, 860, CRC(ee9d7d9e) SHA1(25484e18f6a07f7cdb21a07220e2f2a82fadfe7b) )
218   ROM_REGION( 352, "maincpu:opla", 0 )
219   ROM_LOAD( "tms0970_comp4_opla.pla", 0, 352, CRC(a0f887d1) SHA1(3c666663d484d5bed81e1014f8715aab8a3d489f) )
220   ROM_REGION( 157, "maincpu:spla", 0 )
221   ROM_LOAD( "tms0970_comp4_spla.pla", 0, 157, CRC(e5bddd90) SHA1(4b1c6512c70e5bcd23c2dbf0c88cd8aa2c632a10) )
222ROM_END
223
224
225CONS( 1977, comp4, 0, 0, comp4, comp4, driver_device, 0, "Milton Bradley", "Comp IV", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW )
trunk/src/mess/drivers/hh_tms1k.c
r243822r243823
1313#include "cpu/tms0980/tms0980.h"
1414#include "sound/speaker.h"
1515
16#include "amaztron.lh"
1716#include "ebball.lh"
18#include "comp4.lh"
19#include "simon.lh"
20#include "tc4.lh"
2117
2218
2319class hh_tms1k_state : public driver_device
r243822r243823
2622   hh_tms1k_state(const machine_config &mconfig, device_type type, const char *tag)
2723      : driver_device(mconfig, type, tag),
2824      m_maincpu(*this, "maincpu"),
29      m_inp_matrix(*this, "IN"),
30      m_speaker(*this, "speaker"),
31      m_display_maxy(1),
32      m_display_maxx(0),
33      m_display_wait(50)
25//      m_button_matrix(*this, "IN"),
26      m_speaker(*this, "speaker")
3427   { }
3528
3629   required_device<cpu_device> m_maincpu;
37   optional_ioport_array<7> m_inp_matrix; // max 7
38   optional_device<speaker_sound_device> m_speaker;
39   
40   UINT16 m_r;
41   UINT16 m_o;
42   UINT16 m_inp_mux;
30//   required_ioport_array<3> m_button_matrix;
31   required_device<speaker_sound_device> m_speaker;
4332
44   int m_display_maxy;
45   int m_display_maxx;
46   int m_display_wait;
47   
48   UINT32 m_display_state[0x20];
49   UINT32 m_display_cache[0x20];
50   UINT8 m_display_decay[0x20][0x20];
51   UINT16 m_7seg_mask[0x20];
52
53   TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick);
54   bool index_is_7segled(int index);
55   void display_update();
56   
57   UINT8 read_inputs(int columns);
58
59   // game-specific handlers
60   void amaztron_display();
61   DECLARE_READ8_MEMBER(amaztron_read_k);
62   DECLARE_WRITE16_MEMBER(amaztron_write_o);
63   DECLARE_WRITE16_MEMBER(amaztron_write_r);
64
65   void tc4_display();
66   DECLARE_READ8_MEMBER(tc4_read_k);
67   DECLARE_WRITE16_MEMBER(tc4_write_o);
68   DECLARE_WRITE16_MEMBER(tc4_write_r);
69
70   DECLARE_READ8_MEMBER(comp4_read_k);
71   DECLARE_WRITE16_MEMBER(comp4_write_o);
72   DECLARE_WRITE16_MEMBER(comp4_write_r);
73
74   DECLARE_READ8_MEMBER(simon_read_k);
75   DECLARE_WRITE16_MEMBER(simon_write_o);
76   DECLARE_WRITE16_MEMBER(simon_write_r);
77
7833   virtual void machine_start();
7934};
8035
8136
82void hh_tms1k_state::machine_start()
83{
84   // zerofill
85   memset(m_display_state, 0, sizeof(m_display_state));
86   memset(m_display_cache, 0, sizeof(m_display_cache));
87   memset(m_display_decay, 0, sizeof(m_display_decay));
88   memset(m_7seg_mask, 0, sizeof(m_7seg_mask));
89
90   m_o = 0;
91   m_r = 0;
92   m_inp_mux = 0;
93
94   // register for savestates
95   save_item(NAME(m_display_maxy));
96   save_item(NAME(m_display_maxx));
97   save_item(NAME(m_display_wait));
98
99   save_item(NAME(m_display_state));
100   save_item(NAME(m_display_cache));
101   save_item(NAME(m_display_decay));
102   save_item(NAME(m_7seg_mask));
103
104   save_item(NAME(m_o));
105   save_item(NAME(m_r));
106   save_item(NAME(m_inp_mux));
107}
108
109
110/***************************************************************************
111
112  Helper Functions
113
114***************************************************************************/
115
116
117// The device strobes the outputs very fast, it is unnoticeable to the user.
118// To prevent flickering here, we need to simulate a decay.
119
120
121void hh_tms1k_state::display_update()
122{
123   UINT32 active_state[0x20];
124
125   for (int y = 0; y < m_display_maxy; y++)
126   {
127      active_state[y] = 0;
128
129      for (int x = 0; x < m_display_maxx; x++)
130      {
131         // turn on powered segments
132         if (m_display_state[y] >> x & 1)
133            m_display_decay[y][x] = m_display_wait;
134
135         // determine active state
136         int ds = (m_display_decay[y][x] != 0) ? 1 : 0;
137         active_state[y] |= (ds << x);
138      }
139   }
140
141   // on difference, send to output
142   for (int y = 0; y < m_display_maxy; y++)
143      if (m_display_cache[y] != active_state[y])
144      {
145         if (m_7seg_mask[y] != 0)
146            output_set_digit_value(y, active_state[y] & m_7seg_mask[y]);
147
148         const int mul = (m_display_maxx <= 10) ? 10 : 100;
149         for (int x = 0; x < m_display_maxx; x++)
150            output_set_lamp_value(y * mul + x, active_state[y] >> x & 1);
151      }
152
153   memcpy(m_display_cache, active_state, sizeof(m_display_cache));
154}
155
156TIMER_DEVICE_CALLBACK_MEMBER(hh_tms1k_state::display_decay_tick)
157{
158   // slowly turn off unpowered segments
159   for (int y = 0; y < m_display_maxy; y++)
160      for (int x = 0; x < m_display_maxx; x++)
161         if (!(m_display_state[y] >> x & 1) && m_display_decay[y][x] != 0)
162            m_display_decay[y][x]--;
163   
164   display_update();
165}
166
167
168UINT8 hh_tms1k_state::read_inputs(int columns)
169{
170   UINT8 k = 0;
171
172   // read selected input rows
173   for (int i = 0; i < columns; i++)
174      if (m_inp_mux >> i & 1)
175         k |= m_inp_matrix[i]->read();
176
177   return k;
178}
179
180
181
182/***************************************************************************
183
184  Minidrivers (I/O, Inputs, Machine Config)
185
186***************************************************************************/
187
188/***************************************************************************
189
190  Coleco Amaze-A-Tron, by Ralph Baer
191  * TMS1100 MCU, labeled MP3405(die label too)
192
193  This is an electronic board game with a selection of 8 maze games,
194  most of them for 2 players. A 5x5 playing grid and four markers are
195  required to play. Refer to the official manual for more information.
196
197***************************************************************************/
198
199
200void hh_tms1k_state::amaztron_display()
201{
202   m_display_maxy = 3;
203   m_display_maxx = 8;
204
205   // R8,R9: select digit
206   for (int y = 0; y < 2; y++)
207   {
208      m_7seg_mask[y] = 0x7f;
209      m_display_state[y] = (m_r >> (y + 8) & 1) ? m_o : 0;
210   }
211   
212   // R6,R7: lamps -> lamp20, lamp21
213   m_display_state[2] = m_r >> 6 & 3;
214   
215   display_update();
216}
217
218READ8_MEMBER(hh_tms1k_state::amaztron_read_k)
219{
220   UINT8 k = read_inputs(6);
221
222   // the 5th column is tied to K4+K8
223   if (k & 0x10) k |= 0xc;
224   return k & 0xf;
225}
226
227WRITE16_MEMBER(hh_tms1k_state::amaztron_write_r)
228{
229   // R0-R5: input mux
230   m_inp_mux = data & 0x3f;
231   
232   // R10: speaker out
233   m_speaker->level_w(data >> 10 & 1);
234
235   // other bits:
236   m_r = data;
237   amaztron_display();
238}
239
240WRITE16_MEMBER(hh_tms1k_state::amaztron_write_o)
241{
242   // O0-O6: digit segments
243   // O7: N/C
244   m_o = data & 0x7f;
245   amaztron_display();
246}
247
248
249static INPUT_PORTS_START( amaztron )
250   PORT_START("IN.0") // R0
251   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Button 1")
252   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_NAME("Button 6")
253   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Button 11")
254   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Button 16")
255   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Z) PORT_NAME("Button 21")
256
257   PORT_START("IN.1") // R1
258   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Button 2")
259   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_NAME("Button 7")
260   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Button 12")
261   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Button 17")
262   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_X) PORT_NAME("Button 22")
263
264   PORT_START("IN.2") // R2
265   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Button 3")
266   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Button 8")
267   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Button 13")
268   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_NAME("Button 18")
269   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_NAME("Button 23")
270
271   PORT_START("IN.3") // R3
272   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("Button 4")
273   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_9) PORT_NAME("Button 9")
274   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Button 14")
275   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("Button 19")
276   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_V) PORT_NAME("Button 24")
277
278   PORT_START("IN.4") // R4
279   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_NAME("Button 5")
280   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_0) PORT_NAME("Button 10")
281   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Button 15")
282   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_NAME("Button 20")
283   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_NAME("Button 25")
284
285   PORT_START("IN.5") // R5
286   PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("Game Select")
287   PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("Game Start")
288   PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_UNUSED)
289   PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED)
290   PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_UNUSED)
37static INPUT_PORTS_START( ebball )
29138INPUT_PORTS_END
29239
29340
294static MACHINE_CONFIG_START( amaztron, hh_tms1k_state )
29541
296   /* basic machine hardware */
297   MCFG_CPU_ADD("maincpu", TMS1100, 350000) // RC osc. R=33K?, C=100pf -> ~350kHz
298   MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, amaztron_read_k))
299   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, amaztron_write_o))
300   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, amaztron_write_r))
301
302   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
303
304   MCFG_DEFAULT_LAYOUT(layout_amaztron)
305
306   /* no video! */
307
308   /* sound hardware */
309   MCFG_SPEAKER_STANDARD_MONO("mono")
310   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
311   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
312MACHINE_CONFIG_END
313
314
315
316
31742/***************************************************************************
31843
319  Coleco Total Control 4
320  * TMS1400NLL MP7334-N2 (die labeled MP7334)
44  Machine Config
32145
322  This is a head to head electronic tabletop LED-display sports console.
323  One cartridge(Football) was included with the console, the other three were
324  sold separately. Gameplay has emphasis on strategy, read the official manual
325  on how to play. Remember that you can rotate the view in MESS: rotate left
326  for Home(P1) orientation, rotate right for Visitor(P2) orientation.
327
328  Cartridge socket:
329  1 N/C
330  2 9V+
331  3 power switch
332  4 K8
333  5 K4
334  6 K2
335  7 K1
336  8 R9
337
338  The cartridge connects pin 8 with one of the K-pins.
339
340  Available cartridges:
341  - Football    (K8, confirmed)
342  - Hockey      (K4?)
343  - Soccer      (K2?)
344  - Basketball  (K1?)
345
346
347  TODO:
348  - pin configuration of other carts is guessed
349  - softlist for the cartridges?
350  - offsensive players leds are supposed to look brighter
351  - MCU clock is unknown
352
35346***************************************************************************/
35447
355void hh_tms1k_state::tc4_display()
48void hh_tms1k_state::machine_start()
35649{
357   m_display_maxy = 10;
358   m_display_maxx = 9;
359   
360   // R5,7,8,9 are 7segs
361   for (int y = 0; y < m_display_maxy; y++)
362      if (y >= 5 && y <= 9 && y != 6)
363         m_7seg_mask[y] = 0x7f;
364   
365   // update current state (note: R6 as extra column!)
366   for (int y = 0; y < m_display_maxy; y++)
367      m_display_state[y] = (m_r >> y & 1) ? (m_o | (m_r << 2 & 0x100)) : 0;
368   
369   display_update();
37050}
37151
372READ8_MEMBER(hh_tms1k_state::tc4_read_k)
373{
374   UINT8 k = read_inputs(6);
37552
376   // read from cartridge
377   if (m_inp_mux & 0x200)
378      k |= m_inp_matrix[6]->read();
379
380   return k;
381}
382
383WRITE16_MEMBER(hh_tms1k_state::tc4_write_o)
384{
385   // O0-O7: leds/7segment
386   m_o = data;
387   tc4_display();
388}
389
390WRITE16_MEMBER(hh_tms1k_state::tc4_write_r)
391{
392   // R10: speaker out
393   m_speaker->level_w(data >> 10 & 1);
394
395   // R0-R5: input mux
396   // R9: to cartridge slot
397   m_inp_mux = data & 0x23f;
398   
399   // R6: led column 8
400   // +other: select leds
401   m_r = data;
402   tc4_display();
403}
404
405
406static INPUT_PORTS_START( tc4 )
407   PORT_START("IN.0") // R0
408   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P1 Pass/Shoot Button 3") // right
409   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Pass/Shoot Button 1") // left
410   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Pass/Shoot Button 2") // middle
411   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("P1 D/K Button")
412
413   PORT_START("IN.1") // R1
414   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_RIGHT )
415   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_LEFT )
416   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_UP )
417   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_DOWN )
418
419   PORT_START("IN.2") // R2
420   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_RIGHT )
421   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_LEFT )
422   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_UP )
423   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_DOWN )
424
425   PORT_START("IN.3") // R3
426   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_RIGHT ) PORT_PLAYER(2)
427   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_LEFT ) PORT_PLAYER(2)
428   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_UP ) PORT_PLAYER(2)
429   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_DOWN ) PORT_PLAYER(2)
430
431   PORT_START("IN.4") // R4
432   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_RIGHT ) PORT_PLAYER(2)
433   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_LEFT ) PORT_PLAYER(2)
434   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_UP ) PORT_PLAYER(2)
435   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_DOWN ) PORT_PLAYER(2)
436
437   PORT_START("IN.5") // R5
438   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Pass/Shoot Button 3") // right
439   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Pass/Shoot Button 1") // left
440   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Pass/Shoot Button 2") // middle
441   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_NAME("P2 D/K Button")
442
443   PORT_START("IN.6") // R9
444   PORT_CONFNAME( 0x0f, 0x08, "Cartridge")
445   PORT_CONFSETTING(    0x01, "Basketball" )
446   PORT_CONFSETTING(    0x02, "Soccer" )
447   PORT_CONFSETTING(    0x04, "Hockey" )
448   PORT_CONFSETTING(    0x08, "Football" )
449INPUT_PORTS_END
450
451static MACHINE_CONFIG_START( tc4, hh_tms1k_state )
452
453   /* basic machine hardware */
454   MCFG_CPU_ADD("maincpu", TMS1400, 450000) // approximation - RC osc. R=27.3K, C=100pf, but unknown RC curve
455   MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, tc4_read_k))
456   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, tc4_write_o))
457   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, tc4_write_r))
458
459   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
460
461   MCFG_DEFAULT_LAYOUT(layout_tc4)
462
463   /* no video! */
464
465   /* sound hardware */
466   MCFG_SPEAKER_STANDARD_MONO("mono")
467   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
468   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
469MACHINE_CONFIG_END
470
471
472
473/***************************************************************************
474
475  Milton Bradley Comp IV
476  * TMC0904NL CP0904A (die labeled 4A0970D-04A)
477
478  This is small tabletop Mastermind game; a code-breaking game where the player
479  needs to find out the correct sequence of colours (numbers in our case).
480  It is known as Logic 5 in Europe, and as Pythaligoras in Japan.
481
482  Press the R key to start, followed by a set of unique numbers and E.
483  Refer to the official manual for more information.
484
485
486  TODO:
487  - MCU clock is unknown
488
489***************************************************************************/
490
491READ8_MEMBER(hh_tms1k_state::comp4_read_k)
492{
493   return read_inputs(3);
494}
495
496WRITE16_MEMBER(hh_tms1k_state::comp4_write_r)
497{
498   // leds:
499   // R4    R9
500   // R10!  R8
501   // R2    R7
502   // R1    R6
503   // R0    R5
504   m_display_maxx = 11;
505   m_display_state[0] = data;
506   display_update();
507}
508
509WRITE16_MEMBER(hh_tms1k_state::comp4_write_o)
510{
511   // O0: leds common (always writes 1)
512   // O1-O3: input mux
513   // other bits: N/C
514   m_inp_mux = data >> 1 & 7;
515}
516
517
518static INPUT_PORTS_START( comp4 )
519   PORT_START("IN.0") // O1
520   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("R")
521   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1")
522   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4")
523   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7")
524
525   PORT_START("IN.1") // O2
526   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
527   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("2")
528   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5")
529   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8")
530
531   PORT_START("IN.2") // O3
532   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("E")
533   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
534   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
535   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
536INPUT_PORTS_END
537
538
539
540static MACHINE_CONFIG_START( comp4, hh_tms1k_state )
541
542   /* basic machine hardware */
543   MCFG_CPU_ADD("maincpu", TMS0970, 250000) // approximation - unknown freq
544   MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, comp4_read_k))
545   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, comp4_write_o))
546   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, comp4_write_r))
547
548   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
549
550   MCFG_DEFAULT_LAYOUT(layout_comp4)
551
552   /* no video! */
553
554   /* no sound! */
555MACHINE_CONFIG_END
556
557
558/***************************************************************************
559
560  Milton Bradley Simon, created by Ralph Baer
561
562  Revision A hardware:
563  * TMS1000 (has internal ROM), DS75494 lamp driver
564
565  Newer revisions have a smaller 16-pin MB4850 chip instead of the TMS1000.
566  This one has been decapped too, but we couldn't find an internal ROM.
567  It is possibly a cost-reduced custom ASIC specifically for Simon.
568
569  Other games assumed to be on similar hardware:
570  - Pocket Simon, but there's a chance it only exists with MB4850 chip
571  - Super Simon (TMS1100)
572
573***************************************************************************/
574
575
576
577
578
579/***************************************************************************
580
581  I/O
582
583***************************************************************************/
584
585READ8_MEMBER(hh_tms1k_state::simon_read_k)
586{
587   return read_inputs(4);
588}
589
590WRITE16_MEMBER(hh_tms1k_state::simon_write_r)
591{
592   // R4-R8 go through an 75494 IC first:
593   // R4 -> 75494 IN6 -> green lamp
594   // R5 -> 75494 IN3 -> red lamp
595   // R6 -> 75494 IN5 -> yellow lamp
596   // R7 -> 75494 IN2 -> blue lamp
597   m_display_maxx = 4;
598   m_display_state[0] = data >> 4 & 0xf;
599   display_update();
600
601   // R8 -> 75494 IN0 -> speaker
602   m_speaker->level_w(data >> 8 & 1);
603
604   // R0,R1,R2,R9: input mux
605   // R3: GND
606   // other bits: N/C
607   m_inp_mux = (data & 7) | (data >> 6 & 8);
608}
609
610WRITE16_MEMBER(hh_tms1k_state::simon_write_o)
611{
612   // N/C
613}
614
615
616static INPUT_PORTS_START( simon )
617   PORT_START("IN.0") // R0
618   PORT_CONFNAME( 0x07, 0x02, "Game Select")
619   PORT_CONFSETTING(    0x02, "1" )
620   PORT_CONFSETTING(    0x01, "2" )
621   PORT_CONFSETTING(    0x04, "3" )
622   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
623
624   PORT_START("IN.1") // R1
625   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Green Button")
626   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Red Button")
627   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("Yellow Button")
628   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_NAME("Blue Button")
629
630   PORT_START("IN.2") // R2
631   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("Start")
632   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Last")
633   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Longest")
634   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
635
636   PORT_START("IN.3") // R9
637   PORT_CONFNAME( 0x0f, 0x01, "Skill Level")
638   PORT_CONFSETTING(    0x02, "1" )
639   PORT_CONFSETTING(    0x04, "2" )
640   PORT_CONFSETTING(    0x08, "3" )
641   PORT_CONFSETTING(    0x01, "4" )
642INPUT_PORTS_END
643
644
645static MACHINE_CONFIG_START( simon, hh_tms1k_state )
646
647   /* basic machine hardware */
648   MCFG_CPU_ADD("maincpu", TMS1000, 350000) // RC osc. R=33K, C=100pf -> ~350kHz
649   MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, simon_read_k))
650   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, simon_write_o))
651   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, simon_write_r))
652
653   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
654
655   MCFG_DEFAULT_LAYOUT(layout_simon)
656
657   /* no video! */
658
659   /* sound hardware */
660   MCFG_SPEAKER_STANDARD_MONO("mono")
661   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
662   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
663MACHINE_CONFIG_END
664
665
666
667
668
669/***************************************************************************
670
671  Entex Baseball
672  * TMS1000NLP MP0914 (die labeled MP0914A)
673
674***************************************************************************/
675
676// inputs
677static INPUT_PORTS_START( ebball )
678INPUT_PORTS_END
679
680// machine config
68153static MACHINE_CONFIG_START( ebball, hh_tms1k_state )
68254
68355   /* basic machine hardware */
r243822r243823
70173
70274***************************************************************************/
70375
704
705ROM_START( amaztron )
706   ROM_REGION( 0x0800, "maincpu", 0 )
707   ROM_LOAD( "tms1100nll_mp3405", 0x0000, 0x0800, CRC(9cbc0009) SHA1(17772681271b59280687492f37fa0859998f041d) )
708
709   ROM_REGION( 867, "maincpu:mpla", 0 )
710   ROM_LOAD( "tms1100_amaztron_mpla.pla", 0, 867, CRC(03574895) SHA1(04407cabfb3adee2ee5e4218612cb06c12c540f4) )
711   ROM_REGION( 365, "maincpu:opla", 0 )
712   ROM_LOAD( "tms1100_amaztron_opla.pla", 0, 365, CRC(f3875384) SHA1(3c256a3db4f0aa9d93cf78124db39f4cbdc57e4a) )
713ROM_END
714
715
716
717
718ROM_START( tc4 )
719   ROM_REGION( 0x1000, "maincpu", 0 )
720   ROM_LOAD( "tms1400nll_mp7334", 0x0000, 0x1000, CRC(923f3821) SHA1(a9ae342d7ff8dae1dedcd1e4984bcfae68586581) )
721
722   ROM_REGION( 867, "maincpu:mpla", 0 )
723   ROM_LOAD( "tms1100_default_mpla.pla", 0, 867, CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) )
724   ROM_REGION( 557, "maincpu:opla", 0 )
725   ROM_LOAD( "tms1400_tc4_opla.pla", 0, 557, CRC(3b908725) SHA1(f83bf5faa5b3cb51f87adc1639b00d6f9a71ad19) )
726ROM_END
727
728
72976ROM_START( ebball )
73077   ROM_REGION( 0x0400, "maincpu", 0 )
73178   ROM_LOAD( "mp0914", 0x0000, 0x0400, CRC(3c6fb05b) SHA1(b2fe4b3ca72d6b4c9bfa84d67f64afdc215e7178) )
r243822r243823
73784ROM_END
73885
73986
740ROM_START( comp4 )
741   ROM_REGION( 0x0400, "maincpu", 0 )
742   ROM_LOAD( "tmc0904nl_cp0904a", 0x0000, 0x0400, CRC(6233ee1b) SHA1(738e109b38c97804b4ec52bed80b00a8634ad453) )
743
744   ROM_REGION( 782, "maincpu:ipla", 0 )
745   ROM_LOAD( "tms0970_default_ipla.pla", 0, 782, CRC(e038fc44) SHA1(dfc280f6d0a5828d1bb14fcd59ac29caf2c2d981) )
746   ROM_REGION( 860, "maincpu:mpla", 0 )
747   ROM_LOAD( "tms0970_comp4_mpla.pla", 0, 860, CRC(ee9d7d9e) SHA1(25484e18f6a07f7cdb21a07220e2f2a82fadfe7b) )
748   ROM_REGION( 352, "maincpu:opla", 0 )
749   ROM_LOAD( "tms0970_comp4_opla.pla", 0, 352, CRC(a0f887d1) SHA1(3c666663d484d5bed81e1014f8715aab8a3d489f) )
750   ROM_REGION( 157, "maincpu:spla", 0 )
751   ROM_LOAD( "tms0970_comp4_spla.pla", 0, 157, CRC(e5bddd90) SHA1(4b1c6512c70e5bcd23c2dbf0c88cd8aa2c632a10) )
752ROM_END
753
754
755ROM_START( simon )
756   ROM_REGION( 0x0400, "maincpu", 0 )
757   ROM_LOAD( "tms1000.u1", 0x0000, 0x0400, CRC(9961719d) SHA1(35dddb018a8a2b31f377ab49c1f0cb76951b81c0) )
758
759   ROM_REGION( 867, "maincpu:mpla", 0 )
760   ROM_LOAD( "tms1000_simon_mpla.pla", 0, 867, CRC(52f7c1f1) SHA1(dbc2634dcb98eac173ad0209df487cad413d08a5) )
761   ROM_REGION( 365, "maincpu:opla", 0 )
762   ROM_LOAD( "tms1000_simon_opla.pla", 0, 365, CRC(2943c71b) SHA1(bd5bb55c57e7ba27e49c645937ec1d4e67506601) )
763ROM_END
764
765
766
767
768CONS( 1979, amaztron, 0, 0, amaztron, amaztron, driver_device, 0, "Coleco", "Amaze-A-Tron", GAME_SUPPORTS_SAVE )
769CONS( 1981, tc4, 0, 0, tc4, tc4, driver_device, 0, "Coleco", "Total Control 4", GAME_SUPPORTS_SAVE )
770
77187CONS( 1979, ebball, 0, 0, ebball, ebball, driver_device, 0, "Entex", "Baseball (Entex)", GAME_SUPPORTS_SAVE | GAME_NOT_WORKING )
772
773CONS( 1977, comp4, 0, 0, comp4, comp4, driver_device, 0, "Milton Bradley", "Comp IV", GAME_SUPPORTS_SAVE | GAME_NO_SOUND_HW )
774CONS( 1978, simon, 0, 0, simon, simon, driver_device, 0, "Milton Bradley", "Simon (Rev. A)", GAME_SUPPORTS_SAVE )
trunk/src/mess/drivers/pcd.c
r243822r243823
250250
251251   if((m_dskctl & 1) && floppy0)
252252      m_fdc->set_floppy(floppy0);
253   if((m_dskctl & 2) && floppy1)
254      m_fdc->set_floppy(floppy1);
255253
256254   if(floppy0)
257255   {
r243822r243823
294292   else
295293   {
296294      UINT8 data = m_charram[(m_vram[address] & 0xff) * 16 + linecount];
297      if(cursor && blink)
298         data = 0xff;
299295      for(int i = 0; i < 8; i++)
300296         bitmap.pix32(y, x + i) = m_palette->pen((data & (1 << (7 - i))) ? 1 : 0);
301297   }
r243822r243823
401397//**************************************************************************
402398
403399static ADDRESS_MAP_START( pcd_map, AS_PROGRAM, 16, pcd_state )
404   AM_RANGE(0x00000, 0x7ffff) AM_RAM // fixed 512k for now
400   AM_RANGE(0x00000, 0x3ffff) AM_RAM // fixed 256k for now
405401   AM_RANGE(0xf0000, 0xf7fff) AM_READONLY AM_WRITE(vram_w) AM_SHARE("vram")
406402   AM_RANGE(0xfc000, 0xfffff) AM_ROM AM_REGION("bios", 0)
407403   AM_RANGE(0x00000, 0xfffff) AM_READWRITE8(nmi_io_r, nmi_io_w, 0xffff)
r243822r243823
453449   MCFG_80186_TMROUT1_HANDLER(WRITELINE(pcd_state, i186_timer1_w))
454450   MCFG_80186_IRQ_SLAVE_ACK(READ8(pcd_state, irq_callback))
455451
456   MCFG_CPU_ADD("graphics", I8741, XTAL_16MHz/2)
457   MCFG_DEVICE_DISABLE()
458
459452   MCFG_TIMER_DRIVER_ADD_PERIODIC("timer0_tick", pcd_state, timer0_tick, attotime::from_hz(XTAL_16MHz / 24)) // adjusted to pass post
460453
461454   MCFG_PIC8259_ADD("pic1", DEVWRITELINE("maincpu", i80186_cpu_device, int0_w), VCC, NULL)
trunk/src/mess/drivers/simon.c
r0r243823
1// license:BSD-3-Clause
2// copyright-holders:hap
3/***************************************************************************
4
5  Milton Bradley Simon, created by Ralph Baer
6
7  Revision A hardware:
8  * TMS1000 (has internal ROM), DS75494 lamp driver
9
10  Newer revisions have a smaller 16-pin MB4850 chip instead of the TMS1000.
11  This one has been decapped too, but we couldn't find an internal ROM.
12  It is possibly a cost-reduced custom ASIC specifically for Simon.
13
14  Other games assumed to be on similar hardware:
15  - Pocket Simon, but there's a chance it only exists with MB4850 chip
16  - Super Simon (TMS1100)
17
18***************************************************************************/
19
20#include "emu.h"
21#include "cpu/tms0980/tms0980.h"
22#include "sound/speaker.h"
23
24#include "simon.lh" // clickable
25
26// master clock is a single stage RC oscillator: R=33K, C=100pf,
27// according to the TMS 1000 series data manual this is around 350kHz
28#define MASTER_CLOCK (350000)
29
30
31class simon_state : public driver_device
32{
33public:
34   simon_state(const machine_config &mconfig, device_type type, const char *tag)
35      : driver_device(mconfig, type, tag),
36      m_maincpu(*this, "maincpu"),
37      m_button_matrix(*this, "IN"),
38      m_speaker(*this, "speaker")
39   { }
40
41   required_device<cpu_device> m_maincpu;
42   required_ioport_array<4> m_button_matrix;
43   required_device<speaker_sound_device> m_speaker;
44
45   UINT16 m_r;
46
47   DECLARE_READ8_MEMBER(read_k);
48   DECLARE_WRITE16_MEMBER(write_o);
49   DECLARE_WRITE16_MEMBER(write_r);
50
51   virtual void machine_start();
52};
53
54
55/***************************************************************************
56
57  I/O
58
59***************************************************************************/
60
61READ8_MEMBER(simon_state::read_k)
62{
63   UINT8 k = 0;
64
65   // read selected button rows
66   for (int i = 0; i < 4; i++)
67   {
68      const int ki[4] = { 0, 1, 2, 9 };
69      if (m_r >> ki[i] & 1)
70         k |= m_button_matrix[i]->read();
71   }
72
73   return k;
74}
75
76WRITE16_MEMBER(simon_state::write_r)
77{
78   // R4-R8 go through an 75494 IC first:
79   // R4 -> 75494 IN6 -> green lamp
80   // R5 -> 75494 IN3 -> red lamp
81   // R6 -> 75494 IN5 -> yellow lamp
82   // R7 -> 75494 IN2 -> blue lamp
83   for (int i = 0; i < 4; i++)
84      output_set_lamp_value(i, data >> (4 + i) & 1);
85
86   // R8 -> 75494 IN0 -> speaker
87   m_speaker->level_w(data >> 8 & 1);
88
89   // R0,R1,R2,R9: input mux
90   // R3: GND
91   // other bits: N/C
92   m_r = data;
93}
94
95WRITE16_MEMBER(simon_state::write_o)
96{
97   // N/C
98}
99
100
101
102/***************************************************************************
103
104  Inputs
105
106***************************************************************************/
107
108static INPUT_PORTS_START( simon )
109   PORT_START("IN.0") // R0
110   PORT_CONFNAME( 0x07, 0x02, "Game Select")
111   PORT_CONFSETTING(    0x02, "1" )
112   PORT_CONFSETTING(    0x01, "2" )
113   PORT_CONFSETTING(    0x04, "3" )
114   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
115
116   PORT_START("IN.1") // R1
117   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Green Button")
118   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Red Button")
119   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("Yellow Button")
120   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_NAME("Blue Button")
121
122   PORT_START("IN.2") // R2
123   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("Start")
124   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Last")
125   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Longest")
126   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
127
128   PORT_START("IN.3") // R9
129   PORT_CONFNAME( 0x0f, 0x01, "Skill Level")
130   PORT_CONFSETTING(    0x02, "1" )
131   PORT_CONFSETTING(    0x04, "2" )
132   PORT_CONFSETTING(    0x08, "3" )
133   PORT_CONFSETTING(    0x01, "4" )
134INPUT_PORTS_END
135
136
137
138/***************************************************************************
139
140  Machine Config
141
142***************************************************************************/
143
144void simon_state::machine_start()
145{
146   m_r = 0;
147   save_item(NAME(m_r));
148}
149
150
151static MACHINE_CONFIG_START( simon, simon_state )
152
153   /* basic machine hardware */
154   MCFG_CPU_ADD("maincpu", TMS1000, MASTER_CLOCK)
155   MCFG_TMS1XXX_READ_K_CB(READ8(simon_state, read_k))
156   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(simon_state, write_o))
157   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(simon_state, write_r))
158
159   MCFG_DEFAULT_LAYOUT(layout_simon)
160
161   /* no video! */
162
163   /* sound hardware */
164   MCFG_SPEAKER_STANDARD_MONO("mono")
165   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
166   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
167MACHINE_CONFIG_END
168
169
170
171/***************************************************************************
172
173  Game driver(s)
174
175***************************************************************************/
176
177ROM_START( simon )
178   ROM_REGION( 0x0400, "maincpu", 0 )
179   ROM_LOAD( "tms1000.u1", 0x0000, 0x0400, CRC(9961719d) SHA1(35dddb018a8a2b31f377ab49c1f0cb76951b81c0) )
180
181   ROM_REGION( 867, "maincpu:mpla", 0 )
182   ROM_LOAD( "tms1000_simon_mpla.pla", 0, 867, CRC(52f7c1f1) SHA1(dbc2634dcb98eac173ad0209df487cad413d08a5) )
183   ROM_REGION( 365, "maincpu:opla", 0 )
184   ROM_LOAD( "tms1000_simon_opla.pla", 0, 365, CRC(2943c71b) SHA1(bd5bb55c57e7ba27e49c645937ec1d4e67506601) )
185ROM_END
186
187
188CONS( 1978, simon, 0, 0, simon, simon, driver_device, 0, "Milton Bradley", "Simon (Rev. A)", GAME_SUPPORTS_SAVE )
trunk/src/mess/drivers/tc4.c
r0r243823
1// license:BSD-3-Clause
2// copyright-holders:hap
3/***************************************************************************
4
5  Coleco Total Control 4
6  * TMS1400NLL MP7334-N2 (die labeled MP7334)
7
8  This is a head to head electronic tabletop LED-display sports console.
9  One cartridge(Football) was included with the console, the other three were
10  sold separately. Gameplay has emphasis on strategy, read the official manual
11  on how to play. Remember that you can rotate the view in MESS: rotate left
12  for Home(P1) orientation, rotate right for Visitor(P2) orientation.
13
14  Cartridge socket:
15  1 N/C
16  2 9V+
17  3 power switch
18  4 K8
19  5 K4
20  6 K2
21  7 K1
22  8 R9
23
24  The cartridge connects pin 8 with one of the K-pins.
25
26  Available cartridges:
27  - Football    (K8, confirmed)
28  - Hockey      (K4?)
29  - Soccer      (K2?)
30  - Basketball  (K1?)
31
32
33  TODO:
34  - pin configuration of other carts is guessed
35  - softlist for the cartridges?
36  - offsensive players leds are supposed to look brighter
37  - MCU clock is unknown
38
39***************************************************************************/
40
41#include "emu.h"
42#include "cpu/tms0980/tms0980.h"
43#include "sound/speaker.h"
44
45#include "tc4.lh"
46
47// The master clock is a single stage RC oscillator: R=27.3K, C=100pf.
48// TMS1400 RC curve is unknown, so let's do an approximation until it is.
49#define MASTER_CLOCK (450000)
50
51
52class tc4_state : public driver_device
53{
54public:
55   tc4_state(const machine_config &mconfig, device_type type, const char *tag)
56      : driver_device(mconfig, type, tag),
57      m_maincpu(*this, "maincpu"),
58      m_button_matrix(*this, "IN"),
59      m_speaker(*this, "speaker")
60   { }
61
62   required_device<cpu_device> m_maincpu;
63   required_ioport_array<7> m_button_matrix;
64   required_device<speaker_sound_device> m_speaker;
65
66   UINT16 m_r;
67   UINT16 m_o;
68
69   UINT16 m_display_state[0x10];
70   UINT16 m_display_cache[0x10];
71   UINT8 m_display_decay[0x100];
72
73   DECLARE_READ8_MEMBER(read_k);
74   DECLARE_WRITE16_MEMBER(write_o);
75   DECLARE_WRITE16_MEMBER(write_r);
76
77   TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick);
78   bool index_is_7segled(int index);
79   void display_update();
80
81   virtual void machine_start();
82};
83
84
85
86/***************************************************************************
87
88  LED Display
89
90***************************************************************************/
91
92// The device strobes the outputs very fast, it is unnoticeable to the user.
93// To prevent flickering here, we need to simulate a decay.
94
95// decay time, in steps of 1ms
96#define DISPLAY_DECAY_TIME 50
97
98inline bool tc4_state::index_is_7segled(int index)
99{
100   // R5,7,8,9 are 7segs
101   return (index >= 5 && index <= 9 && index != 6);
102}
103
104void tc4_state::display_update()
105{
106   UINT16 active_state[0x10];
107
108   for (int i = 0; i < 0x10; i++)
109   {
110      // update current state (note: R6 as extra column!)
111      m_display_state[i] = (m_r >> i & 1) ? (m_o | (m_r << 2 & 0x100)) : 0;
112
113      active_state[i] = 0;
114
115      for (int j = 0; j < 0x10; j++)
116      {
117         int di = j << 4 | i;
118
119         // turn on powered segments
120         if (m_display_state[i] >> j & 1)
121            m_display_decay[di] = DISPLAY_DECAY_TIME;
122
123         // determine active state
124         int ds = (m_display_decay[di] != 0) ? 1 : 0;
125         active_state[i] |= (ds << j);
126      }
127   }
128
129   // on difference, send to output
130   for (int i = 0; i < 0x10; i++)
131      if (m_display_cache[i] != active_state[i])
132      {
133         if (index_is_7segled(i))
134            output_set_digit_value(i, active_state[i] & 0x7f);
135
136         for (int j = 0; j < 9; j++)
137            output_set_lamp_value(i*10 + j, active_state[i] >> j & 1);
138      }
139
140   memcpy(m_display_cache, active_state, sizeof(m_display_cache));
141}
142
143TIMER_DEVICE_CALLBACK_MEMBER(tc4_state::display_decay_tick)
144{
145   // slowly turn off unpowered segments
146   for (int i = 0; i < 0x100; i++)
147      if (!(m_display_state[i & 0xf] >> (i>>4) & 1) && m_display_decay[i])
148         m_display_decay[i]--;
149
150   display_update();
151}
152
153
154
155/***************************************************************************
156
157  I/O
158
159***************************************************************************/
160
161READ8_MEMBER(tc4_state::read_k)
162{
163   UINT8 k = 0;
164
165   // read selected button rows
166   for (int i = 0; i < 6; i++)
167      if (m_r >> i & 1)
168         k |= m_button_matrix[i]->read();
169
170   // read from cartridge
171   if (m_r & 0x200)
172      k |= m_button_matrix[6]->read();
173
174   return k;
175}
176
177WRITE16_MEMBER(tc4_state::write_o)
178{
179   // O0-O7: leds/7segment
180   m_o = data;
181   display_update();
182}
183
184WRITE16_MEMBER(tc4_state::write_r)
185{
186   // R10: speaker out
187   m_speaker->level_w(data >> 10 & 1);
188
189   // R0-R5: input mux
190   // R6: led column 8
191   // R9: to cartridge slot
192   // +other: select leds
193   m_r = data & 0x3ff;
194   display_update();
195}
196
197
198
199/***************************************************************************
200
201  Inputs
202
203***************************************************************************/
204
205static INPUT_PORTS_START( tc4 )
206   PORT_START("IN.0") // R0
207   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P1 Pass/Shoot Button 3") // right
208   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Pass/Shoot Button 1") // left
209   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Pass/Shoot Button 2") // middle
210   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("P1 D/K Button")
211
212   PORT_START("IN.1") // R1
213   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_RIGHT )
214   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_LEFT )
215   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_UP )
216   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_DOWN )
217
218   PORT_START("IN.2") // R2
219   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_RIGHT )
220   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_LEFT )
221   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_UP )
222   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_DOWN )
223
224   PORT_START("IN.3") // R3
225   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_RIGHT ) PORT_PLAYER(2)
226   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_LEFT ) PORT_PLAYER(2)
227   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_UP ) PORT_PLAYER(2)
228   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_DOWN ) PORT_PLAYER(2)
229
230   PORT_START("IN.4") // R4
231   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_RIGHT ) PORT_PLAYER(2)
232   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_LEFT ) PORT_PLAYER(2)
233   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_UP ) PORT_PLAYER(2)
234   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_DOWN ) PORT_PLAYER(2)
235
236   PORT_START("IN.5") // R5
237   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Pass/Shoot Button 3") // right
238   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Pass/Shoot Button 1") // left
239   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Pass/Shoot Button 2") // middle
240   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_NAME("P2 D/K Button")
241
242   PORT_START("IN.6") // R9
243   PORT_CONFNAME( 0x0f, 0x08, "Cartridge")
244   PORT_CONFSETTING(    0x01, "Basketball" )
245   PORT_CONFSETTING(    0x02, "Soccer" )
246   PORT_CONFSETTING(    0x04, "Hockey" )
247   PORT_CONFSETTING(    0x08, "Football" )
248INPUT_PORTS_END
249
250
251
252/***************************************************************************
253
254  Machine Config
255
256***************************************************************************/
257
258void tc4_state::machine_start()
259{
260   // zerofill
261   memset(m_display_state, 0, sizeof(m_display_state));
262   memset(m_display_cache, 0, sizeof(m_display_cache));
263   memset(m_display_decay, 0, sizeof(m_display_decay));
264
265   m_r = 0;
266   m_o = 0;
267
268   // register for savestates
269   save_item(NAME(m_display_state));
270   save_item(NAME(m_display_cache));
271   save_item(NAME(m_display_decay));
272
273   save_item(NAME(m_r));
274   save_item(NAME(m_o));
275}
276
277
278static MACHINE_CONFIG_START( tc4, tc4_state )
279
280   /* basic machine hardware */
281   MCFG_CPU_ADD("maincpu", TMS1400, MASTER_CLOCK)
282   MCFG_TMS1XXX_READ_K_CB(READ8(tc4_state, read_k))
283   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(tc4_state, write_o))
284   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(tc4_state, write_r))
285
286   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", tc4_state, display_decay_tick, attotime::from_msec(1))
287
288   MCFG_DEFAULT_LAYOUT(layout_tc4)
289
290   /* no video! */
291
292   /* sound hardware */
293   MCFG_SPEAKER_STANDARD_MONO("mono")
294   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
295   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
296MACHINE_CONFIG_END
297
298
299
300/***************************************************************************
301
302  Game driver(s)
303
304***************************************************************************/
305
306ROM_START( tc4 )
307   ROM_REGION( 0x1000, "maincpu", 0 )
308   ROM_LOAD( "tms1400nll_mp7334", 0x0000, 0x1000, CRC(923f3821) SHA1(a9ae342d7ff8dae1dedcd1e4984bcfae68586581) )
309
310   ROM_REGION( 867, "maincpu:mpla", 0 )
311   ROM_LOAD( "tms1100_default_mpla.pla", 0, 867, CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) )
312   ROM_REGION( 557, "maincpu:opla", 0 )
313   ROM_LOAD( "tms1400_tc4_opla.pla", 0, 557, CRC(3b908725) SHA1(f83bf5faa5b3cb51f87adc1639b00d6f9a71ad19) )
314ROM_END
315
316
317CONS( 1981, tc4, 0, 0, tc4, tc4, driver_device, 0, "Coleco", "Total Control 4", GAME_SUPPORTS_SAVE )
trunk/src/mess/layout/amaztron.lay
r243822r243823
2323   <view name="Internal Layout">
2424      <bounds left="0" right="50" top="0" bottom="15" />
2525
26      <bezel name="lamp20" element="lamp_red"><bounds x="3.5" y="6" width="3" height="3" /></bezel>
27      <bezel name="lamp21" element="lamp_green"><bounds x="13.5" y="6" width="3" height="3" /></bezel>
26      <bezel name="lamp0" element="lamp_red"><bounds x="3.5" y="6" width="3" height="3" /></bezel>
27      <bezel name="lamp1" element="lamp_green"><bounds x="13.5" y="6" width="3" height="3" /></bezel>
2828
2929      <bezel name="digit1" element="digit"><bounds x="30" y="0" width="10" height="15" /></bezel>
3030      <bezel name="digit0" element="digit"><bounds x="40" y="0" width="10" height="15" /></bezel>
trunk/src/mess/mess.mak
r243822r243823
11311131   $(MESS_DRIVERS)/adam.o      \
11321132   $(MESS_DRIVERS)/coleco.o    \
11331133   $(MESS_MACHINE)/coleco.o    \
1134   $(MESS_DRIVERS)/amaztron.o  \
1135   $(MESS_DRIVERS)/tc4.o       \
11341136
11351137$(MESSOBJ)/cromemco.a:          \
11361138   $(MESS_DRIVERS)/c10.o       \
r243822r243823
13831385   $(MESS_DRIVERS)/myb3k.o     \
13841386
13851387$(MESSOBJ)/mb.a:                \
1388   $(MESS_DRIVERS)/comp4.o     \
13861389   $(MESS_DRIVERS)/microvsn.o  \
1390   $(MESS_DRIVERS)/simon.o     \
13871391
13881392$(MESSOBJ)/mchester.a:          \
13891393   $(MESS_DRIVERS)/ssem.o      \
r243822r243823
21422146$(MESS_DRIVERS)/gamecom.o:  $(MESS_LAYOUT)/gamecom.lh
21432147$(MESS_DRIVERS)/glasgow.o:  $(MESS_LAYOUT)/glasgow.lh
21442148$(MESS_DRIVERS)/h8.o:       $(MESS_LAYOUT)/h8.lh
2145$(MESS_DRIVERS)/hh_tms1k.o: $(MESS_LAYOUT)/amaztron.lh \
2146                            $(MESS_LAYOUT)/comp4.lh \
2147                            $(MESS_LAYOUT)/ebball.lh \
2148                            $(MESS_LAYOUT)/simon.lh \
2149                            $(MESS_LAYOUT)/tc4.lh
2149$(MESS_DRIVERS)/hh_tms1k.o: $(MESS_LAYOUT)/ebball.lh
21502150$(MESS_DRIVERS)/ie15.o:     $(MESS_LAYOUT)/ie15.lh
21512151$(MESS_DRIVERS)/instruct.o: $(MESS_LAYOUT)/instruct.lh
21522152$(MESS_DRIVERS)/k1003.o:    $(MESS_LAYOUT)/k1003.lh
trunk/src/osd/windows/video.c
r243822r243823
8383   // create the windows
8484   windows_options &options = downcast<windows_options &>(machine().options());
8585   for (index = 0; index < video_config.numscreens; index++)
86      winwindow_video_window_create(machine(), index, pick_monitor(options, index), &windows[index]);
86      win_window_info::create(machine(), index, pick_monitor(options, index), &windows[index]);
8787   if (video_config.mode != VIDEO_MODE_NONE)
8888      SetForegroundWindow(win_window_list->m_hwnd);
8989
trunk/src/osd/windows/window.c
r243822r243823
120120//  PROTOTYPES
121121//============================================================
122122
123static void winwindow_video_window_destroy(win_window_info *window);
124123
125static unsigned __stdcall thread_entry(void *param);
126static int complete_create(win_window_info *window);
127124static void create_window_class(void);
128static void set_starting_view(int index, win_window_info *window, const char *view);
129125
130static void constrain_to_aspect_ratio(win_window_info *window, RECT *rect, int adjustment);
131static void get_min_bounds(win_window_info *window, RECT *bounds, int constrain);
132static void get_max_bounds(win_window_info *window, RECT *bounds, int constrain);
133static void update_minmax_state(win_window_info *window);
134static void minimize_window(win_window_info *window);
135static void maximize_window(win_window_info *window);
136
137static void adjust_window_position_after_major_change(win_window_info *window);
138static void set_fullscreen(win_window_info *window, int fullscreen);
139
140
141126// temporary hacks
142127#if LOG_THREADS
143128struct mtlog
r243822r243823
213198         fatalerror("Failed to create window thread ready event\n");
214199
215200      // create a thread to run the windows from
216      temp = _beginthreadex(NULL, 0, thread_entry, NULL, 0, (unsigned *)&window_threadid);
201      temp = _beginthreadex(NULL, 0, win_window_info::thread_entry, NULL, 0, (unsigned *)&window_threadid);
217202      window_thread = (HANDLE)temp;
218203      if (window_thread == NULL)
219204         fatalerror("Failed to create window thread\n");
r243822r243823
272257   {
273258      win_window_info *temp = win_window_list;
274259      win_window_list = temp->m_next;
275      winwindow_video_window_destroy(temp);
260      temp->destroy();
261      global_free(temp);
262
276263   }
277264
278265   // kill the drawers
r243822r243823
659646//  (main thread)
660647//============================================================
661648
662void winwindow_video_window_create(running_machine &machine, int index, win_monitor_info *monitor, const osd_window_config *config)
649void win_window_info::create(running_machine &machine, int index, win_monitor_info *monitor, const osd_window_config *config)
663650{
664651   win_window_info *window, *win;
665652
r243822r243823
690677
691678   // set the specific view
692679   windows_options &options = downcast<windows_options &>(machine.options());
693   set_starting_view(index, window, options.view(index));
680   window->set_starting_view(index, options.view(index));
694681
695682   // remember the current values in case they change
696683   window->m_targetview = window->m_target->view();
r243822r243823
720707      }
721708   }
722709   else
723      window->m_init_state = complete_create(window) ? -1 : 1;
710      window->m_init_state = window->complete_create() ? -1 : 1;
724711
725712   // handle error conditions
726713   if (window->m_init_state == -1)
r243822r243823
734721//  (main thread)
735722//============================================================
736723
737static void winwindow_video_window_destroy(win_window_info *window)
724void win_window_info::destroy()
738725{
739726   win_window_info **prevptr;
740727
r243822r243823
742729
743730   // remove us from the list
744731   for (prevptr = &win_window_list; *prevptr != NULL; prevptr = &(*prevptr)->m_next)
745      if (*prevptr == window)
732      if (*prevptr == this)
746733      {
747         *prevptr = window->m_next;
734         *prevptr = this->m_next;
748735         break;
749736      }
750737
751738   // destroy the window
752   if (window->m_hwnd != NULL)
753      SendMessage(window->m_hwnd, WM_USER_SELF_TERMINATE, 0, 0);
739   if (m_hwnd != NULL)
740      SendMessage(m_hwnd, WM_USER_SELF_TERMINATE, 0, 0);
754741
755742   // free the render target
756   window->machine().render().target_free(window->m_target);
743   machine().render().target_free(m_target);
757744
745   // FIXME: move to destructor
758746   // free the lock
759   osd_lock_free(window->m_render_lock);
747   osd_lock_free(m_render_lock);
760748
761   // free the window itself
762   global_free(window);
763749}
764750
765751
r243822r243823
905891//  (main thread)
906892//============================================================
907893
908static void set_starting_view(int index, win_window_info *window, const char *view)
894void win_window_info::set_starting_view(int index, const char *view)
909895{
910   const char *defview = downcast<windows_options &>(window->machine().options()).view();
896   const char *defview = downcast<windows_options &>(machine().options()).view();
911897   int viewindex;
912898
913899   assert(GetCurrentThreadId() == main_threadid);
r243822r243823
917903      view = defview;
918904
919905   // query the video system to help us pick a view
920   viewindex = window->m_target->configured_view(view, index, video_config.numscreens);
906   viewindex = m_target->configured_view(view, index, video_config.numscreens);
921907
922908   // set the view
923   window->m_target->set_view(viewindex);
909   m_target->set_view(viewindex);
924910}
925911
926912
r243822r243823
10371023//  (window thread)
10381024//============================================================
10391025
1040INLINE int wnd_extra_width(win_window_info *window)
1026int win_window_info::wnd_extra_width()
10411027{
10421028   RECT temprect = { 100, 100, 200, 200 };
1043   if (window->m_fullscreen)
1029   if (m_fullscreen)
10441030      return 0;
1045   AdjustWindowRectEx(&temprect, WINDOW_STYLE, window->win_has_menu(), WINDOW_STYLE_EX);
1031   AdjustWindowRectEx(&temprect, WINDOW_STYLE, win_has_menu(), WINDOW_STYLE_EX);
10461032   return rect_width(&temprect) - 100;
10471033}
10481034
r243822r243823
10531039//  (window thread)
10541040//============================================================
10551041
1056INLINE int wnd_extra_height(win_window_info *window)
1042int win_window_info::wnd_extra_height()
10571043{
10581044   RECT temprect = { 100, 100, 200, 200 };
1059   if (window->m_fullscreen)
1045   if (m_fullscreen)
10601046      return 0;
1061   AdjustWindowRectEx(&temprect, WINDOW_STYLE, window->win_has_menu(), WINDOW_STYLE_EX);
1047   AdjustWindowRectEx(&temprect, WINDOW_STYLE, win_has_menu(), WINDOW_STYLE_EX);
10621048   return rect_height(&temprect) - 100;
10631049}
10641050
r243822r243823
10691055//  (window thread)
10701056//============================================================
10711057
1072static unsigned __stdcall thread_entry(void *param)
1058unsigned __stdcall win_window_info::thread_entry(void *param)
10731059{
10741060   MSG message;
10751061
r243822r243823
11411127            case WM_USER_FINISH_CREATE_WINDOW:
11421128            {
11431129               win_window_info *window = (win_window_info *)message.lParam;
1144               window->m_init_state = complete_create(window) ? -1 : 1;
1130               window->m_init_state = window->complete_create() ? -1 : 1;
11451131               dispatch = FALSE;
11461132               break;
11471133            }
r243822r243823
11651151//  (window thread)
11661152//============================================================
11671153
1168static int complete_create(win_window_info *window)
1154int win_window_info::complete_create()
11691155{
11701156   RECT monitorbounds, client;
11711157   int tempwidth, tempheight;
r243822r243823
11751161   assert(GetCurrentThreadId() == window_threadid);
11761162
11771163   // get the monitor bounds
1178   monitorbounds = window->m_monitor->position_size();
1164   monitorbounds = m_monitor->position_size();
11791165
11801166   // create the window menu if needed
1181   if (downcast<windows_options &>(window->machine().options()).menu())
1167   if (downcast<windows_options &>(machine().options()).menu())
11821168   {
1183      if (win_create_menu(window->machine(), &menu))
1169      if (win_create_menu(machine(), &menu))
11841170         return 1;
11851171   }
11861172
11871173   // create the window, but don't show it yet
1188   window->m_hwnd = win_create_window_ex_utf8(
1189                  window->m_fullscreen ? FULLSCREEN_STYLE_EX : WINDOW_STYLE_EX,
1174   m_hwnd = win_create_window_ex_utf8(
1175                  m_fullscreen ? FULLSCREEN_STYLE_EX : WINDOW_STYLE_EX,
11901176                  "MAME",
1191                  window->m_title,
1192                  window->m_fullscreen ? FULLSCREEN_STYLE : WINDOW_STYLE,
1177                  m_title,
1178                  m_fullscreen ? FULLSCREEN_STYLE : WINDOW_STYLE,
11931179                  monitorbounds.left + 20, monitorbounds.top + 20,
11941180                  monitorbounds.left + 100, monitorbounds.top + 100,
11951181                  NULL,//(win_window_list != NULL) ? win_window_list->m_hwnd : NULL,
11961182                  menu,
11971183                  GetModuleHandle(NULL),
11981184                  NULL);
1199   if (window->m_hwnd == NULL)
1185   if (m_hwnd == NULL)
12001186      return 1;
12011187
12021188   // set window #0 as the focus window for all windows, required for D3D & multimonitor
1203   window->m_focus_hwnd = win_window_list->m_hwnd;
1189   m_focus_hwnd = win_window_list->m_hwnd;
12041190
12051191   // set a pointer back to us
1206   SetWindowLongPtr(window->m_hwnd, GWLP_USERDATA, (LONG_PTR)window);
1192   SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG_PTR)this);
12071193
12081194   // skip the positioning stuff for -video none */
12091195   if (video_config.mode == VIDEO_MODE_NONE)
12101196      return 0;
12111197
12121198   // adjust the window position to the initial width/height
1213   tempwidth = (window->m_win_config.width != 0) ? window->m_win_config.width : 640;
1214   tempheight = (window->m_win_config.height != 0) ? window->m_win_config.height : 480;
1215   SetWindowPos(window->m_hwnd, NULL, monitorbounds.left + 20, monitorbounds.top + 20,
1216         monitorbounds.left + tempwidth + wnd_extra_width(window),
1217         monitorbounds.top + tempheight + wnd_extra_height(window),
1199   tempwidth = (m_win_config.width != 0) ? m_win_config.width : 640;
1200   tempheight = (m_win_config.height != 0) ? m_win_config.height : 480;
1201   SetWindowPos(m_hwnd, NULL, monitorbounds.left + 20, monitorbounds.top + 20,
1202         monitorbounds.left + tempwidth + wnd_extra_width(),
1203         monitorbounds.top + tempheight + wnd_extra_height(),
12181204         SWP_NOZORDER);
12191205
12201206   // maximum or minimize as appropriate
1221   if (window->m_startmaximized)
1222      maximize_window(window);
1207   if (m_startmaximized)
1208      maximize_window();
12231209   else
1224      minimize_window(window);
1225   adjust_window_position_after_major_change(window);
1210      minimize_window();
1211   adjust_window_position_after_major_change();
12261212
12271213   // show the window
1228   if (!window->m_fullscreen || window->m_fullscreen_safe)
1214   if (!m_fullscreen || m_fullscreen_safe)
12291215   {
12301216      // finish off by trying to initialize DirectX; if we fail, ignore it
1231      window->m_renderer = draw.create(window);
1232      if (window->m_renderer->create())
1217      m_renderer = draw.create(this);
1218      if (m_renderer->create())
12331219         return 1;
1234      ShowWindow(window->m_hwnd, SW_SHOW);
1220      ShowWindow(m_hwnd, SW_SHOW);
12351221   }
12361222
12371223   // clear the window
1238   dc = GetDC(window->m_hwnd);
1239   GetClientRect(window->m_hwnd, &client);
1224   dc = GetDC(m_hwnd);
1225   GetClientRect(m_hwnd, &client);
12401226   FillRect(dc, &client, (HBRUSH)GetStockObject(BLACK_BRUSH));
1241   ReleaseDC(window->m_hwnd, dc);
1227   ReleaseDC(m_hwnd, dc);
12421228   return 0;
12431229}
12441230
r243822r243823
12581244   if (window != NULL)
12591245   {
12601246      assert(GetCurrentThreadId() == window_threadid);
1261      update_minmax_state(window);
1247      window->update_minmax_state();
12621248   }
12631249
12641250   // handle a few messages
r243822r243823
13601346      {
13611347         RECT *rect = (RECT *)lparam;
13621348         if (video_config.keepaspect && !(GetAsyncKeyState(VK_CONTROL) & 0x8000))
1363            constrain_to_aspect_ratio(window, rect, wparam);
1349            window->constrain_to_aspect_ratio(rect, wparam);
13641350         InvalidateRect(wnd, NULL, FALSE);
13651351         break;
13661352      }
r243822r243823
13801366         // handle maximize
13811367         if (cmd == SC_MAXIMIZE)
13821368         {
1383            update_minmax_state(window);
1369            window->update_minmax_state();
13841370            if (window->m_ismaximized)
1385               minimize_window(window);
1371               window->minimize_window();
13861372            else
1387               maximize_window(window);
1373               window->maximize_window();
13881374            break;
13891375         }
13901376         return DefWindowProc(wnd, message, wparam, lparam);
r243822r243823
14351421
14361422      // fullscreen set
14371423      case WM_USER_SET_FULLSCREEN:
1438         set_fullscreen(window, wparam);
1424         window->set_fullscreen(wparam);
14391425         break;
14401426
14411427      // minimum size set
14421428      case WM_USER_SET_MINSIZE:
1443         minimize_window(window);
1429         window->minimize_window();
14441430         break;
14451431
14461432      // maximum size set
14471433      case WM_USER_SET_MAXSIZE:
1448         maximize_window(window);
1434         window->maximize_window();
14491435         break;
14501436
14511437      // set focus: if we're not the primary window, switch back
r243822r243823
15141500//  (window thread)
15151501//============================================================
15161502
1517static void constrain_to_aspect_ratio(win_window_info *window, RECT *rect, int adjustment)
1503void win_window_info::constrain_to_aspect_ratio(RECT *rect, int adjustment)
15181504{
1519   win_monitor_info *monitor = window->winwindow_video_window_monitor(rect);
1520   INT32 extrawidth = wnd_extra_width(window);
1521   INT32 extraheight = wnd_extra_height(window);
1505   win_monitor_info *monitor = winwindow_video_window_monitor(rect);
1506   INT32 extrawidth = wnd_extra_width();
1507   INT32 extraheight = wnd_extra_height();
15221508   INT32 propwidth, propheight;
15231509   INT32 minwidth, minheight;
15241510   INT32 maxwidth, maxheight;
r243822r243823
15411527   {
15421528      case WMSZ_BOTTOM:
15431529      case WMSZ_TOP:
1544         window->m_target->compute_visible_area(10000, propheight, pixel_aspect, window->m_target->orientation(), propwidth, propheight);
1530         m_target->compute_visible_area(10000, propheight, pixel_aspect, m_target->orientation(), propwidth, propheight);
15451531         break;
15461532
15471533      case WMSZ_LEFT:
15481534      case WMSZ_RIGHT:
1549         window->m_target->compute_visible_area(propwidth, 10000, pixel_aspect, window->m_target->orientation(), propwidth, propheight);
1535         m_target->compute_visible_area(propwidth, 10000, pixel_aspect, m_target->orientation(), propwidth, propheight);
15501536         break;
15511537
15521538      default:
1553         window->m_target->compute_visible_area(propwidth, propheight, pixel_aspect, window->m_target->orientation(), propwidth, propheight);
1539         m_target->compute_visible_area(propwidth, propheight, pixel_aspect, m_target->orientation(), propwidth, propheight);
15541540         break;
15551541   }
15561542
15571543   // get the minimum width/height for the current layout
1558   window->m_target->compute_minimum_size(minwidth, minheight);
1544   m_target->compute_minimum_size(minwidth, minheight);
15591545
15601546   // clamp against the absolute minimum
15611547   propwidth = MAX(propwidth, MIN_WINDOW_DIM);
r243822r243823
15661552   propheight = MAX(propheight, minheight);
15671553
15681554   // clamp against the maximum (fit on one screen for full screen mode)
1569   if (window->m_fullscreen)
1555   if (m_fullscreen)
15701556   {
15711557      maxwidth = rect_width(&monitor->position_size()) - extrawidth;
15721558      maxheight = rect_height(&monitor->position_size()) - extraheight;
r243822r243823
15771563      maxheight = rect_height(&monitor->usuable_position_size()) - extraheight;
15781564
15791565      // further clamp to the maximum width/height in the window
1580      if (window->m_win_config.width != 0)
1581         maxwidth = MIN(maxwidth, window->m_win_config.width + extrawidth);
1582      if (window->m_win_config.height != 0)
1583         maxheight = MIN(maxheight, window->m_win_config.height + extraheight);
1566      if (m_win_config.width != 0)
1567         maxwidth = MIN(maxwidth, m_win_config.width + extrawidth);
1568      if (m_win_config.height != 0)
1569         maxheight = MIN(maxheight, m_win_config.height + extraheight);
15841570   }
15851571
15861572   // clamp to the maximum
r243822r243823
15881574   propheight = MIN(propheight, maxheight);
15891575
15901576   // compute the visible area based on the proposed rectangle
1591   window->m_target->compute_visible_area(propwidth, propheight, pixel_aspect, window->m_target->orientation(), viswidth, visheight);
1577   m_target->compute_visible_area(propwidth, propheight, pixel_aspect, m_target->orientation(), viswidth, visheight);
15921578
15931579   // compute the adjustments we need to make
15941580   adjwidth = (viswidth + extrawidth) - rect_width(rect);
r243822r243823
16301616//  (window thread)
16311617//============================================================
16321618
1633static void get_min_bounds(win_window_info *window, RECT *bounds, int constrain)
1619void win_window_info::get_min_bounds(RECT *bounds, int constrain)
16341620{
16351621   INT32 minwidth, minheight;
16361622
16371623   assert(GetCurrentThreadId() == window_threadid);
16381624
16391625   // get the minimum target size
1640   window->m_target->compute_minimum_size(minwidth, minheight);
1626   m_target->compute_minimum_size(minwidth, minheight);
16411627
16421628   // expand to our minimum dimensions
16431629   if (minwidth < MIN_WINDOW_DIM)
r243822r243823
16461632      minheight = MIN_WINDOW_DIM;
16471633
16481634   // account for extra window stuff
1649   minwidth += wnd_extra_width(window);
1650   minheight += wnd_extra_height(window);
1635   minwidth += wnd_extra_width();
1636   minheight += wnd_extra_height();
16511637
16521638   // if we want it constrained, figure out which one is larger
16531639   if (constrain)
r243822r243823
16581644      test1.top = test1.left = 0;
16591645      test1.right = minwidth;
16601646      test1.bottom = 10000;
1661      constrain_to_aspect_ratio(window, &test1, WMSZ_BOTTOMRIGHT);
1647      constrain_to_aspect_ratio(&test1, WMSZ_BOTTOMRIGHT);
16621648
16631649      // then constrain with no width limit
16641650      test2.top = test2.left = 0;
16651651      test2.right = 10000;
16661652      test2.bottom = minheight;
1667      constrain_to_aspect_ratio(window, &test2, WMSZ_BOTTOMRIGHT);
1653      constrain_to_aspect_ratio(&test2, WMSZ_BOTTOMRIGHT);
16681654
16691655      // pick the larger
16701656      if (rect_width(&test1) > rect_width(&test2))
r243822r243823
16801666   }
16811667
16821668   // get the window rect
1683   GetWindowRect(window->m_hwnd, bounds);
1669   GetWindowRect(m_hwnd, bounds);
16841670
16851671   // now adjust
16861672   bounds->right = bounds->left + minwidth;
r243822r243823
16941680//  (window thread)
16951681//============================================================
16961682
1697static void get_max_bounds(win_window_info *window, RECT *bounds, int constrain)
1683void win_window_info::get_max_bounds(RECT *bounds, int constrain)
16981684{
16991685   RECT maximum;
17001686
17011687   assert(GetCurrentThreadId() == window_threadid);
17021688
17031689   // compute the maximum client area
1704   window->m_monitor->refresh();
1705   maximum = window->m_monitor->usuable_position_size();
1690   m_monitor->refresh();
1691   maximum = m_monitor->usuable_position_size();
17061692
17071693   // clamp to the window's max
1708   if (window->m_win_config.width != 0)
1694   if (m_win_config.width != 0)
17091695   {
1710      int temp = window->m_win_config.width + wnd_extra_width(window);
1696      int temp = m_win_config.width + wnd_extra_width();
17111697      if (temp < rect_width(&maximum))
17121698         maximum.right = maximum.left + temp;
17131699   }
1714   if (window->m_win_config.height != 0)
1700   if (m_win_config.height != 0)
17151701   {
1716      int temp = window->m_win_config.height + wnd_extra_height(window);
1702      int temp = m_win_config.height + wnd_extra_height();
17171703      if (temp < rect_height(&maximum))
17181704         maximum.bottom = maximum.top + temp;
17191705   }
17201706
17211707   // constrain to fit
17221708   if (constrain)
1723      constrain_to_aspect_ratio(window, &maximum, WMSZ_BOTTOMRIGHT);
1709      constrain_to_aspect_ratio(&maximum, WMSZ_BOTTOMRIGHT);
17241710   else
17251711   {
1726      maximum.right -= wnd_extra_width(window);
1727      maximum.bottom -= wnd_extra_height(window);
1712      maximum.right -= wnd_extra_width();
1713      maximum.bottom -= wnd_extra_height();
17281714   }
17291715
17301716   // center within the work area
1731   RECT work = window->m_monitor->usuable_position_size();
1717   RECT work = m_monitor->usuable_position_size();
17321718   bounds->left = work.left + (rect_width(&work) - rect_width(&maximum)) / 2;
17331719   bounds->top = work.top + (rect_height(&work) - rect_height(&maximum)) / 2;
17341720   bounds->right = bounds->left + rect_width(&maximum);
r243822r243823
17421728//  (window thread)
17431729//============================================================
17441730
1745static void update_minmax_state(win_window_info *window)
1731void win_window_info::update_minmax_state()
17461732{
17471733   assert(GetCurrentThreadId() == window_threadid);
17481734
1749   if (!window->m_fullscreen)
1735   if (!m_fullscreen)
17501736   {
17511737      RECT bounds, minbounds, maxbounds;
17521738
17531739      // compare the maximum bounds versus the current bounds
1754      get_min_bounds(window, &minbounds, video_config.keepaspect);
1755      get_max_bounds(window, &maxbounds, video_config.keepaspect);
1756      GetWindowRect(window->m_hwnd, &bounds);
1740      get_min_bounds(&minbounds, video_config.keepaspect);
1741      get_max_bounds(&maxbounds, video_config.keepaspect);
1742      GetWindowRect(m_hwnd, &bounds);
17571743
17581744      // if either the width or height matches, we were maximized
1759      window->m_isminimized = (rect_width(&bounds) == rect_width(&minbounds) ||
1745      m_isminimized = (rect_width(&bounds) == rect_width(&minbounds) ||
17601746                        rect_height(&bounds) == rect_height(&minbounds));
1761      window->m_ismaximized = (rect_width(&bounds) == rect_width(&maxbounds) ||
1747      m_ismaximized = (rect_width(&bounds) == rect_width(&maxbounds) ||
17621748                        rect_height(&bounds) == rect_height(&maxbounds));
17631749   }
17641750   else
17651751   {
1766      window->m_isminimized = FALSE;
1767      window->m_ismaximized = TRUE;
1752      m_isminimized = FALSE;
1753      m_ismaximized = TRUE;
17681754   }
17691755}
17701756
r243822r243823
17751761//  (window thread)
17761762//============================================================
17771763
1778static void minimize_window(win_window_info *window)
1764void win_window_info::minimize_window()
17791765{
17801766   RECT newsize;
17811767
17821768   assert(GetCurrentThreadId() == window_threadid);
17831769
1784   get_min_bounds(window, &newsize, video_config.keepaspect);
1785   SetWindowPos(window->m_hwnd, NULL, newsize.left, newsize.top, rect_width(&newsize), rect_height(&newsize), SWP_NOZORDER);
1770   get_min_bounds(&newsize, video_config.keepaspect);
1771   SetWindowPos(m_hwnd, NULL, newsize.left, newsize.top, rect_width(&newsize), rect_height(&newsize), SWP_NOZORDER);
17861772}
17871773
17881774
r243822r243823
17921778//  (window thread)
17931779//============================================================
17941780
1795static void maximize_window(win_window_info *window)
1781void win_window_info::maximize_window()
17961782{
17971783   RECT newsize;
17981784
17991785   assert(GetCurrentThreadId() == window_threadid);
18001786
1801   get_max_bounds(window, &newsize, video_config.keepaspect);
1802   SetWindowPos(window->m_hwnd, NULL, newsize.left, newsize.top, rect_width(&newsize), rect_height(&newsize), SWP_NOZORDER);
1787   get_max_bounds(&newsize, video_config.keepaspect);
1788   SetWindowPos(m_hwnd, NULL, newsize.left, newsize.top, rect_width(&newsize), rect_height(&newsize), SWP_NOZORDER);
18031789}
18041790
18051791
r243822r243823
18091795//  (window thread)
18101796//============================================================
18111797
1812static void adjust_window_position_after_major_change(win_window_info *window)
1798void win_window_info::adjust_window_position_after_major_change()
18131799{
18141800   RECT oldrect, newrect;
18151801
18161802   assert(GetCurrentThreadId() == window_threadid);
18171803
18181804   // get the current size
1819   GetWindowRect(window->m_hwnd, &oldrect);
1805   GetWindowRect(m_hwnd, &oldrect);
18201806
18211807   // adjust the window size so the client area is what we want
1822   if (!window->m_fullscreen)
1808   if (!m_fullscreen)
18231809   {
18241810      // constrain the existing size to the aspect ratio
18251811      newrect = oldrect;
18261812      if (video_config.keepaspect)
1827         constrain_to_aspect_ratio(window, &newrect, WMSZ_BOTTOMRIGHT);
1813         constrain_to_aspect_ratio(&newrect, WMSZ_BOTTOMRIGHT);
18281814   }
18291815
18301816   // in full screen, make sure it covers the primary display
18311817   else
18321818   {
1833      win_monitor_info *monitor = window->winwindow_video_window_monitor(NULL);
1819      win_monitor_info *monitor = winwindow_video_window_monitor(NULL);
18341820      newrect = monitor->position_size();
18351821   }
18361822
18371823   // adjust the position if different
18381824   if (oldrect.left != newrect.left || oldrect.top != newrect.top ||
18391825      oldrect.right != newrect.right || oldrect.bottom != newrect.bottom)
1840      SetWindowPos(window->m_hwnd, window->m_fullscreen ? HWND_TOPMOST : HWND_TOP,
1826      SetWindowPos(m_hwnd, m_fullscreen ? HWND_TOPMOST : HWND_TOP,
18411827            newrect.left, newrect.top,
18421828            rect_width(&newrect), rect_height(&newrect), 0);
18431829
18441830   // take note of physical window size (used for lightgun coordinate calculation)
1845   if (window == win_window_list)
1831   if (this == win_window_list)
18461832   {
18471833      win_physical_width = rect_width(&newrect);
18481834      win_physical_height = rect_height(&newrect);
r243822r243823
18561842//  (window thread)
18571843//============================================================
18581844
1859static void set_fullscreen(win_window_info *window, int fullscreen)
1845void win_window_info::set_fullscreen(int fullscreen)
18601846{
18611847   assert(GetCurrentThreadId() == window_threadid);
18621848
18631849   // if we're in the right state, punt
1864   if (window->m_fullscreen == fullscreen)
1850   if (m_fullscreen == fullscreen)
18651851      return;
1866   window->m_fullscreen = fullscreen;
1852   m_fullscreen = fullscreen;
18671853
18681854   // kill off the drawers
1869   window->m_renderer->destroy();
1870   global_free(window->m_renderer);
1871   window->m_renderer = NULL;
1855   m_renderer->destroy();
1856   global_free(m_renderer);
1857   m_renderer = NULL;
18721858
18731859   // hide ourself
1874   ShowWindow(window->m_hwnd, SW_HIDE);
1860   ShowWindow(m_hwnd, SW_HIDE);
18751861
18761862   // configure the window if non-fullscreen
18771863   if (!fullscreen)
18781864   {
18791865      // adjust the style
1880      SetWindowLong(window->m_hwnd, GWL_STYLE, WINDOW_STYLE);
1881      SetWindowLong(window->m_hwnd, GWL_EXSTYLE, WINDOW_STYLE_EX);
1882      SetWindowPos(window->m_hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
1866      SetWindowLong(m_hwnd, GWL_STYLE, WINDOW_STYLE);
1867      SetWindowLong(m_hwnd, GWL_EXSTYLE, WINDOW_STYLE_EX);
1868      SetWindowPos(m_hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
18831869
18841870      // force to the bottom, then back on top
1885      SetWindowPos(window->m_hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1886      SetWindowPos(window->m_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1871      SetWindowPos(m_hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1872      SetWindowPos(m_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
18871873
18881874      // if we have previous non-fullscreen bounds, use those
1889      if (window->m_non_fullscreen_bounds.right != window->m_non_fullscreen_bounds.left)
1875      if (m_non_fullscreen_bounds.right != m_non_fullscreen_bounds.left)
18901876      {
1891         SetWindowPos(window->m_hwnd, HWND_TOP, window->m_non_fullscreen_bounds.left, window->m_non_fullscreen_bounds.top,
1892                  rect_width(&window->m_non_fullscreen_bounds), rect_height(&window->m_non_fullscreen_bounds),
1877         SetWindowPos(m_hwnd, HWND_TOP, m_non_fullscreen_bounds.left, m_non_fullscreen_bounds.top,
1878                  rect_width(&m_non_fullscreen_bounds), rect_height(&m_non_fullscreen_bounds),
18931879                  SWP_NOZORDER);
18941880      }
18951881
18961882      // otherwise, set a small size and maximize from there
18971883      else
18981884      {
1899         SetWindowPos(window->m_hwnd, HWND_TOP, 0, 0, MIN_WINDOW_DIM, MIN_WINDOW_DIM, SWP_NOZORDER);
1900         maximize_window(window);
1885         SetWindowPos(m_hwnd, HWND_TOP, 0, 0, MIN_WINDOW_DIM, MIN_WINDOW_DIM, SWP_NOZORDER);
1886         maximize_window();
19011887      }
19021888   }
19031889
r243822r243823
19051891   else
19061892   {
19071893      // save the bounds
1908      GetWindowRect(window->m_hwnd, &window->m_non_fullscreen_bounds);
1894      GetWindowRect(m_hwnd, &m_non_fullscreen_bounds);
19091895
19101896      // adjust the style
1911      SetWindowLong(window->m_hwnd, GWL_STYLE, FULLSCREEN_STYLE);
1912      SetWindowLong(window->m_hwnd, GWL_EXSTYLE, FULLSCREEN_STYLE_EX);
1913      SetWindowPos(window->m_hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
1897      SetWindowLong(m_hwnd, GWL_STYLE, FULLSCREEN_STYLE);
1898      SetWindowLong(m_hwnd, GWL_EXSTYLE, FULLSCREEN_STYLE_EX);
1899      SetWindowPos(m_hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
19141900
19151901      // set topmost
1916      SetWindowPos(window->m_hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1902      SetWindowPos(m_hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
19171903   }
19181904
19191905   // adjust the window to compensate for the change
1920   adjust_window_position_after_major_change(window);
1906   adjust_window_position_after_major_change();
19211907
19221908   // show ourself
1923   if (!window->m_fullscreen || window->m_fullscreen_safe)
1909   if (!m_fullscreen || m_fullscreen_safe)
19241910   {
19251911      if (video_config.mode != VIDEO_MODE_NONE)
1926         ShowWindow(window->m_hwnd, SW_SHOW);
1927      window->m_renderer = draw.create(window);
1928      if (window->m_renderer->create())
1912         ShowWindow(m_hwnd, SW_SHOW);
1913      m_renderer = draw.create(this);
1914      if (m_renderer->create())
19291915         exit(1);
19301916   }
19311917
19321918   // ensure we're still adjusted correctly
1933   adjust_window_position_after_major_change(window);
1919   adjust_window_position_after_major_change();
19341920}
19351921
19361922#if (USE_QTDEBUG)
trunk/src/osd/windows/window.h
r243822r243823
6363
6464   win_monitor_info *monitor() const { return m_monitor; }
6565
66   void destroy();
67
68   // static
69
70   static void create(running_machine &machine, int index, win_monitor_info *monitor, const osd_window_config *config);
71
6672   // static callbacks
6773
6874   static LRESULT CALLBACK video_window_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam);
75   static unsigned __stdcall thread_entry(void *param);
6976
7077   // member variables
7178
r243822r243823
102109
103110private:
104111   void draw_video_contents(HDC dc, int update);
112   void set_starting_view(int index, const char *view);
113   int wnd_extra_width();
114   int wnd_extra_height();
115   int complete_create();
116   void constrain_to_aspect_ratio(RECT *rect, int adjustment);
117   void get_min_bounds(RECT *bounds, int constrain);
118   void get_max_bounds(RECT *bounds, int constrain);
119   void update_minmax_state();
120   void minimize_window();
121   void maximize_window();
122   void adjust_window_position_after_major_change();
123   void set_fullscreen(int fullscreen);
105124
106125   running_machine &   m_machine;
107126};
r243822r243823
125144//  PROTOTYPES
126145//============================================================
127146
128// creation/deletion of windows
129void winwindow_video_window_create(running_machine &machine, int index, win_monitor_info *monitor, const osd_window_config *config);
130
131147BOOL winwindow_has_focus(void);
132148void winwindow_update_cursor_state(running_machine &machine);
133149


Previous 199869 Revisions Next


© 1997-2024 The MAME Team