~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to mess/src/mess/machine/z80ne.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***********************************************************************
2
 
 
3
 
    machine/z80ne.c
4
 
 
5
 
    Functions to emulate general aspects of the machine (RAM, ROM,
6
 
    interrupts, I/O ports)
7
 
 
8
 
***********************************************************************/
9
 
 
10
 
/* Core includes */
11
 
#include "emu.h"
12
 
#include "devintrf.h"
13
 
#include "includes/z80ne.h"
14
 
 
15
 
/* Components */
16
 
#include "machine/ay31015.h"
17
 
#include "machine/kr2376.h"
18
 
#include "video/m6847.h"
19
 
#include "machine/wd17xx.h"
20
 
 
21
 
/* Devices */
22
 
#include "imagedev/cassette.h"
23
 
#include "imagedev/flopdrv.h"
24
 
 
25
 
#define VERBOSE 0
26
 
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
27
 
 
28
 
 
29
 
 
30
 
 
31
 
 
32
 
/* timer to read cassette waveforms */
33
 
 
34
 
static cassette_image_device *cassette_device_image(running_machine &machine)
35
 
{
36
 
        z80ne_state *state = machine.driver_data<z80ne_state>();
37
 
        if (state->m_lx385_ctrl & 0x08)
38
 
                return machine.device<cassette_image_device>(CASSETTE2_TAG);
39
 
        else
40
 
                return machine.device<cassette_image_device>(CASSETTE_TAG);
41
 
}
42
 
 
43
 
static TIMER_CALLBACK(z80ne_cassette_tc)
44
 
{
45
 
        z80ne_state *state = machine.driver_data<z80ne_state>();
46
 
        UINT8 cass_ws = 0;
47
 
        state->m_cass_data.input.length++;
48
 
 
49
 
        cass_ws = ((cassette_device_image(machine))->input() > +0.02) ? 1 : 0;
50
 
 
51
 
        if ((cass_ws ^ state->m_cass_data.input.level) & cass_ws)
52
 
        {
53
 
                state->m_cass_data.input.level = cass_ws;
54
 
                state->m_cass_data.input.bit = ((state->m_cass_data.input.length < state->m_cass_data.wave_filter) || (state->m_cass_data.input.length > 0x20)) ? 1 : 0;
55
 
                state->m_cass_data.input.length = 0;
56
 
                ay31015_set_input_pin( state->m_ay31015, AY31015_SI, state->m_cass_data.input.bit );
57
 
        }
58
 
        state->m_cass_data.input.level = cass_ws;
59
 
 
60
 
        /* saving a tape - convert the serial stream from the uart */
61
 
 
62
 
        state->m_cass_data.output.length--;
63
 
 
64
 
        if (!(state->m_cass_data.output.length))
65
 
        {
66
 
                if (state->m_cass_data.output.level)
67
 
                        state->m_cass_data.output.level = 0;
68
 
                else
69
 
                {
70
 
                        state->m_cass_data.output.level=1;
71
 
                        cass_ws = ay31015_get_output_pin( state->m_ay31015, AY31015_SO );
72
 
                        state->m_cass_data.wave_length = cass_ws ? state->m_cass_data.wave_short : state->m_cass_data.wave_long;
73
 
                }
74
 
                cassette_device_image(machine)->output(state->m_cass_data.output.level ? -1.0 : +1.0);
75
 
                state->m_cass_data.output.length = state->m_cass_data.wave_length;
76
 
        }
77
 
}
78
 
 
79
 
 
80
 
DRIVER_INIT( z80ne )
81
 
{
82
 
        /* first two entries point to rom on reset */
83
 
        UINT8 *RAM = machine.region("z80ne")->base();
84
 
        memory_configure_bank(machine, "bank1", 0, 1, &RAM[0x00000], 0x0400); /* RAM   at 0x0000 */
85
 
        memory_configure_bank(machine, "bank1", 1, 1, &RAM[0x14000], 0x0400); /* ep382 at 0x0000 */
86
 
        memory_configure_bank(machine, "bank2", 0, 1, &RAM[0x14000], 0x0400); /* ep382 at 0x8000 */
87
 
}
88
 
 
89
 
DRIVER_INIT( z80net )
90
 
{
91
 
        DRIVER_INIT_CALL(z80ne);
92
 
}
93
 
 
94
 
DRIVER_INIT( z80netb )
95
 
{
96
 
}
97
 
 
98
 
DRIVER_INIT( z80netf )
99
 
