1 // license:BSD-3-Clause
2 // copyright-holders:Philip Bennett
3 /***************************************************************************
4
5 am29000.c
6 Core implementation of the Am29000 emulator
7
8 Written by Philip Bennett
9
10 Features missing:
11 * MMU
12 * Some instructions
13 * Various exceptions
14
15 ***************************************************************************/
16
17 #include "emu.h"
18 #include "debugger.h"
19 #include "am29000.h"
20 #include "am29dasm.h"
21
22
23 DEFINE_DEVICE_TYPE(AM29000, am29000_cpu_device, "am29000", "AMC Am29000")
24
25
26 /***************************************************************************
27 CONSTANTS
28 ***************************************************************************/
29
30 #define PFLAG_FETCH_EN (1 << 0)
31 #define PFLAG_DECODE_EN (1 << 1)
32 #define PFLAG_EXECUTE_EN (1 << 2)
33 #define PFLAG_WRITEBACK_EN (1 << 3)
34 #define PFLAG_IRQ (1 << 4)
35 #define PFLAG_LOADSTORE (1 << 5)
36 #define PFLAG_MULTI_LOADSTORE (1 << 6)
37 #define PFLAG_JUMP (1 << 7)
38 #define PFLAG_JUMP2 (1 << 8)
39 #define PFLAG_IRET (1 << 9)
40 #define PFLAG_TIMER_LOADED (1 << 10)
41
42 #define PFLAG_RA_DEPENDENCY (1 << 26)
43 #define PFLAG_RB_DEPENDENCY (1 << 27)
44
45 #define PFLAG_MEM_MULTIPLE (1 << 29)
46 #define PFLAG_REG_WRITEBACK (1 << 30)
47 #define PFLAG_MEM_WRITEBACK (1 << 31)
48
49 #define MMU_PROGRAM_ACCESS (0)
50 #define MMU_DATA_ACCESS (1)
51
52 #define FREEZE_MODE (m_cps & CPS_FZ)
53 #define SUPERVISOR_MODE (m_cps & CPS_SM)
54 #define USER_MODE (~m_cps & CPS_SM)
55 #define REGISTER_IS_PROTECTED(x) (m_rbp & (1 << ((x) >> 4)))
56
57 #define INST_RB_FIELD(x) ((x) & 0xff)
58 #define INST_RA_FIELD(x) (((x) >> 8) & 0xff)
59 #define INST_RC_FIELD(x) (((x) >> 16) & 0xff)
60 #define INST_SA_FIELD(x) (((x) >> 8) & 0xff)
61
62 #define FIELD_RA 0
63 #define FIELD_RB 1
64 #define FIELD_RC 2
65
66 #define SIGNAL_EXCEPTION(x) (signal_exception(x))
67
68
69 #define GET_ALU_FC ((m_alu >> ALU_FC_SHIFT) & ALU_FC_MASK)
70 #define GET_ALU_BP ((m_alu >> ALU_BP_SHIFT) & ALU_BP_MASK)
71 #define GET_CHC_CR ((m_chc >> CHC_CR_SHIFT) & CHC_CR_MASK)
72
73 #define SET_ALU_FC(x) do { m_alu &= ~(ALU_FC_MASK << ALU_FC_SHIFT); m_alu |= ((x) & ALU_FC_MASK) << ALU_FC_SHIFT; } while(0)
74 #define SET_ALU_BP(x) do { m_alu &= ~(ALU_BP_MASK << ALU_BP_SHIFT); m_alu |= ((x) & ALU_BP_MASK) << ALU_BP_SHIFT; } while(0)
75 #define SET_CHC_CR(x) do { m_chc &= ~(CHC_CR_MASK << CHC_CR_SHIFT); m_chc |= ((x) & CHC_CR_MASK) << CHC_CR_SHIFT; } while(0)
76
77
78 /***************************************************************************
79 STATE ACCESSORS
80 ***************************************************************************/
81
am29000_cpu_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)82 am29000_cpu_device::am29000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
83 : cpu_device(mconfig, AM29000, tag, owner, clock)
84 , m_program_config("program", ENDIANNESS_BIG, 32, 32, 0)
85 , m_io_config("io", ENDIANNESS_BIG, 32, 32, 0)
86 , m_data_config("data", ENDIANNESS_BIG, 32, 32, 0)
87 {
88 memset( m_r, 0, sizeof(m_r) );
89 memset( m_tlb, 0, sizeof(m_tlb) );
90 m_vab = 0;
91 m_ops = 0;
92 m_cha = 0;
93 m_chd = 0;
94 m_chc = 0;
95 m_rbp = 0;
96 m_tmc = 0;
97 m_tmr = 0;
98 m_pc0 = 0;
99 m_pc1 = 0;
100 m_pc2 = 0;
101 m_mmu = 0;
102 m_lru = 0;
103 m_ipc = 0;
104 m_ipa = 0;
105 m_ipb = 0;
106 m_q = 0;
107 m_alu = 0;
108 m_fpe = 0;
109 m_inte = 0;
110 m_fps = 0;
111 memset( m_exception_queue, 0, sizeof( m_exception_queue) );
112 m_irq_active = 0;
113 m_irq_lines = 0;
114 m_exec_ir = 0;
115 m_next_ir = 0;
116 m_pl_flags = 0;
117 m_iret_pc = 0;
118 m_exec_pc = 0;
119 m_next_pc = 0;
120 }
121
memory_space_config() const122 device_memory_interface::space_config_vector am29000_cpu_device::memory_space_config() const
123 {
124 return space_config_vector {
125 std::make_pair(AS_PROGRAM, &m_program_config),
126 std::make_pair(AS_DATA, &m_data_config),
127 std::make_pair(AS_IO, &m_io_config)
128 };
129 }
130
device_start()131 void am29000_cpu_device::device_start()
132 {
133 space(AS_PROGRAM).cache(m_cache);
134 space(AS_PROGRAM).specific(m_program);
135 space(AS_DATA).cache(m_datacache);
136 space(AS_DATA).specific(m_data);
137 space(AS_IO).specific(m_io);
138
139 m_cfg = (PRL_AM29000 | PRL_REV_D) << CFG_PRL_SHIFT;
140
141 /* Register state for saving */
142 save_item(NAME(m_pc));
143 save_item(NAME(m_r));
144 save_item(NAME(m_tlb));
145
146 save_item(NAME(m_vab));
147 save_item(NAME(m_ops));
148 save_item(NAME(m_cps));
149 save_item(NAME(m_cfg));
150 save_item(NAME(m_cha));
151 save_item(NAME(m_chd));
152 save_item(NAME(m_chc));
153 save_item(NAME(m_rbp));
154 save_item(NAME(m_tmc));
155 save_item(NAME(m_tmr));
156 save_item(NAME(m_pc0));
157 save_item(NAME(m_pc1));
158 save_item(NAME(m_pc2));
159 save_item(NAME(m_mmu));
160 save_item(NAME(m_lru));
161
162 save_item(NAME(m_ipc));
163 save_item(NAME(m_ipa));
164 save_item(NAME(m_ipb));
165 save_item(NAME(m_q));
166
167 save_item(NAME(m_alu));
168 save_item(NAME(m_fpe));
169 save_item(NAME(m_inte));
170 save_item(NAME(m_fps));
171
172 save_item(NAME(m_exceptions));
173 save_item(NAME(m_exception_queue));
174
175 save_item(NAME(m_irq_active));
176 save_item(NAME(m_irq_lines));
177
178 save_item(NAME(m_exec_ir));
179 save_item(NAME(m_next_ir));
180
181 save_item(NAME(m_pl_flags));
182 save_item(NAME(m_next_pl_flags));
183
184 save_item(NAME(m_iret_pc));
185 save_item(NAME(m_exec_pc));
186 save_item(NAME(m_next_pc));
187
188 // Register state for debugger
189 state_add( AM29000_PC, "PC", m_pc ).callimport().formatstr("%08X");
190 state_add( AM29000_VAB, "VAB", m_vab ).formatstr("%08X");
191 state_add( AM29000_OPS, "OPS", m_ops ).formatstr("%08X");
192 state_add( AM29000_CPS, "CPS", m_cps ).formatstr("%08X");
193 state_add( AM29000_CFG, "CFG", m_cfg ).formatstr("%08X");
194 state_add( AM29000_CHA, "CHA", m_cha ).formatstr("%08X");
195 state_add( AM29000_CHD, "CHD", m_chd ).formatstr("%08X");
196 state_add( AM29000_CHC, "CHC", m_chc ).formatstr("%08X");
197 state_add( AM29000_RBP, "RBP", m_rbp ).formatstr("%08X");
198 state_add( AM29000_TMC, "TMC", m_tmc ).formatstr("%08X");
199 state_add( AM29000_TMR, "TMR", m_tmr ).formatstr("%08X");
200 state_add( AM29000_PC0, "PC0", m_pc0 ).formatstr("%08X");
201 state_add( AM29000_PC1, "PC1", m_pc1 ).formatstr("%08X");
202 state_add( AM29000_PC2, "PC2", m_pc2 ).formatstr("%08X");
203 state_add( AM29000_MMU, "MMU", m_mmu ).formatstr("%08X");
204 state_add( AM29000_LRU, "LRU", m_lru ).formatstr("%08X");
205 state_add( AM29000_IPC, "IPC", m_ipc ).formatstr("%08X");
206 state_add( AM29000_IPA, "IPA", m_ipa ).formatstr("%08X");
207 state_add( AM29000_IPB, "IPB", m_ipb ).formatstr("%08X");
208 state_add( AM29000_Q, "Q", m_q ).formatstr("%08X");
209 state_add( AM29000_ALU, "ALU", m_alu ).formatstr("%08X");
210 // state_add( AM29000_BP, "BP", GET_ALU_BP).formatstr("%08X");
211 // state_add( AM29000_FC, "FC", GET_ALU_FC).formatstr("%08X");
212 // state_add( AM29000_CR, "CR", GET_CHC_CR).formatstr("%08X");
213 state_add( AM29000_FPE, "FPE", m_fpe ).formatstr("%08X");
214 state_add( AM29000_INTE, "INTE", m_inte ).formatstr("%08X");
215 state_add( AM29000_FPS, "FPS", m_fps ).formatstr("%08X");
216 state_add( AM29000_R1, "R1", m_r[1] ).formatstr("%08X");
217 state_add( AM29000_R64, "R64", m_r[64] ).formatstr("%08X");
218 state_add( AM29000_R65, "R65", m_r[65] ).formatstr("%08X");
219 state_add( AM29000_R66, "R66", m_r[66] ).formatstr("%08X");
220 state_add( AM29000_R67, "R67", m_r[67] ).formatstr("%08X");
221 state_add( AM29000_R68, "R68", m_r[68] ).formatstr("%08X");
222 state_add( AM29000_R69, "R69", m_r[69] ).formatstr("%08X");
223 state_add( AM29000_R70, "R70", m_r[70] ).formatstr("%08X");
224 state_add( AM29000_R71, "R71", m_r[71] ).formatstr("%08X");
225 state_add( AM29000_R72, "R72", m_r[72] ).formatstr("%08X");
226 state_add( AM29000_R73, "R73", m_r[73] ).formatstr("%08X");
227 state_add( AM29000_R74, "R74", m_r[74] ).formatstr("%08X");
228 state_add( AM29000_R75, "R75", m_r[75] ).formatstr("%08X");
229 state_add( AM29000_R76, "R76", m_r[76] ).formatstr("%08X");
230 state_add( AM29000_R77, "R77", m_r[77] ).formatstr("%08X");
231 state_add( AM29000_R78, "R78", m_r[78] ).formatstr("%08X");
232 state_add( AM29000_R79, "R79", m_r[79] ).formatstr("%08X");
233 state_add( AM29000_R80, "R80", m_r[80] ).formatstr("%08X");
234 state_add( AM29000_R81, "R81", m_r[81] ).formatstr("%08X");
235 state_add( AM29000_R82, "R82", m_r[82] ).formatstr("%08X");
236 state_add( AM29000_R83, "R83", m_r[83] ).formatstr("%08X");
237 state_add( AM29000_R84, "R84", m_r[84] ).formatstr("%08X");
238 state_add( AM29000_R85, "R85", m_r[85] ).formatstr("%08X");
239 state_add( AM29000_R86, "R86", m_r[86] ).formatstr("%08X");
240 state_add( AM29000_R87, "R87", m_r[87] ).formatstr("%08X");
241 state_add( AM29000_R88, "R88", m_r[88] ).formatstr("%08X");
242 state_add( AM29000_R89, "R89", m_r[89] ).formatstr("%08X");
243 state_add( AM29000_R90, "R90", m_r[90] ).formatstr("%08X");
244 state_add( AM29000_R91, "R91", m_r[91] ).formatstr("%08X");
245 state_add( AM29000_R92, "R92", m_r[92] ).formatstr("%08X");
246 state_add( AM29000_R93, "R93", m_r[93] ).formatstr("%08X");
247 state_add( AM29000_R94, "R94", m_r[94] ).formatstr("%08X");
248 state_add( AM29000_R95, "R95", m_r[95] ).formatstr("%08X");
249 state_add( AM29000_R96, "R96", m_r[96] ).formatstr("%08X");
250 state_add( AM29000_R97, "R97", m_r[97] ).formatstr("%08X");
251 state_add( AM29000_R98, "R98", m_r[98] ).formatstr("%08X");
252 state_add( AM29000_R99, "R99", m_r[99] ).formatstr("%08X");
253 state_add( AM29000_R100, "R100", m_r[100] ).formatstr("%08X");
254 state_add( AM29000_R101, "R101", m_r[101] ).formatstr("%08X");
255 state_add( AM29000_R102, "R102", m_r[102] ).formatstr("%08X");
256 state_add( AM29000_R103, "R103", m_r[103] ).formatstr("%08X");
257 state_add( AM29000_R104, "R104", m_r[104] ).formatstr("%08X");
258 state_add( AM29000_R105, "R105", m_r[105] ).formatstr("%08X");
259 state_add( AM29000_R106, "R106", m_r[106] ).formatstr("%08X");
260 state_add( AM29000_R107, "R107", m_r[107] ).formatstr("%08X");
261 state_add( AM29000_R108, "R108", m_r[108] ).formatstr("%08X");
262 state_add( AM29000_R109, "R109", m_r[109] ).formatstr("%08X");
263 state_add( AM29000_R110, "R110", m_r[110] ).formatstr("%08X");
264 state_add( AM29000_R111, "R111", m_r[111] ).formatstr("%08X");
265 state_add( AM29000_R112, "R112", m_r[112] ).formatstr("%08X");
266 state_add( AM29000_R113, "R113", m_r[113] ).formatstr("%08X");
267 state_add( AM29000_R114, "R114", m_r[114] ).formatstr("%08X");
268 state_add( AM29000_R115, "R115", m_r[115] ).formatstr("%08X");
269 state_add( AM29000_R116, "R116", m_r[116] ).formatstr("%08X");
270 state_add( AM29000_R117, "R117", m_r[117] ).formatstr("%08X");
271 state_add( AM29000_R118, "R118", m_r[118] ).formatstr("%08X");
272 state_add( AM29000_R119, "R119", m_r[119] ).formatstr("%08X");
273 state_add( AM29000_R120, "R120", m_r[120] ).formatstr("%08X");
274 state_add( AM29000_R121, "R121", m_r[121] ).formatstr("%08X");
275 state_add( AM29000_R122, "R122", m_r[122] ).formatstr("%08X");
276 state_add( AM29000_R123, "R123", m_r[123] ).formatstr("%08X");
277 state_add( AM29000_R124, "R124", m_r[124] ).formatstr("%08X");
278 state_add( AM29000_R125, "R125", m_r[125] ).formatstr("%08X");
279 state_add( AM29000_R126, "R126", m_r[126] ).formatstr("%08X");
280 state_add( AM29000_R127, "R127", m_r[127] ).formatstr("%08X");
281 state_add( AM29000_R128, "R128", m_r[128] ).formatstr("%08X");
282 state_add( AM29000_R129, "R129", m_r[129] ).formatstr("%08X");
283 state_add( AM29000_R130, "R130", m_r[130] ).formatstr("%08X");
284 state_add( AM29000_R131, "R131", m_r[131] ).formatstr("%08X");
285 state_add( AM29000_R132, "R132", m_r[132] ).formatstr("%08X");
286 state_add( AM29000_R133, "R133", m_r[133] ).formatstr("%08X");
287 state_add( AM29000_R134, "R134", m_r[134] ).formatstr("%08X");
288 state_add( AM29000_R135, "R135", m_r[135] ).formatstr("%08X");
289 state_add( AM29000_R136, "R136", m_r[136] ).formatstr("%08X");
290 state_add( AM29000_R137, "R137", m_r[137] ).formatstr("%08X");
291 state_add( AM29000_R138, "R138", m_r[138] ).formatstr("%08X");
292 state_add( AM29000_R139, "R139", m_r[139] ).formatstr("%08X");
293 state_add( AM29000_R140, "R140", m_r[140] ).formatstr("%08X");
294 state_add( AM29000_R141, "R141", m_r[141] ).formatstr("%08X");
295 state_add( AM29000_R142, "R142", m_r[142] ).formatstr("%08X");
296 state_add( AM29000_R143, "R143", m_r[143] ).formatstr("%08X");
297 state_add( AM29000_R144, "R144", m_r[144] ).formatstr("%08X");
298 state_add( AM29000_R145, "R145", m_r[145] ).formatstr("%08X");
299 state_add( AM29000_R146, "R146", m_r[146] ).formatstr("%08X");
300 state_add( AM29000_R147, "R147", m_r[147] ).formatstr("%08X");
301 state_add( AM29000_R148, "R148", m_r[148] ).formatstr("%08X");
302 state_add( AM29000_R149, "R149", m_r[149] ).formatstr("%08X");
303 state_add( AM29000_R150, "R150", m_r[150] ).formatstr("%08X");
304 state_add( AM29000_R151, "R151", m_r[151] ).formatstr("%08X");
305 state_add( AM29000_R152, "R152", m_r[152] ).formatstr("%08X");
306 state_add( AM29000_R153, "R153", m_r[153] ).formatstr("%08X");
307 state_add( AM29000_R154, "R154", m_r[154] ).formatstr("%08X");
308 state_add( AM29000_R155, "R155", m_r[155] ).formatstr("%08X");
309 state_add( AM29000_R156, "R156", m_r[156] ).formatstr("%08X");
310 state_add( AM29000_R157, "R157", m_r[157] ).formatstr("%08X");
311 state_add( AM29000_R158, "R158", m_r[158] ).formatstr("%08X");
312 state_add( AM29000_R159, "R159", m_r[159] ).formatstr("%08X");
313 state_add( AM29000_R160, "R160", m_r[160] ).formatstr("%08X");
314 state_add( AM29000_R161, "R161", m_r[161] ).formatstr("%08X");
315 state_add( AM29000_R162, "R162", m_r[162] ).formatstr("%08X");
316 state_add( AM29000_R163, "R163", m_r[163] ).formatstr("%08X");
317 state_add( AM29000_R164, "R164", m_r[164] ).formatstr("%08X");
318 state_add( AM29000_R165, "R165", m_r[165] ).formatstr("%08X");
319 state_add( AM29000_R166, "R166", m_r[166] ).formatstr("%08X");
320 state_add( AM29000_R167, "R167", m_r[167] ).formatstr("%08X");
321 state_add( AM29000_R168, "R168", m_r[168] ).formatstr("%08X");
322 state_add( AM29000_R169, "R169", m_r[169] ).formatstr("%08X");
323 state_add( AM29000_R170, "R170", m_r[170] ).formatstr("%08X");
324 state_add( AM29000_R171, "R171", m_r[171] ).formatstr("%08X");
325 state_add( AM29000_R172, "R172", m_r[172] ).formatstr("%08X");
326 state_add( AM29000_R173, "R173", m_r[173] ).formatstr("%08X");
327 state_add( AM29000_R174, "R174", m_r[174] ).formatstr("%08X");
328 state_add( AM29000_R175, "R175", m_r[175] ).formatstr("%08X");
329 state_add( AM29000_R176, "R176", m_r[176] ).formatstr("%08X");
330 state_add( AM29000_R177, "R177", m_r[177] ).formatstr("%08X");
331 state_add( AM29000_R178, "R178", m_r[178] ).formatstr("%08X");
332 state_add( AM29000_R179, "R179", m_r[179] ).formatstr("%08X");
333 state_add( AM29000_R180, "R180", m_r[180] ).formatstr("%08X");
334 state_add( AM29000_R181, "R181", m_r[181] ).formatstr("%08X");
335 state_add( AM29000_R182, "R182", m_r[182] ).formatstr("%08X");
336 state_add( AM29000_R183, "R183", m_r[183] ).formatstr("%08X");
337 state_add( AM29000_R184, "R184", m_r[184] ).formatstr("%08X");
338 state_add( AM29000_R185, "R185", m_r[185] ).formatstr("%08X");
339 state_add( AM29000_R186, "R186", m_r[186] ).formatstr("%08X");
340 state_add( AM29000_R187, "R187", m_r[187] ).formatstr("%08X");
341 state_add( AM29000_R188, "R188", m_r[188] ).formatstr("%08X");
342 state_add( AM29000_R189, "R189", m_r[189] ).formatstr("%08X");
343 state_add( AM29000_R190, "R190", m_r[190] ).formatstr("%08X");
344 state_add( AM29000_R191, "R191", m_r[191] ).formatstr("%08X");
345 state_add( AM29000_R192, "R192", m_r[192] ).formatstr("%08X");
346 state_add( AM29000_R193, "R193", m_r[193] ).formatstr("%08X");
347 state_add( AM29000_R194, "R194", m_r[194] ).formatstr("%08X");
348 state_add( AM29000_R195, "R195", m_r[195] ).formatstr("%08X");
349 state_add( AM29000_R196, "R196", m_r[196] ).formatstr("%08X");
350 state_add( AM29000_R197, "R197", m_r[197] ).formatstr("%08X");
351 state_add( AM29000_R198, "R198", m_r[198] ).formatstr("%08X");
352 state_add( AM29000_R199, "R199", m_r[199] ).formatstr("%08X");
353 state_add( AM29000_R200, "R200", m_r[200] ).formatstr("%08X");
354 state_add( AM29000_R201, "R201", m_r[201] ).formatstr("%08X");
355 state_add( AM29000_R202, "R202", m_r[202] ).formatstr("%08X");
356 state_add( AM29000_R203, "R203", m_r[203] ).formatstr("%08X");
357 state_add( AM29000_R204, "R204", m_r[204] ).formatstr("%08X");
358 state_add( AM29000_R205, "R205", m_r[205] ).formatstr("%08X");
359 state_add( AM29000_R206, "R206", m_r[206] ).formatstr("%08X");
360 state_add( AM29000_R207, "R207", m_r[207] ).formatstr("%08X");
361 state_add( AM29000_R208, "R208", m_r[208] ).formatstr("%08X");
362 state_add( AM29000_R209, "R209", m_r[209] ).formatstr("%08X");
363 state_add( AM29000_R210, "R210", m_r[210] ).formatstr("%08X");
364 state_add( AM29000_R211, "R211", m_r[211] ).formatstr("%08X");
365 state_add( AM29000_R212, "R212", m_r[212] ).formatstr("%08X");
366 state_add( AM29000_R213, "R213", m_r[213] ).formatstr("%08X");
367 state_add( AM29000_R214, "R214", m_r[214] ).formatstr("%08X");
368 state_add( AM29000_R215, "R215", m_r[215] ).formatstr("%08X");
369 state_add( AM29000_R216, "R216", m_r[216] ).formatstr("%08X");
370 state_add( AM29000_R217, "R217", m_r[217] ).formatstr("%08X");
371 state_add( AM29000_R218, "R218", m_r[218] ).formatstr("%08X");
372 state_add( AM29000_R219, "R219", m_r[219] ).formatstr("%08X");
373 state_add( AM29000_R220, "R220", m_r[220] ).formatstr("%08X");
374 state_add( AM29000_R221, "R221", m_r[221] ).formatstr("%08X");
375 state_add( AM29000_R222, "R222", m_r[222] ).formatstr("%08X");
376 state_add( AM29000_R223, "R223", m_r[223] ).formatstr("%08X");
377 state_add( AM29000_R224, "R224", m_r[224] ).formatstr("%08X");
378 state_add( AM29000_R225, "R225", m_r[225] ).formatstr("%08X");
379 state_add( AM29000_R226, "R226", m_r[226] ).formatstr("%08X");
380 state_add( AM29000_R227, "R227", m_r[227] ).formatstr("%08X");
381 state_add( AM29000_R228, "R228", m_r[228] ).formatstr("%08X");
382 state_add( AM29000_R229, "R229", m_r[229] ).formatstr("%08X");
383 state_add( AM29000_R230, "R230", m_r[230] ).formatstr("%08X");
384 state_add( AM29000_R231, "R231", m_r[231] ).formatstr("%08X");
385 state_add( AM29000_R232, "R232", m_r[232] ).formatstr("%08X");
386 state_add( AM29000_R233, "R233", m_r[233] ).formatstr("%08X");
387 state_add( AM29000_R234, "R234", m_r[234] ).formatstr("%08X");
388 state_add( AM29000_R235, "R235", m_r[235] ).formatstr("%08X");
389 state_add( AM29000_R236, "R236", m_r[236] ).formatstr("%08X");
390 state_add( AM29000_R237, "R237", m_r[237] ).formatstr("%08X");
391 state_add( AM29000_R238, "R238", m_r[238] ).formatstr("%08X");
392 state_add( AM29000_R239, "R239", m_r[239] ).formatstr("%08X");
393 state_add( AM29000_R240, "R240", m_r[240] ).formatstr("%08X");
394 state_add( AM29000_R241, "R241", m_r[241] ).formatstr("%08X");
395 state_add( AM29000_R242, "R242", m_r[242] ).formatstr("%08X");
396 state_add( AM29000_R243, "R243", m_r[243] ).formatstr("%08X");
397 state_add( AM29000_R244, "R244", m_r[244] ).formatstr("%08X");
398 state_add( AM29000_R245, "R245", m_r[245] ).formatstr("%08X");
399 state_add( AM29000_R246, "R246", m_r[246] ).formatstr("%08X");
400 state_add( AM29000_R247, "R247", m_r[247] ).formatstr("%08X");
401 state_add( AM29000_R248, "R248", m_r[248] ).formatstr("%08X");
402 state_add( AM29000_R249, "R249", m_r[249] ).formatstr("%08X");
403 state_add( AM29000_R250, "R250", m_r[250] ).formatstr("%08X");
404 state_add( AM29000_R251, "R251", m_r[251] ).formatstr("%08X");
405 state_add( AM29000_R252, "R252", m_r[252] ).formatstr("%08X");
406 state_add( AM29000_R253, "R253", m_r[253] ).formatstr("%08X");
407 state_add( AM29000_R254, "R254", m_r[254] ).formatstr("%08X");
408 state_add( AM29000_R255, "R255", m_r[255] ).formatstr("%08X");
409
410 state_add(STATE_GENPCBASE, "CURPC", m_pc).callimport().noshow();
411 state_add(STATE_GENFLAGS, "CURFLAGS", m_alu).formatstr("%13s").noshow();
412
413 set_icountptr(m_icount);
414 }
415
416
417 //-------------------------------------------------
418 // state_import - import state into the device,
419 // after it has been set
420 //-------------------------------------------------
421
state_import(const device_state_entry & entry)422 void am29000_cpu_device::state_import(const device_state_entry &entry)
423 {
424 switch (entry.index())
425 {
426 case AM29000_PC:
427 case STATE_GENPCBASE:
428 m_next_pc = m_pc;
429 break;
430 }
431 }
432
433
434 //-------------------------------------------------
435 // state_string_export - export state as a string
436 // for the debugger
437 //-------------------------------------------------
438
state_string_export(const device_state_entry & entry,std::string & str) const439 void am29000_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const
440 {
441 switch (entry.index())
442 {
443 case STATE_GENFLAGS:
444 str = string_format("%c%c%c%c%c%c%c%c%c|%3d",
445 m_alu & ALU_V ? 'V' : '.',
446 m_alu & ALU_Z ? 'Z' : '.',
447 m_alu & ALU_N ? 'N' : '.',
448 m_alu & ALU_C ? 'C' : '.',
449 m_cps & CPS_IP ? 'I' : '.',
450 m_cps & CPS_FZ ? 'F' : '.',
451 m_cps & CPS_SM ? 'S' : 'U',
452 m_cps & CPS_DI ? 'I' : '.',
453 m_cps & CPS_DA ? 'D' : '.',
454 (m_r[1] >> 2) & 0x7f);
455 break;
456 }
457 }
458
459
device_reset()460 void am29000_cpu_device::device_reset()
461 {
462 m_cps = CPS_FZ | CPS_RE | CPS_PD | CPS_PI | CPS_SM | CPS_DI | CPS_DA;
463 m_cfg &= ~(CFG_DW | CFG_CD);
464 m_chc &= ~CHC_CV;
465
466 m_pc = 0;
467 m_next_pl_flags = 0;
468 m_exceptions = 0;
469 m_irq_lines = 0;
470 }
471
472
signal_exception(uint32_t type)473 void am29000_cpu_device::signal_exception(uint32_t type)
474 {
475 m_exception_queue[m_exceptions++] = type;
476 }
477
478
external_irq_check()479 void am29000_cpu_device::external_irq_check()
480 {
481 int mask = (m_cps >> CPS_IM_SHIFT) & CPS_IM_MASK;
482 int irq_en = !(m_cps & CPS_DI) && !(m_cps & CPS_DA);
483 int i;
484
485 /* Clear interrupt pending bit to begin with */
486 m_cps &= ~CPS_IP;
487
488 for (i = 0; i < 4; ++i)
489 {
490 if (!(m_irq_active & (1 << i)) && (m_irq_lines & (1 << i)))
491 {
492 if (irq_en)
493 {
494 if (i <= mask)
495 {
496 m_irq_active |= (1 << i);
497 signal_exception(EXCEPTION_INTR0 + i);
498 m_pl_flags |= PFLAG_IRQ;
499 return;
500 }
501 }
502 /* Set interrupt pending bit if interrupt was disabled */
503 m_cps |= CPS_IP;
504 }
505 else
506 m_irq_active &= ~(1 << i);
507 }
508 }
509
510
read_program_word(uint32_t address)511 uint32_t am29000_cpu_device::read_program_word(uint32_t address)
512 {
513 /* TODO: ROM enable? */
514 if (m_cps & CPS_PI || m_cps & CPS_RE)
515 return m_cache.read_dword(address);
516 else
517 {
518 fatalerror("Am29000 instruction MMU translation enabled!\n");
519 }
520 // never executed
521 //return 0;
522 }
523
524 /***************************************************************************
525 HELPER FUNCTIONS
526 ***************************************************************************/
527
get_abs_reg(uint8_t r,uint32_t iptr)528 uint32_t am29000_cpu_device::get_abs_reg(uint8_t r, uint32_t iptr)
529 {
530 if (r & 0x80)
531 {
532 /* Stack pointer access */
533 r = ((m_r[1] >> 2) & 0x7f) + (r & 0x7f);
534 r |= 0x80;
535 }
536 else if (r == 0)
537 {
538 /* Indirect pointer access */
539 r = (iptr >> IPX_SHIFT) & 0xff;
540 }
541 else if (r > 1 && r < 64)
542 {
543 fatalerror("Am29000: Undefined register access (%d)\n", r);
544 }
545 return r;
546 }
547
548
549 /***************************************************************************
550 CORE INCLUDE
551 ***************************************************************************/
552
553 #include "am29ops.h"
554
555
556 /***************************************************************************
557 PIPELINE STAGES
558 ***************************************************************************/
559
fetch_decode()560 void am29000_cpu_device::fetch_decode()
561 {
562 uint32_t inst;
563 uint32_t op_flags;
564
565 inst = read_program_word(m_pc);
566 m_next_ir = inst;
567
568 op_flags = op_table[inst >> 24].flags;
569
570 /* Illegal instruction */
571 /* TODO: This should be checked at this point */
572 #if 0
573 if (op_flags & IFLAG_ILLEGAL)
574 {
575 fatalerror("Illegal instruction: %x PC:%x PC0:%x PC1:%x\n", inst, m_pc, m_pc0, m_pc1);
576 SIGNAL_EXCEPTION(EXCEPTION_ILLEGAL_OPCODE);
577 return;
578 }
579 #endif
580
581 /* Privledge violations */
582 if (USER_MODE)
583 {
584 if ((op_flags & IFLAG_SUPERVISOR_ONLY))
585 {
586 signal_exception(EXCEPTION_PROTECTION_VIOLATION);
587 return;
588 }
589
590 if ((op_flags & IFLAG_SPR_ACCESS))
591 {
592 /* TODO: Is this the right place to check this? */
593 if (INST_SA_FIELD(inst) < 128)
594 {
595 SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION);
596 return;
597 }
598 }
599
600 /* Register bank protection */
601 if ((op_flags & IFLAG_RA_PRESENT) && REGISTER_IS_PROTECTED(INST_RA_FIELD(inst)))
602 {
603 SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION);
604 return;
605 }
606
607 if ((op_flags & IFLAG_RB_PRESENT) && REGISTER_IS_PROTECTED(INST_RB_FIELD(inst)))
608 {
609 SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION);
610 return;
611 }
612
613 if ((op_flags & IFLAG_RC_PRESENT) && REGISTER_IS_PROTECTED(INST_RC_FIELD(inst)))
614 {
615 SIGNAL_EXCEPTION(EXCEPTION_PROTECTION_VIOLATION);
616 return;
617 }
618 }
619
620 if (m_pl_flags & PFLAG_IRET)
621 m_next_pc = m_iret_pc;
622 else
623 m_next_pc += 4;
624 }
625
626 /***************************************************************************
627 CORE EXECUTION LOOP
628 ***************************************************************************/
629
execute_run()630 void am29000_cpu_device::execute_run()
631 {
632 uint32_t call_debugger = (machine().debug_flags & DEBUG_FLAG_ENABLED) != 0;
633
634 external_irq_check();
635
636 do
637 {
638 m_next_pl_flags = PFLAG_EXECUTE_EN;
639
640 if (!FREEZE_MODE)
641 {
642 m_pc1 = m_pc0;
643 m_pc0 = m_pc;
644 }
645
646 if (m_exceptions)
647 {
648 m_ops = m_cps;
649 m_cps &= ~(CPS_TE | CPS_TP | CPS_TU | CPS_FZ | CPS_LK | CPS_WM | CPS_PD | CPS_PI | CPS_SM | CPS_DI | CPS_DA);
650 m_cps |= (CPS_FZ | CPS_PD | CPS_PI | CPS_SM | CPS_DI | CPS_DA);
651
652 if (m_pl_flags & PFLAG_IRET)
653 {
654 m_pc0 = m_iret_pc;
655 m_pc1 = m_next_pc;
656 }
657
658
659 if (m_cfg & CFG_VF)
660 {
661 uint32_t vaddr = m_vab | m_exception_queue[0] * 4;
662 uint32_t vect = m_datacache.read_dword(vaddr);
663
664 m_pc = vect & ~3;
665 m_next_pc = m_pc;
666 }
667 else
668 {
669 fatalerror("Am29000: Non vectored interrupt fetch!\n");
670 }
671
672 m_exceptions = 0;
673 m_pl_flags = 0;
674 }
675
676 if (call_debugger)
677 debugger_instruction_hook(m_pc);
678
679 fetch_decode();
680
681 if (m_pl_flags & PFLAG_EXECUTE_EN)
682 {
683 if (!FREEZE_MODE)
684 m_pc2 = m_pc1;
685
686 (this->*op_table[m_exec_ir >> 24].opcode)();
687 }
688
689 m_exec_ir = m_next_ir;
690 m_pl_flags = m_next_pl_flags;
691 m_exec_pc = m_pc;
692 m_pc = m_next_pc;
693 } while (--m_icount > 0);
694 }
695
696
execute_set_input(int inputnum,int state)697 void am29000_cpu_device::execute_set_input(int inputnum, int state)
698 {
699 if (state)
700 m_irq_lines |= (1 << inputnum);
701 else
702 m_irq_lines &= ~(1 << inputnum);
703
704 // TODO : CHECK IRQs
705 }
706
create_disassembler()707 std::unique_ptr<util::disasm_interface> am29000_cpu_device::create_disassembler()
708 {
709 return std::make_unique<am29000_disassembler>();
710 }
711