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

« back to all changes in this revision

Viewing changes to src/emu/cpu/pic16c5x/pic16c5x.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:
31
31
 *   - The Prescaler rate was incorrectly being zeroed, instead of the      *
32
32
 *     actual Prescaler counter in the CLRWDT and SLEEP instructions.       *
33
33
 *   - Added masking to the FSR register. Upper unused bits are always 1.   *
 
34
 *  TLP (27-Aug-2009) Ver 1.13                                              *
 
35
 *   - Indirect addressing was not taking into account special purpose      *
 
36
 *     memory mapped locations.                                             *
 
37
 *   - 'iorlw' instruction was saving the result to memory instead of       *
 
38
 *     the W register.                                                      *
 
39
 *   - 'tris' instruction no longer modifies Port-C on PIC models that      *
 
40
 *     do not have Port-C implemented.                                      *
 
41
 *  TLP (07-Sep-2009) Ver 1.14                                              *
 
42
 *   - Edge sense control for the T0 count input was incorrectly reversed   *
34
43
 *                                                                          *
35
44
 *                                                                          *
36
45
 *  **** Notes: ****                                                        *
56
65
 
57
66
 
58
67
 
59
 
#define M_RDRAM(A)              (((A) < 8) ? cpustate->internalram[A] : PIC16C5x_RAM_RDMEM(A))
60
 
#define M_WRTRAM(A,V)   do { if ((A) < 8) cpustate->internalram[A] = (V); else PIC16C5x_RAM_WRMEM(A,V); } while (0)
61
 
#define M_RDOP(A)               PIC16C5x_RDOP(A)
62
 
#define M_RDOP_ARG(A)   PIC16C5x_RDOP_ARG(A)
63
 
#define P_IN(A)                 PIC16C5x_In(A)
64
 
#define P_OUT(A,V)              PIC16C5x_Out(A,V)
65
 
#define S_T0_IN                 PIC16C5x_T0_In
66
 
#define ADDR_MASK               0x7ff
67
 
 
68
 
 
69
 
 
70
68
 
71
69
typedef struct _pic16c5x_state pic16c5x_state;
72
70
struct _pic16c5x_state
85
83
        UINT16  STACK[2];
86
84
        UINT16  prescaler;      /* Note: this is really an 8-bit register */
87
85
        PAIR    opcode;
88
 
        UINT8   internalram[8];
 
86
        UINT8   *internalram;
89
87
 
90
88
        int             icount;
91
89
        int             reset_vector;
117
115
        return (pic16c5x_state *)device->token;
118
116
}
119
117
 
 
118
 
120
119
/* opcode table entry */
121
120
typedef struct _pic16c5x_opcode pic16c5x_opcode;
122
121
struct _pic16c5x_opcode
124
123
        UINT8   cycles;
125
124
        void    (*function)(pic16c5x_state *);
126
125
};
127
 
/* opcode table entry (Opcode 00? has sub-opcodes) */
128
 
typedef struct _pic16c5x_opcode_00x pic16c5x_opcode_00x;
129
 
struct _pic16c5x_opcode_00x
 
126
 
 
127
 
 
128
INLINE void update_internalram_ptr(pic16c5x_state *cpustate)
130
129
{
131
 
        UINT8   cycles;
132
 
        void    (*function)(pic16c5x_state *);
133
 
};
134
 
 
135
 
 
136
 
 
137
 
/****************************************************************************
138
 
 *  Read the state of the T0 Clock input signal
139
 
 */
140
 
 
141
 
#define PIC16C5x_T0_In (memory_read_byte_8le(cpustate->io, PIC16C5x_T0))
142
 
 
143
 
 
144
 
/****************************************************************************
145
 
 *  Input a word from given I/O port
146
 
 */
147
 
 
148
 
#define PIC16C5x_In(Port) ((UINT8)memory_read_byte_8le(cpustate->io, (Port)))
149
 
 
150
 
 
151
 
/****************************************************************************
152
 
 *  Output a word to given I/O port
153
 
 */
154
 
 
 
130
        cpustate->internalram = (UINT8 *)memory_get_write_ptr(cpustate->data, 0x00);
 
131
}
 
132
 
 
133
 
 
134
 
 
135
 
 
136
#define PIC16C5x_RDOP(A)         (memory_decrypted_read_word(cpustate->program, (A)<<1))
 
137
#define PIC16C5x_RAM_RDMEM(A)    ((UINT8)memory_read_byte_8le(cpustate->data, A))
 
138
#define PIC16C5x_RAM_WRMEM(A,V)  (memory_write_byte_8le(cpustate->data, A,V))
 
139
#define PIC16C5x_In(Port)        ((UINT8)memory_read_byte_8le(cpustate->io, (Port)))
155
140
#define PIC16C5x_Out(Port,Value) (memory_write_byte_8le(cpustate->io, (Port),Value))
156
 
 
157
 
 
158
 
 
159
 
/****************************************************************************
160
 
 *  Read a word from given RAM memory location
161
 
 */
162
 
 
163
 
#define PIC16C5x_RAM_RDMEM(A) ((UINT8)memory_read_byte_8le(cpustate->data, A))
164
 
 
165
 
 
166
 
/****************************************************************************
167
 
 *  Write a word to given RAM memory location
168
 
 */
169
 
 
170
 
#define PIC16C5x_RAM_WRMEM(A,V) (memory_write_byte_8le(cpustate->data, A,V))
171
 
 
172
 
 
173
 
 
174
 
/****************************************************************************
175
 
 *  PIC16C5X_RDOP() is identical to PIC16C5X_RDMEM() except it is used for
176
 
 *  reading opcodes. In case of system with memory mapped I/O, this function
177
 
 *  can be used to greatly speed up emulation
178
 
 */
179
 
 
180
 
#define PIC16C5x_RDOP(A) (memory_decrypted_read_word(cpustate->program, (A)<<1))
181
 
 
182
 
 
183
 
/****************************************************************************
184
 
 *  PIC16C5X_RDOP_ARG() is identical to PIC16C5X_RDOP() except it is used
185
 
 *  for reading opcode arguments. This difference can be used to support systems
186
 
 *  that use different encoding mechanisms for opcodes and opcode arguments
187
 
 */
188
 
 
189
 
#define PIC16C5x_RDOP_ARG(A) (memory_raw_read_word(cpustate->program, (A)<<1))
 
141
/************  Read the state of the T0 Clock input signal  ************/
 
142
#define PIC16C5x_T0_In           (memory_read_byte_8le(cpustate->io, PIC16C5x_T0))
 
143
 
 
144
#define M_RDRAM(A)              (((A) < 8) ? cpustate->internalram[A] : PIC16C5x_RAM_RDMEM(A))
 
145
#define M_WRTRAM(A,V)   do { if ((A) < 8) cpustate->internalram[A] = (V); else PIC16C5x_RAM_WRMEM(A,V); } while (0)
 
146
#define M_RDOP(A)               PIC16C5x_RDOP(A)
 
147
#define P_IN(A)                 PIC16C5x_In(A)
 
148
#define P_OUT(A,V)              PIC16C5x_Out(A,V)
 
149
#define S_T0_IN                 PIC16C5x_T0_In
 
150
#define ADDR_MASK               0x7ff
 
151
 
190
152
 
191
153
 
192
154
#define TMR0    internalram[1]
200
162
 
201
163
#define ADDR    (cpustate->opcode.b.l & 0x1f)
202
164
 
203
 
#define POSITIVE_EDGE_T0  (( (int)(T0_in - cpustate->old_T0) > 0) ? 1 : 0)
204
 
#define NEGATIVE_EDGE_T0  (( (int)(cpustate->old_T0 - T0_in) > 0) ? 1 : 0)
 
165
#define  RISING_EDGE_T0  (( (int)(T0_in - cpustate->old_T0) > 0) ? 1 : 0)
 
166
#define FALLING_EDGE_T0  (( (int)(T0_in - cpustate->old_T0) < 0) ? 1 : 0)
205
167
 
206
168
 
207
169
/********  The following is the Status Flag register definition.  *********/
208
 
                        /* | 7 | 6 | 5 |  4 |  3 | 2 | 1  | 0 | */
 
170
                        /* | 7 | 6 | 5 |  4 |  3 | 2 |  1 | 0 | */