{
100
 
        /* first two entries point to rom on reset */
101
 
        UINT8 *RAM = machine.region("z80ne")->base();
102
 
        memory_configure_bank(machine, "bank1", 0, 1, &RAM[0x00000], 0x0400); /* RAM   at 0x0000-0x03FF */
103
 
        memory_configure_bank(machine, "bank1", 1, 3, &RAM[0x14400], 0x0400); /* ep390, ep1390, ep2390 at 0x0000-0x03FF */
104
 
        memory_configure_bank(machine, "bank1", 4, 1, &RAM[0x14000], 0x0400); /* ep382 at 0x0000-0x03FF */
105
 
        memory_configure_bank(machine, "bank1", 5, 1, &RAM[0x10000], 0x0400); /* ep548 at 0x0000-0x03FF */
106
 
 
107
 
        memory_configure_bank(machine, "bank2", 0, 1, &RAM[0x00400], 0x3C00); /* RAM   at 0x0400 */
108
 
        memory_configure_bank(machine, "bank2", 1, 1, &RAM[0x10400], 0x3C00); /* ep548 at 0x0400-0x3FFF */
109
 
 
110
 
        memory_configure_bank(machine, "bank3", 0, 1, &RAM[0x08000], 0x0400); /* RAM   at 0x8000 */
111
 
        memory_configure_bank(machine, "bank3", 1, 1, &RAM[0x14000], 0x0400); /* ep382 at 0x8000 */
112
 
 
113
 
        memory_configure_bank(machine, "bank4", 0, 1, &RAM[0x0F000], 0x0400); /* RAM   at 0xF000 */
114
 
        memory_configure_bank(machine, "bank4", 1, 3, &RAM[0x14400], 0x0400); /* ep390, ep1390, ep2390 at 0xF000 */
115
 
 
116
 
}
117
 
 
118
 
static TIMER_CALLBACK( z80ne_kbd_scan )
119
 
{
120
 
        z80ne_state *state = machine.driver_data<z80ne_state>();
121
 
        /*
122
 
     * NE555 is connected to a 74LS93 binary counter
123
 
     * 74LS93 output:
124
 
     *   QA-QC: column index for LEDs and keyboard
125
 
     *   QD:    keyboard row select
126
 
     *
127
 
     * Port F0 input bit assignment:
128
 
     *   0  QA  bits 0..3 of row counter
129
 
     *   1  QB
130
 
     *   2  QC
131
 
     *   3  QD
132
 
     *   4  Control button pressed, active high
133
 
     *   5  Always low
134
 
     *   6  Always low
135
 
     *   7  Selected button pressed, active low
136
 
     *
137
 
     *
138
 
     */
139
 
 
140
 
        UINT16 key_bits;
141
 
        UINT8 ctrl; //, rst;
142
 
        UINT8 i;
143
 
 
144
 
        /* 4-bit counter */
145
 
        --state->m_lx383_scan_counter;
146
 
        state->m_lx383_scan_counter &= 0x0f;
147
 
 
148
 
        if ( --state->m_lx383_downsampler == 0 )
149
 
        {
150
 
                state->m_lx383_downsampler = LX383_DOWNSAMPLING;
151
 
                key_bits = (input_port_read(machine, "ROW1") << 8) | input_port_read(machine, "ROW0");
152
 
//      rst = input_port_read(machine, "RST");
153
 
                ctrl = input_port_read(machine, "CTRL");
154
 
 
155
 
                for ( i = 0; i<LX383_KEYS; i++)
156
 
                {
157
 
                        state->m_lx383_key[i] = ( i | (key_bits & 0x01 ? 0x80 : 0x00) | ~ctrl);
158
 
                        key_bits >>= 1;
159
 
                }
160
 
        }
161
 
}
162
 
 
163
 
DIRECT_UPDATE_HANDLER( z80ne_default )
164
 
{
165
 
        return address;
166
 
}
167
 
/*
168
 
 * Handle NMI delay for single step instruction
169
 
 */
170
 
DIRECT_UPDATE_HANDLER( z80ne_nmi_delay_count )
171
 
{
172
 
        z80ne_state *state = machine.driver_data<z80ne_state>();
173
 
        state->m_nmi_delay_counter--;
174
 
 
175
 
        if (!state->m_nmi_delay_counter)
176
 
        {
177
 
                machine.device("z80ne")->memory().space(AS_PROGRAM)->set_direct_update_handler(direct_update_delegate(FUNC(z80ne_default), &machine));
178
 
                cputag_set_input_line(machine, "z80ne", INPUT_LINE_NMI, PULSE_LINE);
179
 
        }
180
 
        return address;
181
 
}
182
 
 
183
 
/*
184
 
 * Handle delayed ROM/RAM banking at RESET
185
 
 * after the first reset_delay_counter bytes have been read from ROM, switch the RAM back in
186
 
 */
187
 
DIRECT_UPDATE_HANDLER( z80ne_reset_delay_count )
188
 
{
189
 
        z80ne_state *state = machine.driver_data<z80ne_state>();
190
 
        address_space *space = machine.device("z80ne")->memory().space(AS_PROGRAM);
191
 
        /*
192
 
     * TODO: when debugger is active, his memory access causes this callback
193
 
     *
194
 
     */
195
 
        if(!space->debugger_access())
196
 
                state->m_reset_delay_counter--;
197
 
 
198
 
        if (!state->m_reset_delay_counter)
199
 
        {
200
 
                /* remove this callback */
201
 
                machine.device("z80ne")->memory().space(AS_PROGRAM)->set_direct_update_handler(direct_update_delegate(FUNC(z80ne_default), &machine));
202
 
                /* and switch to RAM bank at address 0x0000 */
203
 
                memory_set_bank( machine, "bank1", 0 ); /* RAM at 0x0000 (bank 1) */
204
 
        }
205
 
        return address;
206
 
}
207
 
 
208
 
static void reset_lx388(running_machine &machine)
209
 
{
210
 
        z80ne_state *state = machine.driver_data<z80ne_state>();
211
 
        state->m_lx388_kr2376 = machine.device("lx388_kr2376");
212
 
        kr2376_set_input_pin( state->m_lx388_kr2376, KR2376_DSII, 0);
213
 
        kr2376_set_input_pin( state->m_lx388_kr2376, KR2376_PII, 0);
214
 
}
215
 
 
216
 
