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

« back to all changes in this revision

Viewing changes to mess/src/mess/machine/svi318.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
 
** Spectravideo SVI-318 and SVI-328
3
 
**
4
 
** Sean Young, Tomas Karlsson
5
 
**
6
 
*/
7
 
 
8
 
#include "emu.h"
9
 
#include "video/mc6845.h"
10
 
#include "includes/svi318.h"
11
 
#include "cpu/z80/z80.h"
12
 
#include "video/tms9928a.h"
13
 
#include "machine/i8255.h"
14
 
#include "machine/ins8250.h"
15
 
#include "machine/wd17xx.h"
16
 
#include "machine/ctronics.h"
17
 
#include "imagedev/flopdrv.h"
18
 
#include "imagedev/cassette.h"
19
 
#include "formats/svi_cas.h"
20
 
#include "sound/dac.h"
21
 
#include "sound/ay8910.h"
22
 
#include "machine/ram.h"
23
 
 
24
 
enum {
25
 
        SVI_INTERNAL    = 0,
26
 
        SVI_CART        = 1,
27
 
        SVI_EXPRAM2     = 2,
28
 
        SVI_EXPRAM3     = 3
29
 
};
30
 
 
31
 
 
32
 
static void svi318_set_banks(running_machine &machine);
33
 
 
34
 
 
35
 
/* Serial ports */
36
 
 
37
 
static WRITE_LINE_DEVICE_HANDLER( svi318_ins8250_interrupt )
38
 
{
39
 
        svi318_state *drvstate = device->machine().driver_data<svi318_state>();
40
 
        if (drvstate->m_svi.bankLow != SVI_CART)
41
 
        {
42
 
                cputag_set_input_line(device->machine(), "maincpu", 0, (state ? HOLD_LINE : CLEAR_LINE));
43
 
        }
44
 
}
45
 
 
46
 
static INS8250_REFRESH_CONNECT( svi318_com_refresh_connected )
47
 
{
48
 
        /* Motorola MC14412 modem */
49
 
        ins8250_handshake_in(device, UART8250_HANDSHAKE_IN_CTS|UART8250_HANDSHAKE_IN_DSR|UART8250_INPUTS_RING_INDICATOR|UART8250_INPUTS_DATA_CARRIER_DETECT);
50
 
}
51
 
 
52
 
const ins8250_interface svi318_ins8250_interface[2]=
53
 
{
54
 
        {
55
 
                1000000,
56
 
                DEVCB_LINE(svi318_ins8250_interrupt),
57
 
                NULL,
58
 
                NULL,
59
 
                svi318_com_refresh_connected
60
 
        },
61
 
        {
62
 
                3072000,
63
 
                DEVCB_LINE(svi318_ins8250_interrupt),
64
 
                NULL,
65
 
                NULL,
66
 
                NULL
67
 
        }
68
 
};
69
 
 
70
 
 
71
 
/* Cartridge */
72
 
 
73
 
static int svi318_verify_cart (UINT8 magic[2])
74
 
{
75
 
        /* read the first two bytes */
76
 
        if ( (magic[0] == 0xf3) && (magic[1] == 0x31) )
77
 
                return IMAGE_VERIFY_PASS;
78
 
        else
79
 
                return IMAGE_VERIFY_FAIL;
80
 
}
81
 
 
82
 
DEVICE_START( svi318_cart )
83
 
{
84
 
        svi318_state *state = device->machine().driver_data<svi318_state>();
85
 
        state->m_pcart = NULL;
86
 
        state->m_pcart_rom_size = 0;
87
 
}
88
 
 
89
 
DEVICE_IMAGE_LOAD( svi318_cart )
90
 
{
91
 
        svi318_state *state = image.device().machine().driver_data<svi318_state>();
92
 
        UINT8 *p = image.device().machine().region("user1")->base();
93
 
        UINT32 size;
94
 
 
95
 
        if (image.software_entry() == NULL)
96
 
                size = image.length();
97
 
        else
98
 
                size = image.get_software_region_length("rom");
99
 
 
100
 
        if (size > 0x8000)
101
 
                logerror("Cart image %s larger than expected. Please report the issue.\n", image.filename());
102
 
 
103
 
        if (image.software_entry() == NULL)
104
 
        {
105
 
                if (image.fread(p, size) != size)
106
 
                {
107
 
                        logerror("Can't read file %s\n", image.filename());
108
 
                        return IMAGE_INIT_FAIL;
109
 
                }
110
 
        }
111
 
        else
112
 
                memcpy(p, image.get_software_region("rom"), size);
113
 
 
114
 
        if (svi318_verify_cart(p) == IMAGE_VERIFY_FAIL)
115
 
                return IMAGE_INIT_FAIL;
116
 
 
117
 
        state->m_pcart = p;
118
 
        state->m_pcart_rom_size = size;
119
 
 
120
 
        return IMAGE_INIT_PASS;
121
 
}
122
 
 
123
 
DEVICE_IMAGE_UNLOAD( svi318_cart )
124
 
{
125
 
        svi318_state *state = image.device().machine().driver_data<svi318_state>();
126
 
        state->m_pcart = NULL;
127
 
        state->m_pcart_rom_size = 0;
128
 
}
129
 
 
130
 
