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 *
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 *
36
45
* **** Notes: **** *
125
124
void (*function)(pic16c5x_state *);
127
/* opcode table entry (Opcode 00? has sub-opcodes) */
128
typedef struct _pic16c5x_opcode_00x pic16c5x_opcode_00x;
129
struct _pic16c5x_opcode_00x
128
INLINE void update_internalram_ptr(pic16c5x_state *cpustate)
132
void (*function)(pic16c5x_state *);
137
/****************************************************************************
138
* Read the state of the T0 Clock input signal
141
#define PIC16C5x_T0_In (memory_read_byte_8le(cpustate->io, PIC16C5x_T0))
144
/****************************************************************************
145
* Input a word from given I/O port
148
#define PIC16C5x_In(Port) ((UINT8)memory_read_byte_8le(cpustate->io, (Port)))
151
/****************************************************************************
152
* Output a word to given I/O port
130
cpustate->internalram = (UINT8 *)memory_get_write_ptr(cpustate->data, 0x00);
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))
159
/****************************************************************************
160
* Read a word from given RAM memory location
163
#define PIC16C5x_RAM_RDMEM(A) ((UINT8)memory_read_byte_8le(cpustate->data, A))
166
/****************************************************************************
167
* Write a word to given RAM memory location
170
#define PIC16C5x_RAM_WRMEM(A,V) (memory_write_byte_8le(cpustate->data, A,V))
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
180
#define PIC16C5x_RDOP(A) (memory_decrypted_read_word(cpustate->program, (A)<<1))
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
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))
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
192
154
#define TMR0 internalram[1]
201
163
#define ADDR (cpustate->opcode.b.l & 0x1f)
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)
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) */
252
214
************************************************************************/
216
#define CLR(flagreg, flag) ( flagreg &= (UINT8)(~flag) )
217
#define SET(flagreg, flag) ( flagreg |= flag )
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 };
260
INLINE void CLR(pic16c5x_state *cpustate, UINT16 flag) { cpustate->STATUS &= ~flag; }
261
INLINE void SET(pic16c5x_state *cpustate, UINT16 flag) { cpustate->STATUS |= flag; }
265
227
INLINE void CALCULATE_Z_FLAG(pic16c5x_state *cpustate)
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);
271
233
INLINE void CALCULATE_ADD_CARRY(pic16c5x_state *cpustate)
273
235
if ((UINT8)(cpustate->old_data) > (UINT8)(cpustate->ALU)) {
274
SET(cpustate, C_FLAG);
236
SET(cpustate->STATUS, C_FLAG);
277
CLR(cpustate, C_FLAG);
239
CLR(cpustate->STATUS, C_FLAG);
281
243
INLINE void CALCULATE_ADD_DIGITCARRY(pic16c5x_state *cpustate)
283
245
if (((UINT8)(cpustate->old_data) & 0x0f) > ((UINT8)(cpustate->ALU) & 0x0f)) {
284
SET(cpustate, DC_FLAG);
246
SET(cpustate->STATUS, DC_FLAG);
287
CLR(cpustate, DC_FLAG);
249
CLR(cpustate->STATUS, DC_FLAG);
291
253
INLINE void CALCULATE_SUB_CARRY(pic16c5x_state *cpustate)
293
255
if ((UINT8)(cpustate->old_data) < (UINT8)(cpustate->ALU)) {
294
CLR(cpustate, C_FLAG);
256
CLR(cpustate->STATUS, C_FLAG);
297
SET(cpustate, C_FLAG);
259
SET(cpustate->STATUS, C_FLAG);
301
263
INLINE void CALCULATE_SUB_DIGITCARRY(pic16c5x_state *cpustate)
303
265
if (((UINT8)(cpustate->old_data) & 0x0f) < ((UINT8)(cpustate->ALU) & 0x0f)) {
304
CLR(cpustate, DC_FLAG);
266
CLR(cpustate->STATUS, DC_FLAG);
307
SET(cpustate, DC_FLAG);
269
SET(cpustate->STATUS, DC_FLAG);
326
289
INLINE UINT8 GET_REGFILE(pic16c5x_state *cpustate, offs_t addr) /* Read from internal memory */
330
if ((cpustate->picmodel == 0x16C57) || (cpustate->picmodel == 0x16C58))
332
addr |= (cpustate->FSR & 0x60); /* FSR used for banking */
293
if (addr == 0) { /* Indirect addressing */
294
addr = (cpustate->FSR & cpustate->picRAMmask);
297
if ((cpustate->picmodel == 0x16C57) || (cpustate->picmodel == 0x16C58)) {
298
addr |= (cpustate->FSR & 0x60); /* FSR bits 6-5 are used for banking in direct mode */
334
301
if ((addr & 0x10) == 0) addr &= 0x0f;
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 */
343
case 04: data = (cpustate->FSR | (~cpustate->picRAMmask)); break;
305
case 00: /* Not an actual register, so return 0 */
308
case 04: data = (cpustate->FSR | (UINT8)(~cpustate->picRAMmask));
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) */
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);
353
319
case 07: if ((cpustate->picmodel == 0x16C55) || (cpustate->picmodel == 0x16C57)) {
355
321
data &= cpustate->TRISC;
356
data |= (~cpustate->TRISC & cpustate->PORTC);
322
data |= ((UINT8)(~cpustate->TRISC) & cpustate->PORTC);
358
else { /* PIC16C54, PIC16C56, PIC16C58 */
324
else { /* PIC16C54, PIC16C56, PIC16C58 */
359
325
data = M_RDRAM(addr);
362
default: data = M_RDRAM(addr); break;
328
default: data = M_RDRAM(addr);
368
334
INLINE void STORE_REGFILE(pic16c5x_state *cpustate, offs_t addr, UINT8 data) /* Write to internal memory */
370
if ((cpustate->picmodel == 0x16C57) || (cpustate->picmodel == 0x16C58))
372
addr |= (cpustate->FSR & 0x60);
336
if (addr == 0) { /* Indirect addressing */
337
addr = (cpustate->FSR & cpustate->picRAMmask);
340
if ((cpustate->picmodel == 0x16C57) || (cpustate->picmodel == 0x16C58)) {
341
addr |= (cpustate->FSR & 0x60); /* FSR bits 6-5 are used for banking in direct mode */
374
344
if ((addr & 0x10) == 0) addr &= 0x0f;
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 */
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;
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;
357
case 03: cpustate->STATUS &= (UINT8)(~PA_REG); cpustate->STATUS |= (data & PA_REG);
359
case 04: cpustate->FSR = (data | (UINT8)(~cpustate->picRAMmask));
361
case 05: data &= 0x0f; /* 4-bit port (only lower 4 bits used) */
362
P_OUT(0,data & (UINT8)(~cpustate->TRISA)); cpustate->PORTA = data;
364
case 06: P_OUT(1,data & (UINT8)(~cpustate->TRISB)); cpustate->PORTB = data;
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;
396
370
else { /* PIC16C54, PIC16C56, PIC16C58 */
397
371
M_WRTRAM(addr, data);
400
default: M_WRTRAM(addr, data); break;
374
default: M_WRTRAM(addr, data);
498
473
static void clrw(pic16c5x_state *cpustate)
501
SET(cpustate, Z_FLAG);
476
SET(cpustate->STATUS, Z_FLAG);
504
479
static void clrf(pic16c5x_state *cpustate)
506
481
STORE_REGFILE(cpustate, ADDR, 0);
507
SET(cpustate, Z_FLAG);
482
SET(cpustate->STATUS, Z_FLAG);
510
485
static void clrwdt(pic16c5x_state *cpustate)
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);
518
493
static void comf(pic16c5x_state *cpustate)
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);
665
640
switch(cpustate->opcode.b.l & 0x7)
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; }
651
illegal(cpustate); break;
673
653
default: illegal(cpustate); break;
698
678
static const pic16c5x_opcode opcode_main[256]=
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 },
735
static const pic16c5x_opcode_00x opcode_00x[16]=
715
static const pic16c5x_opcode opcode_00x[16]=
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 }
749
729
pic16c5x_state *cpustate = get_safe_token(device);
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);
736
/* ensure the internal ram pointers are set before get_info is called */
737
update_internalram_ptr(cpustate);
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);
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;
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;
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;
1039
1025
case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->PREVPC; break;
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;
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;
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;
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)) );
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;
1141
case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 9; break;
1142
case CPUINFO_INT_ADDRBUS_WIDTH_DATA: info->i = 5; break;
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;
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;
1160
1152
default: CPU_GET_INFO_CALL(pic16c5x); break;
1199
case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 9; break;
1200
case CPUINFO_INT_ADDRBUS_WIDTH_DATA: info->i = 5; break;
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;
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;
1212
1210
default: CPU_GET_INFO_CALL(pic16c5x); break;
1257
case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 10; break;
1258
case CPUINFO_INT_ADDRBUS_WIDTH_DATA: info->i = 5; break;
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;
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;
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;
1266
1268
default: CPU_GET_INFO_CALL(pic16c5x); break;
1277
1279
ADDRESS_MAP_END
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
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;
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;
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;
1324
1328
default: CPU_GET_INFO_CALL(pic16c5x); break;
1335
1339
ADDRESS_MAP_END
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
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;
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;
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;
1382
1388
default: CPU_GET_INFO_CALL(pic16c5x); break;