Previous 199869 Revisions Next

r36713 Friday 27th March, 2015 at 13:36:54 UTC by Miodrag Milanović
Merge branch 'master' of https://github.com/mamedev/mame
[src/mame/drivers]ttchamp.c
[src/mess/drivers]hh_hmcs40.c hh_pic16.c hh_tms1k.c hh_ucom4.c mbdtower.c ticalc1x.c tispeak.c
[src/mess/includes]hh_tms1k.h

trunk/src/mame/drivers/ttchamp.c
r245224r245225
5858
5959Notes
6060I think the PIC is used to interface with battry backed RAM instead of an EEPROM,
61we currently attempt to simulate this as the PIC is read protected.
61we currently simulate this as the PIC is read protected.
6262
6363
6464
r245224r245225
264264//   printf("%06x: read from PIC (%04x)\n", space.device().safe_pc(),mem_mask);
265265   if (picmodex == PIC_SET_READLATCH)
266266   {
267      printf("read data %02x from %02x\n", m_pic_latched, m_pic_readaddr);
267//      printf("read data %02x from %02x\n", m_pic_latched, m_pic_readaddr);
268268      picmodex = PIC_IDLE;
269      return m_pic_latched;
270269
270      return m_pic_latched << 8;
271
271272   }
272273   return 0x00;
273274
r245224r245225
297298      {
298299         picmodex = PIC_IDLE;
299300         m_bakram[m_pic_writeaddr] = m_pic_writelatched;
300         printf("wrote %02x to %02x\n", m_pic_writelatched, m_pic_writeaddr);
301   //      printf("wrote %02x to %02x\n", m_pic_writelatched, m_pic_writeaddr);
301302      }
302303      else if (data == 0x22) // next data to latch
303304      {
304         m_pic_latched = m_bakram[m_pic_readaddr];
305         // why does it read twice as many addresses, forcing us to shift the
306         // address by 1 to give correct results? maybe it can read 'previous' data' too?
307         m_pic_latched = m_bakram[m_pic_readaddr>>1];
308
305309//         printf("latch read data %02x from %02x\n",m_pic_latched, m_pic_readaddr );
306310         picmodex = PIC_SET_READLATCH; // waiting to read...
307311      }
r245224r245225
672676
673677DRIVER_INIT_MEMBER(ttchamp_state,ttchamp)
674678{
675//  UINT8 *ROM1 = memregion("user1")->base();
676//  membank("bank1")->set_base(&ROM1[0x100000]);
677//  membank("bank2")->set_base(&ROM1[0x180000]);
678679}
679680
681// only the graphics differ between the two sets, code section is the same
680682GAME( 1995, ttchamp, 0,        ttchamp, ttchamp, ttchamp_state, ttchamp, ROT0,  "Gamart",                               "Table Tennis Champions", 0 ) // this has various advertising boards, including 'Electronic Devices' and 'Deniam'
681683GAME( 1995, ttchampa,ttchamp,  ttchamp, ttchamp, ttchamp_state, ttchamp, ROT0,  "Gamart (Palencia Elektronik license)", "Table Tennis Champions (Palencia Elektronik license)", 0 ) // this only has Palencia Elektronik advertising boards
trunk/src/mess/drivers/hh_hmcs40.c
r245224r245225
8989
9090   TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick);
9191   void display_update();
92   void set_display_size(int maxx, int maxy);
9293   void display_matrix(int maxx, int maxy, UINT64 setx, UINT32 sety);
9394
9495   // game-specific handlers
r245224r245225
199200   display_update();
200201}
201202
202void hh_hmcs40_state::display_matrix(int maxx, int maxy, UINT64 setx, UINT32 sety)
203void hh_hmcs40_state::set_display_size(int maxx, int maxy)
203204{
204205   m_display_maxx = maxx;
205206   m_display_maxy = maxy;
207}
206208
209void hh_hmcs40_state::display_matrix(int maxx, int maxy, UINT64 setx, UINT32 sety)
210{
211   set_display_size(maxx, maxy);
212
207213   // update current state
208214   UINT64 mask = (1 << maxx) - 1;
209215   for (int y = 0; y < maxy; y++)
trunk/src/mess/drivers/hh_pic16.c
r245224r245225
6565
6666   TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick);
6767   void display_update();
68   void set_display_size(int maxx, int maxy);
6869   void display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety);
6970
7071   // game-specific handlers
r245224r245225
162163   display_update();
163164}
164165
165void hh_pic16_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety)
166void hh_pic16_state::set_display_size(int maxx, int maxy)
166167{
167168   m_display_maxx = maxx;
168169   m_display_maxy = maxy;
170}
169171
172void hh_pic16_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety)
173{
174   set_display_size(maxx, maxy);
175
170176   // update current state
171177   UINT32 mask = (1 << maxx) - 1;
172178   for (int y = 0; y < maxy; y++)
r245224r245225
204210   m_speaker->level_w((m_b >> 7 & 1) | (m_c >> 6 & 2));
205211
206212   // d0-d6: 7seg
207   m_display_maxx = 7;
208   m_display_maxy = 2;
209
210213   m_display_segmask[offset] = 0x7f;
211214   m_display_state[offset] = ~data & 0x7f;
215
216   set_display_size(7, 2);
212217   display_update();
213218}
214219
trunk/src/mess/drivers/hh_tms1k.c
r245224r245225
194194   display_update();
195195}
196196
197void hh_tms1k_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety)
197void hh_tms1k_state::set_display_size(int maxx, int maxy)
198198{
199199   m_display_maxx = maxx;
200200   m_display_maxy = maxy;
201}
201202
203void hh_tms1k_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety)
204{
205   set_display_size(maxx, maxy);
206
202207   // update current state
203208   UINT32 mask = (1 << maxx) - 1;
204209   for (int y = 0; y < maxy; y++)
r245224r245225
270275
271276void hh_tms1k_state::mathmagi_display()
272277{
273   m_display_maxx = 8;
274   m_display_maxy = 11;
275
276278   // R0-R7: 7seg leds
277279   for (int y = 0; y < 8; y++)
278280   {
r245224r245225
286288   for (int y = 8; y < 11; y++)
287289      m_display_state[y] = (m_r >> y & 1) ? m_o : 0;
288290
291   set_display_size(8, 11);
289292   display_update();
290293}
291294
r245224r245225
433436
434437void hh_tms1k_state::amaztron_display()
435438{
436   m_display_maxx = 8;
437   m_display_maxy = 3;
438
439439   // R8,R9: select digit
440440   for (int y = 0; y < 2; y++)
441441   {
r245224r245225
446446   // R6,R7: lamps (-> lamp20,21)
447447   m_display_state[2] = m_r >> 6 & 3;
448448
449   set_display_size(8, 3);
449450   display_update();
450451}
451452
r245224r245225
960961
961962void hh_tms1k_state::ebball3_display()
962963{
963   m_display_maxx = 7;
964   m_display_maxy = 10+2;
965
966964   // update current state
967965   for (int y = 0; y < 10; y++)
968966      m_display_state[y] = (m_r >> y & 1) ? m_o : 0;
r245224r245225
975973   m_display_state[11] = ((m_display_state[4] & 0x10) | (m_display_state[7] & 0x01)) << 1;
976974   m_display_segmask[10] = m_display_segmask[11] = 0x22;
977975
976   set_display_size(7, 10+2);
978977   display_update();
979978}
980979
r245224r245225
16121611
16131612WRITE16_MEMBER(hh_tms1k_state::cnsector_write_r)
16141613{
1615   m_display_maxx = 8;
1616   m_display_maxy = 7;
1617
16181614   // R0-R5: select digit (right-to-left)
16191615   for (int y = 0; y < 6; y++)
16201616   {
r245224r245225
16251621   // R6-R9: direction leds (-> lamp60-63)
16261622   m_display_state[6] = data >> 6 & 0xf;
16271623
1624   set_display_size(8, 7);
16281625   display_update();
16291626}
16301627
r245224r245225
18141811
18151812WRITE16_MEMBER(hh_tms1k_state::stopthief_write_r)
18161813{
1817   m_display_maxx = 7;
1818   m_display_maxy = 3;
1819
18201814   // R0-R2: select digit
18211815   UINT8 o = BITSWAP8(m_o,3,5,2,1,4,0,6,7) & 0x7f;
1822   for (int y = 0; y < m_display_maxy; y++)
1816   for (int y = 0; y < 3; y++)
18231817   {
18241818      m_display_segmask[y] = 0x7f;
18251819      m_display_state[y] = (data >> y & 1) ? o : 0;
18261820   }
18271821
1822   set_display_size(7, 3);
18281823   display_update();
18291824
18301825   // R3-R8: speaker on
trunk/src/mess/drivers/hh_ucom4.c
r245224r245225
7676
7777   TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick);
7878   void display_update();
79   void set_display_size(int maxx, int maxy);
7980   void display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety);
8081
8182   // game-specific handlers
r245224r245225
207208   display_update();
208209}
209210
210void hh_ucom4_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety)
211void hh_ucom4_state::set_display_size(int maxx, int maxy)
211212{
212213   m_display_maxx = maxx;
213214   m_display_maxy = maxy;
215}
214216
217void hh_ucom4_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety)
218{
219   set_display_size(maxx, maxy);
220
215221   // update current state
216222   UINT32 mask = (1 << maxx) - 1;
217223   for (int y = 0; y < maxy; y++)
trunk/src/mess/drivers/mbdtower.c
r245224r245225
6161void mbdtower_state::mbdtower_display()
6262{
6363   // declare display matrix size and the 2 7segs
64   m_display_maxx = 7;
65   m_display_maxy = 3;
64   set_display_size(7, 3);
6665   m_display_segmask[1] = m_display_segmask[2] = 0x7f;
6766
6867   // update current state
trunk/src/mess/drivers/ticalc1x.c
r245224r245225
22// copyright-holders:hap, Sean Riddle
33/***************************************************************************
44
5  ** subclass of hh_tms1k_state (includes/hh_tms1k.h, drivers/hh_tms1k.c) **
6
57  Texas Instruments TMS1xxx/0970/0980 handheld calculators (mostly single-chip)
68
79  Refer to their official manuals on how to use them.
r245224r245225
1315
1416***************************************************************************/
1517
16#include "emu.h"
17#include "cpu/tms0980/tms0980.h"
18#include "sound/speaker.h"
18#include "includes/hh_tms1k.h"
1919
2020// internal artwork
2121#include "ti1270.lh"
r245224r245225
2424#include "wizatron.lh"
2525
2626
27class ticalc1x_state : public driver_device
27class ticalc1x_state : public hh_tms1k_state
2828{
2929public:
3030   ticalc1x_state(const machine_config &mconfig, device_type type, const char *tag)
31      : driver_device(mconfig, type, tag),
32      m_maincpu(*this, "maincpu"),
33      m_inp_matrix(*this, "IN"),
34      m_speaker(*this, "speaker"),
35      m_display_wait(33),
36      m_display_maxy(1),
37      m_display_maxx(0)
31      : hh_tms1k_state(mconfig, type, tag)
3832   { }
3933
40   // devices
41   required_device<cpu_device> m_maincpu;
42   optional_ioport_array<11> m_inp_matrix; // max 11
43   optional_device<speaker_sound_device> m_speaker;
44
45   // misc common
46   UINT16 m_r;                         // MCU R-pins data
47   UINT16 m_o;                         // MCU O-pins data
48   UINT16 m_inp_mux;                   // multiplexed inputs mask
49   bool m_power_on;
50
51   UINT8 read_inputs(int columns);
52   DECLARE_INPUT_CHANGED_MEMBER(power_button);
53   DECLARE_WRITE_LINE_MEMBER(auto_power_off);
54
55   virtual void machine_reset();
56   virtual void machine_start();
57
58   // display common
59   int m_display_wait;                 // led/lamp off-delay in microseconds (default 33ms)
60   int m_display_maxy;                 // display matrix number of rows
61   int m_display_maxx;                 // display matrix number of columns
62
63   UINT32 m_display_state[0x20];       // display matrix rows data
64   UINT16 m_display_segmask[0x20];     // if not 0, display matrix row is a digit, mask indicates connected segments
65   UINT32 m_display_cache[0x20];       // (internal use)
66   UINT8 m_display_decay[0x20][0x20];  // (internal use)
67
68   TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick);
69   void display_update();
7034   void display_matrix_seg(int maxx, int maxy, UINT32 setx, UINT32 sety, UINT16 segmask);
7135
7236   // calculator-specific handlers
r245224r245225
9357   DECLARE_WRITE16_MEMBER(ti30_write_o);
9458   DECLARE_WRITE16_MEMBER(ti30_write_r);
9559   DECLARE_READ8_MEMBER(ti30_read_k);
60
61protected:
62   virtual void machine_start();
9663};
9764
9865
99// machine_start/reset
100
10166void ticalc1x_state::machine_start()
10267{
103   // zerofill
104   memset(m_display_state, 0, sizeof(m_display_state));
105   memset(m_display_cache, ~0, sizeof(m_display_cache));
106   memset(m_display_decay, 0, sizeof(m_display_decay));
68   hh_tms1k_state::machine_start();
10769   memset(m_display_segmask, ~0, sizeof(m_display_segmask)); // !
108
109   m_o = 0;
110   m_r = 0;
111   m_inp_mux = 0;
112   m_power_on = false;
113
114   // register for savestates
115   save_item(NAME(m_display_maxy));
116   save_item(NAME(m_display_maxx));
117   save_item(NAME(m_display_wait));
118
119   save_item(NAME(m_display_state));
120   /* save_item(NAME(m_display_cache)); */ // don't save!
121   save_item(NAME(m_display_decay));
122   save_item(NAME(m_display_segmask));
123
124   save_item(NAME(m_o));
125   save_item(NAME(m_r));
126   save_item(NAME(m_inp_mux));
127   save_item(NAME(m_power_on));
12870}
12971
130void ticalc1x_state::machine_reset()
131{
132   m_power_on = true;
133}
134
135
136
137/***************************************************************************
138
139  Helper Functions
140
141***************************************************************************/
142
143// The device may strobe the outputs very fast, it is unnoticeable to the user.
144// To prevent flickering here, we need to simulate a decay.
145
146void ticalc1x_state::display_update()
147{
148   UINT32 active_state[0x20];
149
150   for (int y = 0; y < m_display_maxy; y++)
151   {
152      active_state[y] = 0;
153
154      for (int x = 0; x < m_display_maxx; x++)
155      {
156         // turn on powered segments
157         if (m_power_on && m_display_state[y] >> x & 1)
158            m_display_decay[y][x] = m_display_wait;
159
160         // determine active state
161         int ds = (m_display_decay[y][x] != 0) ? 1 : 0;
162         active_state[y] |= (ds << x);
163      }
164   }
165
166   // on difference, send to output
167   for (int y = 0; y < m_display_maxy; y++)
168      if (m_display_cache[y] != active_state[y])
169      {
170         if (m_display_segmask[y] != 0)
171            output_set_digit_value(y, active_state[y] & m_display_segmask[y]);
172
173         const int mul = (m_display_maxx <= 10) ? 10 : 100;
174         for (int x = 0; x < m_display_maxx; x++)
175         {
176            int state = active_state[y] >> x & 1;
177            output_set_lamp_value(y * mul + x, state);
178
179            // bit coords for svg2lay
180            char buf[10];
181            sprintf(buf, "%d.%d", y, x);
182            output_set_value(buf, state);
183         }
184      }
185
186   memcpy(m_display_cache, active_state, sizeof(m_display_cache));
187}
188
189TIMER_DEVICE_CALLBACK_MEMBER(ticalc1x_state::display_decay_tick)
190{
191   // slowly turn off unpowered segments
192   for (int y = 0; y < m_display_maxy; y++)
193      for (int x = 0; x < m_display_maxx; x++)
194         if (m_display_decay[y][x] != 0)
195            m_display_decay[y][x]--;
196
197   display_update();
198}
199
20072void ticalc1x_state::display_matrix_seg(int maxx, int maxy, UINT32 setx, UINT32 sety, UINT16 segmask)
20173{
202   m_display_maxx = maxx;
203   m_display_maxy = maxy;
204
205   // update current state
206   UINT32 colmask = (1 << maxx) - 1;
20774   for (int y = 0; y < maxy; y++)
208   {
20975      m_display_segmask[y] &= segmask;
210      m_display_state[y] = (sety >> y & 1) ? (setx & colmask) : 0;
211   }
21276
213   display_update();
77   display_matrix(maxx, maxy, setx, sety);
21478}
21579
21680
217UINT8 ticalc1x_state::read_inputs(int columns)
218{
219   UINT8 ret = 0;
22081
221   // read selected input rows
222   for (int i = 0; i < columns; i++)
223      if (m_inp_mux >> i & 1)
224         ret |= m_inp_matrix[i]->read();
225
226   return ret;
227}
228
229
230// devices with a TMS0980 can auto power-off
231
232WRITE_LINE_MEMBER(ticalc1x_state::auto_power_off)
233{
234   if (state)
235   {
236      m_power_on = false;
237      m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
238   }
239}
240
241INPUT_CHANGED_MEMBER(ticalc1x_state::power_button)
242{
243   m_power_on = (bool)(FPTR)param;
244   m_maincpu->set_input_line(INPUT_LINE_RESET, m_power_on ? CLEAR_LINE : ASSERT_LINE);
245}
246
247
248
24982/***************************************************************************
25083
25184  Minidrivers (I/O, Inputs, Machine Config)
r245224r245225
269102   m_display_state[11] = m_display_state[10] << 5 & 0x40;
270103   m_display_state[10] &= 0x40;
271104   
272   m_display_maxx = 8;
273   m_display_maxy = 12;
105   set_display_size(8, 12);
274106   display_update();
275107}
276108
r245224r245225
372204   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, tisr16_write_o))
373205   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, tisr16_write_r))
374206
375   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", ticalc1x_state, display_decay_tick, attotime::from_msec(1))
207   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
376208   MCFG_DEFAULT_LAYOUT(layout_tisr16)
377209
378210   /* no video! */
r245224r245225
548380   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, ti1270_write_o))
549381   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, ti1270_write_r))
550382
551   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", ticalc1x_state, display_decay_tick, attotime::from_msec(1))
383   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
552384   MCFG_DEFAULT_LAYOUT(layout_ti1270)
553385
554386   /* no video! */
r245224r245225
632464   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, wizatron_write_o))
633465   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, wizatron_write_r))
634466
635   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", ticalc1x_state, display_decay_tick, attotime::from_msec(1))
467   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
636468   MCFG_DEFAULT_LAYOUT(layout_wizatron)
637469
638470   /* no video! */
r245224r245225
692524   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, lilprof_write_o))
693525   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, wizatron_write_r))
694526
695   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", ticalc1x_state, display_decay_tick, attotime::from_msec(1))
527   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
696528   MCFG_DEFAULT_LAYOUT(layout_wizatron)
697529
698530   /* no video! */
r245224r245225
706538
707539/***************************************************************************
708540
709  TI Little Professor (1978 version, same as 1980 version)
541  TI Little Professor (1978 version)
710542  * TMS1990 MCU labeled TMC1993NL. die labeled 1990C-c3C
543 
544  1978 re-release, with on/off and level select on buttons instead of
545  switches. The casing was slightly revised in 1980 again, but same rom.
711546
712547***************************************************************************/
713548
r245224r245225
726561   // 6th digit is a custom 7seg for math symbols (see wizatron_write_r)
727562   m_display_state[6] = BITSWAP8(m_display_state[6],7,6,1,4,2,3,5,0);
728563
729   m_display_maxx = 7;
730   m_display_maxy = 9;
564   set_display_size(7, 9);
731565   display_update();
732566}
733567
r245224r245225
788622   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(ticalc1x_state, lilprof78_write_o))
789623   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, lilprof78_write_r))
790624
791   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", ticalc1x_state, display_decay_tick, attotime::from_msec(1))
625   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
792626   MCFG_DEFAULT_LAYOUT(layout_wizatron)
793627
794628   /* no video! */
r245224r245225
1023857   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(ticalc1x_state, ti30_write_r))
1024858   MCFG_TMS1XXX_POWER_OFF_CB(WRITELINE(ticalc1x_state, auto_power_off))
1025859
1026   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", ticalc1x_state, display_decay_tick, attotime::from_msec(1))
860   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
1027861   MCFG_DEFAULT_LAYOUT(layout_ti30)
1028862
1029863   /* no video! */
trunk/src/mess/drivers/tispeak.c
r245224r245225
22// copyright-holders:hap, Lord Nightmare
33/***************************************************************************
44
5  ** subclass of hh_tms1k_state (includes/hh_tms1k.h, drivers/hh_tms1k.c) **
6
57  Texas Instruments 1st-gen. handheld speech devices,
68
79  These devices, mostly edu-toys, are based around an MCU(TMS0270/TMS1100),
r245224r245225
275277
276278***************************************************************************/
277279
278#include "emu.h"
279#include "cpu/tms0980/tms0980.h"
280#include "includes/hh_tms1k.h"
280281#include "sound/tms5110.h"
281282#include "machine/tms6100.h"
282283#include "bus/generic/slot.h"
283284#include "bus/generic/carts.h"
284285
286// internal artwork
285287#include "lantutor.lh"
286288#include "snspell.lh"
287289
r245224r245225
294296#define MASTER_CLOCK (640000)
295297
296298
297class tispeak_state : public driver_device
299class tispeak_state : public hh_tms1k_state
298300{
299301public:
300302   tispeak_state(const machine_config &mconfig, device_type type, const char *tag)
301      : driver_device(mconfig, type, tag),
302      m_maincpu(*this, "maincpu"),
303      : hh_tms1k_state(mconfig, type, tag),
303304      m_tms5100(*this, "tms5100"),
304305      m_tms6100(*this, "tms6100"),
305      m_cart(*this, "cartslot"),
306      m_button_matrix(*this, "IN"),
307      m_display_wait(33),
308      m_display_maxy(1),
309      m_display_maxx(0)
306      m_cart(*this, "cartslot")
310307   { }
311308
312309   // devices
313   required_device<tms0270_cpu_device> m_maincpu;
314310   required_device<tms5100_device> m_tms5100;
315311   required_device<tms6100_device> m_tms6100;
316312   optional_device<generic_slot_device> m_cart;
317   required_ioport_array<9> m_button_matrix;
318313
319   // misc common
320   UINT16 m_r;                         // MCU R-pins data
321   UINT16 m_o;                         // MCU O-pins data
322   int m_power_on;
323   int m_filament_on;
324
325   // display common
326   int m_display_wait;                 // led/lamp off-delay in microseconds (default 33ms)
327   int m_display_maxy;                 // display matrix number of rows
328   int m_display_maxx;                 // display matrix number of columns
329
330   UINT32 m_display_state[0x20];       // display matrix rows data
331   UINT16 m_display_segmask[0x20];     // if not 0, display matrix row is a digit, mask indicates connected segments
332   UINT32 m_display_cache[0x20];       // (internal use)
333   UINT8 m_display_decay[0x20][0x20];  // (internal use)
334
335   TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick);
336   void display_update();
337   void display_matrix_seg(int maxx, int maxy, UINT32 setx, UINT32 sety, UINT16 segmask);
338
339314   // cartridge
340315   UINT32 m_cart_max_size;
341316   UINT8* m_cart_base;
r245224r245225
349324   DECLARE_WRITE16_MEMBER(snspell_write_r);
350325   DECLARE_WRITE16_MEMBER(lantutor_write_r);
351326
352   DECLARE_INPUT_CHANGED_MEMBER(power_button);
353   void power_off();
327   DECLARE_INPUT_CHANGED_MEMBER(snspell_power_button);
328   void snspell_power_off();
329   void snspell_display();
354330
355   virtual void machine_reset();
331protected:
356332   virtual void machine_start();
357333};
358334
r245224r245225
397373
398374/***************************************************************************
399375
400  VFD Display
376  I/O
401377
402378***************************************************************************/
403379
404// The device may strobe the outputs very fast, it is unnoticeable to the user.
405// To prevent flickering here, we need to simulate a decay.
380// common/snspell
406381
407void tispeak_state::display_update()
382void tispeak_state::snspell_display()
408383{
409   UINT32 active_state[0x20];
384   for (int y = 0; y < 16; y++)
385      m_display_segmask[y] = 0x3fff;
410386
411   for (int y = 0; y < m_display_maxy; y++)
412   {
413      active_state[y] = 0;
414
415      for (int x = 0; x < m_display_maxx; x++)
416      {
417         // turn on powered segments
418         if (m_power_on && m_filament_on && m_display_state[y] >> x & 1)
419            m_display_decay[y][x] = m_display_wait;
420
421         // determine active state
422         int ds = (m_display_decay[y][x] != 0) ? 1 : 0;
423         active_state[y] |= (ds << x);
424      }
425   }
426
427   // on difference, send to output
428   for (int y = 0; y < m_display_maxy; y++)
429      if (m_display_cache[y] != active_state[y])
430      {
431         if (m_display_segmask[y] != 0)
432            output_set_digit_value(y, active_state[y] & m_display_segmask[y]);
433
434         const int mul = (m_display_maxx <= 10) ? 10 : 100;
435         for (int x = 0; x < m_display_maxx; x++)
436         {
437            int state = active_state[y] >> x & 1;
438            output_set_lamp_value(y * mul + x, state);
439
440            // bit coords for svg2lay
441            char buf[10];
442            sprintf(buf, "%d.%d", y, x);
443            output_set_value(buf, state);
444         }
445      }
446
447   memcpy(m_display_cache, active_state, sizeof(m_display_cache));
387   display_matrix(16, 16, m_o, (m_r & 0x8000) ? (m_r & 0x21ff) : 0);
448388}
449389
450TIMER_DEVICE_CALLBACK_MEMBER(tispeak_state::display_decay_tick)
451{
452   // slowly turn off unpowered segments
453   for (int y = 0; y < m_display_maxy; y++)
454      for (int x = 0; x < m_display_maxx; x++)
455         if (m_display_decay[y][x] != 0)
456            m_display_decay[y][x]--;
457
458   display_update();
459}
460
461void tispeak_state::display_matrix_seg(int maxx, int maxy, UINT32 setx, UINT32 sety, UINT16 segmask)
462{
463   m_display_maxx = maxx;
464   m_display_maxy = maxy;
465
466   // update current state
467   UINT32 colmask = (1 << maxx) - 1;
468   for (int y = 0; y < maxy; y++)
469   {
470      m_display_segmask[y] &= segmask;
471      m_display_state[y] = (sety >> y & 1) ? (setx & colmask) : 0;
472   }
473
474   display_update();
475}
476
477
478
479/***************************************************************************
480
481  I/O
482
483***************************************************************************/
484
485// common/snspell
486
487390READ8_MEMBER(tispeak_state::snspell_read_k)
488391{
489   // the Vss row is always on
490   UINT8 k = m_button_matrix[8]->read();
491
492   // read selected button rows
493   for (int i = 0; i < 8; i++)
494      if (m_r >> i & 1)
495         k |= m_button_matrix[i]->read();
496
497   return k;
392   // note: the Vss row is always on
393   return m_inp_matrix[8]->read() | read_inputs(8);
498394}
499395
500396WRITE16_MEMBER(tispeak_state::snspell_write_r)
501397{
502   // R15: filament on
503   m_filament_on = data & 0x8000;
504
505398   // R13: power-off request, on falling edge
506399   if ((m_r >> 13 & 1) && !(data >> 13 & 1))
507      power_off();
400      snspell_power_off();
508401
509402   // R0-R7: input mux and select digit (+R8 if the device has 9 digits)
403   // R15: filament on
510404   // other bits: MCU internal use
511   m_r = data & 0x21ff;
512   display_matrix_seg(16, 16, m_o, m_r, 0x3fff);
405   m_r = m_inp_mux = data;
406   snspell_display();
513407}
514408
515409WRITE16_MEMBER(tispeak_state::snspell_write_o)
r245224r245225
517411   // reorder opla to led14seg, plus DP as d14 and AP as d15:
518412   // E,D,C,G,B,A,I,M,L,K,N,J,[AP],H,F,[DP] (sidenote: TI KLMN = MAME MLNK)
519413   m_o = BITSWAP16(data,12,15,10,7,8,9,11,6,13,3,14,0,1,2,4,5);
520   display_matrix_seg(16, 16, m_o, m_r, 0x3fff);
414   snspell_display();
521415}
522416
523417
524void tispeak_state::power_off()
418void tispeak_state::snspell_power_off()
525419{
526420   m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
527421   m_tms5100->reset();
528422   m_tms6100->reset();
529423
530   m_power_on = 0;
424   m_power_on = false;
531425}
532426
533427
r245224r245225
538432   // reorder opla to led14seg, plus DP as d14 and AP as d15:
539433   // [DP],D,C,H,F,B,I,M,L,K,N,J,[AP],E,G,A (sidenote: TI KLMN = MAME MLNK)
540434   m_o = BITSWAP16(data,12,0,10,7,8,9,11,6,3,14,4,13,1,2,5,15);
541   display_matrix_seg(16, 16, m_o, m_r, 0x3fff);
435   snspell_display();
542436}
543437
544438
r245224r245225
547441WRITE16_MEMBER(tispeak_state::lantutor_write_r)
548442{
549443   // same as default, except R13 is used for an extra digit
550   m_filament_on = data & 0x8000;
551   m_r = data & 0x21ff;
552   display_matrix_seg(16, 16, m_o, m_r, 0x3fff);
444   m_r = m_inp_mux = data;
445   snspell_display();
553446}
554447
555448
r245224r245225
560453
561454***************************************************************************/
562455
563INPUT_CHANGED_MEMBER(tispeak_state::power_button)
456INPUT_CHANGED_MEMBER(tispeak_state::snspell_power_button)
564457{
565458   int on = (int)(FPTR)param;
566459
567460   if (on && !m_power_on)
568461   {
569      m_power_on = 1;
462      m_power_on = true;
570463      m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
571464   }
572465   else if (!on && m_power_on)
573      power_off();
466      snspell_power_off();
574467}
575468
576469static INPUT_PORTS_START( snspell )
r245224r245225
631524   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_NAME("Secret Code")
632525   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_NAME("Letter")
633526   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_NAME("Say It")
634   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Spell/On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, power_button, (void *)1)
527   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Spell/On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, snspell_power_button, (void *)true)
635528INPUT_PORTS_END
636529
637530
r245224r245225
683576   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_NAME("Write It")
684577   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_NAME("Greater/Less")
685578   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_NAME("Word Problems")
686   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Solve It/On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, power_button, (void *)1)
579   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Solve It/On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, snspell_power_button, (void *)true)
687580
688581   PORT_START("IN.7")
689582   PORT_BIT( 0x1f, IP_ACTIVE_HIGH, IPT_UNUSED )
r245224r245225
705598   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_NAME("Picture Read")
706599   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_NAME("Letter Stumper")
707600   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_NAME("Hear It")
708   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Word Zap/On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, power_button, (void *)1)
601   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Word Zap/On") PORT_CHANGED_MEMBER(DEVICE_SELF, tispeak_state, snspell_power_button, (void *)true)
709602INPUT_PORTS_END
710603
711604
r245224r245225
746639
747640***************************************************************************/
748641
749void tispeak_state::machine_reset()
750{
751   m_power_on = 1;
752}
753
754642void tispeak_state::machine_start()
755643{
756   // zerofill
757   memset(m_display_state, 0, sizeof(m_display_state));
758   memset(m_display_cache, ~0, sizeof(m_display_cache));
759   memset(m_display_decay, 0, sizeof(m_display_decay));
760   memset(m_display_segmask, ~0, sizeof(m_display_segmask)); // !
644   hh_tms1k_state::machine_start();
761645
762   m_r = 0;
763   m_o = 0;
764   m_power_on = 0;
765   m_filament_on = 0;
766
767   // register for savestates
768   save_item(NAME(m_display_maxy));
769   save_item(NAME(m_display_maxx));
770   save_item(NAME(m_display_wait));
771
772   save_item(NAME(m_display_state));
773   /* save_item(NAME(m_display_cache)); */ // don't save!
774   save_item(NAME(m_display_decay));
775   save_item(NAME(m_display_segmask));
776
777   save_item(NAME(m_r));
778   save_item(NAME(m_o));
779   save_item(NAME(m_power_on));
780   save_item(NAME(m_filament_on));
781
782646   // init cartridge
783647   if (m_cart != NULL && m_cart->exists())
784648   {
r245224r245225
802666   MCFG_TMS0270_WRITE_CTL_CB(DEVWRITE8("tms5100", tms5100_device, ctl_w))
803667   MCFG_TMS0270_WRITE_PDC_CB(DEVWRITELINE("tms5100", tms5100_device, pdc_w))
804668
805   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", tispeak_state, display_decay_tick, attotime::from_msec(1))
669   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
806670   MCFG_DEFAULT_LAYOUT(layout_snspell) // max 9 digits
807671
808672   /* no video! */
trunk/src/mess/includes/hh_tms1k.h
r245224r245225
3030
3131   // devices
3232   required_device<cpu_device> m_maincpu;
33   optional_ioport_array<7> m_inp_matrix; // max 7
33   optional_ioport_array<11> m_inp_matrix; // max 11
3434   optional_device<speaker_sound_device> m_speaker;
3535
3636   // misc common
r245224r245225
5555
5656   TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick);
5757   void display_update();
58   void set_display_size(int maxx, int maxy);
5859   void display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety);
5960
6061   // game-specific handlers


Previous 199869 Revisions Next


© 1997-2024 The MAME Team