fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/cpu/ppc405/opcode13.c *
7 * Created: 2003-11-10 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2003-2018 Hampa Hug <hampa@hampa.ch> *
9 * Copyright: (C) 2003-2006 Lukas Ruf <ruf@lpr.ch> *
10 *****************************************************************************/
11
12/*****************************************************************************
13 * This program is free software. You can redistribute it and / or modify it *
14 * under the terms of the GNU General Public License version 2 as published *
15 * by the Free Software Foundation. *
16 * *
17 * This program is distributed in the hope that it will be useful, but *
18 * WITHOUT ANY WARRANTY, without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
20 * Public License for more details. *
21 *****************************************************************************/
22
23/*****************************************************************************
24 * This software was developed at the Computer Engineering and Networks *
25 * Laboratory (TIK), Swiss Federal Institute of Technology (ETH) Zurich. *
26 *****************************************************************************/
27
28
29#include <stdlib.h>
30
31#include "ppc405.h"
32#include "internal.h"
33
34
35#define crop_and ((0x0c & 0x0a) & 0x0f)
36#define crop_andc ((0x0c & ~0x0a) & 0x0f)
37#define crop_nand (~(0x0c & 0x0a) & 0x0f)
38#define crop_xor ((0x0c ^ 0x0a) & 0x0f)
39#define crop_eqv (~(0x0c ^ 0x0a) & 0x0f)
40#define crop_or ((0x0c | 0x0a) & 0x0f)
41#define crop_orc ((0x0c | ~0x0a) & 0x0f)
42#define crop_nor (~(0x0c | 0x0a) & 0x0f)
43
44
45/* 13 000: mcrf bf, bfa */
46static
47void op_13_000 (p405_t *c)
48{
49 unsigned bft, bfa;
50
51 if (p405_check_reserved (c, 0x0063f801UL)) {
52 return;
53 }
54
55 bft = p405_get_ir_rt (c->ir) >> 2;
56 bfa = p405_get_ir_ra (c->ir) >> 2;
57
58 p405_set_crf (c, bft, p405_get_crf (c, bfa));
59
60 p405_set_clk (c, 4, 1);
61}
62
63/* 13 010: bclr/bclrl */
64static
65void op_13_010 (p405_t *c)
66{
67 p405_op_branch (c,
68 p405_get_lr (c) & 0xfffffffcUL,
69 (c->ir >> 21) & 0x1f, (c->ir >> 16) & 0x1f,
70 1, (c->ir & P405_IR_LK) != 0
71 );
72}
73
74/* 13 021: crnor bt, ba, bb */
75static
76void op_13_021 (p405_t *c)
77{
78 p405_op_crop (c,
79 p405_get_ir_rt (c->ir), p405_get_ir_ra (c->ir), p405_get_ir_rb (c->ir),
80 crop_nor
81 );
82}
83
84/* 13 032: rfi */
85static
86void op_13_032 (p405_t *c)
87{
88 if (p405_check_reserved (c, 0x03fff801UL)) {
89 return;
90 }
91
92 if (p405_check_privilege (c)) {
93 return;
94 }
95
96 p405_set_pc (c, p405_get_srr (c, 0));
97 p405_set_msr (c, p405_get_srr (c, 1));
98
99 p405_set_clk (c, 0, 1);
100}
101
102/* 13 033: rfci */
103static
104void op_13_033 (p405_t *c)
105{
106 if (p405_check_reserved (c, 0x03fff801UL)) {
107 return;
108 }
109
110 if (p405_check_privilege (c)) {
111 return;
112 }
113
114 p405_set_pc (c, p405_get_srr (c, 2));
115 p405_set_msr (c, p405_get_srr (c, 3));
116
117 p405_set_clk (c, 0, 1);
118}
119
120/* 13 081: crandc bt, ba, bb */
121static
122void op_13_081 (p405_t *c)
123{
124 p405_op_crop (c,
125 p405_get_ir_rt (c->ir), p405_get_ir_ra (c->ir), p405_get_ir_rb (c->ir),
126 crop_andc
127 );
128}
129
130/* 13 096: isync */
131static
132void op_13_096 (p405_t *c)
133{
134 if (p405_check_reserved (c, 0x03fff800UL)) {
135 return;
136 }
137
138 p405_set_clk (c, 4, 1);
139}
140
141/* 13 0c1: crxor bt, ba, bb */
142static
143void op_13_0c1 (p405_t *c)
144{
145 p405_op_crop (c,
146 p405_get_ir_rt (c->ir), p405_get_ir_ra (c->ir), p405_get_ir_rb (c->ir),
147 crop_xor
148 );
149}
150
151/* 13 0e1: crnand bt, ba, bb */
152static
153void op_13_0e1 (p405_t *c)
154{
155 p405_op_crop (c,
156 p405_get_ir_rt (c->ir), p405_get_ir_ra (c->ir), p405_get_ir_rb (c->ir),
157 crop_xor
158 );
159}
160
161/* 13 101: crand bt, ba, bb */
162static
163void op_13_101 (p405_t *c)
164{
165 p405_op_crop (c,
166 p405_get_ir_rt (c->ir), p405_get_ir_ra (c->ir), p405_get_ir_rb (c->ir),
167 crop_and
168 );
169}
170
171/* 13 121: creqv bt, ba, bb */
172static
173void op_13_121 (p405_t *c)
174{
175 p405_op_crop (c,
176 p405_get_ir_rt (c->ir), p405_get_ir_ra (c->ir), p405_get_ir_rb (c->ir),
177 crop_eqv
178 );
179}
180
181/* 13 1a1: crorc bt, ba, bb */
182static
183void op_13_1a1 (p405_t *c)
184{
185 p405_op_crop (c,
186 p405_get_ir_rt (c->ir), p405_get_ir_ra (c->ir), p405_get_ir_rb (c->ir),
187 crop_orc
188 );
189}
190
191/* 13 1c1: cror bt, ba, bb */
192static
193void op_13_1c1 (p405_t *c)
194{
195 p405_op_crop (c,
196 p405_get_ir_rt (c->ir), p405_get_ir_ra (c->ir), p405_get_ir_rb (c->ir),
197 crop_or
198 );
199}
200
201/* 13 210: bcctr/bcctrl */
202static
203void op_13_210 (p405_t *c)
204{
205 p405_op_branch (c,
206 p405_get_ctr (c) & 0xfffffffcUL,
207 (c->ir >> 21) & 0x1f, (c->ir >> 16) & 0x1f,
208 1, (c->ir & P405_IR_LK) != 0
209 );
210}
211
212/* 13: */
213static
214void op_13 (p405_t *c)
215{
216 unsigned op2;
217
218 op2 = (c->ir >> 1) & 0x3ff;
219
220 c->opcodes.op13[op2] (c);
221}
222
223
224static
225p405_opcode_list_t p405_opcodes_13[] = {
226 { 0x000, op_13_000 },
227 { 0x010, op_13_010 },
228 { 0x021, op_13_021 },
229 { 0x032, op_13_032 },
230 { 0x033, op_13_033 },
231 { 0x081, op_13_081 },
232 { 0x096, op_13_096 },
233 { 0x0c1, op_13_0c1 },
234 { 0x0e1, op_13_0e1 },
235 { 0x101, op_13_101 },
236 { 0x121, op_13_121 },
237 { 0x1a1, op_13_1a1 },
238 { 0x1c1, op_13_1c1 },
239 { 0x210, op_13_210 },
240 { 0x000, NULL }
241};
242
243void p405_set_opcode13 (p405_t *c)
244{
245 unsigned i;
246 p405_opcode_list_t *lst;
247 p405_opcode_f *p;
248
249 c->opcodes.op[0x13] = op_13;
250
251 p = c->opcodes.op13;
252
253 for (i = 0; i < 1024; i++) {
254 p[i] = p405_op_undefined;
255 }
256
257 lst = p405_opcodes_13;
258
259 while (lst->fct != NULL) {
260 p[lst->op] = lst->fct;
261 lst += 1;
262 }
263}