/* PPI */
131
 
 
132
 
/*
133
 
 PPI Port A Input (address 98H)
134
 
 Bit Name     Description
135
 
  1  TA       Joystick 1, /SENSE
136
 
  2  TB       Joystick 1, EOC
137
 
  3  TC       Joystick 2, /SENSE
138
 
  4  TD       Joystick 2, EOC
139
 
  5  TRIGGER1 Joystick 1, Trigger
140
 
  6  TRIGGER2 Joystick 2, Trigger
141
 
  7  /READY   Cassette, Ready
142
 
  8  CASR     Cassette, Read data
143
 
*/
144
 
 
145
 
static READ8_DEVICE_HANDLER ( svi318_ppi_port_a_r )
146
 
{
147
 
        int data = 0x0f;
148
 
 
149
 
        if ((device->machine().device<cassette_image_device>(CASSETTE_TAG))->input() > 0.0038)
150
 
                data |= 0x80;
151
 
        if (!svi318_cassette_present(device->machine(), 0))
152
 
                data |= 0x40;
153
 
        data |= input_port_read(device->machine(), "BUTTONS") & 0x30;
154
 
 
155
 
        return data;
156
 
}
157
 
 
158
 
/*
159
 
 PPI Port B Input (address 99H)
160
 
 Bit Name Description
161
 
  1  IN0  Keyboard, Column status of selected line
162
 
  2  IN1  Keyboard, Column status of selected line
163
 
  3  IN2  Keyboard, Column status of selected line
164
 
  4  IN3  Keyboard, Column status of selected line
165
 
  5  IN4  Keyboard, Column status of selected line
166
 
  6  IN5  Keyboard, Column status of selected line
167
 
  7  IN6  Keyboard, Column status of selected line
168
 
  8  IN7  Keyboard, Column status of selected line
169
 
*/
170
 
 
171
 
static READ8_DEVICE_HANDLER ( svi318_ppi_port_b_r )
172
 
{
173
 
        svi318_state *state = device->machine().driver_data<svi318_state>();
174
 
        int row;
175
 
        static const char *const keynames[] = {
176
 
                "LINE0", "LINE1", "LINE2", "LINE3", "LINE4", "LINE5",
177
 
                "LINE6", "LINE7", "LINE8", "LINE9", "LINE10"
178
 
        };
179
 
 
180
 
        row = state->m_svi.keyboard_row;
181
 
        if (row <= 10)
182
 
                return input_port_read(device->machine(), keynames[row]);
183
 
 
184
 
        return 0xff;
185
 
}
186
 
 
187
 
/*
188
 
 PPI Port C Output (address 97H)
189
 
 Bit Name   Description
190
 
  1  KB0    Keyboard, Line select 0
191
 
  2  KB1    Keyboard, Line select 1
192
 
  3  KB2    Keyboard, Line select 2
193
 
  4  KB3    Keyboard, Line select 3
194
 
  5  CASON  Cassette, Motor relay control (0=on, 1=off)
195
 
  6  CASW   Cassette, Write data
196
 
  7  CASAUD Cassette, Audio out (pulse)
197
 
  8  SOUND  Keyboard, Click sound bit (pulse)
198
 
*/
199
 
 
200
 
static WRITE8_DEVICE_HANDLER ( svi318_ppi_port_c_w )
201
 
{
202
 
        svi318_state *state = device->machine().driver_data<svi318_state>();
203
 
        int val;
204
 
 
205
 
        /* key click */
206
 
        val = (data & 0x80) ? 0x3e : 0;
207
 
        val += (data & 0x40) ? 0x3e : 0;
208
 
        dac_signed_data_w (device->machine().device("dac"), val);
209
 
 
210
 
        /* cassette motor on/off */
211
 
        if (svi318_cassette_present(device->machine(), 0))
212
 
        {
213
 
 
214
 
                        device->machine().device<cassette_image_device>(CASSETTE_TAG)->change_state(
215
 
                        (data & 0x10) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED,
216
 
                        CASSETTE_MOTOR_DISABLED);
217
 
        }
218
 
 
219
 
        /* cassette signal write */
220
 
        device->machine().device<cassette_image_device>(CASSETTE_TAG)->output((data & 0x20) ? -1.0 : +1.0);
221
 
 
222
 
        state->m_svi.keyboard_row = data & 0x0F;
223
 
}
224
 
 
225
 
I8255_INTERFACE( svi318_ppi8255_interface )
226
 
{
227
 
        DEVCB_HANDLER(svi318_ppi_port_a_r),
228
 
        DEVCB_NULL,
229
 
        DEVCB_HANDLER(svi318_ppi_port_b_r),
230
 
        DEVCB_NULL,
231
 
        DEVCB_NULL,
232
 
        DEVCB_HANDLER(svi318_ppi_port_c_w)
233
 
};
234
 
 
235
 
WRITE8_HANDLER( svi318_ppi_w )
236
 
{
237
 
        i8255_device *ppi = space->machine().device<i8255_device>("ppi8255");
238
 
        ppi->write(*space, offset + 2, data);
239
 
}
240
 
 
241
 
 
242
 