209
171
                        /* |    PA     | TO | PD | Z | DC | C | */
210
172
#define PA_REG          0xe0    /* PA   Program Page Preselect - bit 8 is unused here */
211
173
#define TO_FLAG         0x10    /* TO   Time Out flag (WatchDog) */
251
213
 *  Shortcuts
252
214
 ************************************************************************/
253
215
 
 
216
#define CLR(flagreg, flag) ( flagreg &= (UINT8)(~flag) )
 
217
#define SET(flagreg, flag) ( flagreg |=  flag )
 
218
 
 
219
 
254
220
/* Easy bit position selectors */
255
221
#define POS      ((cpustate->opcode.b.l >> 5) & 7)
256
222
static const unsigned int bit_clr[8] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
257
223
static const unsigned int bit_set[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
258
224
 
259
225
 
260
 
INLINE void CLR(pic16c5x_state *cpustate, UINT16 flag) { cpustate->STATUS &= ~flag; }
261
 
INLINE void SET(pic16c5x_state *cpustate, UINT16 flag) { cpustate->STATUS |=  flag; }
262
 
 
263
 
 
264
226
 
265
227
INLINE void CALCULATE_Z_FLAG(pic16c5x_state *cpustate)
266
228
{
267
 
        if (cpustate->ALU == 0) SET(cpustate, Z_FLAG);
268
 
        else CLR(cpustate, Z_FLAG);
 
229
        if (cpustate->ALU == 0) SET(cpustate->STATUS, Z_FLAG);
 
230
        else CLR(cpustate->STATUS, Z_FLAG);
269
231
}
270
232
 
271
233
INLINE void CALCULATE_ADD_CARRY(pic16c5x_state *cpustate)
272
234
{
273
235
        if ((UINT8)(cpustate->old_data) > (UINT8)(cpustate->ALU)) {
274
 
                SET(cpustate, C_FLAG);
 
236
                SET(cpustate->STATUS, C_FLAG);
275
237
        }
276
238
        else {
277
 
                CLR(cpustate, C_FLAG);
 
239
                CLR(cpustate->STATUS, C_FLAG);
278
240
        }
279
241
}
280
242
 
281
243
INLINE void CALCULATE_ADD_DIGITCARRY(pic16c5x_state *cpustate)
282
244
{
283
245
        if (((UINT8)(cpustate->old_data) & 0x0f) > ((UINT8)(cpustate->ALU) & 0x0f)) {
284
 
                SET(cpustate, DC_FLAG);
 
246
                SET(cpustate->STATUS, DC_FLAG);
285
247
        }
286
248
        else {
287
 
                CLR(cpustate, DC_FLAG);
 
249
                CLR(cpustate->STATUS, DC_FLAG);
288
250
        }
289
251
}
290
252
 
291
253
INLINE void CALCULATE_SUB_CARRY(pic16c5x_state *cpustate)
292
254
{
293
255
        if ((UINT8)(cpustate->old_data) < (UINT8)(cpustate->ALU)) {
294
 
                CLR(cpustate, C_FLAG);
 
256
                CLR(cpustate->STATUS, C_FLAG);
295
257
        }
296
258
        else {
297
 
                SET(cpustate, C_FLAG);
 
259
                SET(cpustate->STATUS, C_FLAG);
298
260
        }
299
261
}
300
262
 
301
263
INLINE void CALCULATE_SUB_DIGITCARRY(pic16c5x_state *cpustate)
302
264
{
303
265
        if (((UINT8)(cpustate->old_data) & 0x0f) < ((UINT8)(cpustate->ALU) & 0x0f)) {
304
 
                CLR(cpustate, DC_FLAG);
 
266
                CLR(cpustate->STATUS, DC_FLAG);
305
267
        }
306
268
        else {
307
 
                SET(cpustate, DC_FLAG);
 
269
                SET(cpustate->STATUS, DC_FLAG);
308
270
        }
309
271
}
310
272
 
323
285
}
324
286
 
325
287
 
 
288
 