static void reset_lx382_banking(running_machine &machine)
217
 
{
218
 
        z80ne_state *state = machine.driver_data<z80ne_state>();
219
 
        address_space *space = machine.device("z80ne")->memory().space(AS_PROGRAM);
220
 
 
221
 
        /* switch to ROM bank at address 0x0000 */
222
 
    memory_set_bank(machine, "bank1", 1);
223
 
    memory_set_bank(machine, "bank2", 0);  /* ep382 at 0x8000 */
224
 
 
225
 
        /* after the first 3 bytes have been read from ROM, switch the RAM back in */
226
 
        state->m_reset_delay_counter = 2;
227
 
        space->set_direct_update_handler(direct_update_delegate(FUNC(z80ne_reset_delay_count), &machine));
228
 
}
229
 
 
230
 
static void reset_lx390_banking(running_machine &machine)
231
 
{
232
 
        z80ne_state *state = machine.driver_data<z80ne_state>();
233
 
        address_space *space = machine.device("z80ne")->memory().space(AS_PROGRAM);
234
 
        state->m_reset_delay_counter = 0;
235
 
 
236
 
        switch (input_port_read(machine, "CONFIG") & 0x07) {
237
 
        case 0x01: /* EP382 Hex Monitor */
238
 
                if (VERBOSE)
239
 
                        logerror("reset_lx390_banking: banking ep382\n");
240
 
            memory_set_bank(machine, "bank1", 4);  /* ep382 at 0x0000 for 3 cycles, then RAM */
241
 
            memory_set_bank(machine, "bank2", 0);  /* RAM   at 0x0400 */
242
 
            memory_set_bank(machine, "bank3", 1);  /* ep382 at 0x8000 */
243
 
            memory_set_bank(machine, "bank4", 0);  /* RAM   at 0xF000 */
244
 
                /* after the first 3 bytes have been read from ROM, switch the RAM back in */
245
 
                state->m_reset_delay_counter = 2;
246
 
                space->set_direct_update_handler(direct_update_delegate(FUNC(z80ne_reset_delay_count), &machine));
247
 
            break;
248
 
        case 0x02: /* EP548  16k BASIC */
249
 
                if (VERBOSE)
250
 
                        logerror("reset_lx390_banking: banking ep548\n");
251
 
            memory_set_bank(machine, "bank1", 5);  /* ep548 at 0x0000-0x03FF */
252
 
            memory_set_bank(machine, "bank2", 1);  /* ep548 at 0x0400-0x3FFF */
253
 
            memory_set_bank(machine, "bank3", 0);  /* RAM   at 0x8000 */
254
 
            memory_set_bank(machine, "bank4", 0);  /* RAM   at 0xF000 */
255
 
                machine.device("z80ne")->memory().space(AS_PROGRAM)->set_direct_update_handler(direct_update_delegate(FUNC(z80ne_default), &machine));
256
 
            break;
257
 
        case 0x03: /* EP390  Boot Loader for 5.5k floppy BASIC */
258
 
                if (VERBOSE)
259
 
                        logerror("reset_lx390_banking: banking ep390\n");
260
 
            memory_set_bank(machine, "bank1", 1);  /* ep390 at 0x0000-0 x03FF for 3 cycles, then RAM */
261
 
            memory_set_bank(machine, "bank2", 0);  /* RAM   at 0x0400-0x3FFF */
262
 
            memory_set_bank(machine, "bank3", 0);  /* RAM   at 0x8000 */
263
 
            memory_set_bank(machine, "bank4", 1);  /* ep390 at 0xF000 */
264
 
                machine.device("z80ne")->memory().space(AS_PROGRAM)->set_direct_update_handler(direct_update_delegate(FUNC(z80ne_default), &machine));
265
 
            break;
266
 
        case 0x04: /* EP1390 Boot Loader for NE DOS 1.0/1.5 */
267
 
                if (VERBOSE)
268
 
                        logerror("reset_lx390_banking: banking ep1390\n");
269
 
            memory_set_bank(machine, "bank1", 2);  /* ep1390 at 0x0000-0x03FF for 3 cycles, then RAM */
270
 
            memory_set_bank(machine, "bank2", 0);  /* RAM   at 0x0400-0x3FFF */
271
 
            memory_set_bank(machine, "bank3", 0);  /* RAM   at 0x8000 */
272
 
            memory_set_bank(machine, "bank4", 2);  /* ep1390 at 0xF000 */
273
 
                machine.device("z80ne")->memory().space(AS_PROGRAM)->set_direct_update_handler(direct_update_delegate(FUNC(z80ne_default), &machine));
274
 
            break;
275
 
        case 0x05: /* EP2390 Boot Loader for NE DOS G.1 */
276
 
                if (VERBOSE)
277
 
                        logerror("reset_lx390_banking: banking ep2390\n");
278
 
            memory_set_bank(machine, "bank1", 3);  /* ep2390 at 0x0000-0x03FF for 3 cycles, then RAM */
279
 
            memory_set_bank(machine, "bank2", 0);  /* RAM   at 0x0400-0x3FFF */
280
 
            memory_set_bank(machine, "bank3", 0);  /* RAM   at 0x8000 */
281
 
            memory_set_bank(machine, "bank4", 3);  /* ep2390 at 0xF000 */
282
 
                machine.device("z80ne")->memory().space(AS_PROGRAM)->set_direct_update_handler(direct_update_delegate(FUNC(z80ne_default), &machine));
283
 
            break;
284
 
        }
285
 
 
286
 
    /* TODO: in real hardware the ENH bus line is pulled down
287
 
     * until a I/O read is performed on a address with A0 address bit low and A1 or A2 address bit high
288
 
     */
289
 
}
290
 
 
291
 