/* PSG */
243
 
 
244
 
/*
245
 
 PSG Port A Input
246
 
 Bit Name   Description
247
 
  1  FWD1   Joystick 1, Forward
248
 
  2  BACK1  Joystick 1, Back
249
 
  3  LEFT1  Joystick 1, Left
250
 
  4  RIGHT1 Joystick 1, Right
251
 
  5  FWD2   Joystick 2, Forward
252
 
  6  BACK2  Joystick 2, Back
253
 
  7  LEFT2  Joystick 2, Left
254
 
  8  RIGHT2 Joystick 2, Right
255
 
*/
256
 
 
257
 
READ8_HANDLER( svi318_psg_port_a_r )
258
 
{
259
 
        return input_port_read(space->machine(), "JOYSTICKS");
260
 
}
261
 
 
262
 
/*
263
 
 PSG Port B Output
264
 
 Bit Name    Description
265
 
  1  /CART   Memory bank 11, ROM 0000-7FFF (Cartridge /CCS1, /CCS2)
266
 
  2  /BK21   Memory bank 21, RAM 0000-7FFF
267
 
  3  /BK22   Memory bank 22, RAM 8000-FFFF
268
 
  4  /BK31   Memory bank 31, RAM 0000-7FFF
269
 
  5  /BK32   Memory bank 32, RAM 8000-7FFF
270
 
  6  CAPS    Caps-Lock diod
271
 
  7  /ROMEN0 Memory bank 12, ROM 8000-BFFF* (Cartridge /CCS3)
272
 
  8  /ROMEN1 Memory bank 12, ROM C000-FFFF* (Cartridge /CCS4)
273
 
 
274
 
 * The /CART signal must be active for any effect and all banks
275
 
 with RAM are disabled.
276
 
*/
277
 
 
278
 
WRITE8_HANDLER( svi318_psg_port_b_w )
279
 
{
280
 
        svi318_state *state = space->machine().driver_data<svi318_state>();
281
 
        if ( (state->m_svi.bank_switch ^ data) & 0x20)
282
 
                set_led_status (space->machine(), 0, !(data & 0x20) );
283
 
 
284
 
        state->m_svi.bank_switch = data;
285
 
        svi318_set_banks(space->machine());
286
 
}
287
 
 
288
 
/* Disk drives  */
289
 
 
290
 
static WRITE_LINE_DEVICE_HANDLER( svi_fdc_intrq_w )
291
 
{
292
 
        svi318_state *drvstate = device->machine().driver_data<svi318_state>();
293
 
        drvstate->m_fdc.irq = state;
294
 
}
295
 
 
296
 
static WRITE_LINE_DEVICE_HANDLER( svi_fdc_drq_w )
297
 
{
298
 
        svi318_state *drvstate = device->machine().driver_data<svi318_state>();
299
 
        drvstate->m_fdc.drq = state;
300
 
}
301
 
 
302
 
const wd17xx_interface svi_wd17xx_interface =
303
 
{
304
 
        DEVCB_NULL,
305
 
        DEVCB_LINE(svi_fdc_intrq_w),
306
 
        DEVCB_LINE(svi_fdc_drq_w),
307
 
        {FLOPPY_0, FLOPPY_1, NULL, NULL}
308
 
};
309
 
 
310
 
static WRITE8_HANDLER( svi318_fdc_drive_motor_w )
311
 
{
312
 
        svi318_state *state = space->machine().driver_data<svi318_state>();
313
 
        device_t *fdc = space->machine().device("wd179x");
314
 
        switch (data & 3)
315
 
        {
316
 
        case 1:
317
 
                wd17xx_set_drive(fdc,0);
318
 
                state->m_fdc.driveselect = 0;
319
 
                break;
320
 
        case 2:
321
 
                wd17xx_set_drive(fdc,1);
322
 
                state->m_fdc.driveselect = 1;
323
 
                break;
324
 
        }
325
 
}
326
 
 
327
 
static WRITE8_HANDLER( svi318_fdc_density_side_w )
328
 
{
329
 
        device_t *fdc = space->machine().device("wd179x");
330
 
 
331
 
        wd17xx_dden_w(fdc, BIT(data, 0));
332
 
        wd17xx_set_side(fdc, BIT(data, 1));
333
 
}
334
 
 
335
 
static READ8_HANDLER( svi318_fdc_irqdrq_r )
336
 
{
337
 
        svi318_state *state = space->machine().driver_data<svi318_state>();
338
 
        UINT8 result = 0;
339
 
 
340
 
        result |= state->m_fdc.drq << 6;
341
 
        result |= state->m_fdc.irq << 7;
342
 
 
343
 
        return result;
344
 
}
345
 
 
346
 
MC6845_UPDATE_ROW( svi806_crtc6845_update_row )
347
 
