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

« back to all changes in this revision

Viewing changes to mess/src/mess/drivers/vtech1.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
 
Video Technology Laser 110-310 computers:
4
 
 
5
 
    Video Technology Laser 110
6
 
      Sanyo Laser 110
7
 
    Video Technology Laser 200
8
 
      Salora Fellow
9
 
      Texet TX-8000
10
 
      Video Technology VZ-200
11
 
    Video Technology Laser 210
12
 
      Dick Smith Electronics VZ-200
13
 
      Sanyo Laser 210
14
 
    Video Technology Laser 310
15
 
      Dick Smith Electronics VZ-300
16
 
 
17
 
System driver:
18
 
 
19
 
    Juergen Buchmueller <pullmoll@t-online.de>, Dec 1999
20
 
      - everything
21
 
 
22
 
    Dirk Best <duke@redump.de>, May 2004
23
 
      - clean up
24
 
      - fixed parent/clone relationsips and memory size for the Laser 200
25
 
      - fixed loading of the DOS ROM
26
 
      - added BASIC V2.1
27
 
      - added SHA1 checksums
28
 
 
29
 
    Dirk Best <duke@redump.de>, March 2006
30
 
      - 64KB memory expansion (banked)
31
 
      - cartridge support
32
 
 
33
 
Thanks go to:
34
 
 
35
 
    - Guy Thomason
36
 
    - Jason Oakley
37
 
    - Bushy Maunder
38
 
    - and anybody else on the vzemu list :)
39
 
    - Davide Moretti for the detailed description of the colors
40
 
    - Leslie Milburn
41
 
 
42
 
Memory maps:
43
 
 
44
 
    Laser 110/200
45
 
        0000-1FFF 8K ROM 0
46
 
        2000-3FFF 8K ROM 1
47
 
        4000-5FFF 8K DOS ROM or other cartridges (optional)
48
 
        6000-67FF 2K reserved for rom cartridges
49
 
        6800-6FFF 2K memory mapped I/O
50
 
                    R: keyboard
51
 
                    W: cassette I/O, speaker, VDP control
52
 
        7000-77FF 2K video RAM
53
 
        7800-7FFF 2K internal user RAM
54
 
        8800-C7FF 16K memory expansion
55
 
        8000-BFFF 64K memory expansion, first bank
56
 
        C000-FFFF 64K memory expansion, other banks
57
 
 
58
 
    Laser 210
59
 
        0000-1FFF 8K ROM 0
60
 
        2000-3FFF 8K ROM 1
61
 
        4000-5FFF 8K DOS ROM or other cartridges (optional)
62
 
        6000-67FF 2K reserved for rom cartridges
63
 
        6800-6FFF 2K memory mapped I/O
64
 
                    R: keyboard
65
 
                    W: cassette I/O, speaker, VDP control
66
 
        7000-77FF 2K video RAM
67
 
        7800-8FFF 6K internal user RAM (3x2K: U2, U3, U4)
68
 
        9000-CFFF 16K memory expansion
69
 
        8000-BFFF 64K memory expansion, first bank
70
 
        C000-FFFF 64K memory expansion, other banks
71
 
 
72
 
    Laser 310
73
 
        0000-3FFF 16K ROM
74
 
        4000-5FFF 8K DOS ROM or other cartridges (optional)
75
 
        6000-67FF 2K reserved for rom cartridges
76
 
        6800-6FFF 2K memory mapped I/O
77
 
                    R: keyboard
78
 
                    W: cassette I/O, speaker, VDP control
79
 
        7000-77FF 2K video RAM
80
 
        7800-B7FF 16K internal user RAM
81
 
        B800-F7FF 16K memory expansion
82
 
        8000-BFFF 64K memory expansion, first bank
83
 
        C000-FFFF 64K memory expansion, other banks
84
 
 
85
 
 
86
 
   Memory expansions available for the Laser/VZ computers:
87
 
 
88
 
   - a 16kb expansion without banking
89
 
   - a 64kb expansion where the first bank is fixed and the other 3 are
90
 
     banked in as needed
91
 
   - a banked memory expansion similar to the 64kb one, that the user could
92
 
     fill themselves with memory up to 4MB total.
93
 
 
94
 
   They are externally connected devices. The 16kb extension is different
95
 
   between Laser 110/210/310 computers, though it could be relativly
96
 
   easily modified to work on another model.
97
 
 
98
 
 
99
 
Todo:
100
 
 
101
 
    - Figure out which machines were shipped with which ROM version
102
 
      where not known (currently only a guess)
103
 
    - Lightpen support
104
 
    - Rewrite floppy and move to its own file
105
 
 
106
 
Notes:
107
 
 
108
 
    - The only known dumped cartridge is the DOS ROM:
109
 
      CRC(b6ed6084) SHA1(59d1cbcfa6c5e1906a32704fbf0d9670f0d1fd8b)
110
 
 
111
 
 
112
 
******************************************************************************/
113
 
 
114
 
#include "emu.h"
115
 
#include "formats/imageutl.h"
116
 
#include "cpu/z80/z80.h"
117
 
#include "video/m6847.h"
118
 
#include "machine/ctronics.h"
119
 
#include "sound/wave.h"
120
 
#include "sound/speaker.h"
121
 
#include "imagedev/cartslot.h"
122
 
#include "imagedev/flopdrv.h"
123
 
#include "imagedev/snapquik.h"
124
 
#include "imagedev/cassette.h"
125
 
#include "machine/ram.h"
126
 
#include "formats/vt_cas.h"
127
 
#include "formats/vtech1_dsk.h"
128
 
 
129
 
/***************************************************************************
130
 
    CONSTANTS & MACROS
131
 
***************************************************************************/
132
 
 
133
 
#define LOG_VTECH1_LATCH 0
134
 
#define LOG_VTECH1_FDC   0
135
 
 
136
 
#define VTECH1_CLK        3579500
137
 
#define VZ300_XTAL1_CLK   XTAL_17_73447MHz
138
 
 
139
 
#define VZ_BASIC 0xf0
140
 
#define VZ_MCODE 0xf1
141
 
 
142
 
#define TRKSIZE_VZ      0x9b0   /* arbitrary (actually from analyzing format) */
143
 
#define TRKSIZE_FM      3172    /* size of a standard FM mode track */
144
 
 
145
 
#define PHI0(n) (((n)>>0)&1)
146
 
#define PHI1(n) (((n)>>1)&1)
147
 
#define PHI2(n) (((n)>>2)&1)
148
 
#define PHI3(n) (((n)>>3)&1)
149
 
 
150
 
 
151
 
/***************************************************************************
152
 
    TYPE DEFINITIONS
153
 
***************************************************************************/
154
 
 
155
 
class vtech1_state : public driver_device
156
 
{
157
 
public:
158
 
        vtech1_state(const machine_config &mconfig, device_type type, const char *tag)
159
 
                : driver_device(mconfig, type, tag) { }
160
 
 
161
 
        /* devices */
162
 
        device_t *m_mc6847;
163
 
        device_t *m_speaker;
164
 
        cassette_image_device *m_cassette;
165
 
        device_t *m_printer;
166
 
 
167
 
        UINT8 *m_ram;
168
 
        UINT32 m_ram_size;
169
 
        UINT8 *m_videoram;
170
 
        size_t m_videoram_size;
171
 
 
172
 
        /* floppy */
173
 
        int m_drive;
174
 
        UINT8 m_fdc_track_x2[2];
175
 
        UINT8 m_fdc_wrprot[2];
176
 
        UINT8 m_fdc_status;
177
 
        UINT8 m_fdc_data[TRKSIZE_FM];
178
 
        int m_data;
179
 
        int m_fdc_edge;
180
 
        int m_fdc_bits;
181
 
        int m_fdc_start;
182
 
        int m_fdc_write;
183
 
        int m_fdc_offs;
184
 
        int m_fdc_latch;
185
 
};
186
 
 
187
 
 
188
 
