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

« back to all changes in this revision

Viewing changes to mess/src/emu/cpu/tlcs900/tlcs900.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
 
Toshiba TLCS-900/H emulation
4
 
 
5
 
This code only supports the 900/H mode which is needed for Neogeo
6
 
Pocket emulation. The 900 and 900/M modes are not supported yet.
7
 
 
8
 
 
9
 
TODO:
10
 
- review cycle counts
11
 
- implement the remaining internal mcu features
12
 
- add support for 900 and 900/M modes
13
 
 
14
 
*******************************************************************/
15
 
 
16
 
#include "emu.h"
17
 
#include "debugger.h"
18
 
#include "tlcs900.h"
19
 
 
20
 
typedef struct _tlcs900_state tlcs900_state;
21
 
struct _tlcs900_state
22
 
{
23
 
        const tlcs900_interface *intf;
24
 
 
25
 
        devcb_resolved_write8   to1;
26
 
        devcb_resolved_write8   to3;
27
 
 
28
 
        /* registers */
29
 
        PAIR    xwa[4];
30
 
        PAIR    xbc[4];
31
 
        PAIR    xde[4];
32
 
        PAIR    xhl[4];
33
 
        PAIR    xix;
34
 
        PAIR    xiy;
35
 
        PAIR    xiz;
36
 
        PAIR    xssp;
37
 
        PAIR    xnsp;
38
 
        PAIR    pc;
39
 
        PAIR    sr;
40
 
        PAIR    f2;     /* f' */
41
 
        /* DMA registers */
42
 
        PAIR    dmas[4];
43
 
        PAIR    dmad[4];
44
 
        PAIR    dmac[4];
45
 
        PAIR    dmam[4];
46
 
 
47
 
        /* Internal timers, irqs, etc */
48
 
        UINT8   reg[0x80];
49
 
        UINT32  timer_pre;
50
 
        UINT8   timer[6];
51
 
        UINT8   tff1;
52
 
        UINT8   tff3;
53
 
        int             timer_change[4];
54
 
 
55
 
        /* Current state of input levels */
56
 
        int             level[TLCS900_NUM_INPUTS];
57
 
        int             check_irqs;
58
 
        int             ad_cycles_left;
59
 
        int             nmi_state;
60
 
 
61
 
        /* used during execution */
62
 
        PAIR    dummy; /* for illegal register references */
63
 
        UINT8   op;
64
 
        PAIR    ea1, ea2;
65
 
        PAIR    imm1, imm2;
66
 
        int     cycles;
67
 
        UINT8   *p1_reg8, *p2_reg8;
68
 
        UINT16  *p1_reg16, *p2_reg16;
69
 
        UINT32  *p1_reg32, *p2_reg32;
70
 
 
71
 
        int halted;
72
 
        int icount;
73
 
        int regbank;
74
 
        device_irq_callback irqcallback;
75
 
        legacy_cpu_device *device;
76
 
        address_space *program;
77
 
};
78
 
 
79
 
 
80
 
/* Internal register defines */
81
 
#define P1                      0x01
82
 
#define P1CR            0x02
83
 
#define P2                      0x06
84
 
#define P2FC            0x09
85
 
#define P5                      0x0d
86
 
#define P5CR            0x10
87
 
#define P5FC            0x11
88
 
#define P6                      0x12
89
 
#define P7                      0x13
90
 
#define P6FC            0x15
91
 
#define P7CR            0x16
92
 
#define P7FC            0x17
93
 
#define P8                      0x18
94
 
#define P9                      0x19
95
 
#define P8CR            0x1a
96
 
#define P8FC            0x1b
97
 
#define PA                      0x1e
98
 
#define PB                      0x1f
99
 
#define TRUN            0x20
100
 
#define TREG0           0x22
101
 
#define TREG1           0x23
102
 
#define T01MOD          0x24
103
 
#define TFFCR           0x25
104
 
#define TREG2           0x26
105
 
#define TREG3           0x27
106
 
#define T23MOD          0x28
107
 
#define TRDC            0x29
108
 
#define PACR            0x2c
109
 
#define PAFC            0x2d
110
 
#define PBCR            0x2e
111
 
#define PBFC            0x2f
112
 
#define TREG4L          0x30
113
 
#define TREG4H          0x31
114
 
#define TREG5L          0x32
115
 
#define TREG5H          0x33
116
 
#define CAP1L           0x34
117
 
#define CAP1H           0x35
118
 
#define CAP2L           0x36
119
 
#define CAP2H           0x37
120
 
#define T4MOD           0x38
121
 
#define T4FFCR          0x39
122
 
#define T45CR           0x3a
123
 
#define MSAR0           0x3c
124
 
#define MAMR0           0x3d
125
 
#define MSAR1           0x3e
126
 
#define MAMR1           0x3f
127
 
#define TREG6L          0x40
128
 
#define TREG6H          0x41
129
 
#define TREG7L          0x42
130
 
#define TREG7H          0x43
131
 
#define CAP3L           0x44
132
 
#define CAP3H           0x45
133
 
#define CAP4L           0x46
134
 
#define CAP4H           0x47
135
 
#define T5MOD           0x48
136
 
#define T5FFCR          0x49
137
 
#define PG0REG          0x4c
138
 
#define PG1REG          0x4d
139
 
#define PG01CR          0x4e
140
 
#define SC0BUF          0x50
141
 
#define SC0CR           0x51
142
 
#define SC0MOD          0x52
143
 
#define BR0CR           0x53
144
 
#define SC1BUF          0x54
145
 
#define SC1CR           0x55
146
 
#define SC1MOD          0x56
147
 
#define BR1CR           0x57
148
 
#define ODE                     0x58
149
 
#define DREFCR          0x5a
150
 
#define DMEMCR          0x5b
151
 
#define MSAR2           0x5c
152
 
#define MAMR2           0x5d
153
 
#define MSAR3           0x5e
154
 
#define MAMR3           0x5f
155
 
#define ADREG0L         0x60
156
 
#define ADREG0H         0x61
157
 
#define ADREG1L         0x62
158
 
#define ADREG1H         0x63
159
 
#define ADREG2L         0x64
160
 
#define ADREG2H         0x65
161
 
#define ADREG3L         0x66
162
 
#define ADREG3H         0x67
163
 
#define B0CS            0x68
164
 
#define B1CS            0x69
165
 
#define B2CS            0x6a
166
 
#define B3CS            0x6b
167
 
#define BEXCS           0x6c
168
 
#define ADMOD           0x6d
169
 
#define WDMOD           0x6e
170
 
#define WDCR            0x6f
171
 
#define INTE0AD         0x70
172
 
#define INTE45          0x71
173
 
#define INTE67          0x72
174
 
#define INTET10         0x73
175
 
#define INTET32         0x74
176
 
#define INTET54         0x75
177
 
#define INTET76         0x76
178
 
#define INTES0          0x77
179
 
#define INTES1          0x78
180
 
#define INTETC10        0x79
181
 
#define INTETC32        0x7a
182
 
#define IIMC            0x7b
183
 
#define DMA0V           0x7c
184
 
#define DMA1V           0x7d
185
 
#define DMA2V           0x7e
186
 
#define DMA3V           0x7f
187
 
 
188
 
 
189
 
/* Flag defines */
190
 
#define FLAG_CF         0x01
191
 
#define FLAG_NF         0x02
192
 
#define FLAG_VF         0x04
193
 
#define FLAG_HF         0x10
194
 
#define FLAG_ZF         0x40
195
 
#define FLAG_SF         0x80
196
 
 
197
 
 
198
 
#define RDMEM(addr)                     cpustate->program->read_byte( addr )
199
 
#define WRMEM(addr,data)        cpustate->program->write_byte( addr, data )
200
 
#define RDOP()                          RDMEM( cpustate->pc.d ); cpustate->pc.d++
201
 
#define RDMEMW(addr)                    ( RDMEM(addr) | ( RDMEM(addr+1) << 8 ) )
202
 
#define RDMEML(addr)                    ( RDMEMW(addr) | ( RDMEMW(addr+2) << 16 ) )
203
 
#define WRMEMW(addr,data)               { UINT16 dw = data; WRMEM(addr,dw & 0xff); WRMEM(addr+1,(dw >> 8 )); }
204
 