static MACHINE_RESET(z80ne_base)
292
 
{
293
 
        z80ne_state *state = machine.driver_data<z80ne_state>();
294
 
        int i;
295
 
        address_space *space = machine.device("z80ne")->memory().space(AS_PROGRAM);
296
 
 
297
 
        LOG(("In MACHINE_RESET z80ne_base\n"));
298
 
 
299
 
        for ( i=0; i<LX383_KEYS; i++)
300
 
        state->m_lx383_key[i] = 0xf0 | i;
301
 
    state->m_lx383_scan_counter = 0x0f;
302
 
    state->m_lx383_downsampler = LX383_DOWNSAMPLING;
303
 
 
304
 
        /* Initialize cassette interface */
305
 
        switch(input_port_read(machine, "LX.385") & 0x07)
306
 
        {
307
 
        case 0x01:
308
 
                state->m_cass_data.speed = TAPE_300BPS;
309
 
                state->m_cass_data.wave_filter = LX385_TAPE_SAMPLE_FREQ / 1600;
310
 
                state->m_cass_data.wave_short = LX385_TAPE_SAMPLE_FREQ / (2400 * 2);
311
 
                state->m_cass_data.wave_long = LX385_TAPE_SAMPLE_FREQ / (1200 * 2);
312
 
                break;
313
 
        case 0x02:
314
 
                state->m_cass_data.speed = TAPE_600BPS;
315
 
                state->m_cass_data.wave_filter = LX385_TAPE_SAMPLE_FREQ / 3200;
316
 
                state->m_cass_data.wave_short = LX385_TAPE_SAMPLE_FREQ / (4800 * 2);
317
 
                state->m_cass_data.wave_long = LX385_TAPE_SAMPLE_FREQ / (2400 * 2);
318
 
                break;
319
 
        case 0x04:
320
 
                state->m_cass_data.speed = TAPE_1200BPS;
321
 
                state->m_cass_data.wave_filter = LX385_TAPE_SAMPLE_FREQ / 6400;
322
 
                state->m_cass_data.wave_short = LX385_TAPE_SAMPLE_FREQ / (9600 * 2);
323
 
                state->m_cass_data.wave_long = LX385_TAPE_SAMPLE_FREQ / (4800 * 2);
324
 
        }
325
 
        state->m_cass_data.wave_length = state->m_cass_data.wave_short;
326
 
        state->m_cass_data.output.length = state->m_cass_data.wave_length;
327
 
        state->m_cass_data.output.level = 1;
328
 
        state->m_cass_data.input.length = 0;
329
 
        state->m_cass_data.input.bit = 1;
330
 
 
331
 
        state->m_ay31015 = machine.device("ay_3_1015");
332
 
        ay31015_set_input_pin( state->m_ay31015, AY31015_CS, 0 );
333
 
        ay31015_set_input_pin( state->m_ay31015, AY31015_NB1, 1 );
334
 
        ay31015_set_input_pin( state->m_ay31015, AY31015_NB2, 1 );
335
 
        ay31015_set_input_pin( state->m_ay31015, AY31015_TSB, 1 );
336
 
        ay31015_set_input_pin( state->m_ay31015, AY31015_EPS, 1 );
337
 
        ay31015_set_input_pin( state->m_ay31015, AY31015_NP, input_port_read(machine, "LX.385") & 0x80 ? 1 : 0 );
338
 
        ay31015_set_input_pin( state->m_ay31015, AY31015_CS, 1 );
339
 
        ay31015_set_receiver_clock( state->m_ay31015, state->m_cass_data.speed * 16.0);
340
 
        ay31015_set_transmitter_clock( state->m_ay31015, state->m_cass_data.speed * 16.0);
341
 
 
342
 
        state->m_nmi_delay_counter = 0;
343
 
        lx385_ctrl_w(space, 0, 0);
344
 
 
345
 
}
346
 
 
347
 
MACHINE_RESET(z80ne)
348
 
{
349
 
        LOG(("In MACHINE_RESET z80ne\n"));
350
 
        reset_lx382_banking(machine);
351
 
        MACHINE_RESET_CALL( z80ne_base );
352
 
}
353
 
 
354
 
MACHINE_RESET(z80net)
355
 
{
356
 
        LOG(("In MACHINE_RESET z80net\n"));
357
 
        MACHINE_RESET_CALL( z80ne );
358
 
        reset_lx388(machine);
359
 
}
360
 
 
361
 
MACHINE_RESET(z80netb)
362
 
{
363
 
        LOG(("In MACHINE_RESET z80netb\n"));
364
 
        MACHINE_RESET_CALL( z80ne_base );
365
 
        reset_lx388(machine);
366
 
}
367
 
 
368
 
MACHINE_RESET(z80netf)
369
 
