Previous 15994 Revisions Next

r15117 Monday 7th May, 2012 at 17:40:48 UTC by Sandro Ronco
tvc: Added sound. [Sandro Ronco]
[src/mess]mess.mak
[src/mess/audio]tvc.c*
[src/mess/drivers]tvc.c
[src/mess/includes]tvc.h*

src/mess/audio/tvc.c
r0r15117
1/***************************************************************************
2
3    Videotone TVC 32/64 sound emulation
4
5***************************************************************************/
6
7#include "emu.h"
8#include "includes/tvc.h"
9
10// device type definition
11const device_type TVC_SOUND = &device_creator<tvc_sound_device>;
12
13//-------------------------------------------------
14//  tvc_sound_device - constructor
15//-------------------------------------------------
16
17tvc_sound_device::tvc_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
18   : device_t(mconfig, TVC_SOUND, "TVC 64 Custom Sound", tag, owner, clock),
19     device_sound_interface(mconfig, *this)
20{
21}
22
23//-------------------------------------------------
24//  device_start - device-specific startup
25//-------------------------------------------------
26void tvc_sound_device::device_start()
27{
28   m_stream = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate(), this );
29}
30
31//-------------------------------------------------
32//  device_reset - device-specific reset
33//-------------------------------------------------
34void tvc_sound_device::device_reset()
35{
36   m_enabled = 0;
37   m_freq    = 0;
38   m_incr    = 0;
39   m_signal  = 1;
40
41}
42
43//-------------------------------------------------
44//  sound_stream_update - handle update requests for
45//  our sound stream
46//-------------------------------------------------
47
48void tvc_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
49{
50   int rate = machine().sample_rate() / 2;
51
52   if (m_enabled && m_freq)
53   {
54      while( samples-- > 0 )
55      {
56         *outputs[0]++ = m_signal * (m_volume * 0x0800);
57         m_incr -= m_freq;
58         while(m_incr < 0)
59         {
60            m_incr += rate;
61            m_signal = -m_signal;
62         }
63      }
64   }
65   else
66   {
67      // fill output with 0 if the sound is disabled
68      memset(outputs[0], 0, samples * sizeof(stream_sample_t));
69   }
70}
71
72
73
74//-------------------------------------------------
75//  ports write
76//-------------------------------------------------
77
78WRITE8_MEMBER(tvc_sound_device::write)
79{
80   m_stream->update();
81
82   m_ports[offset] = data;
83
84   switch(offset)
85   {
86      case 1:
87         m_enabled = BIT(data, 4);
88         // fall through
89
90      case 0:
91      {
92         UINT16 pitch = (m_ports[0] | (m_ports[1]<<8)) & 0x0fff;
93         m_freq = (pitch == 0x0fff) ? 0 : (int)(195312.5 / (4096 - pitch));
94         break;
95      }
96
97      case 2:
98         m_volume = (data>>2) & 0x0f;
99         break;
100   }
101}
src/mess/includes/tvc.h
r0r15117
1/*****************************************************************************
2 *
3 *   includes/tvc.h
4 *
5 ****************************************************************************/
6
7#pragma once
8
9#ifndef TVC_H_
10#define TVC_H_
11
12#include "cpu/z80/z80.h"
13#include "video/mc6845.h"
14#include "machine/ram.h"
15#include "imagedev/cartslot.h"
16
17#define      TVC_RAM_BANK   1
18#define      TVC_ROM_BANK   2
19
20//**************************************************************************
21//  TYPE DEFINITIONS
22//**************************************************************************
23
24// ======================> tvc_sound_device
25
26class tvc_sound_device : public device_t,
27                   public device_sound_interface
28{
29public:
30   // construction/destruction
31   tvc_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
32
33   DECLARE_WRITE8_MEMBER(write);
34
35protected:
36   // device-level overrides
37   virtual void device_start();
38   virtual void device_reset();
39   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
40
41private:
42   sound_stream *   m_stream;
43   int            m_freq;
44   int            m_enabled;
45   int            m_volume;
46   int          m_incr;
47   int          m_signal;
48   UINT8         m_ports[3];
49};
50
51
52// ======================> tvc_state
53
54class tvc_state : public driver_device
55{
56public:
57   tvc_state(const machine_config &mconfig, device_type type, const char *tag)
58      : driver_device(mconfig, type, tag),
59        m_maincpu(*this, "maincpu"),
60        m_ram(*this, RAM_TAG),
61        m_sound(*this, "custom")
62      { }
63
64   required_device<cpu_device> m_maincpu;
65   required_device<ram_device> m_ram;
66   required_device<tvc_sound_device> m_sound;
67
68   void machine_start();
69   void machine_reset();
70
71   void tvc_set_mem_page(UINT8 data);
72   DECLARE_WRITE8_MEMBER(tvc_bank_w);
73   DECLARE_WRITE8_MEMBER(tvc_palette_w);
74   DECLARE_WRITE8_MEMBER(tvc_keyboard_w);
75   DECLARE_READ8_MEMBER(tvc_keyboard_r);
76   DECLARE_READ8_MEMBER(tvc_int_state_r);
77   DECLARE_WRITE8_MEMBER(tvc_flipflop_w);
78   DECLARE_READ8_MEMBER(tvc_exp_id_r);
79   DECLARE_WRITE8_MEMBER(tvc_border_color_w);
80   DECLARE_WRITE8_MEMBER(tvc_sound_w);
81
82   UINT8      m_video_mode;
83   UINT8      m_keyline;
84   UINT8      m_flipflop;
85   UINT8      m_col[4];
86   UINT8      m_bank_type[2];
87};
88
89
90// device type definition
91extern const device_type TVC_SOUND;
92
93#endif /* TVC_H_ */
src/mess/drivers/tvc.c
r15116r15117
55        12/05/2009 Skeleton driver.
66
77        TODO:
8        - add sound
98        - cassette load/save
109        - floppy interface
1110        - expansion ports
r15116r15117
1312****************************************************************************/
1413
1514#include "emu.h"
16#include "cpu/z80/z80.h"
17#include "video/mc6845.h"
18#include "machine/ram.h"
19#include "imagedev/cartslot.h"
15#include "includes/tvc.h"
2016
21
22class tvc_state : public driver_device
17void tvc_state::tvc_set_mem_page(UINT8 data)
2318{
24public:
25   tvc_state(const machine_config &mconfig, device_type type, const char *tag)
26      : driver_device(mconfig, type, tag) { }
27
28   UINT8 m_video_mode;
29   UINT8 m_keyline;
30   UINT8 m_flipflop;
31   UINT8 m_col[4];
32   DECLARE_WRITE8_MEMBER(tvc_bank_w);
33   DECLARE_WRITE8_MEMBER(tvc_video_mode_w);
34   DECLARE_WRITE8_MEMBER(tvc_palette_w);
35   DECLARE_WRITE8_MEMBER(tvc_keyboard_w);
36   DECLARE_READ8_MEMBER(tvc_keyboard_r);
37   DECLARE_READ8_MEMBER(tvc_flipflop_r);
38   DECLARE_WRITE8_MEMBER(tvc_flipflop_w);
39   DECLARE_READ8_MEMBER(tvc_port59_r);
40   DECLARE_WRITE8_MEMBER(tvc_port0_w);
41};
42
43
44
45static void tvc_set_mem_page(running_machine &machine, UINT8 data)
46{
47   tvc_state *state = machine.driver_data<tvc_state>();
48   address_space *space = machine.device("maincpu")->memory().space(AS_PROGRAM);
49   switch(data & 0x18) {
19   address_space *space = m_maincpu->memory().space(AS_PROGRAM);
20   switch(data & 0x18)
21   {
5022      case 0x00 : // system ROM selected
23         if (m_bank_type[0] != TVC_ROM_BANK)
24         {
5125            space->install_read_bank(0x0000, 0x3fff, "bank1");
5226            space->unmap_write(0x0000, 0x3fff);
53            state->membank("bank1")->set_base(machine.root_device().memregion("sys")->base());
54            break;
27            m_bank_type[0] = TVC_ROM_BANK;
28         }
29         membank("bank1")->set_base(memregion("sys")->base());
30         break;
5531      case 0x08 : // Cart ROM selected
32         if (m_bank_type[0] != TVC_ROM_BANK)
33         {
5634            space->install_read_bank(0x0000, 0x3fff, "bank1");
5735            space->unmap_write(0x0000, 0x3fff);
58            state->membank("bank1")->set_base(machine.root_device().memregion("cart")->base());
59            break;
36            m_bank_type[0] = TVC_ROM_BANK;
37         }
38         membank("bank1")->set_base(memregion("cart")->base());
39         break;
6040      case 0x10 : // RAM selected
41         if (m_bank_type[0] != TVC_RAM_BANK)
42         {
6143            space->install_readwrite_bank(0x0000, 0x3fff, "bank1");
62            state->membank("bank1")->set_base(machine.device<ram_device>(RAM_TAG)->pointer());
63            break;
44            m_bank_type[0] = TVC_RAM_BANK;
45         }
46         membank("bank1")->set_base(m_ram->pointer());
47         break;
6448   }
6549   // Bank 2 is always RAM
66   state->membank("bank2")->set_base(machine.device<ram_device>(RAM_TAG)->pointer() + 0x4000);
50   membank("bank2")->set_base(m_ram->pointer() + 0x4000);
6751   if ((data & 0x20)==0) {
6852      // Video RAM
69      state->membank("bank3")->set_base(machine.device<ram_device>(RAM_TAG)->pointer() + 0x10000);
53      membank("bank3")->set_base(m_ram->pointer() + 0x10000);
7054   } else {
7155      // System RAM page 3
72      state->membank("bank3")->set_base(machine.device<ram_device>(RAM_TAG)->pointer() + 0x8000);
56      membank("bank3")->set_base(m_ram->pointer() + 0x8000);
7357   }
74   switch(data & 0xc0) {
58   switch(data & 0xc0)
59   {
7560      case 0x00 : // Cart ROM selected
61         if (m_bank_type[1] != TVC_ROM_BANK)
62         {
7663            space->install_read_bank(0xc000, 0xffff, "bank4");
7764            space->unmap_write(0xc000, 0xffff);
78            state->membank("bank4")->set_base(machine.root_device().memregion("cart")->base());
79            break;
65            m_bank_type[1] = TVC_ROM_BANK;
66         }
67         membank("bank4")->set_base(memregion("cart")->base());
68         break;
8069      case 0x40 : // System ROM selected
70         if (m_bank_type[1] != TVC_ROM_BANK)
71         {
8172            space->install_read_bank(0xc000, 0xffff, "bank4");
8273            space->unmap_write(0xc000, 0xffff);
83            state->membank("bank4")->set_base(machine.root_device().memregion("sys")->base());
84            break;
74            m_bank_type[1] = TVC_ROM_BANK;
75         }
76         membank("bank4")->set_base(memregion("sys")->base());
77         break;
8578      case 0x80 : // RAM selected
79         if (m_bank_type[1] != TVC_RAM_BANK)
80         {
8681            space->install_readwrite_bank(0xc000, 0xffff, "bank4");
87            state->membank("bank4")->set_base(machine.device<ram_device>(RAM_TAG)->pointer()+0xc000);
88            break;
82            m_bank_type[1] = TVC_RAM_BANK;
83         }
84         membank("bank4")->set_base(m_ram->pointer()+0xc000);
85         break;
8986      case 0xc0 : // External ROM selected
87         if (m_bank_type[1] != TVC_ROM_BANK)
88         {
9089            space->install_read_bank(0xc000, 0xffff, "bank4");
9190            space->unmap_write(0xc000, 0xffff);
92            state->membank("bank4")->set_base(machine.root_device().memregion("ext")->base());
93            break;
94
91            m_bank_type[1] = TVC_ROM_BANK;
92         }
93         membank("bank4")->set_base(memregion("ext")->base());
94         break;
9595   }
9696}
9797
9898WRITE8_MEMBER(tvc_state::tvc_bank_w)
9999{
100   tvc_set_mem_page(machine(), data);
100   tvc_set_mem_page(data);
101101}
102102
103WRITE8_MEMBER(tvc_state::tvc_video_mode_w)
104{
105   m_video_mode = data & 0x03;
106}
107
108
109103WRITE8_MEMBER(tvc_state::tvc_palette_w)
110104{
111105   //  0 I 0 G | 0 R 0 B
r15116r15117
129123   return ioport(keynames[m_keyline & 0x0f])->read();
130124}
131125
132READ8_MEMBER(tvc_state::tvc_flipflop_r)
126READ8_MEMBER(tvc_state::tvc_int_state_r)
133127{
134   return m_flipflop;
128   /*
129        x--- ----   ACK from printer
130        -x-- ----   colour
131        --x- ----   cassette input
132        ---x ----   vblank or tone interrupt
133        ---- xxxx   expansions interrupt
134    */
135
136   return 0x40 | (m_flipflop << 4);
135137}
136138
137139WRITE8_MEMBER(tvc_state::tvc_flipflop_w)
138140{
139   m_flipflop |= 0x10;
141   // every write here clears the vblank flipflop
142   m_flipflop = 1;
143   device_set_input_line(m_maincpu, 0, CLEAR_LINE);
140144}
141READ8_MEMBER(tvc_state::tvc_port59_r)
145
146READ8_MEMBER(tvc_state::tvc_exp_id_r)
142147{
148   // TODO: read expansion slot ID
143149   return 0xff;
144150}
145151
146WRITE8_MEMBER(tvc_state::tvc_port0_w)
152WRITE8_MEMBER(tvc_state::tvc_border_color_w)
147153{
154   // x-x- x-x-    border color (I G R B)
148155}
156
157
158WRITE8_MEMBER(tvc_state::tvc_sound_w)
159{
160   switch(offset)
161   {
162      case 1:
163         // bit 6-7 - cassette motors
164         break;
165      case 2:
166         // bit 0-1 - video mode
167         m_video_mode = data & 0x03;
168         break;
169   }
170
171   // sound ports
172   m_sound->write(space, offset, data);
173}
174
175
149176static ADDRESS_MAP_START(tvc_mem, AS_PROGRAM, 8, tvc_state )
150177   AM_RANGE(0x0000, 0x3fff) AM_RAMBANK("bank1")
151178   AM_RANGE(0x4000, 0x7fff) AM_RAMBANK("bank2")
r15116r15117
156183static ADDRESS_MAP_START( tvc_io , AS_IO, 8, tvc_state )
157184   ADDRESS_MAP_UNMAP_HIGH
158185   ADDRESS_MAP_GLOBAL_MASK(0xff)
159   AM_RANGE(0x00, 0x00) AM_WRITE(tvc_port0_w)
186   AM_RANGE(0x00, 0x00) AM_WRITE(tvc_border_color_w)
160187   AM_RANGE(0x02, 0x02) AM_WRITE(tvc_bank_w)
161188   AM_RANGE(0x03, 0x03) AM_WRITE(tvc_keyboard_w)
162   AM_RANGE(0x06, 0x06) AM_WRITE(tvc_video_mode_w)
189   AM_RANGE(0x04, 0x06) AM_WRITE(tvc_sound_w)
163190   AM_RANGE(0x07, 0x07) AM_WRITE(tvc_flipflop_w)
164191   AM_RANGE(0x58, 0x58) AM_READ(tvc_keyboard_r)
165   AM_RANGE(0x59, 0x59) AM_READ(tvc_flipflop_r)
166   AM_RANGE(0x5a, 0x5a) AM_READ(tvc_port59_r)
192   AM_RANGE(0x59, 0x59) AM_READ(tvc_int_state_r)
193   AM_RANGE(0x5a, 0x5a) AM_READ(tvc_exp_id_r)
167194   AM_RANGE(0x60, 0x63) AM_WRITE(tvc_palette_w)
168195   AM_RANGE(0x70, 0x70) AM_DEVWRITE("crtc", mc6845_device, address_w)
169196   AM_RANGE(0x71, 0x71) AM_DEVREADWRITE("crtc", mc6845_device, register_r, register_w)
r15116r15117
269296INPUT_PORTS_END
270297
271298
272static MACHINE_START(tvc)
299void tvc_state::machine_start()
273300{
274   tvc_state *state = machine.driver_data<tvc_state>();
275   int i;
301   for (int i=0; i<4; i++)
302      m_col[i] = i;
276303
277   for (i=0; i<4; i++)
278      state->m_col[i] = i;
279
280   state->m_flipflop = 0xff;
304   m_flipflop = 0;
281305}
282306
283static MACHINE_RESET(tvc)
307void tvc_state::machine_reset()
284308{
285   tvc_state *state = machine.driver_data<tvc_state>();
286   memset(machine.device<ram_device>(RAM_TAG)->pointer(),0,(64+14)*1024);
287   tvc_set_mem_page(machine, 0);
288   state->m_video_mode = 0;
309   memset(m_ram->pointer(), 0, m_ram->size());
310   tvc_set_mem_page(0);
311   m_video_mode = 0;
289312}
290313
291static VIDEO_START( tvc )
292{
293}
294
295314static MC6845_UPDATE_ROW( tvc_update_row )
296315{
297316   tvc_state *state = device->machine().driver_data<tvc_state>();
r15116r15117
305324            for ( i = 0; i < x_count; i++ )
306325            {
307326               UINT16 offset = i  + (y * 64);
308               UINT8 data = device->machine().device<ram_device>(RAM_TAG)->pointer()[ offset + 0x10000];
327               UINT8 data = state->m_ram->pointer()[offset + 0x10000];
309328               *p++ = palette[state->m_col[BIT(data,7)]];
310329               *p++ = palette[state->m_col[BIT(data,6)]];
311330               *p++ = palette[state->m_col[BIT(data,5)]];
r15116r15117
322341            for ( i = 0; i < x_count; i++ )
323342            {
324343               UINT16 offset = i  + (y * 64);
325               UINT8 data = device->machine().device<ram_device>(RAM_TAG)->pointer()[ offset + 0x10000];
344               UINT8 data = state->m_ram->pointer()[offset + 0x10000];
326345               *p++ = palette[state->m_col[BIT(data,3)*2 + BIT(data,7)]];
327346               *p++ = palette[state->m_col[BIT(data,3)*2 + BIT(data,7)]];
328347               *p++ = palette[state->m_col[BIT(data,2)*2 + BIT(data,6)]];
r15116r15117
339358            for ( i = 0; i < x_count; i++ )
340359            {
341360               UINT16 offset = i  + (y * 64);
342               UINT8 data = device->machine().device<ram_device>(RAM_TAG)->pointer()[ offset + 0x10000];
361               UINT8 data = state->m_ram->pointer()[offset + 0x10000];
343362               UINT8 col0 = ((data & 0x80)>>4) | ((data & 0x20)>>4) | ((data & 0x08)>>1) | ((data & 0x02)>>1);
344363               UINT8 col1 = ((data & 0x40)>>3) | ((data & 0x10)>>3) | (data & 0x04) | (data & 0x01);
345364               *p++ = palette[col0];
r15116r15117
400419static INTERRUPT_GEN( tvc_interrupt )
401420{
402421   tvc_state *state = device->machine().driver_data<tvc_state>();
403   state->m_flipflop  &= ~0x10;
404   device_set_input_line(device, 0, HOLD_LINE);
422   state->m_flipflop  = 0;
423   device_set_input_line(device, 0, ASSERT_LINE);
405424}
406425
407426static MACHINE_CONFIG_START( tvc, tvc_state )
r15116r15117
410429    MCFG_CPU_PROGRAM_MAP(tvc_mem)
411430    MCFG_CPU_IO_MAP(tvc_io)
412431
413    MCFG_MACHINE_START(tvc)
414    MCFG_MACHINE_RESET(tvc)
415
416432   MCFG_CPU_VBLANK_INT("screen", tvc_interrupt)
417433
418 /* video hardware */
434   /* video hardware */
419435   MCFG_SCREEN_ADD("screen", RASTER)
420436   MCFG_SCREEN_REFRESH_RATE(50)
421437   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
r15116r15117
426442   MCFG_PALETTE_LENGTH( 16 )
427443   MCFG_PALETTE_INIT(tvc)
428444
429   MCFG_MC6845_ADD("crtc", MC6845, 3125000, tvc_crtc6845_interface) // clk taken from schematics
445   MCFG_MC6845_ADD("crtc", MC6845, 3125000/2, tvc_crtc6845_interface) // clk taken from schematics
430446
431    MCFG_VIDEO_START(tvc)
432
433447   /* internal ram */
434448   MCFG_RAM_ADD(RAM_TAG)
435449   MCFG_RAM_DEFAULT_SIZE("80K")
436450
451   /* sound hardware */
452   MCFG_SPEAKER_STANDARD_MONO("mono")
453   MCFG_SOUND_ADD("custom", TVC_SOUND, 0)
454   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
455
456   /* cartridge */
437457   MCFG_CARTSLOT_ADD("cart")
438458   MCFG_CARTSLOT_EXTENSION_LIST("crt,rom,bin")
439459   MCFG_CARTSLOT_NOT_MANDATORY
src/mess/mess.mak
r15116r15117
387387   $(MESSOBJ)/unisys.a \
388388   $(MESSOBJ)/veb.a \
389389   $(MESSOBJ)/vidbrain.a \
390   $(MESSOBJ)/videoton.a \
390391   $(MESSOBJ)/visual.a \
391392   $(MESSOBJ)/votrax.a \
392393   $(MESSOBJ)/vtech.a \
r15116r15117
18041805   $(MESS_DRIVERS)/vidbrain.o   \
18051806   $(MESS_VIDEO)/vidbrain.o   \
18061807
1808$(MESSOBJ)/videoton.a:         \
1809   $(MESS_DRIVERS)/tvc.o      \
1810   $(MESS_AUDIO)/tvc.o      \
1811
18071812$(MESSOBJ)/visual.a:         \
18081813   $(MESS_DRIVERS)/v1050.o      \
18091814   $(MESS_VIDEO)/v1050.o      \
r15116r15117
19401945   $(MESS_DRIVERS)/tim011.o   \
19411946   $(MESS_DRIVERS)/tricep.o   \
19421947   $(MESS_DRIVERS)/tsispch.o   \
1943   $(MESS_DRIVERS)/tvc.o      \
19441948   $(MESS_DRIVERS)/unior.o      \
19451949   $(MESS_DRIVERS)/unistar.o   \
19461950   $(MESS_DRIVERS)/v6809.o      \

Previous 15994 Revisions Next


© 1998-2018 The MESS Team