#define WRMEML(addr,data)               { UINT32 dl = data; WRMEMW(addr,dl); WRMEMW(addr+2,(dl >> 16)); }
205
 
 
206
 
 
207
 
INLINE tlcs900_state *get_safe_token( device_t *device )
208
 
{
209
 
        assert( device != NULL );
210
 
        assert( device->type() == TLCS900H );
211
 
 
212
 
        return (tlcs900_state *) downcast<legacy_cpu_device *>(device)->token();
213
 
}
214
 
 
215
 
 
216
 
static CPU_INIT( tlcs900 )
217
 
{
218
 
        tlcs900_state *cpustate = get_safe_token(device);
219
 
 
220
 
        cpustate->intf = (const tlcs900_interface *)device->static_config();
221
 
        cpustate->irqcallback = irqcallback;
222
 
        cpustate->device = device;
223
 
        cpustate->program = device->space( AS_PROGRAM );
224
 
 
225
 
        cpustate->to1.resolve(cpustate->intf->to1, *device );
226
 
        cpustate->to3.resolve(cpustate->intf->to3, *device );
227
 
 
228
 
        device->save_item( NAME(cpustate->xwa) );
229
 
        device->save_item( NAME(cpustate->xbc) );
230
 
        device->save_item( NAME(cpustate->xde) );
231
 
        device->save_item( NAME(cpustate->xhl) );
232
 
        device->save_item( NAME(cpustate->xix) );
233
 
        device->save_item( NAME(cpustate->xiy) );
234
 
        device->save_item( NAME(cpustate->xiz) );
235
 
        device->save_item( NAME(cpustate->xssp) );
236
 
        device->save_item( NAME(cpustate->xnsp) );
237
 
        device->save_item( NAME(cpustate->pc) );
238
 
        device->save_item( NAME(cpustate->sr) );
239
 
        device->save_item( NAME(cpustate->f2) );
240
 
        device->save_item( NAME(cpustate->dmas) );
241
 
        device->save_item( NAME(cpustate->dmad) );
242
 
        device->save_item( NAME(cpustate->dmac) );
243
 
        device->save_item( NAME(cpustate->dmam) );
244
 
        device->save_item( NAME(cpustate->reg) );
245
 
        device->save_item( NAME(cpustate->timer_pre) );
246
 
        device->save_item( NAME(cpustate->timer) );
247
 
        device->save_item( NAME(cpustate->tff1) );
248
 
        device->save_item( NAME(cpustate->tff3) );
249
 
        device->save_item( NAME(cpustate->timer_change) );
250
 
        device->save_item( NAME(cpustate->level) );
251
 
        device->save_item( NAME(cpustate->check_irqs) );
252
 
        device->save_item( NAME(cpustate->ad_cycles_left) );
253
 
        device->save_item( NAME(cpustate->nmi_state) );
254
 
}
255
 
 
256
 
 
257
 
static CPU_RESET( tlcs900 )
258
 
{
259
 
        tlcs900_state *cpustate = get_safe_token(device);
260
 
        int i;
261
 
 
262
 
        cpustate->pc.b.l = RDMEM( 0xFFFF00 );
263
 
        cpustate->pc.b.h = RDMEM( 0xFFFF01 );
264
 
        cpustate->pc.b.h2 = RDMEM( 0xFFFF02 );
265
 
        cpustate->pc.b.h3 = 0;
266
 
        /* system mode, iff set to 111, max mode, register bank 0 */
267
 
        cpustate->sr.d = 0xF800;
268
 
        cpustate->regbank = 0;
269
 
        cpustate->xssp.d = 0x0100;
270
 
        cpustate->halted = 0;
271
 
        cpustate->check_irqs = 0;
272
 
        cpustate->ad_cycles_left = 0;
273
 
        cpustate->nmi_state = CLEAR_LINE;
274
 
        cpustate->timer_pre = 0;
275
 
        cpustate->timer_change[0] = 0;
276
 
        cpustate->timer_change[1] = 0;
277
 
        cpustate->timer_change[2] = 0;
278
 
        cpustate->timer_change[3] = 0;
279
 
 
280
 
        cpustate->reg[P1] = 0x00;
281
 
        cpustate->reg[P1CR] = 0x00;
282
 
        cpustate->reg[P2] = 0xff;
283
 
        cpustate->reg[P2FC] = 0x00;
284
 
        cpustate->reg[P5] = 0x3d;
285
 
        cpustate->reg[P5CR] = 0x00;
286
 
        cpustate->reg[P5FC] = 0x00;
287
 
        cpustate->reg[P6] = 0x3b;
288
 
        cpustate->reg[P6FC] = 0x00;
289
 
        cpustate->reg[P7] = 0xff;
290
 
        cpustate->reg[P7CR] = 0x00;
291
 
        cpustate->reg[P7FC] = 0x00;
292
 
        cpustate->reg[P8] = 0x3f;
293
 
        cpustate->reg[P8CR] = 0x00;
294
 
        cpustate->reg[P8FC] = 0x00;
295
 
        cpustate->reg[PA] = 0x0f;
296
 
        cpustate->reg[PACR] = 0x00;
297
 
        cpustate->reg[PAFC] = 0x00;
298
 
        cpustate->reg[PB] = 0xff;
299
 
        cpustate->reg[PBCR] = 0x00;
300
 
        cpustate->reg[PBFC] = 0x00;
301
 
        cpustate->reg[MSAR0] = 0xff;
302
 
        cpustate->reg[MSAR1] = 0xff;
303
 
        cpustate->reg[MSAR2] = 0xff;
304
 
        cpustate->reg[MSAR3] = 0xff;
305
 
        cpustate->reg[MAMR0] = 0xff;
306
 
        cpustate->reg[MAMR1] = 0xff;
307
 
        cpustate->reg[MAMR2] = 0xff;
308
 
        cpustate->reg[MAMR3] = 0xff;
309
 
        cpustate->reg[DREFCR] = 0x00;
310
 
        cpustate->reg[DMEMCR] = 0x80;
311
 
        cpustate->reg[T01MOD] = 0x00;
312
 
        cpustate->reg[T23MOD] = 0x00;
313
 
        cpustate->reg[TFFCR] = 0x00;
314
 
        cpustate->reg[TRUN] = 0x00;
315
 
        cpustate->reg[TRDC] = 0x00;
316
 
        cpustate->reg[T4MOD] = 0x20;
317
 
        cpustate->reg[T4FFCR] = 0x00;
318
 
        cpustate->reg[T5MOD] = 0x20;
319
 
        cpustate->reg[T5FFCR] = 0x00;
320
 
        cpustate->reg[T45CR] = 0x00;
321
 
        cpustate->reg[PG01CR] = 0x00;
322
 
        cpustate->reg[PG0REG] = 0x00;
323
 
        cpustate->reg[PG1REG] = 0x00;
324
 
        cpustate->reg[SC0MOD] = 0x00;
325
 
        cpustate->reg[SC0CR] = 0x00;
326
 
        cpustate->reg[BR0CR] = 0x00;
327
 
        cpustate->reg[SC1MOD] = 0x00;
328
 
        cpustate->reg[SC1CR] = 0x00;
329
 
        cpustate->reg[BR1CR] = 0x00;
330
 
        cpustate->reg[P8FC] = 0x00;
331
 
        cpustate->reg[ODE] = 0x00;
332
 
        cpustate->reg[ADMOD] = 0x00;
333
 
        cpustate->reg[ADREG0L] = 0x3f;
334
 
        cpustate->reg[ADREG1L] = 0x3f;
335
 
        cpustate->reg[ADREG2L] = 0x3f;
336
 
        cpustate->reg[ADREG3L] = 0x3f;
337
 
        cpustate->reg[WDMOD] = 0x80;
338
 
 
339
 
        for ( i = 0; i < TLCS900_NUM_INPUTS; i++ )
340
 
        {
341
 
                cpustate->level[i] = CLEAR_LINE;
342
 
        }
343
 
}
344
 
 
345
 
 
346
 
static CPU_EXIT( tlcs900 )
347
 
{
348
 
}
349
 
 
350
 
 
351
 
#include "900tbl.c"
352
 
 
353
 
 
354
 