326
289
INLINE UINT8 GET_REGFILE(pic16c5x_state *cpustate, offs_t addr) /* Read from internal memory */
327
290
{
328
291
        UINT8 data;
329
292
 
330
 
        if ((cpustate->picmodel == 0x16C57) || (cpustate->picmodel == 0x16C58))
331
 
        {
332
 
                addr |= (cpustate->FSR & 0x60);         /* FSR used for banking */
333
 
        }
 
293
        if (addr == 0) {                                                /* Indirect addressing  */
 
294
                addr = (cpustate->FSR & cpustate->picRAMmask);
 
295
        }
 
296
 
 
297
        if ((cpustate->picmodel == 0x16C57) || (cpustate->picmodel == 0x16C58)) {
 
298
                addr |= (cpustate->FSR & 0x60);         /* FSR bits 6-5 are used for banking in direct mode */
 
299
        }
 
300
 
334
301
        if ((addr & 0x10) == 0) addr &= 0x0f;
335
302
 
336
303
        switch(addr)
337
304
        {
338
 
                case 00:        addr = (cpustate->FSR & cpustate->picRAMmask);
339
 
                                        if (addr == 0) { data = 0; break; }
340
 
                                        if ((addr & 0x10) == 0) addr &= 0x0f;
341
 
                                        data = M_RDRAM(addr);                   /* Indirect address */
342
 
                                        break;
343
 
                case 04:        data = (cpustate->FSR | (~cpustate->picRAMmask)); break;
 
305
                case 00:        /* Not an actual register, so return 0 */
 
306
                                        data = 0;
 
307
                                        break;
 
308
                case 04:        data = (cpustate->FSR | (UINT8)(~cpustate->picRAMmask));
 
309
                                        break;
344
310
                case 05:        data = P_IN(0);
345
311
                                        data &= cpustate->TRISA;
346
 
                                        data |= (~cpustate->TRISA & cpustate->PORTA);
347
 
                                        data &= 0xf;            /* 4-bit port (only lower 4 bits used) */
 
312
                                        data |= ((UINT8)(~cpustate->TRISA) & cpustate->PORTA);
 
313
                                        data &= 0x0f;           /* 4-bit port (only lower 4 bits used) */
348
314
                                        break;
349
315
                case 06:        data = P_IN(1);
350
316
                                        data &= cpustate->TRISB;
351
 
                                        data |= (~cpustate->TRISB & cpustate->PORTB);
 
317
                                        data |= ((UINT8)(~cpustate->TRISB) & cpustate->PORTB);
352
318
                                        break;
353
319
                case 07:        if ((cpustate->picmodel == 0x16C55) || (cpustate->picmodel == 0x16C57)) {
354
320
                                                data = P_IN(2);
355
321
                                                data &= cpustate->TRISC;
356
 
                                                data |= (~cpustate->TRISC & cpustate->PORTC);
 
322
                                                data |= ((UINT8)(~cpustate->TRISC) & cpustate->PORTC);
357
323
                                        }
358
 
                                        else {          /* PIC16C54, PIC16C56, PIC16C58 */
 
324
                                        else {                          /* PIC16C54, PIC16C56, PIC16C58 */
359
325
                                                data = M_RDRAM(addr);
360
326
                                        }
361
327
                                        break;
362
 
                default:        data = M_RDRAM(addr); break;
 
328
                default:        data = M_RDRAM(addr);
 
329
                                        break;
363
330
        }
364
 
 
365
331
        return data;
366
332
}
367
333
 
368
334
INLINE void STORE_REGFILE(pic16c5x_state *cpustate, offs_t addr, UINT8 data)    /* Write to internal memory */
369
335
{
370
 
        if ((cpustate->picmodel == 0x16C57) || (cpustate->picmodel == 0x16C58))
371
 
        {
372
 
                addr |= (cpustate->FSR & 0x60);
373
 
        }
 
336
        if (addr == 0) {                                                /* Indirect addressing  */
 
337
                addr = (cpustate->FSR & cpustate->picRAMmask);
 
338
        }
 
339
 
 
340
        if ((cpustate->picmodel == 0x16C57) || (cpustate->picmodel == 0x16C58)) {
 
341
                addr |= (cpustate->FSR & 0x60);         /* FSR bits 6-5 are used for banking in direct mode */
 
342
        }
 
343
 
374
344
        if ((addr & 0x10) == 0) addr &= 0x0f;
375
345
 
376
346
        switch(addr)
377
347
        {
378
 
                case 00:        addr = (cpustate->FSR & cpustate->picRAMmask);
379
 
                                        if (addr == 0) break;
380
 
                                        if ((addr & 0x10) == 0) addr &= 0x0f;
381
 
                                        M_WRTRAM(addr, data); break;    /* Indirect address */
 
348
                case 00:        /* Not an actual register, nothing to save */
 
349
                                        break;
382
350
                case 01:        cpustate->delay_timer = 2;              /* Timer starts after next two instructions */
383
351
                                        if (PSA == 0) cpustate->prescaler = 0;  /* Must clear the Prescaler */
384
 
                                        cpustate->TMR0 = data; break;
 
352
                                        cpustate->TMR0 = data;
 
353
                                        break;
385
354
                case 02:        cpustate->PCL = data;
386
 
                                        cpustate->PC = ((cpustate->STATUS & PA_REG) << 4) | data; break;
387
 
                case 03:        cpustate->STATUS &= ~PA_REG; cpustate->STATUS |= (data & PA_REG); break;
388
 
                case 04:        cpustate->FSR = (data | (~cpustate->picRAMmask)); break;
389
 
                case 05:        data &= 0xf;            /* 4-bit port (only lower 4 bits used) */
390
 
                                        P_OUT(0,data & (~cpustate->TRISA)); cpustate->PORTA = data; break;
391
 
                case 06:        P_OUT(1,data & (~cpustate->TRISB)); cpustate->PORTB = data; break;
 
355
                                        cpustate->PC = ((cpustate->STATUS & PA_REG) << 4) | data;
 
356
                                        break;
 
357
                case 03:        cpustate->STATUS &= (UINT8)(~PA_REG); cpustate->STATUS |= (data & PA_REG);
 
358
                                        break;
 
359
                case 04:        cpustate->FSR = (data | (UINT8)(~cpustate->picRAMmask));
 
360
                                        break;
 
361
                case 05:        data &= 0x0f;           /* 4-bit port (only lower 4 bits used) */
 
362
                                        P_OUT(0,data & (UINT8)(~cpustate->TRISA)); cpustate->PORTA = data;
 
363
                                        break;
 
364
                case 06:        P_OUT(1,data & (UINT8)(~cpustate->TRISB)); cpustate->PORTB = data;
 
365
                                        break;
392
366
                case 07:        if ((cpustate->picmodel == 0x16C55) || (cpustate->picmodel == 0x16C57)) {
393
 
                                                P_OUT(2,data & (~cpustate->TRISC));
 
367
                                                P_OUT(2,data & (UINT8)(~cpustate->TRISC));
394
368
                                                cpustate->PORTC = data;
395
369
                                        }
396
370
                                        else {          /* PIC16C54, PIC16C56, PIC16C58 */
397
371
                                                M_WRTRAM(addr, data);
398
372
                                        }
399
373
                                        break;
400
 
                default:        M_WRTRAM(addr, data); break;
 
374
                default:        M_WRTRAM(addr, data);
 
375
                                        break;
401
376
        }
402
377
}
403
378
 
498
473
static void clrw(pic16c5x_state *cpustate)
499
474
{
500
475
        cpustate->W = 0;
501
 
        SET(cpustate, Z_FLAG);
 
476
        SET(cpustate->STATUS, Z_FLAG);
502
477
}
503
478
 
504
479
static void clrf(pic16c5x_state *cpustate)
505
480
{
506
481
        STORE_REGFILE(cpustate, ADDR, 0);
507
 
        SET(cpustate, Z_FLAG);
 
482
        SET(cpustate->STATUS, Z_FLAG);
508
483
}
509
484
 
510
485
static void clrwdt(pic16c5x_state *cpustate)
511
486
{
512
487
        cpustate->WDT = 0;
513
488
        if (PSA) cpustate->prescaler = 0;
514
 
        SET(cpustate, TO_FLAG);
515
 
        SET(cpustate, PD_FLAG);
 
489
        SET(cpustate->STATUS, TO_FLAG);
 
490
        SET(cpustate->STATUS, PD_FLAG);
516
491
}
517
492
 
518
493
static void comf(pic16c5x_state *cpustate)
519
494
{
520
 
        cpustate->ALU = ~(GET_REGFILE(cpustate, ADDR));
 
495
        cpustate->ALU = (UINT8)(~(GET_REGFILE(cpustate, ADDR)));
521
496
        STORE_RESULT(cpustate, ADDR, cpustate->ALU);
522
497
        CALCULATE_Z_FLAG(cpustate);
523
498
}
570
545
static void iorlw(pic16c5x_state *cpustate)
571
546
{
572
547
        cpustate->ALU = cpustate->opcode.b.l | cpustate->W;
573
 
        STORE_RESULT(cpustate, ADDR, cpustate->ALU);
 
548
        cpustate->W = cpustate->ALU;
574
549
        CALCULATE_Z_FLAG(cpustate);
575
550
}
576
551
 
605
580
 
606
581
static void option(pic16c5x_state *cpustate)
607
582
{
608
 
        cpustate->OPTION = cpustate->W & 0x3f;
 
583
        cpustate->OPTION = cpustate->W & (T0CS_FLAG | T0SE_FLAG | PSA_FLAG | PS_REG);
609
584
}
610
585
 
611
586
static void retlw(pic16c5x_state *cpustate)
620
595
        cpustate->ALU = GET_REGFILE(cpustate, ADDR);
621
596
        cpustate->ALU <<= 1;
622
597
        if (cpustate->STATUS & C_FLAG) cpustate->ALU |= 1;
623
 
        if (GET_REGFILE(cpustate, ADDR) & 0x80) SET(cpustate, C_FLAG);
624
 
        else CLR(cpustate, C_FLAG);
 
598
        if (GET_REGFILE(cpustate, ADDR) & 0x80) SET(cpustate->STATUS, C_FLAG);
 
599
        else CLR(cpustate->STATUS, C_FLAG);
625
600
        STORE_RESULT(cpustate, ADDR, cpustate->ALU);
626
601
}
627
602
 
630
605
        cpustate->ALU = GET_REGFILE(cpustate, ADDR);
631
606
        cpustate->ALU >>= 1;
632
607
        if (cpustate->STATUS & C_FLAG) cpustate->ALU |= 0x80;
633
 
        if (GET_REGFILE(cpustate, ADDR) & 1) SET(cpustate, C_FLAG);
634
 
        else CLR(cpustate, C_FLAG);
 
608
        if (GET_REGFILE(cpustate, ADDR) & 1) SET(cpustate->STATUS, C_FLAG);
 
609
        else CLR(cpustate->STATUS, C_FLAG);
635
610
        STORE_RESULT(cpustate, ADDR, cpustate->ALU);
636
611
}
637
612
 
639
614
{
640
615
        if (WDTE) cpustate->WDT = 0;
641
616
        if (PSA) cpustate->prescaler = 0;
642
 
        SET(cpustate, TO_FLAG);
643
 
        CLR(cpustate, PD_FLAG);
 
617
        SET(cpustate->STATUS, TO_FLAG);
 
618
        CLR(cpustate->STATUS, PD_FLAG);
644
619
}
645
620
 
646
621
static void subwf(pic16c5x_state *cpustate)
664
639
{
665
640
        switch(cpustate->opcode.b.l & 0x7)
666
641
        {
667
 
                case 05:        if (cpustate->TRISA == cpustate->W) break;
668
 
                                        else cpustate->TRISA = cpustate->W; P_OUT(0,cpustate->PORTA & (~cpustate->TRISA) & 0xf); break;
669
 
                case 06:        if (cpustate->TRISB == cpustate->W) break;
670
 
                                        else cpustate->TRISB = cpustate->W; P_OUT(1,cpustate->PORTB & (~cpustate->TRISB)); break;
671
 
                case 07:        if (cpustate->TRISC == cpustate->W) break;
672
 
                                        else cpustate->TRISC = cpustate->W; P_OUT(2,cpustate->PORTC & (~cpustate->TRISC)); break;
 
642
                case 05:        if   (cpustate->TRISA == cpustate->W) break;
 
643
                                        else { cpustate->TRISA = cpustate->W | 0xf0; P_OUT(0,cpustate->PORTA & (UINT8)(~cpustate->TRISA) & 0x0f); break; }
 
644
                case 06:        if   (cpustate->TRISB == cpustate->W) break;
 
645
                                        else { cpustate->TRISB = cpustate->W; P_OUT(1,cpustate->PORTB & (UINT8)(~cpustate->TRISB)); break; }
 
646
                case 07:        if ((cpustate->picmodel == 0x16C55) || (cpustate->picmodel == 0x16C57)) {
 
647
                                                if   (cpustate->TRISC == cpustate->W) break;
 
648
                                                else { cpustate->TRISC = cpustate->W; P_OUT(2,cpustate->PORTC & (UINT8)(~cpustate->TRISC)); break; }
 
649
                                        }
 
650
                                        else {
 
651
                                                illegal(cpustate); break;
 
652
                                        }
673
653
                default:        illegal(cpustate); break;
674
654
        }
675
655
}
697
677
 