{
370
 
        LOG(("In MACHINE_RESET z80netf\n"));
371
 
        reset_lx390_banking(machine);
372
 
        MACHINE_RESET_CALL( z80ne_base );
373
 
        reset_lx388(machine);
374
 
}
375
 
 
376
 
INPUT_CHANGED( z80ne_reset )
377
 
{
378
 
        UINT8 rst;
379
 
        rst = input_port_read(field.machine(), "RST");
380
 
 
381
 
        if ( ! BIT(rst, 0))
382
 
        {
383
 
                running_machine &machine = field.machine();
384
 
                machine.schedule_soft_reset();
385
 
        }
386
 
}
387
 
 
388
 
INPUT_CHANGED( z80ne_nmi )
389
 
{
390
 
        UINT8 nmi;
391
 
        nmi = input_port_read(field.machine(), "LX388_BRK");
392
 
 
393
 
        if ( ! BIT(nmi, 0))
394
 
        {
395
 
                cputag_set_input_line(field.machine(), "z80ne", INPUT_LINE_NMI, PULSE_LINE);
396
 
        }
397
 
}
398
 
 
399
 
MACHINE_START( z80ne )
400
 
{
401
 
        z80ne_state *state = machine.driver_data<z80ne_state>();
402
 
        LOG(("In MACHINE_START z80ne\n"));
403
 
        state->m_lx385_ctrl = 0x1f;
404
 
        state_save_register_item( machine, "z80ne", NULL, 0, state->m_lx383_scan_counter );
405
 
        state_save_register_item( machine, "z80ne", NULL, 0, state->m_lx383_downsampler );
406
 
        state_save_register_item_array( machine, "z80ne", NULL, 0, state->m_lx383_key );
407
 
        state_save_register_item( machine, "z80ne", NULL, 0, state->m_nmi_delay_counter );
408
 
        state->m_cassette_timer = machine.scheduler().timer_alloc(FUNC(z80ne_cassette_tc));
409
 
        machine.scheduler().timer_pulse( attotime::from_hz(1000), FUNC(z80ne_kbd_scan));
410
 
}
411
 
 
412
 
MACHINE_START( z80net )
413
 
{
414
 
        MACHINE_START_CALL( z80ne );
415
 
        LOG(("In MACHINE_START z80net\n"));
416
 
}
417
 
 
418
 
MACHINE_START( z80netb )
419
 
{
420
 
        MACHINE_START_CALL( z80net );
421
 
        LOG(("In MACHINE_START z80netb\n"));
422
 
}
423
 
 
424
 
MACHINE_START( z80netf )
425
 
{
426
 
        MACHINE_START_CALL( z80net );
427
 
        LOG(("In MACHINE_START z80netf\n"));
428
 
}
429
 
 
430
 
/******************************************************************************
431
 
 Drivers
432
 
******************************************************************************/
433
 
 
434
 
/* LX.383 - LX.384 HEX keyboard and display */
435
 
READ8_HANDLER( lx383_r )
436
 
{
437
 
        z80ne_state *state = space->machine().driver_data<z80ne_state>();
438
 
        /*
439
 
     * Keyboard scanning
440
 
     *
441
 
     * IC14 NE555 astable oscillator
442
 
     * IC13 74LS93 binary counter
443
 
     * IC5  74LS240 tri-state buffer
444
 
     *
445
 
     * l'oscillatore NE555 alimenta il clock del contatore 74LS93
446
 
     *      D0 - Q(A) --\
447
 
     *      D1 - Q(B)    |-- column
448
 
     *      D2 - Q(C) --/
449
 
     *      D3 - Q(D)        row
450
 
     *      D4 - CTRL
451
 
     *      D5 - 0
452
 
     *      D6 - 0
453
 
     *      D7 - ~KEY Pressed
454
 
     */
455
 
    return state->m_lx383_key[state->m_lx383_scan_counter];
456
 
}
457
 
 
458
 
WRITE8_HANDLER( lx383_w )
459
 
{
460
 
        z80ne_state *state = space->machine().driver_data<z80ne_state>();
461
 
        /*
462
 
     * First 8 locations (F0-F7) are mapped to a dual-port 8-byte RAM
463
 
     * The 1KHz NE-555 astable oscillator circuit drive
464
 
     * a 4-bit 74LS93 binary counter.
465
 
     * The 3 least sigificant bits of the counter are connected
466
 
     * both to the read addres of the dual-port ram and to
467
 
     * a 74LS156 3 to 8 binary decoder driving the cathode
468
 
     * of 8 7-segments LEDS.
469
 
     * The data output of the dual-port ram drive the anodes
470
 
     * of the LEDS through 74LS07 buffers.
471
 
     * LED segments - dual-port RAM bit:
472
 
     *   A   0x01
473
 
     *   B   0x02
474
 
     *   C   0x04
475
 
     *   D   0x08
476
 
     *   E   0x10
477
 
     *   F   0x20
478
 
     *   G   0x40
479
 
     *   P   0x80 (represented by DP in original schematics)
480
 
     *
481
 
     *   A write in the range F0-FF starts a 74LS90 counter
482
 
     *   that trigger the NMI line of the CPU afther 2 instruction
483
 
     *   fetch cycles for single step execution.
484
 
     */
485
 
 
486
 
        if ( offset < 8 )
487
 
        output_set_digit_value( offset, data ^ 0xff );
488
 
    else
489
 
        /* after writing to port 0xF8 and the first ~M1 cycles strike a NMI for single step execution */
490
 
        state->m_nmi_delay_counter = 1;
491
 
                space->machine().device("z80ne")->memory().space(AS_PROGRAM)->set_direct_update_handler(direct_update_delegate(FUNC(z80ne_nmi_delay_count), &space->machine()));
492
 
}
493
 
 
494
 
 
495
 