/***************************************************************************
189
 
    SNAPSHOT LOADING
190
 
***************************************************************************/
191
 
 
192
 
static SNAPSHOT_LOAD( vtech1 )
193
 
{
194
 
        vtech1_state *vtech1 = image.device().machine().driver_data<vtech1_state>();
195
 
        address_space *space = image.device().machine().device("maincpu")->memory().space(AS_PROGRAM);
196
 
        UINT8 i, header[24];
197
 
        UINT16 start, end, size;
198
 
        char pgmname[18];
199
 
 
200
 
        /* get the header */
201
 
        image.fread( &header, sizeof(header));
202
 
        for (i = 0; i < 16; i++) pgmname[i] = header[i+4];
203
 
        pgmname[16] = '\0';
204
 
 
205
 
        /* get start and end addresses */
206
 
        start = pick_integer_le(header, 22, 2);
207
 
        end = start + snapshot_size - sizeof(header);
208
 
        size = end - start;
209
 
 
210
 
        /* check if we have enough ram */
211
 
        if (vtech1->m_ram_size < size)
212
 
        {
213
 
                char message[256];
214
 
                snprintf(message, ARRAY_LENGTH(message), "SNAPLOAD: %s\nInsufficient RAM - need %04X",pgmname,size);
215
 
                image.seterror(IMAGE_ERROR_INVALIDIMAGE, message);
216
 
                image.message("SNAPLOAD: %s\nInsufficient RAM - need %04X",pgmname,size);
217
 
                return IMAGE_INIT_FAIL;
218
 
        }
219
 
 
220
 
        /* write it to ram */
221
 
        image.fread( &vtech1->m_ram[start - 0x7800], size);
222
 
 
223
 
        /* patch variables depending on snapshot type */
224
 
        switch (header[21])
225
 
        {
226
 
        case VZ_BASIC:          /* 0xF0 */
227
 
                space->write_byte(0x78a4, start % 256); /* start of basic program */
228
 
                space->write_byte(0x78a5, start / 256);
229
 
                space->write_byte(0x78f9, end % 256); /* end of basic program */
230
 
                space->write_byte(0x78fa, end / 256);
231
 
                space->write_byte(0x78fb, end % 256); /* start variable table */
232
 
                space->write_byte(0x78fc, end / 256);
233
 
                space->write_byte(0x78fd, end % 256); /* start free mem, end variable table */
234
 
                space->write_byte(0x78fe, end / 256);
235
 
                image.message(" %s (B)\nsize=%04X : start=%04X : end=%04X",pgmname,size,start,end);
236
 
                break;
237
 
 
238
 
        case VZ_MCODE:          /* 0xF1 */
239
 
                space->write_byte(0x788e, start % 256); /* usr subroutine address */
240
 
                space->write_byte(0x788f, start / 256);
241
 
                image.message(" %s (M)\nsize=%04X : start=%04X : end=%04X",pgmname,size,start,end);
242
 
                cpu_set_reg(image.device().machine().device("maincpu"), STATE_GENPC, start);                            /* start program */
243
 
                break;
244
 
 
245
 
        default:
246
 
                image.seterror(IMAGE_ERROR_UNSUPPORTED, "Snapshot format not supported.");
247
 
                image.message("Snapshot format not supported.");
248
 
                return IMAGE_INIT_FAIL;
249
 
        }
250
 
 
251
 
        return IMAGE_INIT_PASS;
252
 
}
253
 
 
254
 
 
255
 
/***************************************************************************
256
 
    FLOPPY DRIVE
257
 
***************************************************************************/
258
 
static void vtech1_load_proc(device_image_interface &image)
259
 
{
260
 
        vtech1_state *vtech1 = image.device().machine().driver_data<vtech1_state>();
261
 
        int id = floppy_get_drive(&image.device());
262
 
 
263
 
        if (!image.is_readonly())
264
 
                vtech1->m_fdc_wrprot[id] = 0x00;
265
 
        else
266
 
                vtech1->m_fdc_wrprot[id] = 0x80;
267
 
}
268
 
 
269
 
static void vtech1_get_track(running_machine &machine)
270
 
{
271
 
        vtech1_state *vtech1 = machine.driver_data<vtech1_state>();
272
 
        device_image_interface *image = dynamic_cast<device_image_interface *>(floppy_get_device(machine,vtech1->m_drive));
273
 
 
274
 
        /* drive selected or and image file ok? */
275
 
        if (vtech1->m_drive >= 0 && image->exists())
276
 
        {
277
 
                int size, offs;
278
 
                size = TRKSIZE_VZ;
279
 
                offs = TRKSIZE_VZ * vtech1->m_fdc_track_x2[vtech1->m_drive]/2;
280
 
                image->fseek(offs, SEEK_SET);
281
 
                size = image->fread(vtech1->m_fdc_data, size);
282
 
                if (LOG_VTECH1_FDC)
283
 
                        logerror("get track @$%05x $%04x bytes\n", offs, size);
284
 
        }
285
 
        vtech1->m_fdc_offs = 0;
286
 
        vtech1->m_fdc_write = 0;
287
 
}
288
 
 
289
 
static void vtech1_put_track(running_machine &machine)
290
 
{
291
 
        vtech1_state *vtech1 = machine.driver_data<vtech1_state>();
292
 
 
293
 
 
294
 
    /* drive selected and image file ok? */
295
 
        if (vtech1->m_drive >= 0 && floppy_get_device(machine,vtech1->m_drive) != NULL)
296
 
        {
297
 
                int size, offs;
298
 
                device_image_interface *image = dynamic_cast<device_image_interface *>(floppy_get_device(machine,vtech1->m_drive));
299
 
                offs = TRKSIZE_VZ * vtech1->m_fdc_track_x2[vtech1->m_drive]/2;
300
 
                image->fseek(offs + vtech1->m_fdc_start, SEEK_SET);
301
 
                size = image->fwrite(&vtech1->m_fdc_data[vtech1->m_fdc_start], vtech1->m_fdc_write);
302
 
                if (LOG_VTECH1_FDC)
303
 
                        logerror("put track @$%05X+$%X $%04X/$%04X bytes\n", offs, vtech1->m_fdc_start, size, vtech1->m_fdc_write);
304
 
        }
305
 
}
306
 
 
307
 
static READ8_HANDLER( vtech1_fdc_r )
308
 
{
309
 
        vtech1_state *vtech1 = space->machine().driver_data<vtech1_state>();
310
 
        int data = 0xff;
311
 
 
312
 
        switch (offset)
313
 
        {
314
 
        case 1: /* data (read-only) */
315
 
                if (vtech1->m_fdc_bits > 0)
316
 
                {
317
 
                        if( vtech1->m_fdc_status & 0x80 )
318
 
                                vtech1->m_fdc_bits--;
319
 
                        data = (vtech1->m_data >> vtech1->m_fdc_bits) & 0xff;
320
 
                        if (LOG_VTECH1_FDC) {
321
 
                                logerror("vtech1_fdc_r bits %d%d%d%d%d%d%d%d\n",
322
 
                                        (data>>7)&1,(data>>6)&1,(data>>5)&1,(data>>4)&1,
323
 
                                        (data>>3)&1,(data>>2)&1,(data>>1)&1,(data>>0)&1 );
324
 
                        }
325
 
                }
326
 
                if (vtech1->m_fdc_bits == 0)
327
 
                {
328
 
                        vtech1->m_data = vtech1->m_fdc_data[vtech1->m_fdc_offs];
329
 
                        if (LOG_VTECH1_FDC)
330
 
                                logerror("vtech1_fdc_r %d : data ($%04X) $%02X\n", offset, vtech1->m_fdc_offs, vtech1->m_data);
331
 
                        if(vtech1->m_fdc_status & 0x80)
332
 
                        {
333
 
                                vtech1->m_fdc_bits = 8;
334
 
                                vtech1->m_fdc_offs = (vtech1->m_fdc_offs + 1) % TRKSIZE_FM;
335
 
                        }
336
 
                        vtech1->m_fdc_status &= ~0x80;
337
 
                }
338
 
                break;
339
 
        case 2: /* polling (read-only) */
340
 
                /* fake */
341
 
                if (vtech1->m_drive >= 0)
342
 
                        vtech1->m_fdc_status |= 0x80;
343
 
                data = vtech1->m_fdc_status;
344
 
                break;
345
 
        case 3: /* write protect status (read-only) */
346
 
                if (vtech1->m_drive >= 0)
347
 
                        data = vtech1->m_fdc_wrprot[vtech1->m_drive];
348
 
                if (LOG_VTECH1_FDC)
349
 
                        logerror("vtech1_fdc_r %d : write_protect $%02X\n", offset, data);
350
 
                break;
351
 
        }
352
 
        return data;
353
 
}
354
 
 
355
 