{
348
 
        svi318_state *state = device->machine().driver_data<svi318_state>();
349
 
        int i;
350
 
 
351
 
        for( i = 0; i < x_count; i++ )
352
 
        {
353
 
                int j;
354
 
                UINT8   data = state->m_svi.svi806_gfx[ state->m_svi.svi806_ram->u8(( ma + i ) & 0x7FF) * 16 + ra ];
355
 
 
356
 
                if ( i == cursor_x )
357
 
                {
358
 
                        data = 0xFF;
359
 
                }
360
 
 
361
 
                for( j=0; j < 8; j++ )
362
 
                {
363
 
                        *BITMAP_ADDR16(bitmap, y, i * 8 + j ) = TMS9928A_PALETTE_SIZE + ( ( data & 0x80 ) ? 1 : 0 );
364
 
                        data = data << 1;
365
 
                }
366
 
        }
367
 
}
368
 
 
369
 
 
370
 
/* 80 column card init */
371
 
static void svi318_80col_init(running_machine &machine)
372
 
{
373
 
        svi318_state *state = machine.driver_data<svi318_state>();
374
 
        /* 2K RAM, but allocating 4KB to make banking easier */
375
 
        /* The upper 2KB will be set to FFs and will never be written to */
376
 
        state->m_svi.svi806_ram = machine.region_alloc("gfx2", 0x1000, 1, ENDIANNESS_LITTLE );
377
 
        memset( state->m_svi.svi806_ram->base(), 0x00, 0x800 );
378
 
        memset( state->m_svi.svi806_ram->base() + 0x800, 0xFF, 0x800 );
379
 
        state->m_svi.svi806_gfx = machine.region("gfx1")->base();
380
 
}
381
 
 
382
 
 
383
 
static WRITE8_HANDLER( svi806_ram_enable_w )
384
 
{
385
 
        svi318_state *state = space->machine().driver_data<svi318_state>();
386
 
        state->m_svi.svi806_ram_enabled = ( data & 0x01 );
387
 
        svi318_set_banks(space->machine());
388
 
}
389
 
 
390
 
VIDEO_START( svi328_806 )
391
 
{
392
 
        VIDEO_START_CALL(tms9928a);
393
 
}
394
 
 
395
 
SCREEN_UPDATE( svi328_806 )
396
 
{
397
 
        if (!strcmp(screen->tag(), "screen"))
398
 
        {
399
 
                SCREEN_UPDATE_CALL(tms9928a);
400
 
        }
401
 
        else if (!strcmp(screen->tag(), "svi806"))
402
 
        {
403
 
                mc6845_device *mc6845 = screen->machine().device<mc6845_device>("crtc");
404
 
                mc6845->update(bitmap, cliprect);
405
 
        }
406
 
        else
407
 
        {
408
 
                fatalerror("Unknown screen '%s'", screen->tag());
409
 
        }
410
 
        return 0;
411
 
}
412
 
 
413
 
MACHINE_RESET( svi328_806 )
414
 
{
415
 
        svi318_state *state = machine.driver_data<svi318_state>();
416
 
        MACHINE_RESET_CALL(svi318);
417
 
 
418
 
        svi318_80col_init(machine);
419
 
        state->m_svi.svi806_present = 1;
420
 
        svi318_set_banks(machine);
421
 
 
422
 
        /* Set SVI-806 80 column card palette */
423
 
        palette_set_color_rgb( machine, TMS9928A_PALETTE_SIZE, 0, 0, 0 );               /* Monochrome black */
424
 
        palette_set_color_rgb( machine, TMS9928A_PALETTE_SIZE+1, 0, 224, 0 );   /* Monochrome green */
425
 
}
426
 
 
427
 
/* Init functions */
428
 
 
429
 
void svi318_vdp_interrupt(running_machine &machine, int i)
430
 
{
431
 
        cputag_set_input_line(machine, "maincpu", 0, (i ? HOLD_LINE : CLEAR_LINE));
432
 
}
433
 
 
434
 
 
435
 
static const UINT8 cc_op[0x100] = {
436
 
 4+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1, 4+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,
437
 
 8+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,12+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,
438
 
 7+1,10+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1, 7+1,11+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1,
439
 
 7+1,10+1,13+1, 6+1,11+1,11+1,10+1, 4+1, 7+1,11+1,13+1, 6+1, 4+1, 4+1, 7+1, 4+1,
440
 
 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
441
 
 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
442
 
 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
443
 
 7+1, 7+1, 7+1, 7+1, 7+1, 7+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
444
 
 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
445
 
 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
446
 
 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
447
 
 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1,
448
 
 5+1,10+1,10+1,10+1,10+1,11+1, 7+1,11+1, 5+1,10+1,10+1, 0+1,10+1,17+1, 7+1,11+1,
449
 
 5+1,10+1,10+1,11+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1,11+1,10+1, 0+1, 7+1,11+1,
450
 
 5+1,10+1,10+1,19+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1, 4+1,10+1, 0+1, 7+1,11+1,
451
 
 5+1,10+1,10+1, 4+1,10+1,11+1, 7+1,11+1, 5+1, 6+1,10+1, 4+1,10+1, 0+1, 7+1,11+1
452
 
};
453
 
 
454
 
static const UINT8 cc_cb[0x100] = {
455
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
456
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
457
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
458
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
459
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
460
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
461
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
462
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,12+2, 8+2,
463
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
464
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
465
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
466
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
467
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
468
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
469
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2,
470
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,15+2, 8+2
471
 
};
472
 
 
473
 