/* LX.385 Cassette tape interface */
496
 
/*
497
 
 * NE555 is connected to a 74LS93 binary counter
498
 
 * 74LS93 output:
499
 
 *   QA-QC: colum index for LEDs and keyboard
500
 
 *   QD:    keyboard row select
501
 
 *
502
 
 * Port EE: UART Data Read/Write
503
 
 * Port EF: Status/Control
504
 
 *     read, UART status bits read
505
 
 *         0 OR   Overrun
506
 
 *         1 FE   Framing Error
507
 
 *         2 PE   Parity Error
508
 
 *         3 TBMT Transmitter Buffer Empty
509
 
 *         4 DAV  Data Available
510
 
 *         5 EOC  End Of Character
511
 
 *         6 1
512
 
 *         7 1
513
 
 *     write, UART control bits / Tape Unit select / Modulation control
514
 
 *         0 bit1=0, bit0=0   UART Reset pulse
515
 
 *         1 bit1=0, bit0=1   UART RDAV (Reset Data Available) pulse
516
 
 *         2 Tape modulation enable
517
 
 *         3 *TAPEA Enable (active low) (at reset: low)
518
 
 *         4 *TAPEB Enable (active low) (at reset: low)
519
 
 *  Cassette is connected to the uart data input and output via the cassette
520
 
 *  interface hardware.
521
 
 *
522
 
 *  The cassette interface hardware converts square-wave pulses into bits which the uart receives.
523
 
 *
524
 
 *  1. the cassette format: "frequency shift" is converted
525
 
    into the uart data format "non-return to zero"
526
 
 
527
 
    2. on cassette a 1 data bit is stored as 8 2400 Hz pulses
528
 
    and a 0 data bit as 4 1200 Hz pulses
529
 
    - At 1200 baud, a logic 1 is 1 cycle of 1200 Hz and a logic 0 is 1/2 cycle of 600 Hz.
530
 
    - At 300 baud, a logic 1 is 8 cycles of 2400 Hz and a logic 0 is 4 cycles of 1200 Hz.
531
 
 
532
 
    Attenuation is applied to the signal and the square wave edges are rounded.
533
 
 
534
 
    A manchester encoder is used. A flip-flop synchronises input
535
 
    data on the positive-edge of the clock pulse.
536
 
 *
537
 
 */
538
 
READ8_HANDLER(lx385_data_r)
539
 
{
540
 
        z80ne_state *state = space->machine().driver_data<z80ne_state>();
541
 
        return ay31015_get_received_data( state->m_ay31015 );
542
 
}
543
 
 
544
 
READ8_HANDLER(lx385_ctrl_r)
545
 
{
546
 
        z80ne_state *state = space->machine().driver_data<z80ne_state>();
547
 
        /* set unused bits high */
548
 
        UINT8 data = 0xc0;
549
 
 
550
 
        ay31015_set_input_pin( state->m_ay31015, AY31015_SWE, 0 );
551
 
        data |= (ay31015_get_output_pin( state->m_ay31015, AY31015_OR   ) ? 0x01 : 0);
552
 
        data |= (ay31015_get_output_pin( state->m_ay31015, AY31015_FE   ) ? 0x02 : 0);
553
 
        data |= (ay31015_get_output_pin( state->m_ay31015, AY31015_PE   ) ? 0x04 : 0);
554
 
        data |= (ay31015_get_output_pin( state->m_ay31015, AY31015_TBMT ) ? 0x08 : 0);
555
 
        data |= (ay31015_get_output_pin( state->m_ay31015, AY31015_DAV  ) ? 0x10 : 0);
556
 
        data |= (ay31015_get_output_pin( state->m_ay31015, AY31015_EOC  ) ? 0x20 : 0);
557
 
        ay31015_set_input_pin( state->m_ay31015, AY31015_SWE, 1 );
558
 
 
559
 
        return data;
560
 
}
561
 
 
562
 
WRITE8_HANDLER(lx385_data_w)
563
 
{
564
 
        z80ne_state *state = space->machine().driver_data<z80ne_state>();
565
 
        ay31015_set_transmit_data( state->m_ay31015, data );
566
 
}
567
 
 
568
 
#define LX385_CASSETTE_MOTOR_MASK ((1<<3)|(1<<4))
569
 
 
570
 
WRITE8_HANDLER(lx385_ctrl_w)
571
 