#define NUM_MASKABLE_IRQS       22
355
 
static const struct {
356
 
        UINT8 reg;
357
 
        UINT8 iff;
358
 
        UINT8 vector;
359
 
} irq_vector_map[NUM_MASKABLE_IRQS] =
360
 
{
361
 
        { INTETC32, 0x80, 0x80 },       /* INTTC3 */
362
 
        { INTETC32, 0x08, 0x7c },       /* INTTC2 */
363
 
        { INTETC10, 0x80, 0x78 },       /* INTTC1 */
364
 
        { INTETC10, 0x08, 0x74 },       /* INTTC0 */
365
 
        { INTE0AD, 0x80, 0x70 },        /* INTAD */
366
 
        { INTES1, 0x80, 0x6c },         /* INTTX1 */
367
 
        { INTES1, 0x08, 0x68 },         /* INTRX1 */
368
 
        { INTES0, 0x80, 0x64 },         /* INTTX0 */
369
 
        { INTES0, 0x08, 0x60 },         /* INTRX0 */
370
 
        { INTET76, 0x80, 0x5c },        /* INTTR7 */
371
 
        { INTET76, 0x08, 0x58 },        /* INTTR6 */
372
 
        { INTET54, 0x80, 0x54 },        /* INTTR5 */
373
 
        { INTET54, 0x08, 0x50 },        /* INTTR4 */
374
 
        { INTET32, 0x80, 0x4c },        /* INTT3 */
375
 
        { INTET32, 0x08, 0x48 },        /* INTT2 */
376
 
        { INTET10, 0x80, 0x44 },        /* INTT1 */
377
 
        { INTET10, 0x08, 0x40 },        /* INTT0 */
378
 
                                                                /* 0x3c - reserved */
379
 
        { INTE67, 0x80, 0x38 },         /* INT7 */
380
 
        { INTE67, 0x08, 0x34 },         /* INT6 */
381
 
        { INTE45, 0x80, 0x30 },         /* INT5 */
382
 
        { INTE45, 0x08, 0x2c },         /* INT4 */
383
 
        { INTE0AD, 0x08, 0x28 }         /* INT0 */
384
 
};
385
 
 
386
 
 
387
 
INLINE int tlcs900_process_hdma( tlcs900_state *cpustate, int channel )
388
 
{
389
 
        UINT8 vector = ( cpustate->reg[0x7c + channel] & 0x1f ) << 2;
390
 
 
391
 
        /* Check if any HDMA actions should be performed */
392
 
        if ( vector >= 0x28 && vector != 0x3C && vector < 0x74 )
393
 
        {
394
 
                int irq = 0;
395
 
 
396
 
                while( irq < NUM_MASKABLE_IRQS && irq_vector_map[irq].vector != vector )
397
 
                        irq++;
398
 
 
399
 
                /* Check if our interrupt flip-flop is set */
400
 
                if ( irq < NUM_MASKABLE_IRQS && cpustate->reg[irq_vector_map[irq].reg] & irq_vector_map[irq].iff )
401
 
                {
402
 
                        switch( cpustate->dmam[channel].b.l & 0x1f )
403
 
                        {
404
 
                        case 0x00:
405
 
                                WRMEM( cpustate->dmad[channel].d, RDMEM( cpustate->dmas[channel].d ) );
406
 
                                cpustate->dmad[channel].d += 1;
407
 
                                cpustate->cycles += 8;
408
 
                                break;
409
 
                        case 0x01:
410
 
                                WRMEMW( cpustate->dmad[channel].d, RDMEMW( cpustate->dmas[channel].d ) );
411
 
                                cpustate->dmad[channel].d += 2;
412
 
                                cpustate->cycles += 8;
413
 
                                break;
414
 
                        case 0x02:
415
 
                                WRMEML( cpustate->dmad[channel].d, RDMEML( cpustate->dmas[channel].d ) );
416
 
                                cpustate->dmad[channel].d += 4;
417
 
                                cpustate->cycles += 12;
418
 
                                break;
419
 
                        case 0x04:
420
 
                                WRMEM( cpustate->dmad[channel].d, RDMEM( cpustate->dmas[channel].d ) );
421
 
                                cpustate->dmad[channel].d -= 1;
422
 
                                cpustate->cycles += 8;
423
 
                                break;
424
 
                        case 0x05:
425
 
                                WRMEMW( cpustate->dmad[channel].d, RDMEMW( cpustate->dmas[channel].d ) );
426
 
                                cpustate->dmad[channel].d -= 2;
427
 
                                cpustate->cycles += 8;
428
 
                                break;
429
 
                        case 0x06:
430
 
                                WRMEML( cpustate->dmad[channel].d, RDMEML( cpustate->dmas[channel].d ) );
431
 
                                cpustate->dmad[channel].d -= 4;
432
 
                                cpustate->cycles += 12;
433
 
                                break;
434
 
                        case 0x08:
435
 
                                WRMEM( cpustate->dmad[channel].d, RDMEM( cpustate->dmas[channel].d ) );
436
 
                                cpustate->dmas[channel].d += 1;
437
 
                                cpustate->cycles += 8;
438
 
                                break;
439
 
                        case 0x09:
440
 
                                WRMEMW( cpustate->dmad[channel].d, RDMEMW( cpustate->dmas[channel].d ) );
441
 
                                cpustate->dmas[channel].d += 2;
442
 
                                cpustate->cycles += 8;
443
 
                                break;
444
 
                        case 0x0a:
445
 
                                WRMEML( cpustate->dmad[channel].d, RDMEML( cpustate->dmas[channel].d ) );
446
 
                                cpustate->dmas[channel].d += 4;
447
 
                                cpustate->cycles += 12;
448
 
                                break;
449
 
                        case 0x0c:
450
 
                                WRMEM( cpustate->dmad[channel].d, RDMEMW( cpustate->dmas[channel].d ) );
451
 
                                cpustate->dmas[channel].d -= 1;
452
 
                                cpustate->cycles += 8;
453
 
                                break;
454
 
                        case 0x0d:
455
 
                                WRMEMW( cpustate->dmad[channel].d, RDMEMW( cpustate->dmas[channel].d ) );
456
 
                                cpustate->dmas[channel].d -= 2;
457
 
                                cpustate->cycles += 8;
458
 
                                break;
459
 
                        case 0x0e:
460
 
                                WRMEML( cpustate->dmad[channel].d, RDMEML( cpustate->dmas[channel].d ) );
461
 
                                cpustate->dmas[channel].d -= 4;
462
 
                                cpustate->cycles += 12;
463
 
                                break;
464
 
                        case 0x10:
465
 
                                WRMEM( cpustate->dmad[channel].d, RDMEMW( cpustate->dmas[channel].d ) );
466
 
                                cpustate->cycles += 8;
467
 
                                break;
468
 
                        case 0x11:
469
 
                                WRMEMW( cpustate->dmad[channel].d, RDMEMW( cpustate->dmas[channel].d ) );
470
 
                                cpustate->cycles += 8;
471
 
                                break;
472
 
                        case 0x12:
473
 
                                WRMEML( cpustate->dmad[channel].d, RDMEML( cpustate->dmas[channel].d ) );
474
 
                                cpustate->cycles += 12;
475
 
                                break;
476
 
                        case 0x14:
477
 
                                cpustate->dmas[channel].d += 1;
478
 
                                cpustate->cycles += 5;
479
 
                                break;
480
 
                        }
481
 
 
482
 
                        cpustate->dmac[channel].w.l -= 1;
483
 
 
484
 
                        if ( cpustate->dmac[channel].w.l == 0 )
485
 
                        {
486
 
                                cpustate->reg[0x7c + channel] = 0;
487
 
                                switch( channel )
488
 
                                {
489
 
                                case 0:
490
 
                                        cpustate->reg[INTETC10] |= 0x08;
491
 
                                        break;
492
 
                                case 1:
493
 
                                        cpustate->reg[INTETC10] |= 0x80;
494
 
                                        break;
495
 
                                case 2:
496
 
                                        cpustate->reg[INTETC32] |= 0x08;
497
 
                                        break;
498
 
                                case 3:
499
 
                                        cpustate->reg[INTETC32] |= 0x80;
500
 
                                        break;
501
 
                                }
502
 
                        }
503
 
 
504
 
                        /* Clear the interrupt flip-flop */
505
 
                        cpustate->reg[irq_vector_map[irq].reg] &= ~irq_vector_map[irq].iff;
506
 
 
507
 
                        return 1;
508
 
                }
509
 
        }
510
 
        return 0;
511
 
}
512
 
 
513
 
 
514
 