static const UINT8 cc_ed[0x100] = {
474
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
475
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
476
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
477
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
478
 
12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,
479
 
12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 9+2,
480
 
12+2,12+2,15+2,20+2, 8+2,14+2, 8+2,18+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2,18+2,
481
 
12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 8+2,12+2,12+2,15+2,20+2, 8+2,14+2, 8+2, 8+2,
482
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
483
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
484
 
16+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,16+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,
485
 
16+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,16+2,16+2,16+2,16+2, 8+2, 8+2, 8+2, 8+2,
486
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
487
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
488
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2,
489
 
 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2, 8+2
490
 
};
491
 
 
492
 
static const UINT8 cc_xy[0x100] = {
493
 
 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,15+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
494
 
 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,15+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
495
 
 4+2,14+2,20+2,10+2, 9+2, 9+2, 9+2, 4+2, 4+2,15+2,20+2,10+2, 9+2, 9+2, 9+2, 4+2,
496
 
 4+2, 4+2, 4+2, 4+2,23+2,23+2,19+2, 4+2, 4+2,15+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
497
 
 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
498
 
 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
499
 
 9+2, 9+2, 9+2, 9+2, 9+2, 9+2,19+2, 9+2, 9+2, 9+2, 9+2, 9+2, 9+2, 9+2,19+2, 9+2,
500
 
19+2,19+2,19+2,19+2,19+2,19+2, 4+2,19+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
501
 
 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
502
 
 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
503
 
 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
504
 
 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2, 4+2, 4+2, 4+2, 4+2, 9+2, 9+2,19+2, 4+2,
505
 
 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 0+2, 4+2, 4+2, 4+2, 4+2,
506
 
 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
507
 
 4+2,14+2, 4+2,23+2, 4+2,15+2, 4+2, 4+2, 4+2, 8+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,
508
 
 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2,10+2, 4+2, 4+2, 4+2, 4+2, 4+2, 4+2
509
 
};
510
 
 
511
 
static const UINT8 cc_xycb[0x100] = {
512
 
23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
513
 
23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
514
 
23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
515
 
23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
516
 
20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
517
 
20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
518
 
20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
519
 
20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,20+2,
520
 
23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
521
 
23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
522
 
23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
523
 
23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
524
 
23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
525
 
23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
526
 
23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,
527
 
23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2,23+2
528
 
};
529
 
 
530
 
/* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */
531
 
static const UINT8 cc_ex[0x100] = {
532
 
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
533
 
 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        /* DJNZ */
534
 
 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,        /* JR NZ/JR Z */
535
 
 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,        /* JR NC/JR C */
536
 
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
537
 
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
538
 
 0, 0, 0, 0, 0, 0, 0+1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
539
 
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
540
 
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
541
 
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
542
 
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
543
 
 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0,        /* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */
544
 
 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
545
 
 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
546
 
 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2,
547
 
 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2+1
548
 
};
549
 
 
550
 
 
551
 
DRIVER_INIT( svi318 )
552
 
{
553
 
        svi318_state *state = machine.driver_data<svi318_state>();
554
 
        /* z80 stuff */
555
 
        z80_set_cycle_tables( machine.device("maincpu"), cc_op, cc_cb, cc_ed, cc_xy, cc_xycb, cc_ex );
556
 
 
557
 
        memset(&state->m_svi, 0, sizeof (state->m_svi) );
558
 
 
559
 
        if ( ! strcmp( machine.system().name, "svi318" ) || ! strcmp( machine.system().name, "svi318n" ) )
560
 
        {
561
 
                state->m_svi.svi318 = 1;
562
 
        }
563
 
 
564
 
        device_set_input_line_vector(machine.device("maincpu"), 0, 0xff);
565
 
 
566
 
        /* memory */
567
 
        state->m_svi.empty_bank = auto_alloc_array(machine, UINT8, 0x8000);
568
 
        memset (state->m_svi.empty_bank, 0xff, 0x8000);
569
 
}
570
 
 
571
 
static const TMS9928a_interface svi318_tms9928a_interface =
572
 
{
573
 
        TMS99x8A,
574
 
        0x4000,
575
 
        15,
576
 
        15,
577
 
        svi318_vdp_interrupt
578
 
};
579
 
 
580
 
static const TMS9928a_interface svi318_tms9929a_interface =
581
 
{
582
 
        TMS9929A,
583
 
        0x4000,
584
 
        13,
585
 
        13,
586
 
        svi318_vdp_interrupt
587
 
};
588
 
 
589
 
MACHINE_START( svi318_ntsc )
590
 
{
591
 
        TMS9928A_configure(&svi318_tms9928a_interface);
592
 
}
593
 
 
594
 
MACHINE_START( svi318_pal )
595
 
{
596
 
        TMS9928A_configure(&svi318_tms9929a_interface);
597
 
}
598
 
 
599
 
static void svi318_load_proc(device_image_interface &image)
600
 