static WRITE8_HANDLER( vtech1_fdc_w )
356
 
{
357
 
        vtech1_state *vtech1 = space->machine().driver_data<vtech1_state>();
358
 
        int drive;
359
 
 
360
 
        switch (offset)
361
 
        {
362
 
        case 0: /* latch (write-only) */
363
 
                drive = (data & 0x10) ? 0 : (data & 0x80) ? 1 : -1;
364
 
                if (drive != vtech1->m_drive)
365
 
                {
366
 
                        vtech1->m_drive = drive;
367
 
                        if (vtech1->m_drive >= 0)
368
 
                                vtech1_get_track(space->machine());
369
 
                }
370
 
                if (vtech1->m_drive >= 0)
371
 
                {
372
 
                        if ((PHI0(data) && !(PHI1(data) || PHI2(data) || PHI3(data)) && PHI1(vtech1->m_fdc_latch)) ||
373
 
                                (PHI1(data) && !(PHI0(data) || PHI2(data) || PHI3(data)) && PHI2(vtech1->m_fdc_latch)) ||
374
 
                                (PHI2(data) && !(PHI0(data) || PHI1(data) || PHI3(data)) && PHI3(vtech1->m_fdc_latch)) ||
375
 
                                (PHI3(data) && !(PHI0(data) || PHI1(data) || PHI2(data)) && PHI0(vtech1->m_fdc_latch)))
376
 
                        {
377
 
                                if (vtech1->m_fdc_track_x2[vtech1->m_drive] > 0)
378
 
                                        vtech1->m_fdc_track_x2[vtech1->m_drive]--;
379
 
                                if (LOG_VTECH1_FDC)
380
 
                                        logerror("vtech1_fdc_w(%d) $%02X drive %d: stepout track #%2d.%d\n", offset, data, vtech1->m_drive, vtech1->m_fdc_track_x2[vtech1->m_drive]/2,5*(vtech1->m_fdc_track_x2[vtech1->m_drive]&1));
381
 
                                if ((vtech1->m_fdc_track_x2[vtech1->m_drive] & 1) == 0)
382
 
                                        vtech1_get_track(space->machine());
383
 
                        }
384
 
                        else
385
 
                        if ((PHI0(data) && !(PHI1(data) || PHI2(data) || PHI3(data)) && PHI3(vtech1->m_fdc_latch)) ||
386
 
                                (PHI1(data) && !(PHI0(data) || PHI2(data) || PHI3(data)) && PHI0(vtech1->m_fdc_latch)) ||
387
 
                                (PHI2(data) && !(PHI0(data) || PHI1(data) || PHI3(data)) && PHI1(vtech1->m_fdc_latch)) ||
388
 
                                (PHI3(data) && !(PHI0(data) || PHI1(data) || PHI2(data)) && PHI2(vtech1->m_fdc_latch)))
389
 
                        {
390
 
                                if (vtech1->m_fdc_track_x2[vtech1->m_drive] < 2*40)
391
 
                                        vtech1->m_fdc_track_x2[vtech1->m_drive]++;
392
 
                                if (LOG_VTECH1_FDC)
393
 
                                        logerror("vtech1_fdc_w(%d) $%02X drive %d: stepin track #%2d.%d\n", offset, data, vtech1->m_drive, vtech1->m_fdc_track_x2[vtech1->m_drive]/2,5*(vtech1->m_fdc_track_x2[vtech1->m_drive]&1));
394
 
                                if ((vtech1->m_fdc_track_x2[vtech1->m_drive] & 1) == 0)
395
 
                                        vtech1_get_track(space->machine());
396
 
                        }
397
 
                        if ((data & 0x40) == 0)
398
 
                        {
399
 
                                vtech1->m_data <<= 1;
400
 
                                if ((vtech1->m_fdc_latch ^ data) & 0x20)
401
 
                                        vtech1->m_data |= 1;
402
 
                                if ((vtech1->m_fdc_edge ^= 1) == 0)
403
 
                                {
404
 
                                        vtech1->m_fdc_bits--;
405
 
 
406
 
                                        if (vtech1->m_fdc_bits == 0)
407
 
                                        {
408
 
                                                UINT8 value = 0;
409
 
                                                vtech1->m_data &= 0xffff;
410
 
                                                if (vtech1->m_data & 0x4000 ) value |= 0x80;
411
 
                                                if (vtech1->m_data & 0x1000 ) value |= 0x40;
412
 
                                                if (vtech1->m_data & 0x0400 ) value |= 0x20;
413
 
                                                if (vtech1->m_data & 0x0100 ) value |= 0x10;
414
 
                                                if (vtech1->m_data & 0x0040 ) value |= 0x08;
415
 
                                                if (vtech1->m_data & 0x0010 ) value |= 0x04;
416
 
                                                if (vtech1->m_data & 0x0004 ) value |= 0x02;
417
 
                                                if (vtech1->m_data & 0x0001 ) value |= 0x01;
418
 
                                                if (LOG_VTECH1_FDC)
419
 
                                                        logerror("vtech1_fdc_w(%d) data($%04X) $%02X <- $%02X ($%04X)\n", offset, vtech1->m_fdc_offs, vtech1->m_fdc_data[vtech1->m_fdc_offs], value, vtech1->m_data);
420
 
                                                vtech1->m_fdc_data[vtech1->m_fdc_offs] = value;
421
 
                                                vtech1->m_fdc_offs = (vtech1->m_fdc_offs + 1) % TRKSIZE_FM;
422
 
                                                vtech1->m_fdc_write++;
423
 
                                                vtech1->m_fdc_bits = 8;
424
 
                                        }
425
 
                                }
426
 
                        }
427
 
                        /* change of write signal? */
428
 
                        if ((vtech1->m_fdc_latch ^ data) & 0x40)
429
 
                        {
430
 
                                /* falling edge? */
431
 
                                if (vtech1->m_fdc_latch & 0x40)
432
 
                                {
433
 
                                        vtech1->m_fdc_start = vtech1->m_fdc_offs;
434
 
                                        vtech1->m_fdc_edge = 0;
435
 
                                }
436
 
                                else
437
 
                                {
438
 
                                        /* data written to track before? */
439
 
                                        if (vtech1->m_fdc_write)
440
 
                                                vtech1_put_track(space->machine());
441
 
                                }
442
 
                                vtech1->m_fdc_bits = 8;
443
 
                                vtech1->m_fdc_write = 0;
444
 
                        }
445
 
                }
446
 
                vtech1->m_fdc_latch = data;
447
 
                break;
448
 
        }
449
 
}
450
 
 
451
 
static const floppy_interface vtech1_floppy_interface =
452
 
{
453
 
        DEVCB_NULL,
454
 
        DEVCB_NULL,
455
 
        DEVCB_NULL,
456
 
        DEVCB_NULL,
457
 
        DEVCB_NULL,
458
 
        FLOPPY_STANDARD_5_25_DSHD,
459
 
        FLOPPY_OPTIONS_NAME(vtech1_only),
460
 
        NULL,
461
 
        NULL
462
 
};
463
 
 
464
 