INLINE void tlcs900_check_hdma( tlcs900_state *cpustate )
515
 
{
516
 
        /* HDMA can only be performed if interrupts are allowed */
517
 
        if ( ( cpustate->sr.b.h & 0x70 ) != 0x70 )
518
 
        {
519
 
                if ( ! tlcs900_process_hdma( cpustate, 0 ) )
520
 
                {
521
 
                        if ( ! tlcs900_process_hdma( cpustate, 1 ) )
522
 
                        {
523
 
                                if ( ! tlcs900_process_hdma( cpustate, 2 ) )
524
 
                                {
525
 
                                        tlcs900_process_hdma( cpustate, 3 );
526
 
                                }
527
 
                        }
528
 
                }
529
 
        }
530
 
}
531
 
 
532
 
 
533
 
INLINE void tlcs900_check_irqs( tlcs900_state *cpustate )
534
 
{
535
 
        int irq_vectors[9] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
536
 
        int level = 0;
537
 
        int irq = -1;
538
 
        int i;
539
 
 
540
 
        /* Check for NMI */
541
 
        if ( cpustate->nmi_state == ASSERT_LINE )
542
 
        {
543
 
                cpustate->xssp.d -= 4;
544
 
                WRMEML( cpustate->xssp.d, cpustate->pc.d );
545
 
                cpustate->xssp.d -= 2;
546
 
                WRMEMW( cpustate->xssp.d, cpustate->sr.w.l );
547
 
                cpustate->pc.d = RDMEML( 0xffff00 + 0x20 );
548
 
                cpustate->cycles += 18;
549
 
 
550
 
                cpustate->halted = 0;
551
 
 
552
 
                cpustate->nmi_state = CLEAR_LINE;
553
 
 
554
 
                return;
555
 
        }
556
 
 
557
 
        /* Check regular irqs */
558
 
        for( i = 0; i < NUM_MASKABLE_IRQS; i++ )
559
 
        {
560
 
                if ( cpustate->reg[irq_vector_map[i].reg] & irq_vector_map[i].iff )
561
 
                {
562
 
                        switch( irq_vector_map[i].iff )
563
 
                        {
564
 
                        case 0x80:
565
 
                                irq_vectors[ ( cpustate->reg[ irq_vector_map[i].reg ] >> 4 ) & 0x07 ] = i;
566
 
                                break;
567
 
                        case 0x08:
568
 
                                irq_vectors[ cpustate->reg[ irq_vector_map[i].reg ] & 0x07 ] = i;
569
 
                                break;
570
 
                        }
571
 
                }
572
 
        }
573
 
 
574
 
        /* Check highest allowed priority irq */
575
 
        for ( i = MAX( 1, ( ( cpustate->sr.b.h & 0x70 ) >> 4 ) ); i < 7; i++ )
576
 
        {
577
 
                if ( irq_vectors[i] >= 0 )
578
 
                {
579
 
                        irq = irq_vectors[i];
580
 
                        level = i + 1;
581
 
                }
582
 
        }
583
 
 
584
 
        /* Take irq */
585
 
        if ( irq >= 0 )
586
 
        {
587
 
                UINT8 vector = irq_vector_map[irq].vector;
588
 
 
589
 
                cpustate->xssp.d -= 4;
590
 
                WRMEML( cpustate->xssp.d, cpustate->pc.d );
591
 
                cpustate->xssp.d -= 2;
592
 
                WRMEMW( cpustate->xssp.d, cpustate->sr.w.l );
593
 
 
594
 
                /* Mask off any lower priority interrupts  */
595
 
                cpustate->sr.b.h = ( cpustate->sr.b.h & 0x8f ) | ( level << 4 );
596
 
 
597
 
                cpustate->pc.d = RDMEML( 0xffff00 + vector );
598
 
                cpustate->cycles += 18;
599
 
 
600
 
                cpustate->halted = 0;
601
 
 
602
 
                /* Clear taken IRQ */
603
 
                cpustate->reg[ irq_vector_map[irq].reg ] &= ~ irq_vector_map[irq].iff;
604
 
        }
605
 
}
606
 
 
607
 
 
608
 
INLINE void tlcs900_handle_ad( tlcs900_state *cpustate )
609
 
{
610
 
        if ( cpustate->ad_cycles_left > 0 )
611
 
        {
612
 
                cpustate->ad_cycles_left -= cpustate->cycles;
613
 
                if ( cpustate->ad_cycles_left <= 0 )
614
 
                {
615
 
                        /* Store A/D converted value */
616
 
                        switch( cpustate->reg[ADMOD] & 0x03 )
617
 
                        {
618
 
                        case 0x00:      /* AN0 */
619
 
                                cpustate->reg[ADREG0L] |= 0xc0;
620
 
                                cpustate->reg[ADREG0H] = 0xff;
621
 
                                break;
622
 
                        case 0x01:      /* AN1 */
623
 
                        case 0x02:      /* AN2 */
624
 
                        case 0x03:      /* AN3 */
625
 
                                break;
626
 
                        }
627
 
 
628
 
                        /* Clear BUSY flag, set END flag */
629
 
                        cpustate->reg[ADMOD] &= ~ 0x40;
630
 
                        cpustate->reg[ADMOD] |= 0x80;
631
 
 
632
 
                        cpustate->reg[INTE0AD] |= 0x80;
633
 
                        cpustate->check_irqs = 1;
634
 
                }
635
 
        }
636
 
}
637
 
 
638
 
 
639
 
enum ff_change
640
 
{
641
 
        FF_CLEAR,
642
 
        FF_SET,
643
 
        FF_INVERT
644
 
};
645
 
 
646
 
 
647
 
INLINE void tlcs900_change_tff( tlcs900_state *cpustate, int which, int change )
648
 
{
649
 
        switch( which )
650
 
        {
651
 
        case 1:
652
 
                switch( change )
653
 
                {
654
 
                case FF_CLEAR:
655
 
                        cpustate->tff1 = 0;
656
 
                        break;
657
 
                case FF_SET:
658
 
                        cpustate->tff1 = 1;
659
 
                        break;
660
 
                case FF_INVERT:
661
 
                        cpustate->tff1 ^= 1;
662
 
                        break;
663
 
                }
664
 
                if ( !cpustate->to1.isnull() )
665
 
                        cpustate->to1(0, cpustate->tff1 );
666
 
                break;
667
 
 
668
 
        case 3:
669
 
                switch( change )
670
 
                {
671
 
                case FF_CLEAR:
672
 
                        cpustate->tff3 = 0;
673
 
                        break;
674
 
                case FF_SET:
675
 
                        cpustate->tff3 = 1;
676
 
                        break;
677
 
                case FF_INVERT:
678
 
                        cpustate->tff3 ^= 1;
679
 
                        break;
680
 
                }
681
 
                if ( !cpustate->to3.isnull() )
682
 
                        cpustate->to3(0, cpustate->tff3 );
683
 
                break;
684
 
        }
685
 
}
686
 
 
687
 
 
688
 
INLINE void tlcs900_handle_timers( tlcs900_state *cpustate )
689
 
