2
** Spectravideo SVI-318 and SVI-328
4
** Sean Young, Tomas Karlsson
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"
32
static void svi318_set_banks(running_machine &machine);
37
static WRITE_LINE_DEVICE_HANDLER( svi318_ins8250_interrupt )
39
svi318_state *drvstate = device->machine().driver_data<svi318_state>();
40
if (drvstate->m_svi.bankLow != SVI_CART)
42
cputag_set_input_line(device->machine(), "maincpu", 0, (state ? HOLD_LINE : CLEAR_LINE));
46
static INS8250_REFRESH_CONNECT( svi318_com_refresh_connected )
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);
52
const ins8250_interface svi318_ins8250_interface[2]=
56
DEVCB_LINE(svi318_ins8250_interrupt),
59
svi318_com_refresh_connected
63
DEVCB_LINE(svi318_ins8250_interrupt),
73
static int svi318_verify_cart (UINT8 magic[2])
75
/* read the first two bytes */
76
if ( (magic[0] == 0xf3) && (magic[1] == 0x31) )
77
return IMAGE_VERIFY_PASS;
79
return IMAGE_VERIFY_FAIL;
82
DEVICE_START( svi318_cart )
84
svi318_state *state = device->machine().driver_data<svi318_state>();
85
state->m_pcart = NULL;
86
state->m_pcart_rom_size = 0;
89
DEVICE_IMAGE_LOAD( svi318_cart )
91
svi318_state *state = image.device().machine().driver_data<svi318_state>();
92
UINT8 *p = image.device().machine().region("user1")->base();
95
if (image.software_entry() == NULL)
96
size = image.length();
98
size = image.get_software_region_length("rom");
101
logerror("Cart image %s larger than expected. Please report the issue.\n", image.filename());
103
if (image.software_entry() == NULL)
105
if (image.fread(p, size) != size)
107
logerror("Can't read file %s\n", image.filename());
108
return IMAGE_INIT_FAIL;
112
memcpy(p, image.get_software_region("rom"), size);
114
if (svi318_verify_cart(p) == IMAGE_VERIFY_FAIL)
115
return IMAGE_INIT_FAIL;
118
state->m_pcart_rom_size = size;
120
return IMAGE_INIT_PASS;
123
DEVICE_IMAGE_UNLOAD( svi318_cart )
125
svi318_state *state = image.device().machine().driver_data<svi318_state>();
126
state->m_pcart = NULL;
127
state->m_pcart_rom_size = 0;
133
PPI Port A Input (address 98H)
135
1 TA Joystick 1, /SENSE
137
3 TC Joystick 2, /SENSE
139
5 TRIGGER1 Joystick 1, Trigger
140
6 TRIGGER2 Joystick 2, Trigger
141
7 /READY Cassette, Ready
142
8 CASR Cassette, Read data
145
static READ8_DEVICE_HANDLER ( svi318_ppi_port_a_r )
149
if ((device->machine().device<cassette_image_device>(CASSETTE_TAG))->input() > 0.0038)
151
if (!svi318_cassette_present(device->machine(), 0))
153
data |= input_port_read(device->machine(), "BUTTONS") & 0x30;
159
PPI Port B Input (address 99H)
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
171
static READ8_DEVICE_HANDLER ( svi318_ppi_port_b_r )
173
svi318_state *state = device->machine().driver_data<svi318_state>();
175
static const char *const keynames[] = {
176
"LINE0", "LINE1", "LINE2", "LINE3", "LINE4", "LINE5",
177
"LINE6", "LINE7", "LINE8", "LINE9", "LINE10"
180
row = state->m_svi.keyboard_row;
182
return input_port_read(device->machine(), keynames[row]);
188
PPI Port C Output (address 97H)
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)
200
static WRITE8_DEVICE_HANDLER ( svi318_ppi_port_c_w )
202
svi318_state *state = device->machine().driver_data<svi318_state>();
206
val = (data & 0x80) ? 0x3e : 0;
207
val += (data & 0x40) ? 0x3e : 0;
208
dac_signed_data_w (device->machine().device("dac"), val);
210
/* cassette motor on/off */
211
if (svi318_cassette_present(device->machine(), 0))
214
device->machine().device<cassette_image_device>(CASSETTE_TAG)->change_state(
215
(data & 0x10) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED,
216
CASSETTE_MOTOR_DISABLED);
219
/* cassette signal write */
220
device->machine().device<cassette_image_device>(CASSETTE_TAG)->output((data & 0x20) ? -1.0 : +1.0);
222
state->m_svi.keyboard_row = data & 0x0F;
225
I8255_INTERFACE( svi318_ppi8255_interface )
227
DEVCB_HANDLER(svi318_ppi_port_a_r),
229
DEVCB_HANDLER(svi318_ppi_port_b_r),
232
DEVCB_HANDLER(svi318_ppi_port_c_w)
235
WRITE8_HANDLER( svi318_ppi_w )
237
i8255_device *ppi = space->machine().device<i8255_device>("ppi8255");
238
ppi->write(*space, offset + 2, data);
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
257
READ8_HANDLER( svi318_psg_port_a_r )
259
return input_port_read(space->machine(), "JOYSTICKS");
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)
274
* The /CART signal must be active for any effect and all banks
275
with RAM are disabled.
278
WRITE8_HANDLER( svi318_psg_port_b_w )
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) );
284
state->m_svi.bank_switch = data;
285
svi318_set_banks(space->machine());
290
static WRITE_LINE_DEVICE_HANDLER( svi_fdc_intrq_w )
292
svi318_state *drvstate = device->machine().driver_data<svi318_state>();
293
drvstate->m_fdc.irq = state;
296
static WRITE_LINE_DEVICE_HANDLER( svi_fdc_drq_w )
298
svi318_state *drvstate = device->machine().driver_data<svi318_state>();
299
drvstate->m_fdc.drq = state;
302
const wd17xx_interface svi_wd17xx_interface =
305
DEVCB_LINE(svi_fdc_intrq_w),
306
DEVCB_LINE(svi_fdc_drq_w),
307
{FLOPPY_0, FLOPPY_1, NULL, NULL}
310
static WRITE8_HANDLER( svi318_fdc_drive_motor_w )
312
svi318_state *state = space->machine().driver_data<svi318_state>();
313
device_t *fdc = space->machine().device("wd179x");
317
wd17xx_set_drive(fdc,0);
318
state->m_fdc.driveselect = 0;
321
wd17xx_set_drive(fdc,1);
322
state->m_fdc.driveselect = 1;
327
static WRITE8_HANDLER( svi318_fdc_density_side_w )
329
device_t *fdc = space->machine().device("wd179x");
331
wd17xx_dden_w(fdc, BIT(data, 0));
332
wd17xx_set_side(fdc, BIT(data, 1));
335
static READ8_HANDLER( svi318_fdc_irqdrq_r )
337
svi318_state *state = space->machine().driver_data<svi318_state>();
340
result |= state->m_fdc.drq << 6;
341
result |= state->m_fdc.irq << 7;
346
MC6845_UPDATE_ROW( svi806_crtc6845_update_row )
348
svi318_state *state = device->machine().driver_data<svi318_state>();
351
for( i = 0; i < x_count; i++ )
354
UINT8 data = state->m_svi.svi806_gfx[ state->m_svi.svi806_ram->u8(( ma + i ) & 0x7FF) * 16 + ra ];
361
for( j=0; j < 8; j++ )
363
*BITMAP_ADDR16(bitmap, y, i * 8 + j ) = TMS9928A_PALETTE_SIZE + ( ( data & 0x80 ) ? 1 : 0 );
370
/* 80 column card init */
371
static void svi318_80col_init(running_machine &machine)
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();
383
static WRITE8_HANDLER( svi806_ram_enable_w )
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());
390
VIDEO_START( svi328_806 )
392
VIDEO_START_CALL(tms9928a);
395
SCREEN_UPDATE( svi328_806 )
397
if (!strcmp(screen->tag(), "screen"))
399
SCREEN_UPDATE_CALL(tms9928a);
401
else if (!strcmp(screen->tag(), "svi806"))
403
mc6845_device *mc6845 = screen->machine().device<mc6845_device>("crtc");
404
mc6845->update(bitmap, cliprect);
408
fatalerror("Unknown screen '%s'", screen->tag());
413
MACHINE_RESET( svi328_806 )
415
svi318_state *state = machine.driver_data<svi318_state>();
416
MACHINE_RESET_CALL(svi318);
418
svi318_80col_init(machine);
419
state->m_svi.svi806_present = 1;
420
svi318_set_banks(machine);
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 */
429
void svi318_vdp_interrupt(running_machine &machine, int i)
431
cputag_set_input_line(machine, "maincpu", 0, (i ? HOLD_LINE : CLEAR_LINE));
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
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
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
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
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
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
551
DRIVER_INIT( svi318 )
553
svi318_state *state = machine.driver_data<svi318_state>();
555
z80_set_cycle_tables( machine.device("maincpu"), cc_op, cc_cb, cc_ed, cc_xy, cc_xycb, cc_ex );
557
memset(&state->m_svi, 0, sizeof (state->m_svi) );
559
if ( ! strcmp( machine.system().name, "svi318" ) || ! strcmp( machine.system().name, "svi318n" ) )
561
state->m_svi.svi318 = 1;
564
device_set_input_line_vector(machine.device("maincpu"), 0, 0xff);
567
state->m_svi.empty_bank = auto_alloc_array(machine, UINT8, 0x8000);
568
memset (state->m_svi.empty_bank, 0xff, 0x8000);
571
static const TMS9928a_interface svi318_tms9928a_interface =
580
static const TMS9928a_interface svi318_tms9929a_interface =
589
MACHINE_START( svi318_ntsc )
591
TMS9928A_configure(&svi318_tms9928a_interface);
594
MACHINE_START( svi318_pal )
596
TMS9928A_configure(&svi318_tms9929a_interface);
599
static void svi318_load_proc(device_image_interface &image)
601
svi318_state *state = image.device().machine().driver_data<svi318_state>();
603
int id = floppy_get_drive(&image.device());
605
size = image.length();
608
case 172032: /* SVI-328 SSDD */
609
state->m_fdc.heads[id] = 1;
611
case 346112: /* SVI-328 DSDD */
612
state->m_fdc.heads[id] = 2;
614
case 348160: /* SVI-728 DSDD CP/M */
615
state->m_fdc.heads[id] = 2;
620
MACHINE_RESET( svi318 )
622
svi318_state *state = machine.driver_data<svi318_state>();
627
state->m_svi.bank_switch = 0xff;
628
svi318_set_banks(machine);
630
for(drive=0;drive<2;drive++)
632
floppy_install_load_proc(floppy_get_device(machine, drive), svi318_load_proc);
636
INTERRUPT_GEN( svi318_interrupt )
640
set = input_port_read(device->machine(), "CONFIG");
641
TMS9928A_set_spriteslimit (set & 0x20);
642
TMS9928A_interrupt(device->machine());
647
WRITE8_HANDLER( svi318_writemem1 )
649
svi318_state *state = space->machine().driver_data<svi318_state>();
650
if ( state->m_svi.bankLow_read_only )
653
state->m_svi.bankLow_ptr[offset] = data;
656
WRITE8_HANDLER( svi318_writemem2 )
658
svi318_state *state = space->machine().driver_data<svi318_state>();
659
if ( state->m_svi.bankHigh1_read_only)
662
state->m_svi.bankHigh1_ptr[offset] = data;
665
WRITE8_HANDLER( svi318_writemem3 )
667
svi318_state *state = space->machine().driver_data<svi318_state>();
668
if ( state->m_svi.bankHigh2_read_only)
671
state->m_svi.bankHigh2_ptr[offset] = data;
674
WRITE8_HANDLER( svi318_writemem4 )
676
svi318_state *state = space->machine().driver_data<svi318_state>();
677
if ( state->m_svi.svi806_ram_enabled )
679
if ( offset < 0x800 )
681
state->m_svi.svi806_ram->u8(offset) = data;
686
if ( state->m_svi.bankHigh2_read_only )
689
state->m_svi.bankHigh2_ptr[ 0x3000 + offset] = data;
693
static void svi318_set_banks(running_machine &machine)
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));
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;
703
state->m_svi.bankLow_ptr = state->m_svi.empty_bank;
704
state->m_svi.bankLow_read_only = 1;
706
switch( state->m_svi.bankLow )
709
state->m_svi.bankLow_ptr = machine.region("maincpu")->base();
712
if ( state->m_pcart )
714
state->m_svi.bankLow_ptr = state->m_pcart;
718
if ( ram_size >= 64 * 1024 )
720
state->m_svi.bankLow_ptr = ram + ram_size - 64 * 1024;
721
state->m_svi.bankLow_read_only = 0;
725
if ( ram_size > 128 * 1024 )
727
state->m_svi.bankLow_ptr = ram + ram_size - 128 * 1024;
728
state->m_svi.bankLow_read_only = 0;
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;
736
switch( state->m_svi.bankHigh1 )
739
if ( ram_size == 16 * 1024 )
741
state->m_svi.bankHigh2_ptr = ram;
742
state->m_svi.bankHigh2_read_only = 0;
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;
753
if ( ram_size > 64 * 1024 )
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;
762
if ( ram_size > 128 * 1024 )
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;
772
/* Check for special CART based banking */
773
if ( state->m_svi.bankLow == SVI_CART && ( v & 0xc0 ) != 0xc0 )
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 ) )
781
state->m_svi.bankHigh2_ptr = state->m_pcart + 0x4000;
783
if ( state->m_pcart && ! ( v & 0x40 ) )
785
state->m_svi.bankHigh1_ptr = state->m_pcart;
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 );
793
/* SVI-806 80 column card specific banking */
794
if ( state->m_svi.svi806_present )
796
if ( state->m_svi.svi806_ram_enabled )
798
memory_set_bankptr(machine, "bank4", state->m_svi.svi806_ram );
802
memory_set_bankptr(machine, "bank4", state->m_svi.bankHigh2_ptr + 0x3000 );
809
int svi318_cassette_present(running_machine &machine, int id)
811
device_image_interface *image = dynamic_cast<device_image_interface *>(machine.device<cassette_image_device>(CASSETTE_TAG));
815
return image->exists();
820
READ8_HANDLER( svi318_io_ext_r )
822
svi318_state *state = space->machine().driver_data<svi318_state>();
826
if (state->m_svi.bankLow == SVI_CART)
834
device = space->machine().device("centronics");
835
data = 0xfe | centronics_busy_r(device);
846
device = space->machine().device("ins8250_0");
847
data = ins8250_r(device, offset & 7);
858
device = space->machine().device("ins8250_1");
859
data = ins8250_r(device, offset & 7);
863
device = space->machine().device("wd179x");
864
data = wd17xx_status_r(device, 0);
867
device = space->machine().device("wd179x");
868
data = wd17xx_track_r(device, 0);
871
device = space->machine().device("wd179x");
872
data = wd17xx_sector_r(device, 0);
875
device = space->machine().device("wd179x");
876
data = wd17xx_data_r(device, 0);
879
data = svi318_fdc_irqdrq_r(space, 0);
882
device = space->machine().device("crtc");
883
data = downcast<mc6845_device *>(device)->register_r( *space, offset );
890
WRITE8_HANDLER( svi318_io_ext_w )
892
svi318_state *state = space->machine().driver_data<svi318_state>();
895
if (state->m_svi.bankLow == SVI_CART)
903
device = space->machine().device("centronics");
904
centronics_data_w(device, 0, data);
908
device = space->machine().device("centronics");
909
centronics_strobe_w(device, BIT(data, 0));
920
device = space->machine().device("ins8250_0");
921
ins8250_w(device, offset & 7, data);
932
device = space->machine().device("ins8250_1");
933
ins8250_w(device, offset & 7, data);
937
device = space->machine().device("wd179x");
938
wd17xx_command_w(device, 0, data);
941
device = space->machine().device("wd179x");
942
wd17xx_track_w(device, 0, data);
945
device = space->machine().device("wd179x");
946
wd17xx_sector_w(device, 0, data);
949
device = space->machine().device("wd179x");
950
wd17xx_data_w(device, 0, data);
953
svi318_fdc_drive_motor_w(space, 0, data);
956
svi318_fdc_density_side_w(space, 0, data);
960
device = space->machine().device("crtc");
961
downcast<mc6845_device *>(device)->address_w(*space, offset, data);
964
device = space->machine().device("crtc");
965
downcast<mc6845_device *>(device)->register_w(*space, offset, data);
969
svi806_ram_enable_w(space, 0, data);