Previous 199869 Revisions Next

r24848 Sunday 11th August, 2013 at 21:29:58 UTC by R. Belmont
(MESS) MPU-401: preliminary checkpoint. [R. Belmont, kevtris]
[src/mess]mess.mak
[src/mess/machine]isa_mpu401.c isa_mpu401.h mpu401.c* mpu401.h*

trunk/src/mess/mess.mak
r24847r24848
751751   $(MESS_MACHINE)/midiinport.o    \
752752   $(MESS_MACHINE)/midioutport.o   \
753753   $(MESS_MACHINE)/mpc105.o    \
754   $(MESS_MACHINE)/mpu401.o \
754755   $(MESS_MACHINE)/msm6222b.o  \
755756   $(MESS_MACHINE)/ncr5380.o   \
756757   $(MESS_MACHINE)/ncr5380n.o  \
r24847r24848
791792   $(MESS_MACHINE)/isa_gus.o   \
792793   $(MESS_MACHINE)/isa_hdc.o   \
793794   $(MESS_MACHINE)/isa_ibm_mfc.o   \
794   $(MESS_MACHINE)/isa_mpu401.o\
795   $(MESS_MACHINE)/isa_mpu401.o \
795796   $(MESS_MACHINE)/isa_sblaster.o  \
796797   $(MESS_MACHINE)/isa_stereo_fx.o \
797798   $(MESS_MACHINE)/isa_ssi2001.o   \
trunk/src/mess/machine/mpu401.c
r0r24848
1/***************************************************************************
2
3  Roland MPU-401 core
4
5  This emulates the MPU-401 external box with the 6801, ASIC, and RAM in it.
6 
7  We do it this way to facilitate the various PC, Apple II, C64, and other
8  possible hookups.
9 
10  6801 GPIO port hookups (from the schematics)
11 
12  P10 / P11 / P12: drive the metronome and speaker
13  P13 / P14 / P15: drive 3 pins on the SYNC OUT connector
14  P16: to DSRD on gate array
15  P17: to DRRD on gate array
16 
17  P20: to SYC OUT on gate array
18  P21: to SYC IN on gate array, pulled up to Vcc via 4.7K resistor
19      programmed as output of timer (OLVL)
20  P22: to SRCK on gate array, inverted
21  P23: MIDI IN serial data (SCI in)
22  P24: MIDI OUT serial data (SCI out)
23 
24  ASIC addresses from the 6801:
25  0x20: (r) read pending byte from the PC (w) apparently nothing
26  0x21: (r) ASIC status, see STAT_xxx bits below (w) send new byte to PC data port
27 
28  Theory of operation: 6801's timer/counter is set up to drive a pulse stream
29  out P21 to the ASIC's SYC IN pin.  The ASIC in turn generates the MIDI baud
30  rate (times 8) and returns that on pin P22.
31 
32  The 6801 is believed to run in mode 2, based on a combination of the
33  schematics and the behavior (ie, internal RAM from 80-FF is clearly
34  present from the program's behavior, and ports 3/4 are obviously external
35  address/data buses)
36
37***************************************************************************/
38
39#include "machine/mpu401.h"
40
41#define M6801_TAG   "mpu6801"
42#define ROM_TAG      "mpurom"
43
44#define P2_SYNC_OUT   (0x01)
45#define P2_SYNC_IN   (0x02)
46#define P2_SRCK_OUT   (0x04)
47#define P2_MIDI_IN   (0x08)
48#define P2_MIDI_OUT   (0x10)
49
50#define STAT_CMD_PORT (0x01)   // set if the new byte indicated by TX FULL was written to the command port, clear for data port
51#define STAT_TX_FULL  (0x40)   // indicates the PC has written a new byte we haven't read yet
52#define STAT_RX_EMPTY (0x80)   // indicates we've written a new byte the PC hasn't read yet
53
54static ADDRESS_MAP_START( mpu401_map, AS_PROGRAM, 8, mpu401_device )
55   AM_RANGE(0x0000, 0x001f) AM_READWRITE(regs_mode2_r, regs_mode2_w)
56   AM_RANGE(0x0020, 0x0021) AM_READWRITE(asic_r, asic_w)
57   AM_RANGE(0x0080, 0x00ff) AM_RAM   // on-chip RAM
58   AM_RANGE(0x0800, 0x0fff) AM_RAM   // external RAM
59   AM_RANGE(0xf000, 0xffff) AM_ROM AM_REGION(ROM_TAG, 0)
60ADDRESS_MAP_END
61
62static ADDRESS_MAP_START( mpu401_io_map, AS_IO, 8, mpu401_device )
63   AM_RANGE(M6801_PORT1, M6801_PORT1) AM_READWRITE(port1_r, port1_w)
64   AM_RANGE(M6801_PORT2, M6801_PORT2) AM_READWRITE(port2_r, port2_w)
65ADDRESS_MAP_END
66
67MACHINE_CONFIG_FRAGMENT( mpu401 )
68   MCFG_CPU_ADD(M6801_TAG, M6801, 4000000)   /* 4 MHz as per schematics */
69   MCFG_CPU_PROGRAM_MAP(mpu401_map)
70   MCFG_CPU_IO_MAP(mpu401_io_map)
71MACHINE_CONFIG_END
72
73ROM_START( mpu401 )
74   ROM_REGION(0x1000, ROM_TAG, 0)
75   ROM_LOAD( "roland_6801v0b55p.bin", 0x000000, 0x001000, CRC(65d3a151) SHA1(00efbfb96aeb997b69bb16981c6751d3c784bb87) )
76ROM_END
77
78//**************************************************************************
79//  GLOBAL VARIABLES
80//**************************************************************************
81
82const device_type MPU401 = &device_creator<mpu401_device>;
83
84//-------------------------------------------------
85//  machine_config_additions - device-specific
86//  machine configurations
87//-------------------------------------------------
88
89machine_config_constructor mpu401_device::device_mconfig_additions() const
90{
91   return MACHINE_CONFIG_NAME( mpu401 );
92}
93
94//-------------------------------------------------
95//  rom_region - device-specific ROM region
96//-------------------------------------------------
97
98const rom_entry *mpu401_device::device_rom_region() const
99{
100   return ROM_NAME( mpu401 );
101}
102
103//**************************************************************************
104//  LIVE DEVICE
105//**************************************************************************
106
107//-------------------------------------------------
108//  mpu401_device - constructor
109//-------------------------------------------------
110
111mpu401_device::mpu401_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
112   device_t(mconfig, MPU401, "Roland MPU-401", tag, owner, clock, "mpu401", __FILE__),
113   m_ourcpu(*this, M6801_TAG),
114   write_irq(*this)
115{
116}
117
118//-------------------------------------------------
119//  device_start - device-specific startup
120//-------------------------------------------------
121
122void mpu401_device::device_start()
123{
124   write_irq.resolve_safe();
125}
126
127//-------------------------------------------------
128//  device_reset - device-specific reset
129//-------------------------------------------------
130
131void mpu401_device::device_reset()
132{
133   m_port2 = 0xff & ~P2_SRCK_OUT;
134   m_command = 0;
135   m_mpudata = 0;
136   m_gatearrstat = 0;
137}
138
139READ8_MEMBER(mpu401_device::regs_mode2_r)
140{
141   switch (offset)
142   {
143      case 4:
144      case 5:
145      case 6:
146      case 7:
147      case 0xf:
148         printf("MPU401: read @ unk %x (PC=%x)\n", offset, space.device().safe_pc());
149         break;
150
151      default:
152         return m_ourcpu->m6801_io_r(space, offset);
153   }
154
155   return 0xff;
156}
157
158WRITE8_MEMBER(mpu401_device::regs_mode2_w)
159{
160   switch (offset)
161   {
162      case 4:
163      case 5:
164      case 6:
165      case 7:
166      case 0xf:
167         printf("MPU401: %02x @ unk %x (PC=%x)\n", data, offset, space.device().safe_pc());
168         break;
169
170      default:
171         return m_ourcpu->m6801_io_w(space, offset, data);
172   }
173}
174
175READ8_MEMBER(mpu401_device::port1_r)
176{
177   return 0xff;
178}
179
180WRITE8_MEMBER(mpu401_device::port1_w)
181{
182   printf("port1_w: %02x met %x syncout %x DSRD %d DRRD %d\n", data, data & 3, (data>>3) & 3, (data>>6) & 1, (data>>7) & 1);
183}
184
185READ8_MEMBER(mpu401_device::port2_r)
186{
187   printf("Read P2 (PC=%x)\n", space.device().safe_pc());
188   return m_port2;
189}
190
191WRITE8_MEMBER(mpu401_device::port2_w)
192{
193   printf("port2_w: %02x SYCOUT %d SYCIN %d SRCK %d MIDI OUT %d\n", data, (data & 1), (data>>1) & 1, (data>>2) & 1, (data>>4) & 1);
194}
195
196READ8_MEMBER(mpu401_device::mpu_r)
197{
198//   printf("mpu_r @ %d\n", offset);
199
200   if (offset == 1)   // status
201   {
202      return m_gatearrstat;
203   }
204   else            // data
205   {
206      write_irq(CLEAR_LINE);
207      m_gatearrstat |= STAT_RX_EMPTY;
208      return m_mpudata;
209   }
210}
211
212WRITE8_MEMBER(mpu401_device::mpu_w)
213{
214//   printf("%02x to MPU-401 @ %d\n", data, offset);
215   m_command = data;
216   m_gatearrstat |= STAT_TX_FULL;
217
218   if (offset == 1)
219   {
220      m_gatearrstat |= STAT_CMD_PORT;
221   }
222}
223
224READ8_MEMBER(mpu401_device::asic_r)
225{
226   if (offset == 0)
227   {
228      m_gatearrstat &= ~STAT_TX_FULL;
229      return m_command;
230   }
231   else if (offset == 1)
232   {
233      return m_gatearrstat;
234   }
235
236   return 0xff;
237}
238
239WRITE8_MEMBER(mpu401_device::asic_w)
240{
241//   printf("MPU401: %02x to gate array @ %d\n", data, offset);
242
243   if (offset == 1)
244   {
245      m_mpudata = data;
246      m_gatearrstat &= ~STAT_RX_EMPTY;
247      write_irq(ASSERT_LINE);
248   }
249}
250
Property changes on: trunk/src/mess/machine/mpu401.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mess/machine/mpu401.h
r0r24848
1#pragma once
2
3#ifndef __MPU401_H__
4#define __MPU401_H__
5
6#include "emu.h"
7#include "cpu/m6800/m6800.h"
8
9#define MCFG_MPU401_ADD(_tag, _irqf ) \
10   MCFG_DEVICE_ADD(_tag, MPU401, 0) \
11   MCFG_IRQ_FUNC(_irqf)
12
13#define MCFG_IRQ_FUNC(_irqf) \
14   downcast<mpu401_device *>(device)->set_irqf(DEVCB2_##_irqf);
15
16//**************************************************************************
17//  TYPE DEFINITIONS
18//**************************************************************************
19
20class mpu401_device : public device_t
21{
22public:
23   // construction/destruction
24   mpu401_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
25
26   // optional information overrides
27   virtual machine_config_constructor device_mconfig_additions() const;
28
29   required_device<m6801_cpu_device> m_ourcpu;
30
31   template<class _write> void set_irqf(_write wr)
32   {
33      write_irq.set_callback(wr);
34   }
35
36   devcb2_write_line write_irq;
37
38   DECLARE_READ8_MEMBER(regs_mode2_r);
39   DECLARE_WRITE8_MEMBER(regs_mode2_w);
40   DECLARE_READ8_MEMBER(asic_r);
41   DECLARE_WRITE8_MEMBER(asic_w);
42   DECLARE_READ8_MEMBER(port1_r);
43   DECLARE_WRITE8_MEMBER(port1_w);
44   DECLARE_READ8_MEMBER(port2_r);
45   DECLARE_WRITE8_MEMBER(port2_w);
46
47   // public API - call for reads/writes at I/O 330/331 on PC, C0n0/C0n1 on Apple II, etc.
48   DECLARE_READ8_MEMBER(mpu_r);
49   DECLARE_WRITE8_MEMBER(mpu_w);
50
51protected:
52   // device-level overrides
53   virtual void device_start();
54   virtual void device_reset();
55   virtual const rom_entry *device_rom_region() const;
56
57private:
58   UINT8 m_port2;
59   UINT8 m_command;
60   UINT8 m_mpudata;
61   UINT8 m_gatearrstat;
62};
63
64// device type definition
65extern const device_type MPU401;
66
67#endif  /* __MPU401_H__ */
68
69
Property changes on: trunk/src/mess/machine/mpu401.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/machine/isa_mpu401.c
r24847r24848
1111#include "isa_mpu401.h"
1212#include "machine/pic8259.h"
1313
14#define MPU_CORE_TAG "mpu401"
15
16MACHINE_CONFIG_FRAGMENT( isa8mpu401 )
17   MCFG_MPU401_ADD(MPU_CORE_TAG, WRITELINE(isa8_mpu401_device, mpu_irq_out))
18MACHINE_CONFIG_END
19
1420/*
1521DIP-SWs
16221-2-3-4
r24847r24848
2935      1  irq7
3036*/
3137
32READ8_MEMBER( isa8_mpu401_device::mpu401_r )
38WRITE_LINE_MEMBER( isa8_mpu401_device::mpu_irq_out )
3339{
34   UINT8 res;
35
36   if(offset == 0) // data
37   {
38      res = 0xff;
39   }
40   else // status
41   {
42      res = 0x3f | 0x80; // bit 7 queue empty (DSR), bit 6 DRR (Data Receive Ready?)
43   }
44
45   return res;
4640}
4741
48WRITE8_MEMBER( isa8_mpu401_device::mpu401_w )
49{
50   if(offset == 0) // data
51   {
52      printf("%02x %02x\n",offset,data);
53   }
54   else // command
55   {
56      printf("%02x %02x\n",offset,data);
57
58      switch(data)
59      {
60         case 0xff: // reset
61            //m_isa->irq2_w(1);
62            break;
63      }
64   }
65
66}
67
6842//**************************************************************************
6943//  GLOBAL VARIABLES
7044//**************************************************************************
7145
7246const device_type ISA8_MPU401 = &device_creator<isa8_mpu401_device>;
7347
48//-------------------------------------------------
49//  machine_config_additions - device-specific
50//  machine configurations
51//-------------------------------------------------
7452
53machine_config_constructor isa8_mpu401_device::device_mconfig_additions() const
54{
55   return MACHINE_CONFIG_NAME( isa8mpu401 );
56}
57
58
7559//**************************************************************************
7660//  LIVE DEVICE
7761//**************************************************************************
r24847r24848
8165//-------------------------------------------------
8266
8367isa8_mpu401_device::isa8_mpu401_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
84      : device_t(mconfig, ISA8_MPU401, "Roland MPU-401 Sound Card", tag, owner, clock, "isa_mpu401", __FILE__),
85      device_isa8_card_interface( mconfig, *this )
68      : device_t(mconfig, ISA8_MPU401, "Roland MPU-401 MIDI Interface", tag, owner, clock, "isa_mpu401", __FILE__),
69      device_isa8_card_interface( mconfig, *this ),
70      m_mpu401(*this, MPU_CORE_TAG)
8671{
8772}
8873
r24847r24848
9378void isa8_mpu401_device::device_start()
9479{
9580   set_isa_device();
96   m_isa->install_device(0x330, 0x0331, 0, 0, read8_delegate(FUNC(isa8_mpu401_device::mpu401_r), this), write8_delegate(FUNC(isa8_mpu401_device::mpu401_w), this));
81
82   m_isa->install_device(0x330, 0x0331, 0, 0, READ8_DEVICE_DELEGATE(m_mpu401, mpu401_device, mpu_r), WRITE8_DEVICE_DELEGATE(m_mpu401, mpu401_device, mpu_w));
9783}
9884
9985//-------------------------------------------------
trunk/src/mess/machine/isa_mpu401.h
r24847r24848
55
66#include "emu.h"
77#include "machine/isa.h"
8#include "machine/mpu401.h"
89
910//**************************************************************************
1011//  TYPE DEFINITIONS
r24847r24848
2021      // construction/destruction
2122      isa8_mpu401_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
2223
23      DECLARE_READ8_MEMBER(mpu401_r);
24      DECLARE_WRITE8_MEMBER(mpu401_w);
24      required_device<mpu401_device> m_mpu401;
25
26      // called back by the MPU401 core to set the IRQ line state
27      DECLARE_WRITE_LINE_MEMBER(mpu_irq_out);
28
2529      // optional information overrides
2630protected:
2731      // device-level overrides
2832      virtual void device_start();
2933      virtual void device_reset();
34      virtual machine_config_constructor device_mconfig_additions() const;
35
3036private:
3137      // internal state
3238};

Previous 199869 Revisions Next


© 1997-2024 The MAME Team