{
572
 
        z80ne_state *state = space->machine().driver_data<z80ne_state>();
573
 
        /* Translate data to control signals
574
 
     *     0 bit1=0, bit0=0   UART Reset pulse
575
 
     *     1 bit1=0, bit0=1   UART RDAV (Reset Data Available) pulse
576
 
     *     2 UART Tx Clock Enable (active high)
577
 
     *     3 *TAPEA Enable (active low) (at reset: low)
578
 
     *     4 *TAPEB Enable (active low) (at reset: low)
579
 
     */
580
 
        UINT8 uart_reset, uart_rdav, uart_tx_clock;
581
 
        UINT8 motor_a, motor_b;
582
 
        UINT8 changed_bits = (state->m_lx385_ctrl ^ data) & 0x1C;
583
 
        state->m_lx385_ctrl = data;
584
 
 
585
 
        uart_reset = ((data & 0x03) == 0x00);
586
 
        uart_rdav  = ((data & 0x03) == 0x01);
587
 
        uart_tx_clock = ((data & 0x04) == 0x04);
588
 
        motor_a = ((data & 0x08) == 0x00);
589
 
        motor_b = ((data & 0x10) == 0x00);
590
 
 
591
 
        /* UART Reset and RDAV */
592
 
        if(uart_reset)
593
 
        {
594
 
                ay31015_set_input_pin( state->m_ay31015, AY31015_XR, 1 );
595
 
                ay31015_set_input_pin( state->m_ay31015, AY31015_XR, 0 );
596
 
        }
597
 
 
598
 
        if(uart_rdav)
599
 
        {
600
 
                ay31015_set_input_pin( state->m_ay31015, AY31015_RDAV, 1 );
601
 
                ay31015_set_input_pin( state->m_ay31015, AY31015_RDAV, 0 );
602
 
        }
603
 
 
604
 
        if (!changed_bits) return;
605
 
 
606
 
        /* UART Tx Clock enable/disable */
607
 
        if(changed_bits & 0x04)
608
 
                ay31015_set_transmitter_clock( state->m_ay31015, uart_tx_clock ? state->m_cass_data.speed * 16.0 : 0.0);
609
 
 
610
 
        /* motors */
611
 
        if(changed_bits & 0x18)
612
 
        {
613
 
                space->machine().device<cassette_image_device>(CASSETTE_TAG)->change_state(
614
 
                        (motor_a) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR);
615
 
 
616
 
                space->machine().device<cassette_image_device>(CASSETTE2_TAG)->change_state(
617
 
                        (motor_b) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR);
618
 
 
619
 
                if (motor_a || motor_b)
620
 
                        state->m_cassette_timer->adjust(attotime::zero, 0, attotime::from_hz(LX385_TAPE_SAMPLE_FREQ));
621
 
                else
622
 
                        state->m_cassette_timer->adjust(attotime::zero);
623
 
        }
624
 
}
625
 
 
626
 
READ8_DEVICE_HANDLER( lx388_mc6847_videoram_r )
627
 
{
628
 
        z80ne_state *state = device->machine().driver_data<z80ne_state>();
629
 
        UINT8 *videoram = state->m_videoram;
630
 
        int d6 = BIT(videoram[offset], 6);
631
 
        int d7 = BIT(videoram[offset], 7);
632
 
 
633
 
        mc6847_inv_w(device, d6 && d7);
634
 
        mc6847_as_w(device, !d6 && d7);
635
 
        mc6847_intext_w(device, !d6 && d7);
636
 
 
637
 
        return videoram[offset];
638
 
}
639
 
 
640
 
SCREEN_UPDATE( lx388 )
641
 
{
642
 
        device_t *mc6847 = screen->machine().device("mc6847");
643
 
        return mc6847_update(mc6847, bitmap, cliprect);
644
 
}
645
 
 
646
 
READ8_HANDLER(lx388_data_r)
647
 
{
648
 
        z80ne_state *state = space->machine().driver_data<z80ne_state>();
649
 
        UINT8 data;
650
 
 
651
 
        data = kr2376_data_r(state->m_lx388_kr2376, 0) & 0x7f;
652
 
        data |= kr2376_get_output_pin(state->m_lx388_kr2376, KR2376_SO) << 7;
653
 
        return data;
654
 
}
655
 
 
656
 
READ8_HANDLER( lx388_read_field_sync )
657
 
{
658
 
        device_t *mc6847 = space->machine().device("mc6847");
659
 
        return mc6847_fs_r(mc6847) << 7;
660
 
}
661
 
 
662
 
/*
663
 
 * DRQ INTRQ IC9B.10 IC8B.*Q
664
 
 *  0    0     1       0
665
 
 *  0    1     0       x
666
 
 *  1    0     0       x
667
 
 *  1    1     0       x
668
 
 *
669
 
 */
670
 
 
671
 
WRITE8_DEVICE_HANDLER(lx390_motor_w)
672
 