{
690
 
        UINT32  old_pre = cpustate->timer_pre;
691
 
 
692
 
        /* Is the pre-scaler active */
693
 
        if ( cpustate->reg[TRUN] & 0x80 )
694
 
                cpustate->timer_pre += cpustate->cycles;
695
 
 
696
 
        /* Timer 0 */
697
 
        if ( cpustate->reg[TRUN] & 0x01 )
698
 
        {
699
 
                switch( cpustate->reg[T01MOD] & 0x03 )
700
 
                {
701
 
                case 0x00:      /* TIO */
702
 
                        break;
703
 
                case 0x01:      /* T1 */
704
 
                        cpustate->timer_change[0] += ( cpustate->timer_pre >> 7 ) - ( old_pre >> 7 );
705
 
                        break;
706
 
                case 0x02:      /* T4 */
707
 
                        cpustate->timer_change[0] += ( cpustate->timer_pre >> 9 ) - ( old_pre >> 9 );
708
 
                        break;
709
 
                case 0x03:      /* T16 */
710
 
                        cpustate->timer_change[0] += ( cpustate->timer_pre >> 11 ) - ( old_pre >> 11 );
711
 
                        break;
712
 
                }
713
 
 
714
 
                for( ; cpustate->timer_change[0] > 0; cpustate->timer_change[0]-- )
715
 
                {
716
 
//printf("timer0 = %02x, TREG0 = %02x\n", cpustate->timer[0], cpustate->reg[TREG0] );
717
 
                        cpustate->timer[0] += 1;
718
 
                        if ( cpustate->timer[0] == cpustate->reg[TREG0] )
719
 
                        {
720
 
                                if ( ( cpustate->reg[T01MOD] & 0x0c ) == 0x00 )
721
 
                                {
722
 
                                        cpustate->timer_change[1] += 1;
723
 
                                }
724
 
 
725
 
                                /* In 16bit timer mode the timer should not be reset */
726
 
                                if ( ( cpustate->reg[T01MOD] & 0xc0 ) != 0x40 )
727
 
                                {
728
 
                                        cpustate->timer[0] = 0;
729
 
                                        cpustate->reg[INTET10] |= 0x08;
730
 
                                }
731
 
                        }
732
 
                }
733
 
        }
734
 
 
735
 
        /* Timer 1 */
736
 
        if ( cpustate->reg[TRUN] & 0x02 )
737
 
        {
738
 
                switch( ( cpustate->reg[T01MOD] >> 2 ) & 0x03 )
739
 
                {
740
 
                case 0x00:      /* TO0TRG */
741
 
                        break;
742
 
                case 0x01:      /* T1 */
743
 
                        cpustate->timer_change[1] += ( cpustate->timer_pre >> 7 ) - ( old_pre >> 7 );
744
 
                        break;
745
 
                case 0x02:      /* T16 */
746
 
                        cpustate->timer_change[1] += ( cpustate->timer_pre >> 11 ) - ( old_pre >> 11 );
747
 
                        break;
748
 
                case 0x03:      /* T256 */
749
 
                        cpustate->timer_change[1] += ( cpustate->timer_pre >> 15 ) - ( old_pre >> 15 );
750
 
                        break;
751
 
                }
752
 
 
753
 
                for( ; cpustate->timer_change[1] > 0; cpustate->timer_change[1]-- )
754
 
                {
755
 
                        cpustate->timer[1] += 1;
756
 
                        if ( cpustate->timer[1] == cpustate->reg[TREG1] )
757
 
                        {
758
 
                                cpustate->timer[1] = 0;
759
 
                                cpustate->reg[INTET10] |= 0x80;
760
 
 
761
 
                                if ( cpustate->reg[TFFCR] & 0x02 )
762
 
                                {
763
 
                                        tlcs900_change_tff( cpustate, 1, FF_INVERT );
764
 
                                }
765
 
 
766
 
                                /* In 16bit timer mode also reset timer 0 */
767
 
                                if ( ( cpustate->reg[T01MOD] & 0xc0 ) == 0x40 )
768
 
                                {
769
 
                                        cpustate->timer[0] = 0;
770
 
                                }
771
 
                        }
772
 
                }
773
 
        }
774
 
 
775
 
        /* Timer 2 */
776
 
        if ( cpustate->reg[TRUN] & 0x04 )
777
 
        {
778
 
                switch( cpustate->reg[T23MOD] & 0x03 )
779
 
                {
780
 
                case 0x00:      /* invalid */
781
 
                case 0x01:      /* T1 */
782
 
                        cpustate->timer_change[2] += ( cpustate->timer_pre >> 7 ) - ( old_pre >> 7 );
783
 
                        break;
784
 
                case 0x02:      /* T4 */
785
 
                        cpustate->timer_change[2] += ( cpustate->timer_pre >> 9 ) - ( old_pre >> 9 );
786
 
                        break;
787
 
                case 0x03:      /* T16 */
788
 
                        cpustate->timer_change[2] += ( cpustate->timer_pre >> 11 ) - ( old_pre >> 11 );
789
 
                        break;
790
 
                }
791
 
 
792
 
                for( ; cpustate->timer_change[2] > 0; cpustate->timer_change[2]-- )
793
 
                {
794
 
                        cpustate->timer[2] += 1;
795
 
                        if ( cpustate->timer[2] == cpustate->reg[TREG2] )
796
 
                        {
797
 
                                if ( ( cpustate->reg[T23MOD] & 0x0c ) == 0x00 )
798
 
                                {
799
 
                                        cpustate->timer_change[3] += 1;
800
 
                                }
801
 
 
802
 
                                /* In 16bit timer mode the timer should not be reset */
803
 
                                if ( ( cpustate->reg[T23MOD] & 0xc0 ) != 0x40 )
804
 
                                {
805
 
                                        cpustate->timer[2] = 0;
806
 
                                        cpustate->reg[INTET32] |= 0x08;
807
 
                                }
808
 
                        }
809
 
                }
810
 
        }
811
 
 
812
 
        /* Timer 3 */
813
 
        if ( cpustate->reg[TRUN] & 0x08 )
814
 
        {
815
 
                switch( ( cpustate->reg[T23MOD] >> 2 ) & 0x03 )
816
 
                {
817
 
                case 0x00:      /* TO2TRG */
818
 
                        break;
819
 
                case 0x01:      /* T1 */
820
 
                        cpustate->timer_change[3] += ( cpustate->timer_pre >> 7 ) - ( old_pre >> 7 );
821
 
                        break;
822
 
                case 0x02:      /* T16 */
823
 
                        cpustate->timer_change[3] += ( cpustate->timer_pre >> 11 ) - ( old_pre >> 11 );
824
 
                        break;
825
 
                case 0x03:      /* T256 */
826
 
                        cpustate->timer_change[3] += ( cpustate->timer_pre >> 15 ) - ( old_pre >> 15 );
827
 
                        break;
828
 
                }
829
 
 
830
 
                for( ; cpustate->timer_change[3] > 0; cpustate->timer_change[3]-- )
831
 
                {
832
 
                        cpustate->timer[3] += 1;
833
 
                        if ( cpustate->timer[3] == cpustate->reg[TREG3] )
834
 
                        {
835
 
                                cpustate->timer[3] = 0;
836
 
                                cpustate->reg[INTET32] |= 0x80;
837
 
 
838
 
                                if ( cpustate->reg[TFFCR] & 0x20 )
839
 
                                {
840
 
                                        tlcs900_change_tff( cpustate, 3, FF_INVERT );
841
 
                                }
842
 
 
843
 
                                /* In 16bit timer mode also reset timer 2 */
844
 
                                if ( ( cpustate->reg[T23MOD] & 0xc0 ) == 0x40 )
845
 
                                {
846
 
                                        cpustate->timer[2] = 0;
847
 
                                }
848
 
                        }
849
 
                }
850
 
        }
851
 
 
852
 
        cpustate->timer_pre &= 0xffffff;
853
 
}
854
 
 
855
 
 
856
 
static CPU_EXECUTE( tlcs900 )
857
 
{
858
 
        tlcs900_state *cpustate = get_safe_token(device);
859
 
 
860
 
        do
861
 
        {
862
 
                const tlcs900inst *inst;
863
 
 
864
 
                cpustate->cycles = 0;
865
 
 
866
 
                if ( cpustate->check_irqs )
867
 
                {
868
 
                        tlcs900_check_irqs( cpustate );
869
 
                        cpustate->check_irqs = 0;
870
 
                }
871
 
 
872
 
                debugger_instruction_hook( device, cpustate->pc.d );
873
 
 
874
 
                if ( cpustate->halted )
875
 
                {
876
 
                        cpustate->cycles += 8;
877
 
                }
878
 
                else
879
 
                {
880
 
                        cpustate->op = RDOP();
881
 
                        inst = &mnemonic[cpustate->op];
882
 
                        prepare_operands( cpustate, inst );
883
 
 
884
 
                        /* Execute the instruction */
885
 
                        inst->opfunc( cpustate );
886
 
                        cpustate->cycles += inst->cycles;
887
 
                }
888
 
 
889
 
                tlcs900_handle_ad( cpustate );
890
 
 
891
 
                tlcs900_handle_timers( cpustate );
892
 
 
893
 
                tlcs900_check_hdma( cpustate );
894
 
 
895
 
                cpustate->icount -= cpustate->cycles;
896
 
        } while ( cpustate->icount > 0 );
897
 
}
898
 
 
899
 
 
900
 