698
678
static const pic16c5x_opcode opcode_main[256]=
699
679
{
700
 
/*00*/  {1, nop,        },{0, illegal   },{1, movwf             },{1, movwf             },{1, clrw              },{0, illegal   },{1, clrf              },{1, clrf              },
 
680
/*00*/  {1, nop         },{0, illegal   },{1, movwf             },{1, movwf             },{1, clrw              },{0, illegal   },{1, clrf              },{1, clrf              },
701
681
/*08*/  {1, subwf       },{1, subwf             },{1, subwf             },{1, subwf             },{1, decf              },{1, decf              },{1, decf              },{1, decf              },
702
682
/*10*/  {1, iorwf       },{1, iorwf             },{1, iorwf             },{1, iorwf             },{1, andwf             },{1, andwf             },{1, andwf             },{1, andwf             },
703
683
/*18*/  {1, xorwf       },{1, xorwf             },{1, xorwf             },{1, xorwf             },{1, addwf             },{1, addwf             },{1, addwf             },{1, addwf             },
732
712
};
733
713
 
734
714
 
735
 
static const pic16c5x_opcode_00x opcode_00x[16]=
 
715
static const pic16c5x_opcode opcode_00x[16]=
736
716
{
737
717
/*00*/  {1, nop         },{0, illegal   },{1, option    },{1, sleepic   },{1, clrwdt    },{1, tris              },{1, tris              },{1, tris              },
738
718
/*08*/  {0, illegal     },{0, illegal   },{0, illegal   },{0, illegal   },{0, illegal   },{0, illegal   },{0, illegal   },{0, illegal   }
748
728
{
749
729
        pic16c5x_state *cpustate = get_safe_token(device);
750
730
 
 
731
        cpustate->device = device;
 
732
        cpustate->program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
 
733
        cpustate->data = memory_find_address_space(device, ADDRESS_SPACE_DATA);
 
734
        cpustate->io = memory_find_address_space(device, ADDRESS_SPACE_IO);
 
735
 
 
736
        /* ensure the internal ram pointers are set before get_info is called */
 
737
        update_internalram_ptr(cpustate);
 
738
 
751
739
        state_save_register_device_item(device, 0, cpustate->W);
752
740
        state_save_register_device_item(device, 0, cpustate->ALU);
753
741
        state_save_register_device_item(device, 0, cpustate->OPTION);
779
767
        state_save_register_device_item(device, 0, cpustate->icount);
780
768
        state_save_register_device_item(device, 0, cpustate->temp_config);
781
769
        state_save_register_device_item(device, 0, cpustate->inst_cycles);
782
 
 
783
 
 
784
 
        cpustate->device = device;
785
 
        cpustate->program = memory_find_address_space(device, ADDRESS_SPACE_PROGRAM);
786
 
        cpustate->data = memory_find_address_space(device, ADDRESS_SPACE_DATA);
787
 
        cpustate->io = memory_find_address_space(device, ADDRESS_SPACE_IO);
788
770
}
789
771
 
790
772
 
799
781
        cpustate->TRISA  = 0xff;
800
782
        cpustate->TRISB  = 0xff;
801
783
        cpustate->TRISC  = 0xff;
802
 
        cpustate->OPTION = 0x3f;
 
784
        cpustate->OPTION = (T0CS_FLAG | T0SE_FLAG | PSA_FLAG | PS_REG);
803
785
        cpustate->PCL    = 0xff;
804
 
        cpustate->FSR   |= (~cpustate->picRAMmask);
 
786
        cpustate->FSR   |= (UINT8)(~cpustate->picRAMmask);
805
787
        cpustate->PORTA &= 0x0f;
806
788
        cpustate->prescaler = 0;
807
789
        cpustate->delay_timer = 0;
811
793
 
812
794
static void pic16c5x_soft_reset(pic16c5x_state *cpustate)
813
795
{
814
 
        cpustate->STATUS &= 0x1f;
 
796
        SET(cpustate->STATUS, (TO_FLAG | PD_FLAG | Z_FLAG | DC_FLAG | C_FLAG));
815
797
        pic16c5x_reset_regs(cpustate);
816
798
}
817
799
 
863
845
                                cpustate->prescaler++;
864
846
                                if (cpustate->prescaler >= (1 << PS)) { /* Prescale values from 1 to 128 */
865
847
                                        cpustate->prescaler = 0;
866
 
                                        CLR(cpustate, TO_FLAG);
 
848
                                        CLR(cpustate->STATUS, TO_FLAG);
867
849
                                        pic16c5x_soft_reset(cpustate);
868
850
                                }
869
851
                        }
870
852
                        else {
871
 
                                CLR(cpustate, TO_FLAG);
 
853
                                CLR(cpustate->STATUS, TO_FLAG);
872
854
                                pic16c5x_soft_reset(cpustate);
873
855
                        }
874
856
                }
