#include namespace SuperFamicom { #define DSP2_CPP #include "opcodes.cpp" DSP2 dsp2; #include "serialization.cpp" auto DSP2::power() -> void { status.waiting_for_command = true; status.in_count = 0; status.in_index = 0; status.out_count = 0; status.out_index = 0; status.op05transparent = 0; status.op05haslen = false; status.op05len = 0; status.op06haslen = false; status.op06len = 0; status.op09word1 = 0; status.op09word2 = 0; status.op0dhaslen = false; status.op0doutlen = 0; status.op0dinlen = 0; } auto DSP2::read(uint addr, uint8 data) -> uint8 { if(addr & 1) return 0x00; uint8 r = 0xff; if(status.out_count) { r = status.output[status.out_index++]; status.out_index &= 511; if(status.out_count == status.out_index) { status.out_count = 0; } } return r; } auto DSP2::write(uint addr, uint8 data) -> void { if(addr & 1) return; if(status.waiting_for_command) { status.command = data; status.in_index = 0; status.waiting_for_command = false; switch(data) { case 0x01: status.in_count = 32; break; case 0x03: status.in_count = 1; break; case 0x05: status.in_count = 1; break; case 0x06: status.in_count = 1; break; case 0x07: break; case 0x08: break; case 0x09: status.in_count = 4; break; case 0x0d: status.in_count = 2; break; case 0x0f: status.in_count = 0; break; } } else { status.parameters[status.in_index++] = data; status.in_index &= 511; } if(status.in_count == status.in_index) { status.waiting_for_command = true; status.out_index = 0; switch(status.command) { case 0x01: { status.out_count = 32; op01(); } break; case 0x03: { op03(); } break; case 0x05: { if(status.op05haslen) { status.op05haslen = false; status.out_count = status.op05len; op05(); } else { status.op05len = status.parameters[0]; status.in_index = 0; status.in_count = status.op05len * 2; status.op05haslen = true; if(data)status.waiting_for_command = false; } } break; case 0x06: { if(status.op06haslen) { status.op06haslen = false; status.out_count = status.op06len; op06(); } else { status.op06len = status.parameters[0]; status.in_index = 0; status.in_count = status.op06len; status.op06haslen = true; if(data)status.waiting_for_command = false; } } break; case 0x07: break; case 0x08: break; case 0x09: { op09(); } break; case 0x0d: { if(status.op0dhaslen) { status.op0dhaslen = false; status.out_count = status.op0doutlen; op0d(); } else { status.op0dinlen = status.parameters[0]; status.op0doutlen = status.parameters[1]; status.in_index = 0; status.in_count = (status.op0dinlen + 1) >> 1; status.op0dhaslen = true; if(data)status.waiting_for_command = false; } } break; case 0x0f: break; } } } }