{
601
 
        svi318_state *state = image.device().machine().driver_data<svi318_state>();
602
 
        int size;
603
 
        int id = floppy_get_drive(&image.device());
604
 
 
605
 
        size = image.length();
606
 
        switch (size)
607
 
        {
608
 
        case 172032:    /* SVI-328 SSDD */
609
 
                state->m_fdc.heads[id] = 1;
610
 
                break;
611
 
        case 346112:    /* SVI-328 DSDD */
612
 
                state->m_fdc.heads[id] = 2;
613
 
                break;
614
 
        case 348160:    /* SVI-728 DSDD CP/M */
615
 
                state->m_fdc.heads[id] = 2;
616
 
                break;
617
 
        }
618
 
}
619
 
 
620
 
MACHINE_RESET( svi318 )
621
 
{
622
 
        svi318_state *state = machine.driver_data<svi318_state>();
623
 
        int drive;
624
 
        /* video stuff */
625
 
        TMS9928A_reset();
626
 
 
627
 
        state->m_svi.bank_switch = 0xff;
628
 
        svi318_set_banks(machine);
629
 
 
630
 
        for(drive=0;drive<2;drive++)
631
 
        {
632
 
                floppy_install_load_proc(floppy_get_device(machine, drive), svi318_load_proc);
633
 
        }
634
 
}
635
 
 
636
 
INTERRUPT_GEN( svi318_interrupt )
637
 
{
638
 
        int set;
639
 
 
640
 
        set = input_port_read(device->machine(), "CONFIG");
641
 
        TMS9928A_set_spriteslimit (set & 0x20);
642
 
        TMS9928A_interrupt(device->machine());
643
 
}
644
 
 
645
 
/* Memory */
646
 
 
647
 
WRITE8_HANDLER( svi318_writemem1 )
648
 
{
649
 
        svi318_state *state = space->machine().driver_data<svi318_state>();
650
 
        if ( state->m_svi.bankLow_read_only )
651
 
                return;
652
 
 
653
 
        state->m_svi.bankLow_ptr[offset] = data;
654
 
}
655
 
 
656
 
WRITE8_HANDLER( svi318_writemem2 )
657
 
{
658
 
        svi318_state *state = space->machine().driver_data<svi318_state>();
659
 
        if ( state->m_svi.bankHigh1_read_only)
660
 
                return;
661
 
 
662
 
        state->m_svi.bankHigh1_ptr[offset] = data;
663
 
}
664
 
 
665
 
WRITE8_HANDLER( svi318_writemem3 )
666
 
{
667
 
        svi318_state *state = space->machine().driver_data<svi318_state>();
668
 
        if ( state->m_svi.bankHigh2_read_only)
669
 
                return;
670
 
 
671
 
        state->m_svi.bankHigh2_ptr[offset] = data;
672
 
}
673
 
 
674
 
WRITE8_HANDLER( svi318_writemem4 )
675
 
{
676
 
        svi318_state *state = space->machine().driver_data<svi318_state>();
677
 
        if ( state->m_svi.svi806_ram_enabled )
678
 
        {
679
 
                if ( offset < 0x800 )
680
 
                {
681
 
                        state->m_svi.svi806_ram->u8(offset) = data;
682
 
                }
683
 
        }
684
 
        else
685
 
        {
686
 
                if ( state->m_svi.bankHigh2_read_only )
687
 
                        return;
688
 
 
689
 
                state->m_svi.bankHigh2_ptr[ 0x3000 + offset] = data;
690
 
        }
691
 
}
692
 
 
693
 
static void svi318_set_banks(running_machine &machine)
694
 