/***************************************************************************
465
 
    PRINTER
466
 
***************************************************************************/
467
 
 
468
 
static READ8_DEVICE_HANDLER( vtech1_printer_r )
469
 
{
470
 
        return 0xfe | centronics_busy_r(device);
471
 
}
472
 
 
473
 
/* TODO: figure out how this really works */
474
 
static WRITE8_DEVICE_HANDLER( vtech1_strobe_w )
475
 
{
476
 
        centronics_strobe_w(device, TRUE);
477
 
        centronics_strobe_w(device, FALSE);
478
 
}
479
 
 
480
 
 
481
 
/***************************************************************************
482
 
    RS232 SERIAL
483
 
***************************************************************************/
484
 
 
485
 
static READ8_HANDLER( vtech1_serial_r )
486
 
{
487
 
        logerror("vtech1_serial_r offset $%02x\n", offset);
488
 
        return 0xff;
489
 
}
490
 
 
491
 
static WRITE8_HANDLER( vtech1_serial_w )
492
 
{
493
 
        logerror("vtech1_serial_w $%02x, offset %02x\n", data, offset);
494
 
}
495
 
 
496
 
 
497
 
/***************************************************************************
498
 
    INPUTS
499
 
***************************************************************************/
500
 
 
501
 
static READ8_HANDLER( vtech1_lightpen_r )
502
 
{
503
 
        logerror("vtech1_lightpen_r(%d)\n", offset);
504
 
        return 0xff;
505
 
}
506
 
 
507
 
static READ8_HANDLER( vtech1_joystick_r )
508
 
{
509
 
        int result = 0xff;
510
 
 
511
 
        if (!BIT(offset, 0)) result &= input_port_read(space->machine(), "joystick_0");
512
 
        if (!BIT(offset, 1)) result &= input_port_read(space->machine(), "joystick_0_arm");
513
 
        if (!BIT(offset, 2)) result &= input_port_read(space->machine(), "joystick_1");
514
 
        if (!BIT(offset, 3)) result &= input_port_read(space->machine(), "joystick_1_arm");
515
 
 
516
 
        return result;
517
 
}
518
 
 
519
 
static READ8_HANDLER( vtech1_keyboard_r )
520
 
{
521
 
        vtech1_state *vtech1 = space->machine().driver_data<vtech1_state>();
522
 
        UINT8 result = 0x3f;
523
 
 
524
 
        /* bit 0 to 5, keyboard input */
525
 
        if (!BIT(offset, 0)) result &= input_port_read(space->machine(), "keyboard_0");
526
 
        if (!BIT(offset, 1)) result &= input_port_read(space->machine(), "keyboard_1");
527
 
        if (!BIT(offset, 2)) result &= input_port_read(space->machine(), "keyboard_2");
528
 
        if (!BIT(offset, 3)) result &= input_port_read(space->machine(), "keyboard_3");
529
 
        if (!BIT(offset, 4)) result &= input_port_read(space->machine(), "keyboard_4");
530
 
        if (!BIT(offset, 5)) result &= input_port_read(space->machine(), "keyboard_5");
531
 
        if (!BIT(offset, 6)) result &= input_port_read(space->machine(), "keyboard_6");
532
 
        if (!BIT(offset, 7)) result &= input_port_read(space->machine(), "keyboard_7");
533
 
 
534
 
        /* bit 6, cassette input */
535
 
        result |= ((vtech1->m_cassette->input()) > 0 ? 1 : 0) << 6;
536
 
 
537
 
        /* bit 7, field sync */
538
 
        result |= mc6847_fs_r(vtech1->m_mc6847) << 7;
539
 
 
540
 
        return result;
541
 
}
542
 
 
543
 
 
544
 
/***************************************************************************
545
 
    I/O LATCH
546
 
***************************************************************************/
547
 
 
548
 
static WRITE8_HANDLER( vtech1_latch_w )
549
 
{
550
 
        vtech1_state *vtech1 = space->machine().driver_data<vtech1_state>();
551
 
 
552
 
        if (LOG_VTECH1_LATCH)
553
 
                logerror("vtech1_latch_w $%02X\n", data);
554
 
 
555
 
        /* bit 1, SHRG mod (if installed) */
556
 
        if (vtech1->m_videoram_size == 0x2000)
557
 
        {
558
 
                mc6847_gm0_w(vtech1->m_mc6847, BIT(data, 1));
559
 
                mc6847_gm2_w(vtech1->m_mc6847, BIT(data, 1));
560
 
        }
561
 
 
562
 
        /* bit 2, cassette out */
563
 
        vtech1->m_cassette->output( BIT(data, 2) ? +1.0 : -1.0);
564
 
 
565
 
        /* bit 3 and 4, vdc mode control lines */
566
 
        mc6847_ag_w(vtech1->m_mc6847, BIT(data, 3));
567
 
        mc6847_css_w(vtech1->m_mc6847, BIT(data, 4));
568
 
 
569
 
        /* bit 0 and 5, speaker */
570
 
        speaker_level_w(vtech1->m_speaker, (BIT(data, 5) << 1) | BIT(data, 0));
571
 
}
572
 
 
573
 
 
574
 
/***************************************************************************
575
 
    MEMORY BANKING
576
 
***************************************************************************/
577
 
 
578
 
static WRITE8_HANDLER( vtech1_memory_bank_w )
579
 
{
580
 
        vtech1_state *vtech1 = space->machine().driver_data<vtech1_state>();
581
 
 
582
 
        logerror("vtech1_memory_bank_w $%02X\n", data);
583
 
 
584
 
        if (data >= 1)
585
 
                if ((data <= 3 && vtech1->m_ram_size == 66*1024) || (vtech1->m_ram_size == 4098*1024))
586
 
                        memory_set_bank(space->machine(), "bank3", data - 1);
587
 
}
588
 
 
589
 
static WRITE8_HANDLER( vtech1_video_bank_w )
590
 
{
591
 
        logerror("vtech1_video_bank_w $%02X\n", data);
592
 
        memory_set_bank(space->machine(), "bank4", data & 0x03);
593
 
}
594
 
 
595
 
 
596
 
/***************************************************************************
597
 
    VIDEO EMULATION
598
 
***************************************************************************/
599
 
 
600
 
static READ8_DEVICE_HANDLER( vtech1_mc6847_videoram_r )
601
 
{
602
 
        vtech1_state *vtech1 = device->machine().driver_data<vtech1_state>();
603
 
        mc6847_inv_w(device, BIT(vtech1->m_videoram[offset], 6));
604
 
        mc6847_as_w(device, BIT(vtech1->m_videoram[offset], 7));
605
 
 
606
 
        return vtech1->m_videoram[offset];
607
 
}
608
 
 
609
 
static SCREEN_UPDATE( vtech1 )
610
 
{
611
 
        vtech1_state *vtech1 = screen->machine().driver_data<vtech1_state>();
612
 
        return mc6847_update(vtech1->m_mc6847, bitmap, cliprect);
613
 
}
614
 
 
615
 
 
616
 
/***************************************************************************
617
 
    DRIVER INIT
618
 
***************************************************************************/
619
 
 
620
 
static DRIVER_INIT( vtech1 )
621
 
