Previous 199869 Revisions Next

r31435 Sunday 27th July, 2014 at 04:44:42 UTC by hap
added cc40 system ram addressing and configurable ramsize
[src/mess/drivers]cc40.c

trunk/src/mess/drivers/cc40.c
r31434r31435
5757
5858
5959  TODO:
60  - other RAM configurations (6KB(default), 18KB, external)
61  - understand bus_control_r/w
60  - external RAM cartridge (bus_control_w cartridge memory addressing)
61  - auto clock divider on slow memory access
6262  - Hexbus interface and peripherals
6363    * HX-1000: color plotter
6464    * HX-1010: thermal printer
r31434r31435
8585      : driver_device(mconfig, type, tag),
8686      m_maincpu(*this, "maincpu"),
8787      m_dac(*this, "dac")
88   { }
88   {
89      m_sysram[0] = NULL;
90      m_sysram[1] = NULL;
91   }
8992
9093   required_device<tms70c20_device> m_maincpu;
9194   required_device<dac_device> m_dac;
9295
96   nvram_device *m_nvram[2];
9397   ioport_port *m_key_matrix[8];
9498
99   UINT8 m_bus_control;
95100   UINT8 m_power;
96101   UINT8 m_banks;
97102   UINT8 m_clock_control;
103   UINT8 m_clock_divider;
98104   UINT8 m_key_select;
105   
106   UINT8 *m_sysram[2];
107   UINT16 m_sysram_size[2];
108   UINT16 m_sysram_end[2];
109   UINT16 m_sysram_mask[2];
99110
111   void postload();
112   void init_sysram(int chip, UINT16 size);
100113   void update_lcd_indicator(UINT8 y, UINT8 x, int state);
114   void update_clock_divider();
101115
116   DECLARE_READ8_MEMBER(sysram_r);
117   DECLARE_WRITE8_MEMBER(sysram_w);
102118   DECLARE_READ8_MEMBER(bus_control_r);
103119   DECLARE_WRITE8_MEMBER(bus_control_w);
104120   DECLARE_WRITE8_MEMBER(power_w);
r31434r31435
106122   DECLARE_READ8_MEMBER(battery_r);
107123   DECLARE_READ8_MEMBER(bankswitch_r);
108124   DECLARE_WRITE8_MEMBER(bankswitch_w);
109   DECLARE_READ8_MEMBER(clock_r);
110   DECLARE_WRITE8_MEMBER(clock_w);
125   DECLARE_READ8_MEMBER(clock_control_r);
126   DECLARE_WRITE8_MEMBER(clock_control_w);
111127   DECLARE_READ8_MEMBER(keyboard_r);
112128   DECLARE_WRITE8_MEMBER(keyboard_w);
113129
114130   virtual void machine_reset();
115131   virtual void machine_start();
116132   DECLARE_PALETTE_INIT(cc40);
133   DECLARE_INPUT_CHANGED_MEMBER(sysram_size_changed);
117134   DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cc40_cartridge);
118135};
119136
r31434r31435
210227
211228***************************************************************************/
212229
230READ8_MEMBER(cc40_state::sysram_r)
231{
232   // read system ram, based on addressing configured in bus_control_w
233   if (offset < m_sysram_end[0] && m_sysram_size[0] != 0)
234      return m_sysram[0][offset & (m_sysram_size[0] - 1)];
235   else if (offset < m_sysram_end[1] && m_sysram_size[1] != 0)
236      return m_sysram[1][(offset - m_sysram_end[0]) & (m_sysram_size[1] - 1)];
237   else
238      return 0xff;
239}
240
241WRITE8_MEMBER(cc40_state::sysram_w)
242{
243   // write system ram, based on addressing configured in bus_control_w
244   if (offset < m_sysram_end[0] && m_sysram_size[0] != 0)
245      m_sysram[0][offset & (m_sysram_size[0] - 1)] = data;
246   else if (offset < m_sysram_end[1] && m_sysram_size[1] != 0)
247      m_sysram[1][(offset - m_sysram_end[0]) & (m_sysram_size[1] - 1)] = data;
248}
249
213250READ8_MEMBER(cc40_state::bus_control_r)
214251{
215   // According to TI's official documentation, this register is set with predefined values
216   // describing system hardware configuration, but there doesn't seem to be any indication
217   // that it's used at all.
218   return 0x4c;
252   return m_bus_control;
219253}
220254
221255WRITE8_MEMBER(cc40_state::bus_control_w)
222256{
223   ;
257   // d0,d1: auto enable clock divider on cartridge memory access (d0: area 1, d1: area 2)
258
259   // d2,d3: system ram addressing
260   // 00: 8K, 8K @ $1000-$2fff, $3000-$4fff
261   // 01: 8K, 2K @ $1000-$2fff, $3000-$37ff
262   // 10: 2K, 8K @ $1000-$17ff, $1800-$37ff
263   // 11: 2K, 2K @ $1000-$17ff, $1800-$1fff
264   int d2 = (data & 4) ? 0x0800 : 0x2000;
265   int d3 = (data & 8) ? 0x0800 : 0x2000;
266   m_sysram_end[0] = d3;
267   m_sysram_mask[0] = d3 - 1;
268   m_sysram_end[1] = d3 + d2;
269   m_sysram_mask[1] = d2 - 1;
270   
271   // d4,d5: cartridge memory addressing
272   // 00: 2K @ $5000-$57ff & $5800-$5fff
273   // 01: 8K @ $5000-$6fff & $7000-$8fff
274   // 10:16K @ $5000-$8fff & $9000-$cfff
275   // 11: 8K @ $1000-$2fff & $3000-$4fff - system ram is disabled
276
277   // d6: auto enable clock divider on system rom access
278
279   // d7: unused?
280   m_bus_control = data;
224281}
225282
226283WRITE8_MEMBER(cc40_state::power_w)
r31434r31435
255312   // d0-d1: system rom bankswitch
256313   membank("sysbank")->set_entry(data & 3);
257314
258   // d2-d3: cartridge rom bankswitch
315   // d2-d3: cartridge 32KB page bankswitch
259316   membank("cartbank")->set_entry(data >> 2 & 3);
260317
261318   m_banks = data & 0x0f;
262319}
263320
264READ8_MEMBER(cc40_state::clock_r)
321READ8_MEMBER(cc40_state::clock_control_r)
265322{
266323   return m_clock_control;
267324}
268325
269WRITE8_MEMBER(cc40_state::clock_w)
326void cc40_state::update_clock_divider()
270327{
271   // d3: enable clock divider
272   if (data & 8)
328   // 2.5MHz /3 to /17 in steps of 2
329   m_clock_divider = (~m_clock_control & 7) * 2 + 1;
330   m_maincpu->set_clock_scale((m_clock_control & 8) ? (1.0 / (double)m_clock_divider) : 1);
331}
332
333WRITE8_MEMBER(cc40_state::clock_control_w)
334{
335   // d0-d2: clock divider
336   // d3: enable clock divider always
337   // other bits: unused?
338   if (m_clock_control != (data & 0x0f))
273339   {
274      if (m_clock_control != (data & 0x0f))
275      {
276         // d0-d2: clock divider (2.5MHz /3 to /17 in steps of 2)
277         double div = (~data & 7) * 2 + 1;
278         m_maincpu->set_clock_scale(1 / div);
279      }
340      m_clock_control = data;
341      update_clock_divider();
280342   }
281   else if (m_clock_control & 8)
282   {
283      // high to low
284      m_maincpu->set_clock_scale(1);
285   }
286
287   m_clock_control = data & 0x0f;
288343}
289344
290345READ8_MEMBER(cc40_state::keyboard_r)
r31434r31435
307362   m_key_select = data;
308363}
309364
310
311365static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, cc40_state )
312366   ADDRESS_MAP_UNMAP_HIGH
313367
314368   AM_RANGE(0x0110, 0x0110) AM_READWRITE(bus_control_r, bus_control_w)
315369   AM_RANGE(0x0111, 0x0111) AM_WRITE(power_w)
316   AM_RANGE(0x0112, 0x0112) AM_NOP // hexbus data
317   AM_RANGE(0x0113, 0x0113) AM_NOP // hexbus available
318   AM_RANGE(0x0114, 0x0114) AM_NOP // hexbus handshake
370   AM_RANGE(0x0112, 0x0112) AM_NOP // d0-d3: Hexbus data
371   AM_RANGE(0x0113, 0x0113) AM_NOP // d0: Hexbus available
372   AM_RANGE(0x0114, 0x0114) AM_NOP // d0,d1: Hexbus handshake
319373   AM_RANGE(0x0115, 0x0115) AM_WRITE(sound_w)
320374   AM_RANGE(0x0116, 0x0116) AM_READ(battery_r)
321375   AM_RANGE(0x0119, 0x0119) AM_READWRITE(bankswitch_r, bankswitch_w)
322   AM_RANGE(0x011a, 0x011a) AM_READWRITE(clock_r, clock_w)
376   AM_RANGE(0x011a, 0x011a) AM_READWRITE(clock_control_r, clock_control_w)
323377   AM_RANGE(0x011e, 0x011f) AM_DEVREADWRITE("hd44780", hd44780_device, read, write)
324378
325   AM_RANGE(0x0800, 0x0fff) AM_RAM AM_SHARE("nvram1")
326   AM_RANGE(0x1000, 0x17ff) AM_RAM AM_SHARE("nvram2")
327   AM_RANGE(0x3000, 0x37ff) AM_RAM AM_SHARE("nvram3")
328
379   AM_RANGE(0x0800, 0x0fff) AM_RAM AM_SHARE("sysram.0")
380   AM_RANGE(0x1000, 0x4fff) AM_READWRITE(sysram_r, sysram_w)
329381   AM_RANGE(0x5000, 0xcfff) AM_ROMBANK("cartbank")
330382   AM_RANGE(0xd000, 0xefff) AM_ROMBANK("sysbank")
331383ADDRESS_MAP_END
r31434r31435
343395
344396***************************************************************************/
345397
398INPUT_CHANGED_MEMBER(cc40_state::sysram_size_changed)
399{
400   init_sysram((int)(FPTR)param, newval << 11);
401}
402
346403static INPUT_PORTS_START( cc40 )
404   PORT_START("RAMSIZE")
405   PORT_CONFNAME( 0x07, 0x01, "RAM Chip 1") PORT_CHANGED_MEMBER(DEVICE_SELF, cc40_state, sysram_size_changed, (void *)0)
406   PORT_CONFSETTING(    0x00, "None" )
407   PORT_CONFSETTING(    0x01, "2KB" )
408   PORT_CONFSETTING(    0x04, "8KB" )
409   PORT_CONFNAME( 0x70, 0x10, "RAM Chip 2") PORT_CHANGED_MEMBER(DEVICE_SELF, cc40_state, sysram_size_changed, (void *)1)
410   PORT_CONFSETTING(    0x00, "None" )
411   PORT_CONFSETTING(    0x10, "2KB" )
412   PORT_CONFSETTING(    0x40, "8KB" )
413
347414   // 8x8 keyboard matrix, RESET and ON buttons are not on it. Unused entries are not connected, but some might have a purpose for factory testing(?)
348415   // The numpad number keys are shared with the ones on the main keyboard, also on the real machine.
349416   // PORT_NAME lists functions under [SHIFT] as secondaries.
r31434r31435
440507{
441508   m_power = 1;
442509
510   update_clock_divider();
511
443512   address_space &space = m_maincpu->space(AS_PROGRAM);
444513   bankswitch_w(space, 0, 0);
445514}
446515
516void cc40_state::init_sysram(int chip, UINT16 size)
517{
518   if (m_sysram[chip] == NULL)
519   {
520      // init to largest possible
521      m_sysram[chip] = auto_alloc_array(machine(), UINT8, 0x2000);
522      save_pointer(NAME(m_sysram[chip]), 0x2000, chip);
523     
524      save_item(NAME(m_sysram_size[chip]), chip);
525      save_item(NAME(m_sysram_end[chip]), chip);
526      save_item(NAME(m_sysram_mask[chip]), chip);
527   }
528   
529   m_nvram[chip]->set_base(m_sysram[chip], size);
530   m_sysram_size[chip] = size;
531}
532
533void cc40_state::postload()
534{
535   init_sysram(0, m_sysram_size[0]);
536   init_sysram(1, m_sysram_size[1]);
537
538   update_clock_divider();
539}
540
447541void cc40_state::machine_start()
448542{
543   // init
449544   static const char *const tags[] = { "IN0", "IN1", "IN2", "IN3", "IN4", "IN5", "IN6", "IN7" };
450545   for (int i = 0; i < 8; i++)
451546      m_key_matrix[i] = ioport(tags[i]);
r31434r31435
453548   membank("sysbank")->configure_entries(0, 4, memregion("system")->base(), 0x2000);
454549   membank("cartbank")->configure_entries(0, 4, memregion("user1")->base(), 0x8000);
455550
456   // zerofill
551   m_nvram[0] = machine().device<nvram_device>("sysram.1");
552   m_nvram[1] = machine().device<nvram_device>("sysram.2");
553   init_sysram(0, 0x800);
554   init_sysram(1, 0x800);
555
556   address_space &space = m_maincpu->space(AS_PROGRAM);
557   bus_control_w(space, 0, 0);
558   bankswitch_w(space, 0, 0);
559
560   // zerofill other
457561   m_power = 0;
458   m_banks = 0;
459562   m_clock_control = 0;
460563   m_key_select = 0;
461564
462565   // register for savestates
566   save_item(NAME(m_bus_control));
463567   save_item(NAME(m_power));
464568   save_item(NAME(m_banks));
465569   save_item(NAME(m_clock_control));
570   save_item(NAME(m_clock_divider));
466571   save_item(NAME(m_key_select));
572
573   machine().save().register_postload(save_prepost_delegate(FUNC(cc40_state::postload), this));
467574}
468575
469576static MACHINE_CONFIG_START( cc40, cc40_state )
r31434r31435
473580   MCFG_CPU_PROGRAM_MAP(main_map)
474581   MCFG_CPU_IO_MAP(main_io_map)
475582
476   MCFG_NVRAM_ADD_0FILL("nvram1")
477   MCFG_NVRAM_ADD_0FILL("nvram2")
478   MCFG_NVRAM_ADD_0FILL("nvram3")
583   MCFG_NVRAM_ADD_0FILL("sysram.0")
584   MCFG_NVRAM_ADD_0FILL("sysram.1")
585   MCFG_NVRAM_ADD_0FILL("sysram.2")
479586
480587   /* video hardware */
481588   MCFG_SCREEN_ADD("screen", LCD)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team