902
884
static CPU_EXECUTE( pic16c5x )
903
885
{
904
886
        pic16c5x_state *cpustate = get_safe_token(device);
905
 
        int T0_in;
 
887
        UINT8 T0_in;
 
888
 
 
889
        update_internalram_ptr(cpustate);
 
890
 
906
891
        cpustate->icount = cycles;
907
892
 
908
893
        do
936
921
 
937
922
                        if (T0CS) {                                             /* Count mode */
938
923
                                T0_in = S_T0_IN;
939
 
                                if (T0SE) {                                     /* Count rising edge */
940
 
                                        if (POSITIVE_EDGE_T0) {
 
924
                                if (T0_in) T0_in = 1;
 
925
                                if (T0SE) {                                     /* Count falling edge T0 input */
 
926
                                        if (FALLING_EDGE_T0) {
941
927
                                                pic16c5x_update_timer(cpustate, 1);
942
928
                                        }
943
929
                                }
944
 
                                else {                                          /* Count falling edge */
945
 
                                        if (NEGATIVE_EDGE_T0) {
 
930
                                else {                                          /* Count rising edge T0 input */
 
931
                                        if (RISING_EDGE_T0) {
946
932
                                                pic16c5x_update_timer(cpustate, 1);
947
933
                                        }
948
934
                                }
988
974
                case CPUINFO_INT_SP:
989
975
                case CPUINFO_INT_REGISTER + PIC16C5x_STK1:              cpustate->STACK[1] = info->i;                                   break;
990
976
                case CPUINFO_INT_REGISTER + PIC16C5x_STK0:              cpustate->STACK[0] = info->i;                                   break;
991
 
                case CPUINFO_INT_REGISTER + PIC16C5x_W:             cpustate->W      = info->i;                                         break;
 
977
                case CPUINFO_INT_REGISTER + PIC16C5x_W:                 cpustate->W      = info->i;                                             break;
992
978
                case CPUINFO_INT_REGISTER + PIC16C5x_ALU:               cpustate->ALU    = info->i;                                             break;
993
979
                case CPUINFO_INT_REGISTER + PIC16C5x_STR:               cpustate->STATUS = info->i;                                             break;
994
 
                case CPUINFO_INT_REGISTER + PIC16C5x_OPT:               cpustate->OPTION = info->i;                                             break;
 
980
                case CPUINFO_INT_REGISTER + PIC16C5x_OPT:               cpustate->OPTION = info->i & (T0CS_FLAG | T0SE_FLAG | PSA_FLAG | PS_REG);       break;
995
981
                case CPUINFO_INT_REGISTER + PIC16C5x_TMR0:              cpustate->TMR0   = info->i;                                             break;
996
982
                case CPUINFO_INT_REGISTER + PIC16C5x_WDT:               cpustate->WDT    = info->i;                                             break;
997
983
                case CPUINFO_INT_REGISTER + PIC16C5x_PSCL:              cpustate->prescaler = info->i;                                  break;
998
 
                case CPUINFO_INT_REGISTER + PIC16C5x_PRTA:              cpustate->PORTA  = info->i;                                             break;
 
984
                case CPUINFO_INT_REGISTER + PIC16C5x_PRTA:              cpustate->PORTA  = info->i & 0x0f;                              break;
999
985
                case CPUINFO_INT_REGISTER + PIC16C5x_PRTB:              cpustate->PORTB  = info->i;                                             break;
1000
986
                case CPUINFO_INT_REGISTER + PIC16C5x_PRTC:              cpustate->PORTC  = info->i;                                             break;
1001
 
                case CPUINFO_INT_REGISTER + PIC16C5x_FSR:               cpustate->FSR    = (info->i & cpustate->picRAMmask);    break;
 
987
                case CPUINFO_INT_REGISTER + PIC16C5x_FSR:               cpustate->FSR    = ((info->i & cpustate->picRAMmask) | (UINT8)(~cpustate->picRAMmask)); break;
1002
988
        }
1003
989
}
1004
990
 
1015
1001
        switch (state)
1016
1002
        {
1017
1003
                /* --- the following bits of info are returned as 64-bit signed integers --- */
1018
 
                case CPUINFO_INT_CONTEXT_SIZE:                                  info->i = sizeof(pic16c5x_state);               break;
1019
 
                case CPUINFO_INT_INPUT_LINES:                                   info->i = 0;                                                    break;
1020
 
                case CPUINFO_INT_DEFAULT_IRQ_VECTOR:                    info->i = 0;                                                    break;
1021
 
                case CPUINFO_INT_ENDIANNESS:                                    info->i = ENDIANNESS_LITTLE;                    break;
1022
 
                case CPUINFO_INT_CLOCK_MULTIPLIER:                              info->i = 1;                                                    break;
1023
 
                case CPUINFO_INT_CLOCK_DIVIDER:                                 info->i = 4;                                                    break;
1024
 
                case CPUINFO_INT_MIN_INSTRUCTION_BYTES:                 info->i = 2;                                                    break;
1025
 
                case CPUINFO_INT_MAX_INSTRUCTION_BYTES:                 info->i = 2;                                                    break;
1026
 
                case CPUINFO_INT_MIN_CYCLES:                                    info->i = 1;                                                    break;
1027
 
                case CPUINFO_INT_MAX_CYCLES:                                    info->i = 10;                                                   break;
 
1004
                case CPUINFO_INT_CONTEXT_SIZE:                                  info->i = sizeof(pic16c5x_state);       break;
 
1005
                case CPUINFO_INT_INPUT_LINES:                                   info->i = 1;                                            break;
 
1006
                case CPUINFO_INT_DEFAULT_IRQ_VECTOR:                    info->i = 0;                                            break;
 
1007
                case DEVINFO_INT_ENDIANNESS:                                    info->i = ENDIANNESS_LITTLE;            break;
 
1008
                case CPUINFO_INT_CLOCK_MULTIPLIER:                              info->i = 1;                                            break;
 
1009
                case CPUINFO_INT_CLOCK_DIVIDER:                                 info->i = 4;                                            break;
 
1010
                case CPUINFO_INT_MIN_INSTRUCTION_BYTES:                 info->i = 2;                                            break;
 
1011
                case CPUINFO_INT_MAX_INSTRUCTION_BYTES:                 info->i = 2;                                            break;
 
1012
                case CPUINFO_INT_MIN_CYCLES:                                    info->i = 1;                                            break;
 
1013
                case CPUINFO_INT_MAX_CYCLES:                                    info->i = 2;                                            break;
1028
1014
 
1029
 
                case CPUINFO_INT_DATABUS_WIDTH_PROGRAM: info->i = 16;                                   break;
1030
 
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 9;                                    break;
1031
 
                case CPUINFO_INT_ADDRBUS_SHIFT_PROGRAM: info->i = -1;                                   break;
1032
 
                case CPUINFO_INT_DATABUS_WIDTH_DATA:    info->i = 8;                                    break;
1033
 
                case CPUINFO_INT_ADDRBUS_WIDTH_DATA:    info->i = 5;                                    break;
1034
 
                case CPUINFO_INT_ADDRBUS_SHIFT_DATA:    info->i = 0;                                    break;
1035
 
                case CPUINFO_INT_DATABUS_WIDTH_IO:              info->i = 8;                                    break;
1036
 
                case CPUINFO_INT_ADDRBUS_WIDTH_IO:              info->i = 5;                                    break;
1037
 
                case CPUINFO_INT_ADDRBUS_SHIFT_IO:              info->i = 0;                                    break;
 
1015
                case CPUINFO_INT_DATABUS_WIDTH_PROGRAM:                 info->i = 16;                                           break;
 
1016
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM:                 info->i = 9;                                            break;
 
1017
                case CPUINFO_INT_ADDRBUS_SHIFT_PROGRAM:                 info->i = -1;                                           break;
 
1018
                case CPUINFO_INT_DATABUS_WIDTH_DATA:                    info->i = 8;                                            break;
 
1019
                case CPUINFO_INT_ADDRBUS_WIDTH_DATA:                    info->i = 5;                                            break;
 
1020
                case CPUINFO_INT_ADDRBUS_SHIFT_DATA:                    info->i = 0;                                            break;
 
1021
                case CPUINFO_INT_DATABUS_WIDTH_IO:                              info->i = 8;                                            break;
 
1022
                case CPUINFO_INT_ADDRBUS_WIDTH_IO:                              info->i = 5;                                            break;
 
1023
                case CPUINFO_INT_ADDRBUS_SHIFT_IO:                              info->i = 0;                                            break;
1038
1024
 
1039
1025
                case CPUINFO_INT_PREVIOUSPC:                                    info->i = cpustate->PREVPC;                                             break;
1040
1026
 
1044
1030
                case CPUINFO_INT_SP:
1045
1031
                case CPUINFO_INT_REGISTER + PIC16C5x_STK1:              info->i = cpustate->STACK[1];                                   break;
1046
1032
                case CPUINFO_INT_REGISTER + PIC16C5x_STK0:              info->i = cpustate->STACK[0];                                   break;
1047
 
                case CPUINFO_INT_REGISTER + PIC16C5x_W:                 info->i = cpustate->W;                                                  break;
1048
 
                case CPUINFO_INT_REGISTER + PIC16C5x_ALU:               info->i = cpustate->ALU;                                                break;
1049
 
                case CPUINFO_INT_REGISTER + PIC16C5x_STR:               info->i = cpustate->STATUS;                                             break;
1050
 
                case CPUINFO_INT_REGISTER + PIC16C5x_OPT:               info->i = cpustate->OPTION;                                             break;
 
1033
                case CPUINFO_INT_REGISTER + PIC16C5x_W:                 info->i = cpustate->W;                                                  break;
 
1034
                case CPUINFO_INT_REGISTER + PIC16C5x_ALU:               info->i = cpustate->ALU;                                                break;
 
1035
                case CPUINFO_INT_REGISTER + PIC16C5x_STR:               info->i = cpustate->STATUS;                                             break;
 
1036
                case CPUINFO_INT_REGISTER + PIC16C5x_OPT:               info->i = cpustate->OPTION;                                             break;
1051
1037
                case CPUINFO_INT_REGISTER + PIC16C5x_TMR0:              info->i = cpustate->TMR0;                                               break;
1052
 
                case CPUINFO_INT_REGISTER + PIC16C5x_WDT:               info->i = cpustate->WDT;                                                break;
 
1038
                case CPUINFO_INT_REGISTER + PIC16C5x_WDT:               info->i = cpustate->WDT;                                                break;
1053
1039
                case CPUINFO_INT_REGISTER + PIC16C5x_PSCL:              info->i = cpustate->prescaler;                                  break;
1054
1040
                case CPUINFO_INT_REGISTER + PIC16C5x_PRTA:              info->i = cpustate->PORTA;                                              break;
1055
1041
                case CPUINFO_INT_REGISTER + PIC16C5x_PRTB:              info->i = cpustate->PORTB;                                              break;
1056
1042
                case CPUINFO_INT_REGISTER + PIC16C5x_PRTC:              info->i = cpustate->PORTC;                                              break;
1057
 
                case CPUINFO_INT_REGISTER + PIC16C5x_FSR:               info->i = (cpustate->FSR & cpustate->picRAMmask);       break;
 
1043
                case CPUINFO_INT_REGISTER + PIC16C5x_FSR:               info->i = ((cpustate->FSR & cpustate->picRAMmask) | (UINT8)(~cpustate->picRAMmask));    break;
1058
1044
 
1059
1045
                /* --- the following bits of info are returned as pointers to data or functions --- */
1060
1046
                case CPUINFO_FCT_SET_INFO:                                              info->setinfo = CPU_SET_INFO_NAME(pic16c5x);    break;
1063
1049
                case CPUINFO_FCT_EXIT:                                                  info->exit = CPU_EXIT_NAME(pic16c5x);                   break;
1064
1050
                case CPUINFO_FCT_EXECUTE:                                               info->execute = CPU_EXECUTE_NAME(pic16c5x);             break;
1065
1051
                case CPUINFO_FCT_BURN:                                                  info->burn = NULL;                                                              break;
1066
 
                case CPUINFO_FCT_DISASSEMBLE:                                   info->disassemble = CPU_DISASSEMBLE_NAME(pic16c5x);             break;
 
1052
                case CPUINFO_FCT_DISASSEMBLE:                                   info->disassemble = CPU_DISASSEMBLE_NAME(pic16c5x);     break;
1067
1053
                case CPUINFO_PTR_INSTRUCTION_COUNTER:                   info->icount = &cpustate->icount;                               break;
1068
1054
 
1069
1055
                /* --- the following bits of info are returned as NULL-terminated strings --- */
1070
 
                case CPUINFO_STR_NAME:                                                  strcpy(info->s, "PIC16C5x");                    break;
1071
 
                case CPUINFO_STR_CORE_FAMILY:                                   strcpy(info->s, "Microchip");                   break;
1072
 
                case CPUINFO_STR_CORE_VERSION:                                  strcpy(info->s, "1.12");                                break;
1073
 
                case CPUINFO_STR_CORE_FILE:                                             strcpy(info->s, __FILE__);                              break;
1074
 
                case CPUINFO_STR_CORE_CREDITS:                                  strcpy(info->s, "Copyright Tony La Porta"); break;
 
1056
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "PIC16C5x");                                    break;
 
1057
                case DEVINFO_STR_FAMILY:                                                strcpy(info->s, "Microchip");                                   break;
 
1058
                case DEVINFO_STR_VERSION:                                               strcpy(info->s, "1.14");                                                break;
 
1059
                case DEVINFO_STR_SOURCE_FILE:                                   strcpy(info->s, __FILE__);                                              break;
 
1060
                case DEVINFO_STR_CREDITS:                                               strcpy(info->s, "Copyright Tony La Porta");             break;
1075
1061
 
1076
1062
                case CPUINFO_STR_FLAGS:
1077
1063
                        sprintf(info->s, "%01x%c%c%c%c%c %c%c%c%03x",
1088
1074
                                cpustate->OPTION & 0x08 ? (1<<(cpustate->OPTION&7)) : (2<<(cpustate->OPTION&7)) );
1089
1075
                        break;
1090
1076
 
1091
 
                case CPUINFO_STR_REGISTER + PIC16C5x_PC:                sprintf(info->s, "PC:%03X",   cpustate->PC); break;
1092
 
                case CPUINFO_STR_REGISTER + PIC16C5x_W:                 sprintf(info->s, "W:%02X",    cpustate->W); break;
1093
 
                case CPUINFO_STR_REGISTER + PIC16C5x_ALU:               sprintf(info->s, "ALU:%02X",  cpustate->ALU); break;
1094
 
                case CPUINFO_STR_REGISTER + PIC16C5x_STR:               sprintf(info->s, "STR:%02X",  cpustate->STATUS); break;
1095
 
                case CPUINFO_STR_REGISTER + PIC16C5x_TMR0:              sprintf(info->s, "TMR:%02X",  cpustate->TMR0); break;
1096
 
                case CPUINFO_STR_REGISTER + PIC16C5x_WDT:               sprintf(info->s, "WDT:%04X",  cpustate->WDT); break;
1097
 
                case CPUINFO_STR_REGISTER + PIC16C5x_OPT:               sprintf(info->s, "OPT:%02X",  cpustate->OPTION); break;
1098
 
                case CPUINFO_STR_REGISTER + PIC16C5x_STK0:              sprintf(info->s, "STK0:%03X", cpustate->STACK[0]); break;
1099
 
                case CPUINFO_STR_REGISTER + PIC16C5x_STK1:              sprintf(info->s, "STK1:%03X", cpustate->STACK[1]); break;
1100
 
                case CPUINFO_STR_REGISTER + PIC16C5x_PRTA:              sprintf(info->s, "PRTA:%01X", ((cpustate->PORTA) & 0xf)); break;
1101
 
                case CPUINFO_STR_REGISTER + PIC16C5x_PRTB:              sprintf(info->s, "PRTB:%02X", cpustate->PORTB); break;
1102
 
                case CPUINFO_STR_REGISTER + PIC16C5x_PRTC:              sprintf(info->s, "PRTC:%02X", cpustate->PORTC); break;
1103
 
                case CPUINFO_STR_REGISTER + PIC16C5x_TRSA:              sprintf(info->s, "TRSA:%01X", ((cpustate->TRISA) & 0xf)); break;
1104
 
                case CPUINFO_STR_REGISTER + PIC16C5x_TRSB:              sprintf(info->s, "TRSB:%02X", cpustate->TRISB); break;
1105
 
                case CPUINFO_STR_REGISTER + PIC16C5x_TRSC:              sprintf(info->s, "TRSC:%02X", cpustate->TRISC); break;
1106
 
                case CPUINFO_STR_REGISTER + PIC16C5x_FSR:               sprintf(info->s, "FSR:%02X",  ((cpustate->FSR) & cpustate->picRAMmask)); break;
1107
 
                case CPUINFO_STR_REGISTER + PIC16C5x_PSCL:              sprintf(info->s, "PSCL:%c%02X", ((cpustate->OPTION & 0x08) ? 'W':'T'), cpustate->prescaler); break;
 
1077
                case CPUINFO_STR_REGISTER + PIC16C5x_PC:                sprintf(info->s, "PC:%03X",   cpustate->PC);                            break;
 
1078
                case CPUINFO_STR_REGISTER + PIC16C5x_W:                 sprintf(info->s, "W:%02X",    cpustate->W);                                     break;
 
1079
                case CPUINFO_STR_REGISTER + PIC16C5x_ALU:               sprintf(info->s, "ALU:%02X",  cpustate->ALU);                           break;
 
1080
                case CPUINFO_STR_REGISTER + PIC16C5x_STR:               sprintf(info->s, "STR:%02X",  cpustate->STATUS);                        break;
 
1081
                case CPUINFO_STR_REGISTER + PIC16C5x_TMR0:              sprintf(info->s, "TMR:%02X",  cpustate->TMR0);                          break;
 
1082
                case CPUINFO_STR_REGISTER + PIC16C5x_WDT:               sprintf(info->s, "WDT:%04X",  cpustate->WDT);                           break;
 
1083
                case CPUINFO_STR_REGISTER + PIC16C5x_OPT:               sprintf(info->s, "OPT:%02X",  cpustate->OPTION);                        break;
 
1084
                case CPUINFO_STR_REGISTER + PIC16C5x_STK0:              sprintf(info->s, "STK0:%03X", cpustate->STACK[0]);                      break;
 
1085
                case CPUINFO_STR_REGISTER + PIC16C5x_STK1:              sprintf(info->s, "STK1:%03X", cpustate->STACK[1]);                      break;
 
1086
                case CPUINFO_STR_REGISTER + PIC16C5x_PRTA:              sprintf(info->s, "PRTA:%01X", ((cpustate->PORTA) & 0x0f));      break;
 
1087
                case CPUINFO_STR_REGISTER + PIC16C5x_PRTB:              sprintf(info->s, "PRTB:%02X", cpustate->PORTB);                         break;
 
1088
                case CPUINFO_STR_REGISTER + PIC16C5x_PRTC:              sprintf(info->s, "PRTC:%02X", cpustate->PORTC);                         break;
 
1089
                case CPUINFO_STR_REGISTER + PIC16C5x_TRSA:              sprintf(info->s, "TRSA:%01X", ((cpustate->TRISA) & 0x0f));      break;
 
1090
                case CPUINFO_STR_REGISTER + PIC16C5x_TRSB:              sprintf(info->s, "TRSB:%02X", cpustate->TRISB);                         break;
 
1091
                case CPUINFO_STR_REGISTER + PIC16C5x_TRSC:              sprintf(info->s, "TRSC:%02X", cpustate->TRISC);                         break;
 
1092
                case CPUINFO_STR_REGISTER + PIC16C5x_FSR:               sprintf(info->s, "FSR:%02X",  ((cpustate->FSR) & cpustate->picRAMmask) | (UINT8)(~cpustate->picRAMmask));       break;
 
1093
                case CPUINFO_STR_REGISTER + PIC16C5x_PSCL:              sprintf(info->s, "PSCL:%c%02X", ((cpustate->OPTION & 0x08) ? 'W':'T'), cpustate->prescaler);    break;
1108
1094
        }
1109
1095
}
1110
1096
 
1119
1105
ADDRESS_MAP_END
1120
1106
 
1121
1107
static ADDRESS_MAP_START( pic16c54_ram, ADDRESS_SPACE_DATA, 8 )
1122
 
        AM_RANGE(0x00, 0x1f) AM_RAM
 
1108
        AM_RANGE(0x00, 0x07) AM_RAM
 
1109
        AM_RANGE(0x08, 0x0f) AM_RAM
 
1110
        AM_RANGE(0x10, 0x1f) AM_RAM
1123
1111
ADDRESS_MAP_END
1124
1112
 
1125
1113
 
1131
1119
{
1132
1120
        pic16c5x_state *cpustate = get_safe_token(device);
1133
1121
 
 
1122
        update_internalram_ptr(cpustate);
 
1123
 
1134
1124
        cpustate->picmodel = 0x16C54;
1135
1125
        cpustate->picRAMmask = 0x1f;
1136
1126
        cpustate->reset_vector = 0x1ff;
1137
1127
        pic16c5x_reset_regs(cpustate);
1138
 
        cpustate->STATUS = 0x00;
1139
 
        SET(cpustate, TO_FLAG);
1140
 
        SET(cpustate, PD_FLAG);
 
1128
        CLR(cpustate->STATUS, PA_REG);
 
1129
        SET(cpustate->STATUS, (TO_FLAG | PD_FLAG));
1141
1130
}
1142
1131
 
1143
1132
 
1149
1138
{
1150
1139
        switch (state)
1151
1140
        {
 
1141
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM:                 info->i = 9;                                                    break;
 
1142
                case CPUINFO_INT_ADDRBUS_WIDTH_DATA:                    info->i = 5;                                                    break;
 
1143
 
1152
1144
                /* --- the following bits of info are returned as pointers to data or functions --- */
1153
 
                case CPUINFO_FCT_RESET:                                                 info->reset = CPU_RESET_NAME(pic16c54);                 break;
1154
 
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map16 = ADDRESS_MAP_NAME(pic16c54_rom); break;
1155
 
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:              info->internal_map8 = ADDRESS_MAP_NAME(pic16c54_ram); break;
 
1145
                case CPUINFO_FCT_RESET:                                                 info->reset = CPU_RESET_NAME(pic16c54);                                 break;
 
1146
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map16 = ADDRESS_MAP_NAME(pic16c54_rom);  break;
 
1147
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:              info->internal_map8 = ADDRESS_MAP_NAME(pic16c54_ram);   break;
1156
1148
 
1157
1149
                /* --- the following bits of info are returned as NULL-terminated strings --- */
1158
 
                case CPUINFO_STR_NAME:                                                  strcpy(info->s, "PIC16C54");                    break;
 
1150
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "PIC16C54");                    break;
1159
1151
 
1160
1152
                default:                                                                                CPU_GET_INFO_CALL(pic16c5x);                    break;
1161
1153
        }
1171
1163
ADDRESS_MAP_END
1172
1164
 
1173
1165
static ADDRESS_MAP_START( pic16c55_ram, ADDRESS_SPACE_DATA, 8 )
1174
 
        AM_RANGE(0x00, 0x1f) AM_RAM
 
1166
        AM_RANGE(0x00, 0x07) AM_RAM
 
1167
        AM_RANGE(0x08, 0x0f) AM_RAM
 
1168
        AM_RANGE(0x10, 0x1f) AM_RAM
1175
1169
ADDRESS_MAP_END
1176
1170
 
1177
1171
 
1183
1177
{
1184
1178
        pic16c5x_state *cpustate = get_safe_token(device);
1185
1179
 
 
1180
        update_internalram_ptr(cpustate);
 
1181
 
1186
1182
        cpustate->picmodel = 0x16C55;
1187
1183
        cpustate->picRAMmask = 0x1f;
1188
1184
        cpustate->reset_vector = 0x1ff;
1189
1185
        pic16c5x_reset_regs(cpustate);
1190
 
        cpustate->STATUS = 0x00;
1191
 
        SET(cpustate, TO_FLAG);
1192
 
        SET(cpustate, PD_FLAG);
 
1186
        CLR(cpustate->STATUS, PA_REG);
 
1187
        SET(cpustate->STATUS, (TO_FLAG | PD_FLAG));
1193
1188
}
1194
1189
 
1195
1190
 
1201
1196
{
1202
1197
        switch (state)
1203
1198
        {
 
1199
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM:                 info->i = 9;                                                    break;
 
1200
                case CPUINFO_INT_ADDRBUS_WIDTH_DATA:                    info->i = 5;                                                    break;
 
1201
 
1204
1202
                /* --- the following bits of info are returned as pointers to data or functions --- */
1205
 
                case CPUINFO_FCT_RESET:                                                 info->reset = CPU_RESET_NAME(pic16c55);                 break;
1206
 
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map16 = ADDRESS_MAP_NAME(pic16c55_rom); break;
1207
 
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:              info->internal_map8 = ADDRESS_MAP_NAME(pic16c55_ram); break;
 
1203
                case CPUINFO_FCT_RESET:                                                 info->reset = CPU_RESET_NAME(pic16c55);                                 break;
 
1204
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map16 = ADDRESS_MAP_NAME(pic16c55_rom);  break;
 
1205
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:              info->internal_map8 = ADDRESS_MAP_NAME(pic16c55_ram);   break;
1208
1206
 
1209
1207
                /* --- the following bits of info are returned as NULL-terminated strings --- */
1210
 
                case CPUINFO_STR_NAME:                                                  strcpy(info->s, "PIC16C55");                    break;
 
1208
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "PIC16C55");                    break;
1211
1209
 
1212
1210
                default:                                                                                CPU_GET_INFO_CALL(pic16c5x);                    break;
1213
1211
        }
1223
1221
ADDRESS_MAP_END
1224
1222
 
1225
1223
static ADDRESS_MAP_START( pic16c56_ram, ADDRESS_SPACE_DATA, 8 )
1226
 
        AM_RANGE(0x00, 0x1f) AM_RAM
 
1224
        AM_RANGE(0x00, 0x07) AM_RAM
 
1225
        AM_RANGE(0x08, 0x0f) AM_RAM
 
1226
        AM_RANGE(0x10, 0x1f) AM_RAM
1227
1227
ADDRESS_MAP_END
1228
1228
 
1229
1229
 
1235
1235
{
1236
1236
        pic16c5x_state *cpustate = get_safe_token(device);
1237
1237
 
 
1238
        update_internalram_ptr(cpustate);
 
1239
 
1238
1240
        cpustate->picmodel = 0x16C56;
1239
1241
        cpustate->picRAMmask = 0x1f;
1240
1242
        cpustate->reset_vector = 0x3ff;
1241
1243
        pic16c5x_reset_regs(cpustate);
1242
 
        cpustate->STATUS = 0x00;
1243
 
        SET(cpustate, TO_FLAG);
1244
 
        SET(cpustate, PD_FLAG);
 
1244
        CLR(cpustate->STATUS, PA_REG);
 
1245
        SET(cpustate->STATUS, (TO_FLAG | PD_FLAG));
1245
1246
}
1246
1247
 
1247
1248
 
1253
1254
{
1254
1255
        switch (state)
1255
1256
        {
 
1257
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM:                 info->i = 10;                                                   break;
 
1258
                case CPUINFO_INT_ADDRBUS_WIDTH_DATA:                    info->i = 5;                                                    break;
 
1259
 
1256
1260
                /* --- the following bits of info are returned as pointers to data or functions --- */
1257
 
                case CPUINFO_FCT_RESET:                                                 info->reset = CPU_RESET_NAME(pic16c56);                 break;
1258
 
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map16 = ADDRESS_MAP_NAME(pic16c56_rom); break;
1259
 
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:              info->internal_map8 = ADDRESS_MAP_NAME(pic16c56_ram); break;
1260
 
 
1261
 
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 10;                                   break;
 
1261
                case CPUINFO_FCT_RESET:                                                 info->reset = CPU_RESET_NAME(pic16c56);                                 break;
 
1262
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map16 = ADDRESS_MAP_NAME(pic16c56_rom);  break;
 
1263
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:              info->internal_map8 = ADDRESS_MAP_NAME(pic16c56_ram);   break;
1262
1264
 
1263
1265
                /* --- the following bits of info are returned as NULL-terminated strings --- */
1264
 
                case CPUINFO_STR_NAME:                                                  strcpy(info->s, "PIC16C56");                    break;
 
1266
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "PIC16C56");                    break;
1265
1267
 
1266
1268
                default:                                                                                CPU_GET_INFO_CALL(pic16c5x);                    break;
1267
1269
        }
1277
1279
ADDRESS_MAP_END
1278
1280
 
1279
1281
static ADDRESS_MAP_START( pic16c57_ram, ADDRESS_SPACE_DATA, 8 )
1280
 
        AM_RANGE(0x00, 0x1f) AM_RAM
 
1282
        AM_RANGE(0x00, 0x07) AM_RAM AM_MIRROR(0x60)
 
1283
        AM_RANGE(0x08, 0x0f) AM_RAM AM_MIRROR(0x60)
 
1284
        AM_RANGE(0x10, 0x1f) AM_RAM
1281
1285
        AM_RANGE(0x30, 0x3f) AM_RAM
1282
1286
        AM_RANGE(0x50, 0x5f) AM_RAM
1283
1287
        AM_RANGE(0x70, 0x7f) AM_RAM
1292
1296
{
1293
1297
        pic16c5x_state *cpustate = get_safe_token(device);
1294
1298
 
 
1299
        update_internalram_ptr(cpustate);
 
1300
 
1295
1301
        cpustate->picmodel = 0x16C57;
1296
1302
        cpustate->picRAMmask = 0x7f;
1297
1303
        cpustate->reset_vector = 0x7ff;
1298
1304
        pic16c5x_reset_regs(cpustate);
1299
 
        cpustate->STATUS = 0x00;
1300
 
        SET(cpustate, TO_FLAG);
1301
 
        SET(cpustate, PD_FLAG);
 
1305
        CLR(cpustate->STATUS, PA_REG);
 
1306
        SET(cpustate->STATUS, (TO_FLAG | PD_FLAG));
1302
1307
}
1303
1308
 
1304
1309
 
1310
1315
{
1311
1316
        switch (state)
1312
1317
        {
 
1318
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 11;                                                                   break;
 
1319
                case CPUINFO_INT_ADDRBUS_WIDTH_DATA:    info->i = 7;                                                                    break;
1313
1320
                /* --- the following bits of info are returned as pointers to data or functions --- */
1314
 
                case CPUINFO_FCT_RESET:                                                 info->reset = CPU_RESET_NAME(pic16c57);                 break;
1315
 
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map16 = ADDRESS_MAP_NAME(pic16c57_rom); break;
1316
 
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:              info->internal_map8 = ADDRESS_MAP_NAME(pic16c57_ram); break;
1317
 
 
1318
 
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 11;                                   break;
1319
 
                case CPUINFO_INT_ADDRBUS_WIDTH_DATA:    info->i = 7;                                    break;
 
1321
                case CPUINFO_FCT_RESET:                                                 info->reset = CPU_RESET_NAME(pic16c57);                                 break;
 
1322
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map16 = ADDRESS_MAP_NAME(pic16c57_rom);  break;
 
1323
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:              info->internal_map8 = ADDRESS_MAP_NAME(pic16c57_ram);   break;
1320
1324
 
1321
1325
                /* --- the following bits of info are returned as NULL-terminated strings --- */
1322
 
                case CPUINFO_STR_NAME:                                                  strcpy(info->s, "PIC16C57");                    break;
 
1326
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "PIC16C57");                    break;
1323
1327
 
1324
1328
                default:                                                                                CPU_GET_INFO_CALL(pic16c5x);                    break;
1325
1329
        }
1335
1339
ADDRESS_MAP_END
1336
1340
 
1337
1341
static ADDRESS_MAP_START( pic16c58_ram, ADDRESS_SPACE_DATA, 8 )
1338
 
        AM_RANGE(0x00, 0x1f) AM_RAM
 
1342
        AM_RANGE(0x00, 0x07) AM_RAM AM_MIRROR(0x60)
 
1343
        AM_RANGE(0x08, 0x0f) AM_RAM AM_MIRROR(0x60)
 
1344
        AM_RANGE(0x10, 0x1f) AM_RAM
1339
1345
        AM_RANGE(0x30, 0x3f) AM_RAM
1340
1346
        AM_RANGE(0x50, 0x5f) AM_RAM
1341
1347
        AM_RANGE(0x70, 0x7f) AM_RAM
1350
1356
{
1351
1357
        pic16c5x_state *cpustate = get_safe_token(device);
1352
1358
 
 
1359
        update_internalram_ptr(cpustate);
 
1360
 
1353
1361
        cpustate->picmodel = 0x16C58;
1354
1362
        cpustate->picRAMmask = 0x7f;
1355
1363
        cpustate->reset_vector = 0x7ff;
1356
1364
        pic16c5x_reset_regs(cpustate);
1357
 
        cpustate->STATUS = 0x00;
1358
 
        SET(cpustate, TO_FLAG);
1359
 
        SET(cpustate, PD_FLAG);
 
1365
        CLR(cpustate->STATUS, PA_REG);
 
1366
        SET(cpustate->STATUS, (TO_FLAG | PD_FLAG));
1360
1367
}
1361
1368
 
1362
1369
 
1368
1375
{
1369
1376
        switch (state)
1370
1377
        {
 
1378
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 11;                                                           break;
 
1379
                case CPUINFO_INT_ADDRBUS_WIDTH_DATA:    info->i = 7;                                                            break;
1371
1380
                /* --- the following bits of info are returned as pointers to data or functions --- */
1372
 
                case CPUINFO_FCT_RESET:                                                 info->reset = CPU_RESET_NAME(pic16c58);                 break;
1373
 
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map16 = ADDRESS_MAP_NAME(pic16c58_rom); break;
1374
 
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:              info->internal_map8 = ADDRESS_MAP_NAME(pic16c58_ram); break;
1375
 
 
1376
 
                case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 11;                                   break;
1377
 
                case CPUINFO_INT_ADDRBUS_WIDTH_DATA:    info->i = 7;                                    break;
 
1381
                case CPUINFO_FCT_RESET:                                                 info->reset = CPU_RESET_NAME(pic16c58);                                 break;
 
1382
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:   info->internal_map16 = ADDRESS_MAP_NAME(pic16c58_rom);  break;
 
1383
                case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA:              info->internal_map8 = ADDRESS_MAP_NAME(pic16c58_ram);   break;
1378
1384
 
1379
1385
                /* --- the following bits of info are returned as NULL-terminated strings --- */
1380
 
                case CPUINFO_STR_NAME:                                                  strcpy(info->s, "PIC16C58");                    break;
 
1386
                case DEVINFO_STR_NAME:                                                  strcpy(info->s, "PIC16C58");                    break;
1381
1387
 
1382
1388
                default:                                                                                CPU_GET_INFO_CALL(pic16c5x);                    break;
1383
1389
        }