{
622
 
        vtech1_state *vtech1 = machine.driver_data<vtech1_state>();
623
 
        address_space *prg = machine.device("maincpu")->memory().space(AS_PROGRAM);
624
 
        int id;
625
 
 
626
 
        /* find devices */
627
 
        vtech1->m_mc6847 = machine.device("mc6847");
628
 
        vtech1->m_speaker = machine.device(SPEAKER_TAG);
629
 
        vtech1->m_cassette = machine.device<cassette_image_device>(CASSETTE_TAG);
630
 
        vtech1->m_printer = machine.device("printer");
631
 
 
632
 
        /* ram */
633
 
        vtech1->m_ram = ram_get_ptr(machine.device(RAM_TAG));
634
 
        vtech1->m_ram_size = ram_get_size(machine.device(RAM_TAG));
635
 
 
636
 
        /* setup memory banking */
637
 
        memory_set_bankptr(machine, "bank1", vtech1->m_ram);
638
 
 
639
 
        /* 16k memory expansion? */
640
 
        if (vtech1->m_ram_size == 18*1024 || vtech1->m_ram_size == 22*1024 || vtech1->m_ram_size == 32*1024)
641
 
        {
642
 
                offs_t base = 0x7800 + (vtech1->m_ram_size - 0x4000);
643
 
                prg->install_readwrite_bank(base, base + 0x3fff, "bank2");
644
 
                memory_set_bankptr(machine, "bank2", vtech1->m_ram + base - 0x7800);
645
 
        }
646
 
 
647
 
        /* 64k expansion? */
648
 
        if (vtech1->m_ram_size >= 66*1024)
649
 
        {
650
 
                /* install fixed first bank */
651
 
                prg->install_readwrite_bank(0x8000, 0xbfff, "bank2");
652
 
                memory_set_bankptr(machine, "bank2", vtech1->m_ram + 0x800);
653
 
 
654
 
                /* install the others, dynamically banked in */
655
 
                prg->install_readwrite_bank(0xc000, 0xffff, "bank3");
656
 
                memory_configure_bank(machine, "bank3", 0, (vtech1->m_ram_size - 0x4800) / 0x4000, vtech1->m_ram + 0x4800, 0x4000);
657
 
                memory_set_bank(machine, "bank3", 0);
658
 
        }
659
 
 
660
 
        /* initialize floppy */
661
 
        vtech1->m_drive = -1;
662
 
        vtech1->m_fdc_track_x2[0] = 80;
663
 
        vtech1->m_fdc_track_x2[1] = 80;
664
 
        vtech1->m_fdc_wrprot[0] = 0x80;
665
 
        vtech1->m_fdc_wrprot[1] = 0x80;
666
 
        vtech1->m_fdc_status = 0;
667
 
        vtech1->m_fdc_edge = 0;
668
 
        vtech1->m_fdc_bits = 8;
669
 
        vtech1->m_fdc_start = 0;
670
 
        vtech1->m_fdc_write = 0;
671
 
        vtech1->m_fdc_offs = 0;
672
 
        vtech1->m_fdc_latch = 0;
673
 
 
674
 
        for(id=0;id<2;id++)
675
 
        {
676
 
                floppy_install_load_proc(floppy_get_device(machine, id), vtech1_load_proc);
677
 
        }
678
 
}
679
 
 
680
 
static DRIVER_INIT( vtech1h )
681
 
{
682
 
        vtech1_state *vtech1 = machine.driver_data<vtech1_state>();
683
 
        address_space *prg = machine.device("maincpu")->memory().space(AS_PROGRAM);
684
 
 
685
 
        DRIVER_INIT_CALL(vtech1);
686
 
 
687
 
        /* the SHRG mod replaces the standard videoram chip with an 8k chip */
688
 
        vtech1->m_videoram_size = 0x2000;
689
 
        vtech1->m_videoram = auto_alloc_array(machine, UINT8, vtech1->m_videoram_size);
690
 
 
691
 
        prg->install_readwrite_bank(0x7000, 0x77ff, "bank4");
692
 
        memory_configure_bank(machine, "bank4", 0, 4, vtech1->m_videoram, 0x800);
693
 
        memory_set_bank(machine, "bank4", 0);
694
 
}
695
 
 
696
 
/***************************************************************************
697
 
    ADDRESS MAPS
698
 
***************************************************************************/
699
 
 
700
 
static ADDRESS_MAP_START( laser110_mem, AS_PROGRAM, 8 )
701
 
        AM_RANGE(0x0000, 0x3fff) AM_ROM /* basic rom */
702
 
        AM_RANGE(0x4000, 0x5fff) AM_ROM /* dos rom or other catridges */
703
 
        AM_RANGE(0x6000, 0x67ff) AM_ROM /* reserved for cartridges */
704
 
        AM_RANGE(0x6800, 0x6fff) AM_READWRITE(vtech1_keyboard_r, vtech1_latch_w)
705
 
        AM_RANGE(0x7000, 0x77ff) AM_RAM AM_BASE_MEMBER(vtech1_state, m_videoram) /* (6847) */
706
 
        AM_RANGE(0x7800, 0x7fff) AM_RAMBANK("bank1") /* 2k user ram */
707
 
        AM_RANGE(0x8000, 0xbfff) AM_NOP /* 16k ram expansion */
708
 
        AM_RANGE(0xc000, 0xffff) AM_NOP
709
 
ADDRESS_MAP_END
710
 
 
711
 
static ADDRESS_MAP_START( laser210_mem, AS_PROGRAM, 8 )
712
 
        AM_RANGE(0x0000, 0x3fff) AM_ROM /* basic rom */
713
 
        AM_RANGE(0x4000, 0x5fff) AM_ROM /* dos rom or other catridges */
714
 
        AM_RANGE(0x6000, 0x67ff) AM_ROM /* reserved for cartridges */
715
 
        AM_RANGE(0x6800, 0x6fff) AM_READWRITE(vtech1_keyboard_r, vtech1_latch_w)
716
 
        AM_RANGE(0x7000, 0x77ff) AM_RAM AM_BASE_MEMBER(vtech1_state, m_videoram) /* U7 (6847) */
717
 
        AM_RANGE(0x7800, 0x8fff) AM_RAMBANK("bank1") /* 6k user ram */
718
 
        AM_RANGE(0x9000, 0xcfff) AM_NOP /* 16k ram expansion */
719
 
        AM_RANGE(0xd000, 0xffff) AM_NOP
720
 
ADDRESS_MAP_END
721
 
 
722
 
static ADDRESS_MAP_START( laser310_mem, AS_PROGRAM, 8 )
723
 
        AM_RANGE(0x0000, 0x3fff) AM_ROM /* basic rom */
724
 
        AM_RANGE(0x4000, 0x5fff) AM_ROM /* dos rom or other catridges */
725
 
        AM_RANGE(0x6000, 0x67ff) AM_ROM /* reserved for cartridges */
726
 
        AM_RANGE(0x6800, 0x6fff) AM_READWRITE(vtech1_keyboard_r, vtech1_latch_w)
727
 
        AM_RANGE(0x7000, 0x77ff) AM_RAM AM_BASE_MEMBER(vtech1_state, m_videoram) /* (6847) */
728
 
        AM_RANGE(0x7800, 0xb7ff) AM_RAMBANK("bank1") /* 16k user ram */
729
 
        AM_RANGE(0xb800, 0xf7ff) AM_NOP /* 16k ram expansion */
730
 
        AM_RANGE(0xf8ff, 0xffff) AM_NOP
731
 
ADDRESS_MAP_END
732
 
 
733
 
static ADDRESS_MAP_START( vtech1_io, AS_IO, 8 )
734
 
        ADDRESS_MAP_GLOBAL_MASK(0xff)
735
 
        AM_RANGE(0x00, 0x00) AM_DEVREAD("centronics", vtech1_printer_r)
736
 
        AM_RANGE(0x0d, 0x0d) AM_DEVWRITE("centronics", vtech1_strobe_w)
737
 
        AM_RANGE(0x0e, 0x0e) AM_DEVWRITE("centronics", centronics_data_w)
738
 
        AM_RANGE(0x10, 0x1f) AM_READWRITE(vtech1_fdc_r, vtech1_fdc_w)
739
 
        AM_RANGE(0x20, 0x2f) AM_READ(vtech1_joystick_r)
740
 
        AM_RANGE(0x30, 0x3f) AM_READWRITE(vtech1_serial_r, vtech1_serial_w)
741
 
        AM_RANGE(0x40, 0x4f) AM_READ(vtech1_lightpen_r)