static void tlcs900_input_level_change( tlcs900_state *cpustate, int input, int level )
901
 
{
902
 
        switch( input )
903
 
        {
904
 
        case INPUT_LINE_NMI:
905
 
        case TLCS900_NMI:
906
 
                if ( cpustate->level[TLCS900_NMI] == CLEAR_LINE && level == ASSERT_LINE )
907
 
                {
908
 
                        cpustate->nmi_state = level;
909
 
                }
910
 
                cpustate->level[TLCS900_NMI] = level;
911
 
                break;
912
 
 
913
 
        case TLCS900_INTWD:
914
 
                break;
915
 
 
916
 
        case TLCS900_INT0:
917
 
                /* Is INT0 functionality enabled? */
918
 
                if ( cpustate->reg[IIMC] & 0x04 )
919
 
                {
920
 
                        if ( cpustate->reg[IIMC] & 0x02 )
921
 
                        {
922
 
                                /* Rising edge detect */
923
 
                                if ( cpustate->level[TLCS900_INT0] == CLEAR_LINE && level == ASSERT_LINE )
924
 
                                {
925
 
                                        /* Leave HALT state */
926
 
                                        cpustate->halted = 0;
927
 
                                        cpustate->reg[INTE0AD] |= 0x08;
928
 
                                }
929
 
                        }
930
 
                        else
931
 
                        {
932
 
                                /* Level detect */
933
 
                                if ( level == ASSERT_LINE )
934
 
                                        cpustate->reg[INTE0AD] |= 0x08;
935
 
                                else
936
 
                                        cpustate->reg[INTE0AD] &= ~ 0x08;
937
 
                        }
938
 
                }
939
 
                cpustate->level[TLCS900_INT0] = level;
940
 
                break;
941
 
 
942
 
        case TLCS900_INT4:
943
 
                if ( ! ( cpustate->reg[PBCR] & 0x01 ) )
944
 
                {
945
 
                        if ( cpustate->level[TLCS900_INT4] == CLEAR_LINE && level == ASSERT_LINE )
946
 
                        {
947
 
                                cpustate->reg[INTE45] |= 0x08;
948
 
                        }
949
 
                }
950
 
                cpustate->level[TLCS900_INT4] = level;
951
 
                break;
952
 
 
953
 
        case TLCS900_INT5:
954
 
                if ( ! ( cpustate->reg[PBCR] & 0x02 ) )
955
 
                {
956
 
                        if ( cpustate->level[TLCS900_INT5] == CLEAR_LINE && level == ASSERT_LINE )
957
 
                        {
958
 
                                cpustate->reg[INTE45] |= 0x80;
959
 
                        }
960
 
                }
961
 
                cpustate->level[TLCS900_INT5] = level;
962
 
                break;
963
 
 
964
 
        case TLCS900_TIO:       /* External timer input for timer 0 */
965
 
                if ( ( cpustate->reg[TRUN] & 0x01 ) && ( cpustate->reg[T01MOD] & 0x03 ) == 0x00 )
966
 
                {
967
 
                        if ( cpustate->level[TLCS900_TIO] == CLEAR_LINE && level == ASSERT_LINE )
968
 
                        {
969
 
                                cpustate->timer_change[0] += 1;
970
 
                        }
971
 
                }
972
 
                cpustate->level[TLCS900_TIO] = level;
973
 
                break;
974
 
        }
975
 
        cpustate->check_irqs = 1;
976
 
}
977
 
 
978
 
 
979
 
static READ8_HANDLER( tlcs900_internal_r )
980
 
{
981
 
        tlcs900_state *cpustate = get_safe_token( &space->device() );
982
 
 
983
 
        return cpustate->reg[ offset ];
984
 
}
985
 
 
986
 
 
987
 
static WRITE8_HANDLER( tlcs900_internal_w )
988
 
{
989
 
        tlcs900_state *cpustate = get_safe_token( &space->device() );
990
 
 
991
 
        switch ( offset )
992
 
        {
993
 
        case TRUN:
994
 
                if ( ! ( data & 0x01 ) )
995
 
                {
996
 
                        cpustate->timer[0] = 0;
997
 
                        cpustate->timer_change[0] = 0;
998
 
                }
999
 
                if ( ! ( data & 0x02 ) )
1000
 
                {
1001
 
                        cpustate->timer[1] = 0;
1002
 
                        cpustate->timer_change[1] = 0;
1003
 
                }
1004
 
                if ( ! ( data & 0x04 ) )
1005
 
                {
1006
 
                        cpustate->timer[2] = 0;
1007
 
                        cpustate->timer_change[2] = 0;
1008
 
                }
1009
 
                if ( ! ( data & 0x08 ) )
1010
 
                {
1011
 
                        cpustate->timer[3] = 0;
1012
 
                        cpustate->timer_change[3] = 0;
1013
 
                }
1014
 
                if ( ! ( data & 0x10 ) )
1015
 
                        cpustate->timer[4] = 0;
1016
 
                if ( ! ( data & 0x20 ) )
1017
 
                        cpustate->timer[5] = 0;
1018
 
                break;
1019
 
 
1020
 
        case TFFCR:
1021
 
                switch( data & 0x0c )
1022
 
                {
1023
 
                case 0x00:
1024
 
                        tlcs900_change_tff( cpustate, 1, FF_INVERT );
1025
 
                        break;
1026
 
                case 0x04:
1027
 
                        tlcs900_change_tff( cpustate, 1, FF_SET );
1028
 
                        break;
1029
 
                case 0x08:
1030
 
                        tlcs900_change_tff( cpustate, 1, FF_CLEAR );
1031
 
                        break;
1032
 
                }
1033
 
                switch( data & 0xc0 )
1034
 
                {
1035
 
                case 0x00:
1036
 
                        tlcs900_change_tff( cpustate, 3, FF_INVERT );
1037
 
                        break;
1038
 
                case 0x40:
1039
 
                        tlcs900_change_tff( cpustate, 3, FF_SET );
1040
 
                        break;
1041
 
                case 0x80:
1042
 
                        tlcs900_change_tff( cpustate, 3, FF_CLEAR );
1043
 
                        break;
1044
 
                }
1045
 
                break;
1046
 
        case MSAR0:
1047
 
        case MAMR0:
1048
 
        case MSAR1:
1049
 
        case MAMR1:
1050
 
                break;
1051
 
 
1052
 
        case ADMOD:
1053
 
                /* Preserve read-only bits */
1054
 
                data = ( cpustate->reg[ADMOD] & 0xc0 ) | ( data & 0x3f );
1055
 
 
1056
 
                /* Check for A/D request start */
1057
 
                if ( data & 0x04 )
1058
 
                {
1059
 
                        data &= ~0x04;
1060
 
                        data |= 0x40;
1061
 
                        cpustate->ad_cycles_left = ( data & 0x08 ) ? 640 : 320;
1062
 
                }
1063
 
                break;
1064
 
 
1065
 
        case WDMOD:
1066
 
        case WDCR:
1067
 
                break;
1068
 
 
1069
 
        case INTE0AD:
1070
 
        case INTE45:
1071
 
        case INTE67:
1072
 
        case INTET10:
1073
 
        case INTET32:
1074
 
        case INTET54:
1075
 
        case INTET76:
1076
 
        case INTES0:
1077
 
        case INTES1:
1078
 
        case INTETC10:
1079
 
        case INTETC32:
1080
 
                if ( data & 0x80 )
1081
 
                        data = ( data & 0x7f ) | ( cpustate->reg[offset] & 0x80 );
1082
 
                if ( data & 0x08 )
1083
 
                        data = ( data & 0xf7 ) | ( cpustate->reg[offset] & 0x08 );
1084
 
                break;
1085
 
 
1086
 
        case IIMC:
1087
 
                break;
1088
 
 
1089
 
        default:
1090
 
                break;
1091
 
        }
1092
 
 
1093
 
        cpustate->check_irqs = 1;
1094
 
        cpustate->reg[ offset ] = data;
1095
 
}
1096
 
 
1097
 
 
1098
 
