fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 263 lines 5.9 kB view raw
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}