1 // license:BSD-3-Clause
2 // copyright-holders:Tony La Porta
3 /**************************************************************************\
4 * Microchip PIC16C62X Emulator *
5 * *
6 * Based On *
7 * Microchip PIC16C5X Emulator *
8 * Copyright Tony La Porta *
9 * Originally written for the MAME project. *
10 * *
11 * *
12 * Addressing architecture is based on the Harvard addressing scheme. *
13 * *
14 \**************************************************************************/
15
16 #ifndef MAME_CPU_PIC16C62X_PIC16C62X_H
17 #define MAME_CPU_PIC16C62X_PIC16C62X_H
18
19 #pragma once
20
21
22
23
24 /**************************************************************************
25 * Internal Clock divisor
26 *
27 * External Clock is divided internally by 4 for the instruction cycle
28 * times. (Each instruction cycle passes through 4 machine states). This
29 * is handled by the cpu execution engine.
30 */
31
32 enum
33 {
34 PIC16C62x_PC=1, PIC16C62x_STK0, PIC16C62x_STK1, PIC16C62x_STK2,
35 PIC16C62x_STK3, PIC16C62x_STK4, PIC16C62x_STK5, PIC16C62x_STK6,
36 PIC16C62x_STK7, PIC16C62x_FSR, PIC16C62x_W, PIC16C62x_ALU,
37 PIC16C62x_STR, PIC16C62x_OPT, PIC16C62x_TMR0, PIC16C62x_PRTA,
38 PIC16C62x_PRTB, PIC16C62x_WDT, PIC16C62x_TRSA, PIC16C62x_TRSB,
39 PIC16C62x_PSCL
40 };
41
42 #define PIC16C62x_T0 0
43
44
DECLARE_DEVICE_TYPE(PIC16C620,pic16c620_device)45 DECLARE_DEVICE_TYPE(PIC16C620, pic16c620_device)
46 DECLARE_DEVICE_TYPE(PIC16C620A, pic16c620a_device)
47 //DECLARE_DEVICE_TYPE(PIC16CR620A, pic16cr620a_device)
48 DECLARE_DEVICE_TYPE(PIC16C621, pic16c621_device)
49 DECLARE_DEVICE_TYPE(PIC16C621A, pic16c621a_device)
50 DECLARE_DEVICE_TYPE(PIC16C622, pic16c622_device)
51 DECLARE_DEVICE_TYPE(PIC16C622A, pic16c622a_device)
52
53
54 class pic16c62x_device : public cpu_device
55 {
56 public:
57 void set_config(int data);
58
59 protected:
60 // construction/destruction
61 pic16c62x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int picmodel);
62
63 // device-level overrides
64 virtual void device_start() override;
65 virtual void device_reset() override;
66
67 // device_execute_interface overrides
68 virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks + 4 - 1) / 4; }
69 virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return (cycles * 4); }
70 virtual uint32_t execute_min_cycles() const noexcept override { return 1; }
71 virtual uint32_t execute_max_cycles() const noexcept override { return 2; }
72 virtual uint32_t execute_input_lines() const noexcept override { return 1; }
73 virtual void execute_run() override;
74
75 // device_memory_interface overrides
76 virtual space_config_vector memory_space_config() const override;
77
78 // device_state_interface overrides
79 virtual void state_import(const device_state_entry &entry) override;
80 virtual void state_export(const device_state_entry &entry) override;
81 virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
82
83 // device_disasm_interface overrides
84 virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
85
86 private:
87 address_space_config m_program_config;
88 address_space_config m_data_config;
89 address_space_config m_io_config;
90
91 /******************** CPU Internal Registers *******************/
92 uint16_t m_PC;
93 uint16_t m_PREVPC; /* previous program counter */
94 uint8_t m_W;
95 uint8_t m_PCLATH; /* 0a,8a */
96 uint8_t m_OPTION; /* 81 */
97 uint16_t m_CONFIG;
98 uint8_t m_ALU;
99 uint16_t m_WDT;
100 uint8_t m_TRISA; /* 85 */
101 uint8_t m_TRISB; /* 86 */
102 uint16_t m_STACK[8];
103 uint16_t m_prescaler; /* Note: this is really an 8-bit register */
104 PAIR m_opcode;
105 uint8_t *m_internalram;
106
107 int m_icount;
108 int m_reset_vector;
109 int m_picmodel;
110 int m_delay_timer;
111 uint16_t m_temp_config;
112 uint8_t m_old_T0;
113 int8_t m_old_data;
114 uint8_t m_picRAMmask;
115 int m_inst_cycles;
116
117 memory_access<11, 1, -1, ENDIANNESS_LITTLE>::cache m_cache;
118 memory_access<11, 1, -1, ENDIANNESS_LITTLE>::specific m_program;
119 memory_access< 8, 0, 0, ENDIANNESS_LITTLE>::specific m_data;
120 memory_access< 5, 0, 0, ENDIANNESS_LITTLE>::specific m_io;
121
122 // For debugger
123 int m_debugger_temp;
124
125 /* opcode table entry */
126 typedef void (pic16c62x_device::*pic16c62x_ophandler)();
127 struct pic16c62x_opcode
128 {
129 uint8_t cycles;
130 pic16c62x_ophandler function;
131 };
132 pic16c62x_opcode m_opcode_table[16384];
133
134 /* instruction list entry */
135 struct pic16c62x_instruction
136 {
137 char *format;
138 pic16c62x_ophandler function;
139 uint8_t cycles;
140 };
141 static const pic16c62x_instruction s_instructiontable[];
142
143 void update_internalram_ptr();
144 void CALCULATE_Z_FLAG();
145 void CALCULATE_ADD_CARRY();
146 void CALCULATE_ADD_DIGITCARRY();
147 void CALCULATE_SUB_CARRY();
148 void CALCULATE_SUB_DIGITCARRY();
149 uint16_t POP_STACK();
150 void PUSH_STACK(uint16_t data);
151 uint8_t GET_REGFILE(offs_t addr);
152 void STORE_REGFILE(offs_t addr, uint8_t data);
153 void STORE_RESULT(offs_t addr, uint8_t data);
154 void illegal();
155 void addwf();
156 void addlw();
157 void andwf();
158 void andlw();
159 void bcf();
160 void bsf();
161 void btfss();
162 void btfsc();
163 void call();
164 void clrw();
165 void clrf();
166 void clrwdt();
167 void comf();
168 void decf();
169 void decfsz();
170 void goto_op();
171 void incf();
172 void incfsz();
173 void iorlw();
174 void iorwf();
175 void movf();
176 void movlw();
177 void movwf();
178 void nop();
179 void option();
180 void retlw();
181 void returns();
182 void retfie();
183 void rlf();
184 void rrf();
185 void sleepic();
186 void subwf();
187 void sublw();
188 void swapf();
189 void tris();
190 void xorlw();
191 void xorwf();
192 void build_opcode_table(void);
193 void pic16c62x_reset_regs();
194 void pic16c62x_soft_reset();
195 void pic16c62x_update_watchdog(int counts);
196 void pic16c62x_update_timer(int counts);
197
198 void pic16c620_ram(address_map &map);
199 void pic16c622_ram(address_map &map);
200 void pic16c62x_rom_10(address_map &map);
201 void pic16c62x_rom_11(address_map &map);
202 void pic16c62x_rom_9(address_map &map);
203 void pic16c62xa_ram(address_map &map);
204 };
205
206
207 class pic16c620_device : public pic16c62x_device
208 {
209 public:
210 // construction/destruction
211 pic16c620_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
212 };
213
214 class pic16c620a_device : public pic16c62x_device
215 {
216 public:
217 // construction/destruction
218 pic16c620a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
219 };
220
221 /*
222 class pic16cr620a_device : public pic16c62x_device
223 {
224 public:
225 // construction/destruction
226 pic16cr620a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
227 }*/
228
229 class pic16c621_device : public pic16c62x_device
230 {
231 public:
232 // construction/destruction
233 pic16c621_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
234 };
235
236 class pic16c621a_device : public pic16c62x_device
237 {
238 public:
239 // construction/destruction
240 pic16c621a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
241 };
242
243 class pic16c622_device : public pic16c62x_device
244 {
245 public:
246 // construction/destruction
247 pic16c622_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
248 };
249
250 class pic16c622a_device : public pic16c62x_device
251 {
252 public:
253 // construction/destruction
254 pic16c622a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
255 };
256
257
258 #endif // MAME_CPU_PIC16C62X_PIC16C62X_H
259