Path: blob/master/libsnes/bsnes/snes/chip/hitachidsp/opcodes.cpp
2 views
#ifdef HITACHIDSP_CPP12void HitachiDSP::push() {3stack[7] = stack[6];4stack[6] = stack[5];5stack[5] = stack[4];6stack[4] = stack[3];7stack[3] = stack[2];8stack[2] = stack[1];9stack[1] = stack[0];10stack[0] = regs.pc;11}1213void HitachiDSP::pull() {14regs.pc = stack[0];15stack[0] = stack[1];16stack[1] = stack[2];17stack[2] = stack[3];18stack[3] = stack[4];19stack[4] = stack[5];20stack[5] = stack[6];21stack[6] = stack[7];22stack[7] = 0x0000;23}2425//Shift-A: math opcodes can shift A register prior to ALU operation26unsigned HitachiDSP::sa() {27switch(opcode & 0x0300) { default:28case 0x0000: return regs.a << 0;29case 0x0100: return regs.a << 1;30case 0x0200: return regs.a << 8;31case 0x0300: return regs.a << 16;32}33}3435//Register-or-Immediate: most opcodes can load from a register or immediate36unsigned HitachiDSP::ri() {37if(opcode & 0x0400) return opcode & 0xff;38return reg_read(opcode & 0xff);39}4041//New-PC: determine jump target address; opcode.d9 = long jump flag (1 = yes)42unsigned HitachiDSP::np() {43if(opcode & 0x0200) return (regs.p << 8) | (opcode & 0xff);44return (regs.pc & 0xffff00) | (opcode & 0xff);45}4647void HitachiDSP::exec() {48if((opcode & 0xffff) == 0x0000) {49//0000 0000 0000 000050//nop51}5253else if((opcode & 0xdd00) == 0x0800) {54//00.0 10.0 .... ....55//jump i56if(opcode & 0x2000) push();57regs.pc = np();58}5960else if((opcode & 0xdd00) == 0x0c00) {61//00.0 11.0 .... ....62//jumpeq i63if(regs.z) {64if(opcode & 0x2000) push();65regs.pc = np();66}67}6869else if((opcode & 0xdd00) == 0x1000) {70//00.1 00.0 .... ....71//jumpge i72if(regs.c) {73if(opcode & 0x2000) push();74regs.pc = np();75}76}7778else if((opcode & 0xdd00) == 0x1400) {79//00.1 01.0 .... ....80//jumpmi i81if(regs.n) {82if(opcode & 0x2000) push();83regs.pc = np();84}85}8687else if((opcode & 0xffff) == 0x1c00) {88//0001 1100 0000 000089//loop?90}9192else if((opcode & 0xfffe) == 0x2500) {93//0010 0101 0000 000.94//skiplt/skipge95if(regs.c == (opcode & 1)) regs.pc++;96}9798else if((opcode & 0xfffe) == 0x2600) {99//0010 0110 0000 000.100//skipne/skipeq101if(regs.z == (opcode & 1)) regs.pc++;102}103104else if((opcode & 0xfffe) == 0x2700) {105//0010 0111 0000 000.106//skipmi/skippl107if(regs.n == (opcode & 1)) regs.pc++;108}109110else if((opcode & 0xffff) == 0x3c00) {111//0011 1100 0000 0000112//ret113pull();114}115116else if((opcode & 0xffff) == 0x4000) {117//0100 0000 0000 0000118//rdbus119regs.busdata = bus_read(regs.busaddr++);120}121122else if((opcode & 0xf800) == 0x4800) {123//0100 1... .... ....124//cmpr a<<n,ri125int result = ri() - sa();126regs.n = result & 0x800000;127regs.z = (uint24)result == 0;128regs.c = result >= 0;129}130131else if((opcode & 0xf800) == 0x5000) {132//0101 0... .... ....133//cmp a<<n,ri134int result = sa() - ri();135regs.n = result & 0x800000;136regs.z = (uint24)result == 0;137regs.c = result >= 0;138}139140else if((opcode & 0xfb00) == 0x5900) {141//0101 1.01 .... ....142//sxb143regs.a = (int8)ri();144}145146else if((opcode & 0xfb00) == 0x5a00) {147//0101 1.10 .... ....148//sxw149regs.a = (int16)ri();150}151152else if((opcode & 0xfb00) == 0x6000) {153//0110 0.00 .... ....154//ld a,ri155regs.a = ri();156}157158else if((opcode & 0xfb00) == 0x6100) {159//0110 0.01 .... ....160//ld ?,ri161}162163else if((opcode & 0xfb00) == 0x6300) {164//0110 0.11 .... ....165//ld p,ri166regs.p = ri();167}168169else if((opcode & 0xfb00) == 0x6800) {170//0110 1.00 .... ....171//rdraml172uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);173if(target < 0xc00) regs.ramdata = (regs.ramdata & 0xffff00) | (dataRAM[target] << 0);174}175176else if((opcode & 0xfb00) == 0x6900) {177//0110 1.01 .... ....178//rdramh179uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);180if(target < 0xc00) regs.ramdata = (regs.ramdata & 0xff00ff) | (dataRAM[target] << 8);181}182183else if((opcode & 0xfb00) == 0x6a00) {184//0110 1.10 .... ....185//rdramb186uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);187if(target < 0xc00) regs.ramdata = (regs.ramdata & 0x00ffff) | (dataRAM[target] << 16);188}189190else if((opcode & 0xffff) == 0x7000) {191//0111 0000 0000 0000192//rdrom193regs.romdata = dataROM[regs.a & 0x3ff];194}195196else if((opcode & 0xff00) == 0x7c00) {197//0111 1100 .... ....198//ld pl,i199regs.p = (regs.p & 0xff00) | ((opcode & 0xff) << 0);200}201202else if((opcode & 0xff00) == 0x7d00) {203//0111 1101 .... ....204//ld ph,i205regs.p = (regs.p & 0x00ff) | ((opcode & 0xff) << 8);206}207208else if((opcode & 0xf800) == 0x8000) {209//1000 0... .... ....210//add a<<n,ri211int result = sa() + ri();212regs.a = result;213regs.n = regs.a & 0x800000;214regs.z = regs.a == 0;215regs.c = result > 0xffffff;216}217218else if((opcode & 0xf800) == 0x8800) {219//1000 1... .... ....220//subr a<<n,ri221int result = ri() - sa();222regs.a = result;223regs.n = regs.a & 0x800000;224regs.z = regs.a == 0;225regs.c = result >= 0;226}227228else if((opcode & 0xf800) == 0x9000) {229//1001 0... .... ....230//sub a<<n,ri231int result = sa() - ri();232regs.a = result;233regs.n = regs.a & 0x800000;234regs.z = regs.a == 0;235regs.c = result >= 0;236}237238else if((opcode & 0xfb00) == 0x9800) {239//1001 1.00 .... ....240//mul a,ri241int64 x = (int24)regs.a;242int64 y = (int24)ri();243x *= y;244regs.accl = x >> 0ull;245regs.acch = x >> 24ull;246regs.n = regs.acch & 0x800000;247regs.z = x == 0;248}249250else if((opcode & 0xf800) == 0xa800) {251//1010 1... .... ....252//xor a<<n,ri253regs.a = sa() ^ ri();254regs.n = regs.a & 0x800000;255regs.z = regs.a == 0;256}257258else if((opcode & 0xf800) == 0xb000) {259//1011 0... .... ....260//and a<<n,ri261regs.a = sa() & ri();262regs.n = regs.a & 0x800000;263regs.z = regs.a == 0;264}265266else if((opcode & 0xf800) == 0xb800) {267//1011 1... .... ....268//or a<<n,ri269regs.a = sa() | ri();270regs.n = regs.a & 0x800000;271regs.z = regs.a == 0;272}273274else if((opcode & 0xfb00) == 0xc000) {275//1100 0.00 .... ....276//shr a,ri277regs.a = regs.a >> ri();278regs.n = regs.a & 0x800000;279regs.z = regs.a == 0;280}281282else if((opcode & 0xfb00) == 0xc800) {283//1100 1.00 .... ....284//asr a,ri285regs.a = (int24)regs.a >> ri();286regs.n = regs.a & 0x800000;287regs.z = regs.a == 0;288}289290else if((opcode & 0xfb00) == 0xd000) {291//1101 0.00 .... ....292//ror a,ri293uint24 length = ri();294regs.a = (regs.a >> length) | (regs.a << (24 - length));295regs.n = regs.a & 0x800000;296regs.z = regs.a == 0;297}298299else if((opcode & 0xfb00) == 0xd800) {300//1101 1.00 .... ....301//shl a,ri302regs.a = regs.a << ri();303regs.n = regs.a & 0x800000;304regs.z = regs.a == 0;305}306307else if((opcode & 0xff00) == 0xe000) {308//1110 0000 .... ....309//st r,a310reg_write(opcode & 0xff, regs.a);311}312313else if((opcode & 0xfb00) == 0xe800) {314//1110 1.00 .... ....315//wrraml316uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);317if(target < 0xc00) dataRAM[target] = regs.ramdata >> 0;318}319320else if((opcode & 0xfb00) == 0xe900) {321//1110 1.01 .... ....322//wrramh323uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);324if(target < 0xc00) dataRAM[target] = regs.ramdata >> 8;325}326327else if((opcode & 0xfb00) == 0xea00) {328//1110 1.10 .... ....329//wrramb330uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);331if(target < 0xc00) dataRAM[target] = regs.ramdata >> 16;332}333334else if((opcode & 0xff00) == 0xf000) {335//1111 0000 .... ....336//swap a,r337uint24 source = reg_read(opcode & 0xff);338uint24 target = regs.a;339regs.a = source;340reg_write(opcode & 0xff, target);341}342343else if((opcode & 0xffff) == 0xfc00) {344//1111 1100 0000 0000345//halt346state = State::Idle;347}348349else {350print("Hitachi DSP: invalid opcode @ ", hex<4>(regs.pc - 1), " = ", hex<4>(opcode), "\n");351state = State::Idle;352}353}354355#endif356357358