src/emu/cpu/ssp1610/ssp1610d.c
| r2009 | r2010 | |
| 1 | | /* |
| 2 | | |
| 3 | | SSP1610 disassembler |
| 4 | | written by Pierpaolo Prazzoli |
| 5 | | |
| 6 | | */ |
| 7 | | |
| 8 | | #include <math.h> |
| 9 | | #include "debugger.h" |
| 10 | | #include "cpuintrf.h" |
| 11 | | |
| 12 | | |
| 13 | | static const char *const reg[] = |
| 14 | | { |
| 15 | | "-", "X", "Y", "A", "ST", "STACK", "PC", "P", "AL", "?", "?", "XST", "PL", "?", "?", "SRCR", "BRCR", "BRER", |
| 16 | | "XRD0", "XRD1", "AE", "DIOR", "GR22", "GR23", "EXT0", "EXT1", "EXT2", "EXT3", "EXT4", "EXT5", "EXT6", "EXT7" |
| 17 | | }; |
| 18 | | |
| 19 | | static const char *const rij[] = |
| 20 | | { |
| 21 | | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" |
| 22 | | }; |
| 23 | | |
| 24 | | static const char *const erij[] = |
| 25 | | { |
| 26 | | "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" |
| 27 | | }; |
| 28 | | |
| 29 | | static const char *const modifier[] = |
| 30 | | { |
| 31 | | "", "+!", "-", "+" |
| 32 | | }; |
| 33 | | |
| 34 | | static const char *const cond[] = |
| 35 | | { |
| 36 | | "always", "always", "RESERVED", "RESERVED", "gpi0=0", "gpi0=1", "gpi1=0", "gpi1=1", "l=0", "l=1", "z=0", "z=1", "ov=0", "ov=1", "n=0", "n=1", |
| 37 | | "diof=0", "diof=1", "gpi2=0", "gpi2=1", "gpi3=0", "gpi3=1", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED" |
| 38 | | }; |
| 39 | | |
| 40 | | static const char *const acc_op[] = |
| 41 | | { |
| 42 | | "ror", "rol", "shr", "shl", "inc", "dec", "neg", "abs" |
| 43 | | }; |
| 44 | | |
| 45 | | // pag. 81 uses different addresses! |
| 46 | | static const char *const flag_op[] = |
| 47 | | { |
| 48 | | "?", "?", "resl", "setl", "resie", "setie", "?", "?", "resop", "setop", "?", "?", "?", "?", "res", "set" |
| 49 | | }; |
| 50 | | |
| 51 | | |
| 52 | | static const char *const st_mod[] = |
| 53 | | { |
| 54 | | "macs", "rpl", "gpo", "rb", "gpo0", "gpo1", "gpo2", "gpo3", "wte", "diof", "bre", "reserved", "reserved", "reserved", "reserved", "reserved" |
| 55 | | }; |
| 56 | | |
| 57 | | |
| 58 | | #define BIT_B ((op >> 8) & 1) |
| 59 | | #define RIJ rij[(BIT_B << 2) + (op & 3)] |
| 60 | | #define RI(i) rij[(i) & 3] |
| 61 | | #define RJ(i) rij[((i) & 3) + 4] |
| 62 | | #define MODIFIER(i) modifier[(i) & 3] |
| 63 | | #define MODIFIER_LOW MODIFIER(op >> 2) |
| 64 | | #define MODIFIER_HIGH MODIFIER(op >> 6) |
| 65 | | #define COND cond[(op >> 4) & 0xf] |
| 66 | | |
| 67 | | static offs_t base_pc; |
| 68 | | static const UINT8 *base_oprom; |
| 69 | | #define READ_OP_DASM(p) ((base_oprom[(p) - base_pc] << 8) | base_oprom[(p) + 1 - base_pc]) |
| 70 | | |
| 71 | | //TODO: |
| 72 | | // - add special Short-form Direct Addressing for r3 and r7 |
| 73 | | // - support DASM flags |
| 74 | | |
| 75 | | unsigned dasm_ssp1610(char *buffer, unsigned pc, const UINT8 *oprom) |
| 76 | | { |
| 77 | | UINT16 op; |
| 78 | | UINT8 op_num; |
| 79 | | int size = 1; |
| 80 | | int flags = 0; |
| 81 | | |
| 82 | | base_pc = pc; |
| 83 | | base_oprom = oprom; |
| 84 | | |
| 85 | | op = READ_OP_DASM(pc); |
| 86 | | op_num = op >> 9; |
| 87 | | |
| 88 | | // .....overlapping opcodes.... |
| 89 | | // |
| 90 | | // ldi simm ? |
| 91 | | // ld d, (a) ? |
| 92 | | // mset reg, (ri), b ? overlaps other opcodes |
| 93 | | // mset (rj), (ri), b ? |
| 94 | | // repb simm/srcr, imm ? |
| 95 | | // reps simm/srcr ? |
| 96 | | // subi (rij)/erij/reg,imm,t ? |
| 97 | | /* |
| 98 | | // mod x, nimm, n |
| 99 | | case 0x11: |
| 100 | | sprintf(buffer, "mod x, %X, %d", op & 0xf, (op >> 4) & 1); |
| 101 | | break; |
| 102 | | |
| 103 | | // mset (rj), (ri), ss |
| 104 | | case 0x18, 0x19: // ss order? |
| 105 | | sprintf(buffer, "mset (%s%s), (%s%s), %d%d", RJ(op >> 5), MODIFIER(op >> 7), RI(op), MODIFIER_LOW, (op >> 9) & 1, (op >> 4) & 1); |
| 106 | | break; |
| 107 | | |
| 108 | | // mod st, bs, nimm |
| 109 | | case 0x28: //? docs say 0x24 |
| 110 | | sprintf(buffer, "mod st, %s, %x", st_mod[(op >> 5) & 0xf], op & 0xf); |
| 111 | | break; |
| 112 | | */ |
| 113 | | |
| 114 | | switch( op_num ) |
| 115 | | { |
| 116 | | |
| 117 | | //???????????????????? |
| 118 | | |
| 119 | | // ldi simm |
| 120 | | // case 0x08: |
| 121 | | // sprintf(buffer, "ldi %X", op & 0xff); |
| 122 | | // break; |
| 123 | | |
| 124 | | // maybe |
| 125 | | // mod st, bs, nimm |
| 126 | | case 0x25: //? docs say 0x24 |
| 127 | | sprintf(buffer, "mod st, %s, %x", st_mod[(op >> 5) & 0xf], op & 0xf); |
| 128 | | break; |
| 129 | | |
| 130 | | //???????????????????? |
| 131 | | |
| 132 | | case 0x00: |
| 133 | | |
| 134 | | if(op == 0) // right? |
| 135 | | { |
| 136 | | // nop |
| 137 | | sprintf(buffer, "nop"); |
| 138 | | } |
| 139 | | else if((op & 0xff) == 0x65) |
| 140 | | { |
| 141 | | // ret |
| 142 | | sprintf(buffer, "ret"); |
| 143 | | } |
| 144 | | else |
| 145 | | { |
| 146 | | // ld d, s |
| 147 | | sprintf(buffer, "ld %s, %s", reg[(op >> 4) & 0xf], reg[0xf]); |
| 148 | | } |
| 149 | | |
| 150 | | break; |
| 151 | | |
| 152 | | // ld d, (ri) -> probably right |
| 153 | | case 0x01: // or ldi simm ? |
| 154 | | sprintf(buffer, "ld %s, (%s%s)", reg[(op >> 4) & 0xf], RIJ, MODIFIER_LOW); |
| 155 | | break; |
| 156 | | |
| 157 | | // ld (ri), s |
| 158 | | case 0x02: |
| 159 | | sprintf(buffer, "ld (%s%s), %s", RIJ, MODIFIER_LOW, reg[(op >> 4) & 0xf]); |
| 160 | | break; |
| 161 | | |
| 162 | | // ld a, addr |
| 163 | | case 0x03: |
| 164 | | sprintf(buffer, "ld a, %X", op & 0x1ff); |
| 165 | | break; |
| 166 | | |
| 167 | | // ldi d, imm |
| 168 | | case 0x04: |
| 169 | | sprintf(buffer, "ld %s, %X", reg[(op >> 4) & 0xf], READ_OP_DASM(pc+2)); |
| 170 | | size = 2; |
| 171 | | break; |
| 172 | | |
| 173 | | // ld d, ((ri)) |
| 174 | | case 0x05: |
| 175 | | sprintf(buffer, "ld %s, ((%s%s))", reg[(op >> 4) & 0xf], RIJ, MODIFIER_LOW); |
| 176 | | break; |
| 177 | | |
| 178 | | // ldi (ri), imm |
| 179 | | case 0x06: |
| 180 | | sprintf(buffer, "ld (%s%s), %X", RIJ, MODIFIER_LOW, READ_OP_DASM(pc+2)); |
| 181 | | size = 2; |
| 182 | | break; |
| 183 | | |
| 184 | | // ld addr, a -> almost sure it's this one. some of the 1st 4 bits are set in the code |
| 185 | | case 0x07: // or ld d, (a) ? |
| 186 | | sprintf(buffer, "ld %X, a", op & 0x1ff); |
| 187 | | break; |
| 188 | | |
| 189 | | // ld d, ri |
| 190 | | case 0x09: |
| 191 | | sprintf(buffer, "ld %s, %s%s", reg[(op >> 4) & 0xf], RIJ, MODIFIER_LOW); |
| 192 | | break; |
| 193 | | |
| 194 | | // ld ri, s |
| 195 | | case 0x0a: |
| 196 | | sprintf(buffer, "ld %s%s, %s", RIJ, MODIFIER_LOW, reg[(op >> 4) & 0xf]); |
| 197 | | break; |
| 198 | | |
| 199 | | // mpys (rj), (ri), b |
| 200 | | case 0x0b: |
| 201 | | sprintf(buffer, "mpya (%s%s), (%s%s), %d", RJ(op >> 4), MODIFIER_HIGH, RI(op), MODIFIER_LOW, BIT_B); |
| 202 | | break; |
| 203 | | |
| 204 | | // ldi ri, simm |
| 205 | | case 0x0c: |
| 206 | | case 0x0d: |
| 207 | | case 0x0e: |
| 208 | | case 0x0f: |
| 209 | | sprintf(buffer, "ldi %s, %X", rij[(op >> 7) & 7], op & 0xff); |
| 210 | | break; |
| 211 | | |
| 212 | | // sub a, s |
| 213 | | case 0x10: |
| 214 | | sprintf(buffer, "sub a, %s", reg[op & 0xf]); |
| 215 | | break; |
| 216 | | |
| 217 | | // sub a, (ri) |
| 218 | | case 0x11: |
| 219 | | sprintf(buffer, "sub a, (%s%s)", RIJ, MODIFIER_LOW); |
| 220 | | break; |
| 221 | | |
| 222 | | // mpys s, (ri), b |
| 223 | | case 0x12: |
| 224 | | sprintf(buffer, "mpya %s, (%s%s), %d", reg[(op >> 4) & 0xf], RI(op), MODIFIER_LOW, BIT_B); |
| 225 | | break; |
| 226 | | |
| 227 | | // sub a, adr |
| 228 | | case 0x13: |
| 229 | | sprintf(buffer, "sub a, %X", op & 0xff); |
| 230 | | break; |
| 231 | | |
| 232 | | // subi a, imm |
| 233 | | case 0x14: |
| 234 | | sprintf(buffer, "subi a, %X", READ_OP_DASM(pc+2)); |
| 235 | | size = 2; |
| 236 | | break; |
| 237 | | |
| 238 | | // sub a, ((ri)) |
| 239 | | case 0x15: |
| 240 | | sprintf(buffer, "sub a, ((%s%s))", RIJ, MODIFIER_LOW); |
| 241 | | break; |
| 242 | | |
| 243 | | // sub a, ri |
| 244 | | case 0x19: |
| 245 | | sprintf(buffer, "sub a, %s%s", RIJ, MODIFIER_LOW); |
| 246 | | break; |
| 247 | | |
| 248 | | // mset reg, (ri), s |
| 249 | | case 0x1a: |
| 250 | | case 0x1b: |
| 251 | | sprintf(buffer, "mset %s, (%s%s), %d", reg[(op >> 5) & 0x1f], RI(op), MODIFIER_LOW, (op >> 4) & 1); |
| 252 | | break; |
| 253 | | |
| 254 | | // subi simm |
| 255 | | case 0x1c: |
| 256 | | sprintf(buffer, "subi %X", op & 0xff); |
| 257 | | break; |
| 258 | | |
| 259 | | // sub a, erij |
| 260 | | case 0x23: |
| 261 | | sprintf(buffer, "sub a, %s%s", erij[(op >> 2) & 7], MODIFIER(op)); |
| 262 | | break; |
| 263 | | |
| 264 | | // call cond, addr |
| 265 | | case 0x24: //f bit? |
| 266 | | sprintf(buffer, "call %s, %X", COND, READ_OP_DASM(pc+2)); |
| 267 | | size = 2; |
| 268 | | break; |
| 269 | | |
| 270 | | // bra cond, addr |
| 271 | | case 0x26: //f bit? |
| 272 | | sprintf(buffer, "bra %s, %X", COND, READ_OP_DASM(pc+2)); |
| 273 | | size = 2; |
| 274 | | break; |
| 275 | | |
| 276 | | |
| 277 | | case 0x28: |
| 278 | | |
| 279 | | if(op & 0x100) |
| 280 | | { |
| 281 | | // slow imm |
| 282 | | sprintf(buffer, "slow %X", op & 0xf); |
| 283 | | } |
| 284 | | else |
| 285 | | { |
| 286 | | // stop |
| 287 | | sprintf(buffer, "stop"); |
| 288 | | } |
| 289 | | |
| 290 | | break; |
| 291 | | |
| 292 | | // cmp a, s |
| 293 | | case 0x30: |
| 294 | | sprintf(buffer, "cmp a, %s", reg[op & 0xf]); |
| 295 | | break; |
| 296 | | |
| 297 | | // cmp a, (ri) |
| 298 | | case 0x31: |
| 299 | | sprintf(buffer, "cmp a, (%s%s)", RIJ, MODIFIER_LOW); |
| 300 | | break; |
| 301 | | |
| 302 | | // cmp a, adr |
| 303 | | case 0x33: |
| 304 | | sprintf(buffer, "cmp a, %X", op & 0xff); |
| 305 | | break; |
| 306 | | |
| 307 | | // cmpi a, imm |
| 308 | | case 0x34: |
| 309 | | sprintf(buffer, "cmpi a, %X", READ_OP_DASM(pc+2)); |
| 310 | | size = 2; |
| 311 | | break; |
| 312 | | |
| 313 | | // cmp a, ((ri)) |
| 314 | | case 0x35: |
| 315 | | sprintf(buffer, "cmp a, ((%s%s))", RIJ, MODIFIER_LOW); |
| 316 | | break; |
| 317 | | |
| 318 | | // cmp a, ri |
| 319 | | case 0x39: |
| 320 | | sprintf(buffer, "cmp a, %s%s", RIJ, MODIFIER_LOW); |
| 321 | | break; |
| 322 | | |
| 323 | | // cmpi simm |
| 324 | | case 0x3c: |
| 325 | | sprintf(buffer, "cmpi %X", op & 0xff); |
| 326 | | break; |
| 327 | | |
| 328 | | // add a, s |
| 329 | | case 0x40: |
| 330 | | sprintf(buffer, "add a, %s", reg[op & 0xf]); |
| 331 | | break; |
| 332 | | |
| 333 | | // add a, (ri) |
| 334 | | case 0x41: |
| 335 | | sprintf(buffer, "add a, (%s%s)", RIJ, MODIFIER_LOW); |
| 336 | | break; |
| 337 | | |
| 338 | | // mpya s, (ri), b |
| 339 | | case 0x42: |
| 340 | | sprintf(buffer, "mpya %s, (%s%s), %d", reg[(op >> 4) & 0xf], RI(op), MODIFIER_LOW, BIT_B); |
| 341 | | break; |
| 342 | | |
| 343 | | // add a, adr |
| 344 | | case 0x43: |
| 345 | | sprintf(buffer, "add a, %X", op & 0xff); |
| 346 | | break; |
| 347 | | |
| 348 | | // addi a, imm |
| 349 | | case 0x44: |
| 350 | | //sprintf(buffer, "addi a, %X", READ_OP_DASM(pc+2)); |
| 351 | | size = 2; |
| 352 | | |
| 353 | | if(op & 0x1ff) |
| 354 | | sprintf(buffer, "addi a, %X (CHECK ME!)", READ_OP_DASM(pc+2)); |
| 355 | | else |
| 356 | | sprintf(buffer, "addi a, %X", READ_OP_DASM(pc+2)); |
| 357 | | |
| 358 | | break; |
| 359 | | |
| 360 | | // add a, ((ri)) |
| 361 | | case 0x45: |
| 362 | | sprintf(buffer, "add a, ((%s%s))", RIJ, MODIFIER_LOW); |
| 363 | | break; |
| 364 | | |
| 365 | | // mod cond, op |
| 366 | | case 0x48: |
| 367 | | sprintf(buffer, "mod %s, %s", COND, acc_op[op & 7]); |
| 368 | | break; |
| 369 | | |
| 370 | | // add a, ri |
| 371 | | case 0x49: |
| 372 | | sprintf(buffer, "add a, %s%s", RIJ, MODIFIER_LOW); |
| 373 | | break; |
| 374 | | |
| 375 | | // mod f, op |
| 376 | | case 0x4a: |
| 377 | | sprintf(buffer, "%s", flag_op[op & 0xf]); |
| 378 | | break; |
| 379 | | |
| 380 | | // mpya (rj), (ri), b |
| 381 | | case 0x4b: |
| 382 | | sprintf(buffer, "mpya (%s%s), (%s%s), %d", RJ(op >> 4), MODIFIER_HIGH, RI(op), MODIFIER_LOW, BIT_B); |
| 383 | | break; |
| 384 | | |
| 385 | | // addi simm |
| 386 | | case 0x4c: // docs show a wrong opcode value |
| 387 | | sprintf(buffer, "addi %X", op & 0xff); |
| 388 | | break; |
| 389 | | |
| 390 | | // ld reg, erij |
| 391 | | case 0x4e: |
| 392 | | case 0x4f: |
| 393 | | sprintf(buffer, "ld %s, %s%s", reg[(op >> 5) & 0x1f], erij[(op >> 2) & 7], MODIFIER(op)); |
| 394 | | break; |
| 395 | | |
| 396 | | // and a, s |
| 397 | | case 0x50: |
| 398 | | sprintf(buffer, "and a, %s", reg[op & 0xf]); |
| 399 | | break; |
| 400 | | |
| 401 | | // and a, (ri) |
| 402 | | case 0x51: |
| 403 | | sprintf(buffer, "and a, (%s%s)", RIJ, MODIFIER_LOW); |
| 404 | | break; |
| 405 | | |
| 406 | | // mld s, (ri), b |
| 407 | | case 0x52: |
| 408 | | sprintf(buffer, "mld %s, (%s%s), %d", reg[(op >> 4) & 0xf], RI(op), MODIFIER_LOW, BIT_B); |
| 409 | | break; |
| 410 | | |
| 411 | | // and a, adr |
| 412 | | case 0x53: |
| 413 | | sprintf(buffer, "and a, %X", op & 0xff); |
| 414 | | break; |
| 415 | | |
| 416 | | // andi a, imm |
| 417 | | case 0x54: |
| 418 | | // sprintf(buffer, "andi a, %X", READ_OP_DASM(pc+2)); |
| 419 | | size = 2; |
| 420 | | |
| 421 | | if(op & 0x1ff) |
| 422 | | sprintf(buffer, "andi a, %X (CHECK ME!)", READ_OP_DASM(pc+2)); |
| 423 | | else |
| 424 | | sprintf(buffer, "andi a, %X", READ_OP_DASM(pc+2)); |
| 425 | | |
| 426 | | break; |
| 427 | | |
| 428 | | // and a, ((ri)) |
| 429 | | case 0x55: |
| 430 | | sprintf(buffer, "and a, ((%s%s))", RIJ, MODIFIER_LOW); |
| 431 | | break; |
| 432 | | |
| 433 | | // and a, ri |
| 434 | | case 0x59: |
| 435 | | sprintf(buffer, "and a, %s%s", RIJ, MODIFIER_LOW); |
| 436 | | break; |
| 437 | | |
| 438 | | // mld (rj), (ri), b |
| 439 | | case 0x5b: |
| 440 | | sprintf(buffer, "mld (%s%s), (%s%s), %d", RJ(op >> 4), MODIFIER_HIGH, RI(op), MODIFIER_LOW, BIT_B); |
| 441 | | break; |
| 442 | | |
| 443 | | // andi simm |
| 444 | | case 0x5c: |
| 445 | | sprintf(buffer, "andi %X", op & 0xff); |
| 446 | | break; |
| 447 | | |
| 448 | | // ld erij, reg |
| 449 | | case 0x5e: |
| 450 | | case 0x5f: |
| 451 | | sprintf(buffer, "ld %s%s, %s", erij[(op >> 2) & 7], MODIFIER(op), reg[(op >> 5) & 0x1f]); |
| 452 | | break; |
| 453 | | |
| 454 | | // or a, s |
| 455 | | case 0x60: |
| 456 | | sprintf(buffer, "or a, %s", reg[op & 0xf]); |
| 457 | | break; |
| 458 | | |
| 459 | | // or a, (ri) |
| 460 | | case 0x61: |
| 461 | | sprintf(buffer, "or a, (%s%s)", RIJ, MODIFIER_LOW); |
| 462 | | break; |
| 463 | | |
| 464 | | // or a, adr |
| 465 | | case 0x63: |
| 466 | | sprintf(buffer, "or a, %X", op & 0xff); |
| 467 | | break; |
| 468 | | |
| 469 | | // ori a, imm |
| 470 | | case 0x64: |
| 471 | | sprintf(buffer, "ori a, %X", READ_OP_DASM(pc+2)); |
| 472 | | size = 2; |
| 473 | | break; |
| 474 | | |
| 475 | | // or a, ((ri)) |
| 476 | | case 0x65: |
| 477 | | sprintf(buffer, "or a, ((%s%s))", RIJ, MODIFIER_LOW); |
| 478 | | break; |
| 479 | | |
| 480 | | // or a, ri |
| 481 | | case 0x69: |
| 482 | | sprintf(buffer, "or a, %s%s", RIJ, MODIFIER_LOW); |
| 483 | | break; |
| 484 | | |
| 485 | | // ori simm |
| 486 | | case 0x6c: |
| 487 | | sprintf(buffer, "ori %X", op & 0xff); |
| 488 | | break; |
| 489 | | |
| 490 | | // eor a, s |
| 491 | | case 0x70: |
| 492 | | sprintf(buffer, "eor a, %s", reg[op & 0xf]); |
| 493 | | break; |
| 494 | | |
| 495 | | // eor a, (ri) |
| 496 | | case 0x71: |
| 497 | | sprintf(buffer, "eor a, (%s%s)", RIJ, MODIFIER_LOW); |
| 498 | | break; |
| 499 | | |
| 500 | | // eor a, adr |
| 501 | | case 0x73: |
| 502 | | sprintf(buffer, "eor a, %X", op & 0xff); |
| 503 | | break; |
| 504 | | |
| 505 | | // eori a, imm |
| 506 | | case 0x74: |
| 507 | | sprintf(buffer, "eori a, %X", READ_OP_DASM(pc+2)); |
| 508 | | size = 2; |
| 509 | | break; |
| 510 | | |
| 511 | | // eor a, ((ri)) |
| 512 | | case 0x75: |
| 513 | | sprintf(buffer, "eor a, ((%s%s))", RIJ, MODIFIER_LOW); |
| 514 | | break; |
| 515 | | |
| 516 | | // eor a, ri |
| 517 | | case 0x79: |
| 518 | | sprintf(buffer, "eor a, %s%s", RIJ, MODIFIER_LOW); |
| 519 | | break; |
| 520 | | |
| 521 | | // eori simm |
| 522 | | case 0x7c: |
| 523 | | sprintf(buffer, "eori %X", op & 0xff); |
| 524 | | break; |
| 525 | | |
| 526 | | default: |
| 527 | | sprintf(buffer, "OP = %02X",op_num); |
| 528 | | break; |
| 529 | | } |
| 530 | | |
| 531 | | return size | flags | DASMFLAG_SUPPORTED; |
| 532 | | } |
src/emu/cpu/ssp1610/ssp1610.c
| r2009 | r2010 | |
| 1 | | /******************************************************************** |
| 2 | | SSP1610 cpu emulator |
| 3 | | written by Pierpaolo Prazzoli |
| 4 | | |
| 5 | | Very very preliminary. Still working on it... |
| 6 | | |
| 7 | | *********************************************************************/ |
| 8 | | |
| 9 | | #include "debugger.h" |
| 10 | | #include "deprecat.h" |
| 11 | | #include "ssp1610.h" |
| 12 | | |
| 13 | | #define READ_OP(addr) (cpu_readop16(addr<<1)) |
| 14 | | |
| 15 | | static int ssp1610_ICount; |
| 16 | | |
| 17 | | /* Registers */ |
| 18 | | |
| 19 | | enum |
| 20 | | { |
| 21 | | SSP1610_REG0 = 1, SSP1610_X, SSP1610_Y, SSP1610_A, SSP1610_ST, SSP1610_STACK, SSP1610_PC, |
| 22 | | SSP1610_P, SSP1610_AL, SSP1610_XST, SSP1610_PL, SSP1610_SRCR, SSP1610_BRCR, SSP1610_BRER, |
| 23 | | SSP1610_XRD0, SSP1610_XRD1, SSP1610_AE, SSP1610_DIOR, SSP1610_GR22, SSP1610_GR23, |
| 24 | | SSP1610_EXT0, SSP1610_EXT1, SSP1610_EXT2, SSP1610_EXT3, SSP1610_EXT4, SSP1610_EXT5, SSP1610_EXT6, SSP1610_EXT7 |
| 25 | | }; |
| 26 | | |
| 27 | | /* Internal registers */ |
| 28 | | typedef struct |
| 29 | | { |
| 30 | | UINT32 regs[32]; // some are 8bits, some 16bits and some 32bits |
| 31 | | |
| 32 | | UINT16 ppc; |
| 33 | | |
| 34 | | } ssp1610_regs; |
| 35 | | |
| 36 | | static ssp1610_regs ssp1610; |
| 37 | | |
| 38 | | // number of bits of each register |
| 39 | | static const UINT8 regs_width[] = |
| 40 | | { |
| 41 | | 16, 16, 16, 32, 16, 16, 16, 32, 16, 0, 0, 16, 16, 0, 0, 8, |
| 42 | | 8, 16, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 |
| 43 | | }; |
| 44 | | |
| 45 | | // REGISTERS |
| 46 | | |
| 47 | | #define PPC ssp1610.ppc |
| 48 | | |
| 49 | | #define REG0 ssp1610.regs[0] |
| 50 | | #define X ssp1610.regs[1] |
| 51 | | #define Y ssp1610.regs[2] |
| 52 | | #define A ssp1610.regs[3] |
| 53 | | #define ST ssp1610.regs[4] |
| 54 | | //swapped stack and pc (docs wrong...) |
| 55 | | #define STACK ssp1610.regs[5] |
| 56 | | #define PC ssp1610.regs[6] |
| 57 | | #define P ssp1610.regs[7] |
| 58 | | #define AL ssp1610.regs[8] |
| 59 | | // 9 |
| 60 | | // 10 |
| 61 | | #define XST ssp1610.regs[11] |
| 62 | | #define PL ssp1610.regs[12] |
| 63 | | // 13 |
| 64 | | // 14 |
| 65 | | #define SRCR ssp1610.regs[15] |
| 66 | | #define BRCR ssp1610.regs[16] |
| 67 | | #define BRER ssp1610.regs[17] |
| 68 | | #define XRD0 ssp1610.regs[18] |
| 69 | | #define XRD1 ssp1610.regs[19] |
| 70 | | #define AE ssp1610.regs[20] |
| 71 | | #define DIOR ssp1610.regs[21] |
| 72 | | #define GR22 ssp1610.regs[22] |
| 73 | | #define GR23 ssp1610.regs[23] |
| 74 | | #define EXT0 ssp1610.regs[24] |
| 75 | | #define EXT1 ssp1610.regs[25] |
| 76 | | #define EXT2 ssp1610.regs[26] |
| 77 | | #define EXT3 ssp1610.regs[27] |
| 78 | | #define EXT4 ssp1610.regs[28] |
| 79 | | #define EXT5 ssp1610.regs[29] |
| 80 | | #define EXT6 ssp1610.regs[30] |
| 81 | | #define EXT7 ssp1610.regs[31] |
| 82 | | |
| 83 | | // CONDITIONS |
| 84 | | |
| 85 | | #define IS_PC 6 |
| 86 | | |
| 87 | | // CONTROL bits |
| 88 | | |
| 89 | | |
| 90 | | #define RPL ((ST >> 0) & 7) |
| 91 | | #define RB ((ST >> 3) & 3) |
| 92 | | #define GP0_0 ((ST >> 5) & 1) |
| 93 | | #define GP0_1 ((ST >> 6) & 1) |
| 94 | | #define IE ((ST >> 7) & 1) |
| 95 | | #define OP ((ST >> 8) & 1) |
| 96 | | #define MACS ((ST >> 9) & 1) |
| 97 | | |
| 98 | | |
| 99 | | // FLAG bits |
| 100 | | |
| 101 | | |
| 102 | | #define GPI_0 ((ST >> 10) & 1) |
| 103 | | #define GPI_1 ((ST >> 11) & 1) |
| 104 | | |
| 105 | | |
| 106 | | #define L ((ST >> 12) & 1) |
| 107 | | #define Z ((ST >> 13) & 1) |
| 108 | | #define OV ((ST >> 14) & 1) |
| 109 | | #define N ((ST >> 15) & 1) |
| 110 | | |
| 111 | | #define SET_L(value) ST = (ST & ~(1 << 12)) | ((value) << 12) |
| 112 | | #define SET_Z(value) ST = (ST & ~(1 << 13)) | ((value) << 13) |
| 113 | | #define SET_OV(value) ST = (ST & ~(1 << 14)) | ((value) << 14) |
| 114 | | #define SET_N(value) ST = (ST & ~(1 << 15)) | ((value) << 15) |
| 115 | | |
| 116 | | #define SET_OVSUB(x,y,z)(ST = (ST & ~(1 << 14)) | ((((z) ^ (y)) & ((y) ^ (x)) & 0x80000000) ? (1 << 14): 0)) |
| 117 | | |
| 118 | | static void ssp1610_init(int index, int clock, const void *config, int (*irqcallback)(int)) |
| 119 | | { |
| 120 | | REG0 = 0xffff; // read-only register |
| 121 | | } |
| 122 | | |
| 123 | | static void ssp1610_reset(void) |
| 124 | | { |
| 125 | | ST = 0; |
| 126 | | |
| 127 | | // latch it from 0 but it's selectable (hard-coded for now) |
| 128 | | PC = 0x400; |
| 129 | | } |
| 130 | | |
| 131 | | static void ssp1610_exit(void) |
| 132 | | { |
| 133 | | // nothing to do |
| 134 | | } |
| 135 | | |
| 136 | | static int ssp1610_execute(int cycles) |
| 137 | | { |
| 138 | | ssp1610_ICount = cycles; |
| 139 | | |
| 140 | | do |
| 141 | | { |
| 142 | | UINT16 op; |
| 143 | | |
| 144 | | PPC = PC; /* copy PC to previous PC */ |
| 145 | | |
| 146 | | CALL_DEBUGGER(PC); |
| 147 | | |
| 148 | | op = READ_OP(PC); |
| 149 | | |
| 150 | | PC++; |
| 151 | | |
| 152 | | switch((op >> 9)) |
| 153 | | { |
| 154 | | case 0x00: |
| 155 | | |
| 156 | | if(op == 0) // right? |
| 157 | | { |
| 158 | | // nop |
| 159 | | |
| 160 | | } |
| 161 | | else if((op & 0xff) == 0x65) |
| 162 | | { |
| 163 | | // ret |
| 164 | | |
| 165 | | } |
| 166 | | else |
| 167 | | { |
| 168 | | // ld d, s |
| 169 | | |
| 170 | | int s = op & 0xf; |
| 171 | | int d = (op >> 4) & 0xf; |
| 172 | | |
| 173 | | // TODO: handle special cases... and complete ALU operations |
| 174 | | |
| 175 | | if(regs_width[d] == 16 && (regs_width[s] == 16 || regs_width[s] == 8)) |
| 176 | | { |
| 177 | | ssp1610.regs[d] = ssp1610.regs[s]; |
| 178 | | } |
| 179 | | else if(regs_width[d] == 16 && regs_width[s] == 32) |
| 180 | | { |
| 181 | | ssp1610.regs[d] = (ssp1610.regs[s] >> 16); |
| 182 | | } |
| 183 | | else if(regs_width[d] == 32 && (regs_width[s] == 16 || regs_width[s] == 8)) |
| 184 | | { |
| 185 | | ssp1610.regs[d] = (ssp1610.regs[s] << 16) | (ssp1610.regs[d] & 0xffff); |
| 186 | | } |
| 187 | | else if(regs_width[d] == 32 && regs_width[s] == 32) |
| 188 | | { |
| 189 | | // wrong! if P is s then only the top 16bits are transferred |
| 190 | | ssp1610.regs[d] = (ssp1610.regs[s] & 0xffff0000) | (ssp1610.regs[d] & 0xffff); |
| 191 | | } |
| 192 | | |
| 193 | | if(d == IS_PC) // if d is PC one more cycle |
| 194 | | { |
| 195 | | ssp1610_ICount--; |
| 196 | | change_pc(PC); |
| 197 | | } |
| 198 | | |
| 199 | | } |
| 200 | | |
| 201 | | break; |
| 202 | | |
| 203 | | // ld d, (ri) -> probably right |
| 204 | | case 0x01: // or ldi simm ? |
| 205 | | |
| 206 | | break; |
| 207 | | |
| 208 | | // ld (ri), s |
| 209 | | case 0x02: |
| 210 | | |
| 211 | | break; |
| 212 | | |
| 213 | | // ld a, addr |
| 214 | | case 0x03: |
| 215 | | |
| 216 | | break; |
| 217 | | |
| 218 | | // ldi d, imm |
| 219 | | case 0x04: |
| 220 | | |
| 221 | | |
| 222 | | break; |
| 223 | | |
| 224 | | // ld d, ((ri)) |
| 225 | | case 0x05: |
| 226 | | |
| 227 | | break; |
| 228 | | |
| 229 | | // ldi (ri), imm |
| 230 | | case 0x06: |
| 231 | | |
| 232 | | break; |
| 233 | | |
| 234 | | // ld addr, a -> almost sure it's this one. some of the 1st 4 bits are set in the code |
| 235 | | case 0x07: // or ld d, (a) ? |
| 236 | | |
| 237 | | break; |
| 238 | | |
| 239 | | // ld d, ri |
| 240 | | case 0x09: |
| 241 | | |
| 242 | | break; |
| 243 | | |
| 244 | | // ld ri, s |
| 245 | | case 0x0a: |
| 246 | | |
| 247 | | break; |
| 248 | | |
| 249 | | // mpys (rj), (ri), b |
| 250 | | case 0x0b: |
| 251 | | |
| 252 | | break; |
| 253 | | |
| 254 | | // ldi ri, simm |
| 255 | | case 0x0c: |
| 256 | | case 0x0d: |
| 257 | | case 0x0e: |
| 258 | | case 0x0f: |
| 259 | | |
| 260 | | |
| 261 | | break; |
| 262 | | |
| 263 | | // sub a, s |
| 264 | | case 0x10: |
| 265 | | |
| 266 | | break; |
| 267 | | |
| 268 | | // sub a, (ri) |
| 269 | | case 0x11: |
| 270 | | |
| 271 | | break; |
| 272 | | |
| 273 | | // mpys s, (ri), b |
| 274 | | case 0x12: |
| 275 | | |
| 276 | | break; |
| 277 | | |
| 278 | | // sub a, adr |
| 279 | | case 0x13: |
| 280 | | |
| 281 | | break; |
| 282 | | |
| 283 | | // subi a, imm |
| 284 | | case 0x14: |
| 285 | | |
| 286 | | break; |
| 287 | | |
| 288 | | // sub a, ((ri)) |
| 289 | | case 0x15: |
| 290 | | |
| 291 | | break; |
| 292 | | |
| 293 | | // sub a, ri |
| 294 | | case 0x19: |
| 295 | | |
| 296 | | break; |
| 297 | | |
| 298 | | // mset reg, (ri), s |
| 299 | | case 0x1a: |
| 300 | | case 0x1b: |
| 301 | | |
| 302 | | break; |
| 303 | | |
| 304 | | // subi simm |
| 305 | | case 0x1c: |
| 306 | | |
| 307 | | break; |
| 308 | | |
| 309 | | // sub a, erij |
| 310 | | case 0x23: |
| 311 | | |
| 312 | | break; |
| 313 | | |
| 314 | | // call cond, addr |
| 315 | | case 0x24: //f bit? |
| 316 | | |
| 317 | | break; |
| 318 | | |
| 319 | | // bra cond, addr |
| 320 | | case 0x26: //f bit? |
| 321 | | { |
| 322 | | UINT16 new_pc = READ_OP(PC); |
| 323 | | UINT8 f = (op >> 8) & 1; |
| 324 | | UINT8 cond = 0; |
| 325 | | PC++; |
| 326 | | |
| 327 | | switch((op >> 4) & 0xf) |
| 328 | | { |
| 329 | | case 0x0: |
| 330 | | case 0x1: |
| 331 | | cond = f; // to jump always |
| 332 | | break; |
| 333 | | |
| 334 | | case 0x2: |
| 335 | | case 0x3: |
| 336 | | // reserved |
| 337 | | break; |
| 338 | | |
| 339 | | case 0x4: |
| 340 | | cond = GPI_0 == 0; |
| 341 | | break; |
| 342 | | |
| 343 | | case 0x5: |
| 344 | | cond = GPI_0 == 1; |
| 345 | | break; |
| 346 | | |
| 347 | | case 0x6: |
| 348 | | cond = GPI_1 == 0; |
| 349 | | break; |
| 350 | | |
| 351 | | case 0x7: |
| 352 | | cond = GPI_1 == 1; |
| 353 | | break; |
| 354 | | |
| 355 | | case 0x8: |
| 356 | | cond = L == 0; |
| 357 | | break; |
| 358 | | |
| 359 | | case 0x9: |
| 360 | | cond = L == 1; |
| 361 | | break; |
| 362 | | |
| 363 | | case 0xa: |
| 364 | | cond = Z == 0; |
| 365 | | break; |
| 366 | | |
| 367 | | case 0xb: |
| 368 | | cond = Z == 1; |
| 369 | | break; |
| 370 | | |
| 371 | | case 0xc: |
| 372 | | cond = OV == 0; |
| 373 | | break; |
| 374 | | |
| 375 | | case 0xd: |
| 376 | | cond = OV == 1; |
| 377 | | break; |
| 378 | | |
| 379 | | case 0xe: |
| 380 | | cond = N == 0; |
| 381 | | break; |
| 382 | | |
| 383 | | case 0xf: |
| 384 | | cond = N == 1; |
| 385 | | break; |
| 386 | | } |
| 387 | | |
| 388 | | if((cond && f) || (!cond && !f)) |
| 389 | | { |
| 390 | | PPC = PC; |
| 391 | | PC = new_pc; |
| 392 | | change_pc(PC); |
| 393 | | } |
| 394 | | |
| 395 | | ssp1610_ICount--; |
| 396 | | } |
| 397 | | |
| 398 | | break; |
| 399 | | |
| 400 | | |
| 401 | | case 0x28: |
| 402 | | |
| 403 | | if(op & 0x100) |
| 404 | | { |
| 405 | | // slow imm |
| 406 | | |
| 407 | | } |
| 408 | | else |
| 409 | | { |
| 410 | | // stop |
| 411 | | |
| 412 | | } |
| 413 | | |
| 414 | | break; |
| 415 | | |
| 416 | | // cmp a, s |
| 417 | | case 0x30: |
| 418 | | |
| 419 | | break; |
| 420 | | |
| 421 | | // cmp a, (ri) |
| 422 | | case 0x31: |
| 423 | | |
| 424 | | break; |
| 425 | | |
| 426 | | // cmp a, adr |
| 427 | | case 0x33: |
| 428 | | |
| 429 | | break; |
| 430 | | |
| 431 | | // cmpi a, imm |
| 432 | | case 0x34: |
| 433 | | { |
| 434 | | UINT16 imm = READ_OP(PC) << 16; |
| 435 | | #if 0 |
| 436 | | UINT64 tmp = (UINT64)A - (UINT64)imm; |
| 437 | | #else |
| 438 | | // The previous line causes a bus error in Apple's GCC as of 10.4.9: |
| 439 | | // i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367) |
| 440 | | // The gcc included with the Leopard Beta fixes this error. |
| 441 | | // Using the volatile tempA works around the bus error. |
| 442 | | volatile UINT32 tempA = A; |
| 443 | | UINT64 tmp = (UINT64)tempA - (UINT64)imm; |
| 444 | | #endif |
| 445 | | PC++; |
| 446 | | |
| 447 | | // right flags? |
| 448 | | |
| 449 | | SET_L(A < imm); |
| 450 | | SET_Z((A & 0xffff0000) == imm); |
| 451 | | SET_N(((INT32) A) < ((INT32)imm)); |
| 452 | | SET_OVSUB(imm,A,tmp); |
| 453 | | |
| 454 | | // A = saturated value |
| 455 | | if(OP && OV) |
| 456 | | { |
| 457 | | if((INT64)tmp > 0x7fffff) |
| 458 | | A = 0x7fffff; |
| 459 | | else if((INT64)tmp < -0x800000) |
| 460 | | A = 0x800000; |
| 461 | | } |
| 462 | | } |
| 463 | | break; |
| 464 | | |
| 465 | | // cmp a, ((ri)) |
| 466 | | case 0x35: |
| 467 | | |
| 468 | | break; |
| 469 | | |
| 470 | | // cmp a, ri |
| 471 | | case 0x39: |
| 472 | | |
| 473 | | break; |
| 474 | | |
| 475 | | // cmpi simm |
| 476 | | case 0x3c: |
| 477 | | |
| 478 | | break; |
| 479 | | |
| 480 | | // add a, s |
| 481 | | case 0x40: |
| 482 | | |
| 483 | | break; |
| 484 | | |
| 485 | | // add a, (ri) |
| 486 | | case 0x41: |
| 487 | | |
| 488 | | break; |
| 489 | | |
| 490 | | // mpya s, (ri), b |
| 491 | | case 0x42: |
| 492 | | |
| 493 | | break; |
| 494 | | |
| 495 | | // add a, adr |
| 496 | | case 0x43: |
| 497 | | |
| 498 | | break; |
| 499 | | |
| 500 | | // addi a, imm |
| 501 | | case 0x44: |
| 502 | | |
| 503 | | |
| 504 | | break; |
| 505 | | |
| 506 | | // add a, ((ri)) |
| 507 | | case 0x45: |
| 508 | | |
| 509 | | break; |
| 510 | | |
| 511 | | // mod cond, op |
| 512 | | case 0x48: |
| 513 | | |
| 514 | | break; |
| 515 | | |
| 516 | | // add a, ri |
| 517 | | case 0x49: |
| 518 | | |
| 519 | | break; |
| 520 | | |
| 521 | | // mod f, op |
| 522 | | case 0x4a: |
| 523 | | |
| 524 | | break; |
| 525 | | |
| 526 | | // mpya (rj), (ri), b |
| 527 | | case 0x4b: |
| 528 | | |
| 529 | | break; |
| 530 | | |
| 531 | | // addi simm |
| 532 | | case 0x4c: // docs show a wrong opcode value |
| 533 | | |
| 534 | | break; |
| 535 | | |
| 536 | | // ld reg, erij |
| 537 | | case 0x4e: |
| 538 | | case 0x4f: |
| 539 | | |
| 540 | | break; |
| 541 | | |
| 542 | | // and a, s |
| 543 | | case 0x50: |
| 544 | | |
| 545 | | break; |
| 546 | | |
| 547 | | // and a, (ri) |
| 548 | | case 0x51: |
| 549 | | |
| 550 | | break; |
| 551 | | |
| 552 | | // mld s, (ri), b |
| 553 | | case 0x52: |
| 554 | | break; |
| 555 | | |
| 556 | | // and a, adr |
| 557 | | case 0x53: |
| 558 | | |
| 559 | | break; |
| 560 | | |
| 561 | | // andi a, imm |
| 562 | | case 0x54: |
| 563 | | |
| 564 | | |
| 565 | | break; |
| 566 | | |
| 567 | | // and a, ((ri)) |
| 568 | | case 0x55: |
| 569 | | |
| 570 | | break; |
| 571 | | |
| 572 | | // and a, ri |
| 573 | | case 0x59: |
| 574 | | |
| 575 | | break; |
| 576 | | |
| 577 | | // mld (rj), (ri), b |
| 578 | | case 0x5b: |
| 579 | | |
| 580 | | break; |
| 581 | | |
| 582 | | // andi simm |
| 583 | | case 0x5c: |
| 584 | | A = (A & ~0x00ff0000) | (A & ((op & 0xff) << 16)); |
| 585 | | // SET_L(); |
| 586 | | SET_Z(A == 0); |
| 587 | | SET_N(A >> 31); |
| 588 | | SET_OV(0); |
| 589 | | break; |
| 590 | | |
| 591 | | // ld erij, reg |
| 592 | | case 0x5e: |
| 593 | | case 0x5f: |
| 594 | | |
| 595 | | break; |
| 596 | | |
| 597 | | // or a, s |
| 598 | | case 0x60: |
| 599 | | |
| 600 | | break; |
| 601 | | |
| 602 | | // or a, (ri) |
| 603 | | case 0x61: |
| 604 | | |
| 605 | | break; |
| 606 | | |
| 607 | | // or a, adr |
| 608 | | case 0x63: |
| 609 | | |
| 610 | | break; |
| 611 | | |
| 612 | | // ori a, imm |
| 613 | | case 0x64: |
| 614 | | |
| 615 | | break; |
| 616 | | |
| 617 | | // or a, ((ri)) |
| 618 | | case 0x65: |
| 619 | | |
| 620 | | break; |
| 621 | | |
| 622 | | // or a, ri |
| 623 | | case 0x69: |
| 624 | | |
| 625 | | break; |
| 626 | | |
| 627 | | // ori simm |
| 628 | | case 0x6c: |
| 629 | | |
| 630 | | break; |
| 631 | | |
| 632 | | // eor a, s |
| 633 | | case 0x70: |
| 634 | | |
| 635 | | break; |
| 636 | | |
| 637 | | // eor a, (ri) |
| 638 | | case 0x71: |
| 639 | | |
| 640 | | break; |
| 641 | | |
| 642 | | // eor a, adr |
| 643 | | case 0x73: |
| 644 | | |
| 645 | | break; |
| 646 | | |
| 647 | | // eori a, imm |
| 648 | | case 0x74: |
| 649 | | |
| 650 | | break; |
| 651 | | |
| 652 | | // eor a, ((ri)) |
| 653 | | case 0x75: |
| 654 | | |
| 655 | | break; |
| 656 | | |
| 657 | | // eor a, ri |
| 658 | | case 0x79: |
| 659 | | |
| 660 | | break; |
| 661 | | |
| 662 | | // eori simm |
| 663 | | case 0x7c: |
| 664 | | |
| 665 | | break; |
| 666 | | |
| 667 | | default: |
| 668 | | |
| 669 | | break; |
| 670 | | } |
| 671 | | |
| 672 | | ssp1610_ICount--; |
| 673 | | |
| 674 | | } while( ssp1610_ICount > 0 ); |
| 675 | | |
| 676 | | return cycles - ssp1610_ICount; |
| 677 | | } |
| 678 | | |
| 679 | | static void ssp1610_get_context(void *regs) |
| 680 | | { |
| 681 | | /* copy the context */ |
| 682 | | if( regs ) |
| 683 | | *(ssp1610_regs *)regs = ssp1610; |
| 684 | | } |
| 685 | | |
| 686 | | static void ssp1610_set_context(void *regs) |
| 687 | | { |
| 688 | | /* copy the context */ |
| 689 | | if (regs) |
| 690 | | ssp1610 = *(ssp1610_regs *)regs; |
| 691 | | } |
| 692 | | |
| 693 | | #ifdef ENABLE_DEBUGGER |
| 694 | | static offs_t ssp1610_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram) |
| 695 | | { |
| 696 | | return dasm_ssp1610( buffer, pc, oprom); |
| 697 | | } |
| 698 | | #endif /* ENABLE_DEBUGGER */ |
| 699 | | |
| 700 | | #if (HAS_SSP1610) |
| 701 | | |
| 702 | | /************************************************************************** |
| 703 | | * Generic set_info |
| 704 | | **************************************************************************/ |
| 705 | | |
| 706 | | static void ssp1610_set_info(UINT32 state, cpuinfo *info) |
| 707 | | { |
| 708 | | switch (state) |
| 709 | | { |
| 710 | | /* --- the following bits of info are set as 64-bit signed integers --- */ |
| 711 | | |
| 712 | | // case CPUINFO_INT_REGISTER + SSP1610_REG0: REG0 = info->i; break; |
| 713 | | case CPUINFO_INT_REGISTER + SSP1610_X: X = info->i; break; |
| 714 | | case CPUINFO_INT_REGISTER + SSP1610_Y: Y = info->i; break; |
| 715 | | case CPUINFO_INT_REGISTER + SSP1610_A: A = info->i; break; |
| 716 | | case CPUINFO_INT_REGISTER + SSP1610_ST: ST = info->i; break; |
| 717 | | case CPUINFO_INT_REGISTER + SSP1610_STACK: STACK = info->i; break; |
| 718 | | case CPUINFO_INT_PC: |
| 719 | | case CPUINFO_INT_REGISTER + SSP1610_PC: PC = info->i; change_pc(PC); break; |
| 720 | | case CPUINFO_INT_REGISTER + SSP1610_P: P = info->i; break; |
| 721 | | case CPUINFO_INT_REGISTER + SSP1610_AL: AL = info->i; break; |
| 722 | | case CPUINFO_INT_REGISTER + SSP1610_XST: XST = info->i; break; |
| 723 | | case CPUINFO_INT_REGISTER + SSP1610_PL: PL = info->i; break; |
| 724 | | case CPUINFO_INT_REGISTER + SSP1610_SRCR: SRCR = info->i; break; |
| 725 | | case CPUINFO_INT_REGISTER + SSP1610_BRCR: BRCR = info->i; break; |
| 726 | | case CPUINFO_INT_REGISTER + SSP1610_BRER: BRER = info->i; break; |
| 727 | | case CPUINFO_INT_REGISTER + SSP1610_XRD0: XRD0 = info->i; break; |
| 728 | | case CPUINFO_INT_REGISTER + SSP1610_XRD1: XRD1 = info->i; break; |
| 729 | | case CPUINFO_INT_REGISTER + SSP1610_AE: AE = info->i; break; |
| 730 | | case CPUINFO_INT_REGISTER + SSP1610_DIOR: DIOR = info->i; break; |
| 731 | | case CPUINFO_INT_REGISTER + SSP1610_GR22: GR22 = info->i; break; |
| 732 | | case CPUINFO_INT_REGISTER + SSP1610_GR23: GR23 = info->i; break; |
| 733 | | case CPUINFO_INT_REGISTER + SSP1610_EXT0: EXT0 = info->i; break; |
| 734 | | case CPUINFO_INT_REGISTER + SSP1610_EXT1: EXT1 = info->i; break; |
| 735 | | case CPUINFO_INT_REGISTER + SSP1610_EXT2: EXT2 = info->i; break; |
| 736 | | case CPUINFO_INT_REGISTER + SSP1610_EXT3: EXT3 = info->i; break; |
| 737 | | case CPUINFO_INT_REGISTER + SSP1610_EXT4: EXT4 = info->i; break; |
| 738 | | case CPUINFO_INT_REGISTER + SSP1610_EXT5: EXT5 = info->i; break; |
| 739 | | case CPUINFO_INT_REGISTER + SSP1610_EXT6: EXT6 = info->i; break; |
| 740 | | case CPUINFO_INT_REGISTER + SSP1610_EXT7: EXT7 = info->i; break; |
| 741 | | |
| 742 | | // case CPUINFO_INT_INPUT_STATE + 0: set_irq_line(0, info->i); break; |
| 743 | | // case CPUINFO_INT_INPUT_STATE + 1: set_irq_line(1, info->i); break; |
| 744 | | // case CPUINFO_INT_INPUT_STATE + 2: set_irq_line(2, info->i); break; |
| 745 | | } |
| 746 | | } |
| 747 | | |
| 748 | | /************************************************************************** |
| 749 | | * Generic get_info |
| 750 | | **************************************************************************/ |
| 751 | | |
| 752 | | void ssp1610_get_info(UINT32 state, cpuinfo *info) |
| 753 | | { |
| 754 | | switch (state) |
| 755 | | { |
| 756 | | /* --- the following bits of info are returned as 64-bit signed integers --- */ |
| 757 | | case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(ssp1610_regs); break; |
| 758 | | case CPUINFO_INT_INPUT_LINES: info->i = 3; break; |
| 759 | | case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; |
| 760 | | case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_BE; break; |
| 761 | | case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; |
| 762 | | case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; |
| 763 | | case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; break; |
| 764 | | case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break; |
| 765 | | case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; |
| 766 | | case CPUINFO_INT_MAX_CYCLES: info->i = 3; break; |
| 767 | | |
| 768 | | case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; |
| 769 | | case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break; |
| 770 | | case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = -1; break; |
| 771 | | case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; |
| 772 | | case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break; |
| 773 | | case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; |
| 774 | | case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break; |
| 775 | | case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break; |
| 776 | | case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break; |
| 777 | | |
| 778 | | case CPUINFO_INT_INPUT_STATE + 0: /* not implemented */ break; |
| 779 | | |
| 780 | | case CPUINFO_INT_PREVIOUSPC: info->i = PPC; break; |
| 781 | | |
| 782 | | case CPUINFO_INT_REGISTER + SSP1610_REG0: info->i = REG0; break; |
| 783 | | case CPUINFO_INT_REGISTER + SSP1610_X: info->i = X; break; |
| 784 | | case CPUINFO_INT_REGISTER + SSP1610_Y: info->i = Y; break; |
| 785 | | case CPUINFO_INT_REGISTER + SSP1610_A: info->i = A; break; |
| 786 | | case CPUINFO_INT_REGISTER + SSP1610_ST: info->i = ST; break; |
| 787 | | case CPUINFO_INT_REGISTER + SSP1610_STACK: info->i = STACK; break; |
| 788 | | case CPUINFO_INT_PC: |
| 789 | | case CPUINFO_INT_REGISTER + SSP1610_PC: info->i = PC; change_pc(PC); break; |
| 790 | | case CPUINFO_INT_REGISTER + SSP1610_P: info->i = P; break; |
| 791 | | case CPUINFO_INT_REGISTER + SSP1610_AL: info->i = AL; break; |
| 792 | | case CPUINFO_INT_REGISTER + SSP1610_XST: info->i = XST; break; |
| 793 | | case CPUINFO_INT_REGISTER + SSP1610_PL: info->i = PL; break; |
| 794 | | case CPUINFO_INT_REGISTER + SSP1610_SRCR: info->i = SRCR; break; |
| 795 | | case CPUINFO_INT_REGISTER + SSP1610_BRCR: info->i = BRCR; break; |
| 796 | | case CPUINFO_INT_REGISTER + SSP1610_BRER: info->i = BRER; break; |
| 797 | | case CPUINFO_INT_REGISTER + SSP1610_XRD0: info->i = XRD0; break; |
| 798 | | case CPUINFO_INT_REGISTER + SSP1610_XRD1: info->i = XRD1; break; |
| 799 | | case CPUINFO_INT_REGISTER + SSP1610_AE: info->i = AE; break; |
| 800 | | case CPUINFO_INT_REGISTER + SSP1610_DIOR: info->i = DIOR; break; |
| 801 | | case CPUINFO_INT_REGISTER + SSP1610_GR22: info->i = GR22; break; |
| 802 | | case CPUINFO_INT_REGISTER + SSP1610_GR23: info->i = GR23; break; |
| 803 | | case CPUINFO_INT_REGISTER + SSP1610_EXT0: info->i = EXT0; break; |
| 804 | | case CPUINFO_INT_REGISTER + SSP1610_EXT1: info->i = EXT1; break; |
| 805 | | case CPUINFO_INT_REGISTER + SSP1610_EXT2: info->i = EXT2; break; |
| 806 | | case CPUINFO_INT_REGISTER + SSP1610_EXT3: info->i = EXT3; break; |
| 807 | | case CPUINFO_INT_REGISTER + SSP1610_EXT4: info->i = EXT4; break; |
| 808 | | case CPUINFO_INT_REGISTER + SSP1610_EXT5: info->i = EXT5; break; |
| 809 | | case CPUINFO_INT_REGISTER + SSP1610_EXT6: info->i = EXT6; break; |
| 810 | | case CPUINFO_INT_REGISTER + SSP1610_EXT7: info->i = EXT7; break; |
| 811 | | |
| 812 | | /* --- the following bits of info are returned as pointers to data or functions --- */ |
| 813 | | case CPUINFO_PTR_SET_INFO: info->setinfo = ssp1610_set_info; break; |
| 814 | | case CPUINFO_PTR_GET_CONTEXT: info->getcontext = ssp1610_get_context; break; |
| 815 | | case CPUINFO_PTR_SET_CONTEXT: info->setcontext = ssp1610_set_context; break; |
| 816 | | case CPUINFO_PTR_INIT: info->init = ssp1610_init; break; |
| 817 | | case CPUINFO_PTR_RESET: info->reset = ssp1610_reset; break; |
| 818 | | case CPUINFO_PTR_EXIT: info->exit = ssp1610_exit; break; |
| 819 | | case CPUINFO_PTR_EXECUTE: info->execute = ssp1610_execute; break; |
| 820 | | case CPUINFO_PTR_BURN: info->burn = NULL; break; |
| 821 | | #ifdef ENABLE_DEBUGGER |
| 822 | | case CPUINFO_PTR_DISASSEMBLE: info->disassemble = ssp1610_dasm; break; |
| 823 | | #endif /* ENABLE_DEBUGGER */ |
| 824 | | case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &ssp1610_ICount; break; |
| 825 | | |
| 826 | | case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map = 0; break; |
| 827 | | case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_IO: info->internal_map = 0; break; |
| 828 | | |
| 829 | | /* --- the following bits of info are returned as NULL-terminated strings --- */ |
| 830 | | case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "SSP1610 CPU"); break; |
| 831 | | case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "0.1"); break; |
| 832 | | case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break; |
| 833 | | case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright Pierpaolo Prazzoli"); break; |
| 834 | | |
| 835 | | case CPUINFO_STR_FLAGS: |
| 836 | | sprintf(info->s, "_flags_"); |
| 837 | | break; |
| 838 | | |
| 839 | | case CPUINFO_STR_REGISTER + SSP1610_REG0: sprintf(info->s, "REG0 :%04X", REG0); break; |
| 840 | | case CPUINFO_STR_REGISTER + SSP1610_X: sprintf(info->s, "X :%04X", X); break; |
| 841 | | case CPUINFO_STR_REGISTER + SSP1610_Y: sprintf(info->s, "Y :%04X", Y); break; |
| 842 | | case CPUINFO_STR_REGISTER + SSP1610_A: sprintf(info->s, "A :%08X", A); break; |
| 843 | | case CPUINFO_STR_REGISTER + SSP1610_ST: sprintf(info->s, "ST :%04X", ST); break; |
| 844 | | case CPUINFO_STR_REGISTER + SSP1610_STACK: sprintf(info->s, "STACK :%04X", STACK); break; |
| 845 | | case CPUINFO_STR_REGISTER + SSP1610_PC: sprintf(info->s, "PC :%04X", PC); break; |
| 846 | | case CPUINFO_STR_REGISTER + SSP1610_P: sprintf(info->s, "P :%08X", P); break; |
| 847 | | case CPUINFO_STR_REGISTER + SSP1610_AL: sprintf(info->s, "AL :%04X", AL); break; |
| 848 | | case CPUINFO_STR_REGISTER + SSP1610_XST: sprintf(info->s, "XST :%04X", XST); break; |
| 849 | | case CPUINFO_STR_REGISTER + SSP1610_PL: sprintf(info->s, "PL :%04X", PL); break; |
| 850 | | case CPUINFO_STR_REGISTER + SSP1610_SRCR: sprintf(info->s, "SRCR :%02X", SRCR); break; |
| 851 | | case CPUINFO_STR_REGISTER + SSP1610_BRCR: sprintf(info->s, "BRCR :%02X", BRCR); break; |
| 852 | | case CPUINFO_STR_REGISTER + SSP1610_BRER: sprintf(info->s, "BRER :%04X", BRER); break; |
| 853 | | case CPUINFO_STR_REGISTER + SSP1610_XRD0: sprintf(info->s, "XRD0 :%02X", XRD0); break; |
| 854 | | case CPUINFO_STR_REGISTER + SSP1610_XRD1: sprintf(info->s, "XRD1 :%02X", XRD1); break; |
| 855 | | case CPUINFO_STR_REGISTER + SSP1610_AE: sprintf(info->s, "AE :%02X", AE); break; |
| 856 | | case CPUINFO_STR_REGISTER + SSP1610_DIOR: sprintf(info->s, "DIOR :%04X", DIOR); break; |
| 857 | | case CPUINFO_STR_REGISTER + SSP1610_GR22: sprintf(info->s, "GR22 :%04X", GR22); break; |
| 858 | | case CPUINFO_STR_REGISTER + SSP1610_GR23: sprintf(info->s, "GR23 :%04X", GR23); break; |
| 859 | | case CPUINFO_STR_REGISTER + SSP1610_EXT0: sprintf(info->s, "EXT0 :%04X", EXT0); break; |
| 860 | | case CPUINFO_STR_REGISTER + SSP1610_EXT1: sprintf(info->s, "EXT1 :%04X", EXT1); break; |
| 861 | | case CPUINFO_STR_REGISTER + SSP1610_EXT2: sprintf(info->s, "EXT2 :%04X", EXT2); break; |
| 862 | | case CPUINFO_STR_REGISTER + SSP1610_EXT3: sprintf(info->s, "EXT3 :%04X", EXT3); break; |
| 863 | | case CPUINFO_STR_REGISTER + SSP1610_EXT4: sprintf(info->s, "EXT4 :%04X", EXT4); break; |
| 864 | | case CPUINFO_STR_REGISTER + SSP1610_EXT5: sprintf(info->s, "EXT5 :%04X", EXT5); break; |
| 865 | | case CPUINFO_STR_REGISTER + SSP1610_EXT6: sprintf(info->s, "EXT6 :%04X", EXT6); break; |
| 866 | | case CPUINFO_STR_REGISTER + SSP1610_EXT7: sprintf(info->s, "EXT7 :%04X", EXT7); break; |
| 867 | | |
| 868 | | } |
| 869 | | } |
| 870 | | #endif |