742
 
        AM_RANGE(0x70, 0x7f) AM_WRITE(vtech1_memory_bank_w)
743
 
ADDRESS_MAP_END
744
 
 
745
 
static ADDRESS_MAP_START( vtech1_shrg_io, AS_IO, 8 )
746
 
        AM_IMPORT_FROM(vtech1_io)
747
 
        AM_RANGE(0xd0, 0xdf) AM_WRITE(vtech1_video_bank_w)
748
 
ADDRESS_MAP_END
749
 
 
750
 
 
751
 
/***************************************************************************
752
 
    INPUT PORTS
753
 
***************************************************************************/
754
 
 
755
 
static INPUT_PORTS_START(vtech1)
756
 
        PORT_START("keyboard_0")
757
 
        PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED)
758
 
        PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R       RETURN  LEFT$")   PORT_CODE(KEYCODE_R)     PORT_CHAR('R')
759
 
        PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q       FOR     CHR$")    PORT_CODE(KEYCODE_Q)     PORT_CHAR('Q')
760
 
        PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E       NEXT    LEN(")    PORT_CODE(KEYCODE_E)     PORT_CHAR('E')
761
 
        PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED)
762
 
        PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W       TO      VAL(")    PORT_CODE(KEYCODE_W)     PORT_CHAR('W')
763
 
        PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T       THEN    MID$")    PORT_CODE(KEYCODE_T)     PORT_CHAR('T')
764
 
 
765
 
        PORT_START("keyboard_1")
766
 
        PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED)
767
 
        PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F       GOSUB   RND(")    PORT_CODE(KEYCODE_F)     PORT_CHAR('F')
768
 
        PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A       MODE(   ASC(")    PORT_CODE(KEYCODE_A)     PORT_CHAR('A')
769
 
        PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D       DIM     RESTORE") PORT_CODE(KEYCODE_D)     PORT_CHAR('D')
770
 
        PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL")                    PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2)
771
 
        PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S       STEP    STR$(")   PORT_CODE(KEYCODE_S)     PORT_CHAR('S')
772
 
        PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G       GOTO    STOP")    PORT_CODE(KEYCODE_G)     PORT_CHAR('G')
773
 
 
774
 
        PORT_START("keyboard_2")
775
 
        PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED)
776
 
        PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V       LPRINT  USR")     PORT_CODE(KEYCODE_V)     PORT_CHAR('V')
777
 
        PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z       PEEK(   INP")     PORT_CODE(KEYCODE_Z)     PORT_CHAR('Z')
778
 
        PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C       CONT    COPY")    PORT_CODE(KEYCODE_C)     PORT_CHAR('C')
779
 
        PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SHIFT")                   PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
780
 
        PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X       POKE    OUT")     PORT_CODE(KEYCODE_X)     PORT_CHAR('X')
781
 
        PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B       LLIST   SOUND")   PORT_CODE(KEYCODE_B)     PORT_CHAR('B')
782
 
 
783
 
        PORT_START("keyboard_3")
784
 
        PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED)
785
 
        PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4  $    VERIFY  ATN(")    PORT_CODE(KEYCODE_4)     PORT_CHAR('4') PORT_CHAR('$')
786
 
        PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1  !    CSAVE   SIN(")    PORT_CODE(KEYCODE_1)     PORT_CHAR('1') PORT_CHAR('!')
787
 
        PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3  #    CRUN    TAN(")    PORT_CODE(KEYCODE_3)     PORT_CHAR('3') PORT_CHAR('#')
788
 
        PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED)
789
 
        PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2  \"    CLOAD   COS(")   PORT_CODE(KEYCODE_2)     PORT_CHAR('2') PORT_CHAR('\"')
790
 
        PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5  %    LIST    LOG(")    PORT_CODE(KEYCODE_5)     PORT_CHAR('5') PORT_CHAR('%')
791
 
 
792
 
        PORT_START("keyboard_4")
793
 
        PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED)
794
 
        PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M  \\    \xE2\x86\x90")   PORT_CODE(KEYCODE_M)     PORT_CHAR('M') PORT_CHAR('\\') PORT_CHAR(UCHAR_MAMEKEY(LEFT))
795
 
        PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SPACE   \xE2\x86\x93")    PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_CHAR('~')  PORT_CHAR(UCHAR_MAMEKEY(DOWN))
796
 
        PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(",  <    \xE2\x86\x92")    PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')  PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
797
 
        PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED)
798
 
        PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(".  >    \xE2\x86\x91")    PORT_CODE(KEYCODE_STOP)  PORT_CHAR('.') PORT_CHAR('>')  PORT_CHAR(UCHAR_MAMEKEY(UP))
799
 
        PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N  ^    COLOR   USING")   PORT_CODE(KEYCODE_N)     PORT_CHAR('N') PORT_CHAR('^')
800
 
 
801
 
        PORT_START("keyboard_5")
802
 
        PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED)
803
 
        PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7  '    END     SGN(")    PORT_CODE(KEYCODE_7)     PORT_CHAR('7') PORT_CHAR('\'')
804
 
        PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0  @    DATA    INT(")    PORT_CODE(KEYCODE_0)     PORT_CHAR('0') PORT_CHAR('@')
805
 
        PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8  (    NEW     SQR(")    PORT_CODE(KEYCODE_8)     PORT_CHAR('8') PORT_CHAR('(')
806
 
        PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-  =    [Break]")         PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=')  PORT_CHAR(UCHAR_MAMEKEY(CANCEL))
807
 
        PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9  )    READ    ABS(")    PORT_CODE(KEYCODE_9)     PORT_CHAR('9') PORT_CHAR(')')
808
 
        PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6  &    RUN     EXP(")    PORT_CODE(KEYCODE_6)     PORT_CHAR('6') PORT_CHAR('&')
809
 
 
810
 
        PORT_START("keyboard_6")
811
 
        PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED)
812
 
        PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U       IF      INKEY$")  PORT_CODE(KEYCODE_U)     PORT_CHAR('U')
813
 
        PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P  ]    PRINT   NOT")     PORT_CODE(KEYCODE_P)     PORT_CHAR('P') PORT_CHAR(']')
814
 
        PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I       INPUT   AND")     PORT_CODE(KEYCODE_I)     PORT_CHAR('I')
815
 
        PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RETURN  [Function]")      PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
816
 
        PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O  [    LET     OR")      PORT_CODE(KEYCODE_O)     PORT_CHAR('O') PORT_CHAR('[')
817
 
        PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y       ELSE    RIGHT$(") PORT_CODE(KEYCODE_Y)     PORT_CHAR('Y')
818
 
 
819
 
        PORT_START("keyboard_7")
820
 
        PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED)
821
 
        PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J       REM     RESET")   PORT_CODE(KEYCODE_J)     PORT_CHAR('J')
822
 
        PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(";  +    [Rubout]")        PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+')  PORT_CHAR(UCHAR_MAMEKEY(DEL))
823
 
        PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K  /    TAB(    POINT")   PORT_CODE(KEYCODE_K)     PORT_CHAR('K') PORT_CHAR('/')
824
 
        PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(":  *    [Inverse]")       PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*')  PORT_CHAR(UCHAR_MAMEKEY(HOME))
825
 
        PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L  ?    [Insert]")        PORT_CODE(KEYCODE_L)     PORT_CHAR('L') PORT_CHAR('?')  PORT_CHAR(UCHAR_MAMEKEY(INSERT))
826
 
        PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H       CLS     SET")     PORT_CODE(KEYCODE_H)     PORT_CHAR('H')
827
 
 
828
 
        PORT_START("joystick_0")
829
 
        PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED)
830
 
        PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1)        PORT_PLAYER(1)
831
 
        PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_PLAYER(1)
832
 
        PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT)  PORT_PLAYER(1)
833
 
        PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN)  PORT_PLAYER(1)
834
 
        PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP)    PORT_PLAYER(1)
835
 
 
836
 
        PORT_START("joystick_0_arm")
837
 
        PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED)
838
 
        PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON2)        PORT_PLAYER(1)
839
 
        PORT_BIT(0x0f, IP_ACTIVE_LOW, IPT_UNUSED)
840
 
 
841
 
        PORT_START("joystick_1")
842
 
        PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED)
843
 
        PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1)        PORT_PLAYER(2)
844
 
        PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_PLAYER(2)
845
 
        PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT)  PORT_PLAYER(2)
846
 
        PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN)  PORT_PLAYER(2)
847
 
        PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP)    PORT_PLAYER(2)
848
 
 
849
 
        PORT_START("joystick_1_arm")
850
 
        PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED)
851
 
        PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON2)        PORT_PLAYER(2)
852
 
        PORT_BIT(0x0f, IP_ACTIVE_LOW, IPT_UNUSED)
853
 
 
854
 
        /* Enhanced options not available on real hardware */
855
 
        PORT_START("CONFIG")
856
 
        PORT_CONFNAME( 0x01, 0x01, "Autorun on Quickload")
857
 
        PORT_CONFSETTING(    0x00, DEF_STR(No))
858
 
        PORT_CONFSETTING(    0x01, DEF_STR(Yes))
859
 
//  PORT_CONFNAME( 0x08, 0x08, "Cassette Speaker")
860
 
//  PORT_CONFSETTING(    0x08, DEF_STR(On))
861
 
//  PORT_CONFSETTING(    0x00, DEF_STR(Off))
862
 
INPUT_PORTS_END
863
 
 
864
 
 
865
 
/***************************************************************************
866
 
    PALETTE
867
 
***************************************************************************/
868
 
 
869
 
static const UINT32 vtech1_palette_mono[] =
870
 
{
871
 
        MAKE_RGB(131, 131, 131),
872
 
        MAKE_RGB(211, 211, 211),
873
 
        MAKE_RGB(29, 29, 29),
874
 
        MAKE_RGB(76, 76, 76),
875
 
        MAKE_RGB(213, 213, 213),
876
 
        MAKE_RGB(167, 167, 167),
877
 
        MAKE_RGB(105, 105, 105),
878
 
        MAKE_RGB(136, 136, 136),
879
 
        MAKE_RGB(0, 0, 0),
880
 
        MAKE_RGB(131, 131, 131),
881
 
        MAKE_RGB(0, 0, 0),
882
 
        MAKE_RGB(213, 213, 213),
883
 
        MAKE_RGB(37, 37, 37),
884
 
        MAKE_RGB(133, 133, 133),
885
 
        MAKE_RGB(28, 28, 28),
886
 
        MAKE_RGB(193, 193, 193)
887
 
};
888
 
 
889
 
 
890
 
/***************************************************************************
891
 
    MACHINE DRIVERS
892
 
***************************************************************************/
893
 
 
894
 
static const INT16 speaker_levels[] = {-32768, 0, 32767, 0};
895
 
 
896
 
static const speaker_interface vtech1_speaker_interface =
897
 
{
898
 
        4,
899
 
        speaker_levels
900
 
};
901
 
 
902
 
static const cassette_interface laser_cassette_interface =
903
 
{
904
 
        vtech1_cassette_formats,
905
 
        NULL,
906
 
        (cassette_state)(CASSETTE_PLAY),
907
 
        NULL,
908
 
        NULL
909
 
};
910
 
 
911
 
static const mc6847_interface vtech1_mc6847_intf =
912
 
{
913
 
        DEVCB_HANDLER(vtech1_mc6847_videoram_r),
914
 
        DEVCB_LINE_GND,
915
 
        DEVCB_LINE_VCC,
916
 
        DEVCB_LINE_GND,
917
 
        DEVCB_LINE_GND,
918
 
        DEVCB_NULL,
919
 
        DEVCB_NULL,
920
 
        DEVCB_NULL,
921
 
        DEVCB_NULL,
922
 
        DEVCB_CPU_INPUT_LINE("maincpu", 0),
923
 
        DEVCB_NULL,
924
 
        DEVCB_NULL,
925
 
};
926
 
 
927
 
static const mc6847_interface vtech1_shrg_mc6847_intf =
928
 
{
929
 
        DEVCB_HANDLER(vtech1_mc6847_videoram_r),
930
 
        DEVCB_NULL,
931
 
        DEVCB_LINE_VCC,
932
 
        DEVCB_NULL,
933
 
        DEVCB_LINE_GND,
934
 
        DEVCB_NULL,
935
 
        DEVCB_NULL,
936
 
        DEVCB_NULL,
937
 
        DEVCB_NULL,
938
 
        DEVCB_CPU_INPUT_LINE("maincpu", 0),
939
 
        DEVCB_NULL,
940
 
        DEVCB_NULL,
941
 
};
942
 
 
943
 
static MACHINE_CONFIG_START( laser110, vtech1_state )
944
 
 
945
 
        /* basic machine hardware */
946
 
        MCFG_CPU_ADD("maincpu", Z80, VTECH1_CLK)  /* 3.57950 MHz */
947
 
        MCFG_CPU_PROGRAM_MAP(laser110_mem)
948
 
        MCFG_CPU_IO_MAP(vtech1_io)
949
 
 
950
 
        /* video hardware */
951
 
        MCFG_SCREEN_ADD("screen", RASTER)
952
 
        MCFG_SCREEN_REFRESH_RATE(M6847_PAL_FRAMES_PER_SECOND)
953
 
        MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
954
 
        MCFG_SCREEN_SIZE(320, 25+192+26)
955
 
        MCFG_SCREEN_VISIBLE_AREA(0, 319, 1, 239)
956
 
        MCFG_SCREEN_UPDATE(vtech1)
957
 
 
958
 
        MCFG_MC6847_ADD("mc6847", vtech1_mc6847_intf)
959
 
        MCFG_MC6847_TYPE(M6847_VERSION_ORIGINAL_PAL)
960
 
        MCFG_MC6847_PALETTE(vtech1_palette_mono)
961
 
 
962
 
        /* sound hardware */
963
 
        MCFG_SPEAKER_STANDARD_MONO("mono")
964
 
        MCFG_SOUND_WAVE_ADD(WAVE_TAG, CASSETTE_TAG)
965
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
966
 
        MCFG_SOUND_ADD(SPEAKER_TAG, SPEAKER_SOUND, 0)
967
 
        MCFG_SOUND_CONFIG(vtech1_speaker_interface)
968
 
        MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
969
 
 
970
 
        /* printer */
971
 
        MCFG_CENTRONICS_ADD("centronics", standard_centronics)
972
 
 
973
 
        /* snapshot/quickload */
974
 
        MCFG_SNAPSHOT_ADD("snapshot", vtech1, "vz", 1.5)
975
 
 
976
 
        MCFG_CASSETTE_ADD( CASSETTE_TAG, laser_cassette_interface )
977
 
 
978
 
        /* cartridge */
979
 
        MCFG_CARTSLOT_ADD("cart")
980
 
        MCFG_CARTSLOT_EXTENSION_LIST("rom")
981
 
 
982
 
        /* internal ram */
983
 
        MCFG_RAM_ADD(RAM_TAG)
984
 
        MCFG_RAM_DEFAULT_SIZE("66K")
985
 
        MCFG_RAM_EXTRA_OPTIONS("2K,18K,4098K")
986
 
 
987
 
        MCFG_FLOPPY_2_DRIVES_ADD(vtech1_floppy_interface)
988
 
MACHINE_CONFIG_END
989
 
 
990
 
static MACHINE_CONFIG_DERIVED( laser200, laser110 )
991
 
        MCFG_DEVICE_MODIFY("mc6847")
992
 
        MCFG_MC6847_PALETTE(NULL)
993
 
MACHINE_CONFIG_END
994
 
 
995
 
static MACHINE_CONFIG_DERIVED( laser210, laser200 )
996
 
        MCFG_CPU_MODIFY("maincpu")
997
 
        MCFG_CPU_PROGRAM_MAP(laser210_mem)
998
 
 
999
 
        /* internal ram */
1000
 
        MCFG_RAM_MODIFY(RAM_TAG)
1001
 
        MCFG_RAM_DEFAULT_SIZE("66K")
1002
 
        MCFG_RAM_EXTRA_OPTIONS("6K,22K,4098K")
1003
 
MACHINE_CONFIG_END
1004
 
 
1005
 
static MACHINE_CONFIG_DERIVED( laser310, laser200 )
1006
 
        MCFG_CPU_REPLACE("maincpu", Z80, VZ300_XTAL1_CLK / 5)  /* 3.546894 MHz */
1007
 
        MCFG_CPU_PROGRAM_MAP(laser310_mem)
1008
 
 
1009
 
        /* internal ram */
1010
 
        MCFG_RAM_MODIFY(RAM_TAG)
1011
 
        MCFG_RAM_DEFAULT_SIZE("66K")
1012
 
        MCFG_RAM_EXTRA_OPTIONS("16K,32K,4098K")
1013
 
MACHINE_CONFIG_END
1014
 
 
1015
 
static MACHINE_CONFIG_DERIVED( laser310h, laser310 )
1016
 
        MCFG_CPU_MODIFY("maincpu")
1017
 
        MCFG_CPU_IO_MAP(vtech1_shrg_io)
1018
 
 
1019
 
        MCFG_DEVICE_REMOVE("mc6847")
1020
 
        MCFG_MC6847_ADD("mc6847", vtech1_shrg_mc6847_intf)
1021
 
        MCFG_MC6847_TYPE(M6847_VERSION_ORIGINAL_PAL)
1022
 
MACHINE_CONFIG_END
1023
 
 
1024
 
 
1025
 
/***************************************************************************
1026
 
    ROM DEFINITIONS
1027
 
***************************************************************************/
1028
 
 
1029
 
ROM_START( laser110 )
1030
 
        ROM_REGION(0x6800, "maincpu", 0)
1031
 
        ROM_LOAD("vtechv12.u09",   0x0000, 0x2000, CRC(99412d43) SHA1(6aed8872a0818be8e1b08ecdfd92acbe57a3c96d))
1032
 
        ROM_LOAD("vtechv12.u10",   0x2000, 0x2000, CRC(e4c24e8b) SHA1(9d8fb3d24f3d4175b485cf081a2d5b98158ab2fb))
1033
 
        ROM_CART_LOAD("cart",  0x4000, 0x27ff, ROM_NOMIRROR | ROM_OPTIONAL)
1034
 
ROM_END
1035
 
 
1036
 
/* The VZ-200 sold in Germany and the Netherlands came with BASIC V1.1, which
1037
 
   is currently not dumped. */
1038
 
ROM_START( vz200de )
1039
 
        ROM_REGION(0x6800, "maincpu", 0)
1040
 
        ROM_LOAD("vtechv11.u09",   0x0000, 0x2000, NO_DUMP)
1041
 
        ROM_LOAD("vtechv11.u10",   0x2000, 0x2000, NO_DUMP)
1042
 
        ROM_CART_LOAD("cart",  0x4000, 0x27ff, ROM_NOMIRROR | ROM_OPTIONAL)
1043
 
ROM_END
1044
 
 
1045
 
#define rom_las110de    rom_laser110
1046
 
#define rom_laser200    rom_laser110
1047
 
#define rom_fellow      rom_laser110
1048
 
 
1049
 
/* It's possible that the Texet TX8000 came with BASIC V1.0, but this
1050
 
   needs to be verified */
1051
 
#define rom_tx8000      rom_laser110
1052
 
 
1053
 
ROM_START( laser210 )
1054
 
        ROM_REGION(0x6800, "maincpu", 0)
1055
 
        ROM_LOAD("vtechv20.u09",   0x0000, 0x2000, CRC(cc854fe9) SHA1(6e66a309b8e6dc4f5b0b44e1ba5f680467353d66))
1056
 
        ROM_LOAD("vtechv20.u10",   0x2000, 0x2000, CRC(7060f91a) SHA1(8f3c8f24f97ebb98f3c88d4e4ba1f91ffd563440))
1057
 
        ROM_CART_LOAD("cart",  0x4000, 0x27ff, ROM_NOMIRROR | ROM_OPTIONAL)
1058
 
ROM_END
1059
 
 
1060
 
#define rom_las210de    rom_laser210
1061
 
#define rom_vz200       rom_laser210
1062
 
 
1063
 
ROM_START( laser310 )
1064
 
        ROM_REGION(0x6800, "maincpu", 0)
1065
 
        ROM_SYSTEM_BIOS(0, "basic20", "BASIC V2.0")
1066
 
        ROMX_LOAD("vtechv20.u12", 0x0000, 0x4000, CRC(613de12c) SHA1(f216c266bc09b0dbdbad720796e5ea9bc7d91e53), ROM_BIOS(1))
1067
 
        ROM_SYSTEM_BIOS(1, "basic21", "BASIC V2.1 (hack)")
1068
 
        ROMX_LOAD("vtechv21.u12", 0x0000, 0x4000, CRC(f7df980f) SHA1(5ba14a7a2eedca331b033901080fa5d205e245ea), ROM_BIOS(2))
1069
 
        ROM_CART_LOAD("cart", 0x4000, 0x27ff, ROM_NOMIRROR | ROM_OPTIONAL)
1070
 
ROM_END
1071
 
 
1072
 
#define rom_vz300       rom_laser310
1073
 
#define rom_laser310h   rom_laser310
1074
 
 
1075
 
/***************************************************************************
1076
 
    GAME DRIVERS
1077
 
***************************************************************************/
1078
 
 
1079
 
/*    YEAR  NAME       PARENT    COMPAT  MACHINE    INPUT   INIT     COMPANY                   FULLNAME                          FLAGS */
1080
 
COMP( 1983, laser110,  0,        0,      laser110,  vtech1, vtech1,  "Video Technology",       "Laser 110",                      0 )
1081
 
COMP( 1983, las110de,  laser110, 0,      laser110,  vtech1, vtech1,  "Sanyo",                  "Laser 110 (Germany)",            0 )
1082
 
COMP( 1983, laser200,  0, laser110,      laser200,  vtech1, vtech1,  "Video Technology",       "Laser 200",                      0 )
1083
 
//COMP( 1983, vz200de,   laser200, 0,      laser200,  vtech1, vtech1,  "Video Technology",       "VZ-200 (Germany & Netherlands)", 0 )
1084
 
COMP( 1983, fellow,    laser200, 0,      laser200,  vtech1, vtech1,  "Salora",                 "Fellow (Finland)",               0 )
1085
 
COMP( 1983, tx8000,    laser200, 0,      laser200,  vtech1, vtech1,  "Texet",                  "TX-8000 (UK)",                   0 )
1086
 
COMP( 1984, laser210,  0, laser200,      laser210,  vtech1, vtech1,  "Video Technology",       "Laser 210",                      0 )
1087
 
COMP( 1984, vz200,     laser210, 0,      laser210,  vtech1, vtech1,  "Dick Smith Electronics", "VZ-200 (Oceania)",               0 )
1088
 
COMP( 1984, las210de,  laser210, 0,      laser210,  vtech1, vtech1,  "Sanyo",                  "Laser 210 (Germany)",            0 )
1089
 
COMP( 1984, laser310,  0, laser200,      laser310,  vtech1, vtech1,  "Video Technology",       "Laser 310",                      0 )
1090
 
COMP( 1984, vz300,     laser310, 0,      laser310,  vtech1, vtech1,  "Dick Smith Electronics", "VZ-300 (Oceania)",               0 )
1091
 
COMP( 1984, laser310h, laser310, 0,      laser310h, vtech1, vtech1h, "Video Technology",       "Laser 310 (SHRG)",               GAME_UNOFFICIAL)