{
695
 
        svi318_state *state = machine.driver_data<svi318_state>();
696
 
        const UINT8 v = state->m_svi.bank_switch;
697
 
        UINT8 *ram = ram_get_ptr(machine.device(RAM_TAG));
698
 
        UINT32 ram_size = ram_get_size(machine.device(RAM_TAG));
699
 
 
700
 
        state->m_svi.bankLow = ( v & 1 ) ? ( ( v & 2 ) ? ( ( v & 8 ) ? SVI_INTERNAL : SVI_EXPRAM3 ) : SVI_EXPRAM2 ) : SVI_CART;
701
 
        state->m_svi.bankHigh1 = ( v & 4 ) ? ( ( v & 16 ) ? SVI_INTERNAL : SVI_EXPRAM3 ) : SVI_EXPRAM2;
702
 
 
703
 
        state->m_svi.bankLow_ptr = state->m_svi.empty_bank;
704
 
        state->m_svi.bankLow_read_only = 1;
705
 
 
706
 
        switch( state->m_svi.bankLow )
707
 
        {
708
 
        case SVI_INTERNAL:
709
 
                state->m_svi.bankLow_ptr = machine.region("maincpu")->base();
710
 
                break;
711
 
        case SVI_CART:
712
 
                if ( state->m_pcart )
713
 
                {
714
 
                        state->m_svi.bankLow_ptr = state->m_pcart;
715
 
                }
716
 
                break;
717
 
        case SVI_EXPRAM2:
718
 
                if ( ram_size >= 64 * 1024 )
719
 
                {
720
 
                        state->m_svi.bankLow_ptr = ram + ram_size - 64 * 1024;
721
 
                        state->m_svi.bankLow_read_only = 0;
722
 
                }
723
 
                break;
724
 
        case SVI_EXPRAM3:
725
 
                if ( ram_size > 128 * 1024 )
726
 
                {
727
 
                        state->m_svi.bankLow_ptr = ram + ram_size - 128 * 1024;
728
 
                        state->m_svi.bankLow_read_only = 0;
729
 
                }
730
 
                break;
731
 
        }
732
 
 
733
 
        state->m_svi.bankHigh1_ptr = state->m_svi.bankHigh2_ptr = state->m_svi.empty_bank;
734
 
        state->m_svi.bankHigh1_read_only = state->m_svi.bankHigh2_read_only = 1;
735
 
 
736
 
        switch( state->m_svi.bankHigh1 )
737
 
        {
738
 
        case SVI_INTERNAL:
739
 
                if ( ram_size == 16 * 1024 )
740
 
                {
741
 
                        state->m_svi.bankHigh2_ptr = ram;
742
 
                        state->m_svi.bankHigh2_read_only = 0;
743
 
                }
744
 
                else
745
 
                {
746
 
                        state->m_svi.bankHigh1_ptr = ram;
747
 
                        state->m_svi.bankHigh1_read_only = 0;
748
 
                        state->m_svi.bankHigh2_ptr = ram + 0x4000;
749
 
                        state->m_svi.bankHigh2_read_only = 0;
750
 
                }
751
 
                break;
752
 
        case SVI_EXPRAM2:
753
 
                if ( ram_size > 64 * 1024 )
754
 
                {
755
 
                        state->m_svi.bankHigh1_ptr = ram + ram_size - 64 * 1024 + 32 * 1024;
756
 
                        state->m_svi.bankHigh1_read_only = 0;
757
 
                        state->m_svi.bankHigh2_ptr = ram + ram_size - 64 * 1024 + 48 * 1024;
758
 
                        state->m_svi.bankHigh2_read_only = 0;
759
 
                }
760
 
                break;
761
 
        case SVI_EXPRAM3:
762
 
                if ( ram_size > 128 * 1024 )
763
 
                {
764
 
                        state->m_svi.bankHigh1_ptr = ram + ram_size - 128 * 1024 + 32 * 1024;
765
 
                        state->m_svi.bankHigh1_read_only = 0;
766
 
                        state->m_svi.bankHigh2_ptr = ram + ram_size - 128 * 1024 + 48 * 1024;
767
 
                        state->m_svi.bankHigh2_read_only = 0;
768
 
                }
769
 
                break;
770
 
        }
771
 
 
772
 
        /* Check for special CART based banking */
773
 
        if ( state->m_svi.bankLow == SVI_CART && ( v & 0xc0 ) != 0xc0 )
774
 
        {
775
 
                state->m_svi.bankHigh1_ptr = state->m_svi.empty_bank;
776
 
                state->m_svi.bankHigh1_read_only = 1;
777
 
                state->m_svi.bankHigh2_ptr = state->m_svi.empty_bank;
778
 
                state->m_svi.bankHigh2_read_only = 1;
779
 
                if ( state->m_pcart && ! ( v & 0x80 ) )
780
 
                {
781
 
                        state->m_svi.bankHigh2_ptr = state->m_pcart + 0x4000;
782
 
                }
783
 
                if ( state->m_pcart && ! ( v & 0x40 ) )
784
 
                {
785
 
                        state->m_svi.bankHigh1_ptr = state->m_pcart;
786
 
                }
787
 
        }
788
 
 
789
 
        memory_set_bankptr(machine, "bank1", state->m_svi.bankLow_ptr );
790
 
        memory_set_bankptr(machine, "bank2", state->m_svi.bankHigh1_ptr );
791
 
        memory_set_bankptr(machine, "bank3", state->m_svi.bankHigh2_ptr );
792
 
 
793
 
        /* SVI-806 80 column card specific banking */
794
 
        if ( state->m_svi.svi806_present )
795
 
        {
796
 
                if ( state->m_svi.svi806_ram_enabled )
797
 
                {
798
 
                        memory_set_bankptr(machine, "bank4", state->m_svi.svi806_ram );
799
 
                }
800
 
                else
801
 
                {
802
 
                        memory_set_bankptr(machine, "bank4", state->m_svi.bankHigh2_ptr + 0x3000 );
803
 
                }
804
 
        }
805
 
}
806
 
 
807
 
/* Cassette */
808
 
 
809
 
int svi318_cassette_present(running_machine &machine, int id)
810
 
{
811
 
        device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device<cassette_image_device>(CASSETTE_TAG));
812
 
 
813
 
        if ( image == NULL )
814
 
                return FALSE;
815
 
        return image->exists();
816
 
}
817
 
 
818
 
/* External I/O */
819
 
 
820
 
READ8_HANDLER( svi318_io_ext_r )
821
 