{
673
 
        z80ne_state *state = device->machine().driver_data<z80ne_state>();
674
 
        /* Selection of drive and parameters
675
 
     A write also causes the selected drive motor to turn on for about 3 seconds.
676
 
     When the motor turns off, the drive is deselected.
677
 
        d7 Unused             (trs80: 1=MFM, 0=FM)
678
 
        d6 (trs80: 1=Wait)
679
 
        d5 0=Side 0, 1=Side 1 (trs80: 1=Write Precompensation enabled)
680
 
        d4 Unused             (trs80: 0=Side 0, 1=Side 1)
681
 
        d3 1=select drive 3
682
 
        d2 1=select drive 2
683
 
        d1 1=select drive 1
684
 
        d0 1=select drive 0 */
685
 
 
686
 
                UINT8 drive = 255;
687
 
 
688
 
                if (data & 1)
689
 
                        drive = 0;
690
 
                else
691
 
                if (data & 2)
692
 
                        drive = 1;
693
 
                else
694
 
                if (data & 4)
695
 
                        drive = 2;
696
 
                else
697
 
                if (data & 8)
698
 
                        drive = 3;
699
 
 
700
 
                state->m_wd17xx_state.head = (data & 32) ? 1 : 0;
701
 
                state->m_wd17xx_state.drive = data & 0x0F;
702
 
 
703
 
                /* no drive selected, turn off all leds */
704
 
                if (!state->m_wd17xx_state.drive)
705
 
                {
706
 
                        output_set_value("drv0", 0);
707
 
                        output_set_value("drv1", 0);
708
 
                }
709
 
 
710
 
                if (drive < 4)
711
 
                {
712
 
                        LOG(("lx390_motor_w, set drive %1d\n", drive));
713
 
                        wd17xx_set_drive(device,drive);
714
 
                        LOG(("lx390_motor_w, set side %1d\n", state->m_wd17xx_state.head));
715
 
                        wd17xx_set_side(device, state->m_wd17xx_state.head);
716
 
                }
717
 
}
718
 
 
719
 
READ8_DEVICE_HANDLER(lx390_reset_bank)
720
 
{
721
 
        offs_t pc;
722
 
 
723
 
        /* if PC is not in range, we are under integrated debugger control, DON'T SWAP */
724
 
        pc = cpu_get_pc(device->machine().device("z80ne"));
725
 
        if((pc >= 0xf000) && (pc <=0xffff))
726
 
        {
727
 
                LOG(("lx390_reset_bank, reset memory bank 1\n"));
728
 
                memory_set_bank(device->machine(), "bank1", 0); /* RAM at 0x0000 (bank 1) */
729
 
        }
730
 
        else
731
 
        {
732
 
                LOG(("lx390_reset_bank, bypass because in debugger\n"));
733
 
        }
734
 
        return 0xff;
735
 
}
736
 
 
737
 
READ8_DEVICE_HANDLER(lx390_fdc_r)
738
 
{
739
 
        UINT8 d;
740
 
 
741
 
        switch(offset)
742
 
        {
743
 
        case 0:
744
 
                d = wd17xx_status_r(device, 0) ^ 0xff;
745
 
                LOG(("lx390_fdc_r, WD17xx status: %02x\n", d));
746
 
                break;
747
 
        case 1:
748
 
                d = wd17xx_track_r(device, 0) ^ 0xff;
749
 
                LOG(("lx390_fdc_r, WD17xx track:  %02x\n", d));
750
 
                break;
751
 
        case 2:
752
 
                d = wd17xx_sector_r(device, 0) ^ 0xff;
753
 
                LOG(("lx390_fdc_r, WD17xx sector: %02x\n", d));
754
 
                break;
755
 
        case 3:
756
 
                d = wd17xx_data_r(device, 0) ^ 0xff;
757
 
                LOG(("lx390_fdc_r, WD17xx data3:  %02x\n", d));
758
 
                break;
759
 
        case 6:
760
 
                d = 0xff;
761
 
                lx390_reset_bank(device, 0);
762
 
                break;
763
 
        case 7:
764
 
                d = wd17xx_data_r(device, 3) ^ 0xff;
765
 
                LOG(("lx390_fdc_r, WD17xx data7, force:  %02x\n", d));
766
 
                break;
767
 
        default:
768
 
                d = 0x00;
769
 
        }
770
 
        return d;
771
 
}
772
 
 
773
 
WRITE8_DEVICE_HANDLER(lx390_fdc_w)
774
 
{
775
 
        z80ne_state *state = device->machine().driver_data<z80ne_state>();
776
 
        UINT8 d;
777
 
 
778
 
        d = data;
779
 
        switch(offset)
780
 
        {
781
 
        case 0:
782
 
                LOG(("lx390_fdc_w, WD17xx command: %02x\n", d));
783
 
                wd17xx_command_w(device, offset, d ^ 0xff);
784
 
                if (state->m_wd17xx_state.drive & 1)
785
 
                        output_set_value("drv0", 2);
786
 
                else if (state->m_wd17xx_state.drive & 2)
787
 
                        output_set_value("drv1", 2);
788
 
                break;
789
 
        case 1:
790
 
                LOG(("lx390_fdc_w, WD17xx track:   %02x\n", d));
791
 
                wd17xx_track_w(device, offset, d ^ 0xff);
792
 
                break;
793
 
        case 2:
794
 
                LOG(("lx390_fdc_w, WD17xx sector:  %02x\n", d));
795
 
                wd17xx_sector_w(device, offset, d ^ 0xff);
796
 
                break;
797
 
        case 3:
798
 
                wd17xx_data_w(device, 0, d ^ 0xff);
799
 
                LOG(("lx390_fdc_w, WD17xx data3:   %02x\n", d));
800
 
                break;
801
 
        case 6:
802
 
                LOG(("lx390_fdc_w, motor_w:   %02x\n", d));
803
 
                lx390_motor_w(device, 0, d);
804
 
                break;
805
 
        case 7:
806
 
                LOG(("lx390_fdc_w, WD17xx data7, force:   %02x\n", d));
807
 
                wd17xx_data_w(device, 3, d ^ 0xff);
808
 
                break;
809
 
        }
810
 
}