static ADDRESS_MAP_START( tlcs900_mem, AS_PROGRAM, 8 )
1099
 
        AM_RANGE( 0x000000, 0x00007f ) AM_READWRITE( tlcs900_internal_r, tlcs900_internal_w )
1100
 
ADDRESS_MAP_END
1101
 
 
1102
 
 
1103
 
static CPU_SET_INFO( tlcs900 )
1104
 
{
1105
 
        tlcs900_state *cpustate = get_safe_token( device );
1106
 
 
1107
 
        switch ( state )
1108
 
        {
1109
 
        case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI:
1110
 
        case CPUINFO_INT_INPUT_STATE + TLCS900_NMI:
1111
 
        case CPUINFO_INT_INPUT_STATE + TLCS900_INTWD:
1112
 
        case CPUINFO_INT_INPUT_STATE + TLCS900_INT0:
1113
 
        case CPUINFO_INT_INPUT_STATE + TLCS900_INT4:
1114
 
        case CPUINFO_INT_INPUT_STATE + TLCS900_INT5:
1115
 
        case CPUINFO_INT_INPUT_STATE + TLCS900_TIO:
1116
 
                tlcs900_input_level_change( cpustate, state - CPUINFO_INT_INPUT_STATE, info->i ); break;
1117
 
        }
1118
 
}
1119
 
 
1120
 
 
1121
 
CPU_GET_INFO( tlcs900h )
1122
 