{
822
 
        svi318_state *state = space->machine().driver_data<svi318_state>();
823
 
        UINT8 data = 0xff;
824
 
        device_t *device;
825
 
 
826
 
        if (state->m_svi.bankLow == SVI_CART)
827
 
        {
828
 
                return 0xff;
829
 
        }
830
 
 
831
 
        switch( offset )
832
 
        {
833
 
        case 0x12:
834
 
                device = space->machine().device("centronics");
835
 
                data = 0xfe | centronics_busy_r(device);
836
 
                break;
837
 
 
838
 
        case 0x20:
839
 
        case 0x21:
840
 
        case 0x22:
841
 
        case 0x23:
842
 
        case 0x24:
843
 
        case 0x25:
844
 
        case 0x26:
845
 
        case 0x27:
846
 
                device = space->machine().device("ins8250_0");
847
 
                data = ins8250_r(device, offset & 7);
848
 
                break;
849
 
 
850
 
        case 0x28:
851
 
        case 0x29:
852
 
        case 0x2A:
853
 
        case 0x2B:
854
 
        case 0x2C:
855
 
        case 0x2D:
856
 
        case 0x2E:
857
 
        case 0x2F:
858
 
                device = space->machine().device("ins8250_1");
859
 
                data = ins8250_r(device, offset & 7);
860
 
                break;
861
 
 
862
 
        case 0x30:
863
 
                device = space->machine().device("wd179x");
864
 
                data = wd17xx_status_r(device, 0);
865
 
                break;
866
 
        case 0x31:
867
 
                device = space->machine().device("wd179x");
868
 
                data = wd17xx_track_r(device, 0);
869
 
                break;
870
 
        case 0x32:
871
 
                device = space->machine().device("wd179x");
872
 
                data = wd17xx_sector_r(device, 0);
873
 
                break;
874
 
        case 0x33:
875
 
                device = space->machine().device("wd179x");
876
 
                data = wd17xx_data_r(device, 0);
877
 
                break;
878
 
        case 0x34:
879
 
                data = svi318_fdc_irqdrq_r(space, 0);
880
 
                break;
881
 
        case 0x51:
882
 
                device = space->machine().device("crtc");
883
 
                data = downcast<mc6845_device *>(device)->register_r( *space, offset );
884
 
                break;
885
 
        }
886
 
 
887
 
        return data;
888
 
}
889
 
 
890
 
WRITE8_HANDLER( svi318_io_ext_w )
891
 
{
892
 
        svi318_state *state = space->machine().driver_data<svi318_state>();
893
 
        device_t *device;
894
 
 
895
 
        if (state->m_svi.bankLow == SVI_CART)
896
 
        {
897
 
                return;
898
 
        }
899
 
 
900
 
        switch( offset )
901
 
        {
902
 
        case 0x10:
903
 
                device = space->machine().device("centronics");
904
 
                centronics_data_w(device, 0, data);
905
 
                break;
906
 
 
907
 
        case 0x11:
908
 
                device = space->machine().device("centronics");
909
 
                centronics_strobe_w(device, BIT(data, 0));
910
 
                break;
911
 
 
912
 
        case 0x20:
913
 
        case 0x21:
914
 
        case 0x22:
915
 
        case 0x23:
916
 
        case 0x24:
917
 
        case 0x25:
918
 
        case 0x26:
919
 
        case 0x27:
920
 
                device = space->machine().device("ins8250_0");
921
 
                ins8250_w(device, offset & 7, data);
922
 
                break;
923
 
 
924
 
        case 0x28:
925
 
        case 0x29:
926
 
        case 0x2A:
927
 
        case 0x2B:
928
 
        case 0x2C:
929
 
        case 0x2D:
930
 
        case 0x2E:
931
 
        case 0x2F:
932
 
                device = space->machine().device("ins8250_1");
933
 
                ins8250_w(device, offset & 7, data);
934
 
                break;
935
 
 
936
 
        case 0x30:
937
 
                device = space->machine().device("wd179x");
938
 
                wd17xx_command_w(device, 0, data);
939
 
                break;
940
 
        case 0x31:
941
 
                device = space->machine().device("wd179x");
942
 
                wd17xx_track_w(device, 0, data);
943
 
                break;
944
 
        case 0x32:
945
 
                device = space->machine().device("wd179x");
946
 
                wd17xx_sector_w(device, 0, data);
947
 
                break;
948
 
        case 0x33:
949
 
                device = space->machine().device("wd179x");
950
 
                wd17xx_data_w(device, 0, data);
951
 
                break;
952
 
        case 0x34:
953
 
                svi318_fdc_drive_motor_w(space, 0, data);
954
 
                break;
955
 
        case 0x38:
956
 
                svi318_fdc_density_side_w(space, 0, data);
957
 
                break;
958
 
 
959
 
        case 0x50:
960
 
                device = space->machine().device("crtc");
961
 
                downcast<mc6845_device *>(device)->address_w(*space, offset, data);
962
 
                break;
963
 
        case 0x51:
964
 
                device = space->machine().device("crtc");
965
 
                downcast<mc6845_device *>(device)->register_w(*space, offset, data);
966
 
                break;
967
 
 
968
 
        case 0x58:
969
 
                svi806_ram_enable_w(space, 0, data);
970
 
                break;
971
 
        }
972
 
}