~ubuntu-branches/ubuntu/lucid/sdlmame/lucid

« back to all changes in this revision

Viewing changes to src/emu/cpu/z8/z8.c

  • Committer: Bazaar Package Importer
  • Author(s): Cesare Falco
  • Date: 2009-11-03 17:10:15 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20091103171015-6hop4ory5lxnumpn
Tags: 0.135-0ubuntu1
* New upstream release - Closes (LP: #403212)
* debian/watch: unstable releases are no longer detected
* mame.ini: added the cheat subdirectories to cheatpath so zipped
  cheatfiles will be searched too
* renamed crsshair subdirectory to crosshair to reflect upstream change
* mame.ini: renamed references to crosshair subdirectory (see above)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**********************************************************************
 
2
 
 
3
    Zilog Z8 Single-Chip MCU emulation
 
4
 
 
5
    Copyright MESS Team.
 
6
    Visit http://mamedev.org for licensing and usage restrictions.
 
7
 
 
8
**********************************************************************/
 
9
 
 
10
/*
 
11
 
 
12
    TODO:
 
13
 
 
14
    - strobed I/O
 
15
    - interrupts
 
16
    - expose register file to disassembler
 
17
    - decimal adjust instruction
 
18
    - timer Tin/Tout modes
 
19
    - serial
 
20
    - instruction pipeline
 
21
 
 
22
*/
 
23
 
 
24
#include "driver.h"
 
25
#include "debugger.h"
 
26
#include "z8.h"
 
27
 
 
28
/***************************************************************************
 
29
    CONSTANTS
 
30
***************************************************************************/
 
31
 
 
32
enum
 
33
{
 
34
        Z8_REGISTER_P0 = 0,
 
35
        Z8_REGISTER_P1,
 
36
        Z8_REGISTER_P2,
 
37
        Z8_REGISTER_P3,
 
38
        Z8_REGISTER_SIO = 0xf0,
 
39
        Z8_REGISTER_TMR,
 
40
        Z8_REGISTER_T1,
 
41
        Z8_REGISTER_PRE1,
 
42
        Z8_REGISTER_T0,
 
43
        Z8_REGISTER_PRE0,
 
44
        Z8_REGISTER_P2M,
 
45
        Z8_REGISTER_P3M,
 
46
        Z8_REGISTER_P01M,
 
47
        Z8_REGISTER_IPR,
 
48
        Z8_REGISTER_IRQ,
 
49
        Z8_REGISTER_IMR,
 
50
        Z8_REGISTER_FLAGS,
 
51
        Z8_REGISTER_RP,
 
52
        Z8_REGISTER_SPH,
 
53
        Z8_REGISTER_SPL
 
54
};
 
55
 
 
56
#define Z8_P3_DAV0                                      0x04    /* not supported */
 
57
#define Z8_P3_DAV1                                      0x08    /* not supported */
 
58
#define Z8_P3_DAV2                                      0x02    /* not supported */
 
59
#define Z8_P3_RDY0                                      0x20    /* not supported */
 
60
#define Z8_P3_RDY1                                      0x10    /* not supported */
 
61
#define Z8_P3_RDY2                                      0x40    /* not supported */
 
62
#define Z8_P3_IRQ0                                      0x04    /* not supported */
 
63
#define Z8_P3_IRQ1                                      0x08    /* not supported */
 
64
#define Z8_P3_IRQ2                                      0x02    /* not supported */
 
65
#define Z8_P3_IRQ3                                      0x01    /* not supported */
 
66
#define Z8_P3_DI                                        0x01    /* not supported */
 
67
#define Z8_P3_DO                                        0x80    /* not supported */
 
68
#define Z8_P3_TIN                                       0x02    /* not supported */
 
69
#define Z8_P3_TOUT                                      0x40    /* not supported */
 
70
#define Z8_P3_DM                                        0x10    /* not supported */
 
71
 
 
72
#define Z8_PRE0_COUNT_MODULO_N          0x01
 
73
 
 
74
#define Z8_PRE1_COUNT_MODULO_N          0x01
 
75
#define Z8_PRE1_INTERNAL_CLOCK          0x02
 
76
 
 
77
#define Z8_TMR_LOAD_T0                          0x01
 
78
#define Z8_TMR_ENABLE_T0                        0x02
 
79
#define Z8_TMR_LOAD_T1                          0x04
 
80
#define Z8_TMR_ENABLE_T1                        0x08
 
81
#define Z8_TMR_TIN_MASK                         0x30    /* not supported */
 
82
#define Z8_TMR_TIN_EXTERNAL_CLK         0x00    /* not supported */
 
83
#define Z8_TMR_TIN_GATE                         0x10    /* not supported */
 
84
#define Z8_TMR_TIN_TRIGGER                      0x20    /* not supported */
 
85
#define Z8_TMR_TIN_RETRIGGER            0x30    /* not supported */
 
86
#define Z8_TMR_TOUT_MASK                        0xc0    /* not supported */
 
87
#define Z8_TMR_TOUT_OFF                         0x00    /* not supported */
 
88
#define Z8_TMR_TOUT_T0                          0x40    /* not supported */
 
89
#define Z8_TMR_TOUT_T1                          0x80    /* not supported */
 
90
#define Z8_TMR_TOUT_INTERNAL_CLK        0xc0    /* not supported */
 
91
 
 
92
#define Z8_P01M_P0L_MODE_MASK           0x03
 
93
#define Z8_P01M_P0L_MODE_OUTPUT         0x00
 
94
#define Z8_P01M_P0L_MODE_INPUT          0x01
 
95
#define Z8_P01M_P0L_MODE_A8_A11         0x02    /* not supported */
 
96
#define Z8_P01M_INTERNAL_STACK          0x04
 
97
#define Z8_P01M_P1_MODE_MASK            0x18
 
98
#define Z8_P01M_P1_MODE_OUTPUT          0x00
 
99
#define Z8_P01M_P1_MODE_INPUT           0x08
 
100
#define Z8_P01M_P1_MODE_AD0_AD7         0x10    /* not supported */
 
101
#define Z8_P01M_P1_MODE_HI_Z            0x18    /* not supported */
 
102
#define Z8_P01M_EXTENDED_TIMING         0x20    /* not supported */
 
103
#define Z8_P01M_P0H_MODE_MASK           0xc0
 
104
#define Z8_P01M_P0H_MODE_OUTPUT         0x00
 
105
#define Z8_P01M_P0H_MODE_INPUT          0x40
 
106
#define Z8_P01M_P0H_MODE_A12_A15        0x80    /* not supported */
 
107
 
 
108
#define Z8_P3M_P2_ACTIVE_PULLUPS        0x01    /* not supported */
 
109
#define Z8_P3M_P0_STROBED                       0x04    /* not supported */
 
110
#define Z8_P3M_P33_P34_MASK                     0x18
 
111
#define Z8_P3M_P33_P34_INPUT_OUTPUT     0x00
 
112
#define Z8_P3M_P33_P34_INPUT_DM         0x08    /* not supported */
 
113
#define Z8_P3M_P33_P34_INPUT_DM_2       0x10    /* not supported */
 
114
#define Z8_P3M_P33_P34_DAV1_RDY1        0x18    /* not supported */
 
115
#define Z8_P3M_P2_STROBED                       0x20    /* not supported */
 
116
#define Z8_P3M_P3_SERIAL                        0x40    /* not supported */
 
117
#define Z8_P3M_PARITY                           0x80    /* not supported */
 
118
 
 
119
#define Z8_IMR_ENABLE                           0x80    /* not supported */
 
120
#define Z8_IMR_RAM_PROTECT                      0x40    /* not supported */
 
121
#define Z8_IMR_ENABLE_IRQ5                      0x20    /* not supported */
 
122
#define Z8_IMR_ENABLE_IRQ4                      0x10    /* not supported */
 
123
#define Z8_IMR_ENABLE_IRQ3                      0x08    /* not supported */
 
124
#define Z8_IMR_ENABLE_IRQ2                      0x04    /* not supported */
 
125
#define Z8_IMR_ENABLE_IRQ1                      0x02    /* not supported */
 
126
#define Z8_IMR_ENABLE_IRQ0                      0x01    /* not supported */
 
127
 
 
128
#define Z8_FLAGS_F1                                     0x01
 
129
#define Z8_FLAGS_F2                                     0x02
 
130
#define Z8_FLAGS_H                                      0x04
 
131
#define Z8_FLAGS_D                                      0x08
 
132
#define Z8_FLAGS_V                                      0x10
 
133
#define Z8_FLAGS_S                                      0x20
 
134
#define Z8_FLAGS_Z                                      0x40
 
135
#define Z8_FLAGS_C                                      0x80
 
136
 
 
137
enum
 
138
{
 
139
        CC_F = 0, CC_LT, CC_LE, CC_ULE, CC_OV, CC_MI, CC_Z, CC_C,
 
140
        CC_T, CC_GE, CC_GT, CC_UGT, CC_NOV, CC_PL, CC_NZ, CC_NC
 
141
};
 
142
 
 
143
/***************************************************************************
 
144
    MACROS
 
145
***************************************************************************/
 
146
 
 
147
#define P01M            cpustate->r[Z8_REGISTER_P01M]
 
148
#define P2M                     cpustate->r[Z8_REGISTER_P2M]
 
149
#define P3M                     cpustate->r[Z8_REGISTER_P3M]
 
150
#define T0                      cpustate->r[Z8_REGISTER_T0]
 
151
#define T1                      cpustate->r[Z8_REGISTER_T1]
 
152
#define PRE0            cpustate->r[Z8_REGISTER_PRE0]
 
153
#define PRE1            cpustate->r[Z8_REGISTER_PRE1]
 
154
 
 
155
/***************************************************************************
 
156
    TYPE DEFINITIONS
 
157
***************************************************************************/
 
158
 
 
159
typedef struct _z8_state z8_state;
 
160
struct _z8_state
 
161
{
 
162
    const address_space *program;
 
163
    const address_space *data;
 
164
    const address_space *io;
 
165
 
 
166
        /* registers */
 
167
        UINT16 pc;                              /* program counter */
 
168
        UINT8 r[256];                   /* register file */
 
169
        UINT8 input[4];                 /* port input latches */
 
170
        UINT8 output[4];                /* port output latches */
 
171
        UINT8 t0;                               /* timer 0 current count */
 
172
        UINT8 t1;                               /* timer 1 current count */
 
173
 
 
174
        /* fake registers */
 
175
        UINT16 fake_sp;                 /* fake stack pointer */
 
176
        UINT8 fake_r[16];               /* fake working registers */
 
177
 
 
178
        /* interrupts */
 
179
        int irq[6];                             /* interrupts */
 
180
 
 
181
        /* execution logic */
 
182
        int clock;                              /* clock */
 
183
        int icount;                             /* instruction counter */
 
184
 
 
185
        cpu_state_table state_table;
 
186
 
 
187
        /* timers */
 
188
        emu_timer *t0_timer;
 
189
        emu_timer *t1_timer;
 
190
};
 
191
 
 
192
/***************************************************************************
 
193
    CPU STATE DESCRIPTION
 
194
***************************************************************************/
 
195
 
 
196
#define Z8_STATE_ENTRY(_name, _format, _member, _datamask, _flags) \
 
197
        CPU_STATE_ENTRY(Z8_##_name, #_name, _format, z8_state, _member, _datamask, ~0, _flags)
 
198
 
 
199
static const cpu_state_entry state_array[] =
 
200
{
 
201
        Z8_STATE_ENTRY(PC,  "%04X", pc, 0xffff, 0)
 
202
        Z8_STATE_ENTRY(GENPC, "%04X", pc, 0xffff, CPUSTATE_NOSHOW)
 
203
        Z8_STATE_ENTRY(SP, "%04X", fake_sp, 0xffff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
204
        Z8_STATE_ENTRY(GENSP, "%04X", fake_sp, 0xffff, CPUSTATE_NOSHOW | CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
205
        Z8_STATE_ENTRY(RP, "%02X", r[Z8_REGISTER_RP], 0xff, 0)
 
206
        Z8_STATE_ENTRY(T0, "%02X", t0, 0xff, 0)
 
207
        Z8_STATE_ENTRY(T1, "%02X", t1, 0xff, 0)
 
208
 
 
209
        Z8_STATE_ENTRY(R0, "%02X", fake_r[0], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
210
        Z8_STATE_ENTRY(R1, "%02X", fake_r[1], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
211
        Z8_STATE_ENTRY(R2, "%02X", fake_r[2], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
212
        Z8_STATE_ENTRY(R3, "%02X", fake_r[3], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
213
        Z8_STATE_ENTRY(R4, "%02X", fake_r[4], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
214
        Z8_STATE_ENTRY(R5, "%02X", fake_r[5], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
215
        Z8_STATE_ENTRY(R6, "%02X", fake_r[6], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
216
        Z8_STATE_ENTRY(R7, "%02X", fake_r[7], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
217
        Z8_STATE_ENTRY(R8, "%02X", fake_r[8], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
218
        Z8_STATE_ENTRY(R9, "%02X", fake_r[9], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
219
        Z8_STATE_ENTRY(R10, "%02X", fake_r[10], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
220
        Z8_STATE_ENTRY(R11, "%02X", fake_r[11], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
221
        Z8_STATE_ENTRY(R12, "%02X", fake_r[12], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
222
        Z8_STATE_ENTRY(R13, "%02X", fake_r[13], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
223
        Z8_STATE_ENTRY(R14, "%02X", fake_r[14], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
224
        Z8_STATE_ENTRY(R15, "%02X", fake_r[15], 0xff, CPUSTATE_IMPORT | CPUSTATE_EXPORT)
 
225
};
 
226
 
 
227
static const cpu_state_table state_table_template =
 
228
{
 
229
        NULL,                                           /* pointer to the base of state (offsets are relative to this) */
 
230
        0,                                                      /* subtype this table refers to */
 
231
        ARRAY_LENGTH(state_array),      /* number of entries */
 
232
        state_array                                     /* array of entries */
 
233
};
 
234
 
 
235
/***************************************************************************
 
236
    INLINE FUNCTIONS
 
237
***************************************************************************/
 
238
 
 
239
INLINE z8_state *get_safe_token(const device_config *device)
 
240
{
 
241
        assert(device != NULL);
 
242
        assert(device->token != NULL);
 
243
        assert(device->type == CPU);
 
244
        assert((cpu_get_type(device) == CPU_Z8601) ||
 
245
                (cpu_get_type(device) == CPU_UB8830D) ||
 
246
                (cpu_get_type(device) == CPU_Z8611));
 
247
        return (z8_state *)device->token;
 
248
}
 
249
 
 
250
INLINE UINT8 fetch(z8_state *cpustate)
 
251
{
 
252
        UINT8 data = memory_decrypted_read_byte(cpustate->program, cpustate->pc);
 
253
 
 
254
        cpustate->pc++;
 
255
 
 
256
        return data;
 
257
}
 
258
 
 
259
INLINE UINT8 register_read(z8_state *cpustate, UINT8 offset)
 
260
{
 
261
        UINT8 data = 0xff;
 
262
        UINT8 mask = 0;
 
263
 
 
264
        switch (offset)
 
265
        {
 
266
        case Z8_REGISTER_P0:
 
267
                switch (P01M & Z8_P01M_P0L_MODE_MASK)
 
268
                {
 
269
                case Z8_P01M_P0L_MODE_OUTPUT:   data = cpustate->output[offset] & 0x0f;         break;
 
270
                case Z8_P01M_P0L_MODE_INPUT:    mask = 0x0f;                                                            break;
 
271
                default: /* A8...A11 */                 data = 0x0f;                                                            break;
 
272
                }
 
273
 
 
274
                switch (P01M & Z8_P01M_P0H_MODE_MASK)
 
275
                {
 
276
                case Z8_P01M_P0H_MODE_OUTPUT:   data |= cpustate->output[offset] & 0xf0;        break;
 
277
                case Z8_P01M_P0H_MODE_INPUT:    mask |= 0xf0;                                                           break;
 
278
                default: /* A12...A15 */                data |= 0xf0;                                                           break;
 
279
                }
 
280
 
 
281
                if (!(P3M & Z8_P3M_P0_STROBED))
 
282
                {
 
283
                        if (mask) cpustate->input[offset] = memory_read_byte_8be(cpustate->io, offset);
 
284
                }
 
285
 
 
286
                data |= cpustate->input[offset] & mask;
 
287
                break;
 
288
 
 
289
        case Z8_REGISTER_P1:
 
290
                switch (P01M & Z8_P01M_P1_MODE_MASK)
 
291
                {
 
292
                case Z8_P01M_P1_MODE_OUTPUT:    data = cpustate->output[offset];                        break;
 
293
                case Z8_P01M_P1_MODE_INPUT:             mask = 0xff;                                                            break;
 
294
                default: /* AD0..AD7 */                 data = 0xff;                                                            break;
 
295
                }
 
296
 
 
297
                if ((P3M & Z8_P3M_P33_P34_MASK) != Z8_P3M_P33_P34_DAV1_RDY1)
 
298
                {
 
299
                        if (mask) cpustate->input[offset] = memory_read_byte_8be(cpustate->io, offset);
 
300
                }
 
301
 
 
302
                data |= cpustate->input[offset] & mask;
 
303
                break;
 
304
 
 
305
        case Z8_REGISTER_P2:
 
306
                mask = cpustate->r[Z8_REGISTER_P2M];
 
307
 
 
308
                if (!(P3M & Z8_P3M_P2_STROBED))
 
309
                {
 
310
                        if (mask) cpustate->input[offset] = memory_read_byte_8be(cpustate->io, offset);
 
311
                }
 
312
 
 
313
                data = (cpustate->input[offset] & mask) | (cpustate->output[offset] & ~mask);
 
314
                break;
 
315
 
 
316
        case Z8_REGISTER_P3:
 
317
                // TODO: special port 3 modes
 
318
                if (!(P3M & 0x7c))
 
319
                {
 
320
                        mask = 0x0f;
 
321
                }
 
322
 
 
323
                if (mask) cpustate->input[offset] = memory_read_byte_8be(cpustate->io, offset);
 
324
 
 
325
                data = (cpustate->input[offset] & mask) | (cpustate->output[offset] & ~mask);
 
326
                break;
 
327
 
 
328
        case Z8_REGISTER_T0:
 
329
                data = cpustate->t0;
 
330
                break;
 
331
 
 
332
        case Z8_REGISTER_T1:
 
333
                data = cpustate->t1;
 
334
                break;
 
335
 
 
336
        case Z8_REGISTER_PRE1:
 
337
        case Z8_REGISTER_PRE0:
 
338
        case Z8_REGISTER_P2M:
 
339
        case Z8_REGISTER_P3M:
 
340
        case Z8_REGISTER_P01M:
 
341
        case Z8_REGISTER_IPR:
 
342
                /* write only */
 
343
                break;
 
344
 
 
345
        default:
 
346
                data = cpustate->r[offset];
 
347
                break;
 
348
        }
 
349
 
 
350
        return data;
 
351
}
 
352
 
 
353
INLINE UINT16 register_pair_read(z8_state *cpustate, UINT8 offset)
 
354
{
 
355
        return (register_read(cpustate, offset) << 8) | register_read(cpustate, offset + 1);
 
356
}
 
357
 
 
358
INLINE void register_write(z8_state *cpustate, UINT8 offset, UINT8 data)
 
359
{
 
360
        UINT8 mask = 0;
 
361
 
 
362
        switch (offset)
 
363
        {
 
364
        case Z8_REGISTER_P0:
 
365
                cpustate->output[offset] = data;
 
366
                if ((P01M & Z8_P01M_P0L_MODE_MASK) == Z8_P01M_P0L_MODE_OUTPUT) mask |= 0x0f;
 
367
                if ((P01M & Z8_P01M_P0H_MODE_MASK) == Z8_P01M_P0H_MODE_OUTPUT) mask |= 0xf0;
 
368
                if (mask) memory_write_byte_8be(cpustate->io, offset, data & mask);
 
369
                break;
 
370
 
 
371
        case Z8_REGISTER_P1:
 
372
                cpustate->output[offset] = data;
 
373
                if ((P01M & Z8_P01M_P1_MODE_MASK) == Z8_P01M_P1_MODE_OUTPUT) mask = 0xff;
 
374
                if (mask) memory_write_byte_8be(cpustate->io, offset, data & mask);
 
375
                break;
 
376
 
 
377
        case Z8_REGISTER_P2:
 
378
                cpustate->output[offset] = data;
 
379
                mask = cpustate->r[Z8_REGISTER_P2M] ^ 0xff;
 
380
                if (mask) memory_write_byte_8be(cpustate->io, offset, data & mask);
 
381
                break;
 
382
 
 
383
        case Z8_REGISTER_P3:
 
384
                cpustate->output[offset] = data;
 
385
 
 
386
                // TODO: special port 3 modes
 
387
                if (!(P3M & 0x7c))
 
388
                {
 
389
                        mask = 0xf0;
 
390
                }
 
391
 
 
392
                if (mask) memory_write_byte_8be(cpustate->io, offset, data & mask);
 
393
                break;
 
394
 
 
395
        case Z8_REGISTER_SIO:
 
396
                break;
 
397
 
 
398
        case Z8_REGISTER_TMR:
 
399
                if (data & Z8_TMR_LOAD_T0)
 
400
                {
 
401
                        cpustate->t0 = T0;
 
402
                        timer_adjust_periodic(cpustate->t0_timer, attotime_zero, 0, ATTOTIME_IN_HZ(cpustate->clock / 2 / 4 / ((PRE0 >> 2) + 1)));
 
403
                }
 
404
 
 
405
                timer_enable(cpustate->t0_timer, data & Z8_TMR_ENABLE_T0);
 
406
 
 
407
                if (data & Z8_TMR_LOAD_T1)
 
408
                {
 
409
                        cpustate->t1 = T1;
 
410
                        timer_adjust_periodic(cpustate->t1_timer, attotime_zero, 0, ATTOTIME_IN_HZ(cpustate->clock / 2 / 4 / ((PRE1 >> 2) + 1)));
 
411
                }
 
412
 
 
413
                timer_enable(cpustate->t1_timer, data & Z8_TMR_ENABLE_T1);
 
414
                break;
 
415
 
 
416
        case Z8_REGISTER_P2M:
 
417
                break;
 
418
        case Z8_REGISTER_P3M:
 
419
                break;
 
420
        case Z8_REGISTER_P01M:
 
421
                break;
 
422
        case Z8_REGISTER_IPR:
 
423
                break;
 
424
        case Z8_REGISTER_IRQ:
 
425
                break;
 
426
        case Z8_REGISTER_IMR:
 
427
                break;
 
428
        case Z8_REGISTER_FLAGS:
 
429
                break;
 
430
        case Z8_REGISTER_RP:
 
431
                break;
 
432
        case Z8_REGISTER_SPH:
 
433
                break;
 
434
        case Z8_REGISTER_SPL:
 
435
                break;
 
436
        default:
 
437
                // TODO ignore missing registers
 
438
                break;
 
439
        }
 
440
 
 
441
        cpustate->r[offset] = data;
 
442
}
 
443
 
 
444
INLINE void register_pair_write(z8_state *cpustate, UINT8 offset, UINT16 data)
 
445
{
 
446
        register_write(cpustate, offset, data >> 8);
 
447
        register_write(cpustate, offset + 1, data & 0xff);
 
448
}
 
449
 
 
450
INLINE UINT8 get_working_register(z8_state *cpustate, int offset)
 
451
{
 
452
        return (cpustate->r[Z8_REGISTER_RP] & 0xf0) | (offset & 0x0f);
 
453
}
 
454
 
 
455
INLINE UINT8 get_register(z8_state *cpustate, UINT8 offset)
 
456
{
 
457
        if ((offset & 0xf0) == 0xe0)
 
458
                return get_working_register(cpustate, offset & 0x0f);
 
459
        else
 
460
                return offset;
 
461
}
 
462
 
 
463
INLINE UINT8 get_intermediate_register(z8_state *cpustate, int offset)
 
464
{
 
465
        return register_read(cpustate, get_register(cpustate, offset));
 
466
}
 
467
 
 
468
INLINE void stack_push_byte(z8_state *cpustate, UINT8 src)
 
469
{
 
470
        if (register_read(cpustate, Z8_REGISTER_P01M) & Z8_P01M_INTERNAL_STACK)
 
471
        {
 
472
                /* SP <- SP - 1 */
 
473
                UINT8 sp = register_read(cpustate, Z8_REGISTER_SPL) - 1;
 
474
                register_write(cpustate, Z8_REGISTER_SPL, sp);
 
475
 
 
476
                /* @SP <- src */
 
477
                register_write(cpustate, sp, src);
 
478
        }
 
479
        else
 
480
        {
 
481
                /* SP <- SP - 1 */
 
482
                UINT16 sp = register_pair_read(cpustate, Z8_REGISTER_SPH) - 1;
 
483
                register_pair_write(cpustate, Z8_REGISTER_SPH, sp);
 
484
 
 
485
                /* @SP <- src */
 
486
                memory_write_byte(cpustate->data, sp, src);
 
487
        }
 
488
}
 
489
 
 
490
INLINE void stack_push_word(z8_state *cpustate, UINT16 src)
 
491
{
 
492
        if (register_read(cpustate, Z8_REGISTER_P01M) & Z8_P01M_INTERNAL_STACK)
 
493
        {
 
494
                /* SP <- SP - 2 */
 
495
                UINT8 sp = register_read(cpustate, Z8_REGISTER_SPL) - 2;
 
496
                register_write(cpustate, Z8_REGISTER_SPL, sp);
 
497
 
 
498
                /* @SP <- src */
 
499
                register_pair_write(cpustate, sp, src);
 
500
        }
 
501
        else
 
502
        {
 
503
                /* SP <- SP - 2 */
 
504
                UINT16 sp = register_pair_read(cpustate, Z8_REGISTER_SPH) - 2;
 
505
                register_pair_write(cpustate, Z8_REGISTER_SPH, sp);
 
506
 
 
507
                /* @SP <- src */
 
508
                memory_write_word_8le(cpustate->data, sp, src);
 
509
        }
 
510
}
 
511
 
 
512
INLINE UINT8 stack_pop_byte(z8_state *cpustate)
 
513
{
 
514
        if (register_read(cpustate, Z8_REGISTER_P01M) & Z8_P01M_INTERNAL_STACK)
 
515
        {
 
516
                /* SP <- SP + 1 */
 
517
                UINT8 sp = register_read(cpustate, Z8_REGISTER_SPL) + 1;
 
518
                register_write(cpustate, Z8_REGISTER_SPL, sp);
 
519
 
 
520
                /* @SP <- src */
 
521
                return register_read(cpustate, sp);
 
522
        }
 
523
        else
 
524
        {
 
525
                /* SP <- SP + 1 */
 
526
                UINT16 sp = register_pair_read(cpustate, Z8_REGISTER_SPH) + 1;
 
527
                register_pair_write(cpustate, Z8_REGISTER_SPH, sp);
 
528
 
 
529
                /* @SP <- src */
 
530
                return memory_read_byte(cpustate->data, sp);
 
531
        }
 
532
}
 
533
 
 
534
INLINE UINT16 stack_pop_word(z8_state *cpustate)
 
535
{
 
536
        if (register_read(cpustate, Z8_REGISTER_P01M) & Z8_P01M_INTERNAL_STACK)
 
537
        {
 
538
                /* SP <- SP + 2 */
 
539
                UINT8 sp = register_read(cpustate, Z8_REGISTER_SPL) + 2;
 
540
                register_write(cpustate, Z8_REGISTER_SPL, sp);
 
541
 
 
542
                /* @SP <- src */
 
543
                return register_read(cpustate, sp);
 
544
        }
 
545
        else
 
546
        {
 
547
                /* SP <- SP + 2 */
 
548
                UINT16 sp = register_pair_read(cpustate, Z8_REGISTER_SPH) + 2;
 
549
                register_pair_write(cpustate, Z8_REGISTER_SPH, sp);
 
550
 
 
551
                /* @SP <- src */
 
552
                return memory_read_word_8le(cpustate->data, sp);
 
553
        }
 
554
}
 
555
 
 
556
INLINE void set_flag(z8_state *cpustate, UINT8 flag, int state)
 
557
{
 
558
        if (state)
 
559
                cpustate->r[Z8_REGISTER_FLAGS] |= flag;
 
560
        else
 
561
                cpustate->r[Z8_REGISTER_FLAGS] &= ~flag;
 
562
}
 
563
 
 
564
#define set_flag_h(state)       set_flag(cpustate, Z8_FLAGS_H, state);
 
565
#define set_flag_d(state)       set_flag(cpustate, Z8_FLAGS_D, state);
 
566
#define set_flag_v(state)       set_flag(cpustate, Z8_FLAGS_V, state);
 
567
#define set_flag_s(state)       set_flag(cpustate, Z8_FLAGS_S, state);
 
568
#define set_flag_z(state)       set_flag(cpustate, Z8_FLAGS_Z, state);
 
569
#define set_flag_c(state)       set_flag(cpustate, Z8_FLAGS_C, state);
 
570
 
 
571
/***************************************************************************
 
572
    OPCODE HANDLERS
 
573
***************************************************************************/
 
574
 
 
575
#define INSTRUCTION(mnemonic) INLINE void (mnemonic)(z8_state *cpustate, UINT8 opcode, int *cycles)
 
576
 
 
577
INSTRUCTION( illegal )
 
578
{
 
579
        logerror("Z8: PC = %04x, Illegal opcode = %02x\n", cpustate->pc - 1, opcode);
 
580
}
 
581
 
 
582
#include "z8ops.c"
 
583
 
 
584
/***************************************************************************
 
585
    OPCODE TABLES
 
586
***************************************************************************/
 
587
 
 
588
typedef void (*z8_opcode_func) (z8_state *cpustate, UINT8 opcode, int *cycles);
 
589
 
 
590
typedef struct _z8_opcode_map z8_opcode_map;
 
591
struct _z8_opcode_map
 
592
{
 
593
        z8_opcode_func  function;
 
594
        int                             execution_cycles;
 
595
        int                             pipeline_cycles;
 
596
};
 
597
 
 
598
static const z8_opcode_map Z8601_OPCODE_MAP[] =
 
599
{
 
600
        { dec_R1, 6, 5 },       { dec_IR1, 6, 5 },      { add_r1_r2, 10, 5 },   { add_r1_Ir2, 10, 5 },  { add_R2_R1, 10, 5 },   { add_IR2_R1, 10, 5 },  { add_R1_IM, 10, 5 },   { add_IR1_IM, 10, 5 },
 
601
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { illegal, 0, 0 },
 
602
 
 
603
        { rlc_R1, 6, 5 },       { rlc_IR1, 6, 5 },      { adc_r1_r2, 6, 5 },    { adc_r1_Ir2, 6, 5 },   { adc_R2_R1, 10, 5 },   { adc_IR2_R1, 10, 5 },  { adc_R1_IM, 10, 5 },   { adc_IR1_IM, 10, 5 },
 
604
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { illegal, 0, 0 },
 
605
 
 
606
        { inc_R1, 6, 5 },       { inc_IR1, 6, 5 },      { sub_r1_r2, 6, 5 },    { sub_r1_Ir2, 6, 5 },   { sub_R2_R1, 10, 5 },   { sub_IR2_R1, 10, 5 },  { sub_R1_IM, 10, 5 },   { sub_IR1_IM, 10, 5 },
 
607
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { illegal, 0, 0 },
 
608
 
 
609
        { jp_IRR1, 8, 0 },      { srp_IM, 6, 1 },       { sbc_r1_r2, 6, 5 },    { sbc_r1_Ir2, 6, 5 },   { sbc_R2_R1, 10, 5 },   { sbc_IR2_R1, 10, 5 },  { sbc_R1_IM, 10, 5 },   { sbc_IR1_IM, 10, 5 },
 
610
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { illegal, 0, 0 },
 
611
 
 
612
        { da_R1, 8, 5 },        { da_IR1, 8, 5 },       { or_r1_r2, 6, 5 },             { or_r1_Ir2, 6, 5 },    { or_R2_R1, 10, 5 },    { or_IR2_R1, 10, 5 },   { or_R1_IM, 10, 5 },    { or_IR1_IM, 10, 5 },
 
613
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { illegal, 0, 0 },
 
614
 
 
615
        { pop_R1, 10, 5 },      { pop_IR1, 10, 5 },     { and_r1_r2, 6, 5 },    { and_r1_Ir2, 6, 5 },   { and_R2_R1, 10, 5 },   { and_IR2_R1, 10, 5 },  { and_R1_IM, 10, 5 },   { and_IR1_IM, 10, 5 },
 
616
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { illegal, 0, 0 },
 
617
 
 
618
        { com_R1, 6, 5 },       { com_IR1, 6, 5 },      { tcm_r1_r2, 6, 5 },    { tcm_r1_Ir2, 6, 5 },   { tcm_R2_R1, 10, 5 },   { tcm_IR2_R1, 10, 5 },  { tcm_R1_IM, 10, 5 },   { tcm_IR1_IM, 10, 5 },
 
619
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { illegal, 0, 0 },
 
620
 
 
621
        { push_R2, 10, 1 },     { push_IR2, 12, 1 },{ tm_r1_r2, 6, 5 },         { tm_r1_Ir2, 6, 5 },    { tm_R2_R1, 10, 5 },    { tm_IR2_R1, 10, 5 },   { tm_R1_IM, 10, 5 },    { tm_IR1_IM, 10, 5 },
 
622
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { illegal, 0, 0 },
 
623
 
 
624
        { decw_RR1, 10, 5 },{ decw_IR1, 10, 5 },{ lde_r1_Irr2, 12, 0 }, { ldei_Ir1_Irr2, 18, 0 },{ illegal, 0, 0 },             { illegal, 0, 0 },              { illegal, 0, 0 },              { illegal, 0, 0 },
 
625
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { di, 6, 1 },
 
626
 
 
627
        { rl_R1, 6, 5 },        { rl_IR1, 6, 5 },       { lde_r2_Irr1, 12, 0 }, { ldei_Ir2_Irr1, 18, 0 },{ illegal, 0, 0 },             { illegal, 0, 0 },              { illegal, 0, 0 },              { illegal, 0, 0 },
 
628
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { ei, 6, 1 },
 
629
 
 
630
        { incw_RR1, 10, 5 },{ incw_IR1, 10, 5 },{ cp_r1_r2, 6, 5 },             { cp_r1_Ir2, 6, 5 },    { cp_R2_R1, 10, 5 },    { cp_IR2_R1, 10, 5 },   { cp_R1_IM, 10, 5 },    { cp_IR1_IM, 10, 5 },
 
631
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { ret, 14, 0 },
 
632
 
 
633
        { clr_R1, 6, 5 },       { clr_IR1, 6, 5 },      { xor_r1_r2, 6, 5 },    { xor_r1_Ir2, 6, 5 },   { xor_R2_R1, 10, 5 },   { xor_IR2_R1, 10, 5 },  { xor_R1_IM, 10, 5 },   { xor_IR1_IM, 10, 5 },
 
634
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { iret, 16, 0 },
 
635
 
 
636
        { rrc_R1, 6, 5 },       { rrc_IR1, 6, 5 },      { ldc_r1_Irr2, 12, 0 }, { ldci_Ir1_Irr2, 18, 0 },{ illegal, 0, 0 },             { illegal, 0, 0 },              { illegal, 0, 0 },              { ld_r1_x_R2, 10, 5 },
 
637
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { rcf, 6, 5 },
 
638
 
 
639
        { sra_R1, 6, 5 },       { sra_IR1, 6, 5 },      { ldc_r2_Irr1, 12, 0 }, { ldci_Ir2_Irr1, 18, 0 },{ call_IRR1, 20, 0 },  { illegal, 0, 0 },              { call_DA, 20, 0 },             { ld_r2_x_R1, 10, 5 },
 
640
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { scf, 6, 5 },
 
641
 
 
642
        { rr_R1, 6, 5 },        { rr_IR1, 6, 5 },       { illegal, 0, 0 },              { ld_r1_Ir2, 6, 5 },    { ld_R2_R1, 10, 5 },    { ld_IR2_R1, 10, 5 },   { ld_R1_IM, 10, 5 },    { ld_IR1_IM, 10, 5 },
 
643
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { ccf, 6, 5 },
 
644
 
 
645
        { swap_R1, 8, 5 },      { swap_IR1, 8, 5 },     { illegal, 0, 0 },              { ld_Ir1_r2, 6, 5 },    { illegal, 0, 0 },              { ld_R2_IR1, 10, 5 },   { illegal, 0, 0 },              { illegal, 0, 0 },
 
646
        { ld_r1_R2, 6, 5 }, { ld_r2_R1, 6, 5 }, { djnz_r1_RA, 10, 5 },  { jr_cc_RA, 10, 0 },    { ld_r1_IM, 6, 5 },             { jp_cc_DA, 10, 0 },    { inc_r1, 6, 5 },               { nop, 6, 0 },
 
647
};
 
648
 
 
649
/***************************************************************************
 
650
    TIMER CALLBACKS
 
651
***************************************************************************/
 
652
 
 
653
static TIMER_CALLBACK( t0_tick )
 
654
{
 
655
        z8_state *cpustate = (z8_state *)ptr;
 
656
 
 
657
        cpustate->t0--;
 
658
 
 
659
        if (cpustate->t0 == 0)
 
660
        {
 
661
                cpustate->t0 = T0;
 
662
                timer_adjust_periodic(cpustate->t0_timer, attotime_zero, 0, ATTOTIME_IN_HZ(cpustate->clock / 2 / 4 / ((PRE0 >> 2) + 1)));
 
663
                timer_enable(cpustate->t0_timer, PRE0 & Z8_PRE0_COUNT_MODULO_N);
 
664
                cpustate->irq[4] = ASSERT_LINE;
 
665
        }
 
666
}
 
667
 
 
668
static TIMER_CALLBACK( t1_tick )
 
669
{
 
670
        z8_state *cpustate = (z8_state *)ptr;
 
671
 
 
672
        cpustate->t1--;
 
673
 
 
674
        if (cpustate->t1 == 0)
 
675
        {
 
676
                cpustate->t1 = T1;
 
677
                timer_adjust_periodic(cpustate->t1_timer, attotime_zero, 0, ATTOTIME_IN_HZ(cpustate->clock / 2 / 4 / ((PRE1 >> 2) + 1)));
 
678
                timer_enable(cpustate->t1_timer, PRE1 & Z8_PRE0_COUNT_MODULO_N);
 
679
                cpustate->irq[5] = ASSERT_LINE;
 
680
        }
 
681
}
 
682
 
 
683
/***************************************************************************
 
684
    INITIALIZATION
 
685
***************************************************************************/
 
686
 
 
687
static CPU_INIT( z8 )
 
688
{
 
689
        z8_state *cpustate = get_safe_token(device);
 
690
 
 
691
        /* set up the state table */
 
692
        cpustate->state_table = state_table_template;
 
693
        cpustate->state_table.baseptr = cpustate;
 
694
        cpustate->state_table.subtypemask = 1;
 
695
 
 
696
        cpustate->clock = device->clock;
 
697
 
 
698
        /* find address spaces */
 
699
        cpustate->program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
 
700
        cpustate->data = memory_find_address_space(device, ADDRESS_SPACE_DATA);
 
701
        cpustate->io = memory_find_address_space(device, ADDRESS_SPACE_IO);
 
702
 
 
703
        /* allocate timers */
 
704
        cpustate->t0_timer = timer_alloc(device->machine, t0_tick, cpustate);
 
705
        cpustate->t1_timer = timer_alloc(device->machine, t1_tick, cpustate);
 
706
 
 
707
        /* register for state saving */
 
708
        state_save_register_device_item(device, 0, cpustate->pc);
 
709
        state_save_register_device_item_array(device, 0, cpustate->r);
 
710
        state_save_register_device_item_array(device, 0, cpustate->input);
 
711
        state_save_register_device_item_array(device, 0, cpustate->output);
 
712
        state_save_register_device_item_array(device, 0, cpustate->irq);
 
713
}
 
714
 
 
715
/***************************************************************************
 
716
    EXECUTION
 
717
***************************************************************************/
 
718
 
 
719
static CPU_EXECUTE( z8 )
 
720
{
 
721
        z8_state *cpustate = get_safe_token(device);
 
722
 
 
723
        cpustate->icount = cycles;
 
724
 
 
725
        do
 
726
        {
 
727
                UINT8 opcode;
 
728
                int cycles;
 
729
 
 
730
                debugger_instruction_hook(device, cpustate->pc);
 
731
 
 
732
                /* TODO: sample interrupts */
 
733
                cpustate->input[3] = memory_read_byte_8be(cpustate->io, 3);
 
734
 
 
735
                /* fetch opcode */
 
736
                opcode = fetch(cpustate);
 
737
                cycles = Z8601_OPCODE_MAP[opcode].execution_cycles;
 
738
 
 
739
                /* execute instruction */
 
740
                (*(Z8601_OPCODE_MAP[opcode].function))(cpustate, opcode, &cycles);
 
741
 
 
742
                cpustate->icount -= cycles;
 
743
        }
 
744
        while (cpustate->icount > 0);
 
745
 
 
746
        return cycles - cpustate->icount;
 
747
}
 
748
 
 
749
/***************************************************************************
 
750
    RESET
 
751
***************************************************************************/
 
752
 
 
753
static CPU_RESET( z8 )
 
754
{
 
755
        z8_state *cpustate = get_safe_token(device);
 
756
 
 
757
        cpustate->pc = 0x000c;
 
758
 
 
759
        register_write(cpustate, Z8_REGISTER_TMR, 0x00);
 
760
        register_write(cpustate, Z8_REGISTER_PRE1, register_read(cpustate, Z8_REGISTER_PRE1) & 0xfc);
 
761
        register_write(cpustate, Z8_REGISTER_PRE0, register_read(cpustate, Z8_REGISTER_PRE0) & 0xfe);
 
762
        register_write(cpustate, Z8_REGISTER_P2M, 0xff);
 
763
        register_write(cpustate, Z8_REGISTER_P3M, 0x00);
 
764
        register_write(cpustate, Z8_REGISTER_P01M, 0x4d);
 
765
        register_write(cpustate, Z8_REGISTER_IRQ, 0x00);
 
766
        register_write(cpustate, Z8_REGISTER_RP, 0x00);
 
767
}
 
768
 
 
769
/***************************************************************************
 
770
    ADDRESS MAPS
 
771
***************************************************************************/
 
772
 
 
773
static ADDRESS_MAP_START( program_2kb, ADDRESS_SPACE_PROGRAM, 8 )
 
774
        AM_RANGE(0x0000, 0x07ff) AM_ROM
 
775
ADDRESS_MAP_END
 
776
 
 
777
static ADDRESS_MAP_START( program_4kb, ADDRESS_SPACE_PROGRAM, 8 )
 
778
        AM_RANGE(0x0000, 0x0fff) AM_ROM
 
779
ADDRESS_MAP_END
 
780
 
 
781
/**************************************************************************
 
782
 * STATE IMPORT/EXPORT
 
783
 **************************************************************************/
 
784
 
 
785
static CPU_IMPORT_STATE( z8 )
 
786
{
 
787
        z8_state *cpustate = get_safe_token(device);
 
788
 
 
789
        switch (entry->index)
 
790
        {
 
791
                case Z8_SP:
 
792
                case Z8_GENSP:
 
793
                        cpustate->r[Z8_REGISTER_SPH] = cpustate->fake_sp >> 8;
 
794
                        cpustate->r[Z8_REGISTER_SPL] = cpustate->fake_sp & 0xff;
 
795
                        break;
 
796
 
 
797
                case Z8_R0: case Z8_R1: case Z8_R2: case Z8_R3: case Z8_R4: case Z8_R5: case Z8_R6: case Z8_R7: case Z8_R8: case Z8_R9: case Z8_R10: case Z8_R11: case Z8_R12: case Z8_R13: case Z8_R14: case Z8_R15:
 
798
                        cpustate->r[cpustate->r[Z8_REGISTER_RP] + (entry->index - Z8_R0)] = cpustate->fake_r[entry->index - Z8_R0];
 
799
                        break;
 
800
 
 
801
                default:
 
802
                        fatalerror("CPU_IMPORT_STATE(z8) called for unexpected value\n");
 
803
                        break;
 
804
        }
 
805
}
 
806
 
 
807
static CPU_EXPORT_STATE( z8 )
 
808
{
 
809
        z8_state *cpustate = get_safe_token(device);
 
810
 
 
811
        switch (entry->index)
 
812
        {
 
813
                case Z8_SP:
 
814
                case Z8_GENSP:
 
815
                        cpustate->fake_sp = (cpustate->r[Z8_REGISTER_SPH] << 8) | cpustate->r[Z8_REGISTER_SPL];
 
816
                        break;
 
817
 
 
818
                case Z8_R0: case Z8_R1: case Z8_R2: case Z8_R3: case Z8_R4: case Z8_R5: case Z8_R6: case Z8_R7: case Z8_R8: case Z8_R9: case Z8_R10: case Z8_R11: case Z8_R12: case Z8_R13: case Z8_R14: case Z8_R15:
 
819
                        cpustate->fake_r[entry->index - Z8_R0] = cpustate->r[cpustate->r[Z8_REGISTER_RP] + (entry->index - Z8_R0)];
 
820
                        break;
 
821
 
 
822
                default:
 
823
                        fatalerror("CPU_EXPORT_STATE(z8) called for unexpected value\n");
 
824
                        break;
 
825
        }
 
826
}
 
827
 
 
828
/***************************************************************************
 
829
    GENERAL CONTEXT ACCESS
 
830
***************************************************************************/
 
831
 
 
832
static CPU_SET_INFO( z8 )
 
833
{
 
834
        z8_state *cpustate = get_safe_token(device);
 
835
 
 
836
        switch (state)
 
837
        {
 
838
                case CPUINFO_INT_INPUT_STATE + INPUT_LINE_IRQ0: cpustate->irq[0] = info->i;                             break;
 
839
                case CPUINFO_INT_INPUT_STATE + INPUT_LINE_IRQ1: cpustate->irq[1] = info->i;                             break;
 
840
                case CPUINFO_INT_INPUT_STATE + INPUT_LINE_IRQ2: cpustate->irq[2] = info->i;                             break;
 
841
                case CPUINFO_INT_INPUT_STATE + INPUT_LINE_IRQ3: cpustate->irq[3] = info->i;                             break;
 
842
        }
 
843
}
 
844
 
 
845
static CPU_GET_INFO( z8 )
 
846
{
 
847
        z8_state *cpustate = (device != NULL && device->token != NULL) ? get_safe_token(device) : NULL;
 
848
 
 
849
        switch (state)
 
850
        {
 
851
                /* --- the following bits of info are returned as 64-bit signed integers --- */
 
852
                case CPUINFO_INT_CONTEXT_SIZE:                                  info->i = sizeof(z8_state);                             break;
 
853
                case CPUINFO_INT_INPUT_LINES:                                   info->i = 4;                                                    break;
 
854
                case CPUINFO_INT_DEFAULT_IRQ_VECTOR:                    info->i = 0;                                                    break;
 
855
                case DEVINFO_INT_ENDIANNESS:                                    info->i = ENDIANNESS_LITTLE;                    break;
 
856
                case CPUINFO_INT_CLOCK_MULTIPLIER:                              info->i = 1;                                                    break;
 
857
                case CPUINFO_INT_CLOCK_DIVIDER:                                 info->i = 2;                                                    break;
 
858
                case CPUINFO_INT_MIN_INSTRUCTION_BYTES:                 info->i = 1;                                                    break;
 
859
                case CPUINFO_INT_MAX_INSTRUCTION_BYTES:                 info->i = 3;                                                    break;
 
860
                case CPUINFO_INT_MIN_CYCLES:                                    info->i = 6;                                                    break;
 
861
                case CPUINFO_INT_MAX_CYCLES:                                    info->i = 20;                                                   break;
 
862
 
 
863
                case CPUINFO_INT_DATABUS_WIDTH_PROGRAM:                 info->i = 8;                                                    break;
 
864
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM:                 info->i = 16;                                                   break;
 
865
                case CPUINFO_INT_ADDRBUS_SHIFT_PROGRAM:                 info->i = 0;                                                    break;
 
866
                case CPUINFO_INT_DATABUS_WIDTH_DATA:                    info->i = 8;                                                    break;
 
867
                case CPUINFO_INT_ADDRBUS_WIDTH_DATA:                    info->i = 16;                                                   break;
 
868
                case CPUINFO_INT_ADDRBUS_SHIFT_DATA:                    info->i = 0;                                                    break;
 
869
                case CPUINFO_INT_DATABUS_WIDTH_IO:                              info->i = 8;                                                    break;
 
870
                case CPUINFO_INT_ADDRBUS_WIDTH_IO:                              info->i = 2;                                                    break;
 
871
                case CPUINFO_INT_ADDRBUS_SHIFT_IO:                              info->i = 0;                                                    break;
 
872
 
 
873
                /* --- the following bits of info are returned as pointers to functions --- */
 
874
                case CPUINFO_FCT_SET_INFO:                              info->setinfo = CPU_SET_INFO_NAME(z8);                  break;
 
875
                case CPUINFO_FCT_INIT:                                  info->init = CPU_INIT_NAME(z8);                                 break;
 
876
                case CPUINFO_FCT_RESET:                                 info->reset = CPU_RESET_NAME(z8);                               break;
 
877
                case CPUINFO_FCT_EXECUTE:                               info->execute = CPU_EXECUTE_NAME(z8);                   break;
 
878
                case CPUINFO_FCT_DISASSEMBLE:                   info->disassemble = CPU_DISASSEMBLE_NAME(z8);   break;
 
879
                case CPUINFO_FCT_IMPORT_STATE:                  info->import_state = CPU_IMPORT_STATE_NAME(z8); break;
 
880
                case CPUINFO_FCT_EXPORT_STATE:                  info->export_state = CPU_EXPORT_STATE_NAME(z8); break;
 
881
 
 
882
                /* --- the following bits of info are returned as pointers --- */
 
883
                case CPUINFO_PTR_INSTRUCTION_COUNTER:   info->icount = &cpustate->icount;                               break;
 
884
                case CPUINFO_PTR_STATE_TABLE:                   info->state_table = &cpustate->state_table;             break;
 
885
 
 
886
                /* --- the following bits of info are returned as NULL-terminated strings --- */
 
887
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "Z8");                                  break;
 
888
                case DEVINFO_STR_FAMILY:                                                strcpy(info->s, "Zilog Z8");                    break;
 
889
                case DEVINFO_STR_VERSION:                                               strcpy(info->s, "1.0");                                 break;
 
890
                case DEVINFO_STR_SOURCE_FILE:                                   strcpy(info->s, __FILE__);                              break;
 
891
                case DEVINFO_STR_CREDITS:                                               strcpy(info->s, "Copyright MESS Team"); break;
 
892
 
 
893
                case CPUINFO_STR_FLAGS: sprintf(info->s,
 
894
                                                                        "%c%c%c%c%c%c",
 
895
                                                                         cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS_C ? 'C' : '.',
 
896
                                                                         cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS_Z ? 'Z' : '.',
 
897
                                                                         cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS_S ? 'S' : '.',
 
898
                                                                         cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS_V ? 'V' : '.',
 
899
                                                                         cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS_D ? 'D' : '.',
 
900
                                                                         cpustate->r[Z8_REGISTER_FLAGS] & Z8_FLAGS_H ? 'H' : '.');      break;
 
901
        }
 
902
}
 
903
 
 
904
/***************************************************************************
 
905
    CPU-SPECIFIC CONTEXT ACCESS
 
906
***************************************************************************/
 
907
 
 
908
CPU_GET_INFO( z8601 )
 
909
{
 
910
        switch (state)
 
911
        {
 
912
                /* --- the following bits of info are returned as pointers --- */
 
913
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map8 = ADDRESS_MAP_NAME(program_2kb);    break;
 
914
 
 
915
                /* --- the following bits of info are returned as NULL-terminated strings --- */
 
916
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "Z8601");                                                               break;
 
917
 
 
918
                default:                                                                                CPU_GET_INFO_CALL(z8);                                                                  break;
 
919
        }
 
920
}
 
921
 
 
922
CPU_GET_INFO( ub8830d )
 
923
{
 
924
        switch (state)
 
925
        {
 
926
                /* --- the following bits of info are returned as pointers --- */
 
927
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map8 = ADDRESS_MAP_NAME(program_2kb);    break;
 
928
 
 
929
                /* --- the following bits of info are returned as NULL-terminated strings --- */
 
930
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "UB8830D");                                                             break;
 
931
 
 
932
                default:                                                                                CPU_GET_INFO_CALL(z8);                                                                  break;
 
933
        }
 
934
}
 
935
 
 
936
CPU_GET_INFO( z8611 )
 
937
{
 
938
        switch (state)
 
939
        {
 
940
                /* --- the following bits of info are returned as pointers --- */
 
941
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map8 = ADDRESS_MAP_NAME(program_4kb);    break;
 
942
 
 
943
                /* --- the following bits of info are returned as NULL-terminated strings --- */
 
944
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "Z8611");                                                               break;
 
945
 
 
946
                default:                                                                                CPU_GET_INFO_CALL(z8);                                                                  break;
 
947
        }
 
948
}