{
1123
 
        tlcs900_state *cpustate = ( device != NULL && device->token() != NULL ) ? get_safe_token(device) : NULL;
1124
 
 
1125
 
        switch( state )
1126
 
        {
1127
 
        case CPUINFO_INT_CONTEXT_SIZE:                                  info->i = sizeof(tlcs900_state); break;
1128
 
        case DEVINFO_INT_ENDIANNESS:                                    info->i = ENDIANNESS_LITTLE; break;
1129
 
        case CPUINFO_INT_CLOCK_MULTIPLIER:                              info->i = 1; break;
1130
 
        case CPUINFO_INT_CLOCK_DIVIDER:                                 info->i = 1; break;
1131
 
        case CPUINFO_INT_MIN_INSTRUCTION_BYTES:                 info->i = 1; break;
1132
 
        case CPUINFO_INT_MAX_INSTRUCTION_BYTES:                 info->i = 7; break;     /* FIXME */
1133
 
        case CPUINFO_INT_MIN_CYCLES:                                    info->i = 1; break; /* FIXME */
1134
 
        case CPUINFO_INT_MAX_CYCLES:                                    info->i = 1; break; /* FIXME */
1135
 
        case CPUINFO_INT_INPUT_LINES:                                   info->i = 1; break;
1136
 
 
1137
 
        case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM:                    info->i = 8; break;
1138
 
        case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM:                    info->i = 24; break;
1139
 
        case DEVINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM:                    info->i = 0; break;
1140
 
 
1141
 
        case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI:
1142
 
        case CPUINFO_INT_INPUT_STATE + TLCS900_NMI:             info->i = cpustate->level[TLCS900_NMI]; break;
1143
 
        case CPUINFO_INT_INPUT_STATE + TLCS900_INTWD:   info->i = cpustate->level[TLCS900_INTWD]; break;
1144
 
        case CPUINFO_INT_INPUT_STATE + TLCS900_INT0:    info->i = cpustate->level[TLCS900_INT0]; break;
1145
 
        case CPUINFO_INT_INPUT_STATE + TLCS900_INT4:    info->i = cpustate->level[TLCS900_INT4]; break;
1146
 
        case CPUINFO_INT_INPUT_STATE + TLCS900_INT5:    info->i = cpustate->level[TLCS900_INT5]; break;
1147
 
        case CPUINFO_INT_INPUT_STATE + TLCS900_TIO:             info->i = cpustate->level[TLCS900_TIO]; break;
1148
 
 
1149
 
        case CPUINFO_INT_PC:                                                    info->i = cpustate->pc.d; break;
1150
 
        case CPUINFO_INT_REGISTER + TLCS900_PC:                 info->i = cpustate->pc.d; break;
1151
 
        case CPUINFO_INT_REGISTER + TLCS900_SR:                 info->i = cpustate->sr.d; break;
1152
 
        case CPUINFO_INT_REGISTER + TLCS900_XWA0:               info->i = cpustate->xwa[0].d; break;
1153
 
        case CPUINFO_INT_REGISTER + TLCS900_XBC0:               info->i = cpustate->xbc[0].d; break;
1154
 
        case CPUINFO_INT_REGISTER + TLCS900_XDE0:               info->i = cpustate->xde[0].d; break;
1155
 
        case CPUINFO_INT_REGISTER + TLCS900_XHL0:               info->i = cpustate->xhl[0].d; break;
1156
 
        case CPUINFO_INT_REGISTER + TLCS900_XWA1:               info->i = cpustate->xwa[1].d; break;
1157
 
        case CPUINFO_INT_REGISTER + TLCS900_XBC1:               info->i = cpustate->xbc[1].d; break;
1158
 
        case CPUINFO_INT_REGISTER + TLCS900_XDE1:               info->i = cpustate->xde[1].d; break;
1159
 
        case CPUINFO_INT_REGISTER + TLCS900_XHL1:               info->i = cpustate->xhl[1].d; break;
1160
 
        case CPUINFO_INT_REGISTER + TLCS900_XWA2:               info->i = cpustate->xwa[2].d; break;
1161
 
        case CPUINFO_INT_REGISTER + TLCS900_XBC2:               info->i = cpustate->xbc[2].d; break;
1162
 
        case CPUINFO_INT_REGISTER + TLCS900_XDE2:               info->i = cpustate->xde[2].d; break;
1163
 
        case CPUINFO_INT_REGISTER + TLCS900_XHL2:               info->i = cpustate->xhl[2].d; break;
1164
 
        case CPUINFO_INT_REGISTER + TLCS900_XWA3:               info->i = cpustate->xwa[3].d; break;
1165
 
        case CPUINFO_INT_REGISTER + TLCS900_XBC3:               info->i = cpustate->xbc[3].d; break;
1166
 
        case CPUINFO_INT_REGISTER + TLCS900_XDE3:               info->i = cpustate->xde[3].d; break;
1167
 
        case CPUINFO_INT_REGISTER + TLCS900_XHL3:               info->i = cpustate->xhl[3].d; break;
1168
 
        case CPUINFO_INT_REGISTER + TLCS900_XIX:                info->i = cpustate->xix.d; break;
1169
 
        case CPUINFO_INT_REGISTER + TLCS900_XIY:                info->i = cpustate->xiy.d; break;
1170
 
        case CPUINFO_INT_REGISTER + TLCS900_XIZ:                info->i = cpustate->xiz.d; break;
1171
 
        case CPUINFO_INT_REGISTER + TLCS900_XNSP:               info->i = cpustate->xnsp.d; break;
1172
 
        case CPUINFO_INT_REGISTER + TLCS900_XSSP:               info->i = cpustate->xssp.d; break;
1173
 
 
1174
 
        case CPUINFO_FCT_SET_INFO:                                              info->setinfo = CPU_SET_INFO_NAME(tlcs900); break;
1175
 
        case CPUINFO_FCT_INIT:                                                  info->init = CPU_INIT_NAME(tlcs900); break;
1176
 
        case CPUINFO_FCT_RESET:                                                 info->reset = CPU_RESET_NAME(tlcs900); break;
1177
 
        case CPUINFO_FCT_EXIT:                                                  info->exit = CPU_EXIT_NAME(tlcs900); break;
1178
 
        case CPUINFO_FCT_EXECUTE:                                               info->execute = CPU_EXECUTE_NAME(tlcs900); break;
1179
 
        case CPUINFO_FCT_DISASSEMBLE:                                   info->disassemble = CPU_DISASSEMBLE_NAME(tlcs900); break;
1180
 
        case CPUINFO_PTR_INSTRUCTION_COUNTER:                   info->icount = &cpustate->icount; break;
1181
 
        case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM:      info->internal_map8 = ADDRESS_MAP_NAME(tlcs900_mem); break;
1182
 
 
1183
 
        case CPUINFO_STR_REGISTER + TLCS900_PC:                 sprintf( info->s, "PC:%08x", cpustate->pc.d ); break;
1184
 
        case CPUINFO_STR_REGISTER + TLCS900_SR:                 sprintf( info->s, "SR:%c%d%c%d%c%c%c%c%c%c%c%c",
1185
 
                                                                                                                cpustate->sr.w.l & 0x8000 ? 'S' : 'U',
1186
 
                                                                                                                ( cpustate->sr.w.l & 0x7000 ) >> 12,
1187
 
                                                                                                                cpustate->sr.w.l & 0x0800 ? 'M' : 'N',
1188
 
                                                                                                                ( cpustate->sr.w.l & 0x0700 ) >> 8,
1189
 
                                                                                                                cpustate->sr.w.l & 0x0080 ? 'S' : '.',
1190
 
                                                                                                                cpustate->sr.w.l & 0x0040 ? 'Z' : '.',
1191
 
                                                                                                                cpustate->sr.w.l & 0x0020 ? '1' : '.',
1192
 
                                                                                                                cpustate->sr.w.l & 0x0010 ? 'H' : '.',
1193
 
                                                                                                                cpustate->sr.w.l & 0x0008 ? '1' : '.',
1194
 
                                                                                                                cpustate->sr.w.l & 0x0004 ? 'V' : '.',
1195
 
                                                                                                                cpustate->sr.w.l & 0x0002 ? 'N' : '.',
1196
 
                                                                                                                cpustate->sr.w.l & 0x0001 ? 'C' : '.' );
1197
 
                                                                                                        break;
1198
 
        case CPUINFO_STR_REGISTER + TLCS900_XWA0:               sprintf( info->s, "XWA0:%08x", cpustate->xwa[0].d ); break;
1199
 
        case CPUINFO_STR_REGISTER + TLCS900_XBC0:               sprintf( info->s, "XBC0:%08x", cpustate->xbc[0].d ); break;
1200
 
        case CPUINFO_STR_REGISTER + TLCS900_XDE0:               sprintf( info->s, "XDE0:%08x", cpustate->xde[0].d ); break;
1201
 
        case CPUINFO_STR_REGISTER + TLCS900_XHL0:               sprintf( info->s, "XHL0:%08x", cpustate->xhl[0].d ); break;
1202
 
        case CPUINFO_STR_REGISTER + TLCS900_XWA1:               sprintf( info->s, "XWA1:%08x", cpustate->xwa[1].d ); break;
1203
 
        case CPUINFO_STR_REGISTER + TLCS900_XBC1:               sprintf( info->s, "XBC1:%08x", cpustate->xbc[1].d ); break;
1204
 
        case CPUINFO_STR_REGISTER + TLCS900_XDE1:               sprintf( info->s, "XDE1:%08x", cpustate->xde[1].d ); break;
1205
 
        case CPUINFO_STR_REGISTER + TLCS900_XHL1:               sprintf( info->s, "XHL1:%08x", cpustate->xhl[1].d ); break;
1206
 
        case CPUINFO_STR_REGISTER + TLCS900_XWA2:               sprintf( info->s, "XWA2:%08x", cpustate->xwa[2].d ); break;
1207
 
        case CPUINFO_STR_REGISTER + TLCS900_XBC2:               sprintf( info->s, "XBC2:%08x", cpustate->xbc[2].d ); break;
1208
 
        case CPUINFO_STR_REGISTER + TLCS900_XDE2:               sprintf( info->s, "XDE2:%08x", cpustate->xde[2].d ); break;
1209
 
        case CPUINFO_STR_REGISTER + TLCS900_XHL2:               sprintf( info->s, "XHL2:%08x", cpustate->xhl[2].d ); break;
1210
 
        case CPUINFO_STR_REGISTER + TLCS900_XWA3:               sprintf( info->s, "XWA3:%08x", cpustate->xwa[3].d ); break;
1211
 
        case CPUINFO_STR_REGISTER + TLCS900_XBC3:               sprintf( info->s, "XBC3:%08x", cpustate->xbc[3].d ); break;
1212
 
        case CPUINFO_STR_REGISTER + TLCS900_XDE3:               sprintf( info->s, "XDE3:%08x", cpustate->xde[3].d ); break;
1213
 
        case CPUINFO_STR_REGISTER + TLCS900_XHL3:               sprintf( info->s, "XHL3:%08x", cpustate->xhl[3].d ); break;
1214
 
        case CPUINFO_STR_REGISTER + TLCS900_XIX:                sprintf( info->s, "XIX:%08x", cpustate->xix.d ); break;
1215
 
        case CPUINFO_STR_REGISTER + TLCS900_XIY:                sprintf( info->s, "XIY:%08x", cpustate->xiy.d ); break;
1216
 
        case CPUINFO_STR_REGISTER + TLCS900_XIZ:                sprintf( info->s, "XIZ:%08x", cpustate->xiz.d ); break;
1217
 
        case CPUINFO_STR_REGISTER + TLCS900_XNSP:               sprintf( info->s, "XNSP:%08x", cpustate->xnsp.d ); break;
1218
 
        case CPUINFO_STR_REGISTER + TLCS900_XSSP:               sprintf( info->s, "XSSP:%08x", cpustate->xssp.d ); break;
1219
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAS0:              sprintf( info->s, "DMAS0:%08x", cpustate->dmas[0].d ); break;
1220
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAD0:              sprintf( info->s, "DMAD0:%08x", cpustate->dmad[0].d ); break;
1221
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAC0:              sprintf( info->s, "DMAC0:%04x", cpustate->dmac[0].w.l ); break;
1222
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAM0:              sprintf( info->s, "DMAM0:%02x", cpustate->dmam[0].b.l ); break;
1223
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAS1:              sprintf( info->s, "DMAS0:%08x", cpustate->dmas[1].d ); break;
1224
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAD1:              sprintf( info->s, "DMAD0:%08x", cpustate->dmad[1].d ); break;
1225
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAC1:              sprintf( info->s, "DMAC0:%04x", cpustate->dmac[1].w.l ); break;
1226
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAM1:              sprintf( info->s, "DMAM0:%02x", cpustate->dmam[1].b.l ); break;
1227
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAS2:              sprintf( info->s, "DMAS0:%08x", cpustate->dmas[2].d ); break;
1228
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAD2:              sprintf( info->s, "DMAD0:%08x", cpustate->dmad[2].d ); break;
1229
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAC2:              sprintf( info->s, "DMAC0:%04x", cpustate->dmac[2].w.l ); break;
1230
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAM2:              sprintf( info->s, "DMAM0:%02x", cpustate->dmam[2].b.l ); break;
1231
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAS3:              sprintf( info->s, "DMAS0:%08x", cpustate->dmas[3].d ); break;
1232
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAD3:              sprintf( info->s, "DMAD0:%08x", cpustate->dmad[3].d ); break;
1233
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAC3:              sprintf( info->s, "DMAC0:%04x", cpustate->dmac[3].w.l ); break;
1234
 
        case CPUINFO_STR_REGISTER + TLCS900_DMAM3:              sprintf( info->s, "DMAM0:%02x", cpustate->dmam[3].b.l ); break;
1235
 
 
1236
 
        case DEVINFO_STR_NAME:                                                  strcpy( info->s, "TLCS-900/H" ); break;
1237
 
        case DEVINFO_STR_FAMILY:                                        strcpy( info->s, "Toshiba TLCS-900" ); break;
1238
 
        case DEVINFO_STR_VERSION:                                       strcpy( info->s, "0.1" ); break;
1239
 
        case DEVINFO_STR_SOURCE_FILE:                                           strcpy( info->s, __FILE__ ); break;
1240
 
        case DEVINFO_STR_CREDITS:                                       strcpy( info->s, "Copyright Wilbert Pol" ); break;
1241
 
        }
1242
 
}
1243
 
 
1244
 
DEFINE_LEGACY_CPU_DEVICE(TLCS900H, tlcs900h);