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

« back to all changes in this revision

Viewing changes to mess/src/emu/cpu/nec/v25.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
 
    NEC V25/V35 emulator
4
 
 
5
 
    ---------------------------------------------
6
 
 
7
 
    TODO:
8
 
 
9
 
    Using V20/V30 cycle counts for now. V25/V35 cycle counts
10
 
    vary based on whether internal RAM access is enabled (RAMEN).
11
 
    Likewise, the programmable clock divider (PCK) currently only
12
 
    affects the timers, not instruction execution.
13
 
 
14
 
    BTCLR and STOP instructions not implemented.
15
 
 
16
 
    IBRK flag (trap I/O instructions) not implemented.
17
 
 
18
 
    Interrupt macro service function not implemented.
19
 
 
20
 
    Port implementation is incomplete: mode control registers are ignored.
21
 
 
22
 
    Timer implementation is incomplete: polling is not implemented
23
 
    (reading any of the registers just returns the last value written)
24
 
 
25
 
    Serial interface and DMA functions not implemented.
26
 
    Note that these functions differ considerably between
27
 
    the V25/35 and the V25+/35+.
28
 
 
29
 
    Make internal RAM into a real RAM region, and use an
30
 
    internal address map (remapped when IDB is written to)
31
 
    instead of memory access wrapper functions.
32
 
    That way the internal RAM would be visible to the debugger,
33
 
    among other benefits.
34
 
 
35
 
****************************************************************************/
36
 
 
37
 
#include "emu.h"
38
 
#include "debugger.h"
39
 
 
40
 
typedef UINT8 BOOLEAN;
41
 
typedef UINT8 BYTE;
42
 
typedef UINT16 WORD;
43
 
typedef UINT32 DWORD;
44
 
 
45
 
#include "nec.h"
46
 
#include "v25priv.h"
47
 
 
48
 
/* default configuration */
49
 
static const nec_config default_config =
50
 
{
51
 
        NULL
52
 
};
53
 
 
54
 
extern int necv_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom, const nec_config *config);
55
 
 
56
 
INLINE v25_state_t *get_safe_token(device_t *device)
57
 
{
58
 
        assert(device != NULL);
59
 
        assert(device->type() == V25 || device->type() == V35);
60
 
        return (v25_state_t *)downcast<legacy_cpu_device *>(device)->token();
61
 
}
62
 
 
63
 
static TIMER_CALLBACK(v25_timer_callback)
64
 
{
65
 
        v25_state_t *nec_state = (v25_state_t *)ptr;
66
 
        nec_state->pending_irq |= param;
67
 
}
68
 
 
69
 
INLINE void prefetch(v25_state_t *nec_state)
70
 
{
71
 
        nec_state->prefetch_count--;
72
 
}
73
 
 
74
 
static void do_prefetch(v25_state_t *nec_state, int previous_ICount)
75
 
{
76
 
        int diff = previous_ICount - (int) nec_state->icount;
77
 
 
78
 
        /* The implementation is not accurate, but comes close.
79
 
     * It does not respect that the V30 will fetch two bytes
80
 
     * at once directly, but instead uses only 2 cycles instead
81
 
     * of 4. There are however only very few sources publicly
82
 
     * available and they are vague.
83
 
     */
84
 
        while (nec_state->prefetch_count<0)
85
 
        {
86
 
                nec_state->prefetch_count++;
87
 
                if (diff>nec_state->prefetch_cycles)
88
 
                        diff -= nec_state->prefetch_cycles;
89
 
                else
90
 
                        nec_state->icount -= nec_state->prefetch_cycles;
91
 
        }
92
 
 
93
 
        if (nec_state->prefetch_reset)
94
 
        {
95
 
                nec_state->prefetch_count = 0;
96
 
                nec_state->prefetch_reset = 0;
97
 
                return;
98
 
        }
99
 
 
100
 
        while (diff>=nec_state->prefetch_cycles && nec_state->prefetch_count < nec_state->prefetch_size)
101
 
        {
102
 
                diff -= nec_state->prefetch_cycles;
103
 
                nec_state->prefetch_count++;
104
 
        }
105
 
 
106
 
}
107
 
 
108
 
INLINE UINT8 fetch(v25_state_t *nec_state)
109
 
{
110
 
        prefetch(nec_state);
111
 
        return nec_state->direct->read_raw_byte((Sreg(PS)<<4)+nec_state->ip++, nec_state->fetch_xor);
112
 
}
113
 
 
114
 
INLINE UINT16 fetchword(v25_state_t *nec_state)
115
 
{
116
 
        UINT16 r = FETCH();
117
 
        r |= (FETCH()<<8);
118
 
        return r;
119
 
}
120
 
 
121
 
#define nec_state_t v25_state_t
122
 
 
123
 
#include "v25instr.h"
124
 
#include "necmacro.h"
125
 
#include "necea.h"
126
 
#include "necmodrm.h"
127
 
 
128
 
static UINT8 parity_table[256];
129
 
 
130
 
static UINT8 fetchop(v25_state_t *nec_state)
131
 
{
132
 
        UINT8 ret;
133
 
 
134
 
        prefetch(nec_state);
135
 
        ret = nec_state->direct->read_decrypted_byte(( Sreg(PS)<<4)+nec_state->ip++, nec_state->fetch_xor);
136
 
 
137
 
        if (nec_state->MF == 0)
138
 
                if (nec_state->config->v25v35_decryptiontable)
139
 
                {
140
 
                        ret = nec_state->config->v25v35_decryptiontable[ret];
141
 
                }
142
 
        return ret;
143
 
}
144
 
 
145
 
 
146
 
 
147
 
/***************************************************************************/
148
 
 
149
 
static CPU_RESET( v25 )
150
 
{
151
 
        v25_state_t *nec_state = get_safe_token(device);
152
 
        int tmp;
153
 
        attotime time;
154
 
 
155
 
        nec_state->ip = 0;
156
 
        nec_state->IBRK = 1;
157
 
        nec_state->F0 = 0;
158
 
        nec_state->F1 = 0;
159
 
        nec_state->TF = 0;
160
 
        nec_state->IF = 0;
161
 
        nec_state->DF = 0;
162
 
        nec_state->SignVal = 0;
163
 
        nec_state->AuxVal = 0;
164
 
        nec_state->OverVal = 0;
165
 
        nec_state->ZeroVal = 1;
166
 
        nec_state->CarryVal = 0;
167
 
        nec_state->ParityVal = 1;
168
 
        nec_state->pending_irq = 0;
169
 
        nec_state->unmasked_irq = INT_IRQ | NMI_IRQ;
170
 
        nec_state->bankswitch_irq = 0;
171
 
        nec_state->priority_inttu = 7;
172
 
        nec_state->priority_intd = 7;
173
 
        nec_state->priority_intp = 7;
174
 
        nec_state->priority_ints0 = 7;
175
 
        nec_state->priority_ints1 = 7;
176
 
        nec_state->IRQS = nec_state->ISPR = 0;
177
 
        nec_state->nmi_state = 0;
178
 
        nec_state->irq_state = 0;
179
 
        nec_state->poll_state = 1;
180
 
        nec_state->mode_state = nec_state->MF = (nec_state->config->v25v35_decryptiontable) ? 0 : 1;
181
 
        nec_state->intp_state[0] = 0;
182
 
        nec_state->intp_state[1] = 0;
183
 
        nec_state->intp_state[2] = 0;
184
 
 
185
 
        nec_state->TM0 = nec_state->MD0 = nec_state->TM1 = nec_state->MD1 = 0;
186
 
        nec_state->TMC0 = nec_state->TMC1 = 0;
187
 
 
188
 
        nec_state->RAMEN = 1;
189
 
        nec_state->TB = 20;
190
 
        nec_state->PCK = 8;
191
 
        nec_state->IDB = 0xFFE00;
192
 
 
193
 
        tmp = nec_state->PCK << nec_state->TB;
194
 
        time = attotime::from_hz(nec_state->device->unscaled_clock()) * tmp;
195
 
        nec_state->timers[3]->adjust(time, INTTB, time);
196
 
 
197
 
        nec_state->timers[0]->adjust(attotime::never);
198
 
        nec_state->timers[1]->adjust(attotime::never);
199
 
        nec_state->timers[2]->adjust(attotime::never);
200
 
 
201
 
        SetRB(7);
202
 
        Sreg(PS) = 0xffff;
203
 
        Sreg(SS) = 0;
204
 
        Sreg(DS0) = 0;
205
 
        Sreg(DS1) = 0;
206
 
 
207
 
        CHANGE_PC;
208
 
}
209
 
 
210
 
static CPU_EXIT( v25 )
211
 
{
212
 
 
213
 
}
214
 
 
215
 
static void nec_interrupt(v25_state_t *nec_state, unsigned int_num, INTSOURCES source)
216
 
{
217
 
    UINT32 dest_seg, dest_off;
218
 
 
219
 
    i_pushf(nec_state);
220
 
        nec_state->TF = nec_state->IF = 0;
221
 
        nec_state->MF = nec_state->mode_state;
222
 
 
223
 
        switch(source)
224
 
        {
225
 
                case BRKN:      /* force native mode */
226
 
                        nec_state->MF = 1;
227
 
                        break;
228
 
                case BRKS:      /* force secure mode */
229
 
                        if (nec_state->config->v25v35_decryptiontable)
230
 
                                nec_state->MF = 0;
231
 
                        else
232
 
                                logerror("%06x: BRKS executed with no decryption table\n",PC(nec_state));
233
 
                        break;
234
 
                case INT_IRQ:   /* get vector */
235
 
                        int_num = (*nec_state->irq_callback)(nec_state->device, 0);
236
 
                        break;
237
 
                default:
238
 
                        break;
239
 
        }
240
 
 
241
 
    dest_off = read_mem_word(int_num*4);
242
 
    dest_seg = read_mem_word(int_num*4+2);
243
 
 
244
 
        PUSH(Sreg(PS));
245
 
        PUSH(nec_state->ip);
246
 
        nec_state->ip = (WORD)dest_off;
247
 
        Sreg(PS) = (WORD)dest_seg;
248
 
        CHANGE_PC;
249
 
}
250
 
 
251
 
static void nec_bankswitch(v25_state_t *nec_state, unsigned bank_num)
252
 
{
253
 
        int tmp = CompressFlags();
254
 
 
255
 
        nec_state->TF = nec_state->IF = 0;
256
 
        nec_state->MF = nec_state->mode_state;
257
 
 
258
 
        SetRB(bank_num);
259
 
 
260
 
        Wreg(PSW_SAVE) = tmp;
261
 
        Wreg(PC_SAVE) = nec_state->ip;
262
 
        nec_state->ip = Wreg(VECTOR_PC);
263
 
        CHANGE_PC;
264
 
}
265
 
 
266
 
static void nec_trap(v25_state_t *nec_state)
267
 
{
268
 
        nec_instruction[fetchop(nec_state)](nec_state);
269
 
        nec_interrupt(nec_state, NEC_TRAP_VECTOR, BRK);
270
 
}
271
 
 
272
 
#define INTERRUPT(source, vector, priority) \
273
 
        if(pending & (source)) {                                \
274
 
                nec_state->IRQS = vector;                               \
275
 
                nec_state->ISPR |= (1 << (priority));   \
276
 
                nec_state->pending_irq &= ~(source);    \
277
 
                if(nec_state->bankswitch_irq & (source))        \
278
 
                        nec_bankswitch(nec_state, priority);    \
279
 
                else                                                                    \
280
 
                        nec_interrupt(nec_state, vector, source);       \
281
 
                break;  /* break out of loop */ \
282
 
        }
283
 
 
284
 
/* interrupt sources subject to priority control */
285
 
#define SOURCES (INTTU0 | INTTU1 | INTTU2 | INTD0 | INTD1 | INTP0 | INTP1 | INTP2 \
286
 
                                | INTSER0 | INTSR0 | INTST0 | INTSER1 | INTSR1 | INTST1 | INTTB)
287
 
 
288
 
static void external_int(v25_state_t *nec_state)
289
 
{
290
 
        int pending = nec_state->pending_irq & nec_state->unmasked_irq;
291
 
 
292
 
        if (pending & NMI_IRQ)
293
 
        {
294
 
                nec_interrupt(nec_state, NEC_NMI_VECTOR, NMI_IRQ);
295
 
                nec_state->pending_irq &= ~NMI_IRQ;
296
 
        }
297
 
        else if (pending & SOURCES)
298
 
        {
299
 
                for(int i = 0; i < 8; i++)
300
 
                {
301
 
                        if (nec_state->ISPR & (1 << i)) break;
302
 
 
303
 
                        if (nec_state->priority_inttu == i)
304
 
                        {
305
 
                                INTERRUPT(INTTU0, NEC_INTTU0_VECTOR, i)
306
 
                                INTERRUPT(INTTU1, NEC_INTTU1_VECTOR, i)
307
 
                                INTERRUPT(INTTU2, NEC_INTTU2_VECTOR, i)
308
 
                        }
309
 
 
310
 
                        if (nec_state->priority_intd == i)
311
 
                        {
312
 
                                INTERRUPT(INTD0, NEC_INTD0_VECTOR, i)
313
 
                                INTERRUPT(INTD1, NEC_INTD1_VECTOR, i)
314
 
                        }
315
 
 
316
 
                        if (nec_state->priority_intp == i)
317
 
                        {
318
 
                                INTERRUPT(INTP0, NEC_INTP0_VECTOR, i)
319
 
                                INTERRUPT(INTP1, NEC_INTP1_VECTOR, i)
320
 
                                INTERRUPT(INTP2, NEC_INTP2_VECTOR, i)
321
 
                        }
322
 
 
323
 
                        if (nec_state->priority_ints0 == i)
324
 
                        {
325
 
                                INTERRUPT(INTSER0, NEC_INTSER0_VECTOR, i)
326
 
                                INTERRUPT(INTSR0, NEC_INTSR0_VECTOR, i)
327
 
                                INTERRUPT(INTST0, NEC_INTST0_VECTOR, i)
328
 
                        }
329
 
 
330
 
                        if (nec_state->priority_ints1 == i)
331
 
                        {
332
 
                                INTERRUPT(INTSER1, NEC_INTSER1_VECTOR, i)
333
 
                                INTERRUPT(INTSR1, NEC_INTSR1_VECTOR, i)
334
 
                                INTERRUPT(INTST1, NEC_INTST1_VECTOR, i)
335
 
                        }
336
 
 
337
 
                        if (i == 7)
338
 
                                INTERRUPT(INTTB, NEC_INTTB_VECTOR, 7)
339
 
                }
340
 
        }
341
 
        else if (pending & INT_IRQ)
342
 
        {
343
 
                /* the actual vector is retrieved after pushing flags */
344
 
                /* and clearing the IF */
345
 
                nec_interrupt(nec_state, (UINT32)-1, INT_IRQ);
346
 
                nec_state->irq_state = CLEAR_LINE;
347
 
                nec_state->pending_irq &= ~INT_IRQ;
348
 
        }
349
 
}
350
 
 
351
 
/****************************************************************************/
352
 
/*                             OPCODES                                      */
353
 
/****************************************************************************/
354
 
 
355
 
#include "necinstr.c"
356
 
#include "v25instr.c"
357
 
 
358
 
/*****************************************************************************/
359
 
 
360
 
static void set_irq_line(v25_state_t *nec_state, int irqline, int state)
361
 
{
362
 
        switch (irqline)
363
 
        {
364
 
                case 0:
365
 
                        nec_state->irq_state = state;
366
 
                        if (state == CLEAR_LINE)
367
 
                                nec_state->pending_irq &= ~INT_IRQ;
368
 
                        else
369
 
                                nec_state->pending_irq |= INT_IRQ;
370
 
                        break;
371
 
                case INPUT_LINE_NMI:
372
 
                        if (nec_state->nmi_state == state) return;
373
 
                    nec_state->nmi_state = state;
374
 
                        if (state != CLEAR_LINE)
375
 
                                nec_state->pending_irq |= NMI_IRQ;
376
 
                        break;
377
 
                case NEC_INPUT_LINE_INTP0:
378
 
                case NEC_INPUT_LINE_INTP1:
379
 
                case NEC_INPUT_LINE_INTP2:
380
 
                        irqline -= NEC_INPUT_LINE_INTP0;
381
 
                        if (nec_state->intp_state[irqline] == state) return;
382
 
                        nec_state->intp_state[irqline] = state;
383
 
                        if (state != CLEAR_LINE)
384
 
                                nec_state->pending_irq |= (INTP0 << irqline);
385
 
                        break;
386
 
                case NEC_INPUT_LINE_POLL:
387
 
                        nec_state->poll_state = state;
388
 
                        break;
389
 
        }
390
 
}
391
 
 
392
 
static CPU_DISASSEMBLE( v25 )
393
 
{
394
 
        v25_state_t *nec_state = get_safe_token(device);
395
 
 
396
 
        return necv_dasm_one(buffer, pc, oprom, nec_state->config);
397
 
}
398
 
 
399
 
static void v25_init(legacy_cpu_device *device, device_irq_callback irqcallback, int type)
400
 
{
401
 
        const nec_config *config = device->static_config() ? (const nec_config *)device->static_config() : &default_config;
402
 
        v25_state_t *nec_state = get_safe_token(device);
403
 
 
404
 
        unsigned int i, j, c;
405
 
 
406
 
        static const WREGS wreg_name[8]={ AW, CW, DW, BW, SP, BP, IX, IY };
407
 
        static const BREGS breg_name[8]={ AL, CL, DL, BL, AH, CH, DH, BH };
408
 
 
409
 
        for (i = 0; i < 256; i++)
410
 
        {
411
 
                for (j = i, c = 0; j > 0; j >>= 1)
412
 
                        if (j & 1) c++;
413
 
                parity_table[i] = !(c & 1);
414
 
        }
415
 
 
416
 
        for (i = 0; i < 256; i++)
417
 
        {
418
 
                Mod_RM.reg.b[i] = breg_name[(i & 0x38) >> 3];
419
 
                Mod_RM.reg.w[i] = wreg_name[(i & 0x38) >> 3];
420
 
        }
421
 
 
422
 
        for (i = 0xc0; i < 0x100; i++)
423
 
        {
424
 
                Mod_RM.RM.w[i] = wreg_name[i & 7];
425
 
                Mod_RM.RM.b[i] = breg_name[i & 7];
426
 
        }
427
 
 
428
 
        memset(nec_state, 0, sizeof(nec_state));
429
 
 
430
 
        nec_state->config = config;
431
 
 
432
 
        for (int i = 0; i < 4; i++)
433
 
                nec_state->timers[i] = device->machine().scheduler().timer_alloc(FUNC(v25_timer_callback), nec_state);
434
 
 
435
 
        device->save_item(NAME(nec_state->ram.w));
436
 
        device->save_item(NAME(nec_state->intp_state));
437
 
 
438
 
        device->save_item(NAME(nec_state->ip));
439
 
        device->save_item(NAME(nec_state->IBRK));
440
 
        device->save_item(NAME(nec_state->F0));
441
 
        device->save_item(NAME(nec_state->F1));
442
 
        device->save_item(NAME(nec_state->TF));
443
 
        device->save_item(NAME(nec_state->IF));
444
 
        device->save_item(NAME(nec_state->DF));
445
 
        device->save_item(NAME(nec_state->MF));
446
 
        device->save_item(NAME(nec_state->RBW));
447
 
        device->save_item(NAME(nec_state->RBB));
448
 
        device->save_item(NAME(nec_state->SignVal));
449
 
        device->save_item(NAME(nec_state->AuxVal));
450
 
        device->save_item(NAME(nec_state->OverVal));
451
 
        device->save_item(NAME(nec_state->ZeroVal));
452
 
        device->save_item(NAME(nec_state->CarryVal));
453
 
        device->save_item(NAME(nec_state->ParityVal));
454
 
        device->save_item(NAME(nec_state->pending_irq));
455
 
        device->save_item(NAME(nec_state->unmasked_irq));
456
 
        device->save_item(NAME(nec_state->bankswitch_irq));
457
 
        device->save_item(NAME(nec_state->priority_inttu));
458
 
        device->save_item(NAME(nec_state->priority_intd));
459
 
        device->save_item(NAME(nec_state->priority_intp));
460
 
        device->save_item(NAME(nec_state->priority_ints0));
461
 
        device->save_item(NAME(nec_state->priority_ints1));
462
 
        device->save_item(NAME(nec_state->IRQS));
463
 
        device->save_item(NAME(nec_state->ISPR));
464
 
        device->save_item(NAME(nec_state->nmi_state));
465
 
        device->save_item(NAME(nec_state->irq_state));
466
 
        device->save_item(NAME(nec_state->poll_state));
467
 
        device->save_item(NAME(nec_state->mode_state));
468
 
        device->save_item(NAME(nec_state->TM0));
469
 
        device->save_item(NAME(nec_state->MD0));
470
 
        device->save_item(NAME(nec_state->TM1));
471
 
        device->save_item(NAME(nec_state->MD1));
472
 
        device->save_item(NAME(nec_state->TMC0));
473
 
        device->save_item(NAME(nec_state->TMC1));
474
 
        device->save_item(NAME(nec_state->RAMEN));
475
 
        device->save_item(NAME(nec_state->TB));
476
 
        device->save_item(NAME(nec_state->PCK));
477
 
        device->save_item(NAME(nec_state->IDB));
478
 
 
479
 
        nec_state->irq_callback = irqcallback;
480
 
        nec_state->device = device;
481
 
        nec_state->program = device->space(AS_PROGRAM);
482
 
        nec_state->direct = &nec_state->program->direct();
483
 
        nec_state->io = device->space(AS_IO);
484
 
}
485
 
 
486
 
 
487
 
 
488
 
static CPU_EXECUTE( v25 )
489
 
{
490
 
        v25_state_t *nec_state = get_safe_token(device);
491
 
        int prev_ICount;
492
 
 
493
 
        while(nec_state->icount>0) {
494
 
                /* Dispatch IRQ */
495
 
                if (nec_state->no_interrupt==0 && (nec_state->pending_irq & nec_state->unmasked_irq))
496
 
                {
497
 
                        if (nec_state->pending_irq & NMI_IRQ)
498
 
                                external_int(nec_state);
499
 
                        else if (nec_state->IF)
500
 
                                external_int(nec_state);
501
 
                }
502
 
 
503
 
                /* No interrupt allowed between last instruction and this one */
504
 
                if (nec_state->no_interrupt)
505
 
                        nec_state->no_interrupt--;
506
 
 
507
 
                debugger_instruction_hook(device, (Sreg(PS)<<4) + nec_state->ip);
508
 
                prev_ICount = nec_state->icount;
509
 
                nec_instruction[fetchop(nec_state)](nec_state);
510
 
                do_prefetch(nec_state, prev_ICount);
511
 
    }
512
 
}
513
 
 
514
 
/* Wrappers for the different CPU types */
515
 
static CPU_INIT( v25 )
516
 
{
517
 
        v25_state_t *nec_state = get_safe_token(device);
518
 
 
519
 
        v25_init(device, irqcallback, 0);
520
 
        nec_state->fetch_xor = 0;
521
 
        nec_state->chip_type=V20_TYPE;
522
 
        nec_state->prefetch_size = 4;           /* 3 words */
523
 
        nec_state->prefetch_cycles = 4;         /* four cycles per byte */
524
 
}
525
 
 
526
 
static CPU_INIT( v35 )
527
 
{
528
 
        v25_state_t *nec_state = get_safe_token(device);
529
 
 
530
 
        v25_init(device, irqcallback, 1);
531
 
        nec_state->fetch_xor = BYTE_XOR_LE(0);
532
 
        nec_state->chip_type=V30_TYPE;
533
 
        nec_state->prefetch_size = 6;           /* 3 words */
534
 
        nec_state->prefetch_cycles = 2;         /* two cycles per byte / four per word */
535
 
 
536
 
}
537
 
 
538
 
 
539
 
 
540
 
/**************************************************************************
541
 
 * Generic set_info
542
 
 **************************************************************************/
543
 
 
544
 
static CPU_SET_INFO( v25 )
545
 
{
546
 
        v25_state_t *nec_state = get_safe_token(device);
547
 
 
548
 
        switch (state)
549
 
        {
550
 
                /* --- the following bits of info are set as 64-bit signed integers --- */
551
 
                case CPUINFO_INT_INPUT_STATE + 0:                                               set_irq_line(nec_state, 0, info->i);                            break;
552
 
                case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI:                  set_irq_line(nec_state, INPUT_LINE_NMI, info->i);       break;
553
 
                case CPUINFO_INT_INPUT_STATE + NEC_INPUT_LINE_INTP0:    set_irq_line(nec_state, NEC_INPUT_LINE_INTP0, info->i); break;
554
 
                case CPUINFO_INT_INPUT_STATE + NEC_INPUT_LINE_INTP1:    set_irq_line(nec_state, NEC_INPUT_LINE_INTP1, info->i); break;
555
 
                case CPUINFO_INT_INPUT_STATE + NEC_INPUT_LINE_INTP2:    set_irq_line(nec_state, NEC_INPUT_LINE_INTP2, info->i); break;
556
 
                case CPUINFO_INT_INPUT_STATE + NEC_INPUT_LINE_POLL:             set_irq_line(nec_state, NEC_INPUT_LINE_POLL, info->i);  break;
557
 
 
558
 
                case CPUINFO_INT_PC:
559
 
                case CPUINFO_INT_REGISTER + NEC_PC:
560
 
                        if( info->i - (Sreg(PS)<<4) < 0x10000 )
561
 
                        {
562
 
                                nec_state->ip = info->i - (Sreg(PS)<<4);
563
 
                        }
564
 
                        else
565
 
                        {
566
 
                                Sreg(PS) = info->i >> 4;
567
 
                                nec_state->ip = info->i & 0x0000f;
568
 
                        }
569
 
                        break;
570
 
                case CPUINFO_INT_REGISTER + NEC_IP:                             nec_state->ip = info->i;                                                        break;
571
 
                case CPUINFO_INT_SP:
572
 
                        if( info->i - (Sreg(SS)<<4) < 0x10000 )
573
 
                        {
574
 
                                Wreg(SP) = info->i - (Sreg(SS)<<4);
575
 
                        }
576
 
                        else
577
 
                        {
578
 
                                Sreg(SS) = info->i >> 4;
579
 
                                Wreg(SP) = info->i & 0x0000f;
580
 
                        }
581
 
                        break;
582
 
                case CPUINFO_INT_REGISTER + NEC_SP:                             Wreg(SP) = info->i;                                     break;
583
 
                case CPUINFO_INT_REGISTER + NEC_FLAGS:                  ExpandFlags(info->i);                                   break;
584
 
                case CPUINFO_INT_REGISTER + NEC_AW:                             Wreg(AW) = info->i;                                     break;
585
 
                case CPUINFO_INT_REGISTER + NEC_CW:                             Wreg(CW) = info->i;                                     break;
586
 
                case CPUINFO_INT_REGISTER + NEC_DW:                             Wreg(DW) = info->i;                                     break;
587
 
                case CPUINFO_INT_REGISTER + NEC_BW:                             Wreg(BW) = info->i;                                     break;
588
 
                case CPUINFO_INT_REGISTER + NEC_BP:                             Wreg(BP) = info->i;                                     break;
589
 
                case CPUINFO_INT_REGISTER + NEC_IX:                             Wreg(IX) = info->i;                                     break;
590
 
                case CPUINFO_INT_REGISTER + NEC_IY:                             Wreg(IY) = info->i;                                     break;
591
 
                case CPUINFO_INT_REGISTER + NEC_ES:                             Sreg(DS1) = info->i;                                    break;
592
 
                case CPUINFO_INT_REGISTER + NEC_CS:                             Sreg(PS) = info->i;                                     break;
593
 
                case CPUINFO_INT_REGISTER + NEC_SS:                             Sreg(SS) = info->i;                                     break;
594
 
                case CPUINFO_INT_REGISTER + NEC_DS:                             Sreg(DS0) = info->i;                                    break;
595
 
        }
596
 
}
597
 
 
598
 
 
599
 
 
600
 
/**************************************************************************
601
 
 * Generic get_info
602
 
 **************************************************************************/
603
 
 
604
 
static CPU_GET_INFO( v25v35 )
605
 
{
606
 
        v25_state_t *nec_state = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
607
 
        int flags;
608
 
 
609
 
        switch (state)
610
 
        {
611
 
                /* --- the following bits of info are returned as 64-bit signed integers --- */
612
 
                case CPUINFO_INT_CONTEXT_SIZE:                                  info->i = sizeof(v25_state_t);                                  break;
613
 
                case CPUINFO_INT_INPUT_LINES:                                   info->i = 1;                                                    break;
614
 
                case CPUINFO_INT_DEFAULT_IRQ_VECTOR:                    info->i = 0xff;                                                 break;
615
 
                case DEVINFO_INT_ENDIANNESS:                                    info->i = ENDIANNESS_LITTLE;                                    break;
616
 
                case CPUINFO_INT_CLOCK_MULTIPLIER:                              info->i = 1;                                                    break;
617
 
                case CPUINFO_INT_CLOCK_DIVIDER:                                 info->i = 2;                                                    break;
618
 
                case CPUINFO_INT_MIN_INSTRUCTION_BYTES:                 info->i = 1;                                                    break;
619
 
                case CPUINFO_INT_MAX_INSTRUCTION_BYTES:                 info->i = 8;                                                    break;
620
 
                case CPUINFO_INT_MIN_CYCLES:                                    info->i = 1;                                                    break;
621
 
                case CPUINFO_INT_MAX_CYCLES:                                    info->i = 80;                                                   break;
622
 
 
623
 
                case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM:    info->i = 16;                                   break;
624
 
                case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM:    info->i = 20;                                   break;
625
 
                case DEVINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM:    info->i = 0;                                    break;
626
 
                case DEVINFO_INT_DATABUS_WIDTH + AS_DATA:       info->i = 0;                                    break;
627
 
                case DEVINFO_INT_ADDRBUS_WIDTH + AS_DATA:       info->i = 0;                                    break;
628
 
                case DEVINFO_INT_ADDRBUS_SHIFT + AS_DATA:       info->i = 0;                                    break;
629
 
                case DEVINFO_INT_DATABUS_WIDTH + AS_IO:         info->i = 16;                                   break;
630
 
                case DEVINFO_INT_ADDRBUS_WIDTH + AS_IO:         info->i = 17;                                   break;
631
 
                case DEVINFO_INT_ADDRBUS_SHIFT + AS_IO:         info->i = 0;                                    break;
632
 
 
633
 
                case CPUINFO_INT_INPUT_STATE + 0:                                               info->i = (nec_state->pending_irq & INT_IRQ) ? ASSERT_LINE : CLEAR_LINE; break;
634
 
                case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI:                  info->i = nec_state->nmi_state;                         break;
635
 
                case CPUINFO_INT_INPUT_STATE + NEC_INPUT_LINE_INTP0:    info->i = nec_state->intp_state[0];                     break;
636
 
                case CPUINFO_INT_INPUT_STATE + NEC_INPUT_LINE_INTP1:    info->i = nec_state->intp_state[1];                     break;
637
 
                case CPUINFO_INT_INPUT_STATE + NEC_INPUT_LINE_INTP2:    info->i = nec_state->intp_state[2];                     break;
638
 
                case CPUINFO_INT_INPUT_STATE + NEC_INPUT_LINE_POLL:             info->i = nec_state->poll_state;                        break;
639
 
 
640
 
                case CPUINFO_INT_PREVIOUSPC:                                    /* not supported */                                             break;
641
 
 
642
 
                case CPUINFO_INT_PC:
643
 
                case CPUINFO_INT_REGISTER + NEC_PC:                             info->i = ((Sreg(PS)<<4) + nec_state->ip);      break;
644
 
                case CPUINFO_INT_REGISTER + NEC_IP:                             info->i = nec_state->ip;                                                        break;
645
 
                case CPUINFO_INT_SP:                                                    info->i = (Sreg(SS)<<4) + Wreg(SP); break;
646
 
                case CPUINFO_INT_REGISTER + NEC_SP:                             info->i = Wreg(SP);                                     break;
647
 
                case CPUINFO_INT_REGISTER + NEC_FLAGS:                  info->i = CompressFlags();                              break;
648
 
                case CPUINFO_INT_REGISTER + NEC_AW:                             info->i = Wreg(AW);                                     break;
649
 
                case CPUINFO_INT_REGISTER + NEC_CW:                             info->i = Wreg(CW);                                     break;
650
 
                case CPUINFO_INT_REGISTER + NEC_DW:                             info->i = Wreg(DW);                                     break;
651
 
                case CPUINFO_INT_REGISTER + NEC_BW:                             info->i = Wreg(BW);                                     break;
652
 
                case CPUINFO_INT_REGISTER + NEC_BP:                             info->i = Wreg(BP);                                     break;
653
 
                case CPUINFO_INT_REGISTER + NEC_IX:                             info->i = Wreg(IX);                                     break;
654
 
                case CPUINFO_INT_REGISTER + NEC_IY:                             info->i = Wreg(IY);                                     break;
655
 
                case CPUINFO_INT_REGISTER + NEC_ES:                             info->i = Sreg(DS1);                                    break;
656
 
                case CPUINFO_INT_REGISTER + NEC_CS:                             info->i = Sreg(PS);                                     break;
657
 
                case CPUINFO_INT_REGISTER + NEC_SS:                             info->i = Sreg(SS);                                     break;
658
 
                case CPUINFO_INT_REGISTER + NEC_DS:                             info->i = Sreg(DS0);                                    break;
659
 
                case CPUINFO_INT_REGISTER + NEC_PENDING:                info->i = nec_state->pending_irq;                               break;
660
 
 
661
 
                /* --- the following bits of info are returned as pointers to data or functions --- */
662
 
                case CPUINFO_FCT_SET_INFO:                                              info->setinfo = CPU_SET_INFO_NAME(v25);                 break;
663
 
                case CPUINFO_FCT_INIT:                                                  /* set per-CPU */                                               break;
664
 
                case CPUINFO_FCT_RESET:                                                 info->reset = CPU_RESET_NAME(v25);                              break;
665
 
                case CPUINFO_FCT_EXIT:                                                  info->exit = CPU_EXIT_NAME(v25);                                        break;
666
 
                case CPUINFO_FCT_EXECUTE:                                               info->execute = CPU_EXECUTE_NAME(v25);                  break;
667
 
                case CPUINFO_FCT_BURN:                                                  info->burn = NULL;                                              break;
668
 
                case CPUINFO_FCT_DISASSEMBLE:                                   info->disassemble = CPU_DISASSEMBLE_NAME(v25);                  break;
669
 
                case CPUINFO_PTR_INSTRUCTION_COUNTER:                   info->icount = &nec_state->icount;                              break;
670
 
 
671
 
                /* --- the following bits of info are returned as NULL-terminated strings --- */
672
 
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "NEC");                                 break;
673
 
                case DEVINFO_STR_FAMILY:                                        strcpy(info->s, "NEC V-Series");                break;
674
 
                case DEVINFO_STR_VERSION:                                       strcpy(info->s, "2.0");                                 break;
675
 
                case DEVINFO_STR_SOURCE_FILE:                                           strcpy(info->s, __FILE__);                              break;
676
 
                case DEVINFO_STR_CREDITS:                                       strcpy(info->s, "Bryan McPhail (V25/V35 support added by Alex W. Jackson)"); break;
677
 
 
678
 
                case CPUINFO_STR_FLAGS:
679
 
            flags = CompressFlags();
680
 
            sprintf(info->s, "%c %d %c%c%c%c%c%c%c%c%c%c%c%c",
681
 
                flags & 0x8000 ? 'N':'S',
682
 
                (flags & 0x7000) >> 12,
683
 
                flags & 0x0800 ? 'O':'.',
684
 
                flags & 0x0400 ? 'D':'.',
685
 
                flags & 0x0200 ? 'I':'.',
686
 
                flags & 0x0100 ? 'T':'.',
687
 
                flags & 0x0080 ? 'S':'.',
688
 
                flags & 0x0040 ? 'Z':'.',
689
 
                flags & 0x0020 ? '1':'.',
690
 
                flags & 0x0010 ? 'A':'.',
691
 
                flags & 0x0008 ? '0':'.',
692
 
                flags & 0x0004 ? 'P':'.',
693
 
                flags & 0x0002 ? '.':'I',
694
 
                flags & 0x0001 ? 'C':'.');
695
 
            break;
696
 
 
697
 
        case CPUINFO_STR_REGISTER + NEC_PC:                             sprintf(info->s, "PC:%05X", (Sreg(PS)<<4) + nec_state->ip); break;
698
 
        case CPUINFO_STR_REGISTER + NEC_IP:                             sprintf(info->s, "IP:%04X", nec_state->ip); break;
699
 
        case CPUINFO_STR_REGISTER + NEC_SP:                             sprintf(info->s, "SP:%04X", Wreg(SP)); break;
700
 
        case CPUINFO_STR_REGISTER + NEC_FLAGS:                  sprintf(info->s, "F:%04X", CompressFlags()); break;
701
 
        case CPUINFO_STR_REGISTER + NEC_AW:                             sprintf(info->s, "AW:%04X", Wreg(AW)); break;
702
 
        case CPUINFO_STR_REGISTER + NEC_CW:                             sprintf(info->s, "CW:%04X", Wreg(CW)); break;
703
 
        case CPUINFO_STR_REGISTER + NEC_DW:                             sprintf(info->s, "DW:%04X", Wreg(DW)); break;
704
 
        case CPUINFO_STR_REGISTER + NEC_BW:                             sprintf(info->s, "BW:%04X", Wreg(BW)); break;
705
 
        case CPUINFO_STR_REGISTER + NEC_BP:                             sprintf(info->s, "BP:%04X", Wreg(BP)); break;
706
 
        case CPUINFO_STR_REGISTER + NEC_IX:                             sprintf(info->s, "IX:%04X", Wreg(IX)); break;
707
 
        case CPUINFO_STR_REGISTER + NEC_IY:                             sprintf(info->s, "IY:%04X", Wreg(IY)); break;
708
 
        case CPUINFO_STR_REGISTER + NEC_ES:                             sprintf(info->s, "DS1:%04X", Sreg(DS1)); break;
709
 
        case CPUINFO_STR_REGISTER + NEC_CS:                             sprintf(info->s, "PS:%04X", Sreg(PS)); break;
710
 
        case CPUINFO_STR_REGISTER + NEC_SS:                             sprintf(info->s, "SS:%04X", Sreg(SS)); break;
711
 
        case CPUINFO_STR_REGISTER + NEC_DS:                             sprintf(info->s, "DS0:%04X", Sreg(DS0)); break;
712
 
        }
713
 
}
714
 
 
715
 
 
716
 
/**************************************************************************
717
 
 * CPU-specific set_info
718
 
 **************************************************************************/
719
 
 
720
 
CPU_GET_INFO( v25 )
721
 
{
722
 
        switch (state)
723
 
        {
724
 
                /* --- the following bits of info are returned as 64-bit signed integers --- */
725
 
                case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM:    info->i = 8;                                    break;
726
 
                case DEVINFO_INT_DATABUS_WIDTH + AS_IO:         info->i = 8;                                    break;
727
 
 
728
 
                /* --- the following bits of info are returned as pointers to data or functions --- */
729
 
                case CPUINFO_FCT_INIT:                                                  info->init = CPU_INIT_NAME(v25);                                        break;
730
 
 
731
 
                /* --- the following bits of info are returned as NULL-terminated strings --- */
732
 
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "V25");                                 break;
733
 
 
734
 
                default:                                                                                CPU_GET_INFO_CALL(v25v35);                              break;
735
 
        }
736
 
}
737
 
 
738
 
 
739
 
/**************************************************************************
740
 
 * CPU-specific set_info
741
 
 **************************************************************************/
742
 
 
743
 
CPU_GET_INFO( v35 )
744
 
{
745
 
        switch (state)
746
 
        {
747
 
                /* --- the following bits of info are returned as 64-bit signed integers --- */
748
 
                case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM:    info->i = 16;                                   break;
749
 
                case DEVINFO_INT_DATABUS_WIDTH + AS_IO:         info->i = 16;                                   break;
750
 
 
751
 
                /* --- the following bits of info are returned as pointers to data or functions --- */
752
 
                case CPUINFO_FCT_INIT:                                                  info->init = CPU_INIT_NAME(v35);                                        break;
753
 
 
754
 
                /* --- the following bits of info are returned as NULL-terminated strings --- */
755
 
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "V35");                                 break;
756
 
 
757
 
                default:                                                                                CPU_GET_INFO_CALL(v25v35);                              break;
758
 
        }
759
 
}
760
 
 
761
 
DEFINE_LEGACY_CPU_DEVICE(V25, v25);
762
 
DEFINE_LEGACY_CPU_DEVICE(V35, v35);