Previous 199869 Revisions Next

r18038 Thursday 20th September, 2012 at 12:00:57 UTC by Miodrag Milanović
decocass modernized and cleaned (no whatsnew)
[src/mame]mame.mak
[src/mame/drivers]decocass.c
[src/mame/includes]decocass.h*
[src/mame/machine]decocass.c decocass.h decocass_tape.c* decocass_tape.h*
[src/mame/video]decocass.c

trunk/src/mame/machine/decocass.h
r18037r18038
1#include "devlegcy.h"
2
3#ifdef MAME_DEBUG
4#define LOGLEVEL  5
5#else
6#define LOGLEVEL  0
7#endif
8#define LOG(n,x)  do { if (LOGLEVEL >= n) logerror x; } while (0)
9
10
11class decocass_tape_device : public device_t
12{
13public:
14   decocass_tape_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
15   ~decocass_tape_device() { global_free(m_token); }
16
17   // access to legacy token
18   void *token() const { assert(m_token != NULL); return m_token; }
19protected:
20   // device-level overrides
21   virtual void device_config_complete();
22   virtual void device_start();
23   virtual void device_reset();
24private:
25   // internal state
26   void *m_token;
27};
28
29extern const device_type DECOCASS_TAPE;
30
31
32#define MCFG_DECOCASS_TAPE_ADD(_tag) \
33   MCFG_DEVICE_ADD(_tag, DECOCASS_TAPE, 0)
34
35
36
37
38class decocass_state : public driver_device
39{
40public:
41   decocass_state(const machine_config &mconfig, device_type type, const char *tag)
42      : driver_device(mconfig, type, tag),
43        m_rambase(*this, "rambase"),
44        m_charram(*this, "charram"),
45        m_fgvideoram(*this, "fgvideoram"),
46        m_colorram(*this, "colorram"),
47        m_tileram(*this, "tileram"),
48        m_objectram(*this, "objectram"),
49        m_paletteram(*this, "paletteram") { }
50
51   /* memory pointers */
52   required_shared_ptr<UINT8> m_rambase;
53   required_shared_ptr<UINT8> m_charram;
54   required_shared_ptr<UINT8> m_fgvideoram;
55   required_shared_ptr<UINT8> m_colorram;
56   UINT8 *   m_bgvideoram;   /* shares bits D0-3 with tileram! */
57   required_shared_ptr<UINT8> m_tileram;
58   required_shared_ptr<UINT8> m_objectram;
59   required_shared_ptr<UINT8> m_paletteram;
60   size_t    m_bgvideoram_size;
61
62   /* video-related */
63   tilemap_t   *m_fg_tilemap;
64   tilemap_t   *m_bg_tilemap_l;
65   tilemap_t   *m_bg_tilemap_r;
66   INT32     m_watchdog_count;
67   INT32     m_watchdog_flip;
68   INT32     m_color_missiles;
69   INT32     m_color_center_bot;
70   INT32     m_mode_set;
71   INT32     m_back_h_shift;
72   INT32     m_back_vl_shift;
73   INT32     m_back_vr_shift;
74   INT32     m_part_h_shift;
75   INT32     m_part_v_shift;
76   INT32     m_center_h_shift_space;
77   INT32     m_center_v_shift;
78   rectangle m_bg_tilemap_l_clip;
79   rectangle m_bg_tilemap_r_clip;
80
81   /* sound-related */
82   UINT8     m_sound_ack;   /* sound latches, ACK status bits and NMI timer */
83   UINT8     m_audio_nmi_enabled;
84   UINT8     m_audio_nmi_state;
85
86   /* misc */
87   UINT8     *m_decrypted;
88   UINT8     *m_decrypted2;
89   INT32     m_firsttime;
90   UINT8     m_latch1;
91   UINT8     m_decocass_reset;
92   INT32     m_de0091_enable;   /* DE-0091xx daughter board enable */
93   UINT8     m_quadrature_decoder[4];   /* four inputs from the quadrature decoder (H1, V1, H2, V2) */
94   int       m_showmsg;      // for debugging purposes
95
96   /* i8041 */
97   UINT8     m_i8041_p1;
98   UINT8     m_i8041_p2;
99   int       m_i8041_p1_write_latch;
100   int       m_i8041_p1_read_latch;
101   int       m_i8041_p2_write_latch;
102   int       m_i8041_p2_read_latch;
103
104   /* dongles-related */
105   read8_space_func    m_dongle_r;
106   write8_space_func   m_dongle_w;
107
108   /* dongle type #1 */
109   UINT32    m_type1_inmap;
110   UINT32    m_type1_outmap;
111
112   /* dongle type #2: status of the latches */
113   INT32     m_type2_d2_latch;   /* latched 8041-STATUS D2 value */
114   INT32     m_type2_xx_latch;   /* latched value (D7-4 == 0xc0) ? 1 : 0 */
115   INT32     m_type2_promaddr;   /* latched PROM address A0-A7 */
116
117   /* dongle type #3: status and patches */
118   INT32     m_type3_ctrs;      /* 12 bit counter stage */
119   INT32     m_type3_d0_latch;   /* latched 8041-D0 value */
120   INT32     m_type3_pal_19;      /* latched 1 for PAL input pin-19 */
121   INT32     m_type3_swap;
122
123   /* dongle type #4: status */
124   INT32     m_type4_ctrs;      /* latched PROM address (E5x0 LSB, E5x1 MSB) */
125   INT32     m_type4_latch;      /* latched enable PROM (1100xxxx written to E5x1) */
126
127   /* dongle type #5: status */
128   INT32     m_type5_latch;      /* latched enable PROM (1100xxxx written to E5x1) */
129
130   /* DS Telejan */
131   UINT8     m_mux_data;
132
133   /* devices */
134   cpu_device *m_maincpu;
135   cpu_device *m_audiocpu;
136   device_t *m_mcu;
137   device_t *m_cassette;
138   DECLARE_DRIVER_INIT(decocass);
139   DECLARE_DRIVER_INIT(decocrom);
140   DECLARE_DRIVER_INIT(cdsteljn);
141   TILEMAP_MAPPER_MEMBER(fgvideoram_scan_cols);
142   TILEMAP_MAPPER_MEMBER(bgvideoram_scan_cols);
143   TILE_GET_INFO_MEMBER(get_bg_l_tile_info);
144   TILE_GET_INFO_MEMBER(get_bg_r_tile_info);
145   TILE_GET_INFO_MEMBER(get_fg_tile_info);
146   virtual void machine_start();
147   virtual void machine_reset();
148   virtual void video_start();
149   virtual void palette_init();
150   DECLARE_MACHINE_RESET(ctsttape);
151   DECLARE_MACHINE_RESET(cprogolfj);
152   DECLARE_MACHINE_RESET(cdsteljn);
153   DECLARE_MACHINE_RESET(cfishing);
154   DECLARE_MACHINE_RESET(chwy);
155   DECLARE_MACHINE_RESET(cterrani);
156   DECLARE_MACHINE_RESET(castfant);
157   DECLARE_MACHINE_RESET(csuperas);
158   DECLARE_MACHINE_RESET(clocknch);
159   DECLARE_MACHINE_RESET(cprogolf);
160   DECLARE_MACHINE_RESET(cluckypo);
161   DECLARE_MACHINE_RESET(ctisland);
162   DECLARE_MACHINE_RESET(cexplore);
163   DECLARE_MACHINE_RESET(cdiscon1);
164   DECLARE_MACHINE_RESET(ctornado);
165   DECLARE_MACHINE_RESET(cmissnx);
166   DECLARE_MACHINE_RESET(cptennis);
167   DECLARE_MACHINE_RESET(cbtime);
168   DECLARE_MACHINE_RESET(cburnrub);
169   DECLARE_MACHINE_RESET(cgraplop);
170   DECLARE_MACHINE_RESET(cgraplop2);
171   DECLARE_MACHINE_RESET(clapapa);
172   DECLARE_MACHINE_RESET(cskater);
173   DECLARE_MACHINE_RESET(cprobowl);
174   DECLARE_MACHINE_RESET(cnightst);
175   DECLARE_MACHINE_RESET(cpsoccer);
176   DECLARE_MACHINE_RESET(csdtenis);
177   DECLARE_MACHINE_RESET(czeroize);
178   DECLARE_MACHINE_RESET(cppicf);
179   DECLARE_MACHINE_RESET(cfghtice);
180   DECLARE_MACHINE_RESET(type4);
181   DECLARE_MACHINE_RESET(cbdash);
182   DECLARE_MACHINE_RESET(cflyball);
183   UINT32 screen_update_decocass(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
184};
185
186
187
188DECLARE_WRITE8_HANDLER( decocass_coin_counter_w );
189DECLARE_WRITE8_HANDLER( decocass_sound_command_w );
190DECLARE_READ8_HANDLER( decocass_sound_data_r );
191DECLARE_READ8_HANDLER( decocass_sound_ack_r );
192DECLARE_WRITE8_HANDLER( decocass_sound_data_w );
193DECLARE_READ8_HANDLER( decocass_sound_command_r );
194TIMER_DEVICE_CALLBACK( decocass_audio_nmi_gen );
195DECLARE_WRITE8_HANDLER( decocass_sound_nmi_enable_w );
196DECLARE_READ8_HANDLER( decocass_sound_nmi_enable_r );
197DECLARE_READ8_HANDLER( decocass_sound_data_ack_reset_r );
198DECLARE_WRITE8_HANDLER( decocass_sound_data_ack_reset_w );
199DECLARE_WRITE8_HANDLER( decocass_nmi_reset_w );
200DECLARE_WRITE8_HANDLER( decocass_quadrature_decoder_reset_w );
201DECLARE_WRITE8_HANDLER( decocass_adc_w );
202DECLARE_READ8_HANDLER( decocass_input_r );
203
204DECLARE_WRITE8_HANDLER( decocass_reset_w );
205
206DECLARE_READ8_HANDLER( decocass_e5xx_r );
207DECLARE_WRITE8_HANDLER( decocass_e5xx_w );
208DECLARE_WRITE8_HANDLER( decocass_de0091_w );
209DECLARE_WRITE8_HANDLER( decocass_e900_w );
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247DECLARE_WRITE8_HANDLER( i8041_p1_w );
248DECLARE_READ8_HANDLER( i8041_p1_r );
249DECLARE_WRITE8_HANDLER( i8041_p2_w );
250DECLARE_READ8_HANDLER( i8041_p2_r );
251
252void decocass_machine_state_save_init(running_machine &machine);
253
254
255/*----------- defined in video/decocass.c -----------*/
256
257DECLARE_WRITE8_HANDLER( decocass_paletteram_w );
258DECLARE_WRITE8_HANDLER( decocass_charram_w );
259DECLARE_WRITE8_HANDLER( decocass_fgvideoram_w );
260DECLARE_WRITE8_HANDLER( decocass_colorram_w );
261DECLARE_WRITE8_HANDLER( decocass_bgvideoram_w );
262DECLARE_WRITE8_HANDLER( decocass_tileram_w );
263DECLARE_WRITE8_HANDLER( decocass_objectram_w );
264
265DECLARE_WRITE8_HANDLER( decocass_watchdog_count_w );
266DECLARE_WRITE8_HANDLER( decocass_watchdog_flip_w );
267DECLARE_WRITE8_HANDLER( decocass_color_missiles_w );
268DECLARE_WRITE8_HANDLER( decocass_mode_set_w );
269DECLARE_WRITE8_HANDLER( decocass_color_center_bot_w );
270DECLARE_WRITE8_HANDLER( decocass_back_h_shift_w );
271DECLARE_WRITE8_HANDLER( decocass_back_vl_shift_w );
272DECLARE_WRITE8_HANDLER( decocass_back_vr_shift_w );
273DECLARE_WRITE8_HANDLER( decocass_part_h_shift_w );
274DECLARE_WRITE8_HANDLER( decocass_part_v_shift_w );
275DECLARE_WRITE8_HANDLER( decocass_center_h_shift_space_w );
276DECLARE_WRITE8_HANDLER( decocass_center_v_shift_w );
277
278
279
280
281void decocass_video_state_save_init(running_machine &machine);
trunk/src/mame/machine/decocass.c
r18037r18038
77#include "emu.h"
88#include "cpu/m6502/m6502.h"
99#include "cpu/mcs48/mcs48.h"
10#include "machine/decocass.h"
10#include "includes/decocass.h"
11#include "machine/decocass_tape.h"
1112
12#define LOG_CASSETTE_STATE      0
13
1413/* dongle type #1: jumpers C and D assignments */
1514#define MAKE_MAP(m0,m1,m2,m3,m4,m5,m6,m7)   \
1615   ((UINT32)(m0)) | \
r18037r18038
4746};
4847
4948
50
51static UINT8 tape_get_status_bits(device_t *device);
52static UINT8 tape_is_present(device_t *device);
53static void tape_change_speed(device_t *device, INT8 newspeed);
54
55
56WRITE8_HANDLER( decocass_coin_counter_w )
49WRITE8_MEMBER(decocass_state::decocass_coin_counter_w)
5750{
5851}
5952
60WRITE8_HANDLER( decocass_sound_command_w )
53WRITE8_MEMBER(decocass_state::decocass_sound_command_w)
6154{
62   decocass_state *state = space.machine().driver_data<decocass_state>();
6355   LOG(2,("CPU %s sound command -> $%02x\n", space.device().tag(), data));
64   state->soundlatch_byte_w(space, 0, data);
65   state->m_sound_ack |= 0x80;
56   soundlatch_byte_w(space, 0, data);
57   m_sound_ack |= 0x80;
6658   /* remove snd cpu data ack bit. i don't see it in the schems, but... */
67   state->m_sound_ack &= ~0x40;
68   state->m_audiocpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE);
59   m_sound_ack &= ~0x40;
60   m_audiocpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE);
6961}
7062
71READ8_HANDLER( decocass_sound_data_r )
63READ8_MEMBER(decocass_state::decocass_sound_data_r)
7264{
73   decocass_state *state = space.machine().driver_data<decocass_state>();
74   UINT8 data = state->soundlatch2_byte_r(space, 0);
65   UINT8 data = soundlatch2_byte_r(space, 0);
7566   LOG(2,("CPU %s sound data    <- $%02x\n", space.device().tag(), data));
7667   return data;
7768}
7869
79READ8_HANDLER( decocass_sound_ack_r )
70READ8_MEMBER(decocass_state::decocass_sound_ack_r)
8071{
81   decocass_state *state = space.machine().driver_data<decocass_state>();
82   UINT8 data = state->m_sound_ack;   /* D6+D7 */
72   UINT8 data = m_sound_ack;   /* D6+D7 */
8373   LOG(4,("CPU %s sound ack     <- $%02x\n", space.device().tag(), data));
8474   return data;
8575}
8676
87WRITE8_HANDLER( decocass_sound_data_w )
77WRITE8_MEMBER(decocass_state::decocass_sound_data_w)
8878{
89   decocass_state *state = space.machine().driver_data<decocass_state>();
9079   LOG(2,("CPU %s sound data    -> $%02x\n", space.device().tag(), data));
91   state->soundlatch2_byte_w(space, 0, data);
92   state->m_sound_ack |= 0x40;
80   soundlatch2_byte_w(space, 0, data);
81   m_sound_ack |= 0x40;
9382}
9483
95READ8_HANDLER( decocass_sound_command_r )
84READ8_MEMBER(decocass_state::decocass_sound_command_r)
9685{
97   decocass_state *state = space.machine().driver_data<decocass_state>();
98   UINT8 data = state->soundlatch_byte_r(space, 0);
86   UINT8 data = soundlatch_byte_r(space, 0);
9987   LOG(4,("CPU %s sound command <- $%02x\n", space.device().tag(), data));
100   state->m_audiocpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE);
101   state->m_sound_ack &= ~0x80;
88   m_audiocpu->set_input_line(M6502_IRQ_LINE, CLEAR_LINE);
89   m_sound_ack &= ~0x80;
10290   return data;
10391}
10492
r18037r18038
11098   state->m_audiocpu->set_input_line(INPUT_LINE_NMI, (state->m_audio_nmi_enabled && state->m_audio_nmi_state) ? ASSERT_LINE : CLEAR_LINE);
11199}
112100
113WRITE8_HANDLER( decocass_sound_nmi_enable_w )
101WRITE8_MEMBER(decocass_state::decocass_sound_nmi_enable_w)
114102{
115   decocass_state *state = space.machine().driver_data<decocass_state>();
116   state->m_audio_nmi_enabled = 1;
117   state->m_audiocpu->set_input_line(INPUT_LINE_NMI, (state->m_audio_nmi_enabled && state->m_audio_nmi_state) ? ASSERT_LINE : CLEAR_LINE);
103   m_audio_nmi_enabled = 1;
104   m_audiocpu->set_input_line(INPUT_LINE_NMI, (m_audio_nmi_enabled && m_audio_nmi_state) ? ASSERT_LINE : CLEAR_LINE);
118105}
119106
120READ8_HANDLER( decocass_sound_nmi_enable_r )
107READ8_MEMBER(decocass_state::decocass_sound_nmi_enable_r)
121108{
122   decocass_state *state = space.machine().driver_data<decocass_state>();
123   state->m_audio_nmi_enabled = 1;
124   state->m_audiocpu->set_input_line(INPUT_LINE_NMI, (state->m_audio_nmi_enabled && state->m_audio_nmi_state) ? ASSERT_LINE : CLEAR_LINE);
109   m_audio_nmi_enabled = 1;
110   m_audiocpu->set_input_line(INPUT_LINE_NMI, (m_audio_nmi_enabled && m_audio_nmi_state) ? ASSERT_LINE : CLEAR_LINE);
125111   return 0xff;
126112}
127113
128READ8_HANDLER( decocass_sound_data_ack_reset_r )
114READ8_MEMBER(decocass_state::decocass_sound_data_ack_reset_r)
129115{
130   decocass_state *state = space.machine().driver_data<decocass_state>();
131116   UINT8 data = 0xff;
132117   LOG(2,("CPU %s sound ack rst <- $%02x\n", space.device().tag(), data));
133   state->m_sound_ack &= ~0x40;
118   m_sound_ack &= ~0x40;
134119   return data;
135120}
136121
137WRITE8_HANDLER( decocass_sound_data_ack_reset_w )
122WRITE8_MEMBER(decocass_state::decocass_sound_data_ack_reset_w)
138123{
139   decocass_state *state = space.machine().driver_data<decocass_state>();
140124   LOG(2,("CPU %s sound ack rst -> $%02x\n", space.device().tag(), data));
141   state->m_sound_ack &= ~0x40;
125   m_sound_ack &= ~0x40;
142126}
143127
144WRITE8_HANDLER( decocass_nmi_reset_w )
128WRITE8_MEMBER(decocass_state::decocass_nmi_reset_w)
145129{
146   decocass_state *state = space.machine().driver_data<decocass_state>();
147   state->m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE );
130   m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE );
148131}
149132
150WRITE8_HANDLER( decocass_quadrature_decoder_reset_w )
133WRITE8_MEMBER(decocass_state::decocass_quadrature_decoder_reset_w)
151134{
152   decocass_state *state = space.machine().driver_data<decocass_state>();
153135
154136   /* just latch the analog controls here */
155   state->m_quadrature_decoder[0] = state->ioport("AN0")->read();
156   state->m_quadrature_decoder[1] = state->ioport("AN1")->read();
157   state->m_quadrature_decoder[2] = state->ioport("AN2")->read();
158   state->m_quadrature_decoder[3] = state->ioport("AN3")->read();
137   m_quadrature_decoder[0] = ioport("AN0")->read();
138   m_quadrature_decoder[1] = ioport("AN1")->read();
139   m_quadrature_decoder[2] = ioport("AN2")->read();
140   m_quadrature_decoder[3] = ioport("AN3")->read();
159141}
160142
161WRITE8_HANDLER( decocass_adc_w )
143WRITE8_MEMBER(decocass_state::decocass_adc_w)
162144{
163145}
164146
r18037r18038
172154 * E6x6    ""
173155 * E6x7    a/d converter read
174156 */
175READ8_HANDLER( decocass_input_r )
157READ8_MEMBER(decocass_state::decocass_input_r)
176158{
177   decocass_state *state = space.machine().driver_data<decocass_state>();
178159   UINT8 data = 0xff;
179160   static const char *const portnames[] = { "IN0", "IN1", "IN2" };
180161
r18037r18038
184165      data = space.machine().root_device().ioport(portnames[offset & 7])->read();
185166      break;
186167   case 3: case 4: case 5: case 6:
187      data = state->m_quadrature_decoder[(offset & 7) - 3];
168      data = m_quadrature_decoder[(offset & 7) - 3];
188169      break;
189170   default:
190171      break;
r18037r18038
207188#define E5XX_MASK   0x02   /* use 0x0e for old style board */
208189
209190
210WRITE8_HANDLER( decocass_reset_w )
191WRITE8_MEMBER(decocass_state::decocass_reset_w)
211192{
212   decocass_state *state = space.machine().driver_data<decocass_state>();
213193   LOG(1,("%10s 6502-PC: %04x decocass_reset_w(%02x): $%02x\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data));
214   state->m_decocass_reset = data;
194   m_decocass_reset = data;
215195
216196   /* CPU #1 active high reset */
217   state->m_audiocpu->set_input_line(INPUT_LINE_RESET, data & 0x01);
197   m_audiocpu->set_input_line(INPUT_LINE_RESET, data & 0x01);
218198
219199   /* on reset also disable audio NMI */
220200   if (data & 1)
221201   {
222      state->m_audio_nmi_enabled = 0;
223      state->m_audiocpu->set_input_line(INPUT_LINE_NMI, (state->m_audio_nmi_enabled && state->m_audio_nmi_state) ? ASSERT_LINE : CLEAR_LINE);
202      m_audio_nmi_enabled = 0;
203      m_audiocpu->set_input_line(INPUT_LINE_NMI, (m_audio_nmi_enabled && m_audio_nmi_state) ? ASSERT_LINE : CLEAR_LINE);
224204   }
225205
226206   /* 8041 active low reset */
227   state->m_mcu->execute().set_input_line(INPUT_LINE_RESET, (data & 0x08) ? ASSERT_LINE : CLEAR_LINE);
207   m_mcu->set_input_line(INPUT_LINE_RESET, (data & 0x08) ? ASSERT_LINE : CLEAR_LINE);
228208}
229209
230210
r18037r18038
233213{
234214   decocass_state *state = machine.driver_data<decocass_state>();
235215   /* 8041ENA/ and is this a FNO write (function number)? */
236   if (0 == (state->m_i8041_p2 & 0x01))
216   if (0 == (m_i8041_p2 & 0x01))
237217   {
238218      switch (data)
239219      {
r18037r18038
275255 *
276256 ***************************************************************************/
277257
278static READ8_HANDLER( decocass_type1_latch_26_pass_3_inv_2_r )
258READ8_MEMBER(decocass_state::decocass_type1_latch_26_pass_3_inv_2_r)
279259{
280   decocass_state *state = space.machine().driver_data<decocass_state>();
281260   UINT8 data;
282261
283262   if (1 == (offset & 1))
284263   {
285264      if (0 == (offset & E5XX_MASK))
286         data = upi41_master_r(state->m_mcu, 1);
265         data = upi41_master_r(m_mcu, 1);
287266      else
288267         data = 0xff;
289268
r18037r18038
299278      UINT8 save;
300279      UINT8 *prom = space.machine().root_device().memregion("dongle")->base();
301280
302      if (state->m_firsttime)
281      if (m_firsttime)
303282      {
304283         LOG(3,("prom data:\n"));
305284         for (promaddr = 0; promaddr < 32; promaddr++)
r18037r18038
308287               LOG(3,("  %02x:", promaddr));
309288            LOG(3,(" %02x%s", prom[promaddr], (promaddr % 8) == 7 ? "\n" : ""));
310289         }
311         state->m_firsttime = 0;
312         state->m_latch1 = 0;    /* reset latch (??) */
290         m_firsttime = 0;
291         m_latch1 = 0;    /* reset latch (??) */
313292      }
314293
315294      if (0 == (offset & E5XX_MASK))
316         data = upi41_master_r(state->m_mcu, 0);
295         data = upi41_master_r(m_mcu, 0);
317296      else
318297         data = 0xff;
319298
320299      save = data;   /* save the unmodifed data for the latch */
321300
322301      promaddr =
323         (((data >> MAP0(state->m_type1_inmap)) & 1) << 0) |
324         (((data >> MAP1(state->m_type1_inmap)) & 1) << 1) |
325         (((data >> MAP4(state->m_type1_inmap)) & 1) << 2) |
326         (((data >> MAP5(state->m_type1_inmap)) & 1) << 3) |
327         (((data >> MAP7(state->m_type1_inmap)) & 1) << 4);
302         (((data >> MAP0(m_type1_inmap)) & 1) << 0) |
303         (((data >> MAP1(m_type1_inmap)) & 1) << 1) |
304         (((data >> MAP4(m_type1_inmap)) & 1) << 2) |
305         (((data >> MAP5(m_type1_inmap)) & 1) << 3) |
306         (((data >> MAP7(m_type1_inmap)) & 1) << 4);
328307      /* latch bits 2 and 6, pass bit 3, invert bit 2 */
329308      data =
330         (((prom[promaddr] >> 0) & 1)            << MAP0(state->m_type1_outmap)) |
331         (((prom[promaddr] >> 1) & 1)            << MAP1(state->m_type1_outmap)) |
332         ((1 - ((state->m_latch1 >> MAP2(state->m_type1_inmap)) & 1)) << MAP2(state->m_type1_outmap)) |
333         (((data >> MAP3(state->m_type1_inmap)) & 1)         << MAP3(state->m_type1_outmap)) |
334         (((prom[promaddr] >> 2) & 1)            << MAP4(state->m_type1_outmap)) |
335         (((prom[promaddr] >> 3) & 1)            << MAP5(state->m_type1_outmap)) |
336         (((state->m_latch1 >> MAP6(state->m_type1_inmap)) & 1)      << MAP6(state->m_type1_outmap)) |
337         (((prom[promaddr] >> 4) & 1)            << MAP7(state->m_type1_outmap));
309         (((prom[promaddr] >> 0) & 1)            << MAP0(m_type1_outmap)) |
310         (((prom[promaddr] >> 1) & 1)            << MAP1(m_type1_outmap)) |
311         ((1 - ((m_latch1 >> MAP2(m_type1_inmap)) & 1)) << MAP2(m_type1_outmap)) |
312         (((data >> MAP3(m_type1_inmap)) & 1)         << MAP3(m_type1_outmap)) |
313         (((prom[promaddr] >> 2) & 1)            << MAP4(m_type1_outmap)) |
314         (((prom[promaddr] >> 3) & 1)            << MAP5(m_type1_outmap)) |
315         (((m_latch1 >> MAP6(m_type1_inmap)) & 1)      << MAP6(m_type1_outmap)) |
316         (((prom[promaddr] >> 4) & 1)            << MAP7(m_type1_outmap));
338317
339318      LOG(3,("%10s 6502-PC: %04x decocass_type1_latch_26_pass_3_inv_2_r(%02x): $%02x\n",
340319         space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data));
341320
342      state->m_latch1 = save;      /* latch the data for the next A0 == 0 read */
321      m_latch1 = save;      /* latch the data for the next A0 == 0 read */
343322   }
344323   return data;
345324}
r18037r18038
355334 *
356335 ***************************************************************************/
357336
358static READ8_HANDLER( decocass_type1_pass_136_r )
337READ8_MEMBER(decocass_state::decocass_type1_pass_136_r)
359338{
360   decocass_state *state = space.machine().driver_data<decocass_state>();
361339   UINT8 data;
362340
363341   if (1 == (offset & 1))
364342   {
365343      if (0 == (offset & E5XX_MASK))
366         data = upi41_master_r(state->m_mcu, 1);
344         data = upi41_master_r(m_mcu, 1);
367345      else
368346         data = 0xff;
369347
r18037r18038
379357      UINT8 save;
380358      UINT8 *prom = space.machine().root_device().memregion("dongle")->base();
381359
382      if (state->m_firsttime)
360      if (m_firsttime)
383361      {
384362         LOG(3,("prom data:\n"));
385363         for (promaddr = 0; promaddr < 32; promaddr++)
r18037r18038
388366               LOG(3,("  %02x:", promaddr));
389367            LOG(3,(" %02x%s", prom[promaddr], (promaddr % 8) == 7 ? "\n" : ""));
390368         }
391         state->m_firsttime = 0;
392         state->m_latch1 = 0;    /* reset latch (??) */
369         m_firsttime = 0;
370         m_latch1 = 0;    /* reset latch (??) */
393371      }
394372
395373      if (0 == (offset & E5XX_MASK))
396         data = upi41_master_r(state->m_mcu, 0);
374         data = upi41_master_r(m_mcu, 0);
397375      else
398376         data = 0xff;
399377
400378      save = data;   /* save the unmodifed data for the latch */
401379
402380      promaddr =
403         (((data >> MAP0(state->m_type1_inmap)) & 1) << 0) |
404         (((data >> MAP2(state->m_type1_inmap)) & 1) << 1) |
405         (((data >> MAP4(state->m_type1_inmap)) & 1) << 2) |
406         (((data >> MAP5(state->m_type1_inmap)) & 1) << 3) |
407         (((data >> MAP7(state->m_type1_inmap)) & 1) << 4);
381         (((data >> MAP0(m_type1_inmap)) & 1) << 0) |
382         (((data >> MAP2(m_type1_inmap)) & 1) << 1) |
383         (((data >> MAP4(m_type1_inmap)) & 1) << 2) |
384         (((data >> MAP5(m_type1_inmap)) & 1) << 3) |
385         (((data >> MAP7(m_type1_inmap)) & 1) << 4);
408386      /* latch bits 1 and 6, pass bit 3, invert bit 1 */
409387      data =
410         (((prom[promaddr] >> 0) & 1)            << MAP0(state->m_type1_outmap)) |
411         (((data >> MAP1(state->m_type1_inmap)) & 1)         << MAP1(state->m_type1_outmap)) |
412         (((prom[promaddr] >> 1) & 1)            << MAP2(state->m_type1_outmap)) |
413         (((data >> MAP3(state->m_type1_inmap)) & 1)         << MAP3(state->m_type1_outmap)) |
414         (((prom[promaddr] >> 2) & 1)            << MAP4(state->m_type1_outmap)) |
415         (((prom[promaddr] >> 3) & 1)            << MAP5(state->m_type1_outmap)) |
416         (((data >> MAP6(state->m_type1_inmap)) & 1)          << MAP6(state->m_type1_outmap)) |
417         (((prom[promaddr] >> 4) & 1)            << MAP7(state->m_type1_outmap));
388         (((prom[promaddr] >> 0) & 1)            << MAP0(m_type1_outmap)) |
389         (((data >> MAP1(m_type1_inmap)) & 1)         << MAP1(m_type1_outmap)) |
390         (((prom[promaddr] >> 1) & 1)            << MAP2(m_type1_outmap)) |
391         (((data >> MAP3(m_type1_inmap)) & 1)         << MAP3(m_type1_outmap)) |
392         (((prom[promaddr] >> 2) & 1)            << MAP4(m_type1_outmap)) |
393         (((prom[promaddr] >> 3) & 1)            << MAP5(m_type1_outmap)) |
394         (((data >> MAP6(m_type1_inmap)) & 1)          << MAP6(m_type1_outmap)) |
395         (((prom[promaddr] >> 4) & 1)            << MAP7(m_type1_outmap));
418396
419397      LOG(3,("%10s 6502-PC: %04x decocass_type1_pass_136_r(%02x): $%02x\n",
420398         space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data));
421399
422      state->m_latch1 = save;      /* latch the data for the next A0 == 0 read */
400      m_latch1 = save;      /* latch the data for the next A0 == 0 read */
423401   }
424402   return data;
425403}
r18037r18038
435413 *
436414 ***************************************************************************/
437415
438static READ8_HANDLER( decocass_type1_latch_27_pass_3_inv_2_r )
416READ8_MEMBER(decocass_state::decocass_type1_latch_27_pass_3_inv_2_r)
439417{
440   decocass_state *state = space.machine().driver_data<decocass_state>();
441418   UINT8 data;
442419
443420   if (1 == (offset & 1))
444421   {
445422      if (0 == (offset & E5XX_MASK))
446         data = upi41_master_r(state->m_mcu, 1);
423         data = upi41_master_r(m_mcu, 1);
447424      else
448425         data = 0xff;
449426
r18037r18038
459436      UINT8 save;
460437      UINT8 *prom = space.machine().root_device().memregion("dongle")->base();
461438
462      if (state->m_firsttime)
439      if (m_firsttime)
463440      {
464441         LOG(3,("prom data:\n"));
465442         for (promaddr = 0; promaddr < 32; promaddr++)
r18037r18038
468445               LOG(3,("  %02x:", promaddr));
469446            LOG(3,(" %02x%s", prom[promaddr], (promaddr % 8) == 7 ? "\n" : ""));
470447         }
471         state->m_firsttime = 0;
472         state->m_latch1 = 0;    /* reset latch (??) */
448         m_firsttime = 0;
449         m_latch1 = 0;    /* reset latch (??) */
473450      }
474451
475452      if (0 == (offset & E5XX_MASK))
476         data = upi41_master_r(state->m_mcu, 0);
453         data = upi41_master_r(m_mcu, 0);
477454      else
478455         data = 0xff;
479456
480457      save = data;   /* save the unmodifed data for the latch */
481458
482459      promaddr =
483         (((data >> MAP0(state->m_type1_inmap)) & 1) << 0) |
484         (((data >> MAP1(state->m_type1_inmap)) & 1) << 1) |
485         (((data >> MAP4(state->m_type1_inmap)) & 1) << 2) |
486         (((data >> MAP5(state->m_type1_inmap)) & 1) << 3) |
487         (((data >> MAP6(state->m_type1_inmap)) & 1) << 4);
460         (((data >> MAP0(m_type1_inmap)) & 1) << 0) |
461         (((data >> MAP1(m_type1_inmap)) & 1) << 1) |
462         (((data >> MAP4(m_type1_inmap)) & 1) << 2) |
463         (((data >> MAP5(m_type1_inmap)) & 1) << 3) |
464         (((data >> MAP6(m_type1_inmap)) & 1) << 4);
488465      /* latch bits 2 and 7, pass bit 3, invert bit 2 */
489466      data =
490         (((prom[promaddr] >> 0) & 1)            << MAP0(state->m_type1_outmap)) |
491         (((prom[promaddr] >> 1) & 1)            << MAP1(state->m_type1_outmap)) |
492         ((1 - ((state->m_latch1 >> MAP2(state->m_type1_inmap)) & 1)) << MAP2(state->m_type1_outmap)) |
493         (((data >> MAP3(state->m_type1_inmap)) & 1)         << MAP3(state->m_type1_outmap)) |
494         (((prom[promaddr] >> 2) & 1)            << MAP4(state->m_type1_outmap)) |
495         (((prom[promaddr] >> 3) & 1)            << MAP5(state->m_type1_outmap)) |
496         (((prom[promaddr] >> 4) & 1)            << MAP6(state->m_type1_outmap)) |
497         (((state->m_latch1 >> MAP7(state->m_type1_inmap)) & 1)      << MAP7(state->m_type1_outmap));
467         (((prom[promaddr] >> 0) & 1)            << MAP0(m_type1_outmap)) |
468         (((prom[promaddr] >> 1) & 1)            << MAP1(m_type1_outmap)) |
469         ((1 - ((m_latch1 >> MAP2(m_type1_inmap)) & 1)) << MAP2(m_type1_outmap)) |
470         (((data >> MAP3(m_type1_inmap)) & 1)         << MAP3(m_type1_outmap)) |
471         (((prom[promaddr] >> 2) & 1)            << MAP4(m_type1_outmap)) |
472         (((prom[promaddr] >> 3) & 1)            << MAP5(m_type1_outmap)) |
473         (((prom[promaddr] >> 4) & 1)            << MAP6(m_type1_outmap)) |
474         (((m_latch1 >> MAP7(m_type1_inmap)) & 1)      << MAP7(m_type1_outmap));
498475
499476      LOG(3,("%10s 6502-PC: %04x decocass_type1_latch_27_pass_3_inv_2_r(%02x): $%02x\n",
500477         space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data));
501478
502      state->m_latch1 = save;      /* latch the data for the next A0 == 0 read */
479      m_latch1 = save;      /* latch the data for the next A0 == 0 read */
503480   }
504481   return data;
505482}
r18037r18038
515492 *
516493 ***************************************************************************/
517494
518static READ8_HANDLER( decocass_type1_latch_26_pass_5_inv_2_r )
495READ8_MEMBER(decocass_state::decocass_type1_latch_26_pass_5_inv_2_r)
519496{
520   decocass_state *state = space.machine().driver_data<decocass_state>();
521497   UINT8 data;
522498
523499   if (1 == (offset & 1))
524500   {
525501      if (0 == (offset & E5XX_MASK))
526         data = upi41_master_r(state->m_mcu, 1);
502         data = upi41_master_r(m_mcu, 1);
527503      else
528504         data = 0xff;
529505
r18037r18038
539515      UINT8 save;
540516      UINT8 *prom = space.machine().root_device().memregion("dongle")->base();
541517
542      if (state->m_firsttime)
518      if (m_firsttime)
543519      {
544520         LOG(3,("prom data:\n"));
545521         for (promaddr = 0; promaddr < 32; promaddr++)
r18037r18038
548524               LOG(3,("  %02x:", promaddr));
549525            LOG(3,(" %02x%s", prom[promaddr], (promaddr % 8) == 7 ? "\n" : ""));
550526         }
551         state->m_firsttime = 0;
552         state->m_latch1 = 0;    /* reset latch (??) */
527         m_firsttime = 0;
528         m_latch1 = 0;    /* reset latch (??) */
553529      }
554530
555531      if (0 == (offset & E5XX_MASK))
556         data = upi41_master_r(state->m_mcu, 0);
532         data = upi41_master_r(m_mcu, 0);
557533      else
558534         data = 0xff;
559535
560536      save = data;   /* save the unmodifed data for the latch */
561537
562538      promaddr =
563         (((data >> MAP0(state->m_type1_inmap)) & 1) << 0) |
564         (((data >> MAP1(state->m_type1_inmap)) & 1) << 1) |
565         (((data >> MAP3(state->m_type1_inmap)) & 1) << 2) |
566         (((data >> MAP4(state->m_type1_inmap)) & 1) << 3) |
567         (((data >> MAP7(state->m_type1_inmap)) & 1) << 4);
539         (((data >> MAP0(m_type1_inmap)) & 1) << 0) |
540         (((data >> MAP1(m_type1_inmap)) & 1) << 1) |
541         (((data >> MAP3(m_type1_inmap)) & 1) << 2) |
542         (((data >> MAP4(m_type1_inmap)) & 1) << 3) |
543         (((data >> MAP7(m_type1_inmap)) & 1) << 4);
568544      /* latch bits 2 and 6, pass bit 5, invert bit 2 */
569545      data =
570         (((prom[promaddr] >> 0) & 1)            << MAP0(state->m_type1_outmap)) |
571         (((prom[promaddr] >> 1) & 1)            << MAP1(state->m_type1_outmap)) |
572         ((1 - ((state->m_latch1 >> MAP2(state->m_type1_inmap)) & 1)) << MAP2(state->m_type1_outmap)) |
573         (((prom[promaddr] >> 2) & 1)            << MAP3(state->m_type1_outmap)) |
574         (((prom[promaddr] >> 3) & 1)            << MAP4(state->m_type1_outmap)) |
575         (((data >> MAP5(state->m_type1_inmap)) & 1)         << MAP5(state->m_type1_outmap)) |
576         (((state->m_latch1 >> MAP6(state->m_type1_inmap)) & 1)         << MAP6(state->m_type1_outmap)) |
577         (((prom[promaddr] >> 4) & 1)            << MAP7(state->m_type1_outmap));
546         (((prom[promaddr] >> 0) & 1)            << MAP0(m_type1_outmap)) |
547         (((prom[promaddr] >> 1) & 1)            << MAP1(m_type1_outmap)) |
548         ((1 - ((m_latch1 >> MAP2(m_type1_inmap)) & 1)) << MAP2(m_type1_outmap)) |
549         (((prom[promaddr] >> 2) & 1)            << MAP3(m_type1_outmap)) |
550         (((prom[promaddr] >> 3) & 1)            << MAP4(m_type1_outmap)) |
551         (((data >> MAP5(m_type1_inmap)) & 1)         << MAP5(m_type1_outmap)) |
552         (((m_latch1 >> MAP6(m_type1_inmap)) & 1)         << MAP6(m_type1_outmap)) |
553         (((prom[promaddr] >> 4) & 1)            << MAP7(m_type1_outmap));
578554
579555      LOG(3,("%10s 6502-PC: %04x decocass_type1_latch_26_pass_5_inv_2_r(%02x): $%02x\n",
580556         space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data));
581557
582      state->m_latch1 = save;      /* latch the data for the next A0 == 0 read */
558      m_latch1 = save;      /* latch the data for the next A0 == 0 read */
583559   }
584560   return data;
585561}
r18037r18038
597573 *
598574 ***************************************************************************/
599575
600static READ8_HANDLER( decocass_type1_latch_16_pass_3_inv_1_r )
576READ8_MEMBER(decocass_state::decocass_type1_latch_16_pass_3_inv_1_r)
601577{
602   decocass_state *state = space.machine().driver_data<decocass_state>();
603578   UINT8 data;
604579
605580   if (1 == (offset & 1))
606581   {
607582      if (0 == (offset & E5XX_MASK))
608         data = upi41_master_r(state->m_mcu, 1);
583         data = upi41_master_r(m_mcu, 1);
609584      else
610585         data = 0xff;
611586
r18037r18038
621596      UINT8 save;
622597      UINT8 *prom = space.machine().root_device().memregion("dongle")->base();
623598
624      if (state->m_firsttime)
599      if (m_firsttime)
625600      {
626601         LOG(3,("prom data:\n"));
627602         for (promaddr = 0; promaddr < 32; promaddr++)
r18037r18038
630605               LOG(3,("  %02x:", promaddr));
631606            LOG(3,(" %02x%s", prom[promaddr], (promaddr % 8) == 7 ? "\n" : ""));
632607         }
633         state->m_firsttime = 0;
634         state->m_latch1 = 0;    /* reset latch (??) */
608         m_firsttime = 0;
609         m_latch1 = 0;    /* reset latch (??) */
635610      }
636611
637612      if (0 == (offset & E5XX_MASK))
638         data = upi41_master_r(state->m_mcu, 0);
613         data = upi41_master_r(m_mcu, 0);
639614      else
640615         data = 0xff;
641616
642617      save = data;   /* save the unmodifed data for the latch */
643618
644619      promaddr =
645         (((data >> MAP0(state->m_type1_inmap)) & 1) << 0) |
646         (((data >> MAP2(state->m_type1_inmap)) & 1) << 1) |
647         (((data >> MAP4(state->m_type1_inmap)) & 1) << 2) |
648         (((data >> MAP5(state->m_type1_inmap)) & 1) << 3) |
649         (((data >> MAP7(state->m_type1_inmap)) & 1) << 4);
620         (((data >> MAP0(m_type1_inmap)) & 1) << 0) |
621         (((data >> MAP2(m_type1_inmap)) & 1) << 1) |
622         (((data >> MAP4(m_type1_inmap)) & 1) << 2) |
623         (((data >> MAP5(m_type1_inmap)) & 1) << 3) |
624         (((data >> MAP7(m_type1_inmap)) & 1) << 4);
650625      /* latch bits 1 and 6, pass bit 3, invert bit 1 */
651626      data =
652         (((prom[promaddr] >> 0) & 1)            << MAP0(state->m_type1_outmap)) |
653         ((1 - ((state->m_latch1 >> MAP1(state->m_type1_inmap)) & 1)) << MAP1(state->m_type1_outmap)) |
654         (((prom[promaddr] >> 1) & 1)            << MAP2(state->m_type1_outmap)) |
655         (((data >> MAP3(state->m_type1_inmap)) & 1)         << MAP3(state->m_type1_outmap)) |
656         (((prom[promaddr] >> 2) & 1)            << MAP4(state->m_type1_outmap)) |
657         (((prom[promaddr] >> 3) & 1)            << MAP5(state->m_type1_outmap)) |
658         (((state->m_latch1 >> MAP6(state->m_type1_inmap)) & 1)      << MAP6(state->m_type1_outmap)) |
659         (((prom[promaddr] >> 4) & 1)            << MAP7(state->m_type1_outmap));
627         (((prom[promaddr] >> 0) & 1)            << MAP0(m_type1_outmap)) |
628         ((1 - ((m_latch1 >> MAP1(m_type1_inmap)) & 1)) << MAP1(m_type1_outmap)) |
629         (((prom[promaddr] >> 1) & 1)            << MAP2(m_type1_outmap)) |
630         (((data >> MAP3(m_type1_inmap)) & 1)         << MAP3(m_type1_outmap)) |
631         (((prom[promaddr] >> 2) & 1)            << MAP4(m_type1_outmap)) |
632         (((prom[promaddr] >> 3) & 1)            << MAP5(m_type1_outmap)) |
633         (((m_latch1 >> MAP6(m_type1_inmap)) & 1)      << MAP6(m_type1_outmap)) |
634         (((prom[promaddr] >> 4) & 1)            << MAP7(m_type1_outmap));
660635
661636      LOG(3,("%10s 6502-PC: %04x decocass_type1_latch_16_pass_3_inv_1_r(%02x): $%02x\n",
662637         space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data));
663638
664      state->m_latch1 = save;      /* latch the data for the next A0 == 0 read */
639      m_latch1 = save;      /* latch the data for the next A0 == 0 read */
665640   }
666641   return data;
667642}
r18037r18038
678653 *  - Pro Tennis
679654 *
680655 ***************************************************************************/
681static READ8_HANDLER( decocass_type2_r )
656READ8_MEMBER(decocass_state::decocass_type2_r)
682657{
683   decocass_state *state = space.machine().driver_data<decocass_state>();
684658   UINT8 data;
685659
686   if (1 == state->m_type2_xx_latch)
660   if (1 == m_type2_xx_latch)
687661   {
688662      if (1 == (offset & 1))
689663      {
690         UINT8 *prom = state->memregion("dongle")->base();
691         data = prom[256 * state->m_type2_d2_latch + state->m_type2_promaddr];
692         LOG(3,("%10s 6502-PC: %04x decocass_type2_r(%02x): $%02x <- prom[%03x]\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, 256 * state->m_type2_d2_latch + state->m_type2_promaddr));
664         UINT8 *prom = memregion("dongle")->base();
665         data = prom[256 * m_type2_d2_latch + m_type2_promaddr];
666         LOG(3,("%10s 6502-PC: %04x decocass_type2_r(%02x): $%02x <- prom[%03x]\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, 256 * m_type2_d2_latch + m_type2_promaddr));
693667      }
694668      else
695669      {
r18037r18038
699673   else
700674   {
701675      if (0 == (offset & E5XX_MASK))
702         data = upi41_master_r(state->m_mcu, offset);
676         data = upi41_master_r(m_mcu, offset);
703677      else
704678         data = offset & 0xff;
705679
r18037r18038
708682   return data;
709683}
710684
711static WRITE8_HANDLER( decocass_type2_w )
685WRITE8_MEMBER(decocass_state::decocass_type2_w)
712686{
713   decocass_state *state = space.machine().driver_data<decocass_state>();
714   if (1 == state->m_type2_xx_latch)
687   if (1 == m_type2_xx_latch)
715688   {
716689      if (1 == (offset & 1))
717690      {
r18037r18038
719692      }
720693      else
721694      {
722         state->m_type2_promaddr = data;
723         LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> set PROM addr $%02x\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, state->m_type2_promaddr));
695         m_type2_promaddr = data;
696         LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> set PROM addr $%02x\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, m_type2_promaddr));
724697         return;
725698      }
726699   }
r18037r18038
732705   {
733706      if (0xc0 == (data & 0xf0))
734707      {
735         state->m_type2_xx_latch = 1;
736         state->m_type2_d2_latch = (data & 0x04) ? 1 : 0;
737         LOG(3,("PROM:%s D2:%d", state->m_type2_xx_latch ? "on" : "off", state->m_type2_d2_latch));
708         m_type2_xx_latch = 1;
709         m_type2_d2_latch = (data & 0x04) ? 1 : 0;
710         LOG(3,("PROM:%s D2:%d", m_type2_xx_latch ? "on" : "off", m_type2_d2_latch));
738711      }
739712   }
740   upi41_master_w(state->m_mcu, offset & 1, data);
713   upi41_master_w(m_mcu, offset & 1, data);
741714
742715#ifdef MAME_DEBUG
743716   decocass_fno(space.machine(), offset, data);
r18037r18038
762735 *  - Fighting Ice Hockey
763736 *
764737 ***************************************************************************/
765static READ8_HANDLER( decocass_type3_r )
738READ8_MEMBER(decocass_state::decocass_type3_r)
766739{
767   decocass_state *state = space.machine().driver_data<decocass_state>();
768740   UINT8 data, save;
769741
770742   if (1 == (offset & 1))
771743   {
772      if (1 == state->m_type3_pal_19)
744      if (1 == m_type3_pal_19)
773745      {
774         UINT8 *prom = state->memregion("dongle")->base();
775         data = prom[state->m_type3_ctrs];
776         LOG(3,("%10s 6502-PC: %04x decocass_type3_r(%02x): $%02x <- prom[$%03x]\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, state->m_type3_ctrs));
777         if (++state->m_type3_ctrs == 4096)
778            state->m_type3_ctrs = 0;
746         UINT8 *prom = memregion("dongle")->base();
747         data = prom[m_type3_ctrs];
748         LOG(3,("%10s 6502-PC: %04x decocass_type3_r(%02x): $%02x <- prom[$%03x]\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, m_type3_ctrs));
749         if (++m_type3_ctrs == 4096)
750            m_type3_ctrs = 0;
779751      }
780752      else
781753      {
782754         if (0 == (offset & E5XX_MASK))
783755         {
784            data = upi41_master_r(state->m_mcu, 1);
756            data = upi41_master_r(m_mcu, 1);
785757            LOG(4,("%10s 6502-PC: %04x decocass_type3_r(%02x): $%02x <- 8041 STATUS\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data));
786758         }
787759         else
r18037r18038
793765   }
794766   else
795767   {
796      if (1 == state->m_type3_pal_19)
768      if (1 == m_type3_pal_19)
797769      {
798770         save = data = 0xff;    /* open data bus? */
799771         LOG(3,("%10s 6502-PC: %04x decocass_type3_r(%02x): $%02x <- open bus", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data));
r18037r18038
802774      {
803775         if (0 == (offset & E5XX_MASK))
804776         {
805            save = upi41_master_r(state->m_mcu, 0);
806            switch (state->m_type3_swap)
777            save = upi41_master_r(m_mcu, 0);
778            switch (m_type3_swap)
807779            {
808780            case TYPE3_SWAP_01:
809781               data =
810782                  (BIT(save, 1) << 0) |
811                  (state->m_type3_d0_latch << 1) |
783                  (m_type3_d0_latch << 1) |
812784                  (BIT(save, 2) << 2) |
813785                  (BIT(save, 3) << 3) |
814786                  (BIT(save, 4) << 4) |
r18037r18038
818790               break;
819791            case TYPE3_SWAP_12:
820792               data =
821                  (state->m_type3_d0_latch << 0) |
793                  (m_type3_d0_latch << 0) |
822794                  (BIT(save, 2) << 1) |
823795                  (BIT(save, 1) << 2) |
824796                  (BIT(save, 3) << 3) |
r18037r18038
829801               break;
830802            case TYPE3_SWAP_13:
831803               data =
832                  (state->m_type3_d0_latch << 0) |
804                  (m_type3_d0_latch << 0) |
833805                  (BIT(save, 3) << 1) |
834806                  (BIT(save, 2) << 2) |
835807                  (BIT(save, 1) << 3) |
r18037r18038
840812               break;
841813            case TYPE3_SWAP_24:
842814               data =
843                  (state->m_type3_d0_latch << 0) |
815                  (m_type3_d0_latch << 0) |
844816                  (BIT(save, 1) << 1) |
845817                  (BIT(save, 4) << 2) |
846818                  (BIT(save, 3) << 3) |
r18037r18038
851823               break;
852824            case TYPE3_SWAP_25:
853825               data =
854                  (state->m_type3_d0_latch << 0) |
826                  (m_type3_d0_latch << 0) |
855827                  (BIT(save, 1) << 1) |
856828                  (BIT(save, 5) << 2) |
857829                  (BIT(save, 3) << 3) |
r18037r18038
862834               break;
863835            case TYPE3_SWAP_34_0:
864836               data =
865                  (state->m_type3_d0_latch << 0) |
837                  (m_type3_d0_latch << 0) |
866838                  (BIT(save, 1) << 1) |
867839                  (BIT(save, 2) << 2) |
868840                  (BIT(save, 3) << 4) |
r18037r18038
880852                  (BIT(save, 3) << 4) |
881853                  (BIT(save, 5) << 5) |
882854                  (BIT(save, 6) << 6) |
883                  (state->m_type3_d0_latch << 7);
855                  (m_type3_d0_latch << 7);
884856               break;
885857            case TYPE3_SWAP_45:
886858               data =
887                  state->m_type3_d0_latch |
859                  m_type3_d0_latch |
888860                  (BIT(save, 1) << 1) |
889861                  (BIT(save, 2) << 2) |
890862                  (BIT(save, 3) << 3) |
r18037r18038
895867               break;
896868            case TYPE3_SWAP_23_56:
897869               data =
898                  (state->m_type3_d0_latch << 0) |
870                  (m_type3_d0_latch << 0) |
899871                  (BIT(save, 1) << 1) |
900872                  (BIT(save, 3) << 2) |
901873                  (BIT(save, 2) << 3) |
r18037r18038
906878               break;
907879            case TYPE3_SWAP_56:
908880               data =
909                  state->m_type3_d0_latch |
881                  m_type3_d0_latch |
910882                  (BIT(save, 1) << 1) |
911883                  (BIT(save, 2) << 2) |
912884                  (BIT(save, 3) << 3) |
r18037r18038
917889               break;
918890            case TYPE3_SWAP_67:
919891               data =
920                  state->m_type3_d0_latch |
892                  m_type3_d0_latch |
921893                  (BIT(save, 1) << 1) |
922894                  (BIT(save, 2) << 2) |
923895                  (BIT(save, 3) << 3) |
r18037r18038
928900               break;
929901            default:
930902               data =
931                  state->m_type3_d0_latch |
903                  m_type3_d0_latch |
932904                  (BIT(save, 1) << 1) |
933905                  (BIT(save, 2) << 2) |
934906                  (BIT(save, 3) << 3) |
r18037r18038
937909                  (BIT(save, 6) << 6) |
938910                  (BIT(save, 7) << 7);
939911            }
940            state->m_type3_d0_latch = save & 1;
912            m_type3_d0_latch = save & 1;
941913            LOG(3,("%10s 6502-PC: %04x decocass_type3_r(%02x): $%02x '%c' <- 8041-DATA\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, (data >= 32) ? data : '.'));
942914         }
943915         else
944916         {
945917            save = 0xff;   /* open data bus? */
946918            data =
947               state->m_type3_d0_latch |
919               m_type3_d0_latch |
948920               (BIT(save, 1) << 1) |
949921               (BIT(save, 2) << 2) |
950922               (BIT(save, 3) << 3) |
r18037r18038
953925               (BIT(save, 6) << 7) |
954926               (BIT(save, 7) << 6);
955927            LOG(3,("%10s 6502-PC: %04x decocass_type3_r(%02x): $%02x '%c' <- open bus (D0 replaced with latch)\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, (data >= 32) ? data : '.'));
956            state->m_type3_d0_latch = save & 1;
928            m_type3_d0_latch = save & 1;
957929         }
958930      }
959931   }
r18037r18038
961933   return data;
962934}
963935
964static WRITE8_HANDLER( decocass_type3_w )
936WRITE8_MEMBER(decocass_state::decocass_type3_w)
965937{
966   decocass_state *state = space.machine().driver_data<decocass_state>();
967938   if (1 == (offset & 1))
968939   {
969      if (1 == state->m_type3_pal_19)
940      if (1 == m_type3_pal_19)
970941      {
971         state->m_type3_ctrs = data << 4;
942         m_type3_ctrs = data << 4;
972943         LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, "LDCTRS"));
973944         return;
974945      }
975946      else
976947      if (0xc0 == (data & 0xf0))
977         state->m_type3_pal_19 = 1;
948         m_type3_pal_19 = 1;
978949   }
979950   else
980951   {
981      if (1 == state->m_type3_pal_19)
952      if (1 == m_type3_pal_19)
982953      {
983954         /* write nowhere?? */
984955         LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, "nowhere?"));
r18037r18038
986957      }
987958   }
988959   LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, offset & 1 ? "8041-CMND" : "8041-DATA"));
989   upi41_master_w(state->m_mcu, offset, data);
960   upi41_master_w(m_mcu, offset, data);
990961}
991962
992963/***************************************************************************
r18037r18038
1002973 *
1003974 ***************************************************************************/
1004975
1005static READ8_HANDLER( decocass_type4_r )
976READ8_MEMBER(decocass_state::decocass_type4_r)
1006977{
1007   decocass_state *state = space.machine().driver_data<decocass_state>();
1008978   UINT8 data;
1009979
1010980   if (1 == (offset & 1))
1011981   {
1012982      if (0 == (offset & E5XX_MASK))
1013983      {
1014         data = upi41_master_r(state->m_mcu, 1);
984         data = upi41_master_r(m_mcu, 1);
1015985         LOG(4,("%10s 6502-PC: %04x decocass_type4_r(%02x): $%02x <- 8041 STATUS\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data));
1016986      }
1017987      else
r18037r18038
1022992   }
1023993   else
1024994   {
1025      if (state->m_type4_latch)
995      if (m_type4_latch)
1026996      {
1027997         UINT8 *prom = space.machine().root_device().memregion("dongle")->base();
1028998
1029         data = prom[state->m_type4_ctrs];
1030         LOG(3,("%10s 6502-PC: %04x decocass_type4_r(%02x): $%02x '%c' <- PROM[%04x]\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, (data >= 32) ? data : '.', state->m_type4_ctrs));
1031         state->m_type4_ctrs = (state->m_type4_ctrs + 1) & 0x7fff;
999         data = prom[m_type4_ctrs];
1000         LOG(3,("%10s 6502-PC: %04x decocass_type4_r(%02x): $%02x '%c' <- PROM[%04x]\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, (data >= 32) ? data : '.', m_type4_ctrs));
1001         m_type4_ctrs = (m_type4_ctrs + 1) & 0x7fff;
10321002      }
10331003      else
10341004      {
10351005         if (0 == (offset & E5XX_MASK))
10361006         {
1037            data = upi41_master_r(state->m_mcu, 0);
1007            data = upi41_master_r(m_mcu, 0);
10381008            LOG(3,("%10s 6502-PC: %04x decocass_type4_r(%02x): $%02x '%c' <- open bus (D0 replaced with latch)\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, (data >= 32) ? data : '.'));
10391009         }
10401010         else
r18037r18038
10481018   return data;
10491019}
10501020
1051static WRITE8_HANDLER( decocass_type4_w )
1021WRITE8_MEMBER(decocass_state::decocass_type4_w)
10521022{
1053   decocass_state *state = space.machine().driver_data<decocass_state>();
10541023   if (1 == (offset & 1))
10551024   {
1056      if (1 == state->m_type4_latch)
1025      if (1 == m_type4_latch)
10571026      {
1058         state->m_type4_ctrs = (state->m_type4_ctrs & 0x00ff) | ((data & 0x7f) << 8);
1059         LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> CTRS MSB (%04x)\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, state->m_type4_ctrs));
1027         m_type4_ctrs = (m_type4_ctrs & 0x00ff) | ((data & 0x7f) << 8);
1028         LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> CTRS MSB (%04x)\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, m_type4_ctrs));
10601029         return;
10611030      }
10621031      else
10631032      if (0xc0 == (data & 0xf0))
10641033      {
1065         state->m_type4_latch = 1;
1034         m_type4_latch = 1;
10661035      }
10671036   }
10681037   else
10691038   {
1070      if (state->m_type4_latch)
1039      if (m_type4_latch)
10711040      {
1072         state->m_type4_ctrs = (state->m_type4_ctrs & 0xff00) | data;
1073         LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> CTRS LSB (%04x)\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, state->m_type4_ctrs));
1041         m_type4_ctrs = (m_type4_ctrs & 0xff00) | data;
1042         LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> CTRS LSB (%04x)\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, m_type4_ctrs));
10741043         return;
10751044      }
10761045   }
10771046   LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, offset & 1 ? "8041-CMND" : "8041-DATA"));
1078   upi41_master_w(state->m_mcu, offset, data);
1047   upi41_master_w(m_mcu, offset, data);
10791048}
10801049
10811050/***************************************************************************
r18037r18038
10871056 *
10881057 ***************************************************************************/
10891058
1090static READ8_HANDLER( decocass_type5_r )
1059READ8_MEMBER(decocass_state::decocass_type5_r)
10911060{
1092   decocass_state *state = space.machine().driver_data<decocass_state>();
10931061   UINT8 data;
10941062
10951063   if (1 == (offset & 1))
10961064   {
10971065      if (0 == (offset & E5XX_MASK))
10981066      {
1099         data = upi41_master_r(state->m_mcu, 1);
1067         data = upi41_master_r(m_mcu, 1);
11001068         LOG(4,("%10s 6502-PC: %04x decocass_type5_r(%02x): $%02x <- 8041 STATUS\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data));
11011069      }
11021070      else
r18037r18038
11071075   }
11081076   else
11091077   {
1110      if (state->m_type5_latch)
1078      if (m_type5_latch)
11111079      {
11121080         data = 0x55;   /* Only a fixed value? It looks like this is all we need to do */
11131081         LOG(3,("%10s 6502-PC: %04x decocass_type5_r(%02x): $%02x '%c' <- fixed value???\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, (data >= 32) ? data : '.'));
r18037r18038
11161084      {
11171085         if (0 == (offset & E5XX_MASK))
11181086         {
1119            data = upi41_master_r(state->m_mcu, 0);
1087            data = upi41_master_r(m_mcu, 0);
11201088            LOG(3,("%10s 6502-PC: %04x decocass_type5_r(%02x): $%02x '%c' <- open bus (D0 replaced with latch)\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, (data >= 32) ? data : '.'));
11211089         }
11221090         else
r18037r18038
11301098   return data;
11311099}
11321100
1133static WRITE8_HANDLER( decocass_type5_w )
1101WRITE8_MEMBER(decocass_state::decocass_type5_w)
11341102{
1135   decocass_state *state = space.machine().driver_data<decocass_state>();
11361103   if (1 == (offset & 1))
11371104   {
1138      if (1 == state->m_type5_latch)
1105      if (1 == m_type5_latch)
11391106      {
11401107         LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, "latch #2??"));
11411108         return;
11421109      }
11431110      else
11441111      if (0xc0 == (data & 0xf0))
1145         state->m_type5_latch = 1;
1112         m_type5_latch = 1;
11461113   }
11471114   else
11481115   {
1149      if (state->m_type5_latch)
1116      if (m_type5_latch)
11501117      {
11511118         /* write nowhere?? */
11521119         LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, "nowhere?"));
r18037r18038
11541121      }
11551122   }
11561123   LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, offset & 1 ? "8041-CMND" : "8041-DATA"));
1157   upi41_master_w(state->m_mcu, offset, data);
1124   upi41_master_w(m_mcu, offset, data);
11581125}
11591126
11601127/***************************************************************************
r18037r18038
11651132 *
11661133 ***************************************************************************/
11671134
1168static READ8_HANDLER( decocass_nodong_r )
1135READ8_MEMBER(decocass_state::decocass_nodong_r)
11691136{
1170   decocass_state *state = space.machine().driver_data<decocass_state>();
11711137   UINT8 data;
11721138
11731139   if (1 == (offset & 1))
11741140   {
11751141      if (0 == (offset & E5XX_MASK))
11761142      {
1177         data = upi41_master_r(state->m_mcu, 1);
1143         data = upi41_master_r(m_mcu, 1);
11781144         LOG(4,("%10s 6502-PC: %04x decocass_nodong_r(%02x): $%02x <- 8041 STATUS\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data));
11791145      }
11801146      else
r18037r18038
11871153   {
11881154      if (0 == (offset & E5XX_MASK))
11891155      {
1190         data = upi41_master_r(state->m_mcu, 0);
1156         data = upi41_master_r(m_mcu, 0);
11911157         LOG(3,("%10s 6502-PC: %04x decocass_nodong_r(%02x): $%02x '%c' <- open bus (D0 replaced with latch)\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, (data >= 32) ? data : '.'));
11921158      }
11931159      else
r18037r18038
12061172 *
12071173 ***************************************************************************/
12081174
1209READ8_HANDLER( decocass_e5xx_r )
1175READ8_MEMBER(decocass_state::decocass_e5xx_r)
12101176{
1211   decocass_state *state = space.machine().driver_data<decocass_state>();
12121177   UINT8 data;
12131178
12141179   /* E5x2-E5x3 and mirrors */
12151180   if (2 == (offset & E5XX_MASK))
12161181   {
1217      UINT8 bot_eot = (tape_get_status_bits(state->m_cassette) >> 5) & 1;
1182      UINT8 bot_eot = (tape_get_status_bits(m_cassette) >> 5) & 1;
12181183
12191184      data =
1220         (BIT(state->m_i8041_p1, 7)     << 0) |   /* D0 = P17 - REQ/ */
1221         (BIT(state->m_i8041_p2, 0)     << 1) |   /* D1 = P20 - FNO/ */
1222         (BIT(state->m_i8041_p2, 1)     << 2) |   /* D2 = P21 - EOT/ */
1223         (BIT(state->m_i8041_p2, 2)     << 3) |   /* D3 = P22 - ERR/ */
1185         (BIT(m_i8041_p1, 7)     << 0) |   /* D0 = P17 - REQ/ */
1186         (BIT(m_i8041_p2, 0)     << 1) |   /* D1 = P20 - FNO/ */
1187         (BIT(m_i8041_p2, 1)     << 2) |   /* D2 = P21 - EOT/ */
1188         (BIT(m_i8041_p2, 2)     << 3) |   /* D3 = P22 - ERR/ */
12241189         ((bot_eot)             << 4) |   /* D4 = BOT/EOT (direct from drive) */
12251190         (1                 << 5) |   /* D5 floating input */
12261191         (1                 << 6) |   /* D6 floating input */
1227         (!tape_is_present(state->m_cassette) << 7);   /* D7 = cassette present */
1192         (!tape_is_present(m_cassette) << 7);   /* D7 = cassette present */
12281193
12291194      LOG(4,("%10s 6502-PC: %04x decocass_e5xx_r(%02x): $%02x <- STATUS (%s%s%s%s%s%s%s%s)\n",
12301195         space.machine().time().as_string(6),
r18037r18038
12411206   }
12421207   else
12431208   {
1244      if (state->m_dongle_r)
1245         data = (*state->m_dongle_r)(space, offset, mem_mask);
1209      if (!m_dongle_r.isnull())
1210         data = (m_dongle_r)(space, offset, mem_mask);
12461211      else
12471212         data = 0xff;
12481213   }
12491214   return data;
12501215}
12511216
1252WRITE8_HANDLER( decocass_e5xx_w )
1217WRITE8_MEMBER(decocass_state::decocass_e5xx_w)
12531218{
1254   decocass_state *state = space.machine().driver_data<decocass_state>();
1255   if (state->m_dongle_w)
1219   if (!m_dongle_w.isnull())
12561220   {
1257      (*state->m_dongle_w)(space, offset, data, mem_mask);
1221      (m_dongle_w)(space, offset, data, mem_mask);
12581222      return;
12591223   }
12601224
12611225   if (0 == (offset & E5XX_MASK))
12621226   {
12631227      LOG(3,("%10s 6502-PC: %04x decocass_e5xx_w(%02x): $%02x -> %s\n", space.machine().time().as_string(6), space.device().safe_pcbase(), offset, data, offset & 1 ? "8041-CMND" : "8041-DATA"));
1264      upi41_master_w(state->m_mcu, offset & 1, data);
1228      upi41_master_w(m_mcu, offset & 1, data);
12651229#ifdef MAME_DEBUG
12661230      decocass_fno(space.machine(), offset, data);
12671231#endif
r18037r18038
12841248 *
12851249 ***************************************************************************/
12861250
1287WRITE8_HANDLER( decocass_e900_w )
1251WRITE8_MEMBER(decocass_state::decocass_e900_w)
12881252{
1289   decocass_state *state = space.machine().driver_data<decocass_state>();
1290   state->m_de0091_enable = data & 1;
1291   state->membank("bank1")->set_entry(data & 1);
1253   m_de0091_enable = data & 1;
1254   membank("bank1")->set_entry(data & 1);
12921255   /* Perhaps the second row of ROMs is enabled by another bit.
12931256     * There is no way to verify this yet, so for now just look
12941257     * at bit 0 to enable the daughter board at reads between
r18037r18038
12961259     */
12971260}
12981261
1299WRITE8_HANDLER( decocass_de0091_w )
1262WRITE8_MEMBER(decocass_state::decocass_de0091_w)
13001263{
1301   decocass_state *state = space.machine().driver_data<decocass_state>();
13021264   /* don't allow writes to the ROMs */
1303   if (!state->m_de0091_enable)
1265   if (!m_de0091_enable)
13041266      decocass_charram_w(space, offset, data);
13051267}
13061268
r18037r18038
13101272 *
13111273 ***************************************************************************/
13121274/* To be called once from driver_init, i.e. decocass_init */
1313void decocass_machine_state_save_init( running_machine &machine )
1275void decocass_state::decocass_machine_state_save_init()
13141276{
1315   decocass_state *state = machine.driver_data<decocass_state>();
1316   state->save_item(NAME(state->m_firsttime));
1317   state->save_item(NAME(state->m_decocass_reset));
1318   state->save_item(NAME(state->m_i8041_p1));
1319   state->save_item(NAME(state->m_i8041_p2));
1320   state->save_item(NAME(state->m_de0091_enable));
1321   state->save_item(NAME(state->m_type1_inmap));
1322   state->save_item(NAME(state->m_type1_outmap));
1323   state->save_item(NAME(state->m_type2_d2_latch));
1324   state->save_item(NAME(state->m_type2_xx_latch));
1325   state->save_item(NAME(state->m_type2_promaddr));
1326   state->save_item(NAME(state->m_type3_ctrs));
1327   state->save_item(NAME(state->m_type3_d0_latch));
1328   state->save_item(NAME(state->m_type3_pal_19));
1329   state->save_item(NAME(state->m_type3_swap));
1330   state->save_item(NAME(state->m_type4_ctrs));
1331   state->save_item(NAME(state->m_type4_latch));
1332   state->save_item(NAME(state->m_type5_latch));
1333   state->save_item(NAME(state->m_sound_ack));
1277   save_item(NAME(m_firsttime));
1278   save_item(NAME(m_decocass_reset));
1279   save_item(NAME(m_i8041_p1));
1280   save_item(NAME(m_i8041_p2));
1281   save_item(NAME(m_de0091_enable));
1282   save_item(NAME(m_type1_inmap));
1283   save_item(NAME(m_type1_outmap));
1284   save_item(NAME(m_type2_d2_latch));
1285   save_item(NAME(m_type2_xx_latch));
1286   save_item(NAME(m_type2_promaddr));
1287   save_item(NAME(m_type3_ctrs));
1288   save_item(NAME(m_type3_d0_latch));
1289   save_item(NAME(m_type3_pal_19));
1290   save_item(NAME(m_type3_swap));
1291   save_item(NAME(m_type4_ctrs));
1292   save_item(NAME(m_type4_latch));
1293   save_item(NAME(m_type5_latch));
1294   save_item(NAME(m_sound_ack));
13341295
1335   state->save_item(NAME(state->m_quadrature_decoder));
1336   state->save_item(NAME(state->m_latch1));
1337   state->save_item(NAME(state->m_audio_nmi_enabled));
1338   state->save_item(NAME(state->m_audio_nmi_state));
1339   state->save_item(NAME(state->m_i8041_p1_write_latch));
1340   state->save_item(NAME(state->m_i8041_p2_write_latch));
1341   state->save_item(NAME(state->m_i8041_p1_read_latch));
1342   state->save_item(NAME(state->m_i8041_p2_read_latch));
1296   save_item(NAME(m_quadrature_decoder));
1297   save_item(NAME(m_latch1));
1298   save_item(NAME(m_audio_nmi_enabled));
1299   save_item(NAME(m_audio_nmi_state));
1300   save_item(NAME(m_i8041_p1_write_latch));
1301   save_item(NAME(m_i8041_p2_write_latch));
1302   save_item(NAME(m_i8041_p1_read_latch));
1303   save_item(NAME(m_i8041_p2_read_latch));
13431304}
13441305
13451306/***************************************************************************
r18037r18038
13501311
13511312void decocass_state::machine_start()
13521313{
1353
1354   m_maincpu = machine().device<cpu_device>("maincpu");
1355   m_audiocpu = machine().device<cpu_device>("audiocpu");
1356   m_mcu = machine().device("mcu");
1357   m_cassette = machine().device("cassette");
13581314}
13591315
1360static void decocass_reset_common( running_machine &machine )
1316void decocass_state::machine_reset()
13611317{
1362   decocass_state *state = machine.driver_data<decocass_state>();
1363   state->m_firsttime = 1;
1364   state->m_latch1 = 0;
1318   m_firsttime = 1;
1319   m_latch1 = 0;
13651320
1366   state->m_dongle_r = NULL;
1367   state->m_dongle_w = NULL;
1321   m_dongle_r = read8_delegate();
1322   m_dongle_w = write8_delegate();
13681323
1369   state->m_decocass_reset = 0;
1370   state->m_i8041_p1 = 0xff;
1371   state->m_i8041_p2 = 0xff;
1372   state->m_i8041_p1_write_latch = 0xff;
1373   state->m_i8041_p2_write_latch = 0xff;
1374   state->m_i8041_p1_read_latch = 0xff;
1375   state->m_i8041_p2_read_latch = 0xff;
1376   state->m_de0091_enable = 0;
1324   m_decocass_reset = 0;
1325   m_i8041_p1 = 0xff;
1326   m_i8041_p2 = 0xff;
1327   m_i8041_p1_write_latch = 0xff;
1328   m_i8041_p2_write_latch = 0xff;
1329   m_i8041_p1_read_latch = 0xff;
1330   m_i8041_p2_read_latch = 0xff;
1331   m_de0091_enable = 0;
13771332
1378   state->m_type1_inmap = MAKE_MAP(0,1,2,3,4,5,6,7);
1379   state->m_type1_outmap = MAKE_MAP(0,1,2,3,4,5,6,7);
1333   m_type1_inmap = MAKE_MAP(0,1,2,3,4,5,6,7);
1334   m_type1_outmap = MAKE_MAP(0,1,2,3,4,5,6,7);
13801335
1381   state->m_type2_d2_latch = 0;
1382   state->m_type2_xx_latch = 0;
1383   state->m_type2_promaddr = 0;
1336   m_type2_d2_latch = 0;
1337   m_type2_xx_latch = 0;
1338   m_type2_promaddr = 0;
13841339
1385   state->m_type3_ctrs = 0;
1386   state->m_type3_d0_latch = 0;
1387   state->m_type3_pal_19 = 0;
1388   state->m_type3_swap = 0;
1340   m_type3_ctrs = 0;
1341   m_type3_d0_latch = 0;
1342   m_type3_pal_19 = 0;
1343   m_type3_swap = 0;
13891344
1390   state->m_type4_ctrs = 0;
1391   state->m_type4_latch = 0;
1345   m_type4_ctrs = 0;
1346   m_type4_latch = 0;
13921347
1393   state->m_type5_latch = 0;
1348   m_type5_latch = 0;
13941349
1395   memset(state->m_quadrature_decoder, 0, sizeof(state->m_quadrature_decoder));
1396   state->m_sound_ack = 0;
1397   state->m_audio_nmi_enabled = 0;
1398   state->m_audio_nmi_state = 0;
1350   memset(m_quadrature_decoder, 0, sizeof(m_quadrature_decoder));
1351   m_sound_ack = 0;
1352   m_audio_nmi_enabled = 0;
1353   m_audio_nmi_state = 0;
13991354
14001355   /* video-related */
1401   state->m_watchdog_flip = 0;
1402   state->m_color_missiles = 0;
1403   state->m_color_center_bot = 0;
1404   state->m_mode_set = 0;
1405   state->m_back_h_shift = 0;
1406   state->m_back_vl_shift = 0;
1407   state->m_back_vr_shift = 0;
1408   state->m_part_h_shift = 0;
1409   state->m_part_v_shift = 0;
1410   state->m_center_h_shift_space = 0;
1411   state->m_center_v_shift = 0;
1356   m_watchdog_flip = 0;
1357   m_color_missiles = 0;
1358   m_color_center_bot = 0;
1359   m_mode_set = 0;
1360   m_back_h_shift = 0;
1361   m_back_vl_shift = 0;
1362   m_back_vr_shift = 0;
1363   m_part_h_shift = 0;
1364   m_part_v_shift = 0;
1365   m_center_h_shift_space = 0;
1366   m_center_v_shift = 0;
14121367}
14131368
1414void decocass_state::machine_reset()
1415{
1416   decocass_reset_common(machine());
1417}
1418
14191369MACHINE_RESET_MEMBER(decocass_state,ctsttape)
14201370{
1421   decocass_reset_common(machine());
1371   decocass_state::machine_reset();
14221372   LOG(0,("dongle type #1 (DE-0061)\n"));
1423   m_dongle_r = decocass_type1_pass_136_r;
1373   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type1_pass_136_r),this);
14241374}
14251375
14261376MACHINE_RESET_MEMBER(decocass_state,chwy)
14271377{
1428   decocass_reset_common(machine());
1378   decocass_state::machine_reset();
14291379   LOG(0,("dongle type #1 (DE-0061 own PROM)\n"));
1430   m_dongle_r = decocass_type1_latch_27_pass_3_inv_2_r;
1380   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type1_latch_27_pass_3_inv_2_r),this);
14311381}
14321382
14331383MACHINE_RESET_MEMBER(decocass_state,cdsteljn)
14341384{
1435   decocass_reset_common(machine());
1385   decocass_state::machine_reset();
14361386   LOG(0,("dongle type #1 (A-0061)\n"));
1437   m_dongle_r = decocass_type1_latch_27_pass_3_inv_2_r;
1387   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type1_latch_27_pass_3_inv_2_r),this);
14381388}
14391389
14401390MACHINE_RESET_MEMBER(decocass_state,cterrani)
14411391{
1442   decocass_reset_common(machine());
1392   decocass_state::machine_reset();
14431393   LOG(0,("dongle type #1 (DE-0061 straight)\n"));
1444   m_dongle_r = decocass_type1_latch_26_pass_3_inv_2_r;
1394   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type1_latch_26_pass_3_inv_2_r),this);
14451395   m_type1_inmap = MAKE_MAP(0,1,2,3,4,5,6,7);
14461396   m_type1_outmap = MAKE_MAP(0,1,2,3,4,5,6,7);
14471397}
14481398
14491399MACHINE_RESET_MEMBER(decocass_state,castfant)
14501400{
1451   decocass_reset_common(machine());
1401   decocass_state::machine_reset();
14521402   LOG(0,("dongle type #1 (DE-0061)\n"));
1453   m_dongle_r = decocass_type1_latch_16_pass_3_inv_1_r;
1403   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type1_latch_16_pass_3_inv_1_r),this);
14541404}
14551405
14561406MACHINE_RESET_MEMBER(decocass_state,csuperas)
14571407{
1458   decocass_reset_common(machine());
1408   decocass_state::machine_reset();
14591409   LOG(0,("dongle type #1 (DE-0061 flip 4-5)\n"));
1460   m_dongle_r = decocass_type1_latch_26_pass_3_inv_2_r;
1410   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type1_latch_26_pass_3_inv_2_r),this);
14611411   m_type1_inmap = MAKE_MAP(0,1,2,3,5,4,6,7);
14621412   m_type1_outmap = MAKE_MAP(0,1,2,3,5,4,6,7);
14631413}
14641414
14651415MACHINE_RESET_MEMBER(decocass_state,clocknch)
14661416{
1467   decocass_reset_common(machine());
1417   decocass_state::machine_reset();
14681418   LOG(0,("dongle type #1 (DE-0061 flip 2-3)\n"));
1469   m_dongle_r = decocass_type1_latch_26_pass_3_inv_2_r;
1419   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type1_latch_26_pass_3_inv_2_r),this);
14701420   m_type1_inmap = MAKE_MAP(0,1,3,2,4,5,6,7);
14711421   m_type1_outmap = MAKE_MAP(0,1,3,2,4,5,6,7);
14721422}
14731423
14741424MACHINE_RESET_MEMBER(decocass_state,cprogolf)
14751425{
1476   decocass_reset_common(machine());
1426   decocass_state::machine_reset();
14771427   LOG(0,("dongle type #1 (DE-0061 flip 0-1)\n"));
1478   m_dongle_r = decocass_type1_latch_26_pass_3_inv_2_r;
1428   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type1_latch_26_pass_3_inv_2_r),this);
14791429   m_type1_inmap = MAKE_MAP(1,0,2,3,4,5,6,7);
14801430   m_type1_outmap = MAKE_MAP(1,0,2,3,4,5,6,7);
14811431}
14821432
14831433MACHINE_RESET_MEMBER(decocass_state,cprogolfj)
14841434{
1485   decocass_reset_common(machine());
1435   decocass_state::machine_reset();
14861436   LOG(0,("dongle type #1 (A-0061 flip 0-1)\n"));
1487   m_dongle_r = decocass_type1_latch_26_pass_3_inv_2_r;
1437   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type1_latch_26_pass_3_inv_2_r),this);
14881438   m_type1_inmap = MAKE_MAP(1,0,2,3,4,5,6,7);
14891439   m_type1_outmap = MAKE_MAP(1,0,2,3,4,5,6,7);
14901440}
14911441
14921442MACHINE_RESET_MEMBER(decocass_state,cluckypo)
14931443{
1494   decocass_reset_common(machine());
1444   decocass_state::machine_reset();
14951445   LOG(0,("dongle type #1 (DE-0061 flip 1-3)\n"));
1496   m_dongle_r = decocass_type1_latch_26_pass_3_inv_2_r;
1446   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type1_latch_26_pass_3_inv_2_r),this);
14971447   m_type1_inmap = MAKE_MAP(0,3,2,1,4,5,6,7);
14981448   m_type1_outmap = MAKE_MAP(0,3,2,1,4,5,6,7);
14991449}
15001450
15011451MACHINE_RESET_MEMBER(decocass_state,ctisland)
15021452{
1503   decocass_reset_common(machine());
1453   decocass_state::machine_reset();
15041454   LOG(0,("dongle type #1 (DE-0061 flip 0-2)\n"));
1505   m_dongle_r = decocass_type1_latch_26_pass_3_inv_2_r;
1455   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type1_latch_26_pass_3_inv_2_r),this);
15061456   m_type1_inmap = MAKE_MAP(2,1,0,3,4,5,6,7);
15071457   m_type1_outmap = MAKE_MAP(2,1,0,3,4,5,6,7);
15081458}
15091459
15101460MACHINE_RESET_MEMBER(decocass_state,cexplore)
15111461{
1512   decocass_reset_common(machine());
1462   decocass_state::machine_reset();
15131463   LOG(0,("dongle type #1 (DE-0061 own PROM)\n"));
1514   m_dongle_r = decocass_type1_latch_26_pass_5_inv_2_r;
1464   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type1_latch_26_pass_5_inv_2_r),this);
15151465}
15161466
15171467MACHINE_RESET_MEMBER(decocass_state,cdiscon1)
15181468{
1519   decocass_reset_common(machine());
1469   decocass_state::machine_reset();
15201470   LOG(0,("dongle type #2 (CS82-007)\n"));
1521   m_dongle_r = decocass_type2_r;
1522   m_dongle_w = decocass_type2_w;
1471   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type2_r),this);
1472   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type2_w),this);
15231473}
15241474
15251475MACHINE_RESET_MEMBER(decocass_state,ctornado)
15261476{
1527   decocass_reset_common(machine());
1477   decocass_state::machine_reset();
15281478   LOG(0,("dongle type #2 (CS82-007)\n"));
1529   m_dongle_r = decocass_type2_r;
1530   m_dongle_w = decocass_type2_w;
1479   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type2_r),this);
1480   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type2_w),this);
15311481}
15321482
15331483MACHINE_RESET_MEMBER(decocass_state,cmissnx)
15341484{
1535   decocass_reset_common(machine());
1485   decocass_state::machine_reset();
15361486   LOG(0,("dongle type #2 (CS82-007)\n"));
1537   m_dongle_r = decocass_type2_r;
1538   m_dongle_w = decocass_type2_w;
1487   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type2_r),this);
1488   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type2_w),this);
15391489}
15401490
15411491MACHINE_RESET_MEMBER(decocass_state,cptennis)
15421492{
1543   decocass_reset_common(machine());
1493   decocass_state::machine_reset();
15441494   LOG(0,("dongle type #2 (CS82-007)\n"));
1545   m_dongle_r = decocass_type2_r;
1546   m_dongle_w = decocass_type2_w;
1495   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type2_r),this);
1496   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type2_w),this);
15471497}
15481498
15491499MACHINE_RESET_MEMBER(decocass_state,cfishing)
15501500{
1551   decocass_reset_common(machine());
1501   decocass_state::machine_reset();
15521502   LOG(0,("dongle type #3 (PAL)\n"));
1553   m_dongle_r = decocass_type3_r;
1554   m_dongle_w = decocass_type3_w;
1503   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1504   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
15551505   m_type3_swap = TYPE3_SWAP_01;
15561506
15571507}
15581508
15591509MACHINE_RESET_MEMBER(decocass_state,cbtime)
15601510{
1561   decocass_reset_common(machine());
1511   decocass_state::machine_reset();
15621512   LOG(0,("dongle type #3 (PAL)\n"));
1563   m_dongle_r = decocass_type3_r;
1564   m_dongle_w = decocass_type3_w;
1513   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1514   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
15651515   m_type3_swap = TYPE3_SWAP_12;
15661516
15671517}
15681518
15691519MACHINE_RESET_MEMBER(decocass_state,cburnrub)
15701520{
1571   decocass_reset_common(machine());
1521   decocass_state::machine_reset();
15721522   LOG(0,("dongle type #3 (PAL)\n"));
1573   m_dongle_r = decocass_type3_r;
1574   m_dongle_w = decocass_type3_w;
1523   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1524   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
15751525   m_type3_swap = TYPE3_SWAP_67;
15761526}
15771527
15781528MACHINE_RESET_MEMBER(decocass_state,cgraplop)
15791529{
1580   decocass_reset_common(machine());
1530   decocass_state::machine_reset();
15811531   LOG(0,("dongle type #3 (PAL)\n"));
1582   m_dongle_r = decocass_type3_r;
1583   m_dongle_w = decocass_type3_w;
1532   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1533   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
15841534   m_type3_swap = TYPE3_SWAP_56;
15851535}
15861536
15871537MACHINE_RESET_MEMBER(decocass_state,cgraplop2)
15881538{
1589   decocass_reset_common(machine());
1539   decocass_state::machine_reset();
15901540   LOG(0,("dongle type #3 (PAL)\n"));
1591   m_dongle_r = decocass_type3_r;
1592   m_dongle_w = decocass_type3_w;
1541   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1542   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
15931543   m_type3_swap = TYPE3_SWAP_67;
15941544}
15951545
15961546MACHINE_RESET_MEMBER(decocass_state,clapapa)
15971547{
1598   decocass_reset_common(machine());
1548   decocass_state::machine_reset();
15991549   LOG(0,("dongle type #3 (PAL)\n"));
1600   m_dongle_r = decocass_type3_r;
1601   m_dongle_w = decocass_type3_w;
1550   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1551   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
16021552   m_type3_swap = TYPE3_SWAP_34_7;
16031553}
16041554
16051555MACHINE_RESET_MEMBER(decocass_state,cskater)
16061556{
1607   decocass_reset_common(machine());
1557   decocass_state::machine_reset();
16081558   LOG(0,("dongle type #3 (PAL)\n"));
1609   m_dongle_r = decocass_type3_r;
1610   m_dongle_w = decocass_type3_w;
1559   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1560   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
16111561   m_type3_swap = TYPE3_SWAP_45;
16121562}
16131563
16141564MACHINE_RESET_MEMBER(decocass_state,cprobowl)
16151565{
1616   decocass_reset_common(machine());
1566   decocass_state::machine_reset();
16171567   LOG(0,("dongle type #3 (PAL)\n"));
1618   m_dongle_r = decocass_type3_r;
1619   m_dongle_w = decocass_type3_w;
1568   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1569   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
16201570   m_type3_swap = TYPE3_SWAP_34_0;
16211571}
16221572
16231573MACHINE_RESET_MEMBER(decocass_state,cnightst)
16241574{
1625   decocass_reset_common(machine());
1575   decocass_state::machine_reset();
16261576   LOG(0,("dongle type #3 (PAL)\n"));
1627   m_dongle_r = decocass_type3_r;
1628   m_dongle_w = decocass_type3_w;
1577   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1578   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
16291579   m_type3_swap = TYPE3_SWAP_13;
16301580}
16311581
16321582MACHINE_RESET_MEMBER(decocass_state,cpsoccer)
16331583{
1634   decocass_reset_common(machine());
1584   decocass_state::machine_reset();
16351585   LOG(0,("dongle type #3 (PAL)\n"));
1636   m_dongle_r = decocass_type3_r;
1637   m_dongle_w = decocass_type3_w;
1586   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1587   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
16381588   m_type3_swap = TYPE3_SWAP_24;
16391589}
16401590
16411591MACHINE_RESET_MEMBER(decocass_state,csdtenis)
16421592{
1643   decocass_reset_common(machine());
1593   decocass_state::machine_reset();
16441594   LOG(0,("dongle type #3 (PAL)\n"));
1645   m_dongle_r = decocass_type3_r;
1646   m_dongle_w = decocass_type3_w;
1595   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1596   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
16471597   m_type3_swap = TYPE3_SWAP_23_56;
16481598}
16491599
16501600MACHINE_RESET_MEMBER(decocass_state,czeroize)
16511601{
16521602   UINT8 *mem = memregion("dongle")->base();
1653   decocass_reset_common(machine());
1603   decocass_state::machine_reset();
16541604   LOG(0,("dongle type #3 (PAL)\n"));
1655   m_dongle_r = decocass_type3_r;
1656   m_dongle_w = decocass_type3_w;
1605   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1606   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
16571607   m_type3_swap = TYPE3_SWAP_23_56;
16581608
16591609   /*
r18037r18038
16721622
16731623MACHINE_RESET_MEMBER(decocass_state,cppicf)
16741624{
1675   decocass_reset_common(machine());
1625   decocass_state::machine_reset();
16761626   LOG(0,("dongle type #3 (PAL)\n"));
1677   m_dongle_r = decocass_type3_r;
1678   m_dongle_w = decocass_type3_w;
1627   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1628   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
16791629   m_type3_swap = TYPE3_SWAP_01;
16801630}
16811631
16821632MACHINE_RESET_MEMBER(decocass_state,cfghtice)
16831633{
1684   decocass_reset_common(machine());
1634   decocass_state::machine_reset();
16851635   LOG(0,("dongle type #3 (PAL)\n"));
1686   m_dongle_r = decocass_type3_r;
1687   m_dongle_w = decocass_type3_w;
1636   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type3_r),this);
1637   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type3_w),this);
16881638   m_type3_swap = TYPE3_SWAP_25;
16891639}
16901640
16911641MACHINE_RESET_MEMBER(decocass_state,type4)
16921642{
1693   decocass_reset_common(machine());
1643   decocass_state::machine_reset();
16941644   LOG(0,("dongle type #4 (32K ROM)\n"));
1695   m_dongle_r = decocass_type4_r;
1696   m_dongle_w = decocass_type4_w;
1645   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type4_r),this);
1646   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type4_w),this);
16971647}
16981648
16991649MACHINE_RESET_MEMBER(decocass_state,cbdash)
17001650{
1701   decocass_reset_common(machine());
1651   decocass_state::machine_reset();
17021652   LOG(0,("dongle type #5 (NOP)\n"));
1703   m_dongle_r = decocass_type5_r;
1704   m_dongle_w = decocass_type5_w;
1653   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_type5_r),this);
1654   m_dongle_w = write8_delegate(FUNC(decocass_state::decocass_type5_w),this);
17051655}
17061656
17071657MACHINE_RESET_MEMBER(decocass_state,cflyball)
17081658{
1709   decocass_reset_common(machine());
1659   decocass_state::machine_reset();
17101660   LOG(0,("no dongle\n"));
1711   m_dongle_r = decocass_nodong_r;
1661   m_dongle_r = read8_delegate(FUNC(decocass_state::decocass_nodong_r),this);
17121662}
17131663
17141664/***************************************************************************
r18037r18038
17171667 *
17181668 ***************************************************************************/
17191669
1720WRITE8_HANDLER( i8041_p1_w )
1670WRITE8_MEMBER(decocass_state::i8041_p1_w)
17211671{
1722   decocass_state *state = space.machine().driver_data<decocass_state>();
1723   if (data != state->m_i8041_p1_write_latch)
1672   if (data != m_i8041_p1_write_latch)
17241673   {
17251674      LOG(4,("%10s 8041-PC: %03x i8041_p1_w: $%02x (%s%s%s%s%s%s%s%s)\n",
17261675         space.machine().time().as_string(6),
r18037r18038
17341683         data & 0x20 ? "" : " FWD",
17351684         data & 0x40 ? "" : " WREN",
17361685         data & 0x80 ? "" : " REQ"));
1737      state->m_i8041_p1_write_latch = data;
1686      m_i8041_p1_write_latch = data;
17381687   }
17391688
17401689   /* change in FAST/REW/FWD signals? */
1741   if ((data ^ state->m_i8041_p1) & 0x34)
1690   if ((data ^ m_i8041_p1) & 0x34)
17421691   {
17431692      int newspeed = 0;
17441693
r18037r18038
17461695         newspeed = (data & 0x04) ? -1 : -7;
17471696      else if ((data & 0x30) == 0x10)
17481697         newspeed = (data & 0x04) ? 1 : 7;
1749      tape_change_speed(state->m_cassette, newspeed);
1698      tape_change_speed(m_cassette, newspeed);
17501699   }
17511700
1752   state->m_i8041_p1 = data;
1701   m_i8041_p1 = data;
17531702}
17541703
1755READ8_HANDLER( i8041_p1_r )
1704READ8_MEMBER(decocass_state::i8041_p1_r)
17561705{
1757   decocass_state *state = space.machine().driver_data<decocass_state>();
1758   UINT8 data = state->m_i8041_p1;
1706   UINT8 data = m_i8041_p1;
17591707
1760   if (data != state->m_i8041_p1_read_latch)
1708   if (data != m_i8041_p1_read_latch)
17611709   {
17621710      LOG(4,("%10s 8041-PC: %03x i8041_p1_r: $%02x (%s%s%s%s%s%s%s%s)\n",
17631711         space.machine().time().as_string(6),
r18037r18038
17711719         data & 0x20 ? "" : " FWD",
17721720         data & 0x40 ? "" : " WREN",
17731721         data & 0x80 ? "" : " REQ"));
1774      state->m_i8041_p1_read_latch = data;
1722      m_i8041_p1_read_latch = data;
17751723   }
17761724   return data;
17771725}
17781726
1779WRITE8_HANDLER( i8041_p2_w )
1727WRITE8_MEMBER(decocass_state::i8041_p2_w)
17801728{
1781   decocass_state *state = space.machine().driver_data<decocass_state>();
1782   if (data != state->m_i8041_p2_write_latch)
1729   if (data != m_i8041_p2_write_latch)
17831730   {
17841731      LOG(4,("%10s 8041-PC: %03x i8041_p2_w: $%02x (%s%s%s%s%s%s%s%s)\n",
17851732         space.machine().time().as_string(6),
r18037r18038
17931740         data & 0x20 ? " [BOT-EOT]" : "",
17941741         data & 0x40 ? " [RCLK]" : "",
17951742         data & 0x80 ? " [RDATA]" : ""));
1796      state->m_i8041_p2_write_latch = data;
1743      m_i8041_p2_write_latch = data;
17971744   }
1798   state->m_i8041_p2 = (state->m_i8041_p2 & 0xe0) | (data & ~0xe0);
1745   m_i8041_p2 = (m_i8041_p2 & 0xe0) | (data & ~0xe0);
17991746}
18001747
1801READ8_HANDLER( i8041_p2_r )
1748READ8_MEMBER(decocass_state::i8041_p2_r)
18021749{
1803   decocass_state *state = space.machine().driver_data<decocass_state>();
18041750   UINT8 data;
18051751
1806   data = (state->m_i8041_p2 & ~0xe0) | tape_get_status_bits(state->m_cassette);
1752   data = (m_i8041_p2 & ~0xe0) | tape_get_status_bits(m_cassette);
18071753
1808   if (data != state->m_i8041_p2_read_latch)
1754   if (data != m_i8041_p2_read_latch)
18091755   {
18101756      LOG(4,("%10s 8041-PC: %03x i8041_p2_r: $%02x (%s%s%s%s%s%s%s%s)\n",
18111757         space.machine().time().as_string(6),
r18037r18038
18191765         data & 0x20 ? " [BOT-EOT]" : "",
18201766         data & 0x40 ? " [RCLK]" : "",
18211767         data & 0x80 ? " [RDATA]" : ""));
1822      state->m_i8041_p2_read_latch = data;
1768      m_i8041_p2_read_latch = data;
18231769   }
18241770   return data;
18251771}
1826
1827
1828
1829/***************************************************************************
1830    CASSETTE DEVICE INTERFACE
1831***************************************************************************/
1832
1833/* regions within the virtual tape */
1834enum tape_region
1835{
1836   REGION_LEADER,            /* in clear leader section */
1837   REGION_LEADER_GAP,         /* in gap between leader and BOT */
1838   REGION_BOT,               /* in BOT hole */
1839   REGION_BOT_GAP,            /* in gap between BOT hole and data */
1840   REGION_DATA_BLOCK_0,      /* in data block 0 */
1841   REGION_DATA_BLOCK_255 = REGION_DATA_BLOCK_0 + 255,
1842   REGION_EOT_GAP,            /* in gap between data and EOT hole */
1843   REGION_EOT,               /* in EOT hole */
1844   REGION_TRAILER_GAP,         /* in gap between trailer and EOT */
1845   REGION_TRAILER            /* in clear trailer section */
1846};
1847
1848
1849/* bytes within a data block on a virtual tape */
1850enum tape_byte
1851{
1852   BYTE_PRE_GAP_0,            /* 34 bytes of gap, clock held to 0, no data */
1853   BYTE_PRE_GAP_33 = BYTE_PRE_GAP_0 + 33,
1854   BYTE_LEADIN,            /* 1 leadin byte, clocked value 0x00 */
1855   BYTE_HEADER,            /* 1 header byte, clocked value 0xAA */
1856   BYTE_DATA_0,            /* 256 bytes of data, clocked */
1857   BYTE_DATA_255 = BYTE_DATA_0 + 255,
1858   BYTE_CRC16_MSB,            /* 2 bytes of CRC, clocked MSB first, then LSB */
1859   BYTE_CRC16_LSB,
1860   BYTE_TRAILER,            /* 1 trailer byte, clocked value 0xAA */
1861   BYTE_LEADOUT,            /* 1 leadout byte, clocked value 0x00 */
1862   BYTE_LONGCLOCK,            /* 1 longclock byte, clock held to 1, no data */
1863   BYTE_POSTGAP_0,            /* 34 bytes of gap, no clock, no data */
1864   BYTE_POSTGAP_33 = BYTE_POSTGAP_0 + 33,
1865   BYTE_BLOCK_TOTAL         /* total number of bytes in block */
1866};
1867
1868
1869/* state of the tape */
1870struct tape_state
1871{
1872   running_machine *   machine;         /* pointer back to the machine */
1873   emu_timer *         timer;            /* timer for running the tape */
1874   INT8            speed;            /* speed: <-1=fast rewind, -1=reverse, 0=stopped, 1=normal, >1=fast forward */
1875   tape_region         region;            /* current region */
1876   tape_byte         bytenum;         /* byte number within a datablock */
1877   UINT8            bitnum;            /* bit number within a byte */
1878   UINT32            clockpos;         /* the current clock position of the tape */
1879   UINT32            numclocks;         /* total number of clocks on the entire tape */
1880   UINT16            crc16[256];         /* CRC16 for each block */
1881};
1882
1883
1884/* number of tape clock pulses per second */
1885#define TAPE_CLOCKRATE               4800
1886#define TAPE_CLOCKS_PER_BIT            2
1887#define TAPE_CLOCKS_PER_BYTE         (8 * TAPE_CLOCKS_PER_BIT)
1888#define TAPE_MSEC_TO_CLOCKS(x)         ((x) * TAPE_CLOCKRATE / 1000)
1889
1890
1891/* Note on a tapes leader-BOT-data-EOT-trailer format:
1892 * A cassette has a transparent piece of tape on both ends,
1893 * leader and trailer. And data tapes also have BOT and EOT
1894 * holes, shortly before the the leader and trailer.
1895 * The holes and clear tape are detected using a photo-resitor.
1896 * When rewinding, the BOT/EOT signal will show a short
1897 * pulse and if rewind continues a constant high signal later.
1898 * The specs say the holes are "> 2ms" in length.
1899 */
1900
1901/* duration of the clear LEADER (and trailer) of the tape */
1902#define REGION_LEADER_START_CLOCK      0
1903#define REGION_LEADER_LEN_CLOCKS      TAPE_MSEC_TO_CLOCKS(1000)   /* 1s */
1904#define REGION_LEADER_END_CLOCK         (REGION_LEADER_START_CLOCK+REGION_LEADER_LEN_CLOCKS)
1905
1906/* duration of the GAP between leader and BOT/EOT */
1907#define REGION_LEADER_GAP_START_CLOCK   REGION_LEADER_END_CLOCK
1908#define REGION_LEADER_GAP_LEN_CLOCKS   TAPE_MSEC_TO_CLOCKS(1500)   /* 1.5s */
1909#define REGION_LEADER_GAP_END_CLOCK      (REGION_LEADER_GAP_START_CLOCK+REGION_LEADER_GAP_LEN_CLOCKS)
1910
1911/* duration of BOT/EOT holes */
1912#define REGION_BOT_START_CLOCK         REGION_LEADER_GAP_END_CLOCK
1913#define REGION_BOT_LEN_CLOCKS         TAPE_MSEC_TO_CLOCKS(2.5)   /* 0.0025s */
1914#define REGION_BOT_END_CLOCK         (REGION_BOT_START_CLOCK+REGION_BOT_LEN_CLOCKS)
1915
1916/* gap between BOT/EOT and first/last data block */
1917#define REGION_BOT_GAP_START_CLOCK      REGION_BOT_END_CLOCK
1918#define REGION_BOT_GAP_LEN_CLOCKS      TAPE_MSEC_TO_CLOCKS(300)   /* 300ms */
1919#define REGION_BOT_GAP_END_CLOCK      (REGION_BOT_GAP_START_CLOCK+REGION_BOT_GAP_LEN_CLOCKS)
1920
1921
1922/*-------------------------------------------------
1923    get_safe_token - makes sure that the passed
1924    in device is, in fact, an IDE controller
1925-------------------------------------------------*/
1926
1927INLINE tape_state *get_safe_token(device_t *device)
1928{
1929   assert(device != NULL);
1930   assert(device->type() == DECOCASS_TAPE);
1931
1932   return (tape_state *)downcast<decocass_tape_device *>(device)->token();
1933}
1934
1935
1936/*-------------------------------------------------
1937    tape_crc16_byte - accumulate 8 bits worth of
1938    CRC data
1939-------------------------------------------------*/
1940
1941static UINT16 tape_crc16_byte(UINT16 crc, UINT8 data)
1942{
1943   int bit;
1944
1945   for (bit = 0; bit < 8; bit++)
1946   {
1947      crc = (crc >> 1) | (crc << 15);
1948      crc ^= (data << 7) & 0x80;
1949      if (crc & 0x80)
1950         crc ^= 0x0120;
1951      data >>= 1;
1952   }
1953   return crc;
1954}
1955
1956
1957/*-------------------------------------------------
1958    tape_describe_state - create a string that
1959    describes the state of the tape
1960-------------------------------------------------*/
1961
1962static const char *tape_describe_state(tape_state *tape)
1963{
1964   static char buffer[40];
1965   char temprname[40];
1966   const char *rname = temprname;
1967
1968   if (tape->region == REGION_LEADER)
1969      rname = "LEAD";
1970   else if (tape->region == REGION_LEADER_GAP)
1971      rname = "LGAP";
1972   else if (tape->region == REGION_BOT)
1973      rname = "BOT ";
1974   else if (tape->region == REGION_BOT_GAP)
1975      rname = "BGAP";
1976   else if (tape->region == REGION_TRAILER)
1977      rname = "TRLR";
1978   else if (tape->region == REGION_TRAILER_GAP)
1979      rname = "TGAP";
1980   else if (tape->region == REGION_EOT)
1981      rname = "EOT ";
1982   else if (tape->region == REGION_EOT_GAP)
1983      rname = "EGAP";
1984   else
1985   {
1986      char tempbname[40];
1987      const char *bname = tempbname;
1988      int clk;
1989
1990      if (tape->bytenum <= BYTE_PRE_GAP_33)
1991         sprintf(tempbname, "PR%02d", tape->bytenum - BYTE_PRE_GAP_0);
1992      else if (tape->bytenum == BYTE_LEADIN)
1993         bname = "LDIN";
1994      else if (tape->bytenum == BYTE_HEADER)
1995         bname = "HEAD";
1996      else if (tape->bytenum <= BYTE_DATA_255)
1997         sprintf(tempbname, "BY%02X", tape->bytenum - BYTE_DATA_0);
1998      else if (tape->bytenum == BYTE_CRC16_MSB)
1999         bname = "CRCM";
2000      else if (tape->bytenum == BYTE_CRC16_LSB)
2001         bname = "CRCL";
2002      else if (tape->bytenum == BYTE_TRAILER)
2003         bname = "TRLR";
2004      else if (tape->bytenum == BYTE_LEADOUT)
2005         bname = "LOUT";
2006      else if (tape->bytenum == BYTE_LONGCLOCK)
2007         bname = "LONG";
2008      else
2009         sprintf(tempbname, "PO%02d", tape->bytenum - BYTE_POSTGAP_0);
2010
2011      /* in the main data area, the clock alternates at the clock rate */
2012      if (tape->bytenum >= BYTE_LEADIN && tape->bytenum <= BYTE_LEADOUT)
2013         clk = ((UINT32)(tape->clockpos - REGION_BOT_GAP_END_CLOCK) & 1) ? 0 : 1;
2014      else if (tape->bytenum == BYTE_LONGCLOCK)
2015         clk = 1;
2016      else
2017         clk = 0;
2018
2019      sprintf(temprname, "BL%02X.%4s.%d.%d", tape->region - REGION_DATA_BLOCK_0, bname, tape->bitnum, clk);
2020   }
2021
2022   sprintf(buffer, "{%9d=%s}", tape->clockpos, rname);
2023   return buffer;
2024}
2025
2026
2027/*-------------------------------------------------
2028    tape_clock_callback - called once per clock
2029    to increment/decrement the tape location
2030-------------------------------------------------*/
2031
2032static TIMER_CALLBACK( tape_clock_callback )
2033{
2034   device_t *device = (device_t *)ptr;
2035   tape_state *tape = get_safe_token(device);
2036
2037   /* advance by one clock in the desired direction */
2038   if (tape->speed < 0 && tape->clockpos > 0)
2039      tape->clockpos--;
2040   else if (tape->speed > 0 && tape->clockpos < tape->numclocks)
2041      tape->clockpos++;
2042
2043   /* look for states before the start of data */
2044   if (tape->clockpos < REGION_LEADER_END_CLOCK)
2045      tape->region = REGION_LEADER;
2046   else if (tape->clockpos < REGION_LEADER_GAP_END_CLOCK)
2047      tape->region = REGION_LEADER_GAP;
2048   else if (tape->clockpos < REGION_BOT_END_CLOCK)
2049      tape->region = REGION_BOT;
2050   else if (tape->clockpos < REGION_BOT_GAP_END_CLOCK)
2051      tape->region = REGION_BOT_GAP;
2052
2053   /* look for states after the end of data */
2054   else if (tape->clockpos >= tape->numclocks - REGION_LEADER_END_CLOCK)
2055      tape->region = REGION_TRAILER;
2056   else if (tape->clockpos >= tape->numclocks - REGION_LEADER_GAP_END_CLOCK)
2057      tape->region = REGION_TRAILER_GAP;
2058   else if (tape->clockpos >= tape->numclocks - REGION_BOT_END_CLOCK)
2059      tape->region = REGION_EOT;
2060   else if (tape->clockpos >= tape->numclocks - REGION_BOT_GAP_END_CLOCK)
2061      tape->region = REGION_EOT_GAP;
2062
2063   /* everything else is data */
2064   else
2065   {
2066      UINT32 dataclock = tape->clockpos - REGION_BOT_GAP_END_CLOCK;
2067
2068      /* compute the block number */
2069      tape->region = (tape_region)(REGION_DATA_BLOCK_0 + dataclock / (TAPE_CLOCKS_PER_BYTE * BYTE_BLOCK_TOTAL));
2070      dataclock -= (tape->region - REGION_DATA_BLOCK_0) * TAPE_CLOCKS_PER_BYTE * BYTE_BLOCK_TOTAL;
2071
2072      /* compute the byte within the block */
2073      tape->bytenum = (tape_byte)(dataclock / TAPE_CLOCKS_PER_BYTE);
2074      dataclock -= tape->bytenum * TAPE_CLOCKS_PER_BYTE;
2075
2076      /* compute the bit within the byte */
2077      tape->bitnum = dataclock / TAPE_CLOCKS_PER_BIT;
2078   }
2079
2080   /* log */
2081   if (LOG_CASSETTE_STATE)
2082      tape_describe_state(tape);
2083}
2084
2085
2086/*-------------------------------------------------
2087    tape_get_status_bits - return the 3 status
2088    bits from the tape
2089-------------------------------------------------*/
2090
2091static UINT8 tape_get_status_bits(device_t *device)
2092{
2093   tape_state *tape = get_safe_token(device);
2094   UINT8 tape_bits = 0;
2095
2096   /* bit 0x20 is the BOT/EOT signal, which is also set in the leader/trailer area */
2097   if (tape->region == REGION_LEADER || tape->region == REGION_BOT || tape->region == REGION_EOT || tape->region == REGION_TRAILER)
2098      tape_bits |= 0x20;
2099
2100   /* bit 0x40 is the clock, which is only valid in some areas of the data block */
2101   /* bit 0x80 is the data, which is only valid in some areas of the data block */
2102   if (tape->region >= REGION_DATA_BLOCK_0 && tape->region <= REGION_DATA_BLOCK_255)
2103   {
2104      int blocknum = tape->region - REGION_DATA_BLOCK_0;
2105      UINT8 byteval = 0x00;
2106
2107      /* in the main data area, the clock alternates at the clock rate */
2108      if (tape->bytenum >= BYTE_LEADIN && tape->bytenum <= BYTE_LEADOUT)
2109         tape_bits |= ((UINT32)(tape->clockpos - REGION_BOT_GAP_END_CLOCK) & 1) ? 0x00 : 0x40;
2110
2111      /* in the longclock area, the clock holds high */
2112      else if (tape->bytenum == BYTE_LONGCLOCK)
2113         tape_bits |= 0x40;
2114
2115      /* everywhere else, the clock holds to 0 */
2116      else
2117         ;
2118
2119      /* lead-in and lead-out bytes are 0xAA */
2120      if (tape->bytenum == BYTE_HEADER || tape->bytenum == BYTE_TRAILER)
2121         byteval = 0xaa;
2122
2123      /* data block bytes are data */
2124      else if (tape->bytenum >= BYTE_DATA_0 && tape->bytenum <= BYTE_DATA_255)
2125         byteval = static_cast<UINT8 *>(*device->region())[blocknum * 256 + (tape->bytenum - BYTE_DATA_0)];
2126
2127      /* CRC MSB */
2128      else if (tape->bytenum == BYTE_CRC16_MSB)
2129         byteval = tape->crc16[blocknum] >> 8;
2130
2131      /* CRC LSB */
2132      else if (tape->bytenum == BYTE_CRC16_LSB)
2133         byteval = tape->crc16[blocknum];
2134
2135      /* select the appropriate bit from the byte and move to the upper bit */
2136      if ((byteval >> tape->bitnum) & 1)
2137         tape_bits |= 0x80;
2138   }
2139   return tape_bits;
2140}
2141
2142
2143/*-------------------------------------------------
2144    tape_is_present - return TRUE if the tape is
2145    present
2146-------------------------------------------------*/
2147
2148static UINT8 tape_is_present(device_t *device)
2149{
2150   return device->region() != NULL;
2151}
2152
2153
2154/*-------------------------------------------------
2155    tape_change_speed - alter the speed of tape
2156    playback
2157-------------------------------------------------*/
2158
2159static void tape_change_speed(device_t *device, INT8 newspeed)
2160{
2161   tape_state *tape = get_safe_token(device);
2162   attotime newperiod;
2163   INT8 absnewspeed;
2164
2165   /* do nothing if speed has not changed */
2166   if (tape->speed == newspeed)
2167      return;
2168
2169   /* compute how fast to run the tape timer */
2170   absnewspeed = (newspeed < 0) ? -newspeed : newspeed;
2171   if (newspeed == 0)
2172      newperiod = attotime::never;
2173   else
2174      newperiod = attotime::from_hz(TAPE_CLOCKRATE * absnewspeed);
2175
2176   /* set the new speed */
2177   tape->timer->adjust(newperiod, 0, newperiod);
2178   tape->speed = newspeed;
2179}
2180
2181
2182/*-------------------------------------------------
2183    device start callback
2184-------------------------------------------------*/
2185
2186static DEVICE_START( decocass_tape )
2187{
2188   tape_state *tape = get_safe_token(device);
2189   int curblock, offs, numblocks;
2190
2191   /* validate some basic stuff */
2192   assert(device != NULL);
2193   assert(device->static_config() == NULL);
2194
2195   /* fetch the data pointer */
2196   tape->timer = device->machine().scheduler().timer_alloc(FUNC(tape_clock_callback), (void *)device);
2197   if (device->region() == NULL)
2198      return;
2199   UINT8 *regionbase = *device->region();
2200
2201   /* scan for the first non-empty block in the image */
2202   for (offs = device->region()->bytes() - 1; offs >= 0; offs--)
2203      if (regionbase[offs] != 0)
2204         break;
2205   numblocks = ((offs | 0xff) + 1) / 256;
2206   assert(numblocks < ARRAY_LENGTH(tape->crc16));
2207
2208   /* compute the total length */
2209   tape->numclocks = REGION_BOT_GAP_END_CLOCK + numblocks * BYTE_BLOCK_TOTAL * 16 + REGION_BOT_GAP_END_CLOCK;
2210
2211   /* compute CRCs for each block */
2212   for (curblock = 0; curblock < numblocks; curblock++)
2213   {
2214      UINT16 crc = 0;
2215      int testval;
2216
2217      /* first CRC the 256 bytes of data */
2218      for (offs = 256 * curblock; offs < 256 * curblock + 256; offs++)
2219         crc = tape_crc16_byte(crc, regionbase[offs]);
2220
2221      /* then find a pair of bytes that will bring the CRC to 0 (any better way than brute force?) */
2222      for (testval = 0; testval < 0x10000; testval++)
2223         if (tape_crc16_byte(tape_crc16_byte(crc, testval >> 8), testval) == 0)
2224            break;
2225      tape->crc16[curblock] = testval;
2226   }
2227
2228   /* register states */
2229   device->save_item(NAME(tape->speed));
2230   device->save_item(NAME(tape->bitnum));
2231   device->save_item(NAME(tape->clockpos));
2232}
2233
2234
2235/*-------------------------------------------------
2236    device reset callback
2237-------------------------------------------------*/
2238
2239static DEVICE_RESET( decocass_tape )
2240{
2241   /* turn the tape off */
2242   tape_change_speed(device, 0);
2243}
2244
2245
2246const device_type DECOCASS_TAPE = &device_creator<decocass_tape_device>;
2247
2248decocass_tape_device::decocass_tape_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
2249   : device_t(mconfig, DECOCASS_TAPE, "DECO Cassette Tape", tag, owner, clock)
2250{
2251   m_token = global_alloc_clear(tape_state);
2252}
2253
2254//-------------------------------------------------
2255//  device_config_complete - perform any
2256//  operations now that the configuration is
2257//  complete
2258//-------------------------------------------------
2259
2260void decocass_tape_device::device_config_complete()
2261{
2262}
2263
2264//-------------------------------------------------
2265//  device_start - device-specific startup
2266//-------------------------------------------------
2267
2268void decocass_tape_device::device_start()
2269{
2270   DEVICE_START_NAME( decocass_tape )(this);
2271}
2272
2273//-------------------------------------------------
2274//  device_reset - device-specific reset
2275//-------------------------------------------------
2276
2277void decocass_tape_device::device_reset()
2278{
2279   DEVICE_RESET_NAME( decocass_tape )(this);
2280}
2281
2282
trunk/src/mame/machine/decocass_tape.c
r0r18038
1/***********************************************************************
2
3    DECO Cassette System machine
4
5 ***********************************************************************/
6
7#include "emu.h"
8#include "cpu/m6502/m6502.h"
9#include "cpu/mcs48/mcs48.h"
10#include "machine/decocass_tape.h"
11
12#define LOG_CASSETTE_STATE      0
13
14/***************************************************************************
15    CASSETTE DEVICE INTERFACE
16***************************************************************************/
17
18/* regions within the virtual tape */
19enum tape_region
20{
21   REGION_LEADER,            /* in clear leader section */
22   REGION_LEADER_GAP,         /* in gap between leader and BOT */
23   REGION_BOT,               /* in BOT hole */
24   REGION_BOT_GAP,            /* in gap between BOT hole and data */
25   REGION_DATA_BLOCK_0,      /* in data block 0 */
26   REGION_DATA_BLOCK_255 = REGION_DATA_BLOCK_0 + 255,
27   REGION_EOT_GAP,            /* in gap between data and EOT hole */
28   REGION_EOT,               /* in EOT hole */
29   REGION_TRAILER_GAP,         /* in gap between trailer and EOT */
30   REGION_TRAILER            /* in clear trailer section */
31};
32
33
34/* bytes within a data block on a virtual tape */
35enum tape_byte
36{
37   BYTE_PRE_GAP_0,            /* 34 bytes of gap, clock held to 0, no data */
38   BYTE_PRE_GAP_33 = BYTE_PRE_GAP_0 + 33,
39   BYTE_LEADIN,            /* 1 leadin byte, clocked value 0x00 */
40   BYTE_HEADER,            /* 1 header byte, clocked value 0xAA */
41   BYTE_DATA_0,            /* 256 bytes of data, clocked */
42   BYTE_DATA_255 = BYTE_DATA_0 + 255,
43   BYTE_CRC16_MSB,            /* 2 bytes of CRC, clocked MSB first, then LSB */
44   BYTE_CRC16_LSB,
45   BYTE_TRAILER,            /* 1 trailer byte, clocked value 0xAA */
46   BYTE_LEADOUT,            /* 1 leadout byte, clocked value 0x00 */
47   BYTE_LONGCLOCK,            /* 1 longclock byte, clock held to 1, no data */
48   BYTE_POSTGAP_0,            /* 34 bytes of gap, no clock, no data */
49   BYTE_POSTGAP_33 = BYTE_POSTGAP_0 + 33,
50   BYTE_BLOCK_TOTAL         /* total number of bytes in block */
51};
52
53
54/* state of the tape */
55struct tape_state
56{
57   running_machine *   machine;         /* pointer back to the machine */
58   emu_timer *         timer;            /* timer for running the tape */
59   INT8            speed;            /* speed: <-1=fast rewind, -1=reverse, 0=stopped, 1=normal, >1=fast forward */
60   tape_region         region;            /* current region */
61   tape_byte         bytenum;         /* byte number within a datablock */
62   UINT8            bitnum;            /* bit number within a byte */
63   UINT32            clockpos;         /* the current clock position of the tape */
64   UINT32            numclocks;         /* total number of clocks on the entire tape */
65   UINT16            crc16[256];         /* CRC16 for each block */
66};
67
68
69/* number of tape clock pulses per second */
70#define TAPE_CLOCKRATE               4800
71#define TAPE_CLOCKS_PER_BIT            2
72#define TAPE_CLOCKS_PER_BYTE         (8 * TAPE_CLOCKS_PER_BIT)
73#define TAPE_MSEC_TO_CLOCKS(x)         ((x) * TAPE_CLOCKRATE / 1000)
74
75
76/* Note on a tapes leader-BOT-data-EOT-trailer format:
77 * A cassette has a transparent piece of tape on both ends,
78 * leader and trailer. And data tapes also have BOT and EOT
79 * holes, shortly before the the leader and trailer.
80 * The holes and clear tape are detected using a photo-resitor.
81 * When rewinding, the BOT/EOT signal will show a short
82 * pulse and if rewind continues a constant high signal later.
83 * The specs say the holes are "> 2ms" in length.
84 */
85
86/* duration of the clear LEADER (and trailer) of the tape */
87#define REGION_LEADER_START_CLOCK      0
88#define REGION_LEADER_LEN_CLOCKS      TAPE_MSEC_TO_CLOCKS(1000)   /* 1s */
89#define REGION_LEADER_END_CLOCK         (REGION_LEADER_START_CLOCK+REGION_LEADER_LEN_CLOCKS)
90
91/* duration of the GAP between leader and BOT/EOT */
92#define REGION_LEADER_GAP_START_CLOCK   REGION_LEADER_END_CLOCK
93#define REGION_LEADER_GAP_LEN_CLOCKS   TAPE_MSEC_TO_CLOCKS(1500)   /* 1.5s */
94#define REGION_LEADER_GAP_END_CLOCK      (REGION_LEADER_GAP_START_CLOCK+REGION_LEADER_GAP_LEN_CLOCKS)
95
96/* duration of BOT/EOT holes */
97#define REGION_BOT_START_CLOCK         REGION_LEADER_GAP_END_CLOCK
98#define REGION_BOT_LEN_CLOCKS         TAPE_MSEC_TO_CLOCKS(2.5)   /* 0.0025s */
99#define REGION_BOT_END_CLOCK         (REGION_BOT_START_CLOCK+REGION_BOT_LEN_CLOCKS)
100
101/* gap between BOT/EOT and first/last data block */
102#define REGION_BOT_GAP_START_CLOCK      REGION_BOT_END_CLOCK
103#define REGION_BOT_GAP_LEN_CLOCKS      TAPE_MSEC_TO_CLOCKS(300)   /* 300ms */
104#define REGION_BOT_GAP_END_CLOCK      (REGION_BOT_GAP_START_CLOCK+REGION_BOT_GAP_LEN_CLOCKS)
105
106
107/*-------------------------------------------------
108    get_safe_token - makes sure that the passed
109    in device is, in fact, an IDE controller
110-------------------------------------------------*/
111
112INLINE tape_state *get_safe_token(device_t *device)
113{
114   assert(device != NULL);
115   assert(device->type() == DECOCASS_TAPE);
116
117   return (tape_state *)downcast<decocass_tape_device *>(device)->token();
118}
119
120
121/*-------------------------------------------------
122    tape_crc16_byte - accumulate 8 bits worth of
123    CRC data
124-------------------------------------------------*/
125
126static UINT16 tape_crc16_byte(UINT16 crc, UINT8 data)
127{
128   int bit;
129
130   for (bit = 0; bit < 8; bit++)
131   {
132      crc = (crc >> 1) | (crc << 15);
133      crc ^= (data << 7) & 0x80;
134      if (crc & 0x80)
135         crc ^= 0x0120;
136      data >>= 1;
137   }
138   return crc;
139}
140
141
142/*-------------------------------------------------
143    tape_describe_state - create a string that
144    describes the state of the tape
145-------------------------------------------------*/
146
147static const char *tape_describe_state(tape_state *tape)
148{
149   static char buffer[40];
150   char temprname[40];
151   const char *rname = temprname;
152
153   if (tape->region == REGION_LEADER)
154      rname = "LEAD";
155   else if (tape->region == REGION_LEADER_GAP)
156      rname = "LGAP";
157   else if (tape->region == REGION_BOT)
158      rname = "BOT ";
159   else if (tape->region == REGION_BOT_GAP)
160      rname = "BGAP";
161   else if (tape->region == REGION_TRAILER)
162      rname = "TRLR";
163   else if (tape->region == REGION_TRAILER_GAP)
164      rname = "TGAP";
165   else if (tape->region == REGION_EOT)
166      rname = "EOT ";
167   else if (tape->region == REGION_EOT_GAP)
168      rname = "EGAP";
169   else
170   {
171      char tempbname[40];
172      const char *bname = tempbname;
173      int clk;
174
175      if (tape->bytenum <= BYTE_PRE_GAP_33)
176         sprintf(tempbname, "PR%02d", tape->bytenum - BYTE_PRE_GAP_0);
177      else if (tape->bytenum == BYTE_LEADIN)
178         bname = "LDIN";
179      else if (tape->bytenum == BYTE_HEADER)
180         bname = "HEAD";
181      else if (tape->bytenum <= BYTE_DATA_255)
182         sprintf(tempbname, "BY%02X", tape->bytenum - BYTE_DATA_0);
183      else if (tape->bytenum == BYTE_CRC16_MSB)
184         bname = "CRCM";
185      else if (tape->bytenum == BYTE_CRC16_LSB)
186         bname = "CRCL";
187      else if (tape->bytenum == BYTE_TRAILER)
188         bname = "TRLR";
189      else if (tape->bytenum == BYTE_LEADOUT)
190         bname = "LOUT";
191      else if (tape->bytenum == BYTE_LONGCLOCK)
192         bname = "LONG";
193      else
194         sprintf(tempbname, "PO%02d", tape->bytenum - BYTE_POSTGAP_0);
195
196      /* in the main data area, the clock alternates at the clock rate */
197      if (tape->bytenum >= BYTE_LEADIN && tape->bytenum <= BYTE_LEADOUT)
198         clk = ((UINT32)(tape->clockpos - REGION_BOT_GAP_END_CLOCK) & 1) ? 0 : 1;
199      else if (tape->bytenum == BYTE_LONGCLOCK)
200         clk = 1;
201      else
202         clk = 0;
203
204      sprintf(temprname, "BL%02X.%4s.%d.%d", tape->region - REGION_DATA_BLOCK_0, bname, tape->bitnum, clk);
205   }
206
207   sprintf(buffer, "{%9d=%s}", tape->clockpos, rname);
208   return buffer;
209}
210
211
212/*-------------------------------------------------
213    tape_clock_callback - called once per clock
214    to increment/decrement the tape location
215-------------------------------------------------*/
216
217static TIMER_CALLBACK( tape_clock_callback )
218{
219   device_t *device = (device_t *)ptr;
220   tape_state *tape = get_safe_token(device);
221
222   /* advance by one clock in the desired direction */
223   if (tape->speed < 0 && tape->clockpos > 0)
224      tape->clockpos--;
225   else if (tape->speed > 0 && tape->clockpos < tape->numclocks)
226      tape->clockpos++;
227
228   /* look for states before the start of data */
229   if (tape->clockpos < REGION_LEADER_END_CLOCK)
230      tape->region = REGION_LEADER;
231   else if (tape->clockpos < REGION_LEADER_GAP_END_CLOCK)
232      tape->region = REGION_LEADER_GAP;
233   else if (tape->clockpos < REGION_BOT_END_CLOCK)
234      tape->region = REGION_BOT;
235   else if (tape->clockpos < REGION_BOT_GAP_END_CLOCK)
236      tape->region = REGION_BOT_GAP;
237
238   /* look for states after the end of data */
239   else if (tape->clockpos >= tape->numclocks - REGION_LEADER_END_CLOCK)
240      tape->region = REGION_TRAILER;
241   else if (tape->clockpos >= tape->numclocks - REGION_LEADER_GAP_END_CLOCK)
242      tape->region = REGION_TRAILER_GAP;
243   else if (tape->clockpos >= tape->numclocks - REGION_BOT_END_CLOCK)
244      tape->region = REGION_EOT;
245   else if (tape->clockpos >= tape->numclocks - REGION_BOT_GAP_END_CLOCK)
246      tape->region = REGION_EOT_GAP;
247
248   /* everything else is data */
249   else
250   {
251      UINT32 dataclock = tape->clockpos - REGION_BOT_GAP_END_CLOCK;
252
253      /* compute the block number */
254      tape->region = (tape_region)(REGION_DATA_BLOCK_0 + dataclock / (TAPE_CLOCKS_PER_BYTE * BYTE_BLOCK_TOTAL));
255      dataclock -= (tape->region - REGION_DATA_BLOCK_0) * TAPE_CLOCKS_PER_BYTE * BYTE_BLOCK_TOTAL;
256
257      /* compute the byte within the block */
258      tape->bytenum = (tape_byte)(dataclock / TAPE_CLOCKS_PER_BYTE);
259      dataclock -= tape->bytenum * TAPE_CLOCKS_PER_BYTE;
260
261      /* compute the bit within the byte */
262      tape->bitnum = dataclock / TAPE_CLOCKS_PER_BIT;
263   }
264
265   /* log */
266   if (LOG_CASSETTE_STATE)
267      tape_describe_state(tape);
268}
269
270
271/*-------------------------------------------------
272    tape_get_status_bits - return the 3 status
273    bits from the tape
274-------------------------------------------------*/
275
276UINT8 tape_get_status_bits(device_t *device)
277{
278   tape_state *tape = get_safe_token(device);
279   UINT8 tape_bits = 0;
280
281   /* bit 0x20 is the BOT/EOT signal, which is also set in the leader/trailer area */
282   if (tape->region == REGION_LEADER || tape->region == REGION_BOT || tape->region == REGION_EOT || tape->region == REGION_TRAILER)
283      tape_bits |= 0x20;
284
285   /* bit 0x40 is the clock, which is only valid in some areas of the data block */
286   /* bit 0x80 is the data, which is only valid in some areas of the data block */
287   if (tape->region >= REGION_DATA_BLOCK_0 && tape->region <= REGION_DATA_BLOCK_255)
288   {
289      int blocknum = tape->region - REGION_DATA_BLOCK_0;
290      UINT8 byteval = 0x00;
291
292      /* in the main data area, the clock alternates at the clock rate */
293      if (tape->bytenum >= BYTE_LEADIN && tape->bytenum <= BYTE_LEADOUT)
294         tape_bits |= ((UINT32)(tape->clockpos - REGION_BOT_GAP_END_CLOCK) & 1) ? 0x00 : 0x40;
295
296      /* in the longclock area, the clock holds high */
297      else if (tape->bytenum == BYTE_LONGCLOCK)
298         tape_bits |= 0x40;
299
300      /* everywhere else, the clock holds to 0 */
301      else
302         ;
303
304      /* lead-in and lead-out bytes are 0xAA */
305      if (tape->bytenum == BYTE_HEADER || tape->bytenum == BYTE_TRAILER)
306         byteval = 0xaa;
307
308      /* data block bytes are data */
309      else if (tape->bytenum >= BYTE_DATA_0 && tape->bytenum <= BYTE_DATA_255)
310         byteval = static_cast<UINT8 *>(*device->region())[blocknum * 256 + (tape->bytenum - BYTE_DATA_0)];
311
312      /* CRC MSB */
313      else if (tape->bytenum == BYTE_CRC16_MSB)
314         byteval = tape->crc16[blocknum] >> 8;
315
316      /* CRC LSB */
317      else if (tape->bytenum == BYTE_CRC16_LSB)
318         byteval = tape->crc16[blocknum];
319
320      /* select the appropriate bit from the byte and move to the upper bit */
321      if ((byteval >> tape->bitnum) & 1)
322         tape_bits |= 0x80;
323   }
324   return tape_bits;
325}
326
327
328/*-------------------------------------------------
329    tape_is_present - return TRUE if the tape is
330    present
331-------------------------------------------------*/
332
333UINT8 tape_is_present(device_t *device)
334{
335   return device->region() != NULL;
336}
337
338
339/*-------------------------------------------------
340    tape_change_speed - alter the speed of tape
341    playback
342-------------------------------------------------*/
343
344void tape_change_speed(device_t *device, INT8 newspeed)
345{
346   tape_state *tape = get_safe_token(device);
347   attotime newperiod;
348   INT8 absnewspeed;
349
350   /* do nothing if speed has not changed */
351   if (tape->speed == newspeed)
352      return;
353
354   /* compute how fast to run the tape timer */
355   absnewspeed = (newspeed < 0) ? -newspeed : newspeed;
356   if (newspeed == 0)
357      newperiod = attotime::never;
358   else
359      newperiod = attotime::from_hz(TAPE_CLOCKRATE * absnewspeed);
360
361   /* set the new speed */
362   tape->timer->adjust(newperiod, 0, newperiod);
363   tape->speed = newspeed;
364}
365
366
367/*-------------------------------------------------
368    device start callback
369-------------------------------------------------*/
370
371static DEVICE_START( decocass_tape )
372{
373   tape_state *tape = get_safe_token(device);
374   int curblock, offs, numblocks;
375
376   /* validate some basic stuff */
377   assert(device != NULL);
378   assert(device->static_config() == NULL);
379
380   /* fetch the data pointer */
381   tape->timer = device->machine().scheduler().timer_alloc(FUNC(tape_clock_callback), (void *)device);
382   if (device->region() == NULL)
383      return;
384   UINT8 *regionbase = *device->region();
385
386   /* scan for the first non-empty block in the image */
387   for (offs = device->region()->bytes() - 1; offs >= 0; offs--)
388      if (regionbase[offs] != 0)
389         break;
390   numblocks = ((offs | 0xff) + 1) / 256;
391   assert(numblocks < ARRAY_LENGTH(tape->crc16));
392
393   /* compute the total length */
394   tape->numclocks = REGION_BOT_GAP_END_CLOCK + numblocks * BYTE_BLOCK_TOTAL * 16 + REGION_BOT_GAP_END_CLOCK;
395
396   /* compute CRCs for each block */
397   for (curblock = 0; curblock < numblocks; curblock++)
398   {
399      UINT16 crc = 0;
400      int testval;
401
402      /* first CRC the 256 bytes of data */
403      for (offs = 256 * curblock; offs < 256 * curblock + 256; offs++)
404         crc = tape_crc16_byte(crc, regionbase[offs]);
405
406      /* then find a pair of bytes that will bring the CRC to 0 (any better way than brute force?) */
407      for (testval = 0; testval < 0x10000; testval++)
408         if (tape_crc16_byte(tape_crc16_byte(crc, testval >> 8), testval) == 0)
409            break;
410      tape->crc16[curblock] = testval;
411   }
412
413   /* register states */
414   device->save_item(NAME(tape->speed));
415   device->save_item(NAME(tape->bitnum));
416   device->save_item(NAME(tape->clockpos));
417}
418
419
420/*-------------------------------------------------
421    device reset callback
422-------------------------------------------------*/
423
424static DEVICE_RESET( decocass_tape )
425{
426   /* turn the tape off */
427   tape_change_speed(device, 0);
428}
429
430
431const device_type DECOCASS_TAPE = &device_creator<decocass_tape_device>;
432
433decocass_tape_device::decocass_tape_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
434   : device_t(mconfig, DECOCASS_TAPE, "DECO Cassette Tape", tag, owner, clock)
435{
436   m_token = global_alloc_clear(tape_state);
437}
438
439//-------------------------------------------------
440//  device_config_complete - perform any
441//  operations now that the configuration is
442//  complete
443//-------------------------------------------------
444
445void decocass_tape_device::device_config_complete()
446{
447}
448
449//-------------------------------------------------
450//  device_start - device-specific startup
451//-------------------------------------------------
452
453void decocass_tape_device::device_start()
454{
455   DEVICE_START_NAME( decocass_tape )(this);
456}
457
458//-------------------------------------------------
459//  device_reset - device-specific reset
460//-------------------------------------------------
461
462void decocass_tape_device::device_reset()
463{
464   DEVICE_RESET_NAME( decocass_tape )(this);
465}
466
467
trunk/src/mame/machine/decocass_tape.h
r0r18038
1#ifndef __DECOCASS_TAPE_H__
2#define __DECOCASS_TAPE_H__
3
4class decocass_tape_device : public device_t
5{
6public:
7   decocass_tape_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
8   ~decocass_tape_device() { global_free(m_token); }
9
10   // access to legacy token
11   void *token() const { assert(m_token != NULL); return m_token; }
12protected:
13   // device-level overrides
14   virtual void device_config_complete();
15   virtual void device_start();
16   virtual void device_reset();
17private:
18   // internal state
19   void *m_token;
20};
21
22extern const device_type DECOCASS_TAPE;
23
24UINT8 tape_get_status_bits(device_t *device);
25UINT8 tape_is_present(device_t *device);
26void tape_change_speed(device_t *device, INT8 newspeed);
27
28
29#define MCFG_DECOCASS_TAPE_ADD(_tag) \
30   MCFG_DEVICE_ADD(_tag, DECOCASS_TAPE, 0)
31
32#endif
trunk/src/mame/video/decocass.c
r18037r18038
55 ***********************************************************************/
66
77#include "emu.h"
8#include "machine/decocass.h"
8#include "includes/decocass.h"
99
1010
1111static const UINT32 tile_offset[32*32] = {
r18037r18038
4646/********************************************
4747    state saving setup
4848 ********************************************/
49void decocass_video_state_save_init( running_machine &machine )
49void decocass_state::decocass_video_state_save_init()
5050{
51   decocass_state *state = machine.driver_data<decocass_state>();
52
53   state->save_item(NAME(state->m_watchdog_count));
54   state->save_item(NAME(state->m_watchdog_flip));
55   state->save_item(NAME(state->m_color_missiles));
56   state->save_item(NAME(state->m_color_center_bot));
57   state->save_item(NAME(state->m_mode_set));
58   state->save_item(NAME(state->m_back_h_shift));
59   state->save_item(NAME(state->m_back_vl_shift));
60   state->save_item(NAME(state->m_back_vr_shift));
61   state->save_item(NAME(state->m_part_h_shift));
62   state->save_item(NAME(state->m_part_v_shift));
63   state->save_item(NAME(state->m_center_h_shift_space));
64   state->save_item(NAME(state->m_center_v_shift));
51   save_item(NAME(m_watchdog_count));
52   save_item(NAME(m_watchdog_flip));
53   save_item(NAME(m_color_missiles));
54   save_item(NAME(m_color_center_bot));
55   save_item(NAME(m_mode_set));
56   save_item(NAME(m_back_h_shift));
57   save_item(NAME(m_back_vl_shift));
58   save_item(NAME(m_back_vr_shift));
59   save_item(NAME(m_part_h_shift));
60   save_item(NAME(m_part_v_shift));
61   save_item(NAME(m_center_h_shift_space));
62   save_item(NAME(m_center_v_shift));
6563}
6664
6765/********************************************
r18037r18038
115113    big object
116114 ********************************************/
117115
118static void draw_object( running_machine& machine, bitmap_ind16 &bitmap, const rectangle &cliprect )
116void decocass_state::draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect)
119117{
120   decocass_state *state = machine.driver_data<decocass_state>();
121118   int sx, sy, color;
122119
123   if (0 == (state->m_mode_set & 0x80))  /* part_h_enable off? */
120   if (0 == (m_mode_set & 0x80))  /* part_h_enable off? */
124121      return;
125122
126   color = (state->m_color_center_bot >> 4) & 15;
123   color = (m_color_center_bot >> 4) & 15;
127124
128   sy = 192 - (state->m_part_v_shift & 0x7f);
125   sy = 192 - (m_part_v_shift & 0x7f);
129126
130   if (state->m_part_h_shift & 0x80)
131      sx = (state->m_part_h_shift & 0x7f) + 1;
127   if (m_part_h_shift & 0x80)
128      sx = (m_part_h_shift & 0x7f) + 1;
132129   else
133      sx = 91 - (state->m_part_h_shift & 0x7f);
130      sx = 91 - (m_part_h_shift & 0x7f);
134131
135   drawgfx_transpen(bitmap, cliprect, machine.gfx[3], 0, color, 0, 0, sx + 64, sy, 0);
136   drawgfx_transpen(bitmap, cliprect, machine.gfx[3], 1, color, 0, 0, sx, sy, 0);
137   drawgfx_transpen(bitmap, cliprect, machine.gfx[3], 0, color, 0, 1, sx + 64, sy - 64, 0);
138   drawgfx_transpen(bitmap, cliprect, machine.gfx[3], 1, color, 0, 1, sx, sy - 64, 0);
132   drawgfx_transpen(bitmap, cliprect, machine().gfx[3], 0, color, 0, 0, sx + 64, sy, 0);
133   drawgfx_transpen(bitmap, cliprect, machine().gfx[3], 1, color, 0, 0, sx, sy, 0);
134   drawgfx_transpen(bitmap, cliprect, machine().gfx[3], 0, color, 0, 1, sx + 64, sy - 64, 0);
135   drawgfx_transpen(bitmap, cliprect, machine().gfx[3], 1, color, 0, 1, sx, sy - 64, 0);
139136}
140137
141static void draw_center( running_machine& machine, bitmap_ind16 &bitmap, const rectangle &cliprect )
138void decocass_state::draw_center(bitmap_ind16 &bitmap, const rectangle &cliprect)
142139{
143   decocass_state *state = machine.driver_data<decocass_state>();
144140   int sx, sy, x, y, color;
145141
146142   color = 0;
147   if (state->m_color_center_bot & 0x10)
143   if (m_color_center_bot & 0x10)
148144      color |= 4;
149   if (state->m_color_center_bot & 0x20)
145   if (m_color_center_bot & 0x20)
150146      color |= 2;
151   if (state->m_color_center_bot & 0x40)
147   if (m_color_center_bot & 0x40)
152148      color |= 1;
153   if (state->m_color_center_bot & 0x80)
149   if (m_color_center_bot & 0x80)
154150      color = (color & 4) + ((color << 1) & 2) + ((color >> 1) & 1);
155151
156   sy = state->m_center_v_shift;
157   sx = (state->m_center_h_shift_space >> 2) & 0x3c;
152   sy = m_center_v_shift;
153   sx = (m_center_h_shift_space >> 2) & 0x3c;
158154
159155   for (y = 0; y < 4; y++)
160156      if ((sy + y) >= cliprect.min_y && (sy + y) <= cliprect.max_y)
161157      {
162         if (((sy + y) & state->m_color_center_bot & 3) == (sy & state->m_color_center_bot & 3))
158         if (((sy + y) & m_color_center_bot & 3) == (sy & m_color_center_bot & 3))
163159            for (x = 0; x < 256; x++)
164               if (0 != (x & 16) || 0 != (state->m_center_h_shift_space & 1))
160               if (0 != (x & 16) || 0 != (m_center_h_shift_space & 1))
165161                  bitmap.pix16(sy + y, (sx + x) & 255) = color;
166162      }
167163}
r18037r18038
170166    memory handlers
171167 ********************************************/
172168
173WRITE8_HANDLER( decocass_paletteram_w )
169WRITE8_MEMBER(decocass_state::decocass_paletteram_w )
174170{
175171   /*
176172     * RGB output is inverted and A4 is inverted too
177173     * (ME/ input on 1st paletteram, inverter -> ME/ on 2nd)
178174     */
179175   offset = (offset & 31) ^ 16;
180   colortable_palette_set_color(space.machine().colortable, offset, MAKE_RGB(pal3bit(~data >> 0), pal3bit(~data >> 3), pal2bit(~data >> 6)));
176   colortable_palette_set_color(machine().colortable, offset, MAKE_RGB(pal3bit(~data >> 0), pal3bit(~data >> 3), pal2bit(~data >> 6)));
181177}
182178
183WRITE8_HANDLER( decocass_charram_w )
179WRITE8_MEMBER(decocass_state::decocass_charram_w )
184180{
185   decocass_state *state = space.machine().driver_data<decocass_state>();
186   state->m_charram[offset] = data;
181   m_charram[offset] = data;
187182   /* dirty sprite */
188   space.machine().gfx[1]->mark_dirty((offset >> 5) & 255);
183   machine().gfx[1]->mark_dirty((offset >> 5) & 255);
189184   /* dirty char */
190   space.machine().gfx[0]->mark_dirty((offset >> 3) & 1023);
185   machine().gfx[0]->mark_dirty((offset >> 3) & 1023);
191186}
192187
193188
194WRITE8_HANDLER( decocass_fgvideoram_w )
189WRITE8_MEMBER(decocass_state::decocass_fgvideoram_w )
195190{
196   decocass_state *state = space.machine().driver_data<decocass_state>();
197   state->m_fgvideoram[offset] = data;
198   state->m_fg_tilemap->mark_tile_dirty(offset);
191   m_fgvideoram[offset] = data;
192   m_fg_tilemap->mark_tile_dirty(offset);
199193}
200194
201WRITE8_HANDLER( decocass_colorram_w )
195WRITE8_MEMBER(decocass_state::decocass_colorram_w )
202196{
203   decocass_state *state = space.machine().driver_data<decocass_state>();
204   state->m_colorram[offset] = data;
205   state->m_fg_tilemap->mark_tile_dirty(offset);
197   m_colorram[offset] = data;
198   m_fg_tilemap->mark_tile_dirty(offset);
206199}
207200
208static void mark_bg_tile_dirty( running_machine &machine, offs_t offset )
201void decocass_state::mark_bg_tile_dirty(offs_t offset )
209202{
210   decocass_state *state = machine.driver_data<decocass_state>();
211203   if (offset & 0x80)
212      state->m_bg_tilemap_r->mark_tile_dirty(offset);
204      m_bg_tilemap_r->mark_tile_dirty(offset);
213205   else
214      state->m_bg_tilemap_l->mark_tile_dirty(offset);
206      m_bg_tilemap_l->mark_tile_dirty(offset);
215207}
216208
217WRITE8_HANDLER( decocass_tileram_w )
209WRITE8_MEMBER(decocass_state::decocass_tileram_w )
218210{
219   decocass_state *state = space.machine().driver_data<decocass_state>();
220   state->m_tileram[offset] = data;
211   m_tileram[offset] = data;
221212   /* dirty tile (64 bytes per tile) */
222   space.machine().gfx[2]->mark_dirty((offset / 64) & 15);
213   machine().gfx[2]->mark_dirty((offset / 64) & 15);
223214   /* first 1KB of tile RAM is shared with tilemap RAM */
224   if (offset < state->m_bgvideoram_size)
225      mark_bg_tile_dirty(space.machine(), offset);
215   if (offset < m_bgvideoram_size)
216      mark_bg_tile_dirty(offset);
226217}
227218
228WRITE8_HANDLER( decocass_objectram_w )
219WRITE8_MEMBER(decocass_state::decocass_objectram_w )
229220{
230   decocass_state *state = space.machine().driver_data<decocass_state>();
231   state->m_objectram[offset] = data;
221   m_objectram[offset] = data;
232222   /* dirty the object */
233   space.machine().gfx[3]->mark_dirty(0);
234   space.machine().gfx[3]->mark_dirty(1);
223   machine().gfx[3]->mark_dirty(0);
224   machine().gfx[3]->mark_dirty(1);
235225}
236226
237WRITE8_HANDLER( decocass_bgvideoram_w )
227WRITE8_MEMBER(decocass_state::decocass_bgvideoram_w )
238228{
239   decocass_state *state = space.machine().driver_data<decocass_state>();
240   state->m_bgvideoram[offset] = data;
241   mark_bg_tile_dirty(space.machine(), offset);
229   m_bgvideoram[offset] = data;
230   mark_bg_tile_dirty(offset);
242231}
243232
244233/* The watchdog is a 4bit counter counting down every frame */
245WRITE8_HANDLER( decocass_watchdog_count_w )
234WRITE8_MEMBER(decocass_state::decocass_watchdog_count_w )
246235{
247   decocass_state *state = space.machine().driver_data<decocass_state>();
248236   LOG(1,("decocass_watchdog_count_w: $%02x\n", data));
249   state->m_watchdog_count = data & 0x0f;
237   m_watchdog_count = data & 0x0f;
250238}
251239
252WRITE8_HANDLER( decocass_watchdog_flip_w )
240WRITE8_MEMBER(decocass_state::decocass_watchdog_flip_w )
253241{
254   decocass_state *state = space.machine().driver_data<decocass_state>();
255242   LOG(1,("decocass_watchdog_flip_w: $%02x\n", data));
256   state->m_watchdog_flip = data;
243   m_watchdog_flip = data;
257244}
258245
259WRITE8_HANDLER( decocass_color_missiles_w )
246WRITE8_MEMBER(decocass_state::decocass_color_missiles_w )
260247{
261   decocass_state *state = space.machine().driver_data<decocass_state>();
262248   LOG(1,("decocass_color_missiles_w: $%02x\n", data));
263249   /* only bits D0-D2 and D4-D6 are connected to
264250     * the color RAM demux:
265251     * D0-D2 to the IC0 inputs
266252     * D4-D6 to the IC1 inputs
267253     */
268   state->m_color_missiles = data & 0x77;
254   m_color_missiles = data & 0x77;
269255}
270256
271257/*
r18037r18038
278264 * D6 - tunnel
279265 * D7 - part h enable
280266 */
281WRITE8_HANDLER( decocass_mode_set_w )
267WRITE8_MEMBER(decocass_state::decocass_mode_set_w )
282268{
283   decocass_state *state = space.machine().driver_data<decocass_state>();
284   if (data == state->m_mode_set)
269   if (data == m_mode_set)
285270      return;
286271   LOG(1,("decocass_mode_set_w: $%02x (%s%s%s%s%s%s%s%s)\n", data,
287272      (data & 0x01) ? "D0?" : "",
r18037r18038
293278      (data & 0x40) ? " tunnel" : "",
294279      (data & 0x80) ? " part_h_enable" : ""));
295280
296   state->m_mode_set = data;
281   m_mode_set = data;
297282}
298283
299WRITE8_HANDLER( decocass_color_center_bot_w )
284WRITE8_MEMBER(decocass_state::decocass_color_center_bot_w )
300285{
301   decocass_state *state = space.machine().driver_data<decocass_state>();
302   if (data == state->m_color_center_bot)
286   if (data == m_color_center_bot)
303287      return;
304288   LOG(1,("decocass_color_center_bot_w: $%02x (color:%d, center_bot:%d)\n", data, data & 3, data >> 4));
305289   /*
r18037r18038
313297     * D0   CLD3
314298     */
315299
316   if ((state->m_color_center_bot ^ data) & 0x80)
300   if ((m_color_center_bot ^ data) & 0x80)
317301   {
318      state->m_bg_tilemap_r->mark_all_dirty();
319      state->m_bg_tilemap_l->mark_all_dirty();
302      m_bg_tilemap_r->mark_all_dirty();
303      m_bg_tilemap_l->mark_all_dirty();
320304   }
321   if ((state->m_color_center_bot ^ data) & 0x01)
322      state->m_fg_tilemap->mark_all_dirty();
323   state->m_color_center_bot = data;
305   if ((m_color_center_bot ^ data) & 0x01)
306      m_fg_tilemap->mark_all_dirty();
307   m_color_center_bot = data;
324308}
325309
326WRITE8_HANDLER( decocass_back_h_shift_w )
310WRITE8_MEMBER(decocass_state::decocass_back_h_shift_w )
327311{
328   decocass_state *state = space.machine().driver_data<decocass_state>();
329   if (data == state->m_back_h_shift)
312   if (data == m_back_h_shift)
330313      return;
331314   LOG(1,("decocass_back_h_shift_w: $%02x\n", data));
332   state->m_back_h_shift = data;
315   m_back_h_shift = data;
333316}
334317
335WRITE8_HANDLER( decocass_back_vl_shift_w )
318WRITE8_MEMBER(decocass_state::decocass_back_vl_shift_w )
336319{
337   decocass_state *state = space.machine().driver_data<decocass_state>();
338   if (data == state->m_back_vl_shift)
320   if (data == m_back_vl_shift)
339321      return;
340322   LOG(1,("decocass_back_vl_shift_w: $%02x\n", data));
341   state->m_back_vl_shift = data;
323   m_back_vl_shift = data;
342324}
343325
344WRITE8_HANDLER( decocass_back_vr_shift_w )
326WRITE8_MEMBER(decocass_state::decocass_back_vr_shift_w )
345327{
346   decocass_state *state = space.machine().driver_data<decocass_state>();
347   if (data == state->m_back_vr_shift)
328   if (data == m_back_vr_shift)
348329      return;
349330   LOG(1,("decocass_back_vr_shift_w: $%02x\n", data));
350   state->m_back_vr_shift = data;
331   m_back_vr_shift = data;
351332}
352333
353WRITE8_HANDLER( decocass_part_h_shift_w )
334WRITE8_MEMBER(decocass_state::decocass_part_h_shift_w )
354335{
355   decocass_state *state = space.machine().driver_data<decocass_state>();
356   if (data == state->m_part_v_shift )
336   if (data == m_part_v_shift )
357337      return;
358338   LOG(1,("decocass_part_h_shift_w: $%02x\n", data));
359   state->m_part_h_shift = data;
339   m_part_h_shift = data;
360340}
361341
362WRITE8_HANDLER( decocass_part_v_shift_w )
342WRITE8_MEMBER(decocass_state::decocass_part_v_shift_w )
363343{
364   decocass_state *state = space.machine().driver_data<decocass_state>();
365   if (data == state->m_part_v_shift )
344   if (data == m_part_v_shift )
366345      return;
367346   LOG(1,("decocass_part_v_shift_w: $%02x\n", data));
368   state->m_part_v_shift = data;
347   m_part_v_shift = data;
369348}
370349
371WRITE8_HANDLER( decocass_center_h_shift_space_w )
350WRITE8_MEMBER(decocass_state::decocass_center_h_shift_space_w )
372351{
373   decocass_state *state = space.machine().driver_data<decocass_state>();
374   if (data == state->m_center_h_shift_space)
352   if (data == m_center_h_shift_space)
375353      return;
376354   LOG(1,("decocass_center_h_shift_space_w: $%02x\n", data));
377   state->m_center_h_shift_space = data;
355   m_center_h_shift_space = data;
378356}
379357
380WRITE8_HANDLER( decocass_center_v_shift_w )
358WRITE8_MEMBER(decocass_state::decocass_center_v_shift_w )
381359{
382   decocass_state *state = space.machine().driver_data<decocass_state>();
383360   LOG(1,("decocass_center_v_shift_w: $%02x\n", data));
384   state->m_center_v_shift = data;
361   m_center_v_shift = data;
385362}
386363
387364/********************************************
388365    memory handlers
389366 ********************************************/
390367
391static void draw_sprites(running_machine& machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int color,
368void decocass_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int color,
392369                  int sprite_y_adjust, int sprite_y_adjust_flip_screen,
393370                  UINT8 *sprite_ram, int interleave)
394371{
395   decocass_state *state = machine.driver_data<decocass_state>();
396372   int i,offs;
397373
398374   /* Draw the sprites */
r18037r18038
409385      flipx = sprite_ram[offs + 0] & 0x04;
410386      flipy = sprite_ram[offs + 0] & 0x02;
411387
412      if (state->flip_screen())
388      if (flip_screen())
413389      {
414390         sx = 240 - sx;
415391         sy = 240 - sy + sprite_y_adjust_flip_screen;
r18037r18038
420396
421397      sy -= sprite_y_adjust;
422398
423      drawgfx_transpen(bitmap,cliprect, machine.gfx[1],
399      drawgfx_transpen(bitmap,cliprect, machine().gfx[1],
424400            sprite_ram[offs + interleave],
425401            color,
426402            flipx,flipy,
427403            sx,sy, 0);
428404
429      sy += (state->flip_screen() ? -256 : 256);
405      sy += (flip_screen() ? -256 : 256);
430406
431407      // Wrap around
432      drawgfx_transpen(bitmap,cliprect, machine.gfx[1],
408      drawgfx_transpen(bitmap,cliprect, machine().gfx[1],
433409            sprite_ram[offs + interleave],
434410            color,
435411            flipx,flipy,
r18037r18038
438414}
439415
440416
441static void draw_missiles(running_machine &machine,bitmap_ind16 &bitmap, const rectangle &cliprect,
417void decocass_state::draw_missiles(bitmap_ind16 &bitmap, const rectangle &cliprect,
442418                  int missile_y_adjust, int missile_y_adjust_flip_screen,
443419                  UINT8 *missile_ram, int interleave)
444420{
445   decocass_state *state = machine.driver_data<decocass_state>();
446421   int i, offs, x;
447422
448423   /* Draw the missiles (16 of them) seemingly with alternating colors
r18037r18038
453428
454429      sy = 255 - missile_ram[offs + 0 * interleave];
455430      sx = 255 - missile_ram[offs + 2 * interleave];
456      if (state->flip_screen())
431      if (flip_screen())
457432      {
458433         sx = 240 - sx;
459434         sy = 240 - sy + missile_y_adjust_flip_screen;
r18037r18038
463438         for (x = 0; x < 4; x++)
464439         {
465440            if (sx >= cliprect.min_x && sx <= cliprect.max_x)
466               bitmap.pix16(sy, sx) = (state->m_color_missiles >> 4) & 7;
441               bitmap.pix16(sy, sx) = (m_color_missiles >> 4) & 7;
467442            sx++;
468443         }
469444
470445      sy = 255 - missile_ram[offs + 1 * interleave];
471446      sx = 255 - missile_ram[offs + 3 * interleave];
472      if (state->flip_screen())
447      if (flip_screen())
473448      {
474449         sx = 240 - sx;
475450         sy = 240 - sy + missile_y_adjust_flip_screen;
r18037r18038
479454         for (x = 0; x < 4; x++)
480455         {
481456            if (sx >= cliprect.min_x && sx <= cliprect.max_x)
482               bitmap.pix16(sy, sx) = state->m_color_missiles & 7;
457               bitmap.pix16(sy, sx) = m_color_missiles & 7;
483458            sx++;
484459         }
485460   }
r18037r18038
587562
588563   if (m_mode_set & 0x20)
589564   {
590      draw_object(machine(), bitmap, cliprect);
591      draw_center(machine(), bitmap, cliprect);
565      draw_object(bitmap, cliprect);
566      draw_center(bitmap, cliprect);
592567   }
593568   else
594569   {
595      draw_object(machine(), bitmap, cliprect);
596      draw_center(machine(), bitmap, cliprect);
570      draw_object(bitmap, cliprect);
571      draw_center(bitmap, cliprect);
597572      if (m_mode_set & 0x08)   /* bkg_ena on ? */
598573      {
599574         clip = m_bg_tilemap_l_clip;
r18037r18038
606581      }
607582   }
608583   m_fg_tilemap->draw(bitmap, cliprect, 0, 0);
609   draw_sprites(machine(), bitmap, cliprect, (m_color_center_bot >> 1) & 1, 0, 0, m_fgvideoram, 0x20);
610   draw_missiles(machine(), bitmap, cliprect, 1, 0, m_colorram, 0x20);
584   draw_sprites(bitmap, cliprect, (m_color_center_bot >> 1) & 1, 0, 0, m_fgvideoram, 0x20);
585   draw_missiles(bitmap, cliprect, 1, 0, m_colorram, 0x20);
611586   return 0;
612587}
trunk/src/mame/mame.mak
r18037r18038
626626   $(DRIVERS)/deco156.o $(MACHINE)/deco156.o \
627627   $(DRIVERS)/deco32.o $(VIDEO)/deco32.o $(VIDEO)/dvi.o \
628628    $(AUDIO)/decobsmt.o \
629   $(DRIVERS)/decocass.o $(MACHINE)/decocass.o $(VIDEO)/decocass.o \
629   $(DRIVERS)/decocass.o $(MACHINE)/decocass.o $(MACHINE)/decocass_tape.o $(VIDEO)/decocass.o \
630630   $(DRIVERS)/deshoros.o \
631631   $(DRIVERS)/dietgo.o $(VIDEO)/dietgo.o \
632632   $(DRIVERS)/exprraid.o $(VIDEO)/exprraid.o \
trunk/src/mame/includes/decocass.h
r0r18038
1#ifdef MAME_DEBUG
2#define LOGLEVEL  5
3#else
4#define LOGLEVEL  0
5#endif
6#define LOG(n,x)  do { if (LOGLEVEL >= n) logerror x; } while (0)
7
8#include "machine/decocass_tape.h"
9
10class decocass_state : public driver_device
11{
12public:
13   decocass_state(const machine_config &mconfig, device_type type, const char *tag)
14      : driver_device(mconfig, type, tag),
15        m_maincpu(*this, "maincpu"),
16        m_audiocpu(*this, "audiocpu"),
17        m_mcu(*this, "mcu"),
18         m_cassette(*this, "cassette"),
19        m_rambase(*this, "rambase"),
20        m_charram(*this, "charram"),
21        m_fgvideoram(*this, "fgvideoram"),
22        m_colorram(*this, "colorram"),
23        m_tileram(*this, "tileram"),
24        m_objectram(*this, "objectram"),
25        m_paletteram(*this, "paletteram") { }
26
27   /* devices */
28   required_device<cpu_device> m_maincpu;
29   required_device<cpu_device> m_audiocpu;
30   required_device<cpu_device> m_mcu;
31   required_device<decocass_tape_device> m_cassette;
32
33   /* memory pointers */
34   required_shared_ptr<UINT8> m_rambase;
35   required_shared_ptr<UINT8> m_charram;
36   required_shared_ptr<UINT8> m_fgvideoram;
37   required_shared_ptr<UINT8> m_colorram;
38   UINT8 *   m_bgvideoram;   /* shares bits D0-3 with tileram! */
39   required_shared_ptr<UINT8> m_tileram;
40   required_shared_ptr<UINT8> m_objectram;
41   required_shared_ptr<UINT8> m_paletteram;
42   size_t    m_bgvideoram_size;
43
44   /* video-related */
45   tilemap_t   *m_fg_tilemap;
46   tilemap_t   *m_bg_tilemap_l;
47   tilemap_t   *m_bg_tilemap_r;
48   INT32     m_watchdog_count;
49   INT32     m_watchdog_flip;
50   INT32     m_color_missiles;
51   INT32     m_color_center_bot;
52   INT32     m_mode_set;
53   INT32     m_back_h_shift;
54   INT32     m_back_vl_shift;
55   INT32     m_back_vr_shift;
56   INT32     m_part_h_shift;
57   INT32     m_part_v_shift;
58   INT32     m_center_h_shift_space;
59   INT32     m_center_v_shift;
60   rectangle m_bg_tilemap_l_clip;
61   rectangle m_bg_tilemap_r_clip;
62
63   /* sound-related */
64   UINT8     m_sound_ack;   /* sound latches, ACK status bits and NMI timer */
65   UINT8     m_audio_nmi_enabled;
66   UINT8     m_audio_nmi_state;
67
68   /* misc */
69   UINT8     *m_decrypted;
70   UINT8     *m_decrypted2;
71   INT32     m_firsttime;
72   UINT8     m_latch1;
73   UINT8     m_decocass_reset;
74   INT32     m_de0091_enable;   /* DE-0091xx daughter board enable */
75   UINT8     m_quadrature_decoder[4];   /* four inputs from the quadrature decoder (H1, V1, H2, V2) */
76   int       m_showmsg;      // for debugging purposes
77
78   /* i8041 */
79   UINT8     m_i8041_p1;
80   UINT8     m_i8041_p2;
81   int       m_i8041_p1_write_latch;
82   int       m_i8041_p1_read_latch;
83   int       m_i8041_p2_write_latch;
84   int       m_i8041_p2_read_latch;
85
86   /* dongles-related */
87   read8_delegate    m_dongle_r;
88   write8_delegate   m_dongle_w;
89
90   /* dongle type #1 */
91   UINT32    m_type1_inmap;
92   UINT32    m_type1_outmap;
93
94   /* dongle type #2: status of the latches */
95   INT32     m_type2_d2_latch;   /* latched 8041-STATUS D2 value */
96   INT32     m_type2_xx_latch;   /* latched value (D7-4 == 0xc0) ? 1 : 0 */
97   INT32     m_type2_promaddr;   /* latched PROM address A0-A7 */
98
99   /* dongle type #3: status and patches */
100   INT32     m_type3_ctrs;      /* 12 bit counter stage */
101   INT32     m_type3_d0_latch;   /* latched 8041-D0 value */
102   INT32     m_type3_pal_19;      /* latched 1 for PAL input pin-19 */
103   INT32     m_type3_swap;
104
105   /* dongle type #4: status */
106   INT32     m_type4_ctrs;      /* latched PROM address (E5x0 LSB, E5x1 MSB) */
107   INT32     m_type4_latch;      /* latched enable PROM (1100xxxx written to E5x1) */
108
109   /* dongle type #5: status */
110   INT32     m_type5_latch;      /* latched enable PROM (1100xxxx written to E5x1) */
111
112   /* DS Telejan */
113   UINT8     m_mux_data;
114
115   DECLARE_DRIVER_INIT(decocass);
116   DECLARE_DRIVER_INIT(decocrom);
117   DECLARE_DRIVER_INIT(cdsteljn);
118   TILEMAP_MAPPER_MEMBER(fgvideoram_scan_cols);
119   TILEMAP_MAPPER_MEMBER(bgvideoram_scan_cols);
120   TILE_GET_INFO_MEMBER(get_bg_l_tile_info);
121   TILE_GET_INFO_MEMBER(get_bg_r_tile_info);
122   TILE_GET_INFO_MEMBER(get_fg_tile_info);
123   virtual void machine_start();
124   virtual void machine_reset();
125   virtual void video_start();
126   virtual void palette_init();
127   DECLARE_MACHINE_RESET(ctsttape);
128   DECLARE_MACHINE_RESET(cprogolfj);
129   DECLARE_MACHINE_RESET(cdsteljn);
130   DECLARE_MACHINE_RESET(cfishing);
131   DECLARE_MACHINE_RESET(chwy);
132   DECLARE_MACHINE_RESET(cterrani);
133   DECLARE_MACHINE_RESET(castfant);
134   DECLARE_MACHINE_RESET(csuperas);
135   DECLARE_MACHINE_RESET(clocknch);
136   DECLARE_MACHINE_RESET(cprogolf);
137   DECLARE_MACHINE_RESET(cluckypo);
138   DECLARE_MACHINE_RESET(ctisland);
139   DECLARE_MACHINE_RESET(cexplore);
140   DECLARE_MACHINE_RESET(cdiscon1);
141   DECLARE_MACHINE_RESET(ctornado);
142   DECLARE_MACHINE_RESET(cmissnx);
143   DECLARE_MACHINE_RESET(cptennis);
144   DECLARE_MACHINE_RESET(cbtime);
145   DECLARE_MACHINE_RESET(cburnrub);
146   DECLARE_MACHINE_RESET(cgraplop);
147   DECLARE_MACHINE_RESET(cgraplop2);
148   DECLARE_MACHINE_RESET(clapapa);
149   DECLARE_MACHINE_RESET(cskater);
150   DECLARE_MACHINE_RESET(cprobowl);
151   DECLARE_MACHINE_RESET(cnightst);
152   DECLARE_MACHINE_RESET(cpsoccer);
153   DECLARE_MACHINE_RESET(csdtenis);
154   DECLARE_MACHINE_RESET(czeroize);
155   DECLARE_MACHINE_RESET(cppicf);
156   DECLARE_MACHINE_RESET(cfghtice);
157   DECLARE_MACHINE_RESET(type4);
158   DECLARE_MACHINE_RESET(cbdash);
159   DECLARE_MACHINE_RESET(cflyball);
160   UINT32 screen_update_decocass(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
161   DECLARE_WRITE8_MEMBER(decocass_coin_counter_w);
162   DECLARE_WRITE8_MEMBER(decocass_sound_command_w);
163   DECLARE_READ8_MEMBER(decocass_sound_data_r);
164   DECLARE_READ8_MEMBER(decocass_sound_ack_r);
165   DECLARE_WRITE8_MEMBER(decocass_sound_data_w);
166   DECLARE_READ8_MEMBER(decocass_sound_command_r);
167   DECLARE_WRITE8_MEMBER(decocass_sound_nmi_enable_w);
168   DECLARE_READ8_MEMBER(decocass_sound_nmi_enable_r);
169   DECLARE_READ8_MEMBER(decocass_sound_data_ack_reset_r);
170   DECLARE_WRITE8_MEMBER(decocass_sound_data_ack_reset_w);
171   DECLARE_WRITE8_MEMBER(decocass_nmi_reset_w);
172   DECLARE_WRITE8_MEMBER(decocass_quadrature_decoder_reset_w);
173   DECLARE_WRITE8_MEMBER(decocass_adc_w);
174   DECLARE_READ8_MEMBER(decocass_input_r);
175
176   DECLARE_WRITE8_MEMBER(decocass_reset_w);
177
178   DECLARE_READ8_MEMBER(decocass_e5xx_r);
179   DECLARE_WRITE8_MEMBER(decocass_e5xx_w);
180   DECLARE_WRITE8_MEMBER(decocass_de0091_w);
181   DECLARE_WRITE8_MEMBER(decocass_e900_w);
182
183
184   DECLARE_WRITE8_MEMBER(i8041_p1_w);
185   DECLARE_READ8_MEMBER(i8041_p1_r);
186   DECLARE_WRITE8_MEMBER(i8041_p2_w);
187   DECLARE_READ8_MEMBER(i8041_p2_r);
188
189   void decocass_machine_state_save_init();
190
191   DECLARE_WRITE8_MEMBER(decocass_paletteram_w);
192   DECLARE_WRITE8_MEMBER(decocass_charram_w);
193   DECLARE_WRITE8_MEMBER(decocass_fgvideoram_w);
194   DECLARE_WRITE8_MEMBER(decocass_colorram_w);
195   DECLARE_WRITE8_MEMBER(decocass_bgvideoram_w);
196   DECLARE_WRITE8_MEMBER(decocass_tileram_w);
197   DECLARE_WRITE8_MEMBER(decocass_objectram_w);
198
199   DECLARE_WRITE8_MEMBER(decocass_watchdog_count_w);
200   DECLARE_WRITE8_MEMBER(decocass_watchdog_flip_w);
201   DECLARE_WRITE8_MEMBER(decocass_color_missiles_w);
202   DECLARE_WRITE8_MEMBER(decocass_mode_set_w);
203   DECLARE_WRITE8_MEMBER(decocass_color_center_bot_w);
204   DECLARE_WRITE8_MEMBER(decocass_back_h_shift_w);
205   DECLARE_WRITE8_MEMBER(decocass_back_vl_shift_w);
206   DECLARE_WRITE8_MEMBER(decocass_back_vr_shift_w);
207   DECLARE_WRITE8_MEMBER(decocass_part_h_shift_w);
208   DECLARE_WRITE8_MEMBER(decocass_part_v_shift_w);
209   DECLARE_WRITE8_MEMBER(decocass_center_h_shift_space_w);
210   DECLARE_WRITE8_MEMBER(decocass_center_v_shift_w);
211
212   void decocass_video_state_save_init();
213   
214   DECLARE_WRITE8_MEMBER(ram_w);
215   DECLARE_WRITE8_MEMBER(charram_w);
216   DECLARE_WRITE8_MEMBER(fgvideoram_w);
217   DECLARE_WRITE8_MEMBER(fgcolorram_w);
218   DECLARE_WRITE8_MEMBER(tileram_w);
219   DECLARE_WRITE8_MEMBER(objectram_w);
220   DECLARE_WRITE8_MEMBER(mirrorvideoram_w);
221   DECLARE_WRITE8_MEMBER(mirrorcolorram_w);
222   DECLARE_READ8_MEMBER(mirrorvideoram_r);
223   DECLARE_READ8_MEMBER(mirrorcolorram_r);
224   DECLARE_READ8_MEMBER(cdsteljn_input_r);
225   DECLARE_WRITE8_MEMBER(cdsteljn_mux_w);
226private:
227   DECLARE_READ8_MEMBER(decocass_type1_latch_26_pass_3_inv_2_r);
228   DECLARE_READ8_MEMBER(decocass_type1_pass_136_r);
229   DECLARE_READ8_MEMBER(decocass_type1_latch_27_pass_3_inv_2_r);
230   DECLARE_READ8_MEMBER(decocass_type1_latch_26_pass_5_inv_2_r);
231   DECLARE_READ8_MEMBER(decocass_type1_latch_16_pass_3_inv_1_r);
232   DECLARE_READ8_MEMBER(decocass_type2_r);
233   DECLARE_WRITE8_MEMBER(decocass_type2_w);
234   DECLARE_READ8_MEMBER(decocass_type3_r);
235   DECLARE_WRITE8_MEMBER(decocass_type3_w);
236   DECLARE_READ8_MEMBER(decocass_type4_r);
237   DECLARE_WRITE8_MEMBER(decocass_type4_w);
238   DECLARE_READ8_MEMBER(decocass_type5_r);
239   DECLARE_WRITE8_MEMBER(decocass_type5_w);
240   DECLARE_READ8_MEMBER(decocass_nodong_r);
241   
242   void draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect);
243   void draw_center(bitmap_ind16 &bitmap, const rectangle &cliprect);
244   void mark_bg_tile_dirty(offs_t offset);
245   void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int color,
246               int sprite_y_adjust, int sprite_y_adjust_flip_screen,
247               UINT8 *sprite_ram, int interleave);
248               
249   void draw_missiles(bitmap_ind16 &bitmap, const rectangle &cliprect,
250               int missile_y_adjust, int missile_y_adjust_flip_screen,
251               UINT8 *missile_ram, int interleave);                     
252};
253
254TIMER_DEVICE_CALLBACK(decocass_audio_nmi_gen);
trunk/src/mame/drivers/decocass.c
r18037r18038
3434#include "emu.h"
3535#include "cpu/m6502/m6502.h"
3636#include "cpu/mcs48/mcs48.h"
37#include "machine/decocass.h"
37#include "includes/decocass.h"
38#include "machine/decocass_tape.h"
3839#include "sound/ay8910.h"
3940
4041#define MASTER_CLOCK   XTAL_12MHz
r18037r18038
5556   return (data & 0x9f) | ((data & 0x20) << 1) | ((data & 0x40) >> 1);
5657}
5758
58static WRITE8_HANDLER( ram_w )
59WRITE8_MEMBER(decocass_state::ram_w)
5960{
60   decocass_state *state = space.machine().driver_data<decocass_state>();
61   state->m_decrypted[0x0000 + offset] = swap_bits_5_6(data);
62   state->m_rambase[0x0000 + offset] = data;
61   m_decrypted[0x0000 + offset] = swap_bits_5_6(data);
62   m_rambase[0x0000 + offset] = data;
6363}
6464
65static WRITE8_HANDLER( charram_w )
65WRITE8_MEMBER(decocass_state::charram_w)
6666{
67   decocass_state *state = space.machine().driver_data<decocass_state>();
68   state->m_decrypted[0x6000 + offset] = swap_bits_5_6(data);
67   m_decrypted[0x6000 + offset] = swap_bits_5_6(data);
6968   decocass_charram_w(space, offset, data);
7069}
7170
72static WRITE8_HANDLER( fgvideoram_w )
71WRITE8_MEMBER(decocass_state::fgvideoram_w)
7372{
74   decocass_state *state = space.machine().driver_data<decocass_state>();
75   state->m_decrypted[0xc000 + offset] = swap_bits_5_6(data);
73   m_decrypted[0xc000 + offset] = swap_bits_5_6(data);
7674   decocass_fgvideoram_w(space, offset, data);
7775}
7876
79static WRITE8_HANDLER( fgcolorram_w )
77WRITE8_MEMBER(decocass_state::fgcolorram_w)
8078{
81   decocass_state *state = space.machine().driver_data<decocass_state>();
82   state->m_decrypted[0xc400 + offset] = swap_bits_5_6(data);
79   m_decrypted[0xc400 + offset] = swap_bits_5_6(data);
8380   decocass_colorram_w(space, offset, data);
8481}
8582
86static WRITE8_HANDLER( tileram_w )
83WRITE8_MEMBER(decocass_state::tileram_w)
8784{
88   decocass_state *state = space.machine().driver_data<decocass_state>();
89   state->m_decrypted[0xd000 + offset] = swap_bits_5_6(data);
85   m_decrypted[0xd000 + offset] = swap_bits_5_6(data);
9086   decocass_tileram_w(space, offset, data);
9187}
9288
93static WRITE8_HANDLER( objectram_w )
89WRITE8_MEMBER(decocass_state::objectram_w)
9490{
95   decocass_state *state = space.machine().driver_data<decocass_state>();
96   state->m_decrypted[0xd800 + offset] = swap_bits_5_6(data);
91   m_decrypted[0xd800 + offset] = swap_bits_5_6(data);
9792   decocass_objectram_w(space, offset, data);
9893}
9994
100static WRITE8_HANDLER( mirrorvideoram_w ) { offset = ((offset >> 5) & 0x1f) | ((offset & 0x1f) << 5); fgvideoram_w(space, offset, data, mem_mask); }
101static WRITE8_HANDLER( mirrorcolorram_w ) { offset = ((offset >> 5) & 0x1f) | ((offset & 0x1f) << 5); fgcolorram_w(space, offset, data, mem_mask); }
95WRITE8_MEMBER(decocass_state::mirrorvideoram_w) { offset = ((offset >> 5) & 0x1f) | ((offset & 0x1f) << 5); fgvideoram_w(space, offset, data, mem_mask); }
96WRITE8_MEMBER(decocass_state::mirrorcolorram_w) { offset = ((offset >> 5) & 0x1f) | ((offset & 0x1f) << 5); fgcolorram_w(space, offset, data, mem_mask); }
10297
103static READ8_HANDLER( mirrorvideoram_r )
98READ8_MEMBER(decocass_state::mirrorvideoram_r)
10499{
105   decocass_state *state = space.machine().driver_data<decocass_state>();
106100   offset = ((offset >> 5) & 0x1f) | ((offset & 0x1f) << 5);
107   return state->m_fgvideoram[offset];
101   return m_fgvideoram[offset];
108102}
109103
110static READ8_HANDLER( mirrorcolorram_r )
104READ8_MEMBER(decocass_state::mirrorcolorram_r)
111105{
112   decocass_state *state = space.machine().driver_data<decocass_state>();
113106   offset = ((offset >> 5) & 0x1f) | ((offset & 0x1f) << 5);
114   return state->m_colorram[offset];
107   return m_colorram[offset];
115108}
116109
117110
118111static ADDRESS_MAP_START( decocass_map, AS_PROGRAM, 8, decocass_state )
119   AM_RANGE(0x0000, 0x5fff) AM_RAM_WRITE_LEGACY(ram_w) AM_SHARE("rambase")
120   AM_RANGE(0x6000, 0xbfff) AM_RAM_WRITE_LEGACY(charram_w) AM_SHARE("charram") /* still RMS3 RAM */
121   AM_RANGE(0xc000, 0xc3ff) AM_RAM_WRITE_LEGACY(fgvideoram_w) AM_SHARE("fgvideoram")  /* DSP3 RAM */
122   AM_RANGE(0xc400, 0xc7ff) AM_RAM_WRITE_LEGACY(fgcolorram_w) AM_SHARE("colorram")
123   AM_RANGE(0xc800, 0xcbff) AM_READWRITE_LEGACY(mirrorvideoram_r, mirrorvideoram_w)
124   AM_RANGE(0xcc00, 0xcfff) AM_READWRITE_LEGACY(mirrorcolorram_r, mirrorcolorram_w)
125   AM_RANGE(0xd000, 0xd7ff) AM_RAM_WRITE_LEGACY(tileram_w) AM_SHARE("tileram")
126   AM_RANGE(0xd800, 0xdbff) AM_RAM_WRITE_LEGACY(objectram_w) AM_SHARE("objectram")
127   AM_RANGE(0xe000, 0xe0ff) AM_RAM_WRITE_LEGACY(decocass_paletteram_w) AM_SHARE("paletteram")
128   AM_RANGE(0xe300, 0xe300) AM_READ_PORT("DSW1") AM_WRITE_LEGACY(decocass_watchdog_count_w)
129   AM_RANGE(0xe301, 0xe301) AM_READ_PORT("DSW2") AM_WRITE_LEGACY(decocass_watchdog_flip_w)
130   AM_RANGE(0xe302, 0xe302) AM_WRITE_LEGACY(decocass_color_missiles_w)
131   AM_RANGE(0xe400, 0xe400) AM_WRITE_LEGACY(decocass_reset_w)
112   AM_RANGE(0x0000, 0x5fff) AM_RAM_WRITE(ram_w) AM_SHARE("rambase")
113   AM_RANGE(0x6000, 0xbfff) AM_RAM_WRITE(charram_w) AM_SHARE("charram") /* still RMS3 RAM */
114   AM_RANGE(0xc000, 0xc3ff) AM_RAM_WRITE(fgvideoram_w) AM_SHARE("fgvideoram")  /* DSP3 RAM */
115   AM_RANGE(0xc400, 0xc7ff) AM_RAM_WRITE(fgcolorram_w) AM_SHARE("colorram")
116   AM_RANGE(0xc800, 0xcbff) AM_READWRITE(mirrorvideoram_r, mirrorvideoram_w)
117   AM_RANGE(0xcc00, 0xcfff) AM_READWRITE(mirrorcolorram_r, mirrorcolorram_w)
118   AM_RANGE(0xd000, 0xd7ff) AM_RAM_WRITE(tileram_w) AM_SHARE("tileram")
119   AM_RANGE(0xd800, 0xdbff) AM_RAM_WRITE(objectram_w) AM_SHARE("objectram")
120   AM_RANGE(0xe000, 0xe0ff) AM_RAM_WRITE(decocass_paletteram_w) AM_SHARE("paletteram")
121   AM_RANGE(0xe300, 0xe300) AM_READ_PORT("DSW1") AM_WRITE(decocass_watchdog_count_w)
122   AM_RANGE(0xe301, 0xe301) AM_READ_PORT("DSW2") AM_WRITE(decocass_watchdog_flip_w)
123   AM_RANGE(0xe302, 0xe302) AM_WRITE(decocass_color_missiles_w)
124   AM_RANGE(0xe400, 0xe400) AM_WRITE(decocass_reset_w)
132125
133126/* BIO-3 board */
134   AM_RANGE(0xe402, 0xe402) AM_WRITE_LEGACY(decocass_mode_set_w)
135   AM_RANGE(0xe403, 0xe403) AM_WRITE_LEGACY(decocass_back_h_shift_w)
136   AM_RANGE(0xe404, 0xe404) AM_WRITE_LEGACY(decocass_back_vl_shift_w)
137   AM_RANGE(0xe405, 0xe405) AM_WRITE_LEGACY(decocass_back_vr_shift_w)
138   AM_RANGE(0xe406, 0xe406) AM_WRITE_LEGACY(decocass_part_h_shift_w)
139   AM_RANGE(0xe407, 0xe407) AM_WRITE_LEGACY(decocass_part_v_shift_w)
127   AM_RANGE(0xe402, 0xe402) AM_WRITE(decocass_mode_set_w)
128   AM_RANGE(0xe403, 0xe403) AM_WRITE(decocass_back_h_shift_w)
129   AM_RANGE(0xe404, 0xe404) AM_WRITE(decocass_back_vl_shift_w)
130   AM_RANGE(0xe405, 0xe405) AM_WRITE(decocass_back_vr_shift_w)
131   AM_RANGE(0xe406, 0xe406) AM_WRITE(decocass_part_h_shift_w)
132   AM_RANGE(0xe407, 0xe407) AM_WRITE(decocass_part_v_shift_w)
140133
141   AM_RANGE(0xe410, 0xe410) AM_WRITE_LEGACY(decocass_color_center_bot_w)
142   AM_RANGE(0xe411, 0xe411) AM_WRITE_LEGACY(decocass_center_h_shift_space_w)
143   AM_RANGE(0xe412, 0xe412) AM_WRITE_LEGACY(decocass_center_v_shift_w)
144   AM_RANGE(0xe413, 0xe413) AM_WRITE_LEGACY(decocass_coin_counter_w)
145   AM_RANGE(0xe414, 0xe414) AM_WRITE_LEGACY(decocass_sound_command_w)
146   AM_RANGE(0xe415, 0xe416) AM_WRITE_LEGACY(decocass_quadrature_decoder_reset_w)
147   AM_RANGE(0xe417, 0xe417) AM_WRITE_LEGACY(decocass_nmi_reset_w)
148   AM_RANGE(0xe420, 0xe42f) AM_WRITE_LEGACY(decocass_adc_w)
134   AM_RANGE(0xe410, 0xe410) AM_WRITE(decocass_color_center_bot_w)
135   AM_RANGE(0xe411, 0xe411) AM_WRITE(decocass_center_h_shift_space_w)
136   AM_RANGE(0xe412, 0xe412) AM_WRITE(decocass_center_v_shift_w)
137   AM_RANGE(0xe413, 0xe413) AM_WRITE(decocass_coin_counter_w)
138   AM_RANGE(0xe414, 0xe414) AM_WRITE(decocass_sound_command_w)
139   AM_RANGE(0xe415, 0xe416) AM_WRITE(decocass_quadrature_decoder_reset_w)
140   AM_RANGE(0xe417, 0xe417) AM_WRITE(decocass_nmi_reset_w)
141   AM_RANGE(0xe420, 0xe42f) AM_WRITE(decocass_adc_w)
149142
150   AM_RANGE(0xe500, 0xe5ff) AM_READWRITE_LEGACY(decocass_e5xx_r, decocass_e5xx_w)   /* read data from 8041/status */
143   AM_RANGE(0xe500, 0xe5ff) AM_READWRITE(decocass_e5xx_r, decocass_e5xx_w)   /* read data from 8041/status */
151144
152   AM_RANGE(0xe600, 0xe6ff) AM_READ_LEGACY(decocass_input_r)      /* inputs */
153   AM_RANGE(0xe700, 0xe700) AM_READ_LEGACY(decocass_sound_data_r)   /* read sound CPU data */
154   AM_RANGE(0xe701, 0xe701) AM_READ_LEGACY(decocass_sound_ack_r)   /* read sound CPU ack status */
145   AM_RANGE(0xe600, 0xe6ff) AM_READ(decocass_input_r)      /* inputs */
146   AM_RANGE(0xe700, 0xe700) AM_READ(decocass_sound_data_r)   /* read sound CPU data */
147   AM_RANGE(0xe701, 0xe701) AM_READ(decocass_sound_ack_r)   /* read sound CPU ack status */
155148
156149   AM_RANGE(0xf000, 0xffff) AM_ROM
157150ADDRESS_MAP_END
158151
159152static ADDRESS_MAP_START( decocass_sound_map, AS_PROGRAM, 8, decocass_state )
160153   AM_RANGE(0x0000, 0x0fff) AM_RAM
161   AM_RANGE(0x1000, 0x17ff) AM_READWRITE_LEGACY(decocass_sound_nmi_enable_r, decocass_sound_nmi_enable_w)
162   AM_RANGE(0x1800, 0x1fff) AM_READWRITE_LEGACY(decocass_sound_data_ack_reset_r, decocass_sound_data_ack_reset_w)
154   AM_RANGE(0x1000, 0x17ff) AM_READWRITE(decocass_sound_nmi_enable_r, decocass_sound_nmi_enable_w)
155   AM_RANGE(0x1800, 0x1fff) AM_READWRITE(decocass_sound_data_ack_reset_r, decocass_sound_data_ack_reset_w)
163156   AM_RANGE(0x2000, 0x2fff) AM_DEVWRITE_LEGACY("ay1", ay8910_data_w)
164157   AM_RANGE(0x4000, 0x4fff) AM_DEVWRITE_LEGACY("ay1", ay8910_address_w)
165158   AM_RANGE(0x6000, 0x6fff) AM_DEVWRITE_LEGACY("ay2", ay8910_data_w)
166159   AM_RANGE(0x8000, 0x8fff) AM_DEVWRITE_LEGACY("ay2", ay8910_address_w)
167   AM_RANGE(0xa000, 0xafff) AM_READ_LEGACY(decocass_sound_command_r)
168   AM_RANGE(0xc000, 0xcfff) AM_WRITE_LEGACY(decocass_sound_data_w)
160   AM_RANGE(0xa000, 0xafff) AM_READ(decocass_sound_command_r)
161   AM_RANGE(0xc000, 0xcfff) AM_WRITE(decocass_sound_data_w)
169162   AM_RANGE(0xf800, 0xffff) AM_ROM
170163ADDRESS_MAP_END
171164
172165
173166static ADDRESS_MAP_START( decocass_mcu_portmap, AS_IO, 8, decocass_state )
174   AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE_LEGACY(i8041_p1_r, i8041_p1_w)
175   AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE_LEGACY(i8041_p2_r, i8041_p2_w)
167   AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(i8041_p1_r, i8041_p1_w)
168   AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(i8041_p2_r, i8041_p2_w)
176169ADDRESS_MAP_END
177170
178171static INPUT_PORTS_START( decocass )
r18037r18038
16171610   save_pointer(NAME(m_decrypted), 0x10000);
16181611
16191612   /* Call the state save setup code in machine/decocass.c */
1620   decocass_machine_state_save_init(machine());
1613   decocass_machine_state_save_init();
16211614   /* and in video/decocass.c, too */
1622   decocass_video_state_save_init(machine());
1615   decocass_video_state_save_init();
16231616}
16241617
16251618DRIVER_INIT_MEMBER(decocass_state,decocrom)
r18037r18038
16391632
16401633   /* convert charram to a banked ROM */
16411634   machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_bank(0x6000, 0xafff, "bank1");
1642   machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0x6000, 0xafff, FUNC(decocass_de0091_w));
1635   machine().device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x6000, 0xafff, write8_delegate(FUNC(decocass_state::decocass_de0091_w),this));
16431636   membank("bank1")->configure_entry(0, m_charram);
16441637   membank("bank1")->configure_entry(1, memregion("user3")->base());
16451638   membank("bank1")->configure_decrypted_entry(0, &m_decrypted[0x6000]);
r18037r18038
16471640   membank("bank1")->set_entry(0);
16481641
16491642   /* install the bank selector */
1650   machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xe900, 0xe900, FUNC(decocass_e900_w));
1643   machine().device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0xe900, 0xe900, write8_delegate(FUNC(decocass_state::decocass_e900_w),this));
16511644
16521645   save_pointer(NAME(m_decrypted2), romlength);
16531646}
16541647
1655static READ8_HANDLER( cdsteljn_input_r )
1648READ8_MEMBER(decocass_state::cdsteljn_input_r )
16561649{
1657   decocass_state *state = space.machine().driver_data<decocass_state>();
16581650   UINT8 res;
16591651   static const char *const portnames[2][4] = {
16601652      {"P1_MP0", "P1_MP1", "P1_MP2", "P1_MP3"},
r18037r18038
16631655   if(offset & 6)
16641656      return decocass_input_r(space,offset);
16651657
1666   res = space.machine().root_device().ioport(portnames[offset & 1][state->m_mux_data])->read();
1658   res = machine().root_device().ioport(portnames[offset & 1][m_mux_data])->read();
16671659
16681660   return res;
16691661}
16701662
1671static WRITE8_HANDLER( cdsteljn_mux_w )
1663WRITE8_MEMBER(decocass_state::cdsteljn_mux_w )
16721664{
1673   decocass_state *state = space.machine().driver_data<decocass_state>();
1674
1675   state->m_mux_data = (data & 0xc) >> 2;
1665   m_mux_data = (data & 0xc) >> 2;
16761666   /* bit 0 and 1 are p1/p2 lamps */
16771667
16781668   if(data & ~0xf)
r18037r18038
16851675   DRIVER_INIT_CALL(decocass);
16861676
16871677   /* install custom mahjong panel */
1688   machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(0xe413, 0xe413, FUNC(cdsteljn_mux_w));
1689   machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(0xe600, 0xe6ff, FUNC(cdsteljn_input_r));
1678   machine().device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0xe413, 0xe413, write8_delegate(FUNC(decocass_state::cdsteljn_mux_w), this));
1679   machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0xe600, 0xe6ff, read8_delegate(FUNC(decocass_state::cdsteljn_input_r), this));
16901680}
16911681
16921682/* -- */ GAME( 1981, decocass,  0,        decocass, decocass, decocass_state, decocass, ROT270, "Data East Corporation", "DECO Cassette System", GAME_IS_BIOS_ROOT )

Previous 199869 Revisions Next


© 1997